diff options
8 files changed, 54 insertions, 33 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 4006d68ba1f..d35f8f00fd1 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 @@ -1,7 +1,7 @@ // Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.controller.api.integration; -import com.yahoo.vespa.hosted.controller.api.integration.aws.ApplicationRoleService; +import com.yahoo.vespa.hosted.controller.api.integration.aws.RoleService; import com.yahoo.vespa.hosted.controller.api.integration.aws.AwsEventFetcher; import com.yahoo.vespa.hosted.controller.api.integration.aws.ResourceTagger; import com.yahoo.vespa.hosted.controller.api.integration.billing.BillingController; @@ -74,7 +74,7 @@ public interface ServiceRegistry { ResourceTagger resourceTagger(); - ApplicationRoleService applicationRoleService(); + RoleService roleService(); SystemMonitor systemMonitor(); diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/NoopApplicationRoleService.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/NoopRoleService.java index 4842389bccb..81fec1582d0 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/NoopApplicationRoleService.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/NoopRoleService.java @@ -2,16 +2,27 @@ package com.yahoo.vespa.hosted.controller.api.integration.aws; import com.yahoo.config.provision.ApplicationId; +import com.yahoo.config.provision.TenantName; import java.util.Optional; /** * @author mortent */ -public class NoopApplicationRoleService implements ApplicationRoleService { +public class NoopRoleService implements RoleService { @Override public Optional<ApplicationRoles> createApplicationRoles(ApplicationId applicationId) { return Optional.empty(); } + + @Override + public String createTenantRole(TenantName tenant) { + return ""; + } + + @Override + public String createTenantPolicy(TenantName tenant, String policyName, String awsId, String role) { + return ""; + } } diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/ApplicationRoleService.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/RoleService.java index e72ba5823d8..93c86c406b4 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/ApplicationRoleService.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/aws/RoleService.java @@ -2,12 +2,19 @@ package com.yahoo.vespa.hosted.controller.api.integration.aws; import com.yahoo.config.provision.ApplicationId; +import com.yahoo.config.provision.TenantName; import java.util.Optional; /** * @author mortent */ -public interface ApplicationRoleService { +public interface RoleService { + Optional<ApplicationRoles> createApplicationRoles(ApplicationId applicationId); + + String createTenantRole(TenantName tenant); + + String createTenantPolicy(TenantName tenant, String policyName, String awsId, String role); + } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java index 8447353a869..5eb7fb6e03d 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java @@ -131,7 +131,6 @@ public class ApplicationController { private final ApplicationPackageValidator applicationPackageValidator; private final EndpointCertificateManager endpointCertificateManager; private final StringFlag dockerImageRepoFlag; - private final BooleanFlag provisionApplicationRoles; private final BillingController billingController; ApplicationController(Controller controller, CuratorDb curator, AccessControl accessControl, Clock clock, @@ -145,7 +144,6 @@ public class ApplicationController { this.artifactRepository = controller.serviceRegistry().artifactRepository(); this.applicationStore = controller.serviceRegistry().applicationStore(); this.dockerImageRepoFlag = PermanentFlags.DOCKER_IMAGE_REPO.bindTo(flagSource); - this.provisionApplicationRoles = Flags.PROVISION_APPLICATION_ROLES.bindTo(flagSource); this.billingController = billingController; deploymentTrigger = new DeploymentTrigger(controller, clock); @@ -403,15 +401,6 @@ public class ApplicationController { endpoints = controller.routing().registerEndpointsInDns(application.get(), job.application().instance(), zone); - // Provision application roles if enabled for the zone - if (provisionApplicationRoles.with(FetchVector.Dimension.ZONE_ID, zone.value()).value()) { - try { - applicationRoles = controller.serviceRegistry().applicationRoleService().createApplicationRoles(instance.id()); - } catch (Exception e) { - log.log(Level.SEVERE, "Exception creating application roles for application: " + instance.id(), e); - throw new RuntimeException("Unable to provision iam roles for application"); - } - } } // Release application lock while doing the deployment, which is a lengthy task. // Carry out deployment without holding the application lock. diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Controller.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Controller.java index aa5f0ae0fdc..ffe80866086 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Controller.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Controller.java @@ -111,7 +111,7 @@ public class Controller extends AbstractComponent { nameServiceForwarder = new NameServiceForwarder(curator); jobController = new JobController(this); applicationController = new ApplicationController(this, curator, accessControl, clock, secretStore, flagSource, serviceRegistry.billingController()); - tenantController = new TenantController(this, curator, accessControl); + tenantController = new TenantController(this, curator, accessControl, flagSource); routingController = new RoutingController(this, Objects.requireNonNull(rotationsConfig, "RotationsConfig cannot be null")); auditLogger = new AuditLogger(curator, clock); jobControl = new JobControl(new JobControlFlags(curator, flagSource)); 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 4c9cf4f105f..d3992290f20 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 @@ -3,6 +3,10 @@ package com.yahoo.vespa.hosted.controller; import com.yahoo.config.provision.TenantName; import com.yahoo.vespa.curator.Lock; +import com.yahoo.vespa.flags.BooleanFlag; +import com.yahoo.vespa.flags.FetchVector; +import com.yahoo.vespa.flags.FlagSource; +import com.yahoo.vespa.flags.Flags; import com.yahoo.vespa.hosted.controller.api.identifiers.TenantId; import com.yahoo.vespa.hosted.controller.athenz.impl.AthenzFacade; import com.yahoo.vespa.hosted.controller.concurrent.Once; @@ -37,11 +41,15 @@ public class TenantController { private final Controller controller; private final CuratorDb curator; private final AccessControl accessControl; + private final BooleanFlag provisionTenantRoles; - public TenantController(Controller controller, CuratorDb curator, AccessControl accessControl) { + + public TenantController(Controller controller, CuratorDb curator, AccessControl accessControl, FlagSource flagSource) { this.controller = Objects.requireNonNull(controller, "controller must be non-null"); this.curator = Objects.requireNonNull(curator, "curator must be non-null"); this.accessControl = accessControl; + this.provisionTenantRoles = Flags.PROVISION_TENANT_ROLES.bindTo(flagSource); + // Update serialization format of all tenants Once.after(Duration.ofMinutes(1), () -> { @@ -101,6 +109,16 @@ public class TenantController { requireNonExistent(tenantSpec.tenant()); TenantId.validate(tenantSpec.tenant().value()); curator.writeTenant(accessControl.createTenant(tenantSpec, controller.clock().instant(), credentials, asList())); + + // Provision tenant role if enabled + if (provisionTenantRoles.with(FetchVector.Dimension.TENANT_ID, tenantSpec.tenant().value()).value()) { + try { + controller.serviceRegistry().roleService().createTenantRole(tenantSpec.tenant()); + } catch (Exception e) { + throw new RuntimeException("Unable to create tenant role for tenant: " + tenantSpec.tenant()); + } + } + } } 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 ae1e2c38e6a..fd0e7c20896 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 @@ -7,10 +7,10 @@ import com.yahoo.component.AbstractComponent; import com.yahoo.config.provision.SystemName; import com.yahoo.test.ManualClock; import com.yahoo.vespa.hosted.controller.api.integration.ServiceRegistry; -import com.yahoo.vespa.hosted.controller.api.integration.aws.ApplicationRoleService; +import com.yahoo.vespa.hosted.controller.api.integration.aws.RoleService; import com.yahoo.vespa.hosted.controller.api.integration.aws.MockAwsEventFetcher; import com.yahoo.vespa.hosted.controller.api.integration.aws.MockResourceTagger; -import com.yahoo.vespa.hosted.controller.api.integration.aws.NoopApplicationRoleService; +import com.yahoo.vespa.hosted.controller.api.integration.aws.NoopRoleService; import com.yahoo.vespa.hosted.controller.api.integration.aws.ResourceTagger; import com.yahoo.vespa.hosted.controller.api.integration.billing.BillingController; import com.yahoo.vespa.hosted.controller.api.integration.billing.MockBillingController; @@ -58,7 +58,7 @@ public class ServiceRegistryMock extends AbstractComponent implements ServiceReg private final ApplicationStoreMock applicationStoreMock = new ApplicationStoreMock(); private final MockRunDataStore mockRunDataStore = new MockRunDataStore(); private final MockResourceTagger mockResourceTagger = new MockResourceTagger(); - private final ApplicationRoleService applicationRoleService = new NoopApplicationRoleService(); + private final RoleService roleService = new NoopRoleService(); private final BillingController billingController = new MockBillingController(); private final ContainerRegistryMock containerRegistry = new ContainerRegistryMock(); @@ -178,8 +178,8 @@ public class ServiceRegistryMock extends AbstractComponent implements ServiceReg } @Override - public ApplicationRoleService applicationRoleService() { - return applicationRoleService; + public RoleService roleService() { + return roleService; } @Override diff --git a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java index 075166e4759..c5a9eb5ca5f 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java @@ -12,11 +12,7 @@ import java.util.List; import java.util.Optional; import java.util.TreeMap; -import static com.yahoo.vespa.flags.FetchVector.Dimension.APPLICATION_ID; -import static com.yahoo.vespa.flags.FetchVector.Dimension.HOSTNAME; -import static com.yahoo.vespa.flags.FetchVector.Dimension.NODE_TYPE; -import static com.yahoo.vespa.flags.FetchVector.Dimension.VESPA_VERSION; -import static com.yahoo.vespa.flags.FetchVector.Dimension.ZONE_ID; +import static com.yahoo.vespa.flags.FetchVector.Dimension.*; /** * Definitions of feature flags. @@ -140,19 +136,19 @@ public class Flags { "Override the default dist host for yum.", "Takes effect on next tick or on host-admin restart (may vary where used)."); - public static final UnboundBooleanFlag PROVISION_APPLICATION_ROLES = defineFeatureFlag( - "provision-application-roles", false, + public static final UnboundBooleanFlag PROVISION_TENANT_ROLES = defineFeatureFlag( + "provision-tenant-roles", false, List.of("tokle"), "2020-12-02", "2021-04-01", - "Whether application roles should be provisioned", + "Whether tenant roles should be provisioned", "Takes effect on next deployment (controller)", - ZONE_ID); + TENANT_ID); - public static final UnboundBooleanFlag APPLICATION_IAM_ROLE = defineFeatureFlag( + public static final UnboundBooleanFlag TENANT_IAM_ROLE = defineFeatureFlag( "application-iam-roles", false, List.of("tokle"), "2020-12-02", "2021-04-01", "Allow separate iam roles when provisioning/assigning hosts", "Takes effect immediately on new hosts, on next redeploy for applications", - APPLICATION_ID); + TENANT_ID); public static final UnboundIntFlag MAX_TRIAL_TENANTS = defineIntFlag( "max-trial-tenants", -1, |