aboutsummaryrefslogtreecommitdiffstats
path: root/controller-api/src/main/java/com/yahoo/vespa/hosted
diff options
context:
space:
mode:
authorbjormel <bjormel@yahooinc.com>2023-10-01 12:23:12 +0000
committerbjormel <bjormel@yahooinc.com>2023-10-01 12:23:12 +0000
commite9058b555d4dfea2f6c872d9a677e8678b569569 (patch)
treefa1b67c6e39712c1e0d9f308b0dd55573b43f913 /controller-api/src/main/java/com/yahoo/vespa/hosted
parent0ad931fa86658904fe9212b014d810236b0e00e4 (diff)
parent16030193ec04ee41e98779a3d7ee6a6c1d0d0d6f (diff)
Merge branch 'master' into bjormel/aws-main-controller
Diffstat (limited to 'controller-api/src/main/java/com/yahoo/vespa/hosted')
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/archive/ArchiveService.java17
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/archive/MockArchiveService.java6
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/BillingController.java10
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/BillingReporter.java5
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/BillingReporterMock.java21
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/MockBillingController.java9
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java6
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/MockVpcEndpointService.java2
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/VpcEndpointService.java2
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/systemflags/v1/SystemFlagsDataArchive.java27
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/AthenzTenant.java8
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/CloudAccountInfo.java19
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/CloudTenant.java7
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/DeletedTenant.java3
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/Tenant.java9
15 files changed, 125 insertions, 26 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/archive/ArchiveService.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/archive/ArchiveService.java
index ed965f4331e..66cf3eef954 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/archive/ArchiveService.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/archive/ArchiveService.java
@@ -1,6 +1,7 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.controller.api.integration.archive;
+import com.yahoo.component.Version;
import com.yahoo.config.provision.CloudAccount;
import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.zone.ZoneId;
@@ -10,6 +11,7 @@ import java.net.URI;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
+import java.util.stream.Stream;
/**
* Service that manages archive storage URIs for tenant nodes.
@@ -28,4 +30,19 @@ public interface ArchiveService {
Optional<String> findEnclaveArchiveBucket(ZoneId zoneId, CloudAccount cloudAccount);
URI bucketURI(ZoneId zoneId, String bucketName);
+
+ /**
+ * @return the version of the template that was used during the last apply for the given cloud account,
+ * or {@link Version#emptyVersion} if the version tag was not present or invalid,
+ * or {@link Optional#empty()} if the we have no access to the cloud account (template probably not applied yet)
+ */
+ Optional<Version> getEnclaveTemplateVersion(CloudAccount cloudAccount);
+
+ static Stream<Version> parseVersion(String versionString) {
+ try {
+ return Stream.of(Version.fromString(versionString));
+ } catch (IllegalArgumentException e) {
+ return Stream.empty();
+ }
+ }
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/archive/MockArchiveService.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/archive/MockArchiveService.java
index 7461d3aa47e..4e6e71ca855 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/archive/MockArchiveService.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/archive/MockArchiveService.java
@@ -1,6 +1,7 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.controller.api.integration.archive;
+import com.yahoo.component.Version;
import com.yahoo.config.provision.CloudAccount;
import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.zone.ZoneId;
@@ -59,6 +60,11 @@ public class MockArchiveService implements ArchiveService {
return URI.create(String.format("s3://%s/", bucketName));
}
+ @Override
+ public Optional<Version> getEnclaveTemplateVersion(CloudAccount cloudAccount) {
+ return Optional.of(new Version(1, 2, 3));
+ }
+
public void setEnclaveArchiveBucket(ZoneId zoneId, CloudAccount cloudAccount, String bucketName) {
removeEnclaveArchiveBucket(zoneId, cloudAccount);
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/BillingController.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/BillingController.java
index 5c6e5c9542a..dfa0d4dccf2 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/BillingController.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/BillingController.java
@@ -2,6 +2,7 @@
package com.yahoo.vespa.hosted.controller.api.integration.billing;
import com.yahoo.config.provision.TenantName;
+import com.yahoo.vespa.hosted.controller.tenant.CloudTenant;
import java.math.BigDecimal;
import java.time.LocalDate;
@@ -109,6 +110,9 @@ public interface BillingController {
/** Get all bills from the system */
List<Bill> getBills();
+ /** Get the bill with the given id */
+ Bill getBill(Bill.Id billId);
+
/** Get the bill collection method for the given tenant */
default CollectionMethod getCollectionMethod(TenantName tenant) {
return CollectionMethod.NONE;
@@ -125,4 +129,8 @@ public interface BillingController {
}
default void updateCache(List<TenantName> tenants) {}
-} \ No newline at end of file
+
+ default String exportBill(Bill bill, String exportMethod, CloudTenant tenant) {
+ return "NOT_IMPLEMENTED";
+ }
+}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/BillingReporter.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/BillingReporter.java
index a4b3abf3bf9..719d22429b8 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/BillingReporter.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/BillingReporter.java
@@ -1,5 +1,8 @@
package com.yahoo.vespa.hosted.controller.api.integration.billing;
+import com.yahoo.vespa.hosted.controller.tenant.BillingReference;
+import com.yahoo.vespa.hosted.controller.tenant.CloudTenant;
+
public interface BillingReporter {
- double maintain();
+ BillingReference maintainTenant(CloudTenant tenant);
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/BillingReporterMock.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/BillingReporterMock.java
new file mode 100644
index 00000000000..34599f83a8c
--- /dev/null
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/BillingReporterMock.java
@@ -0,0 +1,21 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.controller.api.integration.billing;
+
+import com.yahoo.vespa.hosted.controller.tenant.BillingReference;
+import com.yahoo.vespa.hosted.controller.tenant.CloudTenant;
+
+import java.time.Clock;
+import java.util.UUID;
+
+public class BillingReporterMock implements BillingReporter {
+ private final Clock clock;
+
+ public BillingReporterMock(Clock clock) {
+ this.clock = clock;
+ }
+
+ @Override
+ public BillingReference maintainTenant(CloudTenant tenant) {
+ return new BillingReference(UUID.randomUUID().toString(), clock.instant());
+ }
+}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/MockBillingController.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/MockBillingController.java
index 671739bacab..eb20126304e 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/MockBillingController.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/MockBillingController.java
@@ -171,6 +171,15 @@ public class MockBillingController implements BillingController {
}
@Override
+ public Bill getBill(Bill.Id billId) {
+ return committedBills.values().stream()
+ .flatMap(Collection::stream)
+ .filter(bill -> bill.id().equals(billId))
+ .findFirst()
+ .orElseThrow();
+ }
+
+ @Override
public CollectionMethod getCollectionMethod(TenantName tenant) {
return collectionMethod.getOrDefault(tenant, CollectionMethod.AUTO);
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java
index 19bfc84db7a..31fdc9d1b64 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/configserver/ConfigServer.java
@@ -6,6 +6,7 @@ import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.EndpointsChecker.Availability;
import com.yahoo.config.provision.EndpointsChecker.Endpoint;
+import com.yahoo.config.provision.HostName;
import com.yahoo.config.provision.zone.ZoneId;
import ai.vespa.http.DomainName;
import ai.vespa.http.HttpURL.Path;
@@ -16,6 +17,8 @@ import com.yahoo.vespa.hosted.controller.api.application.v4.model.EndpointStatus
import com.yahoo.vespa.hosted.controller.api.application.v4.model.SearchNodeMetrics;
import com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId;
import com.yahoo.vespa.hosted.controller.api.integration.LogEntry;
+import com.yahoo.vespa.hosted.controller.api.integration.dataplanetoken.FingerPrint;
+import com.yahoo.vespa.hosted.controller.api.integration.dataplanetoken.TokenId;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.TestReport;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.TesterCloud;
import com.yahoo.vespa.hosted.controller.api.integration.noderepository.RestartFilter;
@@ -158,4 +161,7 @@ public interface ConfigServer {
/** Validates secret store configuration. */
String validateSecretStore(DeploymentId deploymentId, TenantSecretStore tenantSecretStore, String region, String parameterName);
+ /** Fingerprints of active data plane tokens, per healthy host with token auth, in the given deployment. */
+ Map<HostName, Map<TokenId, List<FingerPrint>>> activeTokenFingerprints(DeploymentId deploymentId);
+
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/MockVpcEndpointService.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/MockVpcEndpointService.java
index 39975138140..48cdc6ee053 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/MockVpcEndpointService.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/MockVpcEndpointService.java
@@ -29,7 +29,7 @@ public class MockVpcEndpointService implements VpcEndpointService {
}
@Override
- public synchronized Optional<DnsChallenge> setPrivateDns(DomainName privateDnsName, ClusterId clusterId, Optional<CloudAccount> account) {
+ public synchronized Optional<DnsChallenge> setPrivateDns(DomainName privateDnsName, ClusterId clusterId, Optional<CloudAccount> account, boolean isGenerated) {
DnsChallenge challenge = new DnsChallenge(RecordName.from("challenge--" + privateDnsName.value()),
RecordData.from(account.map(CloudAccount::value).orElse("system")),
clusterId,
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/VpcEndpointService.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/VpcEndpointService.java
index a3ee7681e2a..97e1b88b25c 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/VpcEndpointService.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/dns/VpcEndpointService.java
@@ -38,7 +38,7 @@ public interface VpcEndpointService {
enum ChallengeState { pending, ready, running, done }
/** Sets the private DNS name for any VPC endpoint for the given cluster, potentially guarded by a challenge. */
- Optional<DnsChallenge> setPrivateDns(DomainName privateDnsName, ClusterId clusterId, Optional<CloudAccount> account);
+ Optional<DnsChallenge> setPrivateDns(DomainName privateDnsName, ClusterId clusterId, Optional<CloudAccount> account, boolean isGenerated);
/** Attempts to complete the challenge, and returns the updated challenge state. */
ChallengeState process(DnsChallenge challenge);
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/systemflags/v1/SystemFlagsDataArchive.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/systemflags/v1/SystemFlagsDataArchive.java
index e661c88e117..8f47ac68cda 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/systemflags/v1/SystemFlagsDataArchive.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/systemflags/v1/SystemFlagsDataArchive.java
@@ -8,6 +8,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TextNode;
import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.ApplicationName;
import com.yahoo.config.provision.CloudAccount;
import com.yahoo.config.provision.CloudName;
import com.yahoo.config.provision.ClusterSpec;
@@ -191,8 +192,8 @@ public class SystemFlagsDataArchive {
flagData.rules().forEach(rule -> rule.conditions().forEach(condition -> {
int force_switch_expression_dummy = switch (condition.type()) {
case RELATIONAL -> switch (condition.dimension()) {
- case INSTANCE_ID, CLOUD, CLOUD_ACCOUNT, CLUSTER_ID, CLUSTER_TYPE, CONSOLE_USER_EMAIL,
- ENVIRONMENT, HOSTNAME, NODE_TYPE, SYSTEM, TENANT_ID, ZONE_ID ->
+ case APPLICATION_ID, CLOUD, CLOUD_ACCOUNT, CLUSTER_ID, CLUSTER_TYPE, CONSOLE_USER_EMAIL,
+ ENVIRONMENT, HOSTNAME, INSTANCE_ID, NODE_TYPE, SYSTEM, TENANT_ID, ZONE_ID ->
throw new FlagValidationException(condition.type().toWire() + " " +
DimensionHelper.toWire(condition.dimension()) +
" condition is not supported");
@@ -206,7 +207,7 @@ public class SystemFlagsDataArchive {
};
case WHITELIST, BLACKLIST -> switch (condition.dimension()) {
- case INSTANCE_ID -> validateConditionValues(condition, ApplicationId::fromSerializedForm);
+ case APPLICATION_ID -> validateConditionValues(condition, SystemFlagsDataArchive::validateTenantApplication);
case CONSOLE_USER_EMAIL -> validateConditionValues(condition, email -> {
if (!email.contains("@"))
throw new FlagValidationException("Invalid email address: " + email);
@@ -220,6 +221,7 @@ public class SystemFlagsDataArchive {
case CLUSTER_TYPE -> validateConditionValues(condition, ClusterSpec.Type::from);
case ENVIRONMENT -> validateConditionValues(condition, Environment::from);
case HOSTNAME -> validateConditionValues(condition, HostName::of);
+ case INSTANCE_ID -> validateConditionValues(condition, ApplicationId::fromSerializedForm);
case NODE_TYPE -> validateConditionValues(condition, NodeType::valueOf);
case SYSTEM -> throw new IllegalStateException("Flag data contains system dimension");
case TENANT_ID -> validateConditionValues(condition, TenantName::from);
@@ -250,23 +252,20 @@ public class SystemFlagsDataArchive {
return 0; // dummy to force switch expression
}
+ private static void validateTenantApplication(String application) {
+ String[] parts = application.split(":");
+ if (parts.length != 2)
+ throw new IllegalArgumentException("Applications must be on the form tenant:application, but was %s".formatted(application));
+ TenantName.from(parts[0]);
+ ApplicationName.from(parts[1]);
+ }
+
private static FlagData parseFlagData(FlagId flagId, String fileContent, ZoneRegistry zoneRegistry, boolean inController) {
if (fileContent.isBlank()) return new FlagData(flagId);
final JsonNode root;
try {
root = mapper.readTree(fileContent);
- // TODO (mortent): Remove this after completing migration of APPLICATION_ID dimension
- // replace "application" with "instance" for all dimension fields
-// List<JsonNode> dimensionParents = root.findParents("dimension");
-// for (JsonNode parentNode : dimensionParents) {
-// JsonNode dimension = parentNode.get("dimension");
-// if (dimension.isTextual() && "application".equals(dimension.textValue())) {
-// ObjectNode parent = (ObjectNode) parentNode;
-// parent.remove("dimension");
-// parent.put("dimension", "instance");
-// }
-// }
} catch (JsonProcessingException e) {
throw new FlagValidationException("Invalid JSON: " + e.getMessage());
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/AthenzTenant.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/AthenzTenant.java
index 53a3f431de7..0754a5ed49f 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/AthenzTenant.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/AthenzTenant.java
@@ -8,6 +8,7 @@ import com.yahoo.vespa.hosted.controller.api.identifiers.PropertyId;
import com.yahoo.vespa.hosted.controller.api.integration.organization.Contact;
import java.time.Instant;
+import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -27,8 +28,9 @@ public class AthenzTenant extends Tenant {
* Use {@link #create(TenantName, AthenzDomain, Property, Optional, Instant)}.
* */
public AthenzTenant(TenantName name, AthenzDomain domain, Property property, Optional<PropertyId> propertyId,
- Optional<Contact> contact, Instant createdAt, LastLoginInfo lastLoginInfo, Instant tenantRolesLastMaintained) {
- super(name, createdAt, lastLoginInfo, contact, tenantRolesLastMaintained);
+ Optional<Contact> contact, Instant createdAt, LastLoginInfo lastLoginInfo, Instant tenantRolesLastMaintained,
+ List<CloudAccountInfo> cloudAccounts) {
+ super(name, createdAt, lastLoginInfo, contact, tenantRolesLastMaintained, cloudAccounts);
this.domain = Objects.requireNonNull(domain, "domain must be non-null");
this.property = Objects.requireNonNull(property, "property must be non-null");
this.propertyId = Objects.requireNonNull(propertyId, "propertyId must be non-null");
@@ -62,7 +64,7 @@ public class AthenzTenant extends Tenant {
/** Create a new Athenz tenant */
public static AthenzTenant create(TenantName name, AthenzDomain domain, Property property,
Optional<PropertyId> propertyId, Instant createdAt) {
- return new AthenzTenant(requireName(name), domain, property, propertyId, Optional.empty(), createdAt, LastLoginInfo.EMPTY, Instant.EPOCH);
+ return new AthenzTenant(requireName(name), domain, property, propertyId, Optional.empty(), createdAt, LastLoginInfo.EMPTY, Instant.EPOCH, List.of());
}
@Override
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/CloudAccountInfo.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/CloudAccountInfo.java
new file mode 100644
index 00000000000..430f5770165
--- /dev/null
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/CloudAccountInfo.java
@@ -0,0 +1,19 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.controller.tenant;
+
+import com.yahoo.component.Version;
+import com.yahoo.config.provision.CloudAccount;
+
+import java.util.Objects;
+
+/**
+ * @author freva
+ */
+public record CloudAccountInfo(CloudAccount cloudAccount, Version templateVersion) {
+
+ public CloudAccountInfo {
+ Objects.requireNonNull(cloudAccount, "cloudAccount must be non-null");
+ Objects.requireNonNull(templateVersion, "templateVersion must be non-null");
+ }
+
+}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/CloudTenant.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/CloudTenant.java
index 4d7aee7b604..173d3e1950e 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/CloudTenant.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/CloudTenant.java
@@ -34,8 +34,8 @@ public class CloudTenant extends Tenant {
BiMap<PublicKey, SimplePrincipal> developerKeys, TenantInfo info,
List<TenantSecretStore> tenantSecretStores, ArchiveAccess archiveAccess,
Optional<Instant> invalidateUserSessionsBefore, Instant tenantRoleLastMaintained,
- Optional<BillingReference> billingReference) {
- super(name, createdAt, lastLoginInfo, Optional.empty(), tenantRoleLastMaintained);
+ List<CloudAccountInfo> cloudAccounts, Optional<BillingReference> billingReference) {
+ super(name, createdAt, lastLoginInfo, Optional.empty(), tenantRoleLastMaintained, cloudAccounts);
this.creator = creator;
this.developerKeys = developerKeys;
this.info = Objects.requireNonNull(info);
@@ -51,7 +51,8 @@ public class CloudTenant extends Tenant {
createdAt,
LastLoginInfo.EMPTY,
Optional.ofNullable(creator).map(SimplePrincipal::of),
- ImmutableBiMap.of(), TenantInfo.empty(), List.of(), new ArchiveAccess(), Optional.empty(), Instant.EPOCH, Optional.empty());
+ ImmutableBiMap.of(), TenantInfo.empty(), List.of(), new ArchiveAccess(), Optional.empty(),
+ Instant.EPOCH, List.of(), Optional.empty());
}
/** The user that created the tenant */
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/DeletedTenant.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/DeletedTenant.java
index b58fdf81278..30ce5d5a3b2 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/DeletedTenant.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/DeletedTenant.java
@@ -4,6 +4,7 @@ package com.yahoo.vespa.hosted.controller.tenant;
import com.yahoo.config.provision.TenantName;
import java.time.Instant;
+import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -17,7 +18,7 @@ public class DeletedTenant extends Tenant {
private final Instant deletedAt;
public DeletedTenant(TenantName name, Instant createdAt, Instant deletedAt) {
- super(name, createdAt, LastLoginInfo.EMPTY, Optional.empty(), Instant.EPOCH);
+ super(name, createdAt, LastLoginInfo.EMPTY, Optional.empty(), Instant.EPOCH, List.of());
this.deletedAt = Objects.requireNonNull(deletedAt, "deletedAt must be non-null");
}
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/Tenant.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/Tenant.java
index a4500991bf2..8b1c6b3ebde 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/Tenant.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/Tenant.java
@@ -5,6 +5,7 @@ import com.yahoo.config.provision.TenantName;
import com.yahoo.vespa.hosted.controller.api.integration.organization.Contact;
import java.time.Instant;
+import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -20,13 +21,15 @@ public abstract class Tenant {
private final LastLoginInfo lastLoginInfo;
private final Optional<Contact> contact;
private final Instant tenantRolesLastMaintained;
+ private final List<CloudAccountInfo> cloudAccounts;
- Tenant(TenantName name, Instant createdAt, LastLoginInfo lastLoginInfo, Optional<Contact> contact, Instant tenantRolesLastMaintained) {
+ Tenant(TenantName name, Instant createdAt, LastLoginInfo lastLoginInfo, Optional<Contact> contact, Instant tenantRolesLastMaintained, List<CloudAccountInfo> cloudAccounts) {
this.name = name;
this.createdAt = createdAt;
this.lastLoginInfo = lastLoginInfo;
this.contact = contact;
this.tenantRolesLastMaintained = tenantRolesLastMaintained;
+ this.cloudAccounts = cloudAccounts;
}
/** Name of this tenant */
@@ -53,6 +56,10 @@ public abstract class Tenant {
return tenantRolesLastMaintained;
}
+ public List<CloudAccountInfo> cloudAccounts() {
+ return cloudAccounts;
+ }
+
public abstract Type type();
@Override