Skip to content

Commit

Permalink
Merge pull request #24021 from vespa-engine/mortent/revert-restrict-d…
Browse files Browse the repository at this point in the history
…p-bindings

Revert "Restrict data plane bindings"
  • Loading branch information
Harald Musum authored Sep 12, 2022
2 parents bea3884 + 35730b5 commit 5f654b6
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 196 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import com.yahoo.vespa.model.container.xml.BundleInstantiationSpecificationBuilder;
import org.w3c.dom.Element;

import java.util.OptionalInt;
import java.util.Set;

import static com.yahoo.vespa.model.container.ApplicationContainerCluster.METRICS_V2_HANDLER_BINDING_1;
Expand All @@ -37,38 +36,23 @@ public class DomHandlerBuilder extends VespaDomBuilder.DomConfigProducerBuilder<
VIP_HANDLER_BINDING);

private final ApplicationContainerCluster cluster;
private OptionalInt portBindingOverride;

public DomHandlerBuilder(ApplicationContainerCluster cluster) {
this(cluster, OptionalInt.empty());
}
public DomHandlerBuilder(ApplicationContainerCluster cluster, OptionalInt portBindingOverride) {
this.cluster = cluster;
this.portBindingOverride = portBindingOverride;
}

@Override
protected Handler doBuild(DeployState deployState, AbstractConfigProducer<?> parent, Element handlerElement) {
Handler handler = createHandler(handlerElement);
OptionalInt port = portBindingOverride.isPresent() && deployState.isHosted() && deployState.featureFlags().useRestrictedDataPlaneBindings()
? portBindingOverride
: OptionalInt.empty();

for (Element binding : XML.getChildren(handlerElement, "binding"))
addServerBinding(handler, userBindingPattern(XML.getValue(binding), port), deployState.getDeployLogger());
addServerBinding(handler, UserBindingPattern.fromPattern(XML.getValue(binding)), deployState.getDeployLogger());

DomComponentBuilder.addChildren(deployState, parent, handlerElement, handler);

return handler;
}

private static UserBindingPattern userBindingPattern(String path, OptionalInt port) {
UserBindingPattern bindingPattern = UserBindingPattern.fromPattern(path);
return port.isPresent()
? bindingPattern.withPort(port.getAsInt())
: bindingPattern;
}

