From ce9787a414e70f0fbcdbd3534eb87824fb0da288 Mon Sep 17 00:00:00 2001 From: Bryan Bende Date: Fri, 17 Nov 2017 17:15:03 -0500 Subject: [PATCH] NIFI-4622 Adding status tool to TLS toolkit This closes #2280. Signed-off-by: Bryan Bende --- nifi-toolkit/nifi-toolkit-tls/pom.xml | 10 ++ .../nifi/toolkit/tls/TlsToolkitMain.java | 2 + .../tls/commandLine/BaseCommandLine.java | 134 +-------------- .../BaseTlsToolkitCommandLine.java | 157 ++++++++++++++++++ .../tls/configuration/GetStatusConfig.java | 41 +++++ .../BaseCertificateAuthorityCommandLine.java | 4 +- .../TlsToolkitStandaloneCommandLine.java | 4 +- .../tls/status/TlsToolkitGetStatus.java | 50 ++++++ .../TlsToolkitGetStatusCommandLine.java | 154 +++++++++++++++++ .../standalone/TlsToolkitStandaloneTest.java | 6 +- .../TlsToolkitGetStatusCommandLineTest.java | 120 +++++++++++++ 11 files changed, 549 insertions(+), 133 deletions(-) create mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/commandLine/BaseTlsToolkitCommandLine.java create mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/GetStatusConfig.java create mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/status/TlsToolkitGetStatus.java create mode 100644 nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/status/TlsToolkitGetStatusCommandLine.java create mode 100644 nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/status/TlsToolkitGetStatusCommandLineTest.java diff --git a/nifi-toolkit/nifi-toolkit-tls/pom.xml b/nifi-toolkit/nifi-toolkit-tls/pom.xml index e75c00a9b4..94c8b7faee 100644 --- a/nifi-toolkit/nifi-toolkit-tls/pom.xml +++ b/nifi-toolkit/nifi-toolkit-tls/pom.xml @@ -62,6 +62,16 @@ org.eclipse.jetty jetty-server + + org.glassfish.jersey.core + jersey-client + ${jersey.version} + + + org.glassfish.jersey.inject + jersey-hk2 + ${jersey.version} + com.fasterxml.jackson.core jackson-databind diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/TlsToolkitMain.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/TlsToolkitMain.java index c0dc4b2b20..2e6b8d1e8a 100644 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/TlsToolkitMain.java +++ b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/TlsToolkitMain.java @@ -21,6 +21,7 @@ import org.apache.nifi.toolkit.tls.commandLine.ExitCode; import org.apache.nifi.toolkit.tls.service.client.TlsCertificateAuthorityClientCommandLine; import org.apache.nifi.toolkit.tls.service.server.TlsCertificateAuthorityServiceCommandLine; import org.apache.nifi.toolkit.tls.standalone.TlsToolkitStandaloneCommandLine; +import org.apache.nifi.toolkit.tls.status.TlsToolkitGetStatusCommandLine; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -42,6 +43,7 @@ public class TlsToolkitMain { mainMap.put("standalone", TlsToolkitStandaloneCommandLine.class); mainMap.put("server", TlsCertificateAuthorityServiceCommandLine.class); mainMap.put("client", TlsCertificateAuthorityClientCommandLine.class); + mainMap.put("status", TlsToolkitGetStatusCommandLine.class); } /** diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/commandLine/BaseCommandLine.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/commandLine/BaseCommandLine.java index 33b2c47ee8..a75b7b894f 100644 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/commandLine/BaseCommandLine.java +++ b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/commandLine/BaseCommandLine.java @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.apache.nifi.toolkit.tls.commandLine; import org.apache.commons.cli.CommandLine; @@ -23,72 +22,23 @@ import org.apache.commons.cli.DefaultParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; -import org.apache.nifi.security.util.KeystoreType; import org.apache.nifi.toolkit.tls.TlsToolkitMain; -import org.apache.nifi.toolkit.tls.configuration.TlsConfig; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -/** - * Base class with common CLI parsing functionality as well as arguments shared by multiple entry points - */ public abstract class BaseCommandLine { - private static final Logger logger = LoggerFactory.getLogger(BaseCommandLine.class); + public static final String HELP_ARG = "help"; public static final String JAVA_HOME = "JAVA_HOME"; public static final String NIFI_TOOLKIT_HOME = "NIFI_TOOLKIT_HOME"; public static final String FOOTER = new StringBuilder(System.lineSeparator()).append("Java home: ") .append(System.getenv(JAVA_HOME)).append(System.lineSeparator()).append("NiFi Toolkit home: ").append(System.getenv(NIFI_TOOLKIT_HOME)).toString(); - public static final String KEY_SIZE_ARG = "keySize"; - public static final String KEY_ALGORITHM_ARG = "keyAlgorithm"; - public static final String CERTIFICATE_AUTHORITY_HOSTNAME_ARG = "certificateAuthorityHostname"; - public static final String DAYS_ARG = "days"; - public static final String KEY_STORE_TYPE_ARG = "keyStoreType"; - public static final String SIGNING_ALGORITHM_ARG = "signingAlgorithm"; - public static final String DN_ARG = "dn"; - public static final String DIFFERENT_KEY_AND_KEYSTORE_PASSWORDS_ARG = "differentKeyAndKeystorePasswords"; - - public static final String KEYSTORE = "keystore."; - public static final String TRUSTSTORE = "truststore."; - private final Options options; private final String header; - private int keySize; - private String keyAlgorithm; - private String certificateAuthorityHostname; - private String keyStoreType; - private int days; - private String signingAlgorithm; - private boolean differentPasswordForKeyAndKeystore; public BaseCommandLine(String header) { this.header = System.lineSeparator() + header + System.lineSeparator() + System.lineSeparator(); this.options = new Options(); - if (shouldAddDaysArg()) { - addOptionWithArg("d", DAYS_ARG, "Number of days issued certificate should be valid for.", TlsConfig.DEFAULT_DAYS); - } - addOptionWithArg("T", KEY_STORE_TYPE_ARG, "The type of keyStores to generate.", getKeyStoreTypeDefault()); - options.addOption("h", HELP_ARG, false, "Print help and exit."); - addOptionWithArg("c", CERTIFICATE_AUTHORITY_HOSTNAME_ARG, "Hostname of NiFi Certificate Authority", TlsConfig.DEFAULT_HOSTNAME); - addOptionWithArg("a", KEY_ALGORITHM_ARG, "Algorithm to use for generated keys.", TlsConfig.DEFAULT_KEY_PAIR_ALGORITHM); - addOptionWithArg("k", KEY_SIZE_ARG, "Number of bits for generated keys.", TlsConfig.DEFAULT_KEY_SIZE); - if (shouldAddSigningAlgorithmArg()) { - addOptionWithArg("s", SIGNING_ALGORITHM_ARG, "Algorithm to use for signing certificates.", TlsConfig.DEFAULT_SIGNING_ALGORITHM); - } - addOptionNoArg("g", DIFFERENT_KEY_AND_KEYSTORE_PASSWORDS_ARG, "Use different generated password for the key and the keyStore."); - } - - protected String getKeyStoreTypeDefault() { - return TlsConfig.DEFAULT_KEY_STORE_TYPE; - } - - protected boolean shouldAddSigningAlgorithmArg() { - return true; - } - - protected boolean shouldAddDaysArg() { - return true; + this.options.addOption("h", HELP_ARG, false, "Print help and exit."); } protected void addOptionWithArg(String arg, String longArg, String description) { @@ -130,69 +80,6 @@ public abstract class BaseCommandLine { } } - /** - * Returns the number of bits used when generating KeyPairs - * - * @return the number of bits used when generating KeyPairs - */ - public int getKeySize() { - return keySize; - } - - /** - * Returns the algorithm used when generating KeyPairs - * - * @return the algorithm used when generating KeyPairs - */ - public String getKeyAlgorithm() { - return keyAlgorithm; - } - - /** - * Returns the CA Hostname - * - * @return the CA Hostname - */ - public String getCertificateAuthorityHostname() { - return certificateAuthorityHostname; - } - - /** - * Returns the type to use for KeyStores - * - * @return the type to use for KeyStores - */ - public String getKeyStoreType() { - return keyStoreType; - } - - /** - * Returns the number of Certificates should be valid for - * - * @return the number of Certificates should be valid for - */ - public int getDays() { - return days; - } - - /** - * Returns the signing algorithm to use for cryptographic operations - * - * @return the signing algorithm to use for cryptographic operations - */ - public String getSigningAlgorithm() { - return signingAlgorithm; - } - - /** - * Returns true if different passwords should be used for KeyStore and individual Key entries - * - * @return true if different passwords should be used for KeyStore and individual Key entries - */ - public boolean differentPasswordForKeyAndKeystore() { - return differentPasswordForKeyAndKeystore; - } - protected CommandLine doParse(String[] args) throws CommandLineParseException { CommandLineParser parser = new DefaultParser(); CommandLine commandLine; @@ -201,23 +88,17 @@ public abstract class BaseCommandLine { if (commandLine.hasOption(HELP_ARG)) { return printUsageAndThrow(null, ExitCode.HELP); } - certificateAuthorityHostname = commandLine.getOptionValue(CERTIFICATE_AUTHORITY_HOSTNAME_ARG, TlsConfig.DEFAULT_HOSTNAME); - days = getIntValue(commandLine, DAYS_ARG, TlsConfig.DEFAULT_DAYS); - keySize = getIntValue(commandLine, KEY_SIZE_ARG, TlsConfig.DEFAULT_KEY_SIZE); - keyAlgorithm = commandLine.getOptionValue(KEY_ALGORITHM_ARG, TlsConfig.DEFAULT_KEY_PAIR_ALGORITHM); - keyStoreType = commandLine.getOptionValue(KEY_STORE_TYPE_ARG, getKeyStoreTypeDefault()); - if (KeystoreType.PKCS12.toString().equalsIgnoreCase(keyStoreType)) { - logger.info("Command line argument --" + KEY_STORE_TYPE_ARG + "=" + keyStoreType + " only applies to keystore, recommended truststore type of " + KeystoreType.JKS.toString() + - " unaffected."); - } - signingAlgorithm = commandLine.getOptionValue(SIGNING_ALGORITHM_ARG, TlsConfig.DEFAULT_SIGNING_ALGORITHM); - differentPasswordForKeyAndKeystore = commandLine.hasOption(DIFFERENT_KEY_AND_KEYSTORE_PASSWORDS_ARG); + postParse(commandLine); } catch (ParseException e) { return printUsageAndThrow("Error parsing command line. (" + e.getMessage() + ")", ExitCode.ERROR_PARSING_COMMAND_LINE); } return commandLine; } + protected void postParse(CommandLine commandLine) throws CommandLineParseException { + + } + /** * Parses the command line arguments * @@ -227,4 +108,5 @@ public abstract class BaseCommandLine { public void parse(String... args) throws CommandLineParseException { doParse(args); } + } diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/commandLine/BaseTlsToolkitCommandLine.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/commandLine/BaseTlsToolkitCommandLine.java new file mode 100644 index 0000000000..656bb196c4 --- /dev/null +++ b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/commandLine/BaseTlsToolkitCommandLine.java @@ -0,0 +1,157 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.nifi.toolkit.tls.commandLine; + +import org.apache.commons.cli.CommandLine; +import org.apache.nifi.security.util.KeystoreType; +import org.apache.nifi.toolkit.tls.configuration.TlsConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Base class with common CLI parsing functionality as well as arguments shared by multiple entry points + */ +public abstract class BaseTlsToolkitCommandLine extends BaseCommandLine { + private static final Logger logger = LoggerFactory.getLogger(BaseTlsToolkitCommandLine.class); + + public static final String KEY_SIZE_ARG = "keySize"; + public static final String KEY_ALGORITHM_ARG = "keyAlgorithm"; + public static final String CERTIFICATE_AUTHORITY_HOSTNAME_ARG = "certificateAuthorityHostname"; + public static final String DAYS_ARG = "days"; + public static final String KEY_STORE_TYPE_ARG = "keyStoreType"; + public static final String SIGNING_ALGORITHM_ARG = "signingAlgorithm"; + public static final String DN_ARG = "dn"; + public static final String DIFFERENT_KEY_AND_KEYSTORE_PASSWORDS_ARG = "differentKeyAndKeystorePasswords"; + + public static final String KEYSTORE = "keystore."; + public static final String TRUSTSTORE = "truststore."; + + private int keySize; + private String keyAlgorithm; + private String certificateAuthorityHostname; + private String keyStoreType; + private int days; + private String signingAlgorithm; + private boolean differentPasswordForKeyAndKeystore; + + public BaseTlsToolkitCommandLine(String header) { + super(header); + if (shouldAddDaysArg()) { + addOptionWithArg("d", DAYS_ARG, "Number of days issued certificate should be valid for.", TlsConfig.DEFAULT_DAYS); + } + addOptionWithArg("T", KEY_STORE_TYPE_ARG, "The type of keyStores to generate.", getKeyStoreTypeDefault()); + addOptionWithArg("c", CERTIFICATE_AUTHORITY_HOSTNAME_ARG, "Hostname of NiFi Certificate Authority", TlsConfig.DEFAULT_HOSTNAME); + addOptionWithArg("a", KEY_ALGORITHM_ARG, "Algorithm to use for generated keys.", TlsConfig.DEFAULT_KEY_PAIR_ALGORITHM); + addOptionWithArg("k", KEY_SIZE_ARG, "Number of bits for generated keys.", TlsConfig.DEFAULT_KEY_SIZE); + if (shouldAddSigningAlgorithmArg()) { + addOptionWithArg("s", SIGNING_ALGORITHM_ARG, "Algorithm to use for signing certificates.", TlsConfig.DEFAULT_SIGNING_ALGORITHM); + } + addOptionNoArg("g", DIFFERENT_KEY_AND_KEYSTORE_PASSWORDS_ARG, "Use different generated password for the key and the keyStore."); + } + + protected String getKeyStoreTypeDefault() { + return TlsConfig.DEFAULT_KEY_STORE_TYPE; + } + + protected boolean shouldAddSigningAlgorithmArg() { + return true; + } + + protected boolean shouldAddDaysArg() { + return true; + } + + /** + * Returns the number of bits used when generating KeyPairs + * + * @return the number of bits used when generating KeyPairs + */ + public int getKeySize() { + return keySize; + } + + /** + * Returns the algorithm used when generating KeyPairs + * + * @return the algorithm used when generating KeyPairs + */ + public String getKeyAlgorithm() { + return keyAlgorithm; + } + + /** + * Returns the CA Hostname + * + * @return the CA Hostname + */ + public String getCertificateAuthorityHostname() { + return certificateAuthorityHostname; + } + + /** + * Returns the type to use for KeyStores + * + * @return the type to use for KeyStores + */ + public String getKeyStoreType() { + return keyStoreType; + } + + /** + * Returns the number of Certificates should be valid for + * + * @return the number of Certificates should be valid for + */ + public int getDays() { + return days; + } + + /** + * Returns the signing algorithm to use for cryptographic operations + * + * @return the signing algorithm to use for cryptographic operations + */ + public String getSigningAlgorithm() { + return signingAlgorithm; + } + + /** + * Returns true if different passwords should be used for KeyStore and individual Key entries + * + * @return true if different passwords should be used for KeyStore and individual Key entries + */ + public boolean differentPasswordForKeyAndKeystore() { + return differentPasswordForKeyAndKeystore; + } + + @Override + protected void postParse(CommandLine commandLine) throws CommandLineParseException { + certificateAuthorityHostname = commandLine.getOptionValue(CERTIFICATE_AUTHORITY_HOSTNAME_ARG, TlsConfig.DEFAULT_HOSTNAME); + days = getIntValue(commandLine, DAYS_ARG, TlsConfig.DEFAULT_DAYS); + keySize = getIntValue(commandLine, KEY_SIZE_ARG, TlsConfig.DEFAULT_KEY_SIZE); + keyAlgorithm = commandLine.getOptionValue(KEY_ALGORITHM_ARG, TlsConfig.DEFAULT_KEY_PAIR_ALGORITHM); + keyStoreType = commandLine.getOptionValue(KEY_STORE_TYPE_ARG, getKeyStoreTypeDefault()); + if (KeystoreType.PKCS12.toString().equalsIgnoreCase(keyStoreType)) { + logger.info("Command line argument --" + KEY_STORE_TYPE_ARG + "=" + keyStoreType + " only applies to keystore, recommended truststore type of " + KeystoreType.JKS.toString() + + " unaffected."); + } + signingAlgorithm = commandLine.getOptionValue(SIGNING_ALGORITHM_ARG, TlsConfig.DEFAULT_SIGNING_ALGORITHM); + differentPasswordForKeyAndKeystore = commandLine.hasOption(DIFFERENT_KEY_AND_KEYSTORE_PASSWORDS_ARG); + } + +} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/GetStatusConfig.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/GetStatusConfig.java new file mode 100644 index 0000000000..eab6f14b1d --- /dev/null +++ b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/configuration/GetStatusConfig.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.toolkit.tls.configuration; + +import javax.net.ssl.SSLContext; +import java.net.URI; + +public class GetStatusConfig { + + private final URI url; + + private final SSLContext sslContext; + + public GetStatusConfig(final URI url, final SSLContext sslContext) { + this.url = url; + this.sslContext = sslContext; + } + + public URI getUrl() { + return url; + } + + public SSLContext getSslContext() { + return sslContext; + } + +} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/BaseCertificateAuthorityCommandLine.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/BaseCertificateAuthorityCommandLine.java index e638bff251..e0f9e6df83 100644 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/BaseCertificateAuthorityCommandLine.java +++ b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/BaseCertificateAuthorityCommandLine.java @@ -18,7 +18,7 @@ package org.apache.nifi.toolkit.tls.service; import org.apache.commons.cli.CommandLine; -import org.apache.nifi.toolkit.tls.commandLine.BaseCommandLine; +import org.apache.nifi.toolkit.tls.commandLine.BaseTlsToolkitCommandLine; import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException; import org.apache.nifi.toolkit.tls.commandLine.ExitCode; import org.apache.nifi.toolkit.tls.configuration.TlsConfig; @@ -29,7 +29,7 @@ import java.io.File; /** * Common base argument logic for the CA server and client */ -public abstract class BaseCertificateAuthorityCommandLine extends BaseCommandLine { +public abstract class BaseCertificateAuthorityCommandLine extends BaseTlsToolkitCommandLine { public static final String TOKEN_ARG = "token"; public static final String CONFIG_JSON_ARG = "configJson"; public static final String READ_CONFIG_JSON_ARG = "configJsonIn"; diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/standalone/TlsToolkitStandaloneCommandLine.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/standalone/TlsToolkitStandaloneCommandLine.java index 2fcce7ce1f..2e30b48a21 100644 --- a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/standalone/TlsToolkitStandaloneCommandLine.java +++ b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/standalone/TlsToolkitStandaloneCommandLine.java @@ -31,7 +31,7 @@ import java.util.stream.IntStream; import java.util.stream.Stream; import org.apache.commons.cli.CommandLine; -import org.apache.nifi.toolkit.tls.commandLine.BaseCommandLine; +import org.apache.nifi.toolkit.tls.commandLine.BaseTlsToolkitCommandLine; import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException; import org.apache.nifi.toolkit.tls.commandLine.ExitCode; import org.apache.nifi.toolkit.tls.configuration.InstanceDefinition; @@ -46,7 +46,7 @@ import org.slf4j.LoggerFactory; /** * Command line parser for a StandaloneConfig object and a main entry point to invoke the parser and run the standalone generator */ -public class TlsToolkitStandaloneCommandLine extends BaseCommandLine { +public class TlsToolkitStandaloneCommandLine extends BaseTlsToolkitCommandLine { public static final String OUTPUT_DIRECTORY_ARG = "outputDirectory"; public static final String NIFI_PROPERTIES_FILE_ARG = "nifiPropertiesFile"; public static final String KEY_STORE_PASSWORD_ARG = "keyStorePassword"; diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/status/TlsToolkitGetStatus.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/status/TlsToolkitGetStatus.java new file mode 100644 index 0000000000..da48f74eeb --- /dev/null +++ b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/status/TlsToolkitGetStatus.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.toolkit.tls.status; + +import org.apache.nifi.toolkit.tls.configuration.GetStatusConfig; +import org.glassfish.jersey.client.ClientConfig; +import org.glassfish.jersey.client.ClientProperties; + +import javax.net.ssl.SSLContext; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Response; + +public class TlsToolkitGetStatus { + + public void get(final GetStatusConfig config) { + final SSLContext sslContext = config.getSslContext(); + + final ClientBuilder clientBuilder = ClientBuilder.newBuilder(); + if (sslContext != null) { + clientBuilder.sslContext(sslContext); + } + + final ClientConfig clientConfig = new ClientConfig(); + clientConfig.property(ClientProperties.CONNECT_TIMEOUT, 10000); + clientConfig.property(ClientProperties.READ_TIMEOUT, 10000); + clientBuilder.withConfig(clientConfig); + + final Client client = clientBuilder.build(); + final WebTarget target = client.target(config.getUrl()); + final Response response = target.request().get(); + System.out.println("Response Code - " + response.getStatus()); + } + +} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/status/TlsToolkitGetStatusCommandLine.java b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/status/TlsToolkitGetStatusCommandLine.java new file mode 100644 index 0000000000..73000d4219 --- /dev/null +++ b/nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/status/TlsToolkitGetStatusCommandLine.java @@ -0,0 +1,154 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.toolkit.tls.status; + +import org.apache.commons.cli.CommandLine; +import org.apache.nifi.security.util.SslContextFactory; +import org.apache.nifi.toolkit.tls.commandLine.BaseCommandLine; +import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException; +import org.apache.nifi.toolkit.tls.commandLine.ExitCode; +import org.apache.nifi.toolkit.tls.configuration.GetStatusConfig; +import org.apache.nifi.util.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ssl.SSLContext; +import java.net.URI; +import java.net.URISyntaxException; + +public class TlsToolkitGetStatusCommandLine extends BaseCommandLine { + + private final Logger logger = LoggerFactory.getLogger(TlsToolkitGetStatusCommandLine.class); + + public static final String URL_ARG = "url"; + public static final String KEYSTORE_ARG = "keyStore"; + public static final String KEYSTORE_TYPE_ARG = "keyStoreType"; + public static final String KEYSTORE_PASSWORD_ARG = "keyStorePassword"; + public static final String KEY_PASSWORD_ARG = "keyPassword"; + public static final String TRUSTSTORE_ARG = "trustStore"; + public static final String TRUSTSTORE_TYPE_ARG = "trustStoreType"; + public static final String TRUSTSTORE_PASSWORD_ARG = "trustStorePassword"; + public static final String PROTOCOL_ARG = "protocol"; + + public static final String DEFAULT_PROTOCOL = "TLS"; + public static final String DEFAULT_KEYSTORE_TYPE = "JKS"; + + public static final String DESCRIPTION = "Checks the status of an HTTPS endpoint by making a GET request using a supplied keystore and truststore."; + + + private URI url; + private SSLContext sslContext; + + public TlsToolkitGetStatusCommandLine() { + super(DESCRIPTION); + addOptionWithArg("u", URL_ARG, "The full url to connect to, for example: https://localhost:8443/v1/api"); + addOptionWithArg("ks", KEYSTORE_ARG, "The key store to use"); + addOptionWithArg("kst", KEYSTORE_TYPE_ARG, "The type of key store being used (PKCS12 or JKS)", DEFAULT_KEYSTORE_TYPE); + addOptionWithArg("ksp", KEYSTORE_PASSWORD_ARG, "The password of the key store being used"); + addOptionWithArg("kp", KEY_PASSWORD_ARG, "The key password of the key store being used"); + addOptionWithArg("ts", TRUSTSTORE_ARG, "The trust store being used"); + addOptionWithArg("tst", TRUSTSTORE_TYPE_ARG, "The type of trust store being used (PKCS12 or JKS)", DEFAULT_KEYSTORE_TYPE); + addOptionWithArg("tsp", TRUSTSTORE_PASSWORD_ARG, "The password of the trust store being used"); + addOptionWithArg("p", PROTOCOL_ARG, "The protocol to use", DEFAULT_PROTOCOL); + } + + public static void main(String[] args) { + TlsToolkitGetStatusCommandLine commandLine = new TlsToolkitGetStatusCommandLine(); + try { + commandLine.parse(args); + } catch (CommandLineParseException e) { + System.exit(e.getExitCode().ordinal()); + } + + final GetStatusConfig config = commandLine.createConfig(); + try { + final TlsToolkitGetStatus tlsToolkitGetStatus = new TlsToolkitGetStatus(); + tlsToolkitGetStatus.get(config); + } catch (Exception e) { + commandLine.printUsage("Error communicating with " + config.getUrl().toString() + " (" + e.getMessage() + ")"); + System.exit(ExitCode.SERVICE_ERROR.ordinal()); + } + System.exit(ExitCode.SUCCESS.ordinal()); + } + + + @Override + protected void postParse(CommandLine commandLine) throws CommandLineParseException { + super.postParse(commandLine); + + final String urlValue = commandLine.getOptionValue(URL_ARG); + if (StringUtils.isBlank(urlValue)) { + printUsageAndThrow("Url was missing or blank", ExitCode.INVALID_ARGS); + } + + try { + this.url = new URI(urlValue); + } catch (URISyntaxException e) { + printUsageAndThrow("Invalid Url", ExitCode.INVALID_ARGS); + } + + final String keystoreFilename = commandLine.getOptionValue(KEYSTORE_ARG); + final String keystoreTypeStr = commandLine.getOptionValue(KEYSTORE_TYPE_ARG, DEFAULT_KEYSTORE_TYPE); + final String keystorePassword = commandLine.getOptionValue(KEYSTORE_PASSWORD_ARG); + final String keyPassword = commandLine.getOptionValue(KEY_PASSWORD_ARG); + + final String truststoreFilename = commandLine.getOptionValue(TRUSTSTORE_ARG); + final String truststoreTypeStr = commandLine.getOptionValue(TRUSTSTORE_TYPE_ARG, DEFAULT_KEYSTORE_TYPE); + final String truststorePassword = commandLine.getOptionValue(TRUSTSTORE_PASSWORD_ARG); + + final String protocol = commandLine.getOptionValue(PROTOCOL_ARG, DEFAULT_PROTOCOL); + + final boolean keystoreProvided = !StringUtils.isBlank(keystoreFilename); + final boolean truststoreProvided = !StringUtils.isBlank(truststoreFilename); + + try { + final char[] keystorePass = keystorePassword == null ? null : keystorePassword.toCharArray(); + final char[] keyPass = keyPassword == null ? null : keyPassword.toCharArray(); + final char[] trustPass = truststorePassword == null ? null : truststorePassword.toCharArray(); + + if (keystoreProvided && truststoreProvided) { + this.sslContext = SslContextFactory.createSslContext( + keystoreFilename, + keystorePass, + keyPass, + keystoreTypeStr, + truststoreFilename, + trustPass, + truststoreTypeStr, + SslContextFactory.ClientAuth.NONE, protocol); + + } else if (truststoreProvided) { + this.sslContext = SslContextFactory.createTrustSslContext( + truststoreFilename, + trustPass, + truststoreTypeStr, + protocol); + + } else { + printUsageAndThrow("No keystore or truststore was provided", ExitCode.INVALID_ARGS); + } + } catch (Exception e) { + logger.error(e.getMessage(), e); + printUsageAndThrow("Failed to create SSL Context: " + e.getMessage(), ExitCode.INVALID_ARGS); + } + } + + public GetStatusConfig createConfig() { + return new GetStatusConfig(url, sslContext); + } + +} diff --git a/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/standalone/TlsToolkitStandaloneTest.java b/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/standalone/TlsToolkitStandaloneTest.java index ff32d44626..085312d0b6 100644 --- a/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/standalone/TlsToolkitStandaloneTest.java +++ b/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/standalone/TlsToolkitStandaloneTest.java @@ -23,7 +23,7 @@ import org.apache.nifi.security.util.CertificateUtils; import org.apache.nifi.security.util.KeystoreType; import org.apache.nifi.security.util.KeyStoreUtils; import org.apache.nifi.toolkit.tls.SystemExitCapturer; -import org.apache.nifi.toolkit.tls.commandLine.BaseCommandLine; +import org.apache.nifi.toolkit.tls.commandLine.BaseTlsToolkitCommandLine; import org.apache.nifi.toolkit.tls.commandLine.ExitCode; import org.apache.nifi.toolkit.tls.configuration.TlsConfig; import org.apache.nifi.toolkit.tls.service.TlsCertificateAuthorityTest; @@ -251,14 +251,14 @@ public class TlsToolkitStandaloneTest { trustStore.load(inputStream, nifiProperties.getProperty(NiFiProperties.SECURITY_TRUSTSTORE_PASSWD).toCharArray()); } - String trustStoreFilename = BaseCommandLine.TRUSTSTORE + trustStoreType; + String trustStoreFilename = BaseTlsToolkitCommandLine.TRUSTSTORE + trustStoreType; assertEquals("./conf/" + trustStoreFilename, nifiProperties.getProperty(NiFiProperties.SECURITY_TRUSTSTORE)); Certificate certificate = trustStore.getCertificate(TlsToolkitStandalone.NIFI_CERT); assertEquals(rootCert, certificate); String keyStoreType = nifiProperties.getProperty(NiFiProperties.SECURITY_KEYSTORE_TYPE); - String keyStoreFilename = BaseCommandLine.KEYSTORE + keyStoreType; + String keyStoreFilename = BaseTlsToolkitCommandLine.KEYSTORE + keyStoreType; File keyStoreFile = new File(hostDir, keyStoreFilename); assertEquals("./conf/" + keyStoreFilename, nifiProperties.getProperty(NiFiProperties.SECURITY_KEYSTORE)); diff --git a/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/status/TlsToolkitGetStatusCommandLineTest.java b/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/status/TlsToolkitGetStatusCommandLineTest.java new file mode 100644 index 0000000000..008a9af215 --- /dev/null +++ b/nifi-toolkit/nifi-toolkit-tls/src/test/java/org/apache/nifi/toolkit/tls/status/TlsToolkitGetStatusCommandLineTest.java @@ -0,0 +1,120 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.toolkit.tls.status; + +import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException; +import org.apache.nifi.toolkit.tls.commandLine.ExitCode; +import org.apache.nifi.toolkit.tls.configuration.GetStatusConfig; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import javax.net.ssl.SSLContext; +import java.net.URI; + +import static org.junit.Assert.fail; + +public class TlsToolkitGetStatusCommandLineTest { + + private TlsToolkitGetStatusCommandLine commandLine; + + @Before + public void setup() { + commandLine = new TlsToolkitGetStatusCommandLine(); + } + + @Test + public void testHelp() { + try { + commandLine.parse("-h"); + fail("Expected usage and help exit"); + } catch (CommandLineParseException e) { + Assert.assertEquals(ExitCode.HELP, e.getExitCode()); + } + } + + @Test + public void testSuccess() { + try { + final String urlStr = "https://localhost:8443/test"; + commandLine.parse( + "-u", urlStr, + "-ts", "src/test/resources/localhost/truststore.jks", + "-tst", "JKS", + "-tsp", "t7rmn1fg8np2ck1sduqdd85opv"); + + final GetStatusConfig config = commandLine.createConfig(); + Assert.assertNotNull(config); + + final URI url = config.getUrl(); + Assert.assertNotNull(url); + Assert.assertEquals(urlStr, url.toString()); + + final SSLContext sslContext = config.getSslContext(); + Assert.assertNotNull(sslContext); + } catch (CommandLineParseException e) { + fail("Expected success"); + } + } + + @Test + public void testMissingUrl() { + try { + commandLine.parse( + "-ts", "src/test/resources/localhost/truststore.jks", + "-tst", "JKS", + "-tsp", "t7rmn1fg8np2ck1sduqdd85opv"); + + fail("Expected invalid args"); + } catch (CommandLineParseException e) { + Assert.assertEquals(ExitCode.INVALID_ARGS, e.getExitCode()); + } + } + + @Test + public void testTruststoreDoesNotExist() { + try { + final String urlStr = "https://localhost:8443/test"; + commandLine.parse( + "-u", urlStr, + "-ts", "does/not/exist/truststore.jks", + "-tst", "JKS", + "-tsp", "t7rmn1fg8np2ck1sduqdd85opv"); + + fail("Expected invalid args"); + } catch (CommandLineParseException e) { + Assert.assertEquals(ExitCode.INVALID_ARGS, e.getExitCode()); + } + } + + @Test + public void testInvalidTruststoreType() { + try { + final String urlStr = "https://localhost:8443/test"; + commandLine.parse( + "-u", urlStr, + "-ts", "src/test/resources/localhost/truststore.jks", + "-tst", "INVALID", + "-tsp", "t7rmn1fg8np2ck1sduqdd85opv"); + + fail("Expected invalid args"); + } catch (CommandLineParseException e) { + Assert.assertEquals(ExitCode.INVALID_ARGS, e.getExitCode()); + } + } + +}