This is an automated email from the ASF dual-hosted git repository.
amagyar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/knox.git
The following commit(s) were added to refs/heads/master by this push:
new aa8e1531f KNOX-2752 knoxcli should support batch alias creation (#583)
aa8e1531f is described below
commit aa8e1531f970d5477d60f7ea2c669657b5bf077a
Author: Attila Magyar <[email protected]>
AuthorDate: Thu Jun 9 18:15:11 2022 +0200
KNOX-2752 knoxcli should support batch alias creation (#583)
---
.../java/org/apache/knox/gateway/util/KnoxCLI.java | 146 +++++++++++++++++----
.../org/apache/knox/gateway/util/KnoxCLITest.java | 60 +++++++++
2 files changed, 178 insertions(+), 28 deletions(-)
diff --git
a/gateway-server/src/main/java/org/apache/knox/gateway/util/KnoxCLI.java
b/gateway-server/src/main/java/org/apache/knox/gateway/util/KnoxCLI.java
index 778729e03..c49127a2d 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/util/KnoxCLI.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/util/KnoxCLI.java
@@ -32,10 +32,12 @@ import java.nio.file.Paths;
import java.security.KeyStoreException;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -109,6 +111,7 @@ public class KnoxCLI extends Configured implements Tool {
" [" + CertCreateCommand.USAGE + "]\n" +
" [" + CertExportCommand.USAGE + "]\n" +
" [" + AliasCreateCommand.USAGE + "]\n" +
+ " [" + BatchAliasCreateCommand.USAGE + "]\n" +
" [" + AliasDeleteCommand.USAGE + "]\n" +
" [" + AliasListCommand.USAGE + "]\n" +
" [" + RedeployCommand.USAGE + "]\n" +
@@ -252,6 +255,12 @@ public class KnoxCLI extends Configured implements Tool {
printKnoxShellUsage();
return -1;
}
+ } else if (args[i].equals("create-aliases")) {
+ command = new BatchAliasCreateCommand();
+ if (args.length < 3 || "--help".equals(alias)) {
+ printKnoxShellUsage();
+ return -1;
+ }
} else if (args[i].equals("create-cert")) {
command = new CertCreateCommand();
if ((args.length > i + 1) && args[i + 1].equals("--help")) {
@@ -281,13 +290,22 @@ public class KnoxCLI extends Configured implements Tool {
} else if (args[i].equals("list-alias")) {
command = new AliasListCommand();
} else if (args[i].equals("--value")) {
- if( i+1 >= args.length || args[i+1].startsWith( "-" ) ) {
+ if (i + 1 >= args.length || args[i + 1].startsWith("-")) {
printKnoxShellUsage();
return -1;
}
this.value = args[++i];
- if ( command instanceof MasterCreateCommand ) {
+ if (command instanceof MasterCreateCommand) {
this.master = this.value;
+ } else if (command instanceof BatchAliasCreateCommand) {
+ ((BatchAliasCreateCommand) command).addValue(value);
+ }
+ } else if (args[i].equals("--alias")) {
+ if (command instanceof BatchAliasCreateCommand) {
+ ((BatchAliasCreateCommand) command).addName(args[++i]);
+ } else {
+ printKnoxShellUsage();
+ return -1;
}
} else if ( args[i].equals("version") ) {
command = new VersionCommand();
@@ -905,32 +923,6 @@ public class KnoxCLI extends Configured implements Tool {
public String getUsage() {
return USAGE + ":\n\n" + DESC;
}
-
- protected char[] promptUserForPassword() {
- char[] password = null;
- Console c = System.console();
- if (c == null) {
- System.err
- .println("No console to fetch password from user.Consider setting
via --generate or --value.");
- System.exit(1);
- }
-
- boolean noMatch;
- do {
- char[] newPassword1 = c.readPassword("Enter password: ");
- char[] newPassword2 = c.readPassword("Enter password again: ");
- noMatch = !Arrays.equals(newPassword1, newPassword2);
- if (noMatch) {
- c.format("Passwords don't match. Try again.%n");
- } else {
- password = Arrays.copyOf(newPassword1, newPassword1.length);
- }
- Arrays.fill(newPassword1, ' ');
- Arrays.fill(newPassword2, ' ');
- } while (noMatch);
- return password;
- }
-
}
public class AliasDeleteCommand extends Command {
@@ -977,6 +969,104 @@ public class KnoxCLI extends Configured implements Tool {
}
+ public class BatchAliasCreateCommand extends Command {
+ public static final String USAGE = "create-aliases " +
+ "--alias alias1 [--value value1] " +
+ "--alias alias2 [--value value2] " +
+ "--alias aliasN [--value valueN] ... " +
+ "[--cluster clustername] " +
+ "[--generate]";
+ public static final String DESC = "The create-aliases command will create
multiple aliases\n"
+ + "and secret pairs within the same credential store for the\n"
+ + "indicated --cluster otherwise within the gateway\n"
+ + "credential store. The actual secret may be specified via\n"
+ + "the --value option or --generate (will create a random secret\n"
+ + "for you) or user will be prompt to provide password.";
+
+ private List<String> names = new ArrayList<>();
+ private List<String> values = new ArrayList<>();
+
+ public void addName(String alias) {
+ if (names.contains(alias)) {
+ out.println("Duplicated alias " + alias);
+ System.exit(1);
+ }
+ names.add(alias);
+ values.add(null);
+ }
+
+ public void addValue(String value) {
+ values.set(values.size() -1, value);
+ }
+
+ @Override
+ public void execute() throws Exception {
+ Map<String, String> aliases = toMap();
+ List<String> generated = new ArrayList<>();
+ AliasService as = getAliasService();
+ if (cluster == null) {
+ cluster = "__gateway";
+ }
+ for (Map.Entry<String, String> entry : aliases.entrySet()) {
+ if (entry.getValue() == null) {
+ if (Boolean.parseBoolean(generate)) {
+ entry.setValue(PasswordUtils.generatePassword(16));
+ generated.add(entry.getKey());
+ } else {
+ entry.setValue(new String(promptUserForPassword()));
+ }
+ }
+ }
+ as.addAliasesForCluster(cluster, aliases);
+ if (!generated.isEmpty()) {
+ out.println(generated.size() + " alias(es) have been successfully
generated: " + generated);
+ }
+ List<String> created = new ArrayList<>(aliases.keySet());
+ created.removeAll(generated);
+ if (!created.isEmpty()) {
+ out.println(created.size() + " alias(es) have been successfully
created: " + created);
+ }
+ }
+
+ private Map<String, String> toMap() {
+ Map<String,String> aliases = new LinkedHashMap<>();
+ for (int i = 0; i < names.size(); i++) {
+ aliases.put(names.get(i), values.get(i));
+ }
+ return aliases;
+ }
+
+ @Override
+ public String getUsage() {
+ return USAGE + ":\n\n" + DESC;
+ }
+ }
+
+ public static char[] promptUserForPassword() {
+ char[] password = null;
+ Console c = System.console();
+ if (c == null) {
+ System.err
+ .println("No console to fetch password from user.Consider
setting via --generate or --value.");
+ System.exit(1);
+ }
+
+ boolean noMatch;
+ do {
+ char[] newPassword1 = c.readPassword("Enter password: ");
+ char[] newPassword2 = c.readPassword("Enter password again: ");
+ noMatch = !Arrays.equals(newPassword1, newPassword2);
+ if (noMatch) {
+ c.format("Passwords don't match. Try again.%n");
+ } else {
+ password = Arrays.copyOf(newPassword1, newPassword1.length);
+ }
+ Arrays.fill(newPassword1, ' ');
+ Arrays.fill(newPassword2, ' ');
+ } while (noMatch);
+ return password;
+ }
+
public class MasterCreateCommand extends Command {
public static final String USAGE = "create-master [--force] [--master
mastersecret] [--generate]";
public static final String DESC = "The create-master command persists the
master secret in a file located at:\n" +
diff --git
a/gateway-server/src/test/java/org/apache/knox/gateway/util/KnoxCLITest.java
b/gateway-server/src/test/java/org/apache/knox/gateway/util/KnoxCLITest.java
index 674c48c1e..9c488f6e3 100644
--- a/gateway-server/src/test/java/org/apache/knox/gateway/util/KnoxCLITest.java
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/util/KnoxCLITest.java
@@ -881,6 +881,66 @@ public class KnoxCLITest {
assertThat(outContent.toString(StandardCharsets.UTF_8.name()),
containsString("admin"));
}
+ @Test
+ public void testCreateMultipleAliasesInOneBatch() throws Exception {
+ outContent.reset();
+ String[] args1 = { "create-aliases",
+ "--alias", "alias1", "--value", "testvalue1",
+ "--alias", "alias2", "--value", "testvalue2",
+ "--alias", "alias3", "--value", "testvalue3",
+ "--cluster", "cluster1",
+ "--master", "master" };
+ int rc;
+ KnoxCLI cli = new KnoxCLI();
+ cli.setConf(new GatewayConfigImpl());
+ rc = cli.run(args1);
+ assertEquals(0, rc);
+ assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
outContent.toString(StandardCharsets.UTF_8.name()).contains(
+ "3 alias(es) have been successfully created: [alias1, alias2,
alias3]"));
+ }
+
+ @Test
+ public void testCreateAndGenerateMultipleAliasesInOneBatch1() throws
Exception {
+ outContent.reset();
+ String[] args1 = { "create-aliases",
+ "--alias", "alias1", "--value", "testvalue1",
+ "--alias", "alias2", "--value", "testvalue2",
+ "--alias", "alias3",
+ "--generate",
+ "--cluster", "cluster1",
+ "--master", "master" };
+ int rc;
+ KnoxCLI cli = new KnoxCLI();
+ cli.setConf(new GatewayConfigImpl());
+ rc = cli.run(args1);
+ assertEquals(0, rc);
+ assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
outContent.toString(StandardCharsets.UTF_8.name()).contains(
+ "2 alias(es) have been successfully created: [alias1, alias2]"));
+ assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
outContent.toString(StandardCharsets.UTF_8.name()).contains(
+ "1 alias(es) have been successfully generated: [alias3]"));
+ }
+
+ @Test
+ public void testCreateAndGenerateMultipleAliasesInOneBatch2() throws
Exception {
+ outContent.reset();
+ String[] args1 = { "create-aliases",
+ "--alias", "alias1", "--value", "testvalue1",
+ "--alias", "alias2",
+ "--alias", "alias3",
+ "--generate",
+ "--cluster", "cluster1",
+ "--master", "master" };
+ int rc;
+ KnoxCLI cli = new KnoxCLI();
+ cli.setConf(new GatewayConfigImpl());
+ rc = cli.run(args1);
+ assertEquals(0, rc);
+ assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
outContent.toString(StandardCharsets.UTF_8.name()).contains(
+ "2 alias(es) have been successfully generated: [alias2, alias3]"));
+ assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
outContent.toString(StandardCharsets.UTF_8.name()).contains(
+ "1 alias(es) have been successfully created: [alias1]"));
+ }
+
private class GatewayConfigMock extends GatewayConfigImpl{
private String confDir;
public void setConfDir(String location) {