diff options
Diffstat (limited to 'config-model/src')
3 files changed, 119 insertions, 0 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 84c7a48a998..d59ad5f6252 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 @@ -70,6 +70,7 @@ public class Validation { new RankSetupValidator(validationParameters.ignoreValidationErrors()).validate(model, deployState); new NoPrefixForIndexes().validate(model, deployState); new DeploymentSpecValidator().validate(model, deployState); + new ValidationOverridesValidator().validate(model, deployState); new RankingConstantsValidator().validate(model, deployState); new SecretStoreValidator().validate(model, deployState); new EndpointCertificateSecretsValidator().validate(model, deployState); diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ValidationOverridesValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ValidationOverridesValidator.java new file mode 100644 index 00000000000..0095c2c335d --- /dev/null +++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ValidationOverridesValidator.java @@ -0,0 +1,29 @@ +// 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; + +import com.yahoo.config.application.api.ValidationOverrides; +import com.yahoo.config.model.deploy.DeployState; +import com.yahoo.vespa.model.VespaModel; + +import java.io.Reader; +import java.time.Duration; +import java.util.Optional; + +/** + * Validate validation overrides (validation-overrides.xml). Done as a validator to make sure this is + * done when validating the mode and not when building the model + * + * @author hmusum + */ +public class ValidationOverridesValidator extends Validator { + + @Override + public void validate(VespaModel model, DeployState deployState) { + Optional<Reader> overrides = deployState.getApplicationPackage().getValidationOverrides(); + if (overrides.isEmpty()) return; + + // Dates are validated in constructor + ValidationOverrides.fromXml(overrides.get()); + } + +} diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ValidationOverridesValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ValidationOverridesValidatorTest.java new file mode 100644 index 00000000000..453bdf98ce7 --- /dev/null +++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ValidationOverridesValidatorTest.java @@ -0,0 +1,89 @@ +// 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; + +import com.yahoo.config.model.NullConfigModelRegistry; +import com.yahoo.config.model.deploy.DeployState; +import com.yahoo.config.model.test.MockApplicationPackage; +import com.yahoo.vespa.model.VespaModel; +import org.junit.Test; +import org.xml.sax.SAXException; + +import java.io.IOException; +import java.time.Duration; +import java.time.Instant; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +/** + * @author hmusum + */ +public class ValidationOverridesValidatorTest { + + private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd") + .withZone(ZoneId.systemDefault()); + + @Test + public void testValidationOverride() throws IOException, SAXException { + String tenDays = dateTimeFormatter.format(Instant.now().plus(Duration.ofDays(10))); + + var validationOverridesXml = "<?xml version='1.0' encoding='UTF-8'?>\n" + + " <validation-overrides>\n" + + " <allow until='" + tenDays + "'>deployment-removal</allow>\n" + + " </validation-overrides>"; + + var deployState = createDeployState(validationOverridesXml); + new VespaModel(new NullConfigModelRegistry(), deployState); + } + + @Test + public void testFailsWhenValidationOverrideIsTooFarInFuture() { + Instant now = Instant.now(); + String sixtyDays = dateTimeFormatter.format(now.plus(Duration.ofDays(60))); + String sixtyOneDays = dateTimeFormatter.format(now.plus(Duration.ofDays(61))); + + var validationOverrides = "<?xml version='1.0' encoding='UTF-8'?>\n" + + "<validation-overrides>\n" + + " <allow until='" + sixtyDays + "'>deployment-removal</allow>\n" + + "</validation-overrides>"; + assertValidationError("validation-overrides is invalid: allow 'deployment-removal' until " + + sixtyOneDays + "T00:00:00Z is too far in the future: Max 30 days is allowed", validationOverrides); + } + + private static void assertValidationError(String message, String validationOverridesXml) { + try { + var deployState = createDeployState(validationOverridesXml); + new VespaModel(new NullConfigModelRegistry(), deployState); + fail("Did not get expected exception"); + } catch (IllegalArgumentException e) { + assertEquals(message, e.getMessage()); + } catch (SAXException|IOException e) { + throw new RuntimeException(e); + } + } + + private static DeployState createDeployState(String validationOverridesXml) { + var services = "<services version='1.0'>" + + " <admin version='2.0'>" + + " <adminserver hostalias='node0' />" + + " </admin>" + + " <container id='default' version='1.0'>" + + " <search/>" + + " <nodes>" + + " <node hostalias='node0'/>" + + " </nodes>" + + " </container>" + + "</services>"; + + var app = new MockApplicationPackage.Builder() + .withValidationOverrides(validationOverridesXml) + .withServices(services) + .build(); + var builder = new DeployState.Builder().applicationPackage(app); + return builder.build(); + } + +} + |