Handler createHandler(Element handlerElement) {
BundleInstantiationSpecification bundleSpec = BundleInstantiationSpecificationBuilder.build(handlerElement);
return new Handler(new ComponentModel(bundleSpec));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@
import com.yahoo.vespa.model.container.ContainerCluster;
import com.yahoo.vespa.model.container.ContainerThreadpool;
import com.yahoo.vespa.model.container.PlatformBundles;
import com.yahoo.vespa.model.container.component.BindingPattern;
import com.yahoo.vespa.model.container.component.Handler;
import com.yahoo.vespa.model.container.component.SystemBindingPattern;
import com.yahoo.vespa.model.container.component.UserBindingPattern;

import java.nio.file.Path;
import java.util.Collection;
import java.util.Collections;
import java.util.OptionalInt;

/**
* @author Einar M R Rosenvinge
Expand All @@ -28,29 +26,29 @@ public class ContainerDocumentApi {

private final boolean ignoreUndefinedFields;

public ContainerDocumentApi(ContainerCluster<?> cluster, HandlerOptions handlerOptions, boolean ignoreUndefinedFields, OptionalInt portOverride) {
public ContainerDocumentApi(ContainerCluster<?> cluster, HandlerOptions handlerOptions, boolean ignoreUndefinedFields) {
this.ignoreUndefinedFields = ignoreUndefinedFields;
addRestApiHandler(cluster, handlerOptions, portOverride);
addFeedHandler(cluster, handlerOptions, portOverride);
addRestApiHandler(cluster, handlerOptions);
addFeedHandler(cluster, handlerOptions);
addVespaClientContainerBundle(cluster);
}

public static void addVespaClientContainerBundle(ContainerCluster<?> c) {
c.addPlatformBundle(VESPACLIENT_CONTAINER_BUNDLE);
}

private static void addFeedHandler(ContainerCluster<?> cluster, HandlerOptions handlerOptions, OptionalInt portOverride) {
private static void addFeedHandler(ContainerCluster<?> cluster, HandlerOptions handlerOptions) {
String bindingSuffix = ContainerCluster.RESERVED_URI_PREFIX + "/feedapi";
var executor = new Threadpool("feedapi-handler", handlerOptions.feedApiThreadpoolOptions);
var handler = newVespaClientHandler("com.yahoo.vespa.http.server.FeedHandler",
bindingSuffix, handlerOptions, executor, portOverride);
bindingSuffix, handlerOptions, executor);
cluster.addComponent(handler);
}


private static void addRestApiHandler(ContainerCluster<?> cluster, HandlerOptions handlerOptions, OptionalInt portOverride) {
private static void addRestApiHandler(ContainerCluster<?> cluster, HandlerOptions handlerOptions) {
var handler = newVespaClientHandler("com.yahoo.document.restapi.resource.DocumentV1ApiHandler",
DOCUMENT_V1_PREFIX + "/*", handlerOptions, null, portOverride);
DOCUMENT_V1_PREFIX + "/*", handlerOptions, null);
cluster.addComponent(handler);

// We need to include a dummy implementation of the previous restapi handler (using the same class name).
Expand All @@ -64,37 +62,23 @@ private static void addRestApiHandler(ContainerCluster<?> cluster, HandlerOption
private static Handler newVespaClientHandler(String componentId,
String bindingSuffix,
HandlerOptions handlerOptions,
Threadpool executor,
OptionalInt portOverride) {
Threadpool executor) {
Handler handler = createHandler(componentId, executor);
if (handlerOptions.bindings.isEmpty()) {
handler.addServerBindings(
bindingPattern(bindingSuffix, portOverride),
bindingPattern(bindingSuffix + '/', portOverride));
SystemBindingPattern.fromHttpPath(bindingSuffix),
SystemBindingPattern.fromHttpPath(bindingSuffix + '/'));
} else {
for (String rootBinding : handlerOptions.bindings) {
String pathWithoutLeadingSlash = bindingSuffix.substring(1);
handler.addServerBindings(
userBindingPattern(rootBinding + pathWithoutLeadingSlash, portOverride),
userBindingPattern(rootBinding + pathWithoutLeadingSlash + '/', portOverride));
UserBindingPattern.fromPattern(rootBinding + pathWithoutLeadingSlash),
UserBindingPattern.fromPattern(rootBinding + pathWithoutLeadingSlash + '/'));
}
}
return handler;
}

private static BindingPattern bindingPattern(String path, OptionalInt port) {
return port.isPresent()
? SystemBindingPattern.fromHttpPortAndPath(Integer.toString(port.getAsInt()), path)
: SystemBindingPattern.fromHttpPath(path);
}

private static UserBindingPattern userBindingPattern(String path, OptionalInt port) {
UserBindingPattern bindingPattern = UserBindingPattern.fromPattern(path);
return port.isPresent()
? bindingPattern.withPort(port.getAsInt())
: bindingPattern;
}

private static Handler createHandler(String className, Threadpool executor) {
return new Handler(new ComponentModel(className, null, "vespaclient-container-plugin"),
executor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ public class UserBindingPattern extends BindingPattern {

public static UserBindingPattern fromHttpPath(String path) { return new UserBindingPattern("http", "*", null, path); }
public static UserBindingPattern fromPattern(String binding) { return new UserBindingPattern(binding); }
public UserBindingPattern withPort(int port) { return new UserBindingPattern(scheme(), host(), Integer.toString(port), path()); }

@Override
public String toString() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,35 +32,35 @@ public class HostedSslConnectorFactory extends ConnectorFactory {
*/
public static HostedSslConnectorFactory withProvidedCertificate(
String serverName, EndpointCertificateSecrets endpointCertificateSecrets, boolean enforceHandshakeClientAuth,
Collection<String> tlsCiphersOverride, boolean enableProxyProtocolMixedMode, int port) {
Collection<String> tlsCiphersOverride, boolean enableProxyProtocolMixedMode) {
ConfiguredDirectSslProvider sslProvider = createConfiguredDirectSslProvider(
serverName, endpointCertificateSecrets, DEFAULT_HOSTED_TRUSTSTORE, /*tlsCaCertificates*/null, enforceHandshakeClientAuth);
return new HostedSslConnectorFactory(sslProvider, false, enforceHandshakeClientAuth, tlsCiphersOverride, enableProxyProtocolMixedMode, port);
return new HostedSslConnectorFactory(sslProvider, false, enforceHandshakeClientAuth, tlsCiphersOverride, enableProxyProtocolMixedMode);
}

/**
* Create connector factory that uses a certificate provided by the config-model / configserver and a truststore configured by the application.
*/
public static HostedSslConnectorFactory withProvidedCertificateAndTruststore(
String serverName, EndpointCertificateSecrets endpointCertificateSecrets, String tlsCaCertificates,
Collection<String> tlsCiphersOverride, boolean enableProxyProtocolMixedMode, int port) {
Collection<String> tlsCiphersOverride, boolean enableProxyProtocolMixedMode) {
ConfiguredDirectSslProvider sslProvider = createConfiguredDirectSslProvider(
serverName, endpointCertificateSecrets, /*tlsCaCertificatesPath*/null, tlsCaCertificates, false);
return new HostedSslConnectorFactory(sslProvider, true, false, tlsCiphersOverride, enableProxyProtocolMixedMode, port);
return new HostedSslConnectorFactory(sslProvider, true, false, tlsCiphersOverride, enableProxyProtocolMixedMode);
}

/**
* Create connector factory that uses the default certificate and truststore provided by Vespa (through Vespa-global TLS configuration).
*/
public static HostedSslConnectorFactory withDefaultCertificateAndTruststore(String serverName, Collection<String> tlsCiphersOverride,
boolean enableProxyProtocolMixedMode, int port) {
return new HostedSslConnectorFactory(new DefaultSslProvider(serverName), true, false, tlsCiphersOverride, enableProxyProtocolMixedMode, port);
boolean enableProxyProtocolMixedMode) {
return new HostedSslConnectorFactory(new DefaultSslProvider(serverName), true, false, tlsCiphersOverride, enableProxyProtocolMixedMode);
}

private HostedSslConnectorFactory(SslProvider sslProvider, boolean enforceClientAuth,
boolean enforceHandshakeClientAuth, Collection<String> tlsCiphersOverride,
boolean enableProxyProtocolMixedMode, int port) {
super(new Builder("tls"+port, port).sslProvider(sslProvider));
boolean enableProxyProtocolMixedMode) {
super(new Builder("tls4443", 4443).sslProvider(sslProvider));
this.enforceClientAuth = enforceClientAuth;
this.enforceHandshakeClientAuth = enforceHandshakeClientAuth;
this.tlsCiphersOverride = tlsCiphersOverride;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.Set;
import java.util.function.Consumer;
import java.util.logging.Level;
Expand All @@ -115,9 +114,6 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
// Default path to vip status file for container in Hosted Vespa.
static final String HOSTED_VESPA_STATUS_FILE = Defaults.getDefaults().underVespaHome("var/vespa/load-balancer/status.html");

// Data plane port for hosted Vespa
static final int HOSTED_VESPA_DATAPLANE_PORT = 4443;

//Path to vip status file for container in Hosted Vespa. Only used if set, else use HOSTED_VESPA_STATUS_FILE
private static final String HOSTED_VESPA_STATUS_FILE_SETTING = "VESPA_LB_STATUS_FILE";

Expand Down Expand Up @@ -454,11 +450,11 @@ private void addAdditionalHostedConnector(DeployState deployState, ApplicationCo

connectorFactory = authorizeClient
? HostedSslConnectorFactory.withProvidedCertificateAndTruststore(
serverName, endpointCertificateSecrets, getTlsClientAuthorities(deployState), tlsCiphersOverride, proxyProtocolMixedMode, HOSTED_VESPA_DATAPLANE_PORT)
serverName, endpointCertificateSecrets, getTlsClientAuthorities(deployState), tlsCiphersOverride, proxyProtocolMixedMode)
: HostedSslConnectorFactory.withProvidedCertificate(
serverName, endpointCertificateSecrets, enforceHandshakeClientAuth, tlsCiphersOverride, proxyProtocolMixedMode, HOSTED_VESPA_DATAPLANE_PORT);
serverName, endpointCertificateSecrets, enforceHandshakeClientAuth, tlsCiphersOverride, proxyProtocolMixedMode);
} else {
connectorFactory = HostedSslConnectorFactory.withDefaultCertificateAndTruststore(serverName, tlsCiphersOverride, proxyProtocolMixedMode, HOSTED_VESPA_DATAPLANE_PORT);
connectorFactory = HostedSslConnectorFactory.withDefaultCertificateAndTruststore(serverName, tlsCiphersOverride, proxyProtocolMixedMode);
}
cluster.getHttp().getAccessControl().ifPresent(accessControl -> accessControl.configureHostedConnector(connectorFactory));
server.addConnector(connectorFactory);
Expand Down Expand Up @@ -544,7 +540,7 @@ private void addSearch(DeployState deployState, Element spec, ApplicationContain
addIncludes(searchElement);
cluster.setSearch(buildSearch(deployState, cluster, searchElement));

addSearchHandler(deployState, cluster, searchElement);
addSearchHandler(cluster, searchElement);

validateAndAddConfiguredComponents(deployState, cluster, searchElement, "renderer", ContainerModelBuilder::validateRendererElement);
}
Expand Down Expand Up @@ -595,7 +591,7 @@ private void addProcessing(DeployState deployState, Element spec, ApplicationCon
cluster.addSearchAndDocprocBundles();
addIncludes(processingElement);
cluster.setProcessingChains(new DomProcessingBuilder(null).build(deployState, cluster, processingElement),
serverBindings(deployState, processingElement, ProcessingChains.defaultBindings).toArray(BindingPattern[]::new));
serverBindings(processingElement, ProcessingChains.defaultBindings).toArray(BindingPattern[]::new));
validateAndAddConfiguredComponents(deployState, cluster, processingElement, "renderer", ContainerModelBuilder::validateRendererElement);
}

