diff options
author | Morten Tokle <mortent@verizonmedia.com> | 2020-05-13 12:41:47 +0200 |
---|---|---|
committer | Morten Tokle <mortent@verizonmedia.com> | 2020-05-18 10:29:28 +0200 |
commit | efd71d02a2d65c12022b62011ace1ceca7f6ef8a (patch) | |
tree | 262f0f939e65c5a56faa3db2a075c9f27b157f83 | |
parent | dfa23cab41d83b7c21a34d199e747fe8e5747ea3 (diff) |
Provision application roles and include in cfg deployment
3 files changed, 37 insertions, 8 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/application/v4/model/DeploymentData.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/application/v4/model/DeploymentData.java index 0afe9347341..a74d1f34da0 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/application/v4/model/DeploymentData.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/application/v4/model/DeploymentData.java @@ -5,6 +5,7 @@ import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.DockerImage; import com.yahoo.config.provision.zone.ZoneId; import com.yahoo.vespa.athenz.api.AthenzDomain; +import com.yahoo.vespa.hosted.controller.api.integration.aws.ApplicationRoles; import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateMetadata; import com.yahoo.vespa.hosted.controller.api.integration.configserver.ContainerEndpoint; @@ -28,12 +29,14 @@ public class DeploymentData { private final Optional<EndpointCertificateMetadata> endpointCertificateMetadata; private final Optional<DockerImage> dockerImageRepo; private final Optional<AthenzDomain> athenzDomain; + private final Optional<ApplicationRoles> applicationRoles; public DeploymentData(ApplicationId instance, ZoneId zone, byte[] applicationPackage, Version platform, Set<ContainerEndpoint> containerEndpoints, Optional<EndpointCertificateMetadata> endpointCertificateMetadata, Optional<DockerImage> dockerImageRepo, - Optional<AthenzDomain> athenzDomain) { + Optional<AthenzDomain> athenzDomain, + Optional<ApplicationRoles> applicationRoles) { this.instance = requireNonNull(instance); this.zone = requireNonNull(zone); this.applicationPackage = requireNonNull(applicationPackage); @@ -42,6 +45,7 @@ public class DeploymentData { this.endpointCertificateMetadata = requireNonNull(endpointCertificateMetadata); this.dockerImageRepo = requireNonNull(dockerImageRepo); this.athenzDomain = athenzDomain; + this.applicationRoles = applicationRoles; } public ApplicationId instance() { @@ -75,4 +79,8 @@ public class DeploymentData { public Optional<AthenzDomain> athenzDomain() { return athenzDomain; } + + public Optional<ApplicationRoles> applicationRoles() { + return applicationRoles; + } } 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 e02c1b9f5dd..6a69fae3693 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 @@ -18,6 +18,7 @@ import com.yahoo.vespa.athenz.api.AthenzPrincipal; import com.yahoo.vespa.athenz.api.AthenzService; import com.yahoo.vespa.athenz.api.AthenzUser; 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; @@ -30,6 +31,7 @@ import com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId; import com.yahoo.vespa.hosted.controller.api.identifiers.Hostname; import com.yahoo.vespa.hosted.controller.api.identifiers.InstanceId; import com.yahoo.vespa.hosted.controller.api.identifiers.RevisionId; +import com.yahoo.vespa.hosted.controller.api.integration.aws.ApplicationRoles; import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateMetadata; import com.yahoo.vespa.hosted.controller.api.integration.configserver.ConfigServer; import com.yahoo.vespa.hosted.controller.api.integration.configserver.ConfigServerException; @@ -51,11 +53,11 @@ import com.yahoo.vespa.hosted.controller.application.DeploymentMetrics; import com.yahoo.vespa.hosted.controller.application.SystemApplication; import com.yahoo.vespa.hosted.controller.application.TenantAndApplicationId; import com.yahoo.vespa.hosted.controller.athenz.impl.AthenzFacade; +import com.yahoo.vespa.hosted.controller.certificate.EndpointCertificateManager; import com.yahoo.vespa.hosted.controller.concurrent.Once; import com.yahoo.vespa.hosted.controller.deployment.DeploymentTrigger; import com.yahoo.vespa.hosted.controller.deployment.Run; import com.yahoo.vespa.hosted.controller.deployment.Versions; -import com.yahoo.vespa.hosted.controller.certificate.EndpointCertificateManager; import com.yahoo.vespa.hosted.controller.persistence.CuratorDb; import com.yahoo.vespa.hosted.controller.security.AccessControl; import com.yahoo.vespa.hosted.controller.security.Credentials; @@ -113,6 +115,7 @@ public class ApplicationController { private final ApplicationPackageValidator applicationPackageValidator; private final EndpointCertificateManager endpointCertificateManager; private final StringFlag dockerImageRepoFlag; + private final BooleanFlag provisionApplicationRoles; ApplicationController(Controller controller, CuratorDb curator, AccessControl accessControl, Clock clock, SecretStore secretStore, FlagSource flagSource) { @@ -125,6 +128,7 @@ public class ApplicationController { this.artifactRepository = controller.serviceRegistry().artifactRepository(); this.applicationStore = controller.serviceRegistry().applicationStore(); this.dockerImageRepoFlag = Flags.DOCKER_IMAGE_REPO.bindTo(flagSource); + this.provisionApplicationRoles = Flags.PROVISION_APPLICATION_ROLES.bindTo(flagSource); deploymentTrigger = new DeploymentTrigger(controller, clock); applicationPackageValidator = new ApplicationPackageValidator(controller); @@ -298,6 +302,7 @@ public class ApplicationController { try (Lock deploymentLock = lockForDeployment(job.application(), zone)) { Set<ContainerEndpoint> endpoints; Optional<EndpointCertificateMetadata> endpointCertificateMetadata; + Optional<ApplicationRoles> applicationRoles = Optional.empty(); Run run = controller.jobController().last(job) .orElseThrow(() -> new IllegalStateException("No known run of '" + job + "'")); @@ -328,10 +333,19 @@ public class ApplicationController { endpointCertificateMetadata = endpointCertificateManager.getEndpointCertificateMetadata(instance, zone); 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); + } + } } // Release application lock while doing the deployment, which is a lengthy task. // Carry out deployment without holding the application lock. - ActivateResult result = deploy(job.application(), applicationPackage, zone, platform, endpoints, endpointCertificateMetadata); + ActivateResult result = deploy(job.application(), applicationPackage, zone, platform, endpoints, endpointCertificateMetadata, applicationRoles); lockApplicationOrThrow(applicationId, application -> store(application.with(job.application().instance(), @@ -405,7 +419,7 @@ public class ApplicationController { // Carry out deployment without holding the application lock. ActivateResult result = deploy(instanceId, applicationPackage, zone, platformVersion, - endpoints, endpointCertificateMetadata); + endpoints, endpointCertificateMetadata, Optional.empty()); lockApplicationOrThrow(applicationId, application -> store(application.with(instanceId.instance(), @@ -477,7 +491,7 @@ public class ApplicationController { ApplicationPackage applicationPackage = new ApplicationPackage( artifactRepository.getSystemApplicationPackage(application.id(), zone, version) ); - return deploy(application.id(), applicationPackage, zone, version, Set.of(), /* No application cert */ Optional.empty()); + return deploy(application.id(), applicationPackage, zone, version, Set.of(), /* No application cert */ Optional.empty(), Optional.empty()); } else { throw new RuntimeException("This system application does not have an application package: " + application.id().toShortString()); } @@ -485,12 +499,13 @@ public class ApplicationController { /** Deploys the given tester application to the given zone. */ public ActivateResult deployTester(TesterId tester, ApplicationPackage applicationPackage, ZoneId zone, Version platform) { - return deploy(tester.id(), applicationPackage, zone, platform, Set.of(), /* No application cert for tester*/ Optional.empty()); + return deploy(tester.id(), applicationPackage, zone, platform, Set.of(), /* No application cert for tester*/ Optional.empty(), Optional.empty()); } private ActivateResult deploy(ApplicationId application, ApplicationPackage applicationPackage, ZoneId zone, Version platform, Set<ContainerEndpoint> endpoints, - Optional<EndpointCertificateMetadata> endpointCertificateMetadata) { + Optional<EndpointCertificateMetadata> endpointCertificateMetadata, + Optional<ApplicationRoles> applicationRoles) { try { Optional<DockerImage> dockerImageRepo = Optional.ofNullable( dockerImageRepoFlag @@ -506,7 +521,7 @@ public class ApplicationController { ConfigServer.PreparedApplication preparedApplication = configServer.deploy(new DeploymentData(application, zone, applicationPackage.zippedContent(), platform, - endpoints, endpointCertificateMetadata, dockerImageRepo, domain)); + endpoints, endpointCertificateMetadata, dockerImageRepo, domain, applicationRoles)); return new ActivateResult(new RevisionId(applicationPackage.hash()), preparedApplication.prepareResponse(), applicationPackage.zippedContent().length); } finally { 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 149c03710aa..5a6aed05960 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java @@ -276,6 +276,12 @@ public class Flags { "Whether the application package should be distributed to other config servers during a deployment", "Takes effect immediately"); + public static final UnboundBooleanFlag PROVISION_APPLICATION_ROLES = defineFeatureFlag( + "provision-application-roles", false, + "Whether application roles should be provisioned", + "Takes effect on next deployment (controller)", + ZONE_ID); + public static final UnboundBooleanFlag CONFIGSERVER_UNSET_ENDPOINTS = defineFeatureFlag( "configserver-unset-endpoints", false, "Whether the configserver allows removal of existing endpoints when an empty list of container endpoints is request", |