diff options
author | Jon Marius Venstad <jonmv@users.noreply.github.com> | 2022-09-09 16:38:46 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-09 16:38:46 +0200 |
commit | e5d1a7eaa19fc5353c32129352a790cf64f057dc (patch) | |
tree | 58eb7a33c79d80d6381987eb0418c379c5452140 /controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application | |
parent | 454146ba533344208cfa6a5824579fd512ced376 (diff) |
Revert "Allow setting cloud account for non-production environments"
Diffstat (limited to 'controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application')
-rw-r--r-- | controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/pkg/ApplicationPackageValidator.java | 46 |
1 files changed, 42 insertions, 4 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/pkg/ApplicationPackageValidator.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/pkg/ApplicationPackageValidator.java index 8e8a4e24970..5a131ba4a29 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/pkg/ApplicationPackageValidator.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/pkg/ApplicationPackageValidator.java @@ -7,12 +7,17 @@ import com.yahoo.config.application.api.DeploymentSpec; import com.yahoo.config.application.api.Endpoint; import com.yahoo.config.application.api.ValidationId; import com.yahoo.config.application.api.ValidationOverrides; +import com.yahoo.config.provision.CloudAccount; import com.yahoo.config.provision.CloudName; import com.yahoo.config.provision.Environment; import com.yahoo.config.provision.InstanceName; import com.yahoo.config.provision.RegionName; +import com.yahoo.config.provision.TenantName; import com.yahoo.config.provision.zone.ZoneApi; import com.yahoo.config.provision.zone.ZoneId; +import com.yahoo.vespa.flags.FetchVector; +import com.yahoo.vespa.flags.ListFlag; +import com.yahoo.vespa.flags.PermanentFlags; import com.yahoo.vespa.hosted.controller.Application; import com.yahoo.vespa.hosted.controller.Controller; import com.yahoo.vespa.hosted.controller.application.EndpointId; @@ -26,6 +31,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; /** @@ -36,9 +42,11 @@ import java.util.stream.Collectors; public class ApplicationPackageValidator { private final Controller controller; + private final ListFlag<String> cloudAccountsFlag; public ApplicationPackageValidator(Controller controller) { this.controller = Objects.requireNonNull(controller, "controller must be non-null"); + this.cloudAccountsFlag = PermanentFlags.CLOUD_ACCOUNTS.bindTo(controller.flagSource()); } /** @@ -47,6 +55,7 @@ public class ApplicationPackageValidator { * @throws IllegalArgumentException if any validations fail */ public void validate(Application application, ApplicationPackage applicationPackage, Instant instant) { + validateCloudAccounts(application, applicationPackage.deploymentSpec()); validateSteps(applicationPackage.deploymentSpec()); validateEndpointRegions(applicationPackage.deploymentSpec()); validateEndpointChange(application, applicationPackage, instant); @@ -81,10 +90,20 @@ public class ApplicationPackageValidator { for (var spec : deploymentSpec.instances()) { for (var zone : spec.zones()) { Environment environment = zone.environment(); - if (zone.region().isEmpty()) continue; - ZoneId zoneId = ZoneId.from(environment, zone.region().get()); - if (!controller.zoneRegistry().hasZone(zoneId)) { - throw new IllegalArgumentException("Zone " + zone + " in deployment spec was not found in this system!"); + if (environment.isManuallyDeployed()) + throw new IllegalArgumentException("region must be one with automated deployments, but got: " + environment); + + if (environment == Environment.prod) { + RegionName region = zone.region().orElseThrow(); + if (!controller.zoneRegistry().hasZone(ZoneId.from(environment, region))) { + throw new IllegalArgumentException("Zone " + zone + " in deployment spec was not found in this system!"); + } + Optional<CloudAccount> cloudAccount = spec.cloudAccount(environment, region); + if (cloudAccount.isPresent() && !controller.zoneRegistry().hasZone(ZoneId.from(environment, region), cloudAccount.get())) { + throw new IllegalArgumentException("Zone " + zone + " in deployment spec is not configured for " + + "use in cloud account '" + cloudAccount.get().value() + + "', in this system"); + } } } } @@ -166,6 +185,25 @@ public class ApplicationPackageValidator { ". " + ValidationOverrides.toAllowMessage(validationId)); } + /** Verify that declared cloud accounts are allowed to be used by the tenant */ + private void validateCloudAccounts(Application application, DeploymentSpec deploymentSpec) { + TenantName tenant = application.id().tenant(); + Set<CloudAccount> validAccounts = cloudAccountsFlag.with(FetchVector.Dimension.TENANT_ID, tenant.value()) + .value().stream() + .map(CloudAccount::new) + .collect(Collectors.toSet()); + for (var spec : deploymentSpec.instances()) { + for (var zone : spec.zones()) { + if (!zone.environment().isProduction()) continue; + Optional<CloudAccount> cloudAccount = spec.cloudAccount(zone.environment(), zone.region().get()); + if (cloudAccount.isEmpty()) continue; + if (validAccounts.contains(cloudAccount.get())) continue; + throw new IllegalArgumentException("Cloud account '" + cloudAccount.get().value() + + "' is not valid for tenant '" + tenant + "'"); + } + } + } + /** Returns whether newEndpoints contains all destinations in endpoints */ private static boolean containsAllDestinationsOf(List<Endpoint> endpoints, List<Endpoint> newEndpoints) { var containsAllRegions = true; |