Expand All @@ -620,7 +616,7 @@ private void applyApplicationPackageDirectoryConfigs(ApplicationPackage applicat
private void addUserHandlers(DeployState deployState, ApplicationContainerCluster cluster, Element spec) {
for (Element component: XML.getChildren(spec, "handler")) {
cluster.addComponent(
new DomHandlerBuilder(cluster, OptionalInt.of(HOSTED_VESPA_DATAPLANE_PORT)).build(deployState, cluster, component));
new DomHandlerBuilder(cluster).build(deployState, cluster, component));
}
}

Expand Down Expand Up @@ -879,55 +875,44 @@ private static void applyDefaultPreload(List<ApplicationContainer> containers, E
container.setPreLoad(nodesElement.getAttribute(VespaDomBuilder.PRELOAD_ATTRIB_NAME));
}

private void addSearchHandler(DeployState deployState, ApplicationContainerCluster cluster, Element searchElement) {
BindingPattern bindingPattern = SearchHandler.DEFAULT_BINDING;
if (deployState.isHosted() && deployState.featureFlags().useRestrictedDataPlaneBindings()) {
bindingPattern = SearchHandler.bindingPattern(Optional.of(Integer.toString(HOSTED_VESPA_DATAPLANE_PORT)));
}
private void addSearchHandler(ApplicationContainerCluster cluster, Element searchElement) {
SearchHandler searchHandler = new SearchHandler(cluster,
serverBindings(deployState, searchElement, bindingPattern),
serverBindings(searchElement, SearchHandler.DEFAULT_BINDING),
ContainerThreadpool.UserOptions.fromXml(searchElement).orElse(null));
cluster.addComponent(searchHandler);

// Add as child to SearchHandler to get the correct chains config.
searchHandler.addComponent(Component.fromClassAndBundle(SearchHandler.EXECUTION_FACTORY_CLASS, PlatformBundles.SEARCH_AND_DOCPROC_BUNDLE));
}

private List<BindingPattern> serverBindings(DeployState deployState, Element searchElement, BindingPattern... defaultBindings) {
private List<BindingPattern> serverBindings(Element searchElement, BindingPattern... defaultBindings) {
List<Element> bindings = XML.getChildren(searchElement, "binding");
if (bindings.isEmpty())
return List.of(defaultBindings);

return toBindingList(deployState, bindings);
return toBindingList(bindings);
}

private List<BindingPattern> toBindingList(DeployState deployState, List<Element> bindingElements) {
private List<BindingPattern> toBindingList(List<Element> bindingElements) {
List<BindingPattern> result = new ArrayList<>();
OptionalInt port = deployState.isHosted() && deployState.featureFlags().useRestrictedDataPlaneBindings() ? OptionalInt.of(HOSTED_VESPA_DATAPLANE_PORT) : OptionalInt.empty();

for (Element element: bindingElements) {
String text = element.getTextContent().trim();
if (!text.isEmpty())
result.add(userBindingPattern(text, port));
result.add(UserBindingPattern.fromPattern(text));
}

return result;
}
private static UserBindingPattern userBindingPattern(String path, OptionalInt port) {
UserBindingPattern bindingPattern = UserBindingPattern.fromPattern(path);
return port.isPresent()
? bindingPattern.withPort(port.getAsInt())
: bindingPattern;
}

private ContainerDocumentApi buildDocumentApi(ApplicationContainerCluster cluster, Element spec) {
Element documentApiElement = XML.getChild(spec, "document-api");
if (documentApiElement == null) return null;

ContainerDocumentApi.HandlerOptions documentApiOptions = DocumentApiOptionsBuilder.build(documentApiElement);
Element ignoreUndefinedFields = XML.getChild(documentApiElement, "ignore-undefined-fields");
OptionalInt portBindingOverride = cluster.isHostedVespa()? OptionalInt.of(HOSTED_VESPA_DATAPLANE_PORT) : OptionalInt.empty();
return new ContainerDocumentApi(cluster, documentApiOptions,
"true".equals(XML.getValue(ignoreUndefinedFields)), portBindingOverride);
"true".equals(XML.getValue(ignoreUndefinedFields)));
}

private ContainerDocproc buildDocproc(DeployState deployState, ApplicationContainerCluster cluster, Element spec) {
Expand Down
Loading

0 comments on commit 5f654b6

Please sign in to comment.