Unified configuration option format and renaming keycloak.properties to keycloak.conf
Closes #9606
This commit is contained in:
parent
8ed7c0544f
commit
0a9387ff4f
47 changed files with 275 additions and 393 deletions
|
@ -0,0 +1,34 @@
|
||||||
|
# Basic settings for running in production. Change accordingly before deploying the server.
|
||||||
|
|
||||||
|
# Database
|
||||||
|
|
||||||
|
# The database vendor.
|
||||||
|
#db=postgres
|
||||||
|
|
||||||
|
# The username of the database user.
|
||||||
|
#db-username=keycloak
|
||||||
|
|
||||||
|
# The password of the database user.
|
||||||
|
#db-password=password
|
||||||
|
|
||||||
|
# The full database JDBC URL. If not provided, a default URL is set based on the selected database vendor.
|
||||||
|
#db-url=jdbc:postgresql://localhost/keycloak
|
||||||
|
|
||||||
|
# Observability
|
||||||
|
|
||||||
|
# If the server should expose metrics and healthcheck endpoints.
|
||||||
|
#metrics-enabled=true
|
||||||
|
|
||||||
|
# HTTP
|
||||||
|
|
||||||
|
# The file path to a server certificate or certificate chain in PEM format.
|
||||||
|
#https-certificate-file=${kc.home.dir}conf/server.crt.pem
|
||||||
|
|
||||||
|
# The file path to a private key in PEM format.
|
||||||
|
#https-certificate-key-file=${kc.home.dir}conf/server.key.pem
|
||||||
|
|
||||||
|
# The proxy address forwarding mode if the server is behind a reverse proxy.
|
||||||
|
#proxy=reencrypt
|
||||||
|
|
||||||
|
# Hostname for the Keycloak server.
|
||||||
|
#hostname=myhostname
|
|
@ -1,14 +0,0 @@
|
||||||
# Basic settings for running in production. Change accordingly before deploying the server.
|
|
||||||
# Database
|
|
||||||
#%prod.db=postgres
|
|
||||||
#%prod.db.username=keycloak
|
|
||||||
#%prod.db.password=password
|
|
||||||
#%prod.db.url=jdbc:postgresql://localhost/keycloak
|
|
||||||
# Observability
|
|
||||||
#%prod.metrics.enabled=true
|
|
||||||
# HTTP
|
|
||||||
#%prod.spi.hostname.frontend-url=https://localhost:8443
|
|
||||||
#%prod.https.certificate.file=${kc.home.dir}conf/server.crt.pem
|
|
||||||
#%prod.https.certificate.key-file=${kc.home.dir}conf/server.key.pem
|
|
||||||
#%prod.proxy=reencrypt
|
|
||||||
#%prod.hostname=myhostname
|
|
|
@ -45,7 +45,7 @@ public class CLusteringBuildSteps {
|
||||||
@Record(ExecutionTime.RUNTIME_INIT)
|
@Record(ExecutionTime.RUNTIME_INIT)
|
||||||
@BuildStep
|
@BuildStep
|
||||||
void configureInfinispan(KeycloakRecorder recorder, BuildProducer<SyntheticBeanBuildItem> syntheticBeanBuildItems, ShutdownContextBuildItem shutdownContext) {
|
void configureInfinispan(KeycloakRecorder recorder, BuildProducer<SyntheticBeanBuildItem> syntheticBeanBuildItems, ShutdownContextBuildItem shutdownContext) {
|
||||||
String configFile = getConfigValue("kc.spi.connections-infinispan.quarkus.config-file").getValue();
|
String configFile = getConfigValue("kc.spi-connections-infinispan-quarkus-config-file").getValue();
|
||||||
|
|
||||||
if (configFile != null) {
|
if (configFile != null) {
|
||||||
Path configPath = Paths.get(configFile);
|
Path configPath = Paths.get(configFile);
|
||||||
|
|
|
@ -414,7 +414,7 @@ class KeycloakProcessor {
|
||||||
|
|
||||||
@BuildStep(onlyIf = IsDevelopment.class)
|
@BuildStep(onlyIf = IsDevelopment.class)
|
||||||
void configureDevMode(BuildProducer<HotDeploymentWatchedFileBuildItem> hotFiles) {
|
void configureDevMode(BuildProducer<HotDeploymentWatchedFileBuildItem> hotFiles) {
|
||||||
hotFiles.produce(new HotDeploymentWatchedFileBuildItem("META-INF/keycloak.properties"));
|
hotFiles.produce(new HotDeploymentWatchedFileBuildItem("META-INF/keycloak.conf"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<Spi, Map<Class<? extends Provider>, Map<String, ProviderFactory>>> loadFactories(
|
private Map<Spi, Map<Class<? extends Provider>, Map<String, ProviderFactory>>> loadFactories(
|
||||||
|
@ -591,6 +591,6 @@ class KeycloakProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isMetricsEnabled() {
|
private boolean isMetricsEnabled() {
|
||||||
return Configuration.getOptionalBooleanValue(MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX.concat("metrics.enabled")).orElse(false);
|
return Configuration.getOptionalBooleanValue(MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX.concat("metrics-enabled")).orElse(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ public class KeycloakNegativeHealthCheckTest {
|
||||||
@RegisterExtension
|
@RegisterExtension
|
||||||
static final QuarkusUnitTest test = new QuarkusUnitTest()
|
static final QuarkusUnitTest test = new QuarkusUnitTest()
|
||||||
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
|
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
|
||||||
.addAsResource("keycloak.properties", "META-INF/keycloak.properties"));
|
.addAsResource("keycloak.conf", "META-INF/keycloak.conf"));
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadinessDown() {
|
public void testReadinessDown() {
|
||||||
|
|
|
@ -33,7 +33,7 @@ public class KeycloakReadyHealthCheckTest {
|
||||||
@RegisterExtension
|
@RegisterExtension
|
||||||
static final QuarkusUnitTest test = new QuarkusUnitTest()
|
static final QuarkusUnitTest test = new QuarkusUnitTest()
|
||||||
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
|
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
|
||||||
.addAsResource("keycloak.properties", "META-INF/keycloak.properties"));
|
.addAsResource("keycloak.conf", "META-INF/keycloak.conf"));
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLivenessUp() {
|
public void testLivenessUp() {
|
||||||
|
|
8
quarkus/deployment/src/test/resources/keycloak.conf
Normal file
8
quarkus/deployment/src/test/resources/keycloak.conf
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
http-enabled=true
|
||||||
|
cluster=local
|
||||||
|
hostname-strict=false
|
||||||
|
hostname-strict-https=false
|
||||||
|
db=h2-mem
|
||||||
|
db-username = sa
|
||||||
|
db-password = keycloak
|
||||||
|
metrics-enabled=true
|
|
@ -1,8 +0,0 @@
|
||||||
http.enabled=true
|
|
||||||
cluster=local
|
|
||||||
hostname.strict=false
|
|
||||||
hostname.strict-https=false
|
|
||||||
db=h2-mem
|
|
||||||
db.username = sa
|
|
||||||
db.password = keycloak
|
|
||||||
metrics.enabled=true
|
|
|
@ -99,7 +99,7 @@ public final class ExecutionExceptionHandler implements CommandLine.IExecutionEx
|
||||||
private void printErrorHints(PrintWriter errorWriter, Throwable cause) {
|
private void printErrorHints(PrintWriter errorWriter, Throwable cause) {
|
||||||
if (cause instanceof FileSystemException) {
|
if (cause instanceof FileSystemException) {
|
||||||
FileSystemException fse = (FileSystemException) cause;
|
FileSystemException fse = (FileSystemException) cause;
|
||||||
ConfigValue httpsCertFile = getConfig().getConfigValue("kc.https.certificate.file");
|
ConfigValue httpsCertFile = getConfig().getConfigValue("kc.https-certificate-file");
|
||||||
|
|
||||||
if (fse.getFile().equals(Optional.ofNullable(httpsCertFile.getValue()).orElse(null))) {
|
if (fse.getFile().equals(Optional.ofNullable(httpsCertFile.getValue()).orElse(null))) {
|
||||||
logError(errorWriter, Messages.httpsConfigurationNotSet().getMessage());
|
logError(errorWriter, Messages.httpsConfigurationNotSet().getMessage());
|
||||||
|
|
|
@ -17,12 +17,12 @@
|
||||||
|
|
||||||
package org.keycloak.quarkus.runtime.cli;
|
package org.keycloak.quarkus.runtime.cli;
|
||||||
|
|
||||||
import static io.smallrye.config.common.utils.StringUtil.replaceNonAlphanumericByUnderscores;
|
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.AUTO_BUILD_OPTION_LONG;
|
import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.AUTO_BUILD_OPTION_LONG;
|
||||||
import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.AUTO_BUILD_OPTION_SHORT;
|
import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.AUTO_BUILD_OPTION_SHORT;
|
||||||
import static org.keycloak.quarkus.runtime.configuration.ConfigArgsConfigSource.hasOptionValue;
|
import static org.keycloak.quarkus.runtime.configuration.ConfigArgsConfigSource.hasOptionValue;
|
||||||
import static org.keycloak.quarkus.runtime.configuration.ConfigArgsConfigSource.parseConfigArgs;
|
import static org.keycloak.quarkus.runtime.configuration.ConfigArgsConfigSource.parseConfigArgs;
|
||||||
|
import static org.keycloak.quarkus.runtime.configuration.Configuration.OPTION_PART_SEPARATOR;
|
||||||
import static org.keycloak.quarkus.runtime.configuration.Configuration.getBuildTimeProperty;
|
import static org.keycloak.quarkus.runtime.configuration.Configuration.getBuildTimeProperty;
|
||||||
import static org.keycloak.quarkus.runtime.configuration.Configuration.getConfig;
|
import static org.keycloak.quarkus.runtime.configuration.Configuration.getConfig;
|
||||||
import static org.keycloak.quarkus.runtime.Environment.isDevMode;
|
import static org.keycloak.quarkus.runtime.Environment.isDevMode;
|
||||||
|
@ -35,7 +35,6 @@ import static picocli.CommandLine.Model.UsageMessageSpec.SECTION_KEY_COMMAND_LIS
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -71,7 +70,6 @@ public final class Picocli {
|
||||||
public static final String ARG_PREFIX = "--";
|
public static final String ARG_PREFIX = "--";
|
||||||
private static final String ARG_KEY_VALUE_SEPARATOR = "=";
|
private static final String ARG_KEY_VALUE_SEPARATOR = "=";
|
||||||
public static final String ARG_SHORT_PREFIX = "-";
|
public static final String ARG_SHORT_PREFIX = "-";
|
||||||
public static final String ARG_PART_SEPARATOR = "-";
|
|
||||||
public static final String NO_PARAM_LABEL = "none";
|
public static final String NO_PARAM_LABEL = "none";
|
||||||
|
|
||||||
private Picocli() {
|
private Picocli() {
|
||||||
|
@ -348,10 +346,10 @@ public final class Picocli {
|
||||||
.validate(false);
|
.validate(false);
|
||||||
|
|
||||||
for(PropertyMapper mapper: mappersInCategory) {
|
for(PropertyMapper mapper: mappersInCategory) {
|
||||||
String name = ARG_PREFIX + PropertyMappers.toCLIFormat(mapper.getFrom()).substring(3);
|
String name = mapper.getCliFormat();
|
||||||
String description = mapper.getDescription();
|
String description = mapper.getDescription();
|
||||||
|
|
||||||
if (description == null || cSpec.optionsMap().containsKey(name) || name.endsWith(ARG_PART_SEPARATOR)) {
|
if (description == null || cSpec.optionsMap().containsKey(name) || name.endsWith(OPTION_PART_SEPARATOR)) {
|
||||||
//when key is already added or has no description, don't add.
|
//when key is already added or has no description, don't add.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -378,10 +376,6 @@ public final class Picocli {
|
||||||
cmd.getOut().println(message);
|
cmd.getOut().println(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String normalizeKey(String key) {
|
|
||||||
return replaceNonAlphanumericByUnderscores(key).replace('_', '.');
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<String> parseArgs(String[] rawArgs) {
|
public static List<String> parseArgs(String[] rawArgs) {
|
||||||
if (rawArgs.length == 0) {
|
if (rawArgs.length == 0) {
|
||||||
return List.of();
|
return List.of();
|
||||||
|
|
|
@ -107,7 +107,7 @@ public final class Main {
|
||||||
|
|
||||||
@Option(names = { CONFIG_FILE_SHORT_NAME, CONFIG_FILE_LONG_NAME },
|
@Option(names = { CONFIG_FILE_SHORT_NAME, CONFIG_FILE_LONG_NAME },
|
||||||
arity = "1",
|
arity = "1",
|
||||||
description = "Set the path to a configuration file. By default, configuration properties are read from the \"keycloak.properties\" file in the \"conf\" directory.",
|
description = "Set the path to a configuration file. By default, configuration properties are read from the \"keycloak.conf\" file in the \"conf\" directory.",
|
||||||
paramLabel = "file")
|
paramLabel = "file")
|
||||||
public void setConfigFile(String path) {
|
public void setConfigFile(String path) {
|
||||||
System.setProperty(KeycloakPropertiesConfigSource.KEYCLOAK_CONFIG_FILE_PROP, path);
|
System.setProperty(KeycloakPropertiesConfigSource.KEYCLOAK_CONFIG_FILE_PROP, path);
|
||||||
|
|
|
@ -20,7 +20,6 @@ package org.keycloak.quarkus.runtime.cli.command;
|
||||||
import static org.keycloak.quarkus.runtime.Environment.getCurrentOrPersistedProfile;
|
import static org.keycloak.quarkus.runtime.Environment.getCurrentOrPersistedProfile;
|
||||||
import static org.keycloak.quarkus.runtime.configuration.Configuration.getConfigValue;
|
import static org.keycloak.quarkus.runtime.configuration.Configuration.getConfigValue;
|
||||||
import static org.keycloak.quarkus.runtime.configuration.Configuration.getPropertyNames;
|
import static org.keycloak.quarkus.runtime.configuration.Configuration.getPropertyNames;
|
||||||
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers.canonicalFormat;
|
|
||||||
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers.formatValue;
|
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers.formatValue;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -63,8 +62,6 @@ public final class ShowConfig extends AbstractCommand implements Runnable {
|
||||||
printRunTimeConfig(properties, profile);
|
printRunTimeConfig(properties, profile);
|
||||||
|
|
||||||
if (configArgs.equalsIgnoreCase("all")) {
|
if (configArgs.equalsIgnoreCase("all")) {
|
||||||
printAllProfilesConfig(properties, profile);
|
|
||||||
|
|
||||||
spec.commandLine().getOut().println("Quarkus Configuration:");
|
spec.commandLine().getOut().println("Quarkus Configuration:");
|
||||||
properties.get(MicroProfileConfigProvider.NS_QUARKUS).stream().sorted()
|
properties.get(MicroProfileConfigProvider.NS_QUARKUS).stream().sorted()
|
||||||
.forEachOrdered(this::printProperty);
|
.forEachOrdered(this::printProperty);
|
||||||
|
@ -84,37 +81,10 @@ public final class ShowConfig extends AbstractCommand implements Runnable {
|
||||||
spec.commandLine().getOut().println("Runtime Configuration:");
|
spec.commandLine().getOut().println("Runtime Configuration:");
|
||||||
|
|
||||||
properties.get(MicroProfileConfigProvider.NS_KEYCLOAK).stream().sorted()
|
properties.get(MicroProfileConfigProvider.NS_KEYCLOAK).stream().sorted()
|
||||||
.filter(name -> {
|
.filter(uniqueNames::add)
|
||||||
String canonicalFormat = canonicalFormat(name);
|
|
||||||
|
|
||||||
if (!canonicalFormat.equals(name)) {
|
|
||||||
return uniqueNames.add(canonicalFormat);
|
|
||||||
}
|
|
||||||
return uniqueNames.add(name);
|
|
||||||
})
|
|
||||||
.forEachOrdered(this::printProperty);
|
.forEachOrdered(this::printProperty);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void printAllProfilesConfig(Map<String, Set<String>> properties, String profile) {
|
|
||||||
Set<String> profiles = properties.get("%");
|
|
||||||
|
|
||||||
if (profiles != null) {
|
|
||||||
profiles.stream()
|
|
||||||
.sorted()
|
|
||||||
.collect(Collectors.groupingBy(s -> s.substring(1, s.indexOf('.'))))
|
|
||||||
.forEach((p, properties1) -> {
|
|
||||||
if (p.equals(profile)) {
|
|
||||||
spec.commandLine().getOut().printf("Profile \"%s\" Configuration (%s):%n", p,
|
|
||||||
"current");
|
|
||||||
} else {
|
|
||||||
spec.commandLine().getOut().printf("Profile \"%s\" Configuration:%n", p);
|
|
||||||
}
|
|
||||||
|
|
||||||
properties1.stream().sorted().forEachOrdered(this::printProperty);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Map<String, Set<String>> getPropertiesByGroup() {
|
private static Map<String, Set<String>> getPropertiesByGroup() {
|
||||||
Map<String, Set<String>> properties = StreamSupport
|
Map<String, Set<String>> properties = StreamSupport
|
||||||
.stream(getPropertyNames().spliterator(), false)
|
.stream(getPropertyNames().spliterator(), false)
|
||||||
|
@ -147,8 +117,7 @@ public final class ShowConfig extends AbstractCommand implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void printProperty(String property) {
|
private void printProperty(String property) {
|
||||||
String canonicalFormat = canonicalFormat(property);
|
ConfigValue configValue = getConfigValue(property);
|
||||||
ConfigValue configValue = getConfigValue(canonicalFormat);
|
|
||||||
|
|
||||||
if (configValue.getValue() == null) {
|
if (configValue.getValue() == null) {
|
||||||
configValue = getConfigValue(property);
|
configValue = getConfigValue(property);
|
||||||
|
|
|
@ -21,6 +21,8 @@ import static java.util.Arrays.asList;
|
||||||
import static org.keycloak.quarkus.runtime.cli.Picocli.ARG_SHORT_PREFIX;
|
import static org.keycloak.quarkus.runtime.cli.Picocli.ARG_SHORT_PREFIX;
|
||||||
import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.AUTO_BUILD_OPTION_LONG;
|
import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.AUTO_BUILD_OPTION_LONG;
|
||||||
import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.AUTO_BUILD_OPTION_SHORT;
|
import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.AUTO_BUILD_OPTION_SHORT;
|
||||||
|
import static org.keycloak.quarkus.runtime.configuration.Configuration.OPTION_PART_SEPARATOR;
|
||||||
|
import static org.keycloak.quarkus.runtime.configuration.Configuration.OPTION_PART_SEPARATOR_CHAR;
|
||||||
import static org.keycloak.quarkus.runtime.configuration.Configuration.getMappedPropertyName;
|
import static org.keycloak.quarkus.runtime.configuration.Configuration.getMappedPropertyName;
|
||||||
import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX;
|
import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX;
|
||||||
|
|
||||||
|
@ -97,7 +99,7 @@ public class ConfigArgsConfigSource extends PropertiesConfigSource {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return properties.get(propertyName.replace('-', '.'));
|
return properties.get(propertyName.replace(OPTION_PART_SEPARATOR_CHAR, '.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<String, String> parseArgument() {
|
private static Map<String, String> parseArgument() {
|
||||||
|
@ -127,9 +129,6 @@ public class ConfigArgsConfigSource extends PropertiesConfigSource {
|
||||||
if (mapper != null) {
|
if (mapper != null) {
|
||||||
properties.put(mapper.getFrom(), value);
|
properties.put(mapper.getFrom(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// to make lookup easier, we normalize the key
|
|
||||||
properties.put(Picocli.normalizeKey(key), value);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -17,17 +17,15 @@
|
||||||
|
|
||||||
package org.keycloak.quarkus.runtime.configuration;
|
package org.keycloak.quarkus.runtime.configuration;
|
||||||
|
|
||||||
|
import static io.smallrye.config.common.utils.StringUtil.replaceNonAlphanumericByUnderscores;
|
||||||
import static org.keycloak.quarkus.runtime.Environment.getProfileOrDefault;
|
import static org.keycloak.quarkus.runtime.Environment.getProfileOrDefault;
|
||||||
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers.toCLIFormat;
|
import static org.keycloak.quarkus.runtime.cli.Picocli.ARG_PREFIX;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import io.smallrye.config.ConfigValue;
|
import io.smallrye.config.ConfigValue;
|
||||||
import io.smallrye.config.SmallRyeConfig;
|
import io.smallrye.config.SmallRyeConfig;
|
||||||
import io.smallrye.config.SmallRyeConfigProviderResolver;
|
|
||||||
|
|
||||||
import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
|
import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
|
||||||
import org.eclipse.microprofile.config.spi.ConfigSource;
|
import org.eclipse.microprofile.config.spi.ConfigSource;
|
||||||
|
@ -40,6 +38,9 @@ import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
|
||||||
*/
|
*/
|
||||||
public final class Configuration {
|
public final class Configuration {
|
||||||
|
|
||||||
|
public static final char OPTION_PART_SEPARATOR_CHAR = '-';
|
||||||
|
public static final String OPTION_PART_SEPARATOR = String.valueOf(OPTION_PART_SEPARATOR_CHAR);
|
||||||
|
|
||||||
private Configuration() {
|
private Configuration() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -98,17 +99,14 @@ public final class Configuration {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getMappedPropertyName(String key) {
|
public static String getMappedPropertyName(String key) {
|
||||||
for (PropertyMapper mapper : PropertyMappers.getMappers()) {
|
PropertyMapper mapper = PropertyMappers.getMapper(key);
|
||||||
String mappedProperty = mapper.getFrom();
|
|
||||||
List<String> expectedFormats = Arrays.asList(mappedProperty, toCLIFormat(mappedProperty), mappedProperty.toUpperCase().replace('.', '_').replace('-', '_'));
|
|
||||||
|
|
||||||
if (expectedFormats.contains(key)) {
|
if (mapper == null) {
|
||||||
// we also need to make sure the target property is available when defined such as when defining alias for provider config (no spi-prefix).
|
return key;
|
||||||
return mapper.getTo() == null ? mappedProperty : mapper.getTo();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return key;
|
// we also need to make sure the target property is available when defined such as when defining alias for provider config (no spi-prefix).
|
||||||
|
return mapper.getTo() == null ? mapper.getFrom() : mapper.getTo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Optional<String> getRuntimeProperty(String name) {
|
public static Optional<String> getRuntimeProperty(String name) {
|
||||||
|
@ -131,6 +129,14 @@ public final class Configuration {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String toEnvVarFormat(String key) {
|
||||||
|
return replaceNonAlphanumericByUnderscores(key).toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String toCliFormat(String key) {
|
||||||
|
return ARG_PREFIX + key;
|
||||||
|
}
|
||||||
|
|
||||||
private static String getValue(ConfigSource configSource, String name) {
|
private static String getValue(ConfigSource configSource, String name) {
|
||||||
String value = configSource.getValue(name);
|
String value = configSource.getValue(name);
|
||||||
|
|
||||||
|
|
|
@ -33,10 +33,12 @@ public class KcEnvConfigSource extends EnvConfigSource {
|
||||||
|
|
||||||
private static Map<String, String> buildProperties() {
|
private static Map<String, String> buildProperties() {
|
||||||
Map<String, String> properties = new HashMap<>();
|
Map<String, String> properties = new HashMap<>();
|
||||||
|
String kcPrefix = replaceNonAlphanumericByUnderscores(MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX.toUpperCase());
|
||||||
|
|
||||||
for (Map.Entry<String, String> entry : System.getenv().entrySet()) {
|
for (Map.Entry<String, String> entry : System.getenv().entrySet()) {
|
||||||
String key = entry.getKey();
|
String key = entry.getKey();
|
||||||
if (key.startsWith(replaceNonAlphanumericByUnderscores(MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX.toUpperCase()))) {
|
|
||||||
|
if (key.startsWith(kcPrefix)) {
|
||||||
properties.put(getMappedPropertyName(key), entry.getValue());
|
properties.put(getMappedPropertyName(key), entry.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,6 @@ public class KeycloakConfigSourceProvider implements ConfigSourceProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
CONFIG_SOURCES.add(new ConfigArgsConfigSource());
|
CONFIG_SOURCES.add(new ConfigArgsConfigSource());
|
||||||
CONFIG_SOURCES.add(new SysPropConfigSource());
|
|
||||||
CONFIG_SOURCES.add(new KcEnvConfigSource());
|
CONFIG_SOURCES.add(new KcEnvConfigSource());
|
||||||
CONFIG_SOURCES.add(PersistedConfigSource.getInstance());
|
CONFIG_SOURCES.add(PersistedConfigSource.getInstance());
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.eclipse.microprofile.config.spi.ConfigSource;
|
import org.eclipse.microprofile.config.spi.ConfigSource;
|
||||||
|
@ -45,30 +46,30 @@ import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvi
|
||||||
import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider.NS_QUARKUS;
|
import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider.NS_QUARKUS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A configuration source for {@code keycloak.properties}.
|
* A configuration source for {@code keycloak.conf}.
|
||||||
*/
|
*/
|
||||||
public class KeycloakPropertiesConfigSource extends AbstractLocationConfigSourceLoader {
|
public class KeycloakPropertiesConfigSource extends AbstractLocationConfigSourceLoader {
|
||||||
|
|
||||||
private static final Pattern DOT_SPLIT = Pattern.compile("\\.");
|
private static final Pattern DOT_SPLIT = Pattern.compile("\\.");
|
||||||
private static final String KEYCLOAK_CONFIG_FILE_ENV = "KC_CONFIG_FILE";
|
private static final String KEYCLOAK_CONFIG_FILE_ENV = "KC_CONFIG_FILE";
|
||||||
private static final String KEYCLOAK_PROPERTIES = "keycloak.properties";
|
private static final String KEYCLOAK_CONF_FILE = "keycloak.conf";
|
||||||
public static final String KEYCLOAK_CONFIG_FILE_PROP = NS_KEYCLOAK_PREFIX + "config.file";
|
public static final String KEYCLOAK_CONFIG_FILE_PROP = NS_KEYCLOAK_PREFIX + "config.file";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String[] getFileExtensions() {
|
protected String[] getFileExtensions() {
|
||||||
return new String[] { "properties" };
|
return new String[] { "conf" };
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ConfigSource loadConfigSource(URL url, int ordinal) throws IOException {
|
protected ConfigSource loadConfigSource(URL url, int ordinal) throws IOException {
|
||||||
return new PropertiesConfigSource(transform(ConfigSourceUtil.urlToMap(url)), KEYCLOAK_PROPERTIES, ordinal);
|
return new PropertiesConfigSource(transform(ConfigSourceUtil.urlToMap(url)), KEYCLOAK_CONF_FILE, ordinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class InClassPath extends KeycloakPropertiesConfigSource implements ConfigSourceProvider {
|
public static class InClassPath extends KeycloakPropertiesConfigSource implements ConfigSourceProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ConfigSource> getConfigSources(final ClassLoader classLoader) {
|
public List<ConfigSource> getConfigSources(final ClassLoader classLoader) {
|
||||||
return loadConfigSources("META-INF/keycloak.properties", 150, classLoader);
|
return loadConfigSources("META-INF/" + KEYCLOAK_CONF_FILE, 150, classLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -122,7 +123,7 @@ public class KeycloakPropertiesConfigSource extends AbstractLocationConfigSource
|
||||||
String homeDir = Environment.getHomeDir();
|
String homeDir = Environment.getHomeDir();
|
||||||
|
|
||||||
if (homeDir != null) {
|
if (homeDir != null) {
|
||||||
File file = Paths.get(homeDir, "conf", KeycloakPropertiesConfigSource.KEYCLOAK_PROPERTIES).toFile();
|
File file = Paths.get(homeDir, "conf", KeycloakPropertiesConfigSource.KEYCLOAK_CONF_FILE).toFile();
|
||||||
|
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
filePath = file.getAbsolutePath();
|
filePath = file.getAbsolutePath();
|
||||||
|
|
|
@ -17,6 +17,9 @@
|
||||||
|
|
||||||
package org.keycloak.quarkus.runtime.configuration;
|
package org.keycloak.quarkus.runtime.configuration;
|
||||||
|
|
||||||
|
import static org.keycloak.quarkus.runtime.configuration.Configuration.OPTION_PART_SEPARATOR;
|
||||||
|
import static org.keycloak.quarkus.runtime.configuration.Configuration.toEnvVarFormat;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -60,7 +63,7 @@ public class MicroProfileConfigProvider implements Config.ConfigProvider {
|
||||||
|
|
||||||
public MicroProfileScope(String... scope) {
|
public MicroProfileScope(String... scope) {
|
||||||
this.scope = scope;
|
this.scope = scope;
|
||||||
this.prefix = String.join(".", ArrayUtils.insert(0, scope, NS_KEYCLOAK, "spi"));
|
this.prefix = NS_KEYCLOAK_PREFIX + String.join(OPTION_PART_SEPARATOR, ArrayUtils.insert(0, scope, "spi"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -119,14 +122,14 @@ public class MicroProfileConfigProvider implements Config.ConfigProvider {
|
||||||
.filter(new Predicate<String>() {
|
.filter(new Predicate<String>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean test(String key) {
|
public boolean test(String key) {
|
||||||
return key.startsWith(prefix) || key.startsWith(Picocli.normalizeKey(prefix));
|
return key.startsWith(prefix) || key.startsWith(toEnvVarFormat(prefix));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> T getValue(String key, Class<T> clazz, T defaultValue) {
|
private <T> T getValue(String key, Class<T> clazz, T defaultValue) {
|
||||||
return config.getOptionalValue(toDashCase(prefix.concat(".").concat(key)), clazz).orElse(defaultValue);
|
return config.getOptionalValue(toDashCase(prefix.concat(OPTION_PART_SEPARATOR).concat(key)), clazz).orElse(defaultValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ public final class PersistedConfigSource extends PropertiesConfigSource {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.getValue(propertyName.replace('-', '.'));
|
return super.getValue(propertyName.replace(Configuration.OPTION_PART_SEPARATOR_CHAR, '.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<String, String> readProperties() {
|
private static Map<String, String> readProperties() {
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
|
||||||
* and other contributors as indicated by the @author tags.
|
|
||||||
*
|
|
||||||
* Licensed 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.keycloak.quarkus.runtime.configuration;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
|
|
||||||
import org.eclipse.microprofile.config.spi.ConfigSource;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The only reason for this config source is to keep the Keycloak specific properties when configuring the server so that
|
|
||||||
* they are read again when running the server after the configuration.
|
|
||||||
*/
|
|
||||||
public class SysPropConfigSource implements ConfigSource {
|
|
||||||
|
|
||||||
private final Map<String, String> properties = new TreeMap<>();
|
|
||||||
|
|
||||||
public SysPropConfigSource() {
|
|
||||||
for (Map.Entry<Object, Object> entry : System.getProperties().entrySet()) {
|
|
||||||
String key = (String) entry.getKey();
|
|
||||||
if (key.startsWith(MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX)) {
|
|
||||||
properties.put(key, entry.getValue().toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, String> getProperties() {
|
|
||||||
return properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<String> getPropertyNames() {
|
|
||||||
return properties.keySet();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getValue(final String propertyName) {
|
|
||||||
return System.getProperty(propertyName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return "KcSysPropConfigSource";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getOrdinal() {
|
|
||||||
return 550;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -24,7 +24,7 @@ final class ClusteringPropertyMappers {
|
||||||
.expectedValues("local", "ispn")
|
.expectedValues("local", "ispn")
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("cache-stack")
|
builder().from("cache-stack")
|
||||||
.to("kc.spi.connections-infinispan.quarkus.stack")
|
.to("kc.spi-connections-infinispan-quarkus-stack")
|
||||||
.description("Define the default stack to use for cluster communication and node discovery. This option only takes effect "
|
.description("Define the default stack to use for cluster communication and node discovery. This option only takes effect "
|
||||||
+ "if 'cache' is set to 'ispn'.")
|
+ "if 'cache' is set to 'ispn'.")
|
||||||
.defaultValue("udp")
|
.defaultValue("udp")
|
||||||
|
@ -32,9 +32,9 @@ final class ClusteringPropertyMappers {
|
||||||
.isBuildTimeProperty(true)
|
.isBuildTimeProperty(true)
|
||||||
.expectedValues(Arrays.asList("tcp", "udp", "kubernetes", "ec2", "azure", "google"))
|
.expectedValues(Arrays.asList("tcp", "udp", "kubernetes", "ec2", "azure", "google"))
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("cache.config-file")
|
builder().from("cache-config-file")
|
||||||
.mapFrom("cache")
|
.mapFrom("cache")
|
||||||
.to("kc.spi.connections-infinispan.quarkus.config-file")
|
.to("kc.spi-connections-infinispan-quarkus-config-file")
|
||||||
.description("Defines the file from which cache configuration should be loaded from.")
|
.description("Defines the file from which cache configuration should be loaded from.")
|
||||||
.transformer(new BiFunction<String, ConfigSourceInterceptorContext, String>() {
|
.transformer(new BiFunction<String, ConfigSourceInterceptorContext, String>() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -23,7 +23,7 @@ final class DatabasePropertyMappers {
|
||||||
.transformer((db, context) -> Database.getDialect(db).orElse(Database.getDialect("h2-file").get()))
|
.transformer((db, context) -> Database.getDialect(db).orElse(Database.getDialect("h2-file").get()))
|
||||||
.hidden(true)
|
.hidden(true)
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("db.driver")
|
builder().from("db-driver")
|
||||||
.mapFrom("db")
|
.mapFrom("db")
|
||||||
.defaultValue(Database.getDriver("h2-file").get())
|
.defaultValue(Database.getDriver("h2-file").get())
|
||||||
.to("quarkus.datasource.jdbc.driver")
|
.to("quarkus.datasource.jdbc.driver")
|
||||||
|
@ -38,12 +38,12 @@ final class DatabasePropertyMappers {
|
||||||
.paramLabel("vendor")
|
.paramLabel("vendor")
|
||||||
.expectedValues(asList(Database.getAliases()))
|
.expectedValues(asList(Database.getAliases()))
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("db.tx-type")
|
builder().from("db-tx-type")
|
||||||
.defaultValue("xa")
|
.defaultValue("xa")
|
||||||
.to("quarkus.datasource.jdbc.transactions")
|
.to("quarkus.datasource.jdbc.transactions")
|
||||||
.hidden(true)
|
.hidden(true)
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("db.url")
|
builder().from("db-url")
|
||||||
.to("quarkus.datasource.jdbc.url")
|
.to("quarkus.datasource.jdbc.url")
|
||||||
.mapFrom("db")
|
.mapFrom("db")
|
||||||
.transformer((value, context) -> Database.getDefaultUrl(value).orElse(value))
|
.transformer((value, context) -> Database.getDefaultUrl(value).orElse(value))
|
||||||
|
@ -51,48 +51,48 @@ final class DatabasePropertyMappers {
|
||||||
"For instance, if using 'postgres', the default JDBC URL would be 'jdbc:postgresql://localhost/keycloak'. ")
|
"For instance, if using 'postgres', the default JDBC URL would be 'jdbc:postgresql://localhost/keycloak'. ")
|
||||||
.paramLabel("jdbc-url")
|
.paramLabel("jdbc-url")
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("db.url.host")
|
builder().from("db-url-host")
|
||||||
.to("kc.db.url.host")
|
.to("kc.db-url-host")
|
||||||
.description("Sets the hostname of the default JDBC URL of the chosen vendor. If the `db-url` option is set, this option is ignored.")
|
.description("Sets the hostname of the default JDBC URL of the chosen vendor. If the `db-url` option is set, this option is ignored.")
|
||||||
.paramLabel("hostname")
|
.paramLabel("hostname")
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("db.url.database")
|
builder().from("db-url-database")
|
||||||
.to("kc.db.url.database")
|
.to("kc.db-url-database")
|
||||||
.description("Sets the database name of the default JDBC URL of the chosen vendor. If the `db-url` option is set, this option is ignored.")
|
.description("Sets the database name of the default JDBC URL of the chosen vendor. If the `db-url` option is set, this option is ignored.")
|
||||||
.paramLabel("dbname")
|
.paramLabel("dbname")
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("db.url.properties")
|
builder().from("db-url-properties")
|
||||||
.to("kc.db.url.properties")
|
.to("kc.db-url-properties")
|
||||||
.description("Sets the properties of the default JDBC URL of the chosen vendor. If the `db-url` option is set, this option is ignored.")
|
.description("Sets the properties of the default JDBC URL of the chosen vendor. If the `db-url` option is set, this option is ignored.")
|
||||||
.paramLabel("properties")
|
.paramLabel("properties")
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("db.username")
|
builder().from("db-username")
|
||||||
.to("quarkus.datasource.username")
|
.to("quarkus.datasource.username")
|
||||||
.description("The username of the database user.")
|
.description("The username of the database user.")
|
||||||
.paramLabel("username")
|
.paramLabel("username")
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("db.password")
|
builder().from("db-password")
|
||||||
.to("quarkus.datasource.password")
|
.to("quarkus.datasource.password")
|
||||||
.description("The password of the database user.")
|
.description("The password of the database user.")
|
||||||
.paramLabel("password")
|
.paramLabel("password")
|
||||||
.isMasked(true)
|
.isMasked(true)
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("db.schema")
|
builder().from("db-schema")
|
||||||
.to("quarkus.hibernate-orm.database.default-schema")
|
.to("quarkus.hibernate-orm.database.default-schema")
|
||||||
.description("The database schema to be used.")
|
.description("The database schema to be used.")
|
||||||
.paramLabel("schema")
|
.paramLabel("schema")
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("db.pool.initial-size")
|
builder().from("db-pool-initial-size")
|
||||||
.to("quarkus.datasource.jdbc.initial-size")
|
.to("quarkus.datasource.jdbc.initial-size")
|
||||||
.description("The initial size of the connection pool.")
|
.description("The initial size of the connection pool.")
|
||||||
.paramLabel("size")
|
.paramLabel("size")
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("db.pool.min-size")
|
builder().from("db-pool-min-size")
|
||||||
.to("quarkus.datasource.jdbc.min-size")
|
.to("quarkus.datasource.jdbc.min-size")
|
||||||
.description("The minimal size of the connection pool.")
|
.description("The minimal size of the connection pool.")
|
||||||
.paramLabel("size")
|
.paramLabel("size")
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("db.pool.max-size")
|
builder().from("db-pool-max-size")
|
||||||
.to("quarkus.datasource.jdbc.max-size")
|
.to("quarkus.datasource.jdbc.max-size")
|
||||||
.defaultValue(String.valueOf(100))
|
.defaultValue(String.valueOf(100))
|
||||||
.description("The maximum size of the connection pool.")
|
.description("The maximum size of the connection pool.")
|
||||||
|
|
|
@ -8,35 +8,35 @@ final class HostnamePropertyMappers {
|
||||||
public static PropertyMapper[] getHostnamePropertyMappers() {
|
public static PropertyMapper[] getHostnamePropertyMappers() {
|
||||||
return new PropertyMapper[] {
|
return new PropertyMapper[] {
|
||||||
builder().from("hostname")
|
builder().from("hostname")
|
||||||
.to("kc.spi.hostname.default.hostname")
|
.to("kc.spi-hostname-default-hostname")
|
||||||
.description("Hostname for the Keycloak server.")
|
.description("Hostname for the Keycloak server.")
|
||||||
.paramLabel("hostname")
|
.paramLabel("hostname")
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("hostname.admin")
|
builder().from("hostname-admin")
|
||||||
.to("kc.spi.hostname.default.admin")
|
.to("kc.spi-hostname-default-admin")
|
||||||
.description("Overrides the hostname for the admin console and APIs.")
|
.description("Overrides the hostname for the admin console and APIs.")
|
||||||
.paramLabel("url")
|
.paramLabel("url")
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("hostname.strict")
|
builder().from("hostname-strict")
|
||||||
.to("kc.spi.hostname.default.strict")
|
.to("kc.spi-hostname-default-strict")
|
||||||
.description("Disables dynamically resolving the hostname from request headers. Should always be set to true in production, unless proxy verifies the Host header.")
|
.description("Disables dynamically resolving the hostname from request headers. Should always be set to true in production, unless proxy verifies the Host header.")
|
||||||
.type(Boolean.class)
|
.type(Boolean.class)
|
||||||
.defaultValue(Boolean.TRUE.toString())
|
.defaultValue(Boolean.TRUE.toString())
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("hostname.strict-https")
|
builder().from("hostname-strict-https")
|
||||||
.to("kc.spi.hostname.default.strict-https")
|
.to("kc.spi-hostname-default-strict-https")
|
||||||
.description("Forces URLs to use HTTPS. Only needed if proxy does not properly set the X-Forwarded-Proto header.")
|
.description("Forces URLs to use HTTPS. Only needed if proxy does not properly set the X-Forwarded-Proto header.")
|
||||||
.hidden(true)
|
.hidden(true)
|
||||||
.defaultValue(Boolean.TRUE.toString())
|
.defaultValue(Boolean.TRUE.toString())
|
||||||
.type(Boolean.class)
|
.type(Boolean.class)
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("hostname.strict-backchannel")
|
builder().from("hostname-strict-backchannel")
|
||||||
.to("kc.spi.hostname.default.strict-backchannel")
|
.to("kc.spi-hostname-default-strict-backchannel")
|
||||||
.description("By default backchannel URLs are dynamically resolved from request headers to allow internal an external applications. If all applications use the public URL this option should be enabled.")
|
.description("By default backchannel URLs are dynamically resolved from request headers to allow internal an external applications. If all applications use the public URL this option should be enabled.")
|
||||||
.type(Boolean.class)
|
.type(Boolean.class)
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("hostname.path")
|
builder().from("hostname-path")
|
||||||
.to("kc.spi.hostname.default.path")
|
.to("kc.spi-hostname-default-path")
|
||||||
.description("This should be set if proxy uses a different context-path for Keycloak.")
|
.description("This should be set if proxy uses a different context-path for Keycloak.")
|
||||||
.paramLabel("path")
|
.paramLabel("path")
|
||||||
.build()
|
.build()
|
||||||
|
|
|
@ -19,7 +19,7 @@ final class HttpPropertyMappers {
|
||||||
|
|
||||||
public static PropertyMapper[] getHttpPropertyMappers() {
|
public static PropertyMapper[] getHttpPropertyMappers() {
|
||||||
return new PropertyMapper[] {
|
return new PropertyMapper[] {
|
||||||
builder().from("http.enabled")
|
builder().from("http-enabled")
|
||||||
.to("quarkus.http.insecure-requests")
|
.to("quarkus.http.insecure-requests")
|
||||||
.defaultValue(Boolean.FALSE.toString())
|
.defaultValue(Boolean.FALSE.toString())
|
||||||
.transformer(HttpPropertyMappers::getHttpEnabledTransformer)
|
.transformer(HttpPropertyMappers::getHttpEnabledTransformer)
|
||||||
|
@ -27,90 +27,90 @@ final class HttpPropertyMappers {
|
||||||
.paramLabel(Boolean.TRUE + "|" + Boolean.FALSE)
|
.paramLabel(Boolean.TRUE + "|" + Boolean.FALSE)
|
||||||
.expectedValues(Arrays.asList(Boolean.TRUE.toString(), Boolean.FALSE.toString()))
|
.expectedValues(Arrays.asList(Boolean.TRUE.toString(), Boolean.FALSE.toString()))
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("http.host")
|
builder().from("http-host")
|
||||||
.to("quarkus.http.host")
|
.to("quarkus.http.host")
|
||||||
.defaultValue("0.0.0.0")
|
.defaultValue("0.0.0.0")
|
||||||
.description("The used HTTP Host.")
|
.description("The used HTTP Host.")
|
||||||
.paramLabel("host")
|
.paramLabel("host")
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("http.relative-path")
|
builder().from("http-relative-path")
|
||||||
.to("quarkus.http.root-path")
|
.to("quarkus.http.root-path")
|
||||||
.defaultValue("/")
|
.defaultValue("/")
|
||||||
.description("Set the path relative to '/' for serving resources.")
|
.description("Set the path relative to '/' for serving resources.")
|
||||||
.paramLabel("path")
|
.paramLabel("path")
|
||||||
.isBuildTimeProperty(true)
|
.isBuildTimeProperty(true)
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("http.port")
|
builder().from("http-port")
|
||||||
.to("quarkus.http.port")
|
.to("quarkus.http.port")
|
||||||
.defaultValue(String.valueOf(8080))
|
.defaultValue(String.valueOf(8080))
|
||||||
.description("The used HTTP port.")
|
.description("The used HTTP port.")
|
||||||
.paramLabel("port")
|
.paramLabel("port")
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("https.port")
|
builder().from("https-port")
|
||||||
.to("quarkus.http.ssl-port")
|
.to("quarkus.http.ssl-port")
|
||||||
.defaultValue(String.valueOf(8443))
|
.defaultValue(String.valueOf(8443))
|
||||||
.description("The used HTTPS port.")
|
.description("The used HTTPS port.")
|
||||||
.paramLabel("port")
|
.paramLabel("port")
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("https.client-auth")
|
builder().from("https-client-auth")
|
||||||
.to("quarkus.http.ssl.client-auth")
|
.to("quarkus.http.ssl.client-auth")
|
||||||
.defaultValue("none")
|
.defaultValue("none")
|
||||||
.description("Configures the server to require/request client authentication. Possible Values: none, request, required.")
|
.description("Configures the server to require/request client authentication. Possible Values: none, request, required.")
|
||||||
.paramLabel("auth")
|
.paramLabel("auth")
|
||||||
.expectedValues(Arrays.asList("none", "request", "required"))
|
.expectedValues(Arrays.asList("none", "request", "required"))
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("https.cipher-suites")
|
builder().from("https-cipher-suites")
|
||||||
.to("quarkus.http.ssl.cipher-suites")
|
.to("quarkus.http.ssl.cipher-suites")
|
||||||
.description("The cipher suites to use. If none is given, a reasonable default is selected.")
|
.description("The cipher suites to use. If none is given, a reasonable default is selected.")
|
||||||
.paramLabel("ciphers")
|
.paramLabel("ciphers")
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("https.protocols")
|
builder().from("https-protocols")
|
||||||
.to("quarkus.http.ssl.protocols")
|
.to("quarkus.http.ssl.protocols")
|
||||||
.description("The list of protocols to explicitly enable.")
|
.description("The list of protocols to explicitly enable.")
|
||||||
.paramLabel("protocols")
|
.paramLabel("protocols")
|
||||||
.defaultValue("TLSv1.3")
|
.defaultValue("TLSv1.3")
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("https.certificate.file")
|
builder().from("https-certificate-file")
|
||||||
.to("quarkus.http.ssl.certificate.file")
|
.to("quarkus.http.ssl.certificate.file")
|
||||||
.description("The file path to a server certificate or certificate chain in PEM format.")
|
.description("The file path to a server certificate or certificate chain in PEM format.")
|
||||||
.paramLabel("file")
|
.paramLabel("file")
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("https.certificate.key-file")
|
builder().from("https-certificate-key-file")
|
||||||
.to("quarkus.http.ssl.certificate.key-file")
|
.to("quarkus.http.ssl.certificate.key-file")
|
||||||
.description("The file path to a private key in PEM format.")
|
.description("The file path to a private key in PEM format.")
|
||||||
.paramLabel("file")
|
.paramLabel("file")
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("https.key-store.file")
|
builder().from("https-key-store-file")
|
||||||
.to("quarkus.http.ssl.certificate.key-store-file")
|
.to("quarkus.http.ssl.certificate.key-store-file")
|
||||||
.defaultValue(getDefaultKeystorePathValue())
|
.defaultValue(getDefaultKeystorePathValue())
|
||||||
.description("The key store which holds the certificate information instead of specifying separate files.")
|
.description("The key store which holds the certificate information instead of specifying separate files.")
|
||||||
.paramLabel("file")
|
.paramLabel("file")
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("https.key-store.password")
|
builder().from("https-key-store-password")
|
||||||
.to("quarkus.http.ssl.certificate.key-store-password")
|
.to("quarkus.http.ssl.certificate.key-store-password")
|
||||||
.description("The password of the key store file.")
|
.description("The password of the key store file.")
|
||||||
.defaultValue("password")
|
.defaultValue("password")
|
||||||
.paramLabel("password")
|
.paramLabel("password")
|
||||||
.isMasked(true)
|
.isMasked(true)
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("https.key-store.type")
|
builder().from("https-key-store-type")
|
||||||
.to("quarkus.http.ssl.certificate.key-store-file-type")
|
.to("quarkus.http.ssl.certificate.key-store-file-type")
|
||||||
.description("The type of the key store file. " +
|
.description("The type of the key store file. " +
|
||||||
"If not given, the type is automatically detected based on the file name.")
|
"If not given, the type is automatically detected based on the file name.")
|
||||||
.paramLabel("type")
|
.paramLabel("type")
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("https.trust-store.file")
|
builder().from("https-trust-store-file")
|
||||||
.to("quarkus.http.ssl.certificate.trust-store-file")
|
.to("quarkus.http.ssl.certificate.trust-store-file")
|
||||||
.description("The trust store which holds the certificate information of the certificates to trust.")
|
.description("The trust store which holds the certificate information of the certificates to trust.")
|
||||||
.paramLabel("file")
|
.paramLabel("file")
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("https.trust-store.password")
|
builder().from("https-trust-store-password")
|
||||||
.to("quarkus.http.ssl.certificate.trust-store-password")
|
.to("quarkus.http.ssl.certificate.trust-store-password")
|
||||||
.description("The password of the trust store file.")
|
.description("The password of the trust store file.")
|
||||||
.paramLabel("password")
|
.paramLabel("password")
|
||||||
.isMasked(true)
|
.isMasked(true)
|
||||||
.build(),
|
.build(),
|
||||||
builder().from("https.trust-store.type")
|
builder().from("https-trust-store-type")
|
||||||
.to("quarkus.http.ssl.certificate.trust-store-file-type")
|
.to("quarkus.http.ssl.certificate.trust-store-file-type")
|
||||||
.defaultValue(getDefaultKeystorePathValue())
|
.defaultValue(getDefaultKeystorePathValue())
|
||||||
.description("The type of the trust store file. " +
|
.description("The type of the trust store file. " +
|
||||||
|
@ -131,7 +131,7 @@ final class HttpPropertyMappers {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
ConfigValue proceed = context.proceed("kc.https.certificate.file");
|
ConfigValue proceed = context.proceed("kc.https-certificate-file");
|
||||||
|
|
||||||
if (proceed == null || proceed.getValue() == null) {
|
if (proceed == null || proceed.getValue() == null) {
|
||||||
proceed = getMapper("quarkus.http.ssl.certificate.key-store-file").getConfigValue(context);
|
proceed = getMapper("quarkus.http.ssl.certificate.key-store-file").getConfigValue(context);
|
||||||
|
|
|
@ -9,7 +9,7 @@ final class MetricsPropertyMappers {
|
||||||
|
|
||||||
public static PropertyMapper[] getMetricsPropertyMappers() {
|
public static PropertyMapper[] getMetricsPropertyMappers() {
|
||||||
return new PropertyMapper[] {
|
return new PropertyMapper[] {
|
||||||
builder().from("metrics.enabled")
|
builder().from("metrics-enabled")
|
||||||
.to("quarkus.datasource.metrics.enabled")
|
.to("quarkus.datasource.metrics.enabled")
|
||||||
.isBuildTimeProperty(true)
|
.isBuildTimeProperty(true)
|
||||||
.defaultValue(Boolean.FALSE.toString())
|
.defaultValue(Boolean.FALSE.toString())
|
||||||
|
|
|
@ -16,13 +16,18 @@
|
||||||
*/
|
*/
|
||||||
package org.keycloak.quarkus.runtime.configuration.mappers;
|
package org.keycloak.quarkus.runtime.configuration.mappers;
|
||||||
|
|
||||||
|
import static org.keycloak.quarkus.runtime.configuration.Configuration.OPTION_PART_SEPARATOR;
|
||||||
|
import static org.keycloak.quarkus.runtime.configuration.Configuration.OPTION_PART_SEPARATOR_CHAR;
|
||||||
|
import static org.keycloak.quarkus.runtime.configuration.Configuration.toCliFormat;
|
||||||
|
import static org.keycloak.quarkus.runtime.configuration.Configuration.toEnvVarFormat;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
import io.smallrye.config.ConfigSourceInterceptorContext;
|
import io.smallrye.config.ConfigSourceInterceptorContext;
|
||||||
import io.smallrye.config.ConfigValue;
|
import io.smallrye.config.ConfigValue;
|
||||||
import org.keycloak.quarkus.runtime.cli.Picocli;
|
|
||||||
import org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider;
|
import org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider;
|
||||||
|
|
||||||
public class PropertyMapper {
|
public class PropertyMapper {
|
||||||
|
@ -47,9 +52,9 @@ public class PropertyMapper {
|
||||||
private final ConfigCategory category;
|
private final ConfigCategory category;
|
||||||
private final String paramLabel;
|
private final String paramLabel;
|
||||||
private final boolean hidden;
|
private final boolean hidden;
|
||||||
|
private final String envVarFormat;
|
||||||
private String cliFormat;
|
private String cliFormat;
|
||||||
|
|
||||||
|
|
||||||
PropertyMapper(String from, String to, String defaultValue, BiFunction<String, ConfigSourceInterceptorContext, String> mapper,
|
PropertyMapper(String from, String to, String defaultValue, BiFunction<String, ConfigSourceInterceptorContext, String> mapper,
|
||||||
String mapFrom, boolean buildTime, String description, String paramLabel, boolean mask, Iterable<String> expectedValues,
|
String mapFrom, boolean buildTime, String description, String paramLabel, boolean mask, Iterable<String> expectedValues,
|
||||||
ConfigCategory category, boolean hidden) {
|
ConfigCategory category, boolean hidden) {
|
||||||
|
@ -65,7 +70,8 @@ public class PropertyMapper {
|
||||||
this.expectedValues = expectedValues == null ? Collections.emptyList() : expectedValues;
|
this.expectedValues = expectedValues == null ? Collections.emptyList() : expectedValues;
|
||||||
this.category = category != null ? category : ConfigCategory.GENERAL;
|
this.category = category != null ? category : ConfigCategory.GENERAL;
|
||||||
this.hidden = hidden;
|
this.hidden = hidden;
|
||||||
setCliFormat(this.from);
|
this.cliFormat = toCliFormat(from);
|
||||||
|
this.envVarFormat = toEnvVarFormat(this.from);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PropertyMapper.Builder builder(String fromProp, String toProp) {
|
public static PropertyMapper.Builder builder(String fromProp, String toProp) {
|
||||||
|
@ -87,9 +93,9 @@ public class PropertyMapper {
|
||||||
ConfigValue getConfigValue(String name, ConfigSourceInterceptorContext context) {
|
ConfigValue getConfigValue(String name, ConfigSourceInterceptorContext context) {
|
||||||
String from = this.from;
|
String from = this.from;
|
||||||
|
|
||||||
if (to != null && to.endsWith(".")) {
|
if (to != null && to.endsWith(OPTION_PART_SEPARATOR)) {
|
||||||
// in case mapping is based on prefixes instead of full property names
|
// in case mapping is based on prefixes instead of full property names
|
||||||
from = name.replace(to.substring(0, to.lastIndexOf('.')), from.substring(0, from.lastIndexOf('.')));
|
from = name.replace(to.substring(0, to.lastIndexOf('.')), from.substring(0, from.lastIndexOf(OPTION_PART_SEPARATOR_CHAR)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to obtain the value for the property we want to map first
|
// try to obtain the value for the property we want to map first
|
||||||
|
@ -98,7 +104,7 @@ public class PropertyMapper {
|
||||||
if (config == null) {
|
if (config == null) {
|
||||||
if (mapFrom != null) {
|
if (mapFrom != null) {
|
||||||
// if the property we want to map depends on another one, we use the value from the other property to call the mapper
|
// if the property we want to map depends on another one, we use the value from the other property to call the mapper
|
||||||
String parentKey = MicroProfileConfigProvider.NS_KEYCLOAK + "." + mapFrom;
|
String parentKey = MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX + mapFrom;
|
||||||
ConfigValue parentValue = context.proceed(parentKey);
|
ConfigValue parentValue = context.proceed(parentKey);
|
||||||
|
|
||||||
if (parentValue == null) {
|
if (parentValue == null) {
|
||||||
|
@ -187,6 +193,10 @@ public class PropertyMapper {
|
||||||
return cliFormat;
|
return cliFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getEnvVarFormat() {
|
||||||
|
return envVarFormat;
|
||||||
|
}
|
||||||
|
|
||||||
boolean isMask() {
|
boolean isMask() {
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
@ -209,10 +219,6 @@ public class PropertyMapper {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setCliFormat(String from) {
|
|
||||||
cliFormat = Picocli.ARG_PREFIX + PropertyMappers.toCLIFormat(from).substring(3);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
|
||||||
private String from;
|
private String from;
|
||||||
|
|
|
@ -82,7 +82,7 @@ public final class PropertyMappers {
|
||||||
&& !Environment.PROFILE.equals(name)
|
&& !Environment.PROFILE.equals(name)
|
||||||
&& !"kc.show.config".equals(name)
|
&& !"kc.show.config".equals(name)
|
||||||
&& !"kc.show.config.runtime".equals(name)
|
&& !"kc.show.config.runtime".equals(name)
|
||||||
&& !toCLIFormat("kc.config.file").equals(name);
|
&& !"kc.config-file".equals(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isSpiBuildTimeProperty(String name) {
|
private static boolean isSpiBuildTimeProperty(String name) {
|
||||||
|
@ -93,16 +93,6 @@ public final class PropertyMappers {
|
||||||
return name.startsWith("kc.features");
|
return name.startsWith("kc.features");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String toCLIFormat(String name) {
|
|
||||||
if (name.indexOf('.') == -1) {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX
|
|
||||||
.concat(name.substring(3, name.lastIndexOf('.') + 1)
|
|
||||||
.replaceAll("\\.", "-") + name.substring(name.lastIndexOf('.') + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<PropertyMapper> getRuntimeMappers() {
|
public static List<PropertyMapper> getRuntimeMappers() {
|
||||||
return MAPPERS.values().stream()
|
return MAPPERS.values().stream()
|
||||||
.filter(entry -> !entry.isBuildTime()).collect(Collectors.toList());
|
.filter(entry -> !entry.isBuildTime()).collect(Collectors.toList());
|
||||||
|
@ -113,10 +103,6 @@ public final class PropertyMappers {
|
||||||
.filter(PropertyMapper::isBuildTime).collect(Collectors.toList());
|
.filter(PropertyMapper::isBuildTime).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String canonicalFormat(String name) {
|
|
||||||
return name.replaceAll("-", "\\.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String formatValue(String property, String value) {
|
public static String formatValue(String property, String value) {
|
||||||
property = removeProfilePrefixIfNeeded(property);
|
property = removeProfilePrefixIfNeeded(property);
|
||||||
PropertyMapper mapper = getMapper(property);
|
PropertyMapper mapper = getMapper(property);
|
||||||
|
@ -170,6 +156,7 @@ public final class PropertyMappers {
|
||||||
super.put(mapper.getTo(), mapper);
|
super.put(mapper.getTo(), mapper);
|
||||||
super.put(mapper.getFrom(), mapper);
|
super.put(mapper.getFrom(), mapper);
|
||||||
super.put(mapper.getCliFormat(), mapper);
|
super.put(mapper.getCliFormat(), mapper);
|
||||||
|
super.put(mapper.getEnvVarFormat(), mapper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,19 +8,19 @@ final class VaultPropertyMappers {
|
||||||
public static PropertyMapper[] getVaultPropertyMappers() {
|
public static PropertyMapper[] getVaultPropertyMappers() {
|
||||||
return new PropertyMapper[] {
|
return new PropertyMapper[] {
|
||||||
builder()
|
builder()
|
||||||
.from("vault.file.path")
|
.from("vault-file-path")
|
||||||
.to("kc.spi.vault.files-plaintext.dir")
|
.to("kc.spi-vault-files-plaintext-dir")
|
||||||
.description("If set, secrets can be obtained by reading the content of files within the given path.")
|
.description("If set, secrets can be obtained by reading the content of files within the given path.")
|
||||||
.paramLabel("dir")
|
.paramLabel("dir")
|
||||||
.build(),
|
.build(),
|
||||||
builder()
|
builder()
|
||||||
.from("vault.hashicorp.")
|
.from("vault-hashicorp-")
|
||||||
.to("quarkus.vault.")
|
.to("quarkus.vault.")
|
||||||
.description("If set, secrets can be obtained from Hashicorp Vault.")
|
.description("If set, secrets can be obtained from Hashicorp Vault.")
|
||||||
.build(),
|
.build(),
|
||||||
builder()
|
builder()
|
||||||
.from("vault.hashicorp.paths")
|
.from("vault-hashicorp-paths")
|
||||||
.to("kc.spi.vault.hashicorp.paths")
|
.to("kc.spi-vault-hashicorp-paths")
|
||||||
.description("A set of one or more paths that should be used when looking up secrets.")
|
.description("A set of one or more paths that should be used when looking up secrets.")
|
||||||
.paramLabel("paths")
|
.paramLabel("paths")
|
||||||
.build()
|
.build()
|
||||||
|
|
|
@ -210,7 +210,7 @@ public final class DefaultHostnameProvider implements HostnameProvider, Hostname
|
||||||
|
|
||||||
defaultPath = config.get("path");
|
defaultPath = config.get("path");
|
||||||
noProxy = Configuration.getConfigValue("kc.proxy").getValue().equals("none");
|
noProxy = Configuration.getConfigValue("kc.proxy").getValue().equals("none");
|
||||||
defaultTlsPort = Integer.parseInt(Configuration.getConfigValue("kc.https.port").getValue());
|
defaultTlsPort = Integer.parseInt(Configuration.getConfigValue("kc.https-port").getValue());
|
||||||
adminHostName = config.get("admin");
|
adminHostName = config.get("admin");
|
||||||
strictBackChannel = config.getBoolean("strict-backchannel", false);
|
strictBackChannel = config.getBoolean("strict-backchannel", false);
|
||||||
|
|
||||||
|
|
|
@ -100,11 +100,11 @@ public final class Database {
|
||||||
@Override
|
@Override
|
||||||
public String apply(String alias) {
|
public String apply(String alias) {
|
||||||
if ("h2-file".equalsIgnoreCase(alias)) {
|
if ("h2-file".equalsIgnoreCase(alias)) {
|
||||||
return "jdbc:h2:file:${kc.home.dir:${kc.db.url.path:~}}" + File.separator + "${kc.data.dir:data}"
|
return "jdbc:h2:file:${kc.home.dir:${kc.db-url-path:~}}" + File.separator + "${kc.data.dir:data}"
|
||||||
+ File.separator + "h2" + File.separator
|
+ File.separator + "h2" + File.separator
|
||||||
+ "keycloakdb${kc.db.url.properties:;;AUTO_SERVER=TRUE}";
|
+ "keycloakdb${kc.db-url-properties:;;AUTO_SERVER=TRUE}";
|
||||||
}
|
}
|
||||||
return "jdbc:h2:mem:keycloakdb${kc.db.url.properties:}";
|
return "jdbc:h2:mem:keycloakdb${kc.db-url-properties:}";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
asList("liquibase.database.core.H2Database"),
|
asList("liquibase.database.core.H2Database"),
|
||||||
|
@ -114,13 +114,13 @@ public final class Database {
|
||||||
"com.mysql.cj.jdbc.MysqlXADataSource",
|
"com.mysql.cj.jdbc.MysqlXADataSource",
|
||||||
"org.hibernate.dialect.MySQL8Dialect",
|
"org.hibernate.dialect.MySQL8Dialect",
|
||||||
|
|
||||||
"jdbc:mysql://${kc.db.url.host:localhost}/${kc.db.url.database:keycloak}${kc.db.url.properties:}",
|
"jdbc:mysql://${kc.db-url-host:localhost}/${kc.db-url-database:keycloak}${kc.db-url-properties:}",
|
||||||
asList("org.keycloak.connections.jpa.updater.liquibase.UpdatedMySqlDatabase")
|
asList("org.keycloak.connections.jpa.updater.liquibase.UpdatedMySqlDatabase")
|
||||||
),
|
),
|
||||||
MARIADB("mariadb",
|
MARIADB("mariadb",
|
||||||
"org.mariadb.jdbc.MySQLDataSource",
|
"org.mariadb.jdbc.MySQLDataSource",
|
||||||
"org.hibernate.dialect.MariaDBDialect",
|
"org.hibernate.dialect.MariaDBDialect",
|
||||||
"jdbc:mariadb://${kc.db.url.host:localhost}/${kc.db.url.database:keycloak}${kc.db.url.properties:}",
|
"jdbc:mariadb://${kc.db-url-host:localhost}/${kc.db-url-database:keycloak}${kc.db-url-properties:}",
|
||||||
asList("org.keycloak.connections.jpa.updater.liquibase.UpdatedMariaDBDatabase")
|
asList("org.keycloak.connections.jpa.updater.liquibase.UpdatedMariaDBDatabase")
|
||||||
),
|
),
|
||||||
POSTGRES("postgresql",
|
POSTGRES("postgresql",
|
||||||
|
@ -134,7 +134,7 @@ public final class Database {
|
||||||
return "io.quarkus.hibernate.orm.runtime.dialect.QuarkusPostgreSQL10Dialect";
|
return "io.quarkus.hibernate.orm.runtime.dialect.QuarkusPostgreSQL10Dialect";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jdbc:postgresql://${kc.db.url.host:localhost}/${kc.db.url.database:keycloak}${kc.db.url.properties:}",
|
"jdbc:postgresql://${kc.db-url-host:localhost}/${kc.db-url-database:keycloak}${kc.db-url-properties:}",
|
||||||
asList("liquibase.database.core.PostgresDatabase",
|
asList("liquibase.database.core.PostgresDatabase",
|
||||||
"org.keycloak.connections.jpa.updater.liquibase.PostgresPlusDatabase"),
|
"org.keycloak.connections.jpa.updater.liquibase.PostgresPlusDatabase"),
|
||||||
"postgres", "postgres-95"
|
"postgres", "postgres-95"
|
||||||
|
@ -151,14 +151,14 @@ public final class Database {
|
||||||
return "org.hibernate.dialect.SQLServer2016Dialect";
|
return "org.hibernate.dialect.SQLServer2016Dialect";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jdbc:sqlserver://${kc.db.url.host:localhost}:1433;databaseName=${kc.db.url.database:keycloak}${kc.db.url.properties:}",
|
"jdbc:sqlserver://${kc.db-url-host:localhost}:1433;databaseName=${kc.db-url-database:keycloak}${kc.db-url-properties:}",
|
||||||
asList("org.keycloak.quarkus.runtime.storage.database.liquibase.database.CustomMSSQLDatabase"),
|
asList("org.keycloak.quarkus.runtime.storage.database.liquibase.database.CustomMSSQLDatabase"),
|
||||||
"mssql", "mssql-2012"
|
"mssql", "mssql-2012"
|
||||||
),
|
),
|
||||||
ORACLE("oracle",
|
ORACLE("oracle",
|
||||||
"oracle.jdbc.xa.client.OracleXADataSource",
|
"oracle.jdbc.xa.client.OracleXADataSource",
|
||||||
"org.hibernate.dialect.Oracle12cDialect",
|
"org.hibernate.dialect.Oracle12cDialect",
|
||||||
"jdbc:oracle:thin:@//${kc.db.url.host:localhost}:1521/${kc.db.url.database:keycloak}",
|
"jdbc:oracle:thin:@//${kc.db-url-host:localhost}:1521/${kc.db-url-database:keycloak}",
|
||||||
asList("liquibase.database.core.OracleDatabase")
|
asList("liquibase.database.core.OracleDatabase")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -176,7 +176,7 @@ public final class QuarkusJpaConnectionProviderFactory implements JpaConnectionP
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSchema() {
|
public String getSchema() {
|
||||||
return Configuration.getRawValue("kc.db.schema");
|
return Configuration.getRawValue("kc.db-schema");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -74,11 +74,11 @@ public class CacheManagerFactory {
|
||||||
|
|
||||||
private boolean isStartEagerly() {
|
private boolean isStartEagerly() {
|
||||||
// eagerly starts caches by default
|
// eagerly starts caches by default
|
||||||
return Boolean.parseBoolean(System.getProperty("kc.cache.ispn.start-eagerly", Boolean.TRUE.toString()));
|
return Boolean.parseBoolean(System.getProperty("kc.cache-ispn-start-eagerly", Boolean.TRUE.toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Integer getStartTimeout() {
|
private Integer getStartTimeout() {
|
||||||
return Integer.getInteger("kc.cache.ispn.start-timeout", 120);
|
return Integer.getInteger("kc.cache-ispn-start-timeout", 120);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void shutdownThreadPool() {
|
private void shutdownThreadPool() {
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
# Default and non-production grade database vendor
|
# Default and non-production grade database vendor
|
||||||
db=h2-file
|
db=h2-file
|
||||||
db.username = sa
|
db-username = sa
|
||||||
db.password = keycloak
|
db-password = keycloak
|
||||||
|
|
||||||
# Insecure requests are disabled by default
|
# Insecure requests are disabled by default
|
||||||
http.enabled=false
|
http-enabled=false
|
||||||
|
|
||||||
# Metrics and healthcheck are disabled by default
|
# Metrics and healthcheck are disabled by default
|
||||||
metrics.enabled=false
|
metrics-enabled=false
|
||||||
|
|
||||||
# Default, and insecure, and non-production grade configuration for the development profile
|
# Default, and insecure, and non-production grade configuration for the development profile
|
||||||
%dev.http.enabled=true
|
%dev.http-enabled=true
|
||||||
%dev.hostname.strict=false
|
%dev.hostname-strict=false
|
||||||
%dev.hostname.strict-https=false
|
%dev.hostname-strict-https=false
|
||||||
%dev.cache=local
|
%dev.cache=local
|
||||||
%dev.spi.theme.cache-themes=false
|
%dev.spi-theme-cache-themes=false
|
||||||
%dev.spi.theme.cache-templates=false
|
%dev.spi-theme-cache-templates=false
|
||||||
%dev.spi.theme.static-max-age=-1
|
%dev.spi-theme-static-max-age=-1
|
||||||
|
|
||||||
# The default configuration when running in import or export mode
|
# The default configuration when running in import or export mode
|
||||||
%import_export.http.enabled=true
|
%import_export.http-enabled=true
|
||||||
%import_export.hostname.strict=false
|
%import_export.hostname-strict=false
|
||||||
%import_export.hostname.strict-https=false
|
%import_export.hostname-strict-https=false
|
||||||
%import_export.cluster=local
|
%import_export.cluster=local
|
||||||
|
|
||||||
# Logging configuration. INFO is the default level for most of the categories
|
# Logging configuration. INFO is the default level for most of the categories
|
|
@ -128,14 +128,14 @@ public class ConfigurationTest {
|
||||||
Config.Scope config = initConfig("vault", FilesPlainTextVaultProviderFactory.PROVIDER_ID);
|
Config.Scope config = initConfig("vault", FilesPlainTextVaultProviderFactory.PROVIDER_ID);
|
||||||
assertEquals("/foo/bar", config.get("dir"));
|
assertEquals("/foo/bar", config.get("dir"));
|
||||||
assertTrue(config.getPropertyNames()
|
assertTrue(config.getPropertyNames()
|
||||||
.contains("kc.spi.vault.".concat(FilesPlainTextVaultProviderFactory.PROVIDER_ID).concat(".dir")));
|
.contains("kc.spi-vault-".concat(FilesPlainTextVaultProviderFactory.PROVIDER_ID).concat("-dir")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSysPropPriorityOverEnvVar() {
|
public void testEnvVarPriorityOverSysProps() {
|
||||||
putEnvVar("KC_SPI_HOSTNAME_DEFAULT_FRONTEND_URL", "http://envvar.unittest");
|
putEnvVar("KC_SPI_HOSTNAME_DEFAULT_FRONTEND_URL", "http://envvar.unittest");
|
||||||
System.setProperty("kc.spi.hostname.default.frontend-url", "http://propvar.unittest");
|
System.setProperty("kc.spi-hostname-default-frontend-url", "http://propvar.unittest");
|
||||||
assertEquals("http://propvar.unittest", initConfig("hostname", "default").get("frontendUrl"));
|
assertEquals("http://envvar.unittest", initConfig("hostname", "default").get("frontendUrl"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -203,13 +203,13 @@ public class ConfigurationTest {
|
||||||
assertEquals("secrets", config.get("dir"));
|
assertEquals("secrets", config.get("dir"));
|
||||||
|
|
||||||
System.getProperties().remove(CLI_ARGS);
|
System.getProperties().remove(CLI_ARGS);
|
||||||
System.setProperty("kc.spi.client-registration.openid-connect.static-jwk-url", "http://c.jwk.url");
|
System.setProperty("kc.spi-client-registration-openid-connect-static-jwk-url", "http://c.jwk.url");
|
||||||
config = initConfig("client-registration", "openid-connect");
|
config = initConfig("client-registration", "openid-connect");
|
||||||
assertEquals(1, config.getPropertyNames().size());
|
assertEquals(1, config.getPropertyNames().size());
|
||||||
assertEquals("http://c.jwk.url", config.get("static-jwk-url"));
|
assertEquals("http://c.jwk.url", config.get("static-jwk-url"));
|
||||||
|
|
||||||
System.getProperties().remove(CLI_ARGS);
|
System.getProperties().remove(CLI_ARGS);
|
||||||
System.getProperties().remove("kc.spi.client-registration.openid-connect.static-jwk-url");
|
System.getProperties().remove("kc.spi-client-registration-openid-connect-static-jwk-url");
|
||||||
putEnvVar("KC_SPI_CLIENT_REGISTRATION_OPENID_CONNECT_STATIC_JWK_URL", "http://c.jwk.url/from-env");
|
putEnvVar("KC_SPI_CLIENT_REGISTRATION_OPENID_CONNECT_STATIC_JWK_URL", "http://c.jwk.url/from-env");
|
||||||
config = initConfig("client-registration", "openid-connect");
|
config = initConfig("client-registration", "openid-connect");
|
||||||
assertEquals(1, config.getPropertyNames().size());
|
assertEquals(1, config.getPropertyNames().size());
|
||||||
|
@ -279,8 +279,8 @@ public class ConfigurationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDatabaseProperties() {
|
public void testDatabaseProperties() {
|
||||||
System.setProperty("kc.db.url.properties", ";;test=test;test1=test1");
|
System.setProperty("kc.db-url-properties", ";;test=test;test1=test1");
|
||||||
System.setProperty("kc.db.url.path", "test-dir");
|
System.setProperty("kc.db-url-path", "test-dir");
|
||||||
System.setProperty(CLI_ARGS, "--db=h2-file");
|
System.setProperty(CLI_ARGS, "--db=h2-file");
|
||||||
SmallRyeConfig config = createConfig();
|
SmallRyeConfig config = createConfig();
|
||||||
assertEquals(QuarkusH2Dialect.class.getName(), config.getConfigValue("quarkus.hibernate-orm.dialect").getValue());
|
assertEquals(QuarkusH2Dialect.class.getName(), config.getConfigValue("quarkus.hibernate-orm.dialect").getValue());
|
||||||
|
@ -292,7 +292,7 @@ public class ConfigurationTest {
|
||||||
assertEquals(QuarkusH2Dialect.class.getName(), config.getConfigValue("quarkus.hibernate-orm.dialect").getValue());
|
assertEquals(QuarkusH2Dialect.class.getName(), config.getConfigValue("quarkus.hibernate-orm.dialect").getValue());
|
||||||
assertEquals("jdbc:h2:file:test-dir" + File.separator + "data" + File.separator + "h2" + File.separator + "keycloakdb;;test=test;test1=test1", config.getConfigValue("quarkus.datasource.jdbc.url").getValue());
|
assertEquals("jdbc:h2:file:test-dir" + File.separator + "data" + File.separator + "h2" + File.separator + "keycloakdb;;test=test;test1=test1", config.getConfigValue("quarkus.datasource.jdbc.url").getValue());
|
||||||
|
|
||||||
System.setProperty("kc.db.url.properties", "?test=test&test1=test1");
|
System.setProperty("kc.db-url-properties", "?test=test&test1=test1");
|
||||||
System.setProperty(CLI_ARGS, "--db=mariadb");
|
System.setProperty(CLI_ARGS, "--db=mariadb");
|
||||||
config = createConfig();
|
config = createConfig();
|
||||||
assertEquals("jdbc:mariadb://localhost/keycloak?test=test&test1=test1", config.getConfigValue("quarkus.datasource.jdbc.url").getValue());
|
assertEquals("jdbc:mariadb://localhost/keycloak?test=test&test1=test1", config.getConfigValue("quarkus.datasource.jdbc.url").getValue());
|
||||||
|
@ -307,7 +307,7 @@ public class ConfigurationTest {
|
||||||
|
|
||||||
System.setProperty(CLI_ARGS, "--db-schema=test-schema");
|
System.setProperty(CLI_ARGS, "--db-schema=test-schema");
|
||||||
config = createConfig();
|
config = createConfig();
|
||||||
assertEquals("test-schema", config.getConfigValue("kc.db.schema").getValue());
|
assertEquals("test-schema", config.getConfigValue("kc.db-schema").getValue());
|
||||||
assertEquals("test-schema", config.getConfigValue("quarkus.hibernate-orm.database.default-schema").getValue());
|
assertEquals("test-schema", config.getConfigValue("quarkus.hibernate-orm.database.default-schema").getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,8 +368,8 @@ public class ConfigurationTest {
|
||||||
@Test
|
@Test
|
||||||
public void testDatabaseDriverSetExplicitly() {
|
public void testDatabaseDriverSetExplicitly() {
|
||||||
System.setProperty(CLI_ARGS, "--db=mssql" + ARG_SEPARATOR + "--db-url=jdbc:sqlserver://localhost/keycloak");
|
System.setProperty(CLI_ARGS, "--db=mssql" + ARG_SEPARATOR + "--db-url=jdbc:sqlserver://localhost/keycloak");
|
||||||
System.setProperty("kc.db.driver", "com.microsoft.sqlserver.jdbc.SQLServerDriver");
|
System.setProperty("kc.db-driver", "com.microsoft.sqlserver.jdbc.SQLServerDriver");
|
||||||
System.setProperty("kc.db.tx-type", "enabled");
|
System.setProperty("kc.db-tx-type", "enabled");
|
||||||
assertTrue(System.getProperty(CLI_ARGS, "").contains("mssql"));
|
assertTrue(System.getProperty(CLI_ARGS, "").contains("mssql"));
|
||||||
SmallRyeConfig config = createConfig();
|
SmallRyeConfig config = createConfig();
|
||||||
assertEquals("jdbc:sqlserver://localhost/keycloak", config.getConfigValue("quarkus.datasource.jdbc.url").getValue());
|
assertEquals("jdbc:sqlserver://localhost/keycloak", config.getConfigValue("quarkus.datasource.jdbc.url").getValue());
|
||||||
|
@ -378,11 +378,18 @@ public class ConfigurationTest {
|
||||||
assertEquals("enabled", config.getConfigValue("quarkus.datasource.jdbc.transactions").getValue());
|
assertEquals("enabled", config.getConfigValue("quarkus.datasource.jdbc.transactions").getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testResolveMetricsOption() {
|
||||||
|
System.setProperty(CLI_ARGS, "--metrics-enabled=true");
|
||||||
|
SmallRyeConfig config = createConfig();
|
||||||
|
assertEquals("true", config.getConfigValue("quarkus.datasource.metrics.enabled").getValue());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOptionValueWithEqualSign() {
|
public void testOptionValueWithEqualSign() {
|
||||||
System.setProperty(CLI_ARGS, "--db-password=my_secret=");
|
System.setProperty(CLI_ARGS, "--db-password=my_secret=");
|
||||||
SmallRyeConfig config = createConfig();
|
SmallRyeConfig config = createConfig();
|
||||||
assertEquals("my_secret=", config.getConfigValue("kc.db.password").getValue());
|
assertEquals("my_secret=", config.getConfigValue("kc.db-password").getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Config.Scope initConfig(String... scope) {
|
private Config.Scope initConfig(String... scope) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
spi.hostname.default.frontend-url = ${keycloak.frontendUrl:http://filepropdefault.unittest}
|
spi-hostname-default-frontend-url = ${keycloak.frontendUrl:http://filepropdefault.unittest}
|
||||||
%user-profile.spi.hostname.default.frontend-url = http://filepropprofile.unittest
|
%user-profile.spi-hostname-default-frontend-url = http://filepropprofile.unittest
|
||||||
|
|
||||||
# Default Non-Production Grade Datasource
|
# Default Non-Production Grade Datasource
|
||||||
quarkus.datasource.db-kind=h2
|
quarkus.datasource.db-kind=h2
|
|
@ -204,7 +204,7 @@ public class CLITestExtension extends QuarkusMainTestExtension {
|
||||||
configureDevServices();
|
configureDevServices();
|
||||||
setProperty("kc.db", database.alias());
|
setProperty("kc.db", database.alias());
|
||||||
// databases like mssql are very strict about password policy
|
// databases like mssql are very strict about password policy
|
||||||
setProperty("kc.db.password", "Password1!");
|
setProperty("kc.db-password", "Password1!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,20 +45,15 @@ public class ShowConfigCommandTest {
|
||||||
.contains("Runtime Configuration"));
|
.contains("Runtime Configuration"));
|
||||||
Assertions.assertTrue(result.getOutput()
|
Assertions.assertTrue(result.getOutput()
|
||||||
.contains("Quarkus Configuration"));
|
.contains("Quarkus Configuration"));
|
||||||
Assertions.assertTrue(result.getOutput()
|
|
||||||
.contains("Profile \"import_export\" Configuration"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Launch({ CONFIG_FILE_LONG_NAME+"=src/test/resources/ShowConfigCommandTest/keycloak.properties", ShowConfig.NAME, "all" })
|
@Launch({ CONFIG_FILE_LONG_NAME+"=src/test/resources/ShowConfigCommandTest/keycloak.conf", ShowConfig.NAME, "all" })
|
||||||
void testShowConfigCommandHidesCredentialsInProfiles(LaunchResult result) {
|
void testShowConfigCommandHidesCredentialsInProfiles(LaunchResult result) {
|
||||||
String output = result.getOutput();
|
String output = result.getOutput();
|
||||||
Assertions.assertFalse(output.contains("testpw1"));
|
Assertions.assertFalse(output.contains("testpw1"));
|
||||||
Assertions.assertFalse(output.contains("testpw2"));
|
Assertions.assertFalse(output.contains("testpw2"));
|
||||||
Assertions.assertFalse(output.contains("testpw3"));
|
Assertions.assertFalse(output.contains("testpw3"));
|
||||||
Assertions.assertTrue(output.contains("kc.db.password = " + PropertyMappers.VALUE_MASK));
|
Assertions.assertTrue(output.contains("kc.db-password = " + PropertyMappers.VALUE_MASK));
|
||||||
Assertions.assertTrue(output.contains("%dev.kc.db.password = " + PropertyMappers.VALUE_MASK));
|
|
||||||
Assertions.assertTrue(output.contains("%dev.kc.https.key-store.password = " + PropertyMappers.VALUE_MASK));
|
|
||||||
Assertions.assertTrue(output.contains("%import_export.kc.db.password = " + PropertyMappers.VALUE_MASK));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ public class MSSQLStartDatabaseTest extends AbstractStartDabataseTest {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Test
|
@Test
|
||||||
@Launch({ "-Dkc.db.tx-type=enabled", "-Dkc.db.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver", "start-dev" })
|
@Launch({ "-Dkc.db-tx-type=enabled", "-Dkc.db-driver=com.microsoft.sqlserver.jdbc.SQLServerDriver", "start-dev" })
|
||||||
void testSuccessful(LaunchResult result) {
|
void testSuccessful(LaunchResult result) {
|
||||||
CLIResult cliResult = (CLIResult) result;
|
CLIResult cliResult = (CLIResult) result;
|
||||||
cliResult.assertStartedDevMode();
|
cliResult.assertStartedDevMode();
|
||||||
|
|
|
@ -28,21 +28,21 @@ import io.quarkus.test.junit.main.LaunchResult;
|
||||||
public class CustomTransactionDistTest {
|
public class CustomTransactionDistTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Launch({ "-Dkc.db.tx-type=enabled", "-Dkc.db.driver=org.postgresql.xa.PGXADataSource", "build", "--db=postgres" })
|
@Launch({ "-Dkc.db-tx-type=enabled", "-Dkc.db-driver=org.postgresql.xa.PGXADataSource", "build", "--db=postgres" })
|
||||||
void failNoXAUsingXADriver(LaunchResult result) {
|
void failNoXAUsingXADriver(LaunchResult result) {
|
||||||
CLIResult cliResult = (CLIResult) result;
|
CLIResult cliResult = (CLIResult) result;
|
||||||
cliResult.assertError("Driver org.postgresql.xa.PGXADataSource is an XA datasource, but XA transactions have not been enabled on the default datasource");
|
cliResult.assertError("Driver org.postgresql.xa.PGXADataSource is an XA datasource, but XA transactions have not been enabled on the default datasource");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Launch({ "-Dkc.db.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver", "build", "--db=mssql" })
|
@Launch({ "-Dkc.db-driver=com.microsoft.sqlserver.jdbc.SQLServerDriver", "build", "--db=mssql" })
|
||||||
void failXAUsingNonXADriver(LaunchResult result) {
|
void failXAUsingNonXADriver(LaunchResult result) {
|
||||||
CLIResult cliResult = (CLIResult) result;
|
CLIResult cliResult = (CLIResult) result;
|
||||||
cliResult.assertError("Driver is not an XA dataSource, while XA has been enabled in the configuration of the default datasource");
|
cliResult.assertError("Driver is not an XA dataSource, while XA has been enabled in the configuration of the default datasource");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Launch({ "-Dkc.db.tx-type=enabled", "-Dkc.db.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver", "build", "--db=mssql" })
|
@Launch({ "-Dkc.db-tx-type=enabled", "-Dkc.db-driver=com.microsoft.sqlserver.jdbc.SQLServerDriver", "build", "--db=mssql" })
|
||||||
void testNoXa(LaunchResult result) {
|
void testNoXa(LaunchResult result) {
|
||||||
CLIResult cliResult = (CLIResult) result;
|
CLIResult cliResult = (CLIResult) result;
|
||||||
cliResult.assertBuild();
|
cliResult.assertBuild();
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Default and non-production grade database vendor
|
||||||
|
db=h2-file
|
||||||
|
db-username = sa
|
||||||
|
db-password = keycloak
|
||||||
|
|
||||||
|
db-password=testpw1
|
||||||
|
https-key-store-password=testpw2
|
|
@ -1,48 +0,0 @@
|
||||||
# Default and non-production grade database vendor
|
|
||||||
db=h2-file
|
|
||||||
db.username = sa
|
|
||||||
db.password = keycloak
|
|
||||||
|
|
||||||
# Insecure requests are disabled by default
|
|
||||||
http.enabled=false
|
|
||||||
|
|
||||||
# Metrics and healthcheck are disabled by default
|
|
||||||
metrics.enabled=false
|
|
||||||
|
|
||||||
# Basic settings for running in production. Change accordingly before deploying the server.
|
|
||||||
# Database
|
|
||||||
#%prod.db=postgres
|
|
||||||
#%prod.db.username=keycloak
|
|
||||||
#%prod.db.password=password
|
|
||||||
#%prod.db.url=jdbc:postgresql://localhost/keycloak
|
|
||||||
# Observability
|
|
||||||
#%prod.metrics.enabled=true
|
|
||||||
# HTTP
|
|
||||||
#%prod.spi.hostname.frontend-url=https://localhost:8443
|
|
||||||
#%prod.https.certificate.file=${kc.home.dir}conf/server.crt.pem
|
|
||||||
#%prod.https.certificate.key-file=${kc.home.dir}conf/server.key.pem
|
|
||||||
#%prod.proxy=reencrypt
|
|
||||||
#%prod.hostname=myhostname
|
|
||||||
|
|
||||||
# Default, and insecure, and non-production grade configuration for the development profile
|
|
||||||
%dev.http.enabled=true
|
|
||||||
%dev.hostname.strict=false
|
|
||||||
%dev.db.password=testpw1
|
|
||||||
%dev.hostname.strict-https=false
|
|
||||||
%dev.cluster=local
|
|
||||||
%dev.spi.theme.cache-themes=false
|
|
||||||
%dev.spi.theme.cache-templates=false
|
|
||||||
%dev.spi.theme.static-max-age=-1
|
|
||||||
%dev.https.key-store.password=testpw2
|
|
||||||
|
|
||||||
# The default configuration when running in import or export mode
|
|
||||||
%import_export.http.enabled=true
|
|
||||||
%import_export.db.password=testpw3
|
|
||||||
%import_export.hostname.strict=false
|
|
||||||
%import_export.hostname.strict-https=false
|
|
||||||
%import_export.cluster=local
|
|
||||||
|
|
||||||
# Logging configuration. INFO is the default level for most of the categories
|
|
||||||
#quarkus.log.level = DEBUG
|
|
||||||
quarkus.log.category."org.jboss.resteasy.resteasy_jaxrs.i18n".level=WARN
|
|
||||||
quarkus.log.category."org.infinispan.transaction.lookup.JBossStandaloneJTAManagerLookup".level=WARN
|
|
|
@ -14,7 +14,7 @@ Options:
|
||||||
|
|
||||||
-cf, --config-file <file>
|
-cf, --config-file <file>
|
||||||
Set the path to a configuration file. By default, configuration properties are
|
Set the path to a configuration file. By default, configuration properties are
|
||||||
read from the "keycloak.properties" file in the "conf" directory.
|
read from the "keycloak.conf" file in the "conf" directory.
|
||||||
-D<key>=<value> <sysProps>
|
-D<key>=<value> <sysProps>
|
||||||
Set a Java system property
|
Set a Java system property
|
||||||
-h, --help This help message.
|
-h, --help This help message.
|
||||||
|
|
|
@ -14,7 +14,7 @@ Options:
|
||||||
|
|
||||||
-cf, --config-file <file>
|
-cf, --config-file <file>
|
||||||
Set the path to a configuration file. By default, configuration properties are
|
Set the path to a configuration file. By default, configuration properties are
|
||||||
read from the "keycloak.properties" file in the "conf" directory.
|
read from the "keycloak.conf" file in the "conf" directory.
|
||||||
-D<key>=<value> <sysProps>
|
-D<key>=<value> <sysProps>
|
||||||
Set a Java system property
|
Set a Java system property
|
||||||
-h, --help This help message.
|
-h, --help This help message.
|
||||||
|
|
|
@ -14,7 +14,7 @@ Options:
|
||||||
|
|
||||||
-cf, --config-file <file>
|
-cf, --config-file <file>
|
||||||
Set the path to a configuration file. By default, configuration properties are
|
Set the path to a configuration file. By default, configuration properties are
|
||||||
read from the "keycloak.properties" file in the "conf" directory.
|
read from the "keycloak.conf" file in the "conf" directory.
|
||||||
-D<key>=<value> <sysProps>
|
-D<key>=<value> <sysProps>
|
||||||
Set a Java system property
|
Set a Java system property
|
||||||
-h, --help This help message.
|
-h, --help This help message.
|
||||||
|
|
|
@ -713,7 +713,7 @@ Alternatively, you can perform both steps using the following command:
|
||||||
|
|
||||||
Right now, tests are using a H2 database.
|
Right now, tests are using a H2 database.
|
||||||
|
|
||||||
To run tests using a different database such as PostgreSQL, add the following properties into the `testsuite/integration-arquillian/servers/auth-server/quarkus/src/main/content/conf/keycloak.properties` configuration file:
|
To run tests using a different database such as PostgreSQL, add the following properties into the `testsuite/integration-arquillian/servers/auth-server/quarkus/src/main/content/conf/keycloak.conf` configuration file:
|
||||||
|
|
||||||
```
|
```
|
||||||
# HA using PostgreSQL
|
# HA using PostgreSQL
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
# H2
|
||||||
|
db=h2-file
|
||||||
|
db-username = sa
|
||||||
|
db-password = keycloak
|
||||||
|
|
||||||
|
# Testsuite still relies on HTTP listener
|
||||||
|
http-enabled=true
|
||||||
|
|
||||||
|
# Disables strict hostname
|
||||||
|
hostname-strict=false
|
||||||
|
hostname-strict-https=false
|
||||||
|
|
||||||
|
# SSL
|
||||||
|
https-key-store-file=${kc.home.dir}/conf/keycloak.jks
|
||||||
|
https-key-store-password=secret
|
||||||
|
https-trust-store-file=${kc.home.dir}/conf/keycloak.truststore
|
||||||
|
https-trust-store-password=secret
|
||||||
|
https-client-auth=REQUEST
|
||||||
|
|
||||||
|
# Proxy
|
||||||
|
proxy=passthrough
|
||||||
|
|
||||||
|
# Hostname Provider
|
||||||
|
spi-hostname-default-frontend-url = ${keycloak.frontendUrl:}
|
||||||
|
|
||||||
|
# Truststore Provider
|
||||||
|
spi-truststore-file-file=${kc.home.dir}/conf/keycloak.truststore
|
||||||
|
spi-truststore-file-password=secret
|
||||||
|
|
||||||
|
# Declarative User Profile
|
||||||
|
spi-user-profile-provider=declarative-user-profile
|
||||||
|
spi-user-profile-declarative-user-profile-read-only-attributes=deniedFoo,deniedBar*,deniedSome/thing,deniedsome*thing
|
||||||
|
spi-user-profile-declarative-user-profile-admin-read-only-attributes=deniedSomeAdmin
|
||||||
|
|
||||||
|
#password-blacklists path
|
||||||
|
spi-password-policy-password-blacklist-blacklists-path=${kc.home.dir:}/dependency/password-blacklists
|
||||||
|
|
||||||
|
# http client connection reuse settings
|
||||||
|
spi-connections-http-client-default-reuse-connections=false
|
||||||
|
|
||||||
|
# set max-length of event representation stored so the db can handle it
|
||||||
|
spi-events-store-jpa-max-detail-length=2000
|
||||||
|
|
||||||
|
# set known protocol ports for basicsamltest
|
||||||
|
spi-login-protocol-saml-known-protocols=http=8180,https=8543
|
||||||
|
|
||||||
|
# File-Based Vault
|
||||||
|
vault-file-path=${kc.home.dir}secrets
|
|
@ -1,48 +0,0 @@
|
||||||
# H2
|
|
||||||
db=h2-file
|
|
||||||
db.username = sa
|
|
||||||
db.password = keycloak
|
|
||||||
|
|
||||||
# Testsuite still relies on HTTP listener
|
|
||||||
http.enabled=true
|
|
||||||
|
|
||||||
# Disables strict hostname
|
|
||||||
hostname.strict=false
|
|
||||||
hostname.strict-https=false
|
|
||||||
|
|
||||||
# SSL
|
|
||||||
https.key-store.file=${kc.home.dir}/conf/keycloak.jks
|
|
||||||
https.key-store.password=secret
|
|
||||||
https.trust-store.file=${kc.home.dir}/conf/keycloak.truststore
|
|
||||||
https.trust-store.password=secret
|
|
||||||
https.client-auth=REQUEST
|
|
||||||
|
|
||||||
# Proxy
|
|
||||||
proxy=passthrough
|
|
||||||
|
|
||||||
# Hostname Provider
|
|
||||||
spi.hostname.default.frontend-url = ${keycloak.frontendUrl:}
|
|
||||||
|
|
||||||
# Truststore Provider
|
|
||||||
spi.truststore.file.file=${kc.home.dir}/conf/keycloak.truststore
|
|
||||||
spi.truststore.file.password=secret
|
|
||||||
|
|
||||||
# Declarative User Profile
|
|
||||||
spi.user-profile.provider=declarative-user-profile
|
|
||||||
spi.user-profile.declarative-user-profile.read-only-attributes=deniedFoo,deniedBar*,deniedSome/thing,deniedsome*thing
|
|
||||||
spi.user-profile.declarative-user-profile.admin-read-only-attributes=deniedSomeAdmin
|
|
||||||
|
|
||||||
#password-blacklists path
|
|
||||||
spi.password-policy.password-blacklist.blacklists-path=${kc.home.dir:}/dependency/password-blacklists
|
|
||||||
|
|
||||||
# http client connection reuse settings
|
|
||||||
spi.connections-http-client.default.reuse-connections=false
|
|
||||||
|
|
||||||
# set max-length of event representation stored so the db can handle it
|
|
||||||
spi.events-store.jpa.max-detail-length=2000
|
|
||||||
|
|
||||||
# set known protocol ports for basicsamltest
|
|
||||||
spi.login-protocol.saml.known-protocols=http=8180,https=8543
|
|
||||||
|
|
||||||
# File-Based Vault
|
|
||||||
vault.file.path=${kc.home.dir}secrets
|
|
Loading…
Reference in a new issue