summaryrefslogtreecommitdiffstats
path: root/controller-server
diff options
context:
space:
mode:
authorValerij Fredriksen <valerijf@yahooinc.com>2023-09-25 16:11:26 +0200
committerValerij Fredriksen <valerijf@yahooinc.com>2023-09-26 09:41:30 +0200
commit7ebb018355d1186b084bff1a2b89692b185aafe7 (patch)
tree9338868e43cc04ef155592985540d27be1fedaab /controller-server
parentd8f5db7abd5998a282c2174a158915bde4af1021 (diff)
Maintain tenant cloud accounts
Diffstat (limited to 'controller-server')
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/TenantController.java9
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/CloudAccountVerifier.java55
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ControllerMaintenance.java3
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/EnclaveAccessMaintainer.java2
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/EnclaveAccessMaintainerTest.java5
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/maintenance.json7
6 files changed, 76 insertions, 5 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/TenantController.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/TenantController.java
index bf2f2ab90eb..d11540b28dd 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/TenantController.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/TenantController.java
@@ -12,6 +12,7 @@ import com.yahoo.vespa.hosted.controller.persistence.CuratorDb;
import com.yahoo.vespa.hosted.controller.security.AccessControl;
import com.yahoo.vespa.hosted.controller.security.Credentials;
import com.yahoo.vespa.hosted.controller.security.TenantSpec;
+import com.yahoo.vespa.hosted.controller.tenant.CloudAccountInfo;
import com.yahoo.vespa.hosted.controller.tenant.DeletedTenant;
import com.yahoo.vespa.hosted.controller.tenant.LastLoginInfo;
import com.yahoo.vespa.hosted.controller.tenant.Tenant;
@@ -165,6 +166,14 @@ public class TenantController {
}
}
+ public void updateCloudAccounts(TenantName tenantName, List<CloudAccountInfo> cloudAccounts) {
+ try (Mutex lock = lock(tenantName)) {
+ var tenant = require(tenantName);
+ if (tenant.cloudAccounts().equals(cloudAccounts)) return; // no change
+ curator.writeTenant(LockedTenant.of(tenant, lock).withCloudAccounts(cloudAccounts).get());
+ }
+ }
+
/** Deletes the given tenant. */
public void delete(TenantName tenant, Optional<Credentials> credentials, boolean forget) {
try (Mutex lock = lock(tenant)) {
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/CloudAccountVerifier.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/CloudAccountVerifier.java
new file mode 100644
index 00000000000..f0fc8985bdf
--- /dev/null
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/CloudAccountVerifier.java
@@ -0,0 +1,55 @@
+package com.yahoo.vespa.hosted.controller.maintenance;
+
+import com.yahoo.config.provision.SystemName;
+import com.yahoo.vespa.hosted.controller.Controller;
+import com.yahoo.vespa.hosted.controller.tenant.CloudAccountInfo;
+import com.yahoo.vespa.hosted.controller.tenant.Tenant;
+
+import java.time.Duration;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import static java.util.logging.Level.WARNING;
+
+/**
+ * Verifies the cloud accounts that may be used by a given user have applied the enclave template
+ * and extracts the version of the applied template.
+ *
+ * All maintainers that operate on external cloud accounts should use the list on the Tenant instance
+ * maintained by this class rather than the cloud-accounts feature flag.
+ *
+ * The template version can be used to determine if new features can be enabled for the cloud account.
+ *
+ * @author freva
+ */
+public class CloudAccountVerifier extends ControllerMaintainer {
+
+ private static final Logger logger = Logger.getLogger(CloudAccountVerifier.class.getName());
+
+ CloudAccountVerifier(Controller controller, Duration interval) {
+ super(controller, interval, null, Set.of(SystemName.PublicCd, SystemName.Public));
+ }
+
+ @Override
+ protected double maintain() {
+ int attempts = 0, failures = 0;
+ for (Tenant tenant : controller().tenants().asList()) {
+ try {
+ attempts++;
+ List<CloudAccountInfo> cloudAccountInfos = controller().applications().accountsOf(tenant.name()).stream()
+ .flatMap(account -> controller().serviceRegistry()
+ .archiveService()
+ .getEnclaveTemplateVersion(account)
+ .map(version -> new CloudAccountInfo(account, version))
+ .stream())
+ .toList();
+ controller().tenants().updateCloudAccounts(tenant.name(), cloudAccountInfos);
+ } catch (RuntimeException e) {
+ logger.log(WARNING, "Failed to verify cloud accounts for tenant " + tenant.name(), e);
+ failures++;
+ }
+ }
+ return asSuccessFactorDeviation(attempts, failures);
+ }
+}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ControllerMaintenance.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ControllerMaintenance.java
index 6fae732df0a..3dcd8457da6 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ControllerMaintenance.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ControllerMaintenance.java
@@ -85,6 +85,7 @@ public class ControllerMaintenance extends AbstractComponent {
maintainers.add(new EnclaveAccessMaintainer(controller, intervals.defaultInterval));
maintainers.add(new CertificatePoolMaintainer(controller, metric, intervals.certificatePoolMaintainer));
maintainers.add(new BillingReportMaintainer(controller, intervals.billingReportMaintainer));
+ maintainers.add(new CloudAccountVerifier(controller, intervals.cloudAccountVerifier));
}
public Upgrader upgrader() { return upgrader; }
@@ -147,6 +148,7 @@ public class ControllerMaintenance extends AbstractComponent {
private final Duration meteringMonitorMaintainer;
private final Duration certificatePoolMaintainer;
private final Duration billingReportMaintainer;
+ private final Duration cloudAccountVerifier;
public Intervals(SystemName system) {
this.system = Objects.requireNonNull(system);
@@ -184,6 +186,7 @@ public class ControllerMaintenance extends AbstractComponent {
this.meteringMonitorMaintainer = duration(30, MINUTES);
this.certificatePoolMaintainer = duration(15, MINUTES);
this.billingReportMaintainer = duration(60, MINUTES);
+ this.cloudAccountVerifier = duration(10, MINUTES);
}
private Duration duration(long amount, TemporalUnit unit) {
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/EnclaveAccessMaintainer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/EnclaveAccessMaintainer.java
index 5218da91c46..6c1c4daa1bb 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/EnclaveAccessMaintainer.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/EnclaveAccessMaintainer.java
@@ -33,7 +33,7 @@ public class EnclaveAccessMaintainer extends ControllerMaintainer {
private Set<CloudAccount> externalAccounts() {
Set<CloudAccount> accounts = new HashSet<>();
for (Tenant tenant : controller().tenants().asList())
- accounts.addAll(controller().applications().accountsOf(tenant.name()));
+ tenant.cloudAccounts().forEach(accountInfo -> accounts.add(accountInfo.cloudAccount()));
return accounts;
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/EnclaveAccessMaintainerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/EnclaveAccessMaintainerTest.java
index 5bfac2866ce..1e1079a3314 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/EnclaveAccessMaintainerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/EnclaveAccessMaintainerTest.java
@@ -21,17 +21,20 @@ class EnclaveAccessMaintainerTest {
void test() {
ControllerTester tester = new ControllerTester();
MockEnclaveAccessService amis = tester.serviceRegistry().enclaveAccessService();
- EnclaveAccessMaintainer sharer = new EnclaveAccessMaintainer(tester.controller(), Duration.ofMinutes(1));
+ EnclaveAccessMaintainer sharer = new EnclaveAccessMaintainer(tester.controller(), Duration.ofHours(1));
+ CloudAccountVerifier accountVerifier = new CloudAccountVerifier(tester.controller(), Duration.ofHours(1));
assertEquals(Set.of(), amis.currentAccounts());
assertEquals(1, sharer.maintain());
assertEquals(Set.of(), amis.currentAccounts());
tester.createTenant("tanten");
+ accountVerifier.maintain();
assertEquals(1, sharer.maintain());
assertEquals(Set.of(), amis.currentAccounts());
tester.flagSource().withListFlag(PermanentFlags.CLOUD_ACCOUNTS.id(), List.of("123123123123", "321321321321"), String.class);
+ accountVerifier.maintain();
assertEquals(1, sharer.maintain());
assertEquals(Set.of(CloudAccount.from("aws:123123123123"), CloudAccount.from("aws:321321321321")), amis.currentAccounts());
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/maintenance.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/maintenance.json
index eb376a95c74..8b76613676c 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/maintenance.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/controller/responses/maintenance.json
@@ -34,6 +34,9 @@
"name": "ChangeRequestMaintainer"
},
{
+ "name": "CloudAccountVerifier"
+ },
+ {
"name": "CloudDatabaseMaintainer"
},
{
@@ -130,7 +133,5 @@
"name": "VersionStatusUpdater"
}
],
- "inactive": [
- "DeploymentExpirer"
- ]
+ "inactive": ["DeploymentExpirer"]
}