diff options
author | Bjørn Christian Seime <bjorncs@yahooinc.com> | 2022-11-23 14:10:29 +0100 |
---|---|---|
committer | Bjørn Christian Seime <bjorncs@yahooinc.com> | 2022-11-25 16:29:28 +0100 |
commit | 6b94dfc1fa9461a12e2d267c8c07fc0837f524de (patch) | |
tree | ca3e15b47e9fa677918f811a0f797c14d9b20efe /config-model/src | |
parent | 00013a88a85d0b925f239697cad15876ce2e6b53 (diff) |
Add cloud data plane filter chains for cloud
Diffstat (limited to 'config-model/src')
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()); } |