summaryrefslogtreecommitdiffstats
path: root/config-model/src
diff options
context:
space:
mode:
authorMorten Tokle <mortent@yahooinc.com>2022-11-30 15:49:30 +0100
committerMorten Tokle <mortent@yahooinc.com>2022-11-30 15:49:30 +0100
commit1f801694fe726cd3ebf1dfd10161355573a3af69 (patch)
treee39e109f7eb0bf3e0354a5934c0844ae7ff85d65 /config-model/src
parentf611155a289870ad02b79e0cb9068a9fa1d55f67 (diff)
Add validation override for certificate removal
Diffstat (limited to 'config-model/src')
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java1
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/CertificateRemovalChangeValidator.java47
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/CertificateRemovalChangeValidatorTest.java51
3 files changed, 99 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 68b5adcc84f..b81b3524c67 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
@@ -86,6 +86,7 @@ public class Validation {
new CloudWatchValidator().validate(model, deployState);
new QuotaValidator().validate(model, deployState);
new UriBindingsValidator().validate(model, deployState);
+ new CloudDataPlaneFilterValidator().validate(model, deployState);
additionalValidators.forEach(v -> v.validate(model, deployState));
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/CertificateRemovalChangeValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/CertificateRemovalChangeValidator.java
new file mode 100644
index 00000000000..50fd6572bcc
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/CertificateRemovalChangeValidator.java
@@ -0,0 +1,47 @@
+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.vespa.model.VespaModel;
+import com.yahoo.vespa.model.container.http.Client;
+
+import java.security.cert.X509Certificate;
+import java.time.Instant;
+import java.util.Collection;
+import java.util.List;
+
+public class CertificateRemovalChangeValidator implements ChangeValidator {
+ @Override
+ public List<ConfigChangeAction> validate(VespaModel current, VespaModel next, ValidationOverrides overrides, Instant now) {
+
+ current.getContainerClusters()
+ .forEach((clusterId, currentCluster) -> {
+ validateClients(clusterId, currentCluster.getClients(), next.getContainerClusters().get(clusterId).getClients(), overrides, now);
+ });
+
+ return List.of();
+ }
+
+ void validateClients(String clusterId, List<Client> current, List<Client> next, ValidationOverrides overrides, Instant now) {
+
+ List<X509Certificate> currentCertificates = current.stream()
+ .map(Client::certificates)
+ .flatMap(Collection::stream)
+ .toList();
+ List<X509Certificate> nextCertificates = next.stream()
+ .map(Client::certificates)
+ .flatMap(Collection::stream)
+ .toList();
+
+ List<X509Certificate> missingCerts = currentCertificates.stream().filter(cert -> !nextCertificates.contains(cert)).toList();
+ if (!missingCerts.isEmpty()) {
+ overrides.invalid(ValidationId.certificateRemoval,
+ "Data plane certificate(s) from cluster '" + clusterId + "' is removed " +
+ "(removed certificates: " + missingCerts.stream().map(x509Certificate -> x509Certificate.getSubjectX500Principal().getName()).toList() + ") " +
+ "This can cause client connection issues.",
+ now);
+ }
+
+ }
+}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/CertificateRemovalChangeValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/CertificateRemovalChangeValidatorTest.java
new file mode 100644
index 00000000000..f89c75362da
--- /dev/null
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/CertificateRemovalChangeValidatorTest.java
@@ -0,0 +1,51 @@
+package com.yahoo.vespa.model.application.validation.change;
+
+import com.yahoo.config.application.api.ValidationOverrides;
+import com.yahoo.security.X509CertificateUtils;
+import com.yahoo.vespa.model.container.http.Client;
+import org.junit.jupiter.api.Test;
+
+import java.security.cert.X509Certificate;
+import java.time.Duration;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+public class CertificateRemovalChangeValidatorTest {
+
+ private static final String validationOverrides =
+ "<validation-overrides>\n" +
+ " <allow until='2000-01-14' comment='test override'>certificate-removal</allow>\n" +
+ "</validation-overrides>\n";
+
+ @Test
+ void validate() {
+ Instant now = LocalDate.parse("2000-01-01", DateTimeFormatter.ISO_DATE).atStartOfDay().atZone(ZoneOffset.UTC).toInstant();
+
+ Client c1 = new Client("c1", List.of(), List.of(certificate("cn=c1")));
+ Client c2 = new Client("c2", List.of(), List.of(certificate("cn=c2")));
+ Client c3 = new Client("c3", List.of(), List.of(certificate("cn=c3")));
+
+ CertificateRemovalChangeValidator validator = new CertificateRemovalChangeValidator();
+
+ // Adding certs -> ok
+ validator.validateClients("clusterId", List.of(c1,c2), List.of(c1, c2, c3), ValidationOverrides.empty, now);
+
+ // Removing certs -> fails
+ assertThrows(ValidationOverrides.ValidationException.class,
+ () ->validator.validateClients("clusterId", List.of(c1, c2, c3), List.of(c1, c3), ValidationOverrides.empty, now));
+
+ // Removing certs with validationoverrides -> ok
+ validator.validateClients("clusterId", List.of(c1, c2, c3), List.of(c1, c3), ValidationOverrides.fromXml(validationOverrides), now);
+
+ }
+
+ static X509Certificate certificate(String cn) {
+ return X509CertificateUtils.createSelfSigned(cn, Duration.ofHours(1)).certificate();
+ }
+
+}