aboutsummaryrefslogtreecommitdiffstats
path: root/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java
diff options
context:
space:
mode:
Diffstat (limited to 'controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java')
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java39
1 files changed, 18 insertions, 21 deletions
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 08a8440fbe2..eedc94c729c 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
@@ -10,6 +10,7 @@ import com.yahoo.config.application.api.ValidationId;
import com.yahoo.config.application.api.ValidationOverrides;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.CloudAccount;
+import com.yahoo.config.provision.CloudName;
import com.yahoo.config.provision.DockerImage;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.TenantName;
@@ -694,24 +695,22 @@ public class ApplicationController {
public Optional<CloudAccount> decideCloudAccountOf(DeploymentId deployment, DeploymentSpec spec) {
ZoneId zoneId = deployment.zoneId();
- Optional<CloudAccount> requestedAccount = spec.instance(deployment.applicationId().instance())
- .flatMap(instanceSpec -> instanceSpec.cloudAccount(zoneId.environment(),
- Optional.of(zoneId.region())))
- .or(spec::cloudAccount);
- if (requestedAccount.isEmpty() || requestedAccount.get().isUnspecified()) {
+ CloudName cloud = controller.zoneRegistry().get(zoneId).getCloudName();
+ CloudAccount requestedAccount = spec.cloudAccount(cloud, deployment.applicationId().instance(), deployment.zoneId());
+ if (requestedAccount.isUnspecified())
return Optional.empty();
- }
+
TenantName tenant = deployment.applicationId().tenant();
Set<CloudAccount> tenantAccounts = accountsOf(tenant);
- if (!tenantAccounts.contains(requestedAccount.get())) {
- throw new IllegalArgumentException("Requested cloud account '" + requestedAccount.get().value() +
+ if ( ! tenantAccounts.contains(requestedAccount)) {
+ throw new IllegalArgumentException("Requested cloud account '" + requestedAccount.value() +
"' is not valid for tenant '" + tenant + "'");
}
- if ( ! controller.zoneRegistry().hasZone(zoneId, requestedAccount.get())) {
+ if ( ! controller.zoneRegistry().hasZone(zoneId, requestedAccount)) {
throw new IllegalArgumentException("Zone " + zoneId + " is not configured in requested cloud account '" +
- requestedAccount.get().value() + "'");
+ requestedAccount.value() + "'");
}
- return requestedAccount;
+ return Optional.of(requestedAccount);
}
private LockedApplication withoutDeletedDeployments(LockedApplication application, InstanceName instance) {
@@ -948,7 +947,7 @@ public class ApplicationController {
* @param applicationPackage application package
* @param deployer principal initiating the deployment, possibly empty
*/
- public void verifyApplicationIdentityConfiguration(TenantName tenantName, Optional<InstanceName> instanceName, Optional<ZoneId> zoneId, ApplicationPackage applicationPackage, Optional<Principal> deployer) {
+ public void verifyApplicationIdentityConfiguration(TenantName tenantName, Optional<DeploymentId> deployment, ApplicationPackage applicationPackage, Optional<Principal> deployer) {
Optional<AthenzDomain> identityDomain = applicationPackage.deploymentSpec().athenzDomain()
.map(domain -> new AthenzDomain(domain.value()));
if (identityDomain.isEmpty()) {
@@ -969,14 +968,12 @@ public class ApplicationController {
// Either the user is member of the domain admin role, or is given the "launch" privilege on the service.
Optional<AthenzUser> athenzUser = getUser(deployer);
if (athenzUser.isPresent()) {
- // We only need to validate the root and instance in deployment.xml. Dev/perf entries are found at the instance level as well.
- var zone = zoneId.orElseThrow(() -> new IllegalArgumentException("Unable to evaluate access, no zone provided in deployment"));
- var serviceToLaunch = instanceName
- .flatMap(instance -> applicationPackage.deploymentSpec().instance(instance))
- .flatMap(instanceSpec -> instanceSpec.athenzService(zone.environment(), zone.region()))
- .or(() -> applicationPackage.deploymentSpec().athenzService())
- .map(service -> new AthenzService(identityDomain.get(), service.value()));
-
+ // This is a direct deployment, and we need only validate what the configserver will actually launch.
+ DeploymentId id = deployment.orElseThrow(() -> new IllegalArgumentException("Unable to evaluate access, no zone provided in deployment"));
+ var serviceToLaunch = applicationPackage.deploymentSpec().athenzService(id.applicationId().instance(),
+ id.zoneId().environment(),
+ id.zoneId().region())
+ .map(service -> new AthenzService(identityDomain.get(), service.value()));
if (serviceToLaunch.isPresent()) {
if (
! ((AthenzFacade) accessControl).canLaunch(athenzUser.get(), serviceToLaunch.get()) && // launch privilege
@@ -989,7 +986,7 @@ public class ApplicationController {
} else {
// This is a rare edge case where deployment.xml specifies athenz-service on each step, but not on the root.
// It is undefined which service should be launched, so handle this as an error.
- throw new IllegalArgumentException("Athenz domain configured, but no service defined for deployment to " + zone.value());
+ throw new IllegalArgumentException("Athenz domain configured, but no service defined for deployment to " + id.zoneId().value());
}
} else {
// If this is a deployment pipeline, verify that the domain in deployment.xml is the same as the tenant domain. Access control is already validated before this step.