summaryrefslogtreecommitdiffstats
path: root/controller-server
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@gmail.com>2022-10-12 15:55:11 +0200
committerJon Bratseth <bratseth@gmail.com>2022-10-12 15:55:11 +0200
commit5e0502391c2ca7c4b0bfc9f4f652da2676f26314 (patch)
tree1fb5c7073f0af7b111d3290e4295a323d0d9ece2 /controller-server
parent08f7a121fff008dd1307b106bd1b7d7a84433fe6 (diff)
Add instance tags
Diffstat (limited to 'controller-server')
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Application.java9
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java52
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Instance.java25
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/LockedApplication.java5
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/pkg/ApplicationPackage.java4
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java14
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java7
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java3
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java3
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/application/DeploymentQuotaCalculatorTest.java5
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/certificate/EndpointCertificatesTest.java5
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTriggerTest.java3
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java31
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/athenz/AthenzApiTest.java5
14 files changed, 101 insertions, 70 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Application.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Application.java
index e3a0ad7cb84..66e62ff7b95 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Application.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Application.java
@@ -65,7 +65,7 @@ public class Application {
Set.of(), OptionalLong.empty(), RevisionHistory.empty(), List.of());
}
- // DO NOT USE! For serialization purposes, only.
+ // Do not use directly - edit through LockedApplication.
public Application(TenantAndApplicationId id, Instant createdAt, DeploymentSpec deploymentSpec, ValidationOverrides validationOverrides,
Optional<IssueId> deploymentIssueId, Optional<IssueId> ownershipIssueId, Optional<User> owner,
OptionalInt majorVersion, ApplicationMetrics metrics, Set<PublicKey> deployKeys, OptionalLong projectId,
@@ -230,11 +230,8 @@ public class Application {
@Override
public boolean equals(Object o) {
if (this == o) return true;
- if (! (o instanceof Application)) return false;
-
- Application that = (Application) o;
-
- return id.equals(that.id);
+ if (! (o instanceof Application other)) return false;
+ return id.equals(other.id);
}
@Override
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 19775ef420d..d8234e4f269 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
@@ -12,6 +12,7 @@ import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.CloudAccount;
import com.yahoo.config.provision.DockerImage;
import com.yahoo.config.provision.InstanceName;
+import com.yahoo.config.provision.Tags;
import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.zone.ZoneId;
import com.yahoo.log.LogLevel;
@@ -166,10 +167,11 @@ public class ApplicationController {
int count = 0;
for (TenantAndApplicationId id : curator.readApplicationIds()) {
lockApplicationIfPresent(id, application -> {
- for (InstanceName instance : application.get().deploymentSpec().instanceNames())
- if ( ! application.get().instances().containsKey(instance))
- application = withNewInstance(application, id.instance(instance));
-
+ for (var declaredInstance : application.get().deploymentSpec().instances())
+ if ( ! application.get().instances().containsKey(declaredInstance.name()))
+ application = withNewInstance(application,
+ id.instance(declaredInstance.name()),
+ declaredInstance.tags());
store(application);
});
count++;
@@ -451,14 +453,14 @@ public class ApplicationController {
*
* @throws IllegalArgumentException if the instance already exists, or has an invalid instance name.
*/
- public void createInstance(ApplicationId id) {
+ public void createInstance(ApplicationId id, Tags tags) {
lockApplicationOrThrow(TenantAndApplicationId.from(id), application -> {
- store(withNewInstance(application, id));
+ store(withNewInstance(application, id, tags));
});
}
/** Returns given application with a new instance */
- public LockedApplication withNewInstance(LockedApplication application, ApplicationId instance) {
+ public LockedApplication withNewInstance(LockedApplication application, ApplicationId instance, Tags tags) {
if (instance.instance().isTester())
throw new IllegalArgumentException("'" + instance + "' is a tester application!");
InstanceId.validate(instance.instance().value());
@@ -469,7 +471,7 @@ public class ApplicationController {
throw new IllegalArgumentException("Could not create '" + instance + "': Instance " + dashToUnderscore(instance) + " already exists");
log.info("Created " + instance);
- return application.withNewInstance(instance.instance());
+ return application.withNewInstance(instance.instance(), tags);
}
/** Deploys an application package for an existing application instance. */
@@ -496,10 +498,11 @@ public class ApplicationController {
ApplicationPackage applicationPackage = new ApplicationPackage(applicationStore.get(deployment, revision));
AtomicReference<RevisionId> lastRevision = new AtomicReference<>();
+ Instance instance;
try (Mutex lock = lock(applicationId)) {
LockedApplication application = new LockedApplication(requireApplication(applicationId), lock);
application.get().revisions().last().map(ApplicationVersion::id).ifPresent(lastRevision::set);
- Instance instance = application.get().require(job.application().instance());
+ instance = application.get().require(job.application().instance());
if ( ! applicationPackage.trustedCertificates().isEmpty()
&& run.testerCertificate().isPresent())
@@ -512,7 +515,7 @@ public class ApplicationController {
} // Release application lock while doing the deployment, which is a lengthy task.
// Carry out deployment without holding the application lock.
- ActivateResult result = deploy(job.application(), applicationPackage, zone, platform, containerEndpoints,
+ ActivateResult result = deploy(job.application(), instance.tags(), applicationPackage, zone, platform, containerEndpoints,
endpointCertificateMetadata, run.isDryRun());
endpointCertificateMetadata.ifPresent(e -> deployLogger.accept("Using CA signed certificate version %s".formatted(e.version())));
@@ -543,9 +546,9 @@ public class ApplicationController {
lockApplicationOrThrow(applicationId, application ->
store(application.with(job.application().instance(),
- instance -> instance.withNewDeployment(zone, revision, platform,
- clock.instant(), warningsFrom(result),
- quotaUsage))));
+ i -> i.withNewDeployment(zone, revision, platform,
+ clock.instant(), warningsFrom(result),
+ quotaUsage))));
return result;
}
}
@@ -557,16 +560,19 @@ public class ApplicationController {
application = application.with(applicationPackage.deploymentSpec());
application = application.with(applicationPackage.validationOverrides());
- var existingInstances = application.get().instances().keySet();
- var declaredInstances = applicationPackage.deploymentSpec().instanceNames();
- for (var name : declaredInstances)
- if ( ! existingInstances.contains(name))
- application = withNewInstance(application, application.get().id().instance(name));
+ var existingInstances = application.get().instances();
+ var declaredInstances = applicationPackage.deploymentSpec().instances();
+ for (var declaredInstance : declaredInstances) {
+ if ( ! existingInstances.containsKey(declaredInstance.name()))
+ application = withNewInstance(application, application.get().id().instance(declaredInstance.name()), declaredInstance.tags());
+ else if ( ! existingInstances.get(declaredInstance.name()).tags().equals(declaredInstance.tags()))
+ application = application.with(declaredInstance.name(), instance -> instance.with(declaredInstance.tags()));
+ }
// Delete zones not listed in DeploymentSpec, if allowed
// We do this at deployment time for externally built applications, and at submission time
// for internally built ones, to be able to return a validation failure message when necessary
- for (InstanceName name : existingInstances) {
+ for (InstanceName name : existingInstances.keySet()) {
application = withoutDeletedDeployments(application, name);
}
@@ -599,7 +605,7 @@ public class ApplicationController {
ApplicationPackage applicationPackage = new ApplicationPackage(
artifactRepository.getSystemApplicationPackage(application.id(), zone, version)
);
- return deploy(application.id(), applicationPackage, zone, version, Set.of(), /* No application cert */ Optional.empty(), false);
+ return deploy(application.id(), Tags.empty(), applicationPackage, zone, version, Set.of(), /* No application cert */ Optional.empty(), false);
} else {
throw new RuntimeException("This system application does not have an application package: " + application.id().toShortString());
}
@@ -607,10 +613,10 @@ public class ApplicationController {
/** Deploys the given tester application to the given zone. */
public ActivateResult deployTester(TesterId tester, ApplicationPackage applicationPackage, ZoneId zone, Version platform) {
- return deploy(tester.id(), applicationPackage, zone, platform, Set.of(), /* No application cert for tester*/ Optional.empty(), false);
+ return deploy(tester.id(), Tags.empty(), applicationPackage, zone, platform, Set.of(), /* No application cert for tester*/ Optional.empty(), false);
}
- private ActivateResult deploy(ApplicationId application, ApplicationPackage applicationPackage,
+ private ActivateResult deploy(ApplicationId application, Tags tags, ApplicationPackage applicationPackage,
ZoneId zone, Version platform, Set<ContainerEndpoint> endpoints,
Optional<EndpointCertificateMetadata> endpointCertificateMetadata,
boolean dryRun) {
@@ -646,7 +652,7 @@ public class ApplicationController {
.collect(toList());
Optional<CloudAccount> cloudAccount = decideCloudAccountOf(deployment, applicationPackage.deploymentSpec());
ConfigServer.PreparedApplication preparedApplication =
- configServer.deploy(new DeploymentData(application, zone, applicationPackage.zippedContent(), platform,
+ configServer.deploy(new DeploymentData(application, tags, zone, applicationPackage.zippedContent(), platform,
endpoints, endpointCertificateMetadata, dockerImageRepo, domain,
deploymentQuota, tenantSecretStores, operatorCertificates,
cloudAccount, dryRun));
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..430bafe5c44 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
@@ -5,6 +5,7 @@ import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.InstanceName;
+import com.yahoo.config.provision.Tags;
import com.yahoo.config.provision.zone.ZoneId;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobType;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.RevisionId;
@@ -40,6 +41,7 @@ import java.util.stream.Collectors;
public class Instance {
private final ApplicationId id;
+ private final Tags tags;
private final Map<ZoneId, Deployment> deployments;
private final List<AssignedRotation> rotations;
private final RotationStatus rotationStatus;
@@ -47,14 +49,15 @@ public class Instance {
private final Change change;
/** Creates an empty instance */
- public Instance(ApplicationId id) {
- this(id, Set.of(), Map.of(), List.of(), RotationStatus.EMPTY, Change.empty());
+ public Instance(ApplicationId id, Tags tags) {
+ this(id, tags, Set.of(), Map.of(), List.of(), RotationStatus.EMPTY, Change.empty());
}
/** Creates an empty instance*/
- public Instance(ApplicationId id, Collection<Deployment> deployments, Map<JobType, Instant> jobPauses,
+ public Instance(ApplicationId id, Tags tags, Collection<Deployment> deployments, Map<JobType, Instant> jobPauses,
List<AssignedRotation> rotations, RotationStatus rotationStatus, Change change) {
this.id = Objects.requireNonNull(id, "id cannot be null");
+ this.tags = Objects.requireNonNull(tags, "tags cannot be null");
this.deployments = Objects.requireNonNull(deployments, "deployments cannot be null").stream()
.collect(Collectors.toUnmodifiableMap(Deployment::zone, Function.identity()));
this.jobPauses = Map.copyOf(Objects.requireNonNull(jobPauses, "deploymentJobs cannot be null"));
@@ -63,6 +66,10 @@ public class Instance {
this.change = Objects.requireNonNull(change, "change cannot be null");
}
+ public Instance with(Tags tags) {
+ return new Instance(id, tags, deployments.values(), jobPauses, rotations, rotationStatus, change);
+ }
+
public Instance withNewDeployment(ZoneId zone, RevisionId revision, Version version,
Instant instant, Map<DeploymentMetrics.Warning, Integer> warnings, QuotaUsage quotaUsage) {
// Use info from previous deployment if available, otherwise create a new one.
@@ -87,7 +94,7 @@ public class Instance {
else
jobPauses.remove(jobType);
- return new Instance(id, deployments.values(), jobPauses, rotations, rotationStatus, change);
+ return new Instance(id, tags, deployments.values(), jobPauses, rotations, rotationStatus, change);
}
public Instance recordActivityAt(Instant instant, ZoneId zone) {
@@ -118,15 +125,15 @@ public class Instance {
}
public Instance with(List<AssignedRotation> assignedRotations) {
- return new Instance(id, deployments.values(), jobPauses, assignedRotations, rotationStatus, change);
+ return new Instance(id, tags, deployments.values(), jobPauses, assignedRotations, rotationStatus, change);
}
public Instance with(RotationStatus rotationStatus) {
- return new Instance(id, deployments.values(), jobPauses, rotations, rotationStatus, change);
+ return new Instance(id, tags, deployments.values(), jobPauses, rotations, rotationStatus, change);
}
public Instance withChange(Change change) {
- return new Instance(id, deployments.values(), jobPauses, rotations, rotationStatus, change);
+ return new Instance(id, tags, deployments.values(), jobPauses, rotations, rotationStatus, change);
}
private Instance with(Deployment deployment) {
@@ -136,13 +143,15 @@ public class Instance {
}
private Instance with(Map<ZoneId, Deployment> deployments) {
- return new Instance(id, deployments.values(), jobPauses, rotations, rotationStatus, change);
+ return new Instance(id, tags, deployments.values(), jobPauses, rotations, rotationStatus, change);
}
public ApplicationId id() { return id; }
public InstanceName name() { return id.instance(); }
+ public Tags tags() { return tags; }
+
/** Returns an immutable map of the current deployments of this */
public Map<ZoneId, Deployment> deployments() { return deployments; }
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/LockedApplication.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/LockedApplication.java
index 3e822415e96..fa702a166d2 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/LockedApplication.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/LockedApplication.java
@@ -4,6 +4,7 @@ package com.yahoo.vespa.hosted.controller;
import com.yahoo.config.application.api.DeploymentSpec;
import com.yahoo.config.application.api.ValidationOverrides;
import com.yahoo.config.provision.InstanceName;
+import com.yahoo.config.provision.Tags;
import com.yahoo.transaction.Mutex;
import com.yahoo.vespa.curator.Lock;
import com.yahoo.vespa.hosted.controller.api.integration.organization.IssueId;
@@ -88,9 +89,9 @@ public class LockedApplication {
projectId, revisions, instances.values());
}
- LockedApplication withNewInstance(InstanceName instance) {
+ LockedApplication withNewInstance(InstanceName instance, Tags tags) {
var instances = new HashMap<>(this.instances);
- instances.put(instance, new Instance(id.instance(instance)));
+ instances.put(instance, new Instance(id.instance(instance), tags));
return new LockedApplication(lock, id, createdAt, deploymentSpec, validationOverrides,
deploymentIssueId, ownershipIssueId, owner, majorVersion, metrics, deployKeys,
projectId, instances, revisions);
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/pkg/ApplicationPackage.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/pkg/ApplicationPackage.java
index 4bc9aeb00e4..c2c95a0c4bf 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/pkg/ApplicationPackage.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/pkg/ApplicationPackage.java
@@ -16,6 +16,7 @@ import com.yahoo.config.application.api.ValidationOverrides;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.RegionName;
+import com.yahoo.config.provision.Tags;
import com.yahoo.security.X509CertificateUtils;
import com.yahoo.slime.Inspector;
import com.yahoo.slime.Slime;
@@ -202,7 +203,8 @@ public class ApplicationPackage {
new InputStreamReader(new ByteArrayInputStream(servicesXml.content()), UTF_8),
InstanceName.defaultName(),
Environment.prod,
- RegionName.defaultName())
+ RegionName.defaultName(),
+ Tags.empty())
.run(); // Populates the zip archive cache with files that would be included.
}
catch (IllegalArgumentException e) {
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java
index 36036d6d36d..cca5310ccb9 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java
@@ -8,6 +8,7 @@ import com.yahoo.concurrent.UncheckedTimeoutException;
import com.yahoo.config.application.api.DeploymentSpec.UpgradePolicy;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.SystemName;
+import com.yahoo.config.provision.Tags;
import com.yahoo.config.provision.zone.ZoneId;
import com.yahoo.transaction.Mutex;
import com.yahoo.vespa.hosted.controller.Application;
@@ -321,15 +322,13 @@ public class JobController {
public List<ApplicationId> instances() {
return controller.applications().readable().stream()
.flatMap(application -> application.instances().values().stream())
- .map(Instance::id)
- .collect(toUnmodifiableList());
+ .map(Instance::id).toList();
}
/** Returns all job types which have been run for the given application. */
private List<JobType> jobs(ApplicationId id) {
return JobType.allIn(controller.zoneRegistry()).stream()
- .filter(type -> last(id, type).isPresent())
- .collect(toUnmodifiableList());
+ .filter(type -> last(id, type).isPresent()).toList();
}
/** Returns an immutable map of all known runs for the given application and job type. */
@@ -340,9 +339,8 @@ public class JobController {
/** Lists the start time of non-redeployment runs of the given job, in order of increasing age. */
public List<Instant> jobStarts(JobId id) {
return runs(id).descendingMap().values().stream()
- .filter(run -> ! run.isRedeployment())
- .map(Run::start)
- .collect(toUnmodifiableList());
+ .filter(run -> !run.isRedeployment())
+ .map(Run::start).toList();
}
/** Returns when given deployment last started deploying, falling back to time of deployment if it cannot be determined from job runs */
@@ -698,7 +696,7 @@ public class JobController {
controller.applications().lockApplicationOrThrow(TenantAndApplicationId.from(id), application -> {
if ( ! application.get().instances().containsKey(id.instance()))
- application = controller.applications().withNewInstance(application, id);
+ application = controller.applications().withNewInstance(application, id, Tags.empty());
// TODO(mpolden): Enable for public CD once all tests have been updated
if (controller.system() != SystemName.PublicCd) {
controller.applications().validatePackage(applicationPackage, application.get());
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 5aa847f648a..37c45f38e36 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
@@ -9,6 +9,7 @@ import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.RegionName;
import com.yahoo.config.provision.SystemName;
+import com.yahoo.config.provision.Tags;
import com.yahoo.config.provision.zone.ZoneId;
import com.yahoo.security.KeyUtils;
import com.yahoo.slime.ArrayTraverser;
@@ -97,6 +98,7 @@ public class ApplicationSerializer {
// Instance fields
private static final String instanceNameField = "instanceName";
+ private static final String tagsField = "tags";
private static final String deploymentsField = "deployments";
private static final String deploymentJobsField = "deploymentJobs"; // TODO jonmv: clean up serialisation format
private static final String assignedRotationsField = "assignedRotations";
@@ -184,6 +186,7 @@ public class ApplicationSerializer {
for (Instance instance : application.instances().values()) {
Cursor instanceObject = array.addObject();
instanceObject.setString(instanceNameField, instance.name().value());
+ instanceObject.setString(tagsField, instance.tags().asString());
deploymentsToSlime(instance.deployments().values(), instanceObject.setArray(deploymentsField));
toSlime(instance.jobPauses(), instanceObject.setObject(deploymentJobsField));
assignedRotationsToSlime(instance.rotations(), instanceObject);
@@ -380,12 +383,14 @@ public class ApplicationSerializer {
List<Instance> instances = new ArrayList<>();
field.traverse((ArrayTraverser) (name, object) -> {
InstanceName instanceName = InstanceName.from(object.field(instanceNameField).asString());
- List<Deployment> deployments = deploymentsFromSlime(object.field(deploymentsField), id.instance(instanceName));
+ Tags tags = Tags.fromString(object.field(tagsField).asString());
+ List < Deployment > deployments = deploymentsFromSlime(object.field(deploymentsField), id.instance(instanceName));
Map<JobType, Instant> jobPauses = jobPausesFromSlime(object.field(deploymentJobsField));
List<AssignedRotation> assignedRotations = assignedRotationsFromSlime(object);
RotationStatus rotationStatus = rotationStatusFromSlime(object);
Change change = changeFromSlime(object.field(deployingField));
instances.add(new Instance(id.instance(instanceName),
+ tags,
deployments,
jobPauses,
assignedRotations,
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
index e8fe7b7d5f0..81fb72e19fd 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
@@ -22,6 +22,7 @@ import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.HostName;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.NodeResources;
+import com.yahoo.config.provision.Tags;
import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.zone.RoutingMethod;
import com.yahoo.config.provision.zone.ZoneId;
@@ -2035,7 +2036,7 @@ public class ApplicationApiHandler extends AuditLoggingRequestHandler {
if (controller.applications().getApplication(applicationId).isEmpty())
createApplication(tenantName, applicationName, request);
- controller.applications().createInstance(applicationId.instance(instanceName));
+ controller.applications().createInstance(applicationId.instance(instanceName), Tags.empty());
Slime slime = new Slime();
toSlime(applicationId.instance(instanceName), slime.setObject(), request);
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java
index 5380cf4ee27..0c908b1f035 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTester.java
@@ -7,6 +7,7 @@ import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.HostName;
import com.yahoo.config.provision.RegionName;
import com.yahoo.config.provision.SystemName;
+import com.yahoo.config.provision.Tags;
import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.zone.RoutingMethod;
import com.yahoo.config.provision.zone.ZoneApi;
@@ -370,7 +371,7 @@ public final class ControllerTester {
public Application createApplication(String tenant, String applicationName, String instanceName) {
Application application = createApplication(tenant, applicationName);
- controller().applications().createInstance(application.id().instance(instanceName));
+ controller().applications().createInstance(application.id().instance(instanceName), Tags.empty());
return application;
}
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 3163c8b6439..db45933f498 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
@@ -8,6 +8,7 @@ import com.yahoo.config.application.api.ValidationOverrides;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.RegionName;
+import com.yahoo.config.provision.Tags;
import com.yahoo.config.provision.zone.ZoneId;
import com.yahoo.vespa.hosted.controller.Application;
import com.yahoo.vespa.hosted.controller.Instance;
@@ -63,8 +64,8 @@ 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))));
+ List.of(new Instance(ApplicationId.defaultId(), Tags.empty()).withNewDeployment(ZoneId.from(Environment.dev, RegionName.defaultName()),
+ RevisionId.forProduction(1), Version.emptyVersion, Instant.EPOCH, Map.of(), QuotaUsage.create(0.53d))));
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/certificate/EndpointCertificatesTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/certificate/EndpointCertificatesTest.java
index 9a2d9eddba7..274cf3c5867 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/certificate/EndpointCertificatesTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/certificate/EndpointCertificatesTest.java
@@ -8,6 +8,7 @@ import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.RegionName;
import com.yahoo.config.provision.SystemName;
+import com.yahoo.config.provision.Tags;
import com.yahoo.config.provision.zone.RoutingMethod;
import com.yahoo.config.provision.zone.ZoneId;
import com.yahoo.security.KeyAlgorithm;
@@ -100,7 +101,7 @@ public class EndpointCertificatesTest {
return x509CertificateBuilder.build();
}
- private final Instance testInstance = new Instance(ApplicationId.defaultId());
+ private final Instance testInstance = new Instance(ApplicationId.defaultId(), Tags.empty());
private final String testKeyName = "testKeyName";
private final String testCertName = "testCertName";
private ZoneId testZone;
@@ -234,7 +235,7 @@ public class EndpointCertificatesTest {
@Test
void includes_application_endpoint_when_declared() {
- Instance instance = new Instance(ApplicationId.from("t1", "a1", "default"));
+ Instance instance = new Instance(ApplicationId.from("t1", "a1", "default"), Tags.empty());
ZoneId zone1 = ZoneId.from(Environment.prod, RegionName.from("aws-us-east-1c"));
ZoneId zone2 = ZoneId.from(Environment.prod, RegionName.from("aws-us-west-2a"));
ApplicationPackage applicationPackage = new ApplicationPackageBuilder()
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTriggerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTriggerTest.java
index d8cef45f124..5fba33c9094 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTriggerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTriggerTest.java
@@ -8,6 +8,7 @@ import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.RegionName;
import com.yahoo.config.provision.SystemName;
+import com.yahoo.config.provision.Tags;
import com.yahoo.config.provision.zone.RoutingMethod;
import com.yahoo.config.provision.zone.ZoneApi;
import com.yahoo.config.provision.zone.ZoneId;
@@ -986,7 +987,7 @@ public class DeploymentTriggerTest {
@Test
void testUserInstancesNotInDeploymentSpec() {
var app = tester.newDeploymentContext();
- tester.controller().applications().createInstance(app.application().id().instance("user"));
+ tester.controller().applications().createInstance(app.application().id().instance("user"), Tags.empty());
app.submit().deploy();
}
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 849261d5ae4..40217890351 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
@@ -6,6 +6,7 @@ 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.SystemName;
+import com.yahoo.config.provision.Tags;
import com.yahoo.config.provision.zone.ZoneId;
import com.yahoo.security.KeyUtils;
import com.yahoo.slime.SlimeUtils;
@@ -127,18 +128,21 @@ public class ApplicationSerializerTest {
RevisionHistory revisions = RevisionHistory.ofRevisions(List.of(applicationVersion1),
Map.of(new JobId(id1, DeploymentContext.productionUsEast3), List.of(applicationVersion2)));
- List<Instance> instances = List.of(new Instance(id1,
- deployments,
- Map.of(DeploymentContext.systemTest, Instant.ofEpochMilli(333)),
- List.of(AssignedRotation.fromStrings("foo", "default", "my-rotation", Set.of("us-west-1"))),
- rotationStatus,
- Change.of(new Version("6.1"))),
- new Instance(id3,
- List.of(),
- Map.of(),
- List.of(),
- RotationStatus.EMPTY,
- Change.of(Version.fromString("6.7")).withPin()));
+ List<Instance> instances =
+ List.of(new Instance(id1,
+ Tags.fromString("tag1 tag2"),
+ deployments,
+ Map.of(DeploymentContext.systemTest, Instant.ofEpochMilli(333)),
+ List.of(AssignedRotation.fromStrings("foo", "default", "my-rotation", Set.of("us-west-1"))),
+ rotationStatus,
+ Change.of(new Version("6.1"))),
+ new Instance(id3,
+ Tags.empty(),
+ List.of(),
+ Map.of(),
+ List.of(),
+ RotationStatus.EMPTY,
+ Change.of(Version.fromString("6.7")).withPin()));
Application original = new Application(TenantAndApplicationId.from(id1),
Instant.now().truncatedTo(ChronoUnit.MILLIS),
@@ -177,6 +181,9 @@ public class ApplicationSerializerTest {
assertEquals(original.revisions().production(), serialized.revisions().production());
assertEquals(original.revisions().development(), serialized.revisions().development());
+ assertEquals(original.require(id1.instance()).tags(), serialized.require(id1.instance()).tags());
+ assertEquals(original.require(id3.instance()).tags(), serialized.require(id3.instance()).tags());
+
assertEquals(original.deploymentSpec().xmlForm(), serialized.deploymentSpec().xmlForm());
assertEquals(original.validationOverrides().xmlForm(), serialized.validationOverrides().xmlForm());
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/athenz/AthenzApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/athenz/AthenzApiTest.java
index 3a539987443..2f4b4154c08 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/athenz/AthenzApiTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/athenz/AthenzApiTest.java
@@ -3,6 +3,7 @@ package com.yahoo.vespa.hosted.controller.restapi.athenz;
import com.yahoo.application.container.handler.Request;
import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.Tags;
import com.yahoo.vespa.athenz.api.AthenzDomain;
import com.yahoo.vespa.hosted.controller.ControllerTester;
import com.yahoo.vespa.hosted.controller.restapi.ContainerTester;
@@ -25,8 +26,8 @@ public class AthenzApiTest extends ControllerContainerTest {
controllerTester.createTenant("sandbox", AthenzApiHandler.sandboxDomainIn(tester.controller().system()), 123L);
controllerTester.createApplication("sandbox", "app", "default");
- tester.controller().applications().createInstance(ApplicationId.from("sandbox", "app", hostedOperator.getName()));
- tester.controller().applications().createInstance(ApplicationId.from("sandbox", "app", defaultUser.getName()));
+ tester.controller().applications().createInstance(ApplicationId.from("sandbox", "app", hostedOperator.getName()), Tags.empty());
+ tester.controller().applications().createInstance(ApplicationId.from("sandbox", "app", defaultUser.getName()), Tags.empty());
controllerTester.createApplication("sandbox", "opp", "default");
controllerTester.createTenant("tenant1", "domain1", 123L);