aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@verizonmedia.com>2021-03-11 13:51:42 +0100
committerBjørn Christian Seime <bjorncs@verizonmedia.com>2021-03-11 13:51:42 +0100
commit8dfd194e88197552c6dcb9c0806c024868c61dba (patch)
tree2f2d00d96a81b95bb97333e0812f3e96ac9eeb80
parentb310bcb0d382dcb2f5c481902772c591a77197d8 (diff)
Add shared ZK client config generator for zkfacade and vespa-zkcli
-rw-r--r--pom.xml1
-rw-r--r--zkfacade/pom.xml6
-rw-r--r--zkfacade/src/main/java/com/yahoo/vespa/curator/Curator.java18
-rw-r--r--zookeeper-client-common/OWNERS1
-rw-r--r--zookeeper-client-common/README.md3
-rw-r--r--zookeeper-client-common/pom.xml47
-rw-r--r--zookeeper-client-common/src/main/java/com/yahoo/vespa/zookeeper/client/VespaSslContextProvider.java25
-rw-r--r--zookeeper-client-common/src/main/java/com/yahoo/vespa/zookeeper/client/ZkClientConfigBuilder.java60
-rw-r--r--zookeeper-command-line-client/pom.xml14
-rw-r--r--zookeeper-command-line-client/src/main/java/com/yahoo/vespa/zookeeper/cli/Main.java19
-rwxr-xr-xzookeeper-command-line-client/src/main/sh/vespa-zkcli2
11 files changed, 179 insertions, 17 deletions
diff --git a/pom.xml b/pom.xml
index 2dcae38fe2d..def94f212b1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -149,6 +149,7 @@
<module>vsm</module>
<module>yolean</module>
<module>zkfacade</module>
+ <module>zookeeper-client-common</module>
<module>zookeeper-command-line-client</module>
<module>zookeeper-server</module>
</modules>
diff --git a/zkfacade/pom.xml b/zkfacade/pom.xml
index d9bd377ffa1..7563ef068a9 100644
--- a/zkfacade/pom.xml
+++ b/zkfacade/pom.xml
@@ -42,6 +42,12 @@
<scope>provided</scope>
</dependency>
<dependency>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>zookeeper-client-common</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
</dependency>
diff --git a/zkfacade/src/main/java/com/yahoo/vespa/curator/Curator.java b/zkfacade/src/main/java/com/yahoo/vespa/curator/Curator.java
index 4cbb6c95cb4..b825e33cbd8 100644
--- a/zkfacade/src/main/java/com/yahoo/vespa/curator/Curator.java
+++ b/zkfacade/src/main/java/com/yahoo/vespa/curator/Curator.java
@@ -10,8 +10,8 @@ import com.yahoo.text.Utf8;
import com.yahoo.vespa.curator.api.VespaCurator;
import com.yahoo.vespa.curator.recipes.CuratorCounter;
import com.yahoo.vespa.defaults.Defaults;
-import com.yahoo.vespa.zookeeper.VespaSslContextProvider;
import com.yahoo.vespa.zookeeper.VespaZooKeeperServer;
+import com.yahoo.vespa.zookeeper.client.ZkClientConfigBuilder;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
@@ -124,16 +124,9 @@ public class Curator implements VespaCurator, AutoCloseable {
private static ZKClientConfig createClientConfig(Optional<File> clientConfigFile) {
if (clientConfigFile.isPresent()) {
- boolean useSecureClient = Boolean.parseBoolean(getEnvironmentVariable("VESPA_USE_TLS_FOR_ZOOKEEPER_CLIENT").orElse("false"));
- StringBuilder configBuilder = new StringBuilder("zookeeper.client.secure=").append(useSecureClient).append("\n");
- if (useSecureClient) {
- configBuilder.append("zookeeper.ssl.context.supplier.class=").append(VespaSslContextProvider.class.getName()).append("\n")
- .append("zookeeper.ssl.enabledProtocols=").append(VespaSslContextProvider.enabledTlsProtocolConfigValue()).append("\n")
- .append("zookeeper.ssl.ciphersuites=").append(VespaSslContextProvider.enabledTlsCiphersConfigValue()).append("\n")
- .append("zookeeper.ssl.clientAuth=NEED\n");
- }
+ String config = new ZkClientConfigBuilder().toConfigString();
clientConfigFile.get().getParentFile().mkdirs();
- IOUtils.writeFile(clientConfigFile.get(), Utf8.toBytes(configBuilder.toString()));
+ IOUtils.writeFile(clientConfigFile.get(), Utf8.toBytes(config));
try {
return new ZKClientConfig(clientConfigFile.get());
} catch (QuorumPeerConfig.ConfigException e) {
@@ -406,9 +399,4 @@ public class Curator implements VespaCurator, AutoCloseable {
*/
public int zooKeeperEnsembleCount() { return connectionSpec.ensembleSize(); }
- private static Optional<String> getEnvironmentVariable(String variableName) {
- return Optional.ofNullable(System.getenv().get(variableName))
- .filter(var -> !var.isEmpty());
- }
-
}
diff --git a/zookeeper-client-common/OWNERS b/zookeeper-client-common/OWNERS
new file mode 100644
index 00000000000..569bf1cc3a1
--- /dev/null
+++ b/zookeeper-client-common/OWNERS
@@ -0,0 +1 @@
+bjorncs
diff --git a/zookeeper-client-common/README.md b/zookeeper-client-common/README.md
new file mode 100644
index 00000000000..51c757a8af2
--- /dev/null
+++ b/zookeeper-client-common/README.md
@@ -0,0 +1,3 @@
+# zookeeper-client-common
+
+Shared client configuration logic for ZooKeeper clients
diff --git a/zookeeper-client-common/pom.xml b/zookeeper-client-common/pom.xml
new file mode 100644
index 00000000000..fd799e13fca
--- /dev/null
+++ b/zookeeper-client-common/pom.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0"?>
+<!-- Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>parent</artifactId>
+ <version>7-SNAPSHOT</version>
+ <relativePath>../parent/pom.xml</relativePath>
+ </parent>
+ <artifactId>zookeeper-client-common</artifactId>
+ <packaging>jar</packaging>
+ <version>7-SNAPSHOT</version>
+
+ <dependencies>
+ <!-- provided -->
+ <dependency>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>security-utils</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.zookeeper</groupId>
+ <artifactId>zookeeper</artifactId>
+ <version>${zookeeper.client.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <!-- compile scope -->
+ <!-- test scope -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/zookeeper-client-common/src/main/java/com/yahoo/vespa/zookeeper/client/VespaSslContextProvider.java b/zookeeper-client-common/src/main/java/com/yahoo/vespa/zookeeper/client/VespaSslContextProvider.java
new file mode 100644
index 00000000000..209e08db6cc
--- /dev/null
+++ b/zookeeper-client-common/src/main/java/com/yahoo/vespa/zookeeper/client/VespaSslContextProvider.java
@@ -0,0 +1,25 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.zookeeper.client;
+
+import com.yahoo.security.tls.TlsContext;
+import com.yahoo.security.tls.TransportSecurityUtils;
+
+import javax.net.ssl.SSLContext;
+import java.util.function.Supplier;
+
+/**
+ * Provider for Vespa {@link SSLContext} instance to Zookeeper + misc utility methods for providing Vespa TLS specific ZK configuration.
+ *
+ * @author bjorncs
+ */
+public class VespaSslContextProvider implements Supplier<SSLContext> {
+
+ private static final SSLContext sslContext = TransportSecurityUtils.getSystemTlsContext().map(TlsContext::context).orElse(null);
+
+ @Override
+ public SSLContext get() {
+ if (sslContext == null) throw new IllegalStateException("Vespa TLS is not enabled");
+ return sslContext;
+ }
+
+}
diff --git a/zookeeper-client-common/src/main/java/com/yahoo/vespa/zookeeper/client/ZkClientConfigBuilder.java b/zookeeper-client-common/src/main/java/com/yahoo/vespa/zookeeper/client/ZkClientConfigBuilder.java
new file mode 100644
index 00000000000..62191880b8f
--- /dev/null
+++ b/zookeeper-client-common/src/main/java/com/yahoo/vespa/zookeeper/client/ZkClientConfigBuilder.java
@@ -0,0 +1,60 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.zookeeper.client;
+
+import com.yahoo.security.tls.MixedMode;
+import com.yahoo.security.tls.TlsContext;
+import com.yahoo.security.tls.TransportSecurityUtils;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * Builder for ZK client configuration
+ *
+ * @author bjorncs
+ */
+public class ZkClientConfigBuilder {
+
+ public static final String CLIENT_SECURE_PROPERTY = "zookeeper.client.secure";
+ public static final String SSL_CONTEXT_SUPPLIER_CLASS_PROPERTY = "zookeeper.ssl.context.supplier.class";
+ public static final String SSL_ENABLED_PROTOCOLS_PROPERTY = "zookeeper.ssl.enabledProtocols";
+ public static final String SSL_ENABLED_CIPHERSUITES_PROPERTY = "zookeeper.ssl.ciphersuites";
+ public static final String SSL_CLIENTAUTH_PROPERTY = "zookeeper.ssl.clientAuth";
+
+ private static final TlsContext tlsContext = getTlsContext().orElse(null);
+
+ public ZkClientConfigBuilder() {}
+
+ public String toConfigString() {
+ StringBuilder builder = new StringBuilder();
+ Map<String, String> properties = toConfigProperties();
+ properties.forEach((key, value) -> builder.append(key).append('=').append(value).append('\n'));
+ return builder.toString();
+ }
+
+ public Map<String, String> toConfigProperties() {
+ Map<String, String> builder = new HashMap<>();
+ builder.put(CLIENT_SECURE_PROPERTY, Boolean.toString(tlsContext != null));
+ if (tlsContext != null) {
+ builder.put(SSL_CONTEXT_SUPPLIER_CLASS_PROPERTY, VespaSslContextProvider.class.getName());
+ String protocolsConfigValue = Arrays.stream(tlsContext.parameters().getProtocols()).sorted().collect(Collectors.joining(","));
+ builder.put(SSL_ENABLED_PROTOCOLS_PROPERTY, protocolsConfigValue);
+ String ciphersConfigValue = Arrays.stream(tlsContext.parameters().getCipherSuites()).sorted().collect(Collectors.joining(","));
+ builder.put(SSL_ENABLED_CIPHERSUITES_PROPERTY, ciphersConfigValue);
+ builder.put(SSL_CLIENTAUTH_PROPERTY, "NEED");
+ }
+ return Map.copyOf(builder);
+ }
+
+ private static Optional<TlsContext> getTlsContext() {
+ // TODO(bjorncs) Remove handling of temporary feature flag
+ boolean temporaryFeatureFlag = Optional.ofNullable(System.getenv("VESPA_USE_TLS_FOR_ZOOKEEPER_CLIENT")).map(Boolean::parseBoolean).orElse(false);
+ if (!temporaryFeatureFlag) return Optional.empty();
+
+ if (TransportSecurityUtils.getInsecureMixedMode() == MixedMode.PLAINTEXT_CLIENT_MIXED_SERVER) return Optional.empty();
+ return TransportSecurityUtils.getSystemTlsContext();
+ }
+}
diff --git a/zookeeper-command-line-client/pom.xml b/zookeeper-command-line-client/pom.xml
index 748a156b30c..c186b377eb6 100644
--- a/zookeeper-command-line-client/pom.xml
+++ b/zookeeper-command-line-client/pom.xml
@@ -17,6 +17,18 @@
<version>${zookeeper.client.version}</version>
</dependency>
<dependency>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>zookeeper-client-common</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>security-utils</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
<!-- Needed by vespa-zkcli -->
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
@@ -34,7 +46,7 @@
<configuration>
<archive>
<manifest>
- <mainClass>org.apache.zookeeper.ZooKeeperMain</mainClass>
+ <mainClass>com.yahoo.vespa.zookeeper.cli.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
diff --git a/zookeeper-command-line-client/src/main/java/com/yahoo/vespa/zookeeper/cli/Main.java b/zookeeper-command-line-client/src/main/java/com/yahoo/vespa/zookeeper/cli/Main.java
new file mode 100644
index 00000000000..1bc1a21a237
--- /dev/null
+++ b/zookeeper-command-line-client/src/main/java/com/yahoo/vespa/zookeeper/cli/Main.java
@@ -0,0 +1,19 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.zookeeper.cli;
+
+import com.yahoo.vespa.zookeeper.client.ZkClientConfigBuilder;
+import org.apache.zookeeper.ZooKeeperMain;
+
+import java.io.IOException;
+
+/**
+ * @author bjorncs
+ */
+public class Main {
+ public static void main(String[] args) throws IOException, InterruptedException {
+ new ZkClientConfigBuilder()
+ .toConfigProperties()
+ .forEach(System::setProperty);
+ ZooKeeperMain.main(args);
+ }
+}
diff --git a/zookeeper-command-line-client/src/main/sh/vespa-zkcli b/zookeeper-command-line-client/src/main/sh/vespa-zkcli
index 5c29f9bb084..1a5858b3222 100755
--- a/zookeeper-command-line-client/src/main/sh/vespa-zkcli
+++ b/zookeeper-command-line-client/src/main/sh/vespa-zkcli
@@ -95,4 +95,4 @@ done
$sudo java \
-cp $VESPA_HOME/lib/jars/zookeeper-command-line-client-jar-with-dependencies.jar \
-Dlog4j.configuration="log4j-vespa.properties" -Xms32m -Xmx512m \
- org.apache.zookeeper.ZooKeeperMain "$@"
+ com.yahoo.vespa.zookeeper.cli.Main "$@"