summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMorten Tokle <mortent@verizonmedia.com>2020-05-13 12:41:47 +0200
committerMorten Tokle <mortent@verizonmedia.com>2020-05-18 10:29:28 +0200
commitefd71d02a2d65c12022b62011ace1ceca7f6ef8a (patch)
tree262f0f939e65c5a56faa3db2a075c9f27b157f83
parentdfa23cab41d83b7c21a34d199e747fe8e5747ea3 (diff)
Provision application roles and include in cfg deployment
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/application/v4/model/DeploymentData.java10
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java29
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/Flags.java6
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",