summaryrefslogtreecommitdiffstats
path: root/config-model/src
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@yahooinc.com>2022-11-23 14:10:29 +0100
committerBjørn Christian Seime <bjorncs@yahooinc.com>2022-11-25 16:29:28 +0100
commit6b94dfc1fa9461a12e2d267c8c07fc0837f524de (patch)
treeca3e15b47e9fa677918f811a0f797c14d9b20efe /config-model/src
parent00013a88a85d0b925f239697cad15876ce2e6b53 (diff)
Add cloud data plane filter chains for cloud
Diffstat (limited to 'config-model/src')
-rwxr-xr-xconfig-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java8
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/component/SystemBindingPattern.java1
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/xml/CloudDataPlaneFilter.java19
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java46
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/container/xml/CloudDataPlaneFilterTest.java11
5 files changed, 74 insertions, 11 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
index 774e90c81f4..f1b3c74a55d 100755
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
@@ -162,7 +162,8 @@ public abstract class ContainerCluster<CONTAINER extends Container>
private String jvmGCOptions = null;
private boolean deferChangesUntilRestart = false;
- private List<Client> clients;
+ private boolean clientsLegacyMode;
+ private List<Client> clients = List.of();
public ContainerCluster(AbstractConfigProducer<?> parent, String configSubId, String clusterId, DeployState deployState, boolean zooKeeperLocalhostAffinity) {
this(parent, configSubId, clusterId, deployState, zooKeeperLocalhostAffinity, 1);
@@ -354,7 +355,8 @@ public abstract class ContainerCluster<CONTAINER extends Container>
return http;
}
- public void setClients(List<Client> clients) {
+ public void setClients(boolean legacyMode, List<Client> clients) {
+ clientsLegacyMode = legacyMode;
this.clients = clients;
}
@@ -362,6 +364,8 @@ public abstract class ContainerCluster<CONTAINER extends Container>
return clients;
}
+ public boolean clientsLegacyMode() { return clientsLegacyMode; }
+
public ContainerDocproc getDocproc() {
return containerDocproc;
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/component/SystemBindingPattern.java b/config-model/src/main/java/com/yahoo/vespa/model/container/component/SystemBindingPattern.java
index 201e26d3575..606557670a5 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/component/SystemBindingPattern.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/component/SystemBindingPattern.java
@@ -14,6 +14,7 @@ public class SystemBindingPattern extends BindingPattern {
public static SystemBindingPattern fromHttpPath(String path) { return new SystemBindingPattern("http", "*", null, path);}
public static SystemBindingPattern fromPattern(String binding) { return new SystemBindingPattern(binding);}
public static SystemBindingPattern fromHttpPortAndPath(String port, String path) { return new SystemBindingPattern("http", "*", port, path); }
+ public static SystemBindingPattern fromHttpPortAndPath(int port, String path) { return new SystemBindingPattern("http", "*", Integer.toString(port), path); }
@Override
public String toString() {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/CloudDataPlaneFilter.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/CloudDataPlaneFilter.java
index 97cc34f2d7a..6767a61d02b 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/CloudDataPlaneFilter.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/CloudDataPlaneFilter.java
@@ -1,17 +1,19 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.container.xml;
+import com.yahoo.component.ComponentSpecification;
+import com.yahoo.component.chain.dependencies.Dependencies;
+import com.yahoo.component.chain.model.ChainedComponentModel;
import com.yahoo.container.bundle.BundleInstantiationSpecification;
import com.yahoo.jdisc.http.filter.security.cloud.config.CloudDataPlaneFilterConfig;
-import com.yahoo.osgi.provider.model.ComponentModel;
import com.yahoo.security.X509CertificateUtils;
import com.yahoo.vespa.model.container.ApplicationContainerCluster;
-import com.yahoo.vespa.model.container.component.SimpleComponent;
import com.yahoo.vespa.model.container.http.Client;
+import com.yahoo.vespa.model.container.http.Filter;
import java.util.List;
-public class CloudDataPlaneFilter extends SimpleComponent implements CloudDataPlaneFilterConfig.Producer {
+class CloudDataPlaneFilter extends Filter implements CloudDataPlaneFilterConfig.Producer {
private static final String CLASS = "com.yahoo.jdisc.http.filter.security.cloud.CloudDataPlaneFilter";
private static final String BUNDLE = "jdisc-security-filters";
@@ -19,12 +21,19 @@ public class CloudDataPlaneFilter extends SimpleComponent implements CloudDataPl
private final ApplicationContainerCluster cluster;
private final boolean legacyMode;
- public CloudDataPlaneFilter(ApplicationContainerCluster cluster, boolean legacyMode) {
- super(new ComponentModel(BundleInstantiationSpecification.fromStrings(CLASS, CLASS, BUNDLE)));
+ CloudDataPlaneFilter(ApplicationContainerCluster cluster, boolean legacyMode) {
+ super(model());
this.cluster = cluster;
this.legacyMode = legacyMode;
}
+ private static ChainedComponentModel model() {
+ return new ChainedComponentModel(
+ new BundleInstantiationSpecification(
+ new ComponentSpecification(CLASS), null, new ComponentSpecification(BUNDLE)),
+ Dependencies.emptyDependencies());
+ }
+
@Override
public void getConfig(CloudDataPlaneFilterConfig.Builder builder) {
if (legacyMode) {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
index 97355c647ba..0c0920ed4e8 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
@@ -2,7 +2,11 @@
package com.yahoo.vespa.model.container.xml;
import com.google.common.collect.ImmutableList;
+import com.yahoo.component.ComponentId;
+import com.yahoo.component.ComponentSpecification;
import com.yahoo.component.Version;
+import com.yahoo.component.chain.dependencies.Dependencies;
+import com.yahoo.component.chain.model.ChainedComponentModel;
import com.yahoo.config.application.Xml;
import com.yahoo.config.application.api.ApplicationFile;
import com.yahoo.config.application.api.ApplicationPackage;
@@ -31,7 +35,7 @@ import com.yahoo.config.provision.HostName;
import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provision.Zone;
-import com.yahoo.container.jdisc.AclMapping;
+import com.yahoo.container.bundle.BundleInstantiationSpecification;
import com.yahoo.container.logging.FileConnectionLog;
import com.yahoo.osgi.provider.model.ComponentModel;
import com.yahoo.path.Path;
@@ -72,11 +76,14 @@ import com.yahoo.vespa.model.container.component.Handler;
import com.yahoo.vespa.model.container.component.SimpleComponent;
import com.yahoo.vespa.model.container.component.SystemBindingPattern;
import com.yahoo.vespa.model.container.component.UserBindingPattern;
+import com.yahoo.vespa.model.container.component.chain.Chain;
import com.yahoo.vespa.model.container.docproc.ContainerDocproc;
import com.yahoo.vespa.model.container.docproc.DocprocChains;
import com.yahoo.vespa.model.container.http.AccessControl;
import com.yahoo.vespa.model.container.http.Client;
import com.yahoo.vespa.model.container.http.ConnectorFactory;
+import com.yahoo.vespa.model.container.http.Filter;
+import com.yahoo.vespa.model.container.http.FilterBinding;
import com.yahoo.vespa.model.container.http.FilterChains;
import com.yahoo.vespa.model.container.http.Http;
import com.yahoo.vespa.model.container.http.JettyHttpServer;
@@ -112,6 +119,7 @@ import java.util.logging.Level;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
+import static com.yahoo.vespa.model.container.ContainerCluster.VIP_HANDLER_BINDING;
import static java.util.logging.Level.WARNING;
/**
@@ -446,9 +454,42 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
addHostedImplicitAccessControlIfNotPresent(deployState, cluster);
addDefaultConnectorHostedFilterBinding(cluster);
addAdditionalHostedConnector(deployState, cluster, context);
+ addCloudDataPlaneFilter(deployState, cluster);
}
}
+ private static void addCloudDataPlaneFilter(DeployState deployState, ApplicationContainerCluster cluster) {
+ if (!deployState.isHosted() || !deployState.zone().system().isPublic() || !deployState.featureFlags().enableDataPlaneFilter()) return;
+
+ // Setup secure filter chain
+ var secureChain = new Chain<Filter>(FilterChains.emptyChainSpec(ComponentId.fromString("cloud-data-plane-secure")));
+ secureChain.addInnerComponent(new CloudDataPlaneFilter(cluster, cluster.clientsLegacyMode()));
+ cluster.getHttp().getFilterChains().add(secureChain);
+ // Set cloud data plane filter as default request filter chain for data plane connector
+ cluster.getHttp().getHttpServer().orElseThrow().getConnectorFactories().stream()
+ .filter(c -> c.getListenPort() == HOSTED_VESPA_DATAPLANE_PORT).findAny().orElseThrow()
+ .setDefaultRequestFilterChain(secureChain.getComponentId());
+
+ // Setup insecure filter chain
+ var insecureChain = new Chain<Filter>(FilterChains.emptyChainSpec(ComponentId.fromString("cloud-data-plane-insecure")));
+ insecureChain.addInnerComponent(new Filter(
+ new ChainedComponentModel(
+ new BundleInstantiationSpecification(
+ new ComponentSpecification("com.yahoo.jdisc.http.filter.security.misc.NoopFilter"),
+ null, new ComponentSpecification("jdisc-security-filters")),
+ Dependencies.emptyDependencies())));
+ cluster.getHttp().getFilterChains().add(insecureChain);
+ var insecureChainComponentSpec = new ComponentSpecification(insecureChain.getComponentId().toString());
+ FilterBinding insecureBinding =
+ FilterBinding.create(FilterBinding.Type.REQUEST, insecureChainComponentSpec, VIP_HANDLER_BINDING);
+ cluster.getHttp().getBindings().add(insecureBinding);
+ // Set insecure filter as default request filter chain for default connector
+ cluster.getHttp().getHttpServer().orElseThrow().getConnectorFactories().stream()
+ .filter(c -> c.getListenPort() == Defaults.getDefaults().vespaWebServicePort()).findAny().orElseThrow()
+ .setDefaultRequestFilterChain(insecureChain.getComponentId());
+
+ }
+
protected void addClients(DeployState deployState, Element spec, ApplicationContainerCluster cluster, ConfigModelContext context) {
if (!deployState.isHosted() || !deployState.zone().system().isPublic() || !deployState.featureFlags().enableDataPlaneFilter()) return;
@@ -466,8 +507,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
.map(this::getCLient)
.toList();
}
- cluster.setClients(clients);
- cluster.addComponent(new CloudDataPlaneFilter(cluster, legacyMode));
+ cluster.setClients(legacyMode, clients);
}
private Client getCLient(Element clientElement) {
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/CloudDataPlaneFilterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/CloudDataPlaneFilterTest.java
index bfde7fa1939..0f99f1c67c9 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/CloudDataPlaneFilterTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/CloudDataPlaneFilterTest.java
@@ -11,6 +11,7 @@ import com.yahoo.config.provision.RegionName;
import com.yahoo.config.provision.SystemName;
import com.yahoo.config.provision.Zone;
import com.yahoo.jdisc.http.ConnectorConfig;
+import com.yahoo.jdisc.http.ServerConfig;
import com.yahoo.jdisc.http.filter.security.cloud.config.CloudDataPlaneFilterConfig;
import com.yahoo.security.KeyAlgorithm;
import com.yahoo.security.KeyUtils;
@@ -39,6 +40,7 @@ import java.util.Optional;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertIterableEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
public class CloudDataPlaneFilterTest extends ContainerModelBuilderTestBase {
@@ -80,7 +82,9 @@ public class CloudDataPlaneFilterTest extends ContainerModelBuilderTestBase {
.build();
createModel(root, state, null, clusterElem);
- CloudDataPlaneFilterConfig config = root.getConfig(CloudDataPlaneFilterConfig.class, "container/component/com.yahoo.jdisc.http.filter.security.cloud.CloudDataPlaneFilter");
+ String configId = "container/filters/chain/cloud-data-plane-secure/component/" +
+ "com.yahoo.jdisc.http.filter.security.cloud.CloudDataPlaneFilter";
+ CloudDataPlaneFilterConfig config = root.getConfig(CloudDataPlaneFilterConfig.class, configId);
assertFalse(config.legacyMode());
List<CloudDataPlaneFilterConfig.Clients> clients = config.clients();
assertEquals(1, clients.size());
@@ -100,6 +104,11 @@ public class CloudDataPlaneFilterTest extends ContainerModelBuilderTestBase {
var caCerts = X509CertificateUtils.certificateListFromPem(connectorConfig.ssl().caCertificate());
assertEquals(1, caCerts.size());
assertEquals(List.of(certificate), caCerts);
+ var srvCfg = root.getConfig(ServerConfig.class, "container/http");
+ assertEquals("cloud-data-plane-insecure", srvCfg.defaultFilters().get(0).filterId());
+ assertEquals(8080, srvCfg.defaultFilters().get(0).localPort());
+ assertEquals("cloud-data-plane-secure", srvCfg.defaultFilters().get(1).filterId());
+ assertEquals(4443, srvCfg.defaultFilters().get(1).localPort());
}