aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@vespa.ai>2024-05-13 14:51:13 -0500
committerJon Bratseth <bratseth@vespa.ai>2024-05-13 14:51:13 -0500
commit317b1a3c8ca6ad88385931d8336b87d86b38b701 (patch)
treeb564f673387ed43f568b24f850fd701ec79bc492
parentea1bc491ddf17062112981a2131ced8444b9a70f (diff)
Apply capacity to quota check
-rw-r--r--config-model-api/abi-spec.json3
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/model/api/Provisioned.java21
-rw-r--r--config-model/pom.xml6
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java14
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java2
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java10
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/QuotaValidator.java32
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ResourcesReductionValidator.java4
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/ClusterInfoTest.java2
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/QuotaValidatorTest.java6
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java2
-rw-r--r--configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/ConfigServerFlagSource.java2
-rw-r--r--configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/db/ZooKeeperFlagSource.java2
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java2
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/provision/ProvisionerAdapter.java2
15 files changed, 88 insertions, 22 deletions
diff --git a/config-model-api/abi-spec.json b/config-model-api/abi-spec.json
index 42e7e23dfcc..c0139c87349 100644
--- a/config-model-api/abi-spec.json
+++ b/config-model-api/abi-spec.json
@@ -1624,6 +1624,9 @@
],
"methods" : [
"public void <init>()",
+ "public void add(com.yahoo.config.provision.ClusterSpec, com.yahoo.config.provision.Capacity)",
+ "public java.util.Map clusters()",
+ "public java.util.Map capacities()",
"public void add(com.yahoo.config.provision.ClusterSpec$Id, com.yahoo.config.provision.Capacity)",
"public java.util.Map all()"
],
diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/Provisioned.java b/config-model-api/src/main/java/com/yahoo/config/model/api/Provisioned.java
index db0822c4c10..81e0cb58c7d 100644
--- a/config-model-api/src/main/java/com/yahoo/config/model/api/Provisioned.java
+++ b/config-model-api/src/main/java/com/yahoo/config/model/api/Provisioned.java
@@ -16,13 +16,28 @@ import java.util.Map;
*/
public class Provisioned {
- private final Map<ClusterSpec.Id, Capacity> provisioned = new HashMap<>();
+ private final Map<ClusterSpec.Id, ClusterSpec> clusters = new HashMap<>();
+ private final Map<ClusterSpec.Id, Capacity> capacities = new HashMap<>();
+
+ public void add(ClusterSpec cluster, Capacity capacity) {
+ clusters.put(cluster.id(), cluster);
+ capacities.put(cluster.id(), capacity);
+ }
+
+ /** Returns an unmodifiable map of all the cluster requests recorded during build of the model this belongs to */
+ public Map<ClusterSpec.Id, ClusterSpec> clusters() { return Collections.unmodifiableMap(clusters); }
+
+ /** Returns an unmodifiable map of all the capacity provision requests recorded during build of the model this belongs to */
+ public Map<ClusterSpec.Id, Capacity> capacities() { return Collections.unmodifiableMap(capacities); }
+
+ // TODO: Remove after June 2024
public void add(ClusterSpec.Id id, Capacity capacity) {
- provisioned.put(id, capacity);
+ capacities.put(id, capacity);
}
/** Returns an unmodifiable map of all the provision requests recorded during build of the model this belongs to */
- public Map<ClusterSpec.Id, Capacity> all() { return Collections.unmodifiableMap(provisioned); }
+ // TODO: Remove after June 2024
+ public Map<ClusterSpec.Id, Capacity> all() { return Collections.unmodifiableMap(capacities); }
}
diff --git a/config-model/pom.xml b/config-model/pom.xml
index a0bda542d5f..751d3de63ef 100644
--- a/config-model/pom.xml
+++ b/config-model/pom.xml
@@ -26,6 +26,12 @@
</dependency>
<dependency>
<groupId>com.yahoo.vespa</groupId>
+ <artifactId>flags</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.yahoo.vespa</groupId>
<artifactId>provided-dependencies</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
diff --git a/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java b/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java
index 57a75bd8a38..0e4e296f5a1 100644
--- a/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java
+++ b/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java
@@ -39,6 +39,8 @@ import com.yahoo.vespa.config.ConfigDefinition;
import com.yahoo.vespa.config.ConfigDefinitionBuilder;
import com.yahoo.vespa.config.ConfigDefinitionKey;
import com.yahoo.vespa.documentmodel.DocumentModel;
+import com.yahoo.vespa.flags.FlagSource;
+import com.yahoo.vespa.flags.InMemoryFlagSource;
import com.yahoo.vespa.model.container.search.QueryProfiles;
import com.yahoo.vespa.model.container.search.QueryProfilesBuilder;
import com.yahoo.vespa.model.container.search.SemanticRules;
@@ -79,6 +81,7 @@ public class DeployState implements ConfigDefinitionStore {
private final Version vespaVersion;
private final Set<ContainerEndpoint> endpoints;
private final Zone zone; // TODO: Zone is set separately both here and in properties
+ private final FlagSource flagSource;
private final QueryProfiles queryProfiles;
private final SemanticRules semanticRules;
private final ImportedMlModels importedModels;
@@ -118,6 +121,7 @@ public class DeployState implements ConfigDefinitionStore {
Set<ContainerEndpoint> endpoints,
Collection<MlModelImporter> modelImporters,
Zone zone,
+ FlagSource flagSource,
QueryProfiles queryProfiles,
SemanticRules semanticRules,
Instant now,
@@ -143,6 +147,7 @@ public class DeployState implements ConfigDefinitionStore {
this.configDefinitionRepo = configDefinitionRepo;
this.endpoints = Set.copyOf(endpoints);
this.zone = zone;
+ this.flagSource = flagSource;
this.queryProfiles = queryProfiles; // TODO: Remove this by seeing how pagetemplates are propagated
this.semanticRules = semanticRules; // TODO: Remove this by seeing how pagetemplates are propagated
this.importedModels = importMlModels(applicationPackage, modelImporters, executor);
@@ -273,6 +278,8 @@ public class DeployState implements ConfigDefinitionStore {
/** Returns the zone in which this is currently running */
public Zone zone() { return zone; }
+ public FlagSource flagSource() { return flagSource; }
+
public QueryProfiles getQueryProfiles() { return queryProfiles; }
public SemanticRules getSemanticRules() { return semanticRules; }
@@ -330,6 +337,7 @@ public class DeployState implements ConfigDefinitionStore {
private Set<ContainerEndpoint> endpoints = Set.of();
private Collection<MlModelImporter> modelImporters = List.of();
private Zone zone = Zone.defaultZone();
+ private FlagSource flagSource = new InMemoryFlagSource();
private Instant now = Instant.now();
private Version wantedNodeVespaVersion = Vtag.currentVersion;
private boolean accessLoggingEnabledByDefault = true;
@@ -407,6 +415,11 @@ public class DeployState implements ConfigDefinitionStore {
return this;
}
+ public Builder flagSource(FlagSource flagSource) {
+ this.flagSource = flagSource;
+ return this;
+ }
+
public Builder now(Instant now) {
this.now = now;
return this;
@@ -483,6 +496,7 @@ public class DeployState implements ConfigDefinitionStore {
endpoints,
modelImporters,
zone,
+ flagSource,
queryProfiles,
semanticRules,
now,
diff --git a/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java b/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java
index befe57a97e4..da0fd265724 100644
--- a/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java
+++ b/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java
@@ -158,7 +158,7 @@ public class InMemoryProvisioner implements HostProvisioner {
@Override
public List<HostSpec> prepare(ClusterSpec cluster, Capacity requested, ProvisionLogger logger) {
- provisioned.add(cluster.id(), requested);
+ provisioned.add(cluster, requested);
clusters.add(cluster);
if (environment == Environment.dev && ! requested.isRequired()) {
requested = requested.withLimits(requested.minResources().withNodes(1),
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java b/config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java
index c876976917b..efe83fb4e91 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java
@@ -28,6 +28,8 @@ import com.yahoo.config.provision.QuotaExceededException;
import com.yahoo.config.provision.TransientException;
import com.yahoo.config.provision.Zone;
import com.yahoo.vespa.config.VespaVersion;
+import com.yahoo.vespa.flags.FlagSource;
+import com.yahoo.vespa.flags.InMemoryFlagSource;
import com.yahoo.vespa.model.application.validation.Validation;
import com.yahoo.vespa.model.application.validation.Validator;
import org.xml.sax.SAXException;
@@ -52,6 +54,7 @@ public class VespaModelFactory implements ModelFactory {
private final ConfigModelRegistry configModelRegistry;
private final Collection<MlModelImporter> modelImporters;
private final Zone zone;
+ private final FlagSource flagSource;
private final Clock clock;
private final Version version;
private final List<Validator> additionalValidators;
@@ -60,7 +63,7 @@ public class VespaModelFactory implements ModelFactory {
@Inject
public VespaModelFactory(ComponentRegistry<ConfigModelPlugin> pluginRegistry,
ComponentRegistry<Validator> additionalValidators,
- Zone zone) {
+ Zone zone, FlagSource flagSource) {
this.version = new Version(VespaVersion.major, VespaVersion.minor, VespaVersion.micro);
List<ConfigModelBuilder<?>> modelBuilders = new ArrayList<>();
for (ConfigModelPlugin plugin : pluginRegistry.allComponents()) {
@@ -76,6 +79,7 @@ public class VespaModelFactory implements ModelFactory {
new XGBoostImporter(),
new LightGBMImporter());
this.zone = zone;
+ this.flagSource = flagSource;
this.additionalValidators = List.copyOf(additionalValidators.allComponents());
this.clock = Clock.systemUTC();
@@ -84,7 +88,7 @@ public class VespaModelFactory implements ModelFactory {
// For testing only
protected VespaModelFactory(ConfigModelRegistry configModelRegistry) {
this(new Version(VespaVersion.major, VespaVersion.minor, VespaVersion.micro), configModelRegistry,
- Clock.systemUTC(), Zone.defaultZone());
+ Clock.systemUTC(), Zone.defaultZone());
}
private VespaModelFactory(Version version, ConfigModelRegistry configModelRegistry, Clock clock, Zone zone) {
@@ -98,6 +102,7 @@ public class VespaModelFactory implements ModelFactory {
this.modelImporters = List.of();
this.additionalValidators = List.of();
this.zone = zone;
+ this.flagSource = new InMemoryFlagSource();
this.clock = clock;
}
@@ -192,6 +197,7 @@ public class VespaModelFactory implements ModelFactory {
.endpoints(modelContext.properties().endpoints())
.modelImporters(modelImporters)
.zone(zone)
+ .flagSource(flagSource)
.now(clock.instant())
.wantedNodeVespaVersion(modelContext.wantedNodeVespaVersion())
.wantedDockerImageRepo(modelContext.wantedDockerImageRepo())
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/QuotaValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/QuotaValidator.java
index 4d9386b5f19..0984770ef49 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/QuotaValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/QuotaValidator.java
@@ -1,9 +1,12 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.application.validation;
+import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.Capacity;
+import com.yahoo.config.provision.CapacityPolicies;
import com.yahoo.config.provision.ClusterResources;
import com.yahoo.config.provision.ClusterSpec;
+import com.yahoo.config.provision.Exclusivity;
import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.QuotaExceededException;
import com.yahoo.config.provision.SystemName;
@@ -31,25 +34,34 @@ public class QuotaValidator implements Validator {
@Override
public void validate(Context context) {
+ var zone = context.deployState().zone();
+ var flagSource = context.deployState().flagSource();
+ var capacityPolicies = new CapacityPolicies(zone, new Exclusivity(zone, flagSource), flagSource);
var quota = context.deployState().getProperties().quota();
quota.maxClusterSize().ifPresent(maxClusterSize -> validateMaxClusterSize(maxClusterSize, context.model()));
- quota.budgetAsDecimal().ifPresent(budget -> validateBudget(budget, context.model(), context.deployState().getProperties().zone()));
+ quota.budgetAsDecimal().ifPresent(budget -> validateBudget(budget, context, capacityPolicies));
}
- private void validateBudget(BigDecimal budget, VespaModel model, Zone zone) {
- var maxSpend = model.allClusters().stream()
- .filter(id -> !adminClusterIds(model).contains(id))
- .map(id -> model.provisioned().all().getOrDefault(id, zeroCapacity))
- .mapToDouble(c -> c.maxResources().cost()) // TODO: This may be unspecified -> 0
- .sum();
+ private void validateBudget(BigDecimal budget, Context context,
+ CapacityPolicies capacityPolicies) {
+ var zone = context.deployState().getProperties().zone();
+ var application = context.model().applicationPackage().getApplicationId();
+
+ var maxSpend = 0.0;
+ for (var id : context.model().allClusters()) {
+ if (adminClusterIds(context.model()).contains(id)) continue;
+ var cluster = context.model().provisioned().clusters().get(id);
+ var capacity = context.model().provisioned().capacities().getOrDefault(id, zeroCapacity);
+ maxSpend += capacityPolicies.applyOn(capacity, application, cluster.isExclusive()).maxResources().cost();
+ }
- var actualSpend = model.allocatedHosts().getHosts().stream()
+ var actualSpend = context.model().allocatedHosts().getHosts().stream()
.filter(hostSpec -> hostSpec.membership().get().cluster().type() != ClusterSpec.Type.admin)
.mapToDouble(hostSpec -> hostSpec.advertisedResources().cost())
.sum();
if (Math.abs(actualSpend) < 0.01) {
- log.warning("Deploying application " + model.applicationPackage().getApplicationId() + " with zero budget use. This is suspicious, but not blocked");
+ log.warning("Deploying application " + application + " with zero budget use. This is suspicious, but not blocked");
return;
}
@@ -69,7 +81,7 @@ public class QuotaValidator implements Validator {
/** Check that all clusters in the application do not exceed the quota max cluster size. */
private void validateMaxClusterSize(int maxClusterSize, VespaModel model) {
- var invalidClusters = model.provisioned().all().entrySet().stream()
+ var invalidClusters = model.provisioned().capacities().entrySet().stream()
.filter(entry -> entry.getValue() != null)
.filter(entry -> {
var cluster = entry.getValue();
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ResourcesReductionValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ResourcesReductionValidator.java
index 5d7a8779005..42410dc3acf 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ResourcesReductionValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ResourcesReductionValidator.java
@@ -60,9 +60,9 @@ public class ResourcesReductionValidator implements ChangeValidator {
* This will always yield specified node resources on hosted instances and never on self-hosted instances.
*/
private ClusterResources clusterResources(ClusterSpec.Id id, VespaModel model) {
- if ( ! model.provisioned().all().containsKey(id)) return null;
+ if ( ! model.provisioned().capacities().containsKey(id)) return null;
- ClusterResources resources = model.provisioned().all().get(id).maxResources();
+ ClusterResources resources = model.provisioned().capacities().get(id).maxResources();
if ( ! resources.nodeResources().isUnspecified()) return resources;
var containerCluster = model.getContainerClusters().get(id.value());
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/ClusterInfoTest.java b/config-model/src/test/java/com/yahoo/vespa/model/ClusterInfoTest.java
index 4df9f261dfe..7aa6eb76995 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/ClusterInfoTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/ClusterInfoTest.java
@@ -258,7 +258,7 @@ public class ClusterInfoTest {
.provisioned(provisioner.provisioned())
.build();
new VespaModel(new NullConfigModelRegistry(), deployState);
- return deployState.provisioned().all();
+ return deployState.provisioned().capacities();
}
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/QuotaValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/QuotaValidatorTest.java
index 89f81dfdaef..590433757c3 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/QuotaValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/QuotaValidatorTest.java
@@ -54,6 +54,12 @@ public class QuotaValidatorTest {
}
@Test
+ void test_deploy_within_quota_budget_because_in_dev() {
+ var tester = new ValidationTester(13, false, new TestProperties().setHostedVespa(true).setQuota(quota).setZone(devZone));
+ tester.deploy(null, getServices(10), Environment.dev, null, CONTAINER_CLUSTER);
+ }
+
+ @Test
void test_deploy_above_quota_budget_in_publiccd() {
var tester = new ValidationTester(13, false, new TestProperties().setHostedVespa(true).setQuota(quota.withBudget(BigDecimal.ONE)).setZone(publicCdZone));
try {
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java
index e704da08d18..0e8ce4748b4 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java
@@ -598,7 +598,7 @@ public class ContainerModelBuilderTest extends ContainerModelBuilderTestBase {
.setCloudAccount(cloudAccount))
.build());
assertEquals(2, model.hostSystem().getHosts().size());
- assertEquals(List.of(cloudAccount), model.provisioned().all().values()
+ assertEquals(List.of(cloudAccount), model.provisioned().capacities().values()
.stream()
.map(capacity -> capacity.cloudAccount().get())
.toList());
diff --git a/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/ConfigServerFlagSource.java b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/ConfigServerFlagSource.java
index f30d329cf09..7a0b3695e7c 100644
--- a/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/ConfigServerFlagSource.java
+++ b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/ConfigServerFlagSource.java
@@ -13,6 +13,7 @@ import java.nio.file.FileSystems;
* @author hakonhall
*/
public class ConfigServerFlagSource extends OrderedFlagSource {
+
@Inject
public ConfigServerFlagSource(FlagsDb flagsDb) {
this(FileSystems.getDefault(), flagsDb);
@@ -21,4 +22,5 @@ public class ConfigServerFlagSource extends OrderedFlagSource {
ConfigServerFlagSource(FileSystem fileSystem, FlagsDb flagsDb) {
super(new BootstrapFlagSource(fileSystem), new ZooKeeperFlagSource(flagsDb));
}
+
}
diff --git a/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/db/ZooKeeperFlagSource.java b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/db/ZooKeeperFlagSource.java
index f68c4657d8a..e57088416a0 100644
--- a/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/db/ZooKeeperFlagSource.java
+++ b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/db/ZooKeeperFlagSource.java
@@ -13,6 +13,7 @@ import java.util.Optional;
* @author hakonhall
*/
public class ZooKeeperFlagSource implements FlagSource {
+
private final FlagsDb flagsDb;
public ZooKeeperFlagSource(FlagsDb flagsDb) {
@@ -23,4 +24,5 @@ public class ZooKeeperFlagSource implements FlagSource {
public Optional<RawFlag> fetch(FlagId id, FetchVector vector) {
return flagsDb.getValue(id).flatMap(data -> data.resolve(vector));
}
+
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
index 07a8179732f..22199dfc5b4 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
@@ -1136,7 +1136,7 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
public double getQuotaUsageRate(ApplicationId applicationId) {
var application = getApplication(applicationId);
- return application.getModel().provisioned().all().values().stream()
+ return application.getModel().provisioned().capacities().values().stream()
.map(Capacity::maxResources)// TODO: This may be unspecified -> 0
.mapToDouble(resources -> resources.nodes() * resources.nodeResources().cost())
.sum();
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/provision/ProvisionerAdapter.java b/configserver/src/main/java/com/yahoo/vespa/config/server/provision/ProvisionerAdapter.java
index 956573ecbd4..27805b64e79 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/provision/ProvisionerAdapter.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/provision/ProvisionerAdapter.java
@@ -44,7 +44,7 @@ public class ProvisionerAdapter implements HostProvisioner {
@Override
public List<HostSpec> prepare(ClusterSpec cluster, Capacity capacity, ProvisionLogger logger) {
- provisioned.add(cluster.id(), capacity);
+ provisioned.add(cluster, capacity);
return provisioner.prepare(applicationId, cluster, capacity, logger);
}