diff options
author | jonmv <venstad@gmail.com> | 2022-11-16 13:58:45 +0100 |
---|---|---|
committer | jonmv <venstad@gmail.com> | 2022-11-16 13:58:45 +0100 |
commit | b3a445ba16c0c834b71feb01a0ec6dc6eee3577f (patch) | |
tree | 0406bf2b49c3330f5342a8c40e0820c869d6db77 | |
parent | 7f2f6aff04c8aafc038c55a3aa288b57eeb47d2d (diff) |
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..1da8e5bf761 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 amiService(); + 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..44d7712c243 --- /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 { + + /** Makes the current AMIs available to the given accounts. */ + 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/AMISharer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/AMISharer.java new file mode 100644 index 00000000000..bfd0d71d110 --- /dev/null +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/AMISharer.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 AMISharer extends ControllerMaintainer { + + private static final Logger logger = Logger.getLogger(AMISharer.class.getName()); + + AMISharer(Controller controller, Duration interval) { + super(controller, interval); + } + + @Override + protected double maintain() { + try { + controller().serviceRegistry().amiService().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/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..dc62511e5e2 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 AMISharer(controller, intervals.defaultInterval)); } public Upgrader upgrader() { return upgrader; } 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..fd3d17ce7dd 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 amiService() { + return mockAMIService; + } + + @Override + public MockRoleService roleService() { return roleService; } diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/AMISharerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/AMISharerTest.java new file mode 100644 index 00000000000..77596d54b85 --- /dev/null +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/AMISharerTest.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 AMISharerTest { + + @Test + void test() { + ControllerTester tester = new ControllerTester(); + MockEnclaveAccessService amis = tester.serviceRegistry().amiService(); + AMISharer sharer = new AMISharer(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()); + } + +} |