diff options
author | Morten Tokle <mortent@yahooinc.com> | 2022-09-14 08:21:53 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-14 08:21:53 +0200 |
commit | 90a5bc37eeac0ec786dca81d00e677ebba850ece (patch) | |
tree | dda73b671adbe6037b644f2a688b8f7e95e510aa /config-model/src/test | |
parent | 0857b11fef43e59dac7f5d01ea4f0cb721f8f00b (diff) | |
parent | d110e8cc51a8450eb340b875e31b5fc193f7797f (diff) |
Merge pull request #24037 from vespa-engine/mortent/restrict-data-plane-bindings
restrict data plane bindings
Diffstat (limited to 'config-model/src/test')
2 files changed, 121 insertions, 1 deletions
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/UriBindingsValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/UriBindingsValidatorTest.java index 7c16d3c99cf..ff9596f2062 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/UriBindingsValidatorTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/UriBindingsValidatorTest.java @@ -58,6 +58,11 @@ public class UriBindingsValidatorTest { } @Test + void allows_portbinding_when_restricting_data_plane() throws IOException, SAXException { + runUriBindingValidator(new TestProperties().setHostedVespa(true).setUseRestrictedDataPlaneBindings(true), createServicesXmlWithHandler("http://*:4443/my-handler")); + } + + @Test void allows_user_binding_with_wildcard_port() throws IOException, SAXException { runUriBindingValidator(true, createServicesXmlWithHandler("http://*:*/my-handler")); } @@ -68,12 +73,16 @@ public class UriBindingsValidatorTest { } private void runUriBindingValidator(boolean isHosted, String servicesXml) throws IOException, SAXException { + runUriBindingValidator(new TestProperties().setHostedVespa(isHosted), servicesXml); + } + + private void runUriBindingValidator(TestProperties testProperties, String servicesXml) throws IOException, SAXException { ApplicationPackage app = new MockApplicationPackage.Builder() .withServices(servicesXml) .build(); DeployState deployState = new DeployState.Builder() .applicationPackage(app) - .properties(new TestProperties().setHostedVespa(isHosted)) + .properties(testProperties) .build(); VespaModel model = new VespaModel(new NullConfigModelRegistry(), deployState); new UriBindingsValidator().validate(model, deployState); diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/HandlerBuilderTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/HandlerBuilderTest.java index 291a5f21305..186842ecbf1 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/HandlerBuilderTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/HandlerBuilderTest.java @@ -1,6 +1,8 @@ package com.yahoo.vespa.model.container.xml; import com.yahoo.config.model.builder.xml.test.DomBuilderTest; +import com.yahoo.config.model.deploy.DeployState; +import com.yahoo.config.model.deploy.TestProperties; import com.yahoo.container.ComponentsConfig; import com.yahoo.container.jdisc.JdiscBindingsConfig; import com.yahoo.container.usability.BindingsOverviewHandler; @@ -10,10 +12,14 @@ import com.yahoo.vespa.model.container.component.Handler; import org.junit.jupiter.api.Test; import org.w3c.dom.Element; +import java.util.List; +import java.util.Map; + import static com.yahoo.vespa.model.container.ContainerCluster.ROOT_HANDLER_BINDING; import static com.yahoo.vespa.model.container.ContainerCluster.STATE_HANDLER_BINDING_1; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.hasItem; import static org.junit.jupiter.api.Assertions.*; @@ -100,6 +106,111 @@ public class HandlerBuilderTest extends ContainerModelBuilderTestBase { assertTrue(handler.getInjectedComponentIds().contains("threadpool@default-handler-common")); } + @Test + void restricts_default_bindings_in_hosted_vespa() { + DeployState deployState = new DeployState.Builder() + .properties(new TestProperties().setHostedVespa(true).setUseRestrictedDataPlaneBindings(true)) + .build(); + verifyDefaultBindings(deployState, "http://*:4443"); + } + + @Test + void does_not_restrict_default_bindings_in_hosted_vespa_when_disabled() { + DeployState deployState = new DeployState.Builder() + .properties(new TestProperties().setHostedVespa(true).setUseRestrictedDataPlaneBindings(false)) + .build(); + verifyDefaultBindings(deployState, "http://*"); + } + + @Test + void restricts_custom_bindings_in_hosted_vespa() { + DeployState deployState = new DeployState.Builder() + .properties(new TestProperties().setHostedVespa(true).setUseRestrictedDataPlaneBindings(true)) + .build(); + verifyCustomSearchBindings(deployState, "http://*:4443"); + } + + @Test + void does_not_restrict_default_bindings_in_self_hosted() { + DeployState deployState = new DeployState.Builder() + .properties(new TestProperties().setHostedVespa(false).setUseRestrictedDataPlaneBindings(false)) + .build(); + verifyDefaultBindings(deployState, "http://*"); + } + + @Test + void does_not_restrict_custom_bindings_in_self_hosted() { + DeployState deployState = new DeployState.Builder() + .properties(new TestProperties().setHostedVespa(false).setUseRestrictedDataPlaneBindings(false)) + .build(); + verifyCustomSearchBindings(deployState, "http://*"); + } + + private void verifyDefaultBindings(DeployState deployState, String bindingPrefix) { + Element clusterElem = DomBuilderTest.parse( + "<container id='default' version='1.0'>", + " <search/>", + " <document-api/>", + " <handler id='FooHandler'>", + " <binding>http://*/foo</binding>", + " </handler>", + nodesXml, + "</container>"); + + createModel(root, deployState, null, clusterElem); + JdiscBindingsConfig bindingsConfig = root.getConfig(JdiscBindingsConfig.class, "default"); + + // Verify /search /feed /document and custom handler are bound correctly + Map<String, JdiscBindingsConfig.Handlers> handlers = bindingsConfig.handlers(); + Map<String, List<String>> expectedHandlerMappings = Map.of( + "com.yahoo.search.handler.SearchHandler", List.of("/search/*"), + "com.yahoo.document.restapi.resource.DocumentV1ApiHandler", List.of("/document/v1/*", "/document/v1/*/"), + "com.yahoo.vespa.http.server.FeedHandler", List.of("/reserved-for-internal-use/feedapi", "/reserved-for-internal-use/feedapi/"), + "FooHandler", List.of("/foo")); + expectedHandlerMappings.forEach((handler, bindings) -> validateHandler(handlers.get(handler), bindingPrefix, bindings)); + + // All other handlers should be bound to default (http://*/...) + handlers.entrySet().stream() + .filter(e -> ! expectedHandlerMappings.containsKey(e.getKey())) + .forEach(e -> assertTrue(e.getValue().serverBindings().stream().allMatch(s -> s.startsWith("http://*/")))); + } + + private void verifyCustomSearchBindings(DeployState deployState, String bindingPrefix) { + Element clusterElem = DomBuilderTest.parse( + "<container id='default' version='1.0'>", + " <search>", + " <binding>http://*/search-binding/</binding>", + " </search>", + " <document-api>", + " <binding>http://*/docapi-binding/</binding>", + " </document-api>", + nodesXml, + "</container>"); + + createModel(root, deployState, null, clusterElem); + JdiscBindingsConfig bindingsConfig = root.getConfig(JdiscBindingsConfig.class, "default"); + + // Verify search feed and document handler are bound correctly + Map<String, JdiscBindingsConfig.Handlers> handlers = bindingsConfig.handlers(); + Map<String, List<String>> expectedHandlerMappings = Map.of( + "com.yahoo.search.handler.SearchHandler", List.of("/search-binding/"), + "com.yahoo.document.restapi.resource.DocumentV1ApiHandler", List.of("/docapi-binding/document/v1/*", "/docapi-binding/document/v1/*/"), + "com.yahoo.vespa.http.server.FeedHandler", List.of("/docapi-binding/reserved-for-internal-use/feedapi", "/docapi-binding/reserved-for-internal-use/feedapi/")); + expectedHandlerMappings.forEach((handler, bindings) -> validateHandler(handlers.get(handler), bindingPrefix, bindings)); + + // All other handlers should be bound to default (http://*/...) + handlers.entrySet().stream() + .filter(e -> ! expectedHandlerMappings.containsKey(e.getKey())) + .forEach(e -> assertTrue(e.getValue().serverBindings().stream().allMatch(s -> s.startsWith("http://*/")))); + + } + + private void validateHandler(JdiscBindingsConfig.Handlers handler, String bindingPrefix, List<String> expectedBindings) { + assertNotNull(handler); + assertEquals(expectedBindings.size(), handler.serverBindings().size()); + assertThat(handler.serverBindings(), containsInAnyOrder(expectedBindings.stream().map(s->bindingPrefix+s).toArray())); + } + private void createClusterWithJDiscHandler() { Element clusterElem = DomBuilderTest.parse( "<container id='default' version='1.0'>", |