summaryrefslogtreecommitdiffstats
path: root/config-model
diff options
context:
space:
mode:
authorjonmv <venstad@gmail.com>2023-04-19 14:23:04 +0200
committerjonmv <venstad@gmail.com>2023-04-20 14:17:34 +0200
commit22df37ca85086a09612868825c7b72a8aaa921c5 (patch)
treea6d5b0f0b4ec78cdf5d2e247b9f3480a6a7c7134 /config-model
parent687be0d6e22caca23708de1493fb483069bbab0a (diff)
Forbid applications without a container cluster in hosted Vespa
Diffstat (limited to 'config-model')
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/ContainerInCloudValidator.java19
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java1
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/ContainerInCloudValidatorTest.java60
3 files changed, 80 insertions, 0 deletions
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 = """
+ <container id='default' version='1.0'>
+ <nodes count='2' />
+ </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 = """
+ <services version='1.0'>
+ %s
+ <content version='1.0'>
+ <redundancy>2</redundancy>
+ <documents>
+ </documents>
+ <nodes count='2' />
+ </content>
+ </services>
+ """.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);
+ }
+
+}