From 22df37ca85086a09612868825c7b72a8aaa921c5 Mon Sep 17 00:00:00 2001 From: jonmv Date: Wed, 19 Apr 2023 14:23:04 +0200 Subject: Forbid applications without a container cluster in hosted Vespa --- .../validation/ContainerInCloudValidator.java | 19 +++++++ .../model/application/validation/Validation.java | 1 + .../validation/ContainerInCloudValidatorTest.java | 60 ++++++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 config-model/src/main/java/com/yahoo/vespa/model/application/validation/ContainerInCloudValidator.java create mode 100644 config-model/src/test/java/com/yahoo/vespa/model/application/validation/ContainerInCloudValidatorTest.java (limited to 'config-model') diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ContainerInCloudValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ContainerInCloudValidator.java new file mode 100644 index 00000000000..d9bf82980d7 --- /dev/null +++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ContainerInCloudValidator.java @@ -0,0 +1,19 @@ +package com.yahoo.vespa.model.application.validation; + +import com.yahoo.config.model.deploy.DeployState; +import com.yahoo.vespa.model.VespaModel; + +/** + * Validates that a Vespa Cloud application has at least one container cluster. + * + * @author jonmv + */ +public class ContainerInCloudValidator extends Validator { + + @Override + public void validate(VespaModel model, DeployState deployState) { + if (deployState.isHosted() && model.getContainerClusters().isEmpty()) + throw new IllegalArgumentException("Vespa Cloud applications must have at least one container cluster"); + } + +} 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 2576d9cb392..4f2f8e7932c 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 @@ -76,6 +76,7 @@ public class Validation { new StreamingValidator().validate(model, deployState); new RankSetupValidator(validationParameters.ignoreValidationErrors()).validate(model, deployState); new NoPrefixForIndexes().validate(model, deployState); + new ContainerInCloudValidator().validate(model, deployState); new DeploymentSpecValidator().validate(model, deployState); new ValidationOverridesValidator().validate(model, deployState); new ConstantValidator().validate(model, deployState); diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ContainerInCloudValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ContainerInCloudValidatorTest.java new file mode 100644 index 00000000000..3feb8888821 --- /dev/null +++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ContainerInCloudValidatorTest.java @@ -0,0 +1,60 @@ +package com.yahoo.vespa.model.application.validation; + +import com.yahoo.config.application.api.ApplicationPackage; +import com.yahoo.config.model.NullConfigModelRegistry; +import com.yahoo.config.model.deploy.DeployState; +import com.yahoo.config.model.deploy.TestProperties; +import com.yahoo.config.model.test.MockApplicationPackage; +import com.yahoo.vespa.model.VespaModel; +import org.junit.jupiter.api.Test; +import org.xml.sax.SAXException; + +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class ContainerInCloudValidatorTest { + + @Test + void failsWhenNoContainerInCloud() throws IOException, SAXException { + String noContainer = ""; + String container = """ + + + + """; + runValidatorOnApp(false, container); + runValidatorOnApp(false, noContainer); + runValidatorOnApp(true, container); + assertEquals("Vespa Cloud applications must have at least one container cluster", + assertThrows(IllegalArgumentException.class, + () -> runValidatorOnApp(true, noContainer)) + .getMessage()); + } + + private static void runValidatorOnApp(boolean isHosted, String container) throws IOException, SAXException { + String servicesXml = """ + + %s + + 2 + + + + + + """.formatted(container); + ApplicationPackage app = new MockApplicationPackage.Builder() + .withServices(servicesXml) + .build(); + DeployState deployState = new DeployState.Builder() + .applicationPackage(app) + .properties(new TestProperties().setHostedVespa(isHosted).setAllowUserFilters(false)) + .build(); + VespaModel model = new VespaModel(new NullConfigModelRegistry(), deployState); + new ContainerInCloudValidator().validate(model, deployState); + } + +} -- cgit v1.2.3