aboutsummaryrefslogtreecommitdiffstats
path: root/controller-server
diff options
context:
space:
mode:
authorValerij Fredriksen <valerijf@yahooinc.com>2023-03-03 11:32:23 +0100
committerValerij Fredriksen <valerijf@yahooinc.com>2023-03-03 11:35:23 +0100
commit0636b9fc89039f6f663f6a73ea02b05daffdc452 (patch)
tree85258aa40c97ad57af0c4cef05ed467862716ab5 /controller-server
parent5ee812d587eb747b2de460c6cee64c72b60464c6 (diff)
Store cloudAccount in Deployment
Diffstat (limited to 'controller-server')
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java36
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Instance.java9
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/Deployment.java25
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java4
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/DeploymentQuotaCalculatorTest.java3
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/EndpointCertificateMaintainerTest.java3
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java5
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)),