diff options
author | Valerij Fredriksen <valerijf@yahooinc.com> | 2023-03-03 11:32:23 +0100 |
---|---|---|
committer | Valerij Fredriksen <valerijf@yahooinc.com> | 2023-03-03 11:35:23 +0100 |
commit | 0636b9fc89039f6f663f6a73ea02b05daffdc452 (patch) | |
tree | 85258aa40c97ad57af0c4cef05ed467862716ab5 /controller-server | |
parent | 5ee812d587eb747b2de460c6cee64c72b60464c6 (diff) |
Store cloudAccount in Deployment
Diffstat (limited to 'controller-server')
7 files changed, 48 insertions, 37 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 d1545537d48..a1534ebc533 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 @@ -526,8 +526,8 @@ public class ApplicationController { }; // Carry out deployment without holding the application lock. - DeploymentResult result = deploy(job.application(), applicationPackage, zone, platform, containerEndpoints, - endpointCertificateMetadata, run.isDryRun(), run.testerCertificate()); + DeploymentDataAndResult dataAndResult = deploy(job.application(), applicationPackage, zone, platform, containerEndpoints, + endpointCertificateMetadata, run.isDryRun(), run.testerCertificate()); // Record the quota usage for this application @@ -540,7 +540,7 @@ public class ApplicationController { ? NotificationSource.from(deployment) : revision.equals(lastRevision.get()) ? NotificationSource.from(applicationId) : null; if (source != null) { - List<String> warnings = Optional.ofNullable(result.log()) + List<String> warnings = Optional.ofNullable(dataAndResult.result().log()) .map(logs -> logs.stream() .filter(LogEntry::concernsPackage) .filter(log -> log.level().intValue() >= Level.WARNING.intValue()) @@ -558,9 +558,9 @@ public class ApplicationController { lockApplicationOrThrow(applicationId, application -> store(application.with(job.application().instance(), i -> i.withNewDeployment(zone, revision, platform, - clock.instant(), warningsFrom(result.log()), - quotaUsage)))); - return result; + clock.instant(), warningsFrom(dataAndResult.result().log()), + quotaUsage, dataAndResult.data().cloudAccount().orElse(CloudAccount.empty))))); + return dataAndResult.result(); } } @@ -618,7 +618,7 @@ public class ApplicationController { ApplicationPackageStream applicationPackage = new ApplicationPackageStream( () -> new ByteArrayInputStream(artifactRepository.getSystemApplicationPackage(application.id(), zone, version)) ); - return deploy(application.id(), applicationPackage, zone, version, Set.of(), Optional::empty, false, Optional.empty()); + return deploy(application.id(), applicationPackage, zone, version, Set.of(), Optional::empty, false, Optional.empty()).result(); } else { throw new RuntimeException("This system application does not have an application package: " + application.id().toShortString()); } @@ -626,13 +626,14 @@ public class ApplicationController { /** Deploys the given tester application to the given zone. */ public DeploymentResult deployTester(TesterId tester, ApplicationPackageStream applicationPackage, ZoneId zone, Version platform) { - return deploy(tester.id(), applicationPackage, zone, platform, Set.of(), Optional::empty, false, Optional.empty()); + return deploy(tester.id(), applicationPackage, zone, platform, Set.of(), Optional::empty, false, Optional.empty()).result(); } - private DeploymentResult deploy(ApplicationId application, ApplicationPackageStream applicationPackage, - ZoneId zone, Version platform, Set<ContainerEndpoint> endpoints, - Supplier<Optional<EndpointCertificateMetadata>> endpointCertificateMetadata, - boolean dryRun, Optional<X509Certificate> testerCertificate) { + private record DeploymentDataAndResult(DeploymentData data, DeploymentResult result) {} + private DeploymentDataAndResult deploy(ApplicationId application, ApplicationPackageStream applicationPackage, + ZoneId zone, Version platform, Set<ContainerEndpoint> endpoints, + Supplier<Optional<EndpointCertificateMetadata>> endpointCertificateMetadata, + boolean dryRun, Optional<X509Certificate> testerCertificate) { DeploymentId deployment = new DeploymentId(application, zone); // Routing and metadata may have changed, so we need to refresh state after deployment, even if deployment fails. interface CleanCloseable extends AutoCloseable { void close(); } @@ -664,13 +665,12 @@ public class ApplicationController { operatorCertificates = Stream.concat(operatorCertificates.stream(), testerCertificate.stream()).toList(); } Supplier<Optional<CloudAccount>> cloudAccount = () -> decideCloudAccountOf(deployment, applicationPackage.truncatedPackage().deploymentSpec()); - ConfigServer.PreparedApplication preparedApplication = - configServer.deploy(new DeploymentData(application, zone, applicationPackage::zipStream, platform, - endpoints, endpointCertificateMetadata, dockerImageRepo, domain, - deploymentQuota, tenantSecretStores, operatorCertificates, - cloudAccount, dryRun)); + DeploymentData deploymentData = new DeploymentData(application, zone, applicationPackage::zipStream, platform, + endpoints, endpointCertificateMetadata, dockerImageRepo, domain, + deploymentQuota, tenantSecretStores, operatorCertificates, cloudAccount, dryRun); + ConfigServer.PreparedApplication preparedApplication = configServer.deploy(deploymentData); - return preparedApplication.deploymentResult(); + return new DeploymentDataAndResult(deploymentData, preparedApplication.deploymentResult()); } } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Instance.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Instance.java index d66d1491f73..14bd537a056 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Instance.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Instance.java @@ -3,6 +3,7 @@ package com.yahoo.vespa.hosted.controller; import com.yahoo.component.Version; import com.yahoo.config.provision.ApplicationId; +import com.yahoo.config.provision.CloudAccount; import com.yahoo.config.provision.Environment; import com.yahoo.config.provision.InstanceName; import com.yahoo.config.provision.zone.ZoneId; @@ -63,16 +64,16 @@ public class Instance { this.change = Objects.requireNonNull(change, "change cannot be null"); } - public Instance withNewDeployment(ZoneId zone, RevisionId revision, Version version, - Instant instant, Map<DeploymentMetrics.Warning, Integer> warnings, QuotaUsage quotaUsage) { + public Instance withNewDeployment(ZoneId zone, RevisionId revision, Version version, Instant instant, + Map<DeploymentMetrics.Warning, Integer> warnings, QuotaUsage quotaUsage, CloudAccount cloudAccount) { // Use info from previous deployment if available, otherwise create a new one. - Deployment previousDeployment = deployments.getOrDefault(zone, new Deployment(zone, revision, + Deployment previousDeployment = deployments.getOrDefault(zone, new Deployment(zone, cloudAccount, revision, version, instant, DeploymentMetrics.none, DeploymentActivity.none, QuotaUsage.none, OptionalDouble.empty())); - Deployment newDeployment = new Deployment(zone, revision, version, instant, + Deployment newDeployment = new Deployment(zone, cloudAccount, revision, version, instant, previousDeployment.metrics().with(warnings), previousDeployment.activity(), quotaUsage, diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/Deployment.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/Deployment.java index 2e4afb4e004..6d4fddfbc0a 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/Deployment.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/Deployment.java @@ -2,6 +2,7 @@ package com.yahoo.vespa.hosted.controller.application; import com.yahoo.component.Version; +import com.yahoo.config.provision.CloudAccount; import com.yahoo.config.provision.zone.ZoneId; import com.yahoo.vespa.hosted.controller.api.integration.deployment.RevisionId; @@ -18,6 +19,7 @@ import java.util.OptionalDouble; public class Deployment { private final ZoneId zone; + private final CloudAccount cloudAccount; private final RevisionId revision; private final Version version; private final Instant deployTime; @@ -26,9 +28,10 @@ public class Deployment { private final QuotaUsage quota; private final OptionalDouble cost; - public Deployment(ZoneId zone, RevisionId revision, Version version, Instant deployTime, - DeploymentMetrics metrics, DeploymentActivity activity, QuotaUsage quota, OptionalDouble cost) { + public Deployment(ZoneId zone, CloudAccount cloudAccount, RevisionId revision, Version version, Instant deployTime, + DeploymentMetrics metrics, DeploymentActivity activity, QuotaUsage quota, OptionalDouble cost) { this.zone = Objects.requireNonNull(zone, "zone cannot be null"); + this.cloudAccount = Objects.requireNonNull(cloudAccount, "cloudAccount cannot be null"); this.revision = Objects.requireNonNull(revision, "revision cannot be null"); this.version = Objects.requireNonNull(version, "version cannot be null"); this.deployTime = Objects.requireNonNull(deployTime, "deployTime cannot be null"); @@ -41,6 +44,9 @@ public class Deployment { /** Returns the zone this was deployed to */ public ZoneId zone() { return zone; } + /** Returns the cloud account this was deployed to */ + public CloudAccount cloudAccount() { return cloudAccount; } + /** Returns the deployed application revision */ public RevisionId revision() { return revision; } @@ -65,26 +71,22 @@ public class Deployment { public OptionalDouble cost() { return cost; } public Deployment recordActivityAt(Instant instant) { - return new Deployment(zone, revision, version, deployTime, metrics, + return new Deployment(zone, cloudAccount, revision, version, deployTime, metrics, activity.recordAt(instant, metrics), quota, cost); } public Deployment withMetrics(DeploymentMetrics metrics) { - return new Deployment(zone, revision, version, deployTime, metrics, activity, quota, cost); - } - - public Deployment withQuota(QuotaUsage quota) { - return new Deployment(zone, revision, version, deployTime, metrics, activity, quota, cost); + return new Deployment(zone, cloudAccount, revision, version, deployTime, metrics, activity, quota, cost); } public Deployment withCost(double cost) { if (this.cost.isPresent() && Double.compare(this.cost.getAsDouble(), cost) == 0) return this; - return new Deployment(zone, revision, version, deployTime, metrics, activity, quota, OptionalDouble.of(cost)); + return new Deployment(zone, cloudAccount, revision, version, deployTime, metrics, activity, quota, OptionalDouble.of(cost)); } public Deployment withoutCost() { if (cost.isEmpty()) return this; - return new Deployment(zone, revision, version, deployTime, metrics, activity, quota, OptionalDouble.empty()); + return new Deployment(zone, cloudAccount, revision, version, deployTime, metrics, activity, quota, OptionalDouble.empty()); } @Override @@ -93,6 +95,7 @@ public class Deployment { if (o == null || getClass() != o.getClass()) return false; Deployment that = (Deployment) o; return zone.equals(that.zone) && + cloudAccount.equals(that.cloudAccount) && revision.equals(that.revision) && version.equals(that.version) && deployTime.equals(that.deployTime) && @@ -104,7 +107,7 @@ public class Deployment { @Override public int hashCode() { - return Objects.hash(zone, revision, version, deployTime, metrics, activity, quota, cost); + return Objects.hash(zone, cloudAccount, revision, version, deployTime, metrics, activity, quota, cost); } @Override diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java index 2a9724bb911..ee12c9957b1 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java @@ -5,6 +5,7 @@ import com.yahoo.component.Version; import com.yahoo.config.application.api.DeploymentSpec; import com.yahoo.config.application.api.ValidationOverrides; import com.yahoo.config.provision.ApplicationId; +import com.yahoo.config.provision.CloudAccount; import com.yahoo.config.provision.ClusterSpec; import com.yahoo.config.provision.InstanceName; import com.yahoo.config.provision.RegionName; @@ -103,6 +104,7 @@ public class ApplicationSerializer { // Deployment fields private static final String zoneField = "zone"; + private static final String cloudAccountField = "cloudAccount"; private static final String environmentField = "environment"; private static final String regionField = "region"; private static final String deployTimeField = "deployTime"; @@ -202,6 +204,7 @@ public class ApplicationSerializer { private void deploymentToSlime(Deployment deployment, Cursor object) { zoneIdToSlime(deployment.zone(), object.setObject(zoneField)); + if (!deployment.cloudAccount().isUnspecified()) object.setString(cloudAccountField, deployment.cloudAccount().value()); object.setString(versionField, deployment.version().toString()); object.setLong(deployTimeField, deployment.at().toEpochMilli()); toSlime(deployment.revision(), object.setObject(applicationPackageRevisionField)); @@ -409,6 +412,7 @@ public class ApplicationSerializer { private Deployment deploymentFromSlime(Inspector deploymentObject, ApplicationId id) { ZoneId zone = zoneIdFromSlime(deploymentObject.field(zoneField)); return new Deployment(zone, + SlimeUtils.optionalString(deploymentObject.field(cloudAccountField)).map(CloudAccount::from).orElse(CloudAccount.empty), revisionFromSlime(deploymentObject.field(applicationPackageRevisionField), new JobId(id, JobType.deploymentTo(zone))), Version.fromString(deploymentObject.field(versionField).asString()), SlimeUtils.instant(deploymentObject.field(deployTimeField)), diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/DeploymentQuotaCalculatorTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/DeploymentQuotaCalculatorTest.java index a199ef9e34e..cb9c1c2fa13 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/DeploymentQuotaCalculatorTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/DeploymentQuotaCalculatorTest.java @@ -6,6 +6,7 @@ import com.yahoo.component.Version; import com.yahoo.config.application.api.DeploymentSpec; import com.yahoo.config.application.api.ValidationOverrides; import com.yahoo.config.provision.ApplicationId; +import com.yahoo.config.provision.CloudAccount; import com.yahoo.config.provision.Environment; import com.yahoo.config.provision.RegionName; import com.yahoo.config.provision.zone.ZoneId; @@ -64,7 +65,7 @@ public class DeploymentQuotaCalculatorTest { var existing_dev_deployment = new Application(TenantAndApplicationId.from(ApplicationId.defaultId()), Instant.EPOCH, DeploymentSpec.empty, ValidationOverrides.empty, Optional.empty(), Optional.empty(), Optional.empty(), OptionalInt.empty(), new ApplicationMetrics(1, 1), Set.of(), OptionalLong.empty(), RevisionHistory.empty(), List.of(new Instance(ApplicationId.defaultId()).withNewDeployment(ZoneId.from(Environment.dev, RegionName.defaultName()), - RevisionId.forProduction(1), Version.emptyVersion, Instant.EPOCH, Map.of(), QuotaUsage.create(0.53d)))); + RevisionId.forProduction(1), Version.emptyVersion, Instant.EPOCH, Map.of(), QuotaUsage.create(0.53d), CloudAccount.empty))); Quota calculated = DeploymentQuotaCalculator.calculate(Quota.unlimited().withBudget(2), List.of(existing_dev_deployment), ApplicationId.defaultId(), ZoneId.defaultId(), DeploymentSpec.fromXml( diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/EndpointCertificateMaintainerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/EndpointCertificateMaintainerTest.java index 47a1b44d196..934e15ad623 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/EndpointCertificateMaintainerTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/EndpointCertificateMaintainerTest.java @@ -3,6 +3,7 @@ package com.yahoo.vespa.hosted.controller.maintenance; import com.yahoo.component.Version; import com.yahoo.config.provision.ApplicationId; +import com.yahoo.config.provision.CloudAccount; import com.yahoo.config.provision.zone.ZoneId; import com.yahoo.vespa.hosted.controller.ControllerTester; import com.yahoo.vespa.hosted.controller.api.integration.certificates.EndpointCertificateMetadata; @@ -143,7 +144,7 @@ public class EndpointCertificateMaintainerTest { @NotNull private EndpointCertificateMaintainer.EligibleJob makeDeploymentAtAge(int ageInDays) { - var deployment = new Deployment(ZoneId.defaultId(), RevisionId.forProduction(1), Version.emptyVersion, + var deployment = new Deployment(ZoneId.defaultId(), CloudAccount.empty, RevisionId.forProduction(1), Version.emptyVersion, Instant.now().minus(ageInDays, ChronoUnit.DAYS), DeploymentMetrics.none, DeploymentActivity.none, QuotaUsage.none, OptionalDouble.empty()); return new EndpointCertificateMaintainer.EligibleJob(deployment, ApplicationId.defaultId(), JobType.prod("somewhere")); } diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java index faef6de94ca..589fc25700f 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java @@ -5,6 +5,7 @@ import com.yahoo.component.Version; import com.yahoo.config.application.api.DeploymentSpec; import com.yahoo.config.application.api.ValidationOverrides; import com.yahoo.config.provision.ApplicationId; +import com.yahoo.config.provision.CloudAccount; import com.yahoo.config.provision.ClusterSpec; import com.yahoo.config.provision.RegionName; import com.yahoo.config.provision.zone.ZoneId; @@ -111,9 +112,9 @@ public class ApplicationSerializerTest { Version.fromString("6.3.1"), Instant.ofEpochMilli(496)); Instant activityAt = Instant.parse("2018-06-01T10:15:30.00Z"); - deployments.add(new Deployment(zone1, applicationVersion1.id(), Version.fromString("1.2.3"), Instant.ofEpochMilli(3), + deployments.add(new Deployment(zone1, CloudAccount.empty, applicationVersion1.id(), Version.fromString("1.2.3"), Instant.ofEpochMilli(3), DeploymentMetrics.none, DeploymentActivity.none, QuotaUsage.none, OptionalDouble.empty())); - deployments.add(new Deployment(zone2, applicationVersion2.id(), Version.fromString("1.2.3"), Instant.ofEpochMilli(5), + deployments.add(new Deployment(zone2, CloudAccount.from("001122334455"), applicationVersion2.id(), Version.fromString("1.2.3"), Instant.ofEpochMilli(5), new DeploymentMetrics(2, 3, 4, 5, 6, Optional.of(Instant.now().truncatedTo(ChronoUnit.MILLIS)), Map.of(DeploymentMetrics.Warning.all, 3)), |