diff options
author | Jon Bratseth <bratseth@gmail.com> | 2021-06-07 13:46:13 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@gmail.com> | 2021-06-07 13:46:13 +0200 |
commit | c5a4f7ab002cb700a6bf5823f151ab6482729ed6 (patch) | |
tree | d118bb00ae174582704a9b7a733783f3c7481cca /config-model/src | |
parent | 3c9040eb779608c174cefc32b6da0dc584ec87ed (diff) |
Add redundancy increase validation override
Diffstat (limited to 'config-model/src')
5 files changed, 118 insertions, 2 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java index 55443d4b260..eccb54780d6 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java @@ -20,6 +20,7 @@ import com.yahoo.vespa.model.application.validation.change.GlobalDocumentChangeV import com.yahoo.vespa.model.application.validation.change.IndexedSearchClusterChangeValidator; import com.yahoo.vespa.model.application.validation.change.IndexingModeChangeValidator; import com.yahoo.vespa.model.application.validation.change.NodeResourceChangeValidator; +import com.yahoo.vespa.model.application.validation.change.RedundancyIncreaseValidator; import com.yahoo.vespa.model.application.validation.change.ResourcesReductionValidator; import com.yahoo.vespa.model.application.validation.change.StartupCommandChangeValidator; import com.yahoo.vespa.model.application.validation.change.StreamingSearchClusterChangeValidator; @@ -105,7 +106,8 @@ public class Validation { new ClusterSizeReductionValidator(), new ResourcesReductionValidator(), new ContainerRestartValidator(), - new NodeResourceChangeValidator() + new NodeResourceChangeValidator(), + new RedundancyIncreaseValidator() }; List<ConfigChangeAction> actions = Arrays.stream(validators) .flatMap(v -> v.validate(currentModel, nextModel, overrides, now).stream()) diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validator.java index f3bebbe7fb9..fee63828670 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validator.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validator.java @@ -15,7 +15,7 @@ public abstract class Validator { * Validates the input vespamodel * * @param model a VespaModel object - * @param deployState The {@link DeployState} built from building the model + * @param deployState the {@link DeployState} built from building the model */ public abstract void validate(VespaModel model, DeployState deployState); diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/RedundancyIncreaseValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/RedundancyIncreaseValidator.java new file mode 100644 index 00000000000..dcf16222d35 --- /dev/null +++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/RedundancyIncreaseValidator.java @@ -0,0 +1,45 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.model.application.validation.change; + +import com.yahoo.config.application.api.ValidationId; +import com.yahoo.config.application.api.ValidationOverrides; +import com.yahoo.config.model.api.ConfigChangeAction; +import com.yahoo.config.provision.Capacity; +import com.yahoo.config.provision.ClusterSpec; +import com.yahoo.vespa.model.VespaModel; +import com.yahoo.vespa.model.content.cluster.ContentCluster; + +import java.time.Instant; +import java.util.List; + +/** + * Checks that redundancy is not increased (without a validation override), + * as that may easily cause the cluster to run out of reasources. + * + * @author bratseth + */ +public class RedundancyIncreaseValidator implements ChangeValidator { + + @Override + public List<ConfigChangeAction> validate(VespaModel current, VespaModel next, ValidationOverrides overrides, Instant now) { + for (ContentCluster currentCluster : current.getContentClusters().values()) { + ContentCluster nextCluster = next.getContentClusters().get(currentCluster.getSubId()); + if (nextCluster == null) continue; + if (redundancyOf(nextCluster) > redundancyOf(currentCluster)) { + overrides.invalid(ValidationId.redundancyIncrease, + "Increasing redundancy from " + redundancyOf(currentCluster) + " to " + + redundancyOf(nextCluster) + " in '" + currentCluster + ". " + + "This is a safe operation but verify that you have room for a " + + redundancyOf(nextCluster) + "/" + redundancyOf(currentCluster) + "x increase " + + "in content size", + now); + } + } + return List.of(); + } + + private int redundancyOf(ContentCluster cluster) { + return cluster.redundancy().finalRedundancy(); + } + +} diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java index e0d311e6df6..96f2af66131 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java @@ -674,4 +674,9 @@ public class ContentCluster extends AbstractConfigProducer<AbstractConfigProduce // TODO } + @Override + public String toString() { + return "content cluster '" + clusterId + "'"; + } + } diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/RedundancyIncreaseValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/RedundancyIncreaseValidatorTest.java new file mode 100644 index 00000000000..ddeada8b33f --- /dev/null +++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/RedundancyIncreaseValidatorTest.java @@ -0,0 +1,64 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.model.application.validation.change; + +import com.yahoo.config.application.api.ValidationId; +import com.yahoo.config.application.api.ValidationOverrides; +import com.yahoo.config.provision.Environment; +import com.yahoo.vespa.model.VespaModel; +import com.yahoo.vespa.model.application.validation.ValidationTester; +import com.yahoo.yolean.Exceptions; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +/** + * @author bratseth + */ +public class RedundancyIncreaseValidatorTest { + + private final ValidationTester tester = new ValidationTester(7); + + @Test + public void testRedundancyIncreaseValidation() { + VespaModel previous = tester.deploy(null, getServices(2), Environment.prod, null).getFirst(); + try { + tester.deploy(previous, getServices(3), Environment.prod, null); + fail("Expected exception due to redundancy increase"); + } + catch (IllegalArgumentException expected) { + assertEquals("redundancy-increase: " + + "Increasing redundancy from 2 to 3 in 'content cluster 'contentClusterId'. " + + "This is a safe operation but verify that you have room for a 3/2x increase in content size. " + + ValidationOverrides.toAllowMessage(ValidationId.redundancyIncrease), + Exceptions.toMessageString(expected)); + } + } + + @Test + public void testOverridingContentRemovalValidation() { + VespaModel previous = tester.deploy(null, getServices(2), Environment.prod, null).getFirst(); + tester.deploy(previous, getServices(3), Environment.prod, redundancyIncreaseOverride); // Allowed due to override + } + + private static String getServices(int redundancy) { + return "<services version='1.0'>" + + " <content id='contentClusterId' version='1.0'>" + + " <redundancy>" + redundancy + "</redundancy>" + + " <engine>" + + " <proton/>" + + " </engine>" + + " <documents>" + + " <document type='music' mode='index'/>" + + " </documents>" + + " <nodes count='3'/>" + + " </content>" + + "</services>"; + } + + private static final String redundancyIncreaseOverride = + "<validation-overrides>\n" + + " <allow until='2000-01-03'>redundancy-increase</allow>\n" + + "</validation-overrides>\n"; + +} |