diff options
author | Jon Marius Venstad <jonmv@users.noreply.github.com> | 2022-11-16 14:42:45 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-16 14:42:45 +0100 |
commit | 9a65f43ecc761072b783fc2564de5235b411fecf (patch) | |
tree | f56898a7e2fecd9d371645e873329f9a1858ba86 | |
parent | a91a411a0893853fd6f62dfeb9f31ec14c896604 (diff) | |
parent | 9fc63cca18cab9e8f653ba2102351a8f16789aa1 (diff) |
Merge pull request #24888 from vespa-engine/jonmv/relax-cloud-account-requirements
Enclave access service
7 files changed, 133 insertions, 5 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/ServiceRegistry.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/ServiceRegistry.java index bf16913d05a..e49e9c7998e 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/ServiceRegistry.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/ServiceRegistry.java @@ -7,6 +7,7 @@ import com.yahoo.vespa.hosted.controller.api.identifiers.ControllerVersion; import com.yahoo.vespa.hosted.controller.api.integration.archive.ArchiveService; import com.yahoo.vespa.hosted.controller.api.integration.artifact.ArtifactRegistry; import com.yahoo.vespa.hosted.controller.api.integration.athenz.AccessControlService; +import com.yahoo.vespa.hosted.controller.api.integration.aws.EnclaveAccessService; import com.yahoo.vespa.hosted.controller.api.integration.aws.ResourceTagger; import com.yahoo.vespa.hosted.controller.api.integration.aws.RoleService; import com.yahoo.vespa.hosted.controller.api.integration.billing.BillingController; @@ -86,6 +87,8 @@ public interface ServiceRegistry { ResourceTagger resourceTagger(); + EnclaveAccessService enclaveAccessService(); + RoleService roleService(); SystemMonitor systemMonitor(); diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/EnclaveAccessService.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/EnclaveAccessService.java new file mode 100644 index 00000000000..52e8ba5adf8 --- /dev/null +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/EnclaveAccessService.java @@ -0,0 +1,15 @@ +package com.yahoo.vespa.hosted.controller.api.integration.aws; + +import com.yahoo.config.provision.CloudAccount; + +import java.util.Set; + +/** + * @author jonmv + */ +public interface EnclaveAccessService { + + /** Ensures the given enclave accounts have access to resources they require to function. */ + void allowAccessFor(Set<CloudAccount> accounts); + +} diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/MockEnclaveAccessService.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/MockEnclaveAccessService.java new file mode 100644 index 00000000000..95c69c6a8fa --- /dev/null +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/MockEnclaveAccessService.java @@ -0,0 +1,22 @@ +package com.yahoo.vespa.hosted.controller.api.integration.aws; + +import com.yahoo.config.provision.CloudAccount; + +import java.util.Set; +import java.util.TreeSet; + +/** + * @author jonmv + */ +public class MockEnclaveAccessService implements EnclaveAccessService { + + private volatile Set<CloudAccount> currentAccounts; + + public Set<CloudAccount> currentAccounts() { return currentAccounts; } + + @Override + public void allowAccessFor(Set<CloudAccount> accounts) { + currentAccounts = new TreeSet<>(accounts); + } + +} 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 9c6ab32a338..89ca31105bb 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 @@ -78,6 +78,7 @@ public class ControllerMaintenance extends AbstractComponent { maintainers.add(new UserManagementMaintainer(controller, intervals.userManagementMaintainer, controller.serviceRegistry().roleMaintainer())); maintainers.add(new BillingDatabaseMaintainer(controller, intervals.billingDatabaseMaintainer)); maintainers.add(new MeteringMonitorMaintainer(controller, intervals.meteringMonitorMaintainer, controller.serviceRegistry().resourceDatabase(), metric)); + maintainers.add(new EnclaveAccessMaintainer(controller, intervals.defaultInterval)); } public Upgrader upgrader() { return upgrader; } 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 new file mode 100644 index 00000000000..d9576f4e176 --- /dev/null +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/EnclaveAccessMaintainer.java @@ -0,0 +1,43 @@ +package com.yahoo.vespa.hosted.controller.maintenance; + +import com.yahoo.config.provision.CloudAccount; +import com.yahoo.vespa.hosted.controller.Controller; +import com.yahoo.vespa.hosted.controller.tenant.Tenant; + +import java.time.Duration; +import java.util.HashSet; +import java.util.Set; +import java.util.logging.Logger; + +import static java.util.logging.Level.WARNING; + +public class EnclaveAccessMaintainer extends ControllerMaintainer { + + private static final Logger logger = Logger.getLogger(EnclaveAccessMaintainer.class.getName()); + + EnclaveAccessMaintainer(Controller controller, Duration interval) { + super(controller, interval); + } + + @Override + protected double maintain() { + try { + controller().serviceRegistry().enclaveAccessService().allowAccessFor(externalAccounts()); + return 1; + } + catch (RuntimeException e) { + logger.log(WARNING, "Failed sharing AMIs", e); + return 0; + } + } + + private Set<CloudAccount> externalAccounts() { + Set<CloudAccount> accounts = new HashSet<>(); + for (Tenant tenant : controller().tenants().asList()) + accounts.addAll(controller().applications().accountsOf(tenant.name())); + + return accounts; + } + + +} diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ServiceRegistryMock.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ServiceRegistryMock.java index af542521b31..46c731e6e49 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ServiceRegistryMock.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/integration/ServiceRegistryMock.java @@ -15,10 +15,9 @@ import com.yahoo.vespa.hosted.controller.api.integration.archive.ArchiveService; import com.yahoo.vespa.hosted.controller.api.integration.archive.MockArchiveService; import com.yahoo.vespa.hosted.controller.api.integration.athenz.AccessControlService; import com.yahoo.vespa.hosted.controller.api.integration.athenz.MockAccessControlService; +import com.yahoo.vespa.hosted.controller.api.integration.aws.MockEnclaveAccessService; import com.yahoo.vespa.hosted.controller.api.integration.aws.MockResourceTagger; import com.yahoo.vespa.hosted.controller.api.integration.aws.MockRoleService; -import com.yahoo.vespa.hosted.controller.api.integration.aws.ResourceTagger; -import com.yahoo.vespa.hosted.controller.api.integration.aws.RoleService; import com.yahoo.vespa.hosted.controller.api.integration.billing.BillingController; import com.yahoo.vespa.hosted.controller.api.integration.billing.BillingDatabaseClient; import com.yahoo.vespa.hosted.controller.api.integration.billing.BillingDatabaseClientMock; @@ -79,8 +78,9 @@ public class ServiceRegistryMock extends AbstractComponent implements ServiceReg private final MockTesterCloud mockTesterCloud; private final ApplicationStoreMock applicationStoreMock = new ApplicationStoreMock(); private final MockRunDataStore mockRunDataStore = new MockRunDataStore(); + private final MockEnclaveAccessService mockAMIService = new MockEnclaveAccessService(); private final MockResourceTagger mockResourceTagger = new MockResourceTagger(); - private final RoleService roleService = new MockRoleService(); + private final MockRoleService roleService = new MockRoleService(); private final BillingController billingController = new MockBillingController(clock); private final ArtifactRegistryMock containerRegistry = new ArtifactRegistryMock(); private final NoopTenantSecretService tenantSecretService = new NoopTenantSecretService(); @@ -206,12 +206,17 @@ public class ServiceRegistryMock extends AbstractComponent implements ServiceReg } @Override - public ResourceTagger resourceTagger() { + public MockResourceTagger resourceTagger() { return mockResourceTagger; } @Override - public RoleService roleService() { + public MockEnclaveAccessService enclaveAccessService() { + return mockAMIService; + } + + @Override + public MockRoleService roleService() { return roleService; } 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 new file mode 100644 index 00000000000..f5188d52db6 --- /dev/null +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/EnclaveAccessMaintainerTest.java @@ -0,0 +1,39 @@ +package com.yahoo.vespa.hosted.controller.maintenance; + +import com.yahoo.config.provision.CloudAccount; +import com.yahoo.vespa.flags.PermanentFlags; +import com.yahoo.vespa.hosted.controller.ControllerTester; +import com.yahoo.vespa.hosted.controller.api.integration.aws.MockEnclaveAccessService; +import org.junit.jupiter.api.Test; + +import java.time.Duration; +import java.util.List; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * @author jonmv + */ +class EnclaveAccessMaintainerTest { + + @Test + void test() { + ControllerTester tester = new ControllerTester(); + MockEnclaveAccessService amis = tester.serviceRegistry().enclaveAccessService(); + EnclaveAccessMaintainer sharer = new EnclaveAccessMaintainer(tester.controller(), Duration.ofMinutes(1)); + assertEquals(Set.of(), amis.currentAccounts()); + + assertEquals(1, sharer.maintain()); + assertEquals(Set.of(), amis.currentAccounts()); + + tester.createTenant("tanten"); + assertEquals(1, sharer.maintain()); + assertEquals(Set.of(), amis.currentAccounts()); + + tester.flagSource().withListFlag(PermanentFlags.CLOUD_ACCOUNTS.id(), List.of("123123123123", "321321321321"), String.class); + assertEquals(1, sharer.maintain()); + assertEquals(Set.of(CloudAccount.from("123123123123"), CloudAccount.from("321321321321")), amis.currentAccounts()); + } + +} |