Skip to content

Commit 1f1f354

Browse files
authored
KNOX-3071: New ability in list-alias to list for multiple clusters. New create-list-alias command to create multiple aliases for multiple clusters and also list them. (#940)
* KNOX-3071: New ability in list-alias to list for multiple clusters. New create-list-alias command to create multiple aliases for multiple clusters and also list them.
1 parent 8445d1c commit 1f1f354

File tree

2 files changed

+271
-28
lines changed

2 files changed

+271
-28
lines changed

gateway-server/src/main/java/org/apache/knox/gateway/util/KnoxCLI.java

Lines changed: 118 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,9 @@ public class KnoxCLI extends Configured implements Tool {
136136
" [" + TopologyConverter.USAGE + "]\n" +
137137
" [" + JWKGenerator.USAGE + "]\n" +
138138
" [" + GenerateDescriptorCommand.USAGE + "]\n" +
139-
" [" + TokenMigration.USAGE + "]\n";
139+
" [" + TokenMigration.USAGE + "]\n" +
140+
" [" + CreateListAliasesCommand.USAGE + "]\n";
141+
private static final String CLUSTER_STRING_SEPARATOR = ",";
140142

141143
/** allows stdout to be captured if necessary */
142144
public PrintStream out = System.out;
@@ -275,6 +277,12 @@ private int init(String[] args) throws IOException {
275277
printKnoxShellUsage();
276278
return -1;
277279
}
280+
} else if (args[i].equals("create-list-aliases")) {
281+
command = new CreateListAliasesCommand();
282+
if (args.length < 3 || "--help".equals(alias)) {
283+
printKnoxShellUsage();
284+
return -1;
285+
}
278286
} else if (args[i].equals("create-cert")) {
279287
command = new CertCreateCommand();
280288
if ((args.length > i + 1) && args[i + 1].equals("--help")) {
@@ -337,12 +345,15 @@ private int init(String[] args) throws IOException {
337345
}
338346
} else if( args[i].equals("list-topologies") ){
339347
command = new ListTopologiesCommand();
340-
}else if ( args[i].equals("--cluster") || args[i].equals("--topology") ) {
348+
} else if ( args[i].equals("--cluster") || args[i].equals("--topology") ) {
341349
if( i+1 >= args.length || args[i+1].startsWith( "-" ) ) {
342350
printKnoxShellUsage();
343351
return -1;
344352
}
345353
this.cluster = args[++i];
354+
if(command instanceof CreateListAliasesCommand) {
355+
((CreateListAliasesCommand) command).toMap(this.cluster);
356+
}
346357
} else if (args[i].equals("service-test")) {
347358
if( i + 1 >= args.length) {
348359
printKnoxShellUsage();
@@ -663,6 +674,12 @@ private void printKnoxShellUsage() {
663674
out.println(JWKGenerator.USAGE + "\n\n" + JWKGenerator.DESC);
664675
out.println();
665676
out.println( div );
677+
out.println(BatchAliasCreateCommand.USAGE + "\n\n" + BatchAliasCreateCommand.DESC);
678+
out.println();
679+
out.println( div );
680+
out.println(CreateListAliasesCommand.USAGE + "\n\n" + CreateListAliasesCommand.DESC);
681+
out.println();
682+
out.println( div );
666683
}
667684
}
668685

@@ -701,31 +718,34 @@ protected RemoteConfigurationRegistryClientService getRemoteConfigRegistryClient
701718

702719
private class AliasListCommand extends Command {
703720

704-
public static final String USAGE = "list-alias [--cluster clustername]";
721+
public static final String USAGE = "list-alias [--cluster cluster1,clusterN]";
705722
public static final String DESC = "The list-alias command lists all of the aliases\n" +
706-
"for the given hadoop --cluster. The default\n" +
723+
"for the given hadoop --cluster(s). The default\n" +
707724
"--cluster being the gateway itself.";
708725

709726
@Override
710727
public void execute() throws Exception {
711728
AliasService as = getAliasService();
712-
KeystoreService keystoreService = getKeystoreService();
729+
KeystoreService keystoreService = getKeystoreService();
713730

714731
if (cluster == null) {
715732
cluster = "__gateway";
716733
}
717-
boolean credentialStoreForClusterAvailable =
718-
keystoreService.isCredentialStoreForClusterAvailable(cluster);
719-
if (credentialStoreForClusterAvailable) {
720-
out.println("Listing aliases for: " + cluster);
721-
List<String> aliases = as.getAliasesForCluster(cluster);
722-
for (String alias : aliases) {
723-
out.println(alias);
724-
}
725-
out.println("\n" + aliases.size() + " items.");
726-
} else {
727-
out.println("Invalid cluster name provided: " + cluster);
728-
}
734+
String[] clusters = cluster.split(CLUSTER_STRING_SEPARATOR);
735+
for (String currentCluster : clusters) {
736+
boolean credentialStoreForClusterAvailable =
737+
keystoreService.isCredentialStoreForClusterAvailable(currentCluster);
738+
if (credentialStoreForClusterAvailable) {
739+
out.println("Listing aliases for: " + currentCluster);
740+
List<String> aliases = as.getAliasesForCluster(currentCluster);
741+
for (String alias : aliases) {
742+
out.println(alias);
743+
}
744+
out.println("\n" + aliases.size() + " items.");
745+
} else {
746+
out.println("Invalid cluster name provided: " + currentCluster);
747+
}
748+
}
729749
}
730750

731751
@Override
@@ -1037,8 +1057,8 @@ public class BatchAliasCreateCommand extends Command {
10371057
+ "the --value option or --generate (will create a random secret\n"
10381058
+ "for you) or user will be prompt to provide password.";
10391059

1040-
private List<String> names = new ArrayList<>();
1041-
private List<String> values = new ArrayList<>();
1060+
protected List<String> names = new ArrayList<>();
1061+
protected List<String> values = new ArrayList<>();
10421062

10431063
public void addName(String alias) {
10441064
if (names.contains(alias)) {
@@ -1061,6 +1081,23 @@ public void execute() throws Exception {
10611081
if (cluster == null) {
10621082
cluster = "__gateway";
10631083
}
1084+
fillMissingValues(aliases, generated);
1085+
as.addAliasesForCluster(cluster, aliases);
1086+
printResults(generated, aliases);
1087+
}
1088+
1089+
protected void printResults(List<String> generated, Map<String, String> aliases) {
1090+
if (!generated.isEmpty()) {
1091+
out.println(generated.size() + " alias(es) have been successfully generated: " + generated);
1092+
}
1093+
List<String> created = new ArrayList<>(aliases.keySet());
1094+
created.removeAll(generated);
1095+
if (!created.isEmpty()) {
1096+
out.println(created.size() + " alias(es) have been successfully created: " + created);
1097+
}
1098+
}
1099+
1100+
protected void fillMissingValues(Map<String, String> aliases, List<String> generated) {
10641101
for (Map.Entry<String, String> entry : aliases.entrySet()) {
10651102
if (entry.getValue() == null) {
10661103
if (Boolean.parseBoolean(generate)) {
@@ -1071,15 +1108,6 @@ public void execute() throws Exception {
10711108
}
10721109
}
10731110
}
1074-
as.addAliasesForCluster(cluster, aliases);
1075-
if (!generated.isEmpty()) {
1076-
out.println(generated.size() + " alias(es) have been successfully generated: " + generated);
1077-
}
1078-
List<String> created = new ArrayList<>(aliases.keySet());
1079-
created.removeAll(generated);
1080-
if (!created.isEmpty()) {
1081-
out.println(created.size() + " alias(es) have been successfully created: " + created);
1082-
}
10831111
}
10841112

10851113
private Map<String, String> toMap() {
@@ -1096,6 +1124,68 @@ public String getUsage() {
10961124
}
10971125
}
10981126

1127+
public class CreateListAliasesCommand extends BatchAliasCreateCommand {
1128+
public static final String USAGE = "create-list-aliases " +
1129+
"--alias alias1 [--value value1] " +
1130+
"--alias alias2 [--value value2] " +
1131+
"--alias aliasN [--value valueN] ... " +
1132+
"--cluster cluster1 " +
1133+
"--alias aliasN [--value valueN] ..." +
1134+
"--cluster clusterN " +
1135+
"[--generate]";
1136+
public static final String DESC = "The create-list-aliases command will create multiple aliases\n"
1137+
+ "and secret pairs within the same credential store for the\n"
1138+
+ "indicated --cluster(s) otherwise within the gateway\n"
1139+
+ "credential store. The actual secret may be specified via\n"
1140+
+ "the --value option or --generate (will create a random secret\n"
1141+
+ "for you) or user will be prompt to provide password.";
1142+
1143+
private final Map<String, Map<String, String>> aliasMap = new LinkedHashMap<>();
1144+
1145+
@Override
1146+
public void execute() throws Exception {
1147+
if (cluster == null || !names.isEmpty()) {
1148+
cluster = "__gateway";
1149+
this.toMap(cluster);
1150+
}
1151+
1152+
AliasService aliasService = getAliasService();
1153+
1154+
for (Map.Entry<String, Map<String, String>> aliasesMapEntry : aliasMap.entrySet()) {
1155+
List<String> generated = new ArrayList<>();
1156+
this.fillMissingValues(aliasesMapEntry.getValue(), generated);
1157+
aliasService.addAliasesForCluster(aliasesMapEntry.getKey(), aliasesMapEntry.getValue());
1158+
this.printResults(generated, aliasesMapEntry.getValue());
1159+
this.listAliasesForCluster(aliasesMapEntry.getKey(), aliasService);
1160+
}
1161+
}
1162+
1163+
private void listAliasesForCluster(String cluster, AliasService as) throws AliasServiceException {
1164+
out.println("Listing aliases for: " + cluster);
1165+
List<String> aliases = as.getAliasesForCluster(cluster);
1166+
for (String alias : aliases) {
1167+
out.println(alias);
1168+
}
1169+
out.println("\n" + aliases.size() + " items.");
1170+
}
1171+
1172+
private void toMap(String cluster) {
1173+
Map<String, String> parsedAliases = new LinkedHashMap<>();
1174+
for (int i = 0; i < values.size(); i++) {
1175+
parsedAliases.put(names.get(i), values.get(i));
1176+
}
1177+
1178+
names.clear();
1179+
values.clear();
1180+
aliasMap.put(cluster, parsedAliases);
1181+
}
1182+
1183+
@Override
1184+
public String getUsage() {
1185+
return USAGE + ":\n\n" + DESC;
1186+
}
1187+
}
1188+
10991189
public static char[] promptUserForPassword() {
11001190
char[] password = null;
11011191
Console c = System.console();

gateway-server/src/test/java/org/apache/knox/gateway/util/KnoxCLITest.java

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,6 +1309,159 @@ public void testGeneratingJwk512() throws Exception {
13091309
testGeneratingJWK(JWSAlgorithm.HS512);
13101310
}
13111311

1312+
@Test
1313+
public void testListingAliasesForMultipleClusters() throws Exception {
1314+
GatewayConfigImpl config = new GatewayConfigImpl();
1315+
1316+
outContent.reset();
1317+
String[] args1 = {"create-alias", "multiplealias", "--value", "multiplealias", "--cluster", "cluster1", "--master", "master"};
1318+
int rc;
1319+
KnoxCLI cli = new KnoxCLI();
1320+
cli.setConf(config);
1321+
rc = cli.run(args1);
1322+
assertEquals(0, rc);
1323+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
1324+
outContent.toString(StandardCharsets.UTF_8.name()).contains("multiplealias has been successfully " +
1325+
"created."));
1326+
1327+
outContent.reset();
1328+
String[] args2 = {"create-alias", "multiplealias2", "--value", "multiplealias2", "--cluster", "test",
1329+
"--master", "master"};
1330+
cli = new KnoxCLI();
1331+
cli.setConf( config );
1332+
rc = cli.run(args2);
1333+
assertEquals(0, rc);
1334+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()), outContent.toString(StandardCharsets.UTF_8.name()).contains("multiplealias2 has been successfully " +
1335+
"created."));
1336+
1337+
outContent.reset();
1338+
String[] args3 = { "list-alias", "--cluster", "cluster1,test", "--master", "master" };
1339+
rc = cli.run(args3);
1340+
assertEquals(0, rc);
1341+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
1342+
outContent.toString(StandardCharsets.UTF_8.name()).contains("multiplealias"));
1343+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
1344+
outContent.toString(StandardCharsets.UTF_8.name()).contains("multiplealias2"));
1345+
1346+
outContent.reset();
1347+
String[] args4 = { "list-alias", "--cluster", "cluster1,test,invalidcluster", "--master", "master" };
1348+
rc = cli.run(args4);
1349+
assertEquals(0, rc);
1350+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
1351+
outContent.toString(StandardCharsets.UTF_8.name()).contains("multiplealias"));
1352+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
1353+
outContent.toString(StandardCharsets.UTF_8.name()).contains("multiplealias2"));
1354+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
1355+
outContent.toString(StandardCharsets.UTF_8.name()).contains("Invalid cluster name provided: invalidcluster"));
1356+
1357+
outContent.reset();
1358+
String[] args5 = {"delete-alias", "multiplealias", "--cluster", "cluster1", "--master", "master"};
1359+
rc = cli.run(args5);
1360+
assertEquals(0, rc);
1361+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()), outContent.toString(StandardCharsets.UTF_8.name()).contains("multiplealias has been successfully " +
1362+
"deleted."));
1363+
1364+
outContent.reset();
1365+
String[] args6 = {"delete-alias", "multiplealias2", "--cluster", "test", "--master", "master"};
1366+
rc = cli.run(args6);
1367+
assertEquals(0, rc);
1368+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()), outContent.toString(StandardCharsets.UTF_8.name()).contains("multiplealias2 has been successfully " +
1369+
"deleted."));
1370+
1371+
outContent.reset();
1372+
rc = cli.run(args3);
1373+
assertEquals(0, rc);
1374+
assertFalse(outContent.toString(StandardCharsets.UTF_8.name()), outContent.toString(StandardCharsets.UTF_8.name()).contains("multiplealias2"));
1375+
}
1376+
1377+
@Test
1378+
public void testCreateAndListForMultipleClusters() throws Exception {
1379+
GatewayConfigImpl config = new GatewayConfigImpl();
1380+
1381+
outContent.reset();
1382+
String[] args1 = {"create-list-aliases", "--alias", "alias1", "--value", "value1", "--cluster", "cluster1",
1383+
"--alias", "alias2", "--value", "value2", "--alias", "alias1", "--value", "value1", "--cluster", "cluster2",
1384+
"--master", "master"};
1385+
int rc;
1386+
KnoxCLI cli = new KnoxCLI();
1387+
cli.setConf(config);
1388+
rc = cli.run(args1);
1389+
assertEquals(0, rc);
1390+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
1391+
outContent.toString(StandardCharsets.UTF_8.name()).contains("1 alias(es) have been successfully created: [alias1]"));
1392+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
1393+
outContent.toString(StandardCharsets.UTF_8.name()).contains("Listing aliases for: cluster1"));
1394+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
1395+
outContent.toString(StandardCharsets.UTF_8.name()).contains("alias1"));
1396+
1397+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
1398+
outContent.toString(StandardCharsets.UTF_8.name()).contains("2 alias(es) have been successfully created: [alias2, alias1]"));
1399+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
1400+
outContent.toString(StandardCharsets.UTF_8.name()).contains("Listing aliases for: cluster2"));
1401+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
1402+
outContent.toString(StandardCharsets.UTF_8.name()).contains("alias2"));
1403+
}
1404+
1405+
@Test
1406+
public void testCreateAndListForMultipleClustersWithGenerate() throws Exception {
1407+
GatewayConfigImpl config = new GatewayConfigImpl();
1408+
1409+
outContent.reset();
1410+
String[] args1 = {"create-list-aliases", "--alias", "alias1", "--cluster", "cluster1", "--alias",
1411+
"alias2", "--value", "value2", "--alias", "alias3", "--cluster", "cluster2",
1412+
"--master", "master", "--generate"};
1413+
int rc;
1414+
KnoxCLI cli = new KnoxCLI();
1415+
cli.setConf(config);
1416+
rc = cli.run(args1);
1417+
assertEquals(0, rc);
1418+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
1419+
outContent.toString(StandardCharsets.UTF_8.name()).contains("1 alias(es) have been successfully generated: [alias1]"));
1420+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
1421+
outContent.toString(StandardCharsets.UTF_8.name()).contains("Listing aliases for: cluster1"));
1422+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
1423+
outContent.toString(StandardCharsets.UTF_8.name()).contains("alias1"));
1424+
1425+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
1426+
outContent.toString(StandardCharsets.UTF_8.name()).contains("1 alias(es) have been successfully created: [alias2]"));
1427+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
1428+
outContent.toString(StandardCharsets.UTF_8.name()).contains("1 alias(es) have been successfully generated: [alias3]"));
1429+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
1430+
outContent.toString(StandardCharsets.UTF_8.name()).contains("Listing aliases for: cluster2"));
1431+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
1432+
outContent.toString(StandardCharsets.UTF_8.name()).contains("alias3"));
1433+
}
1434+
1435+
@Test
1436+
public void testCreateAndListForMultipleClustersNoCLuster() throws Exception {
1437+
GatewayConfigImpl config = new GatewayConfigImpl();
1438+
1439+
outContent.reset();
1440+
String[] args1 = {"create-list-aliases", "--alias", "alias1", "--cluster", "cluster1", "--alias",
1441+
"alias2", "--value", "value2", "--alias", "alias3",
1442+
"--master", "master", "--generate"};
1443+
int rc;
1444+
KnoxCLI cli = new KnoxCLI();
1445+
cli.setConf(config);
1446+
rc = cli.run(args1);
1447+
assertEquals(0, rc);
1448+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
1449+
outContent.toString(StandardCharsets.UTF_8.name()).contains("1 alias(es) have been successfully generated: [alias1]"));
1450+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
1451+
outContent.toString(StandardCharsets.UTF_8.name()).contains("Listing aliases for: cluster1"));
1452+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
1453+
outContent.toString(StandardCharsets.UTF_8.name()).contains("alias1"));
1454+
1455+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
1456+
outContent.toString(StandardCharsets.UTF_8.name()).contains("1 alias(es) have been successfully created: [alias2]"));
1457+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
1458+
outContent.toString(StandardCharsets.UTF_8.name()).contains("1 alias(es) have been successfully generated: [alias3]"));
1459+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
1460+
outContent.toString(StandardCharsets.UTF_8.name()).contains("Listing aliases for: __gateway"));
1461+
assertTrue(outContent.toString(StandardCharsets.UTF_8.name()),
1462+
outContent.toString(StandardCharsets.UTF_8.name()).contains("alias3"));
1463+
}
1464+
13121465
private void testGeneratingJWK(JWSAlgorithm jwkAlgorithm) throws Exception {
13131466
testGeneratingJWK(jwkAlgorithm, null);
13141467
}

0 commit comments

Comments
 (0)