diff options
author | Andreas Eriksen <andreer@verizonmedia.com> | 2020-08-26 09:03:10 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-26 09:03:10 +0200 |
commit | a0497ac0892be9f8372d5814cead725f656d29b7 (patch) | |
tree | fdd33c21a0239be47ea985f4e1640479e7084a5b | |
parent | 4746dcd27ad567eb6f00adf773e9ac8fd55ffd35 (diff) |
pass quota from plans to configserver (overridable by feature flag) (#14087)
* pass quota from plans to configserver (overridable by feature flag)
* make quota optional
6 files changed, 57 insertions, 6 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 a74d1f34da0..717a4296b81 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 @@ -6,6 +6,7 @@ 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.billing.Quota; import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateMetadata; import com.yahoo.vespa.hosted.controller.api.integration.configserver.ContainerEndpoint; @@ -30,13 +31,15 @@ public class DeploymentData { private final Optional<DockerImage> dockerImageRepo; private final Optional<AthenzDomain> athenzDomain; private final Optional<ApplicationRoles> applicationRoles; + private final Optional<Quota> quota; public DeploymentData(ApplicationId instance, ZoneId zone, byte[] applicationPackage, Version platform, Set<ContainerEndpoint> containerEndpoints, Optional<EndpointCertificateMetadata> endpointCertificateMetadata, Optional<DockerImage> dockerImageRepo, Optional<AthenzDomain> athenzDomain, - Optional<ApplicationRoles> applicationRoles) { + Optional<ApplicationRoles> applicationRoles, + Optional<Quota> quota) { this.instance = requireNonNull(instance); this.zone = requireNonNull(zone); this.applicationPackage = requireNonNull(applicationPackage); @@ -46,6 +49,7 @@ public class DeploymentData { this.dockerImageRepo = requireNonNull(dockerImageRepo); this.athenzDomain = athenzDomain; this.applicationRoles = applicationRoles; + this.quota = quota; } public ApplicationId instance() { @@ -83,4 +87,8 @@ public class DeploymentData { public Optional<ApplicationRoles> applicationRoles() { return applicationRoles; } + + public Optional<Quota> quota() { + return quota; + } } diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/BillingController.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/BillingController.java index a21c9f2a40e..c5b548b8e6c 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/BillingController.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/BillingController.java @@ -2,7 +2,6 @@ package com.yahoo.vespa.hosted.controller.api.integration.billing; import com.yahoo.config.provision.TenantName; -import com.yahoo.vespa.hosted.controller.api.identifiers.DeploymentId; import com.yahoo.vespa.hosted.controller.api.integration.user.User; import java.math.BigDecimal; @@ -17,6 +16,8 @@ public interface BillingController { PlanId getPlan(TenantName tenant); + Optional<Quota> getQuota(TenantName tenant); + /** * @return String containing error message if something went wrong. Empty otherwise */ diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/MockBillingController.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/MockBillingController.java index 24259a94ccf..62d32b1e848 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/MockBillingController.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/MockBillingController.java @@ -31,6 +31,11 @@ public class MockBillingController implements BillingController { } @Override + public Optional<Quota> getQuota(TenantName tenant) { + return Optional.of(new Quota(5)); + } + + @Override public PlanResult setPlan(TenantName tenant, PlanId planId, boolean hasDeployments) { plans.put(tenant, planId); return PlanResult.success(); diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/Quota.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/Quota.java new file mode 100644 index 00000000000..6f162a8275e --- /dev/null +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/Quota.java @@ -0,0 +1,32 @@ +package com.yahoo.vespa.hosted.controller.api.integration.billing; + +import java.util.Objects; + +/** + * Quota information transmitted to the configserver on deploy. + */ +public class Quota { + + private final int maxClusterSize; + + public Quota(int maxClusterSize) { + this.maxClusterSize = maxClusterSize; + } + + public int maxClusterSize() { + return maxClusterSize; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Quota quota = (Quota) o; + return maxClusterSize == quota.maxClusterSize; + } + + @Override + public int hashCode() { + return Objects.hash(maxClusterSize); + } +} 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 c03b38867f9..7ec8d5428dd 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 @@ -28,10 +28,11 @@ import com.yahoo.vespa.hosted.controller.api.application.v4.model.DeployOptions; import com.yahoo.vespa.hosted.controller.api.application.v4.model.DeploymentData; import com.yahoo.vespa.hosted.controller.api.application.v4.model.configserverbindings.ConfigChangeActions; 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.billing.BillingController; +import com.yahoo.vespa.hosted.controller.api.integration.billing.Quota; 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; @@ -117,9 +118,10 @@ public class ApplicationController { 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, - SecretStore secretStore, FlagSource flagSource) { + SecretStore secretStore, FlagSource flagSource, BillingController billingController) { this.controller = controller; this.curator = curator; @@ -130,6 +132,7 @@ public class ApplicationController { this.applicationStore = controller.serviceRegistry().applicationStore(); this.dockerImageRepoFlag = Flags.DOCKER_IMAGE_REPO.bindTo(flagSource); this.provisionApplicationRoles = Flags.PROVISION_APPLICATION_ROLES.bindTo(flagSource); + this.billingController = billingController; deploymentTrigger = new DeploymentTrigger(controller, clock); applicationPackageValidator = new ApplicationPackageValidator(controller); @@ -522,9 +525,11 @@ public class ApplicationController { .filter(tenant-> tenant instanceof AthenzTenant) .map(tenant -> ((AthenzTenant)tenant).domain()); + Optional<Quota> quota = billingController.getQuota(application.tenant()); + ConfigServer.PreparedApplication preparedApplication = configServer.deploy(new DeploymentData(application, zone, applicationPackage.zippedContent(), platform, - endpoints, endpointCertificateMetadata, dockerImageRepo, domain, applicationRoles)); + endpoints, endpointCertificateMetadata, dockerImageRepo, domain, applicationRoles, quota)); return new ActivateResult(new RevisionId(applicationPackage.hash()), preparedApplication.prepareResponse(), applicationPackage.zippedContent().length); } finally { 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 9750c322242..b0309957604 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 @@ -109,7 +109,7 @@ public class Controller extends AbstractComponent { metrics = new ConfigServerMetrics(serviceRegistry.configServer()); nameServiceForwarder = new NameServiceForwarder(curator); jobController = new JobController(this); - applicationController = new ApplicationController(this, curator, accessControl, clock, secretStore, flagSource); + applicationController = new ApplicationController(this, curator, accessControl, clock, secretStore, flagSource, serviceRegistry.billingController()); tenantController = new TenantController(this, curator, accessControl); routingController = new RoutingController(this, Objects.requireNonNull(rotationsConfig, "RotationsConfig cannot be null")); auditLogger = new AuditLogger(curator, clock); |