Skip to content

Commit

Permalink
KEYCLOAK-19425 Allow comma separated args-list in CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
DGuhr authored and pedroigor committed Oct 4, 2021
1 parent 021245a commit 24a6b77
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 26 deletions.
8 changes: 5 additions & 3 deletions quarkus/runtime/src/main/java/org/keycloak/cli/Picocli.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
final class Picocli {

private static final Logger logger = Logger.getLogger(Picocli.class);
private static final String ARG_SEPARATOR = ";;";
private static final String ARG_PREFIX = "--";

static CommandLine createCommandLine(List<String> cliArgs) {
CommandLine.Model.CommandSpec spec = CommandLine.Model.CommandSpec.forAnnotatedObject(new MainCommand())
Expand Down Expand Up @@ -86,9 +88,9 @@ static String parseConfigArgs(List<String> argsList) {
iterator.remove();
}

if (key.startsWith("--")) {
if (key.startsWith(ARG_PREFIX)) {
if (options.length() > 0) {
options.append(",");
options.append(ARG_SEPARATOR);
}
options.append(key);
}
Expand All @@ -106,7 +108,7 @@ private static void addOption(CommandLine.Model.CommandSpec spec, String command
}

for (PropertyMapper mapper : mappers) {
String name = "--" + PropertyMappers.toCLIFormat(mapper.getFrom()).substring(3);
String name = ARG_PREFIX + PropertyMappers.toCLIFormat(mapper.getFrom()).substring(3);
String description = mapper.getDescription();

if (description == null || commandSpec.optionsMap().containsKey(name)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public class ConfigArgsConfigSource extends PropertiesConfigSource {

private static final Logger log = Logger.getLogger(ConfigArgsConfigSource.class);

private static final Pattern ARG_SPLIT = Pattern.compile(",");
private static final Pattern ARG_SPLIT = Pattern.compile(";;");
private static final Pattern ARG_KEY_VALUE_SPLIT = Pattern.compile("=");
private static final String ARG_PREFIX = "--";
private static final Pattern DOT_SPLIT = Pattern.compile("\\.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public class ConfigurationTest {

private static final Properties SYSTEM_PROPERTIES = (Properties) System.getProperties().clone();
private static final Map<String, String> ENVIRONMENT_VARIABLES = new HashMap<>(System.getenv());
private static final String ARG_SEPARATOR = ";;";

@SuppressWarnings("unchecked")
public static void putEnvVar(String name, String value) {
Expand Down Expand Up @@ -110,57 +111,57 @@ public void testCamelCase() {

@Test
public void testEnvVarPriorityOverPropertiesFile() {
putEnvVar("KC_SPI_HOSTNAME_DEFAULT_FRONTEND_URL", "http://envvar.com");
assertEquals("http://envvar.com", initConfig("hostname", "default").get("frontendUrl"));
putEnvVar("KC_SPI_HOSTNAME_DEFAULT_FRONTEND_URL", "http://envvar.unittest");
assertEquals("http://envvar.unittest", initConfig("hostname", "default").get("frontendUrl"));
}

@Test
public void testSysPropPriorityOverEnvVar() {
putEnvVar("KC_SPI_HOSTNAME_DEFAULT_FRONTEND_URL", "http://envvar.com");
System.setProperty("kc.spi.hostname.default.frontend-url", "http://propvar.com");
assertEquals("http://propvar.com", initConfig("hostname", "default").get("frontendUrl"));
putEnvVar("KC_SPI_HOSTNAME_DEFAULT_FRONTEND_URL", "http://envvar.unittest");
System.setProperty("kc.spi.hostname.default.frontend-url", "http://propvar.unittest");
assertEquals("http://propvar.unittest", initConfig("hostname", "default").get("frontendUrl"));
}

@Test
public void testCLIPriorityOverSysProp() {
System.setProperty("kc.spi.hostname.default.frontend-url", "http://propvar.com");
System.setProperty(CLI_ARGS, "--spi-hostname-default-frontend-url=http://cli.com");
assertEquals("http://cli.com", initConfig("hostname", "default").get("frontendUrl"));
System.setProperty("kc.spi.hostname.default.frontend-url", "http://propvar.unittest");
System.setProperty(CLI_ARGS, "--spi-hostname-default-frontend-url=http://cli.unittest");
assertEquals("http://cli.unittest", initConfig("hostname", "default").get("frontendUrl"));
}

@Test
public void testDefaultValueFromProperty() {
System.setProperty("keycloak.frontendUrl", "http://defaultvalueprop.com");
assertEquals("http://defaultvalueprop.com", initConfig("hostname", "default").get("frontendUrl"));
System.setProperty("keycloak.frontendUrl", "http://defaultvalueprop.unittest");
assertEquals("http://defaultvalueprop.unittest", initConfig("hostname", "default").get("frontendUrl"));
}

@Test
public void testDefaultValue() {
assertEquals("http://filepropdefault.com", initConfig("hostname", "default").get("frontendUrl"));
assertEquals("http://filepropdefault.unittest", initConfig("hostname", "default").get("frontendUrl"));
}

@Test
public void testKeycloakProfilePropertySubstitution() {
System.setProperty("kc.profile", "user-profile");
assertEquals("http://filepropprofile.com", initConfig("hostname", "default").get("frontendUrl"));
assertEquals("http://filepropprofile.unittest", initConfig("hostname", "default").get("frontendUrl"));
}

@Test
public void testQuarkusProfilePropertyStillWorks() {
System.setProperty("quarkus.profile", "user-profile");
assertEquals("http://filepropprofile.com", initConfig("hostname", "default").get("frontendUrl"));
assertEquals("http://filepropprofile.unittest", initConfig("hostname", "default").get("frontendUrl"));
}

@Test
public void testCommandLineArguments() {
System.setProperty(CLI_ARGS, "--spi-hostname-default-frontend-url=http://fromargs.com,--no-ssl");
assertEquals("http://fromargs.com", initConfig("hostname", "default").get("frontendUrl"));
System.setProperty(CLI_ARGS, "--spi-hostname-default-frontend-url=http://fromargs.unittest" + ARG_SEPARATOR + "--no-ssl");
assertEquals("http://fromargs.unittest", initConfig("hostname", "default").get("frontendUrl"));
}

@Test
public void testSpiConfigurationUsingCommandLineArguments() {
System.setProperty(CLI_ARGS, "--spi-hostname-default-frontend-url=http://spifull.com");
assertEquals("http://spifull.com", initConfig("hostname", "default").get("frontendUrl"));
System.setProperty(CLI_ARGS, "--spi-hostname-default-frontend-url=http://spifull.unittest");
assertEquals("http://spifull.unittest", initConfig("hostname", "default").get("frontendUrl"));

// test multi-word SPI names using camel cases
System.setProperty(CLI_ARGS, "--spi-action-token-handler-verify-email-some-property=test");
Expand All @@ -175,15 +176,15 @@ public void testSpiConfigurationUsingCommandLineArguments() {

@Test
public void testPropertyMapping() {
System.setProperty(CLI_ARGS, "--db=mariadb,--db-url=jdbc:mariadb://localhost/keycloak");
System.setProperty(CLI_ARGS, "--db=mariadb" + ARG_SEPARATOR + "--db-url=jdbc:mariadb://localhost/keycloak");
SmallRyeConfig config = createConfig();
assertEquals(MariaDBDialect.class.getName(), config.getConfigValue("quarkus.hibernate-orm.dialect").getValue());
assertEquals("jdbc:mariadb://localhost/keycloak", config.getConfigValue("quarkus.datasource.jdbc.url").getValue());
}

@Test
public void testDatabaseUrlProperties() {
System.setProperty(CLI_ARGS, "--db=mariadb,--db-url=jdbc:mariadb:aurora://foo/bar?a=1&b=2");
System.setProperty(CLI_ARGS, "--db=mariadb" + ARG_SEPARATOR + "--db-url=jdbc:mariadb:aurora://foo/bar?a=1&b=2");
SmallRyeConfig config = createConfig();
assertEquals(MariaDBDialect.class.getName(), config.getConfigValue("quarkus.hibernate-orm.dialect").getValue());
assertEquals("jdbc:mariadb:aurora://foo/bar?a=1&b=2", config.getConfigValue("quarkus.datasource.jdbc.url").getValue());
Expand All @@ -205,7 +206,7 @@ public void testDatabaseDefaults() {

@Test
public void testDatabaseKindProperties() {
System.setProperty(CLI_ARGS, "--db=postgres-10,--db-url=jdbc:postgresql://localhost/keycloak");
System.setProperty(CLI_ARGS, "--db=postgres-10" + ARG_SEPARATOR + "--db-url=jdbc:postgresql://localhost/keycloak");
SmallRyeConfig config = createConfig();
assertEquals("io.quarkus.hibernate.orm.runtime.dialect.QuarkusPostgreSQL10Dialect",
config.getConfigValue("quarkus.hibernate-orm.dialect").getValue());
Expand Down Expand Up @@ -267,6 +268,21 @@ public void testClusterConfig() {
Assert.assertEquals("foo", initConfig("connectionsInfinispan", "quarkus").get("stack"));
}

@Test
public void testCommaSeparatedArgValues() {
System.setProperty(CLI_ARGS, "--spi-client-jpa-searchable-attributes=bar,foo");
assertEquals("bar,foo", initConfig("client-jpa").get("searchable-attributes"));

System.setProperty(CLI_ARGS, "--spi-client-jpa-searchable-attributes=bar,foo,foo bar");
assertEquals("bar,foo,foo bar", initConfig("client-jpa").get("searchable-attributes"));

System.setProperty(CLI_ARGS, "--spi-client-jpa-searchable-attributes=bar,foo, \"foo bar\"");
assertEquals("bar,foo, \"foo bar\"", initConfig("client-jpa").get("searchable-attributes"));

System.setProperty(CLI_ARGS, "--spi-client-jpa-searchable-attributes=bar,foo, \"foo bar\"" + ARG_SEPARATOR + "--spi-hostname-default-frontend-url=http://foo.unittest");
assertEquals("http://foo.unittest", initConfig("hostname-default").get("frontend-url"));
}

private Config.Scope initConfig(String... scope) {
Config.init(new MicroProfileConfigProvider(createConfig()));
return Config.scope(scope);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
spi.hostname.default.frontend-url = ${keycloak.frontendUrl:http://filepropdefault.com}
%user-profile.spi.hostname.default.frontend-url = http://filepropprofile.com
spi.hostname.default.frontend-url = ${keycloak.frontendUrl:http://filepropdefault.unittest}
%user-profile.spi.hostname.default.frontend-url = http://filepropprofile.unittest

# Default Non-Production Grade Datasource
quarkus.datasource.db-kind=h2
Expand Down

0 comments on commit 24a6b77

Please sign in to comment.