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)
|
||||
@BuildStep
|
||||
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) {
|
||||
Path configPath = Paths.get(configFile);
|
||||
|
|
|
@ -414,7 +414,7 @@ class KeycloakProcessor {
|
|||
|
||||
@BuildStep(onlyIf = IsDevelopment.class)
|
||||
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(
|
||||
|
@ -591,6 +591,6 @@ class KeycloakProcessor {
|
|||
}
|
||||
|
||||
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
|
||||
static final QuarkusUnitTest test = new QuarkusUnitTest()
|
||||
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
|
||||
.addAsResource("keycloak.properties", "META-INF/keycloak.properties"));
|
||||
.addAsResource("keycloak.conf", "META-INF/keycloak.conf"));
|
||||
|
||||
@Test
|
||||
public void testReadinessDown() {
|
||||
|
|
|
@ -33,7 +33,7 @@ public class KeycloakReadyHealthCheckTest {
|
|||
@RegisterExtension
|
||||
static final QuarkusUnitTest test = new QuarkusUnitTest()
|
||||
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
|
||||
.addAsResource("keycloak.properties", "META-INF/keycloak.properties"));
|
||||
.addAsResource("keycloak.conf", "META-INF/keycloak.conf"));
|
||||
|
||||
@Test
|
||||
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) {
|
||||
if (cause instanceof FileSystemException) {
|
||||
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))) {
|
||||
logError(errorWriter, Messages.httpsConfigurationNotSet().getMessage());
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
|
||||
package org.keycloak.quarkus.runtime.cli;
|
||||
|
||||
import static io.smallrye.config.common.utils.StringUtil.replaceNonAlphanumericByUnderscores;
|
||||
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_SHORT;
|
||||
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.Configuration.OPTION_PART_SEPARATOR;
|
||||
import static org.keycloak.quarkus.runtime.configuration.Configuration.getBuildTimeProperty;
|
||||
import static org.keycloak.quarkus.runtime.configuration.Configuration.getConfig;
|
||||
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.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
@ -71,7 +70,6 @@ public final class Picocli {
|
|||
public static final String ARG_PREFIX = "--";
|
||||
private static final String ARG_KEY_VALUE_SEPARATOR = "=";
|
||||
public static final String ARG_SHORT_PREFIX = "-";
|
||||
public static final String ARG_PART_SEPARATOR = "-";
|
||||
public static final String NO_PARAM_LABEL = "none";
|
||||
|
||||
private Picocli() {
|
||||
|
@ -348,10 +346,10 @@ public final class Picocli {
|
|||
.validate(false);
|
||||
|
||||
for(PropertyMapper mapper: mappersInCategory) {
|
||||
String name = ARG_PREFIX + PropertyMappers.toCLIFormat(mapper.getFrom()).substring(3);
|
||||
String name = mapper.getCliFormat();
|
||||
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.
|
||||
continue;
|
||||
}
|
||||
|
@ -378,10 +376,6 @@ public final class Picocli {
|
|||
cmd.getOut().println(message);
|
||||
}
|
||||
|
||||
public static String normalizeKey(String key) {
|
||||
return replaceNonAlphanumericByUnderscores(key).replace('_', '.');
|
||||
}
|
||||
|
||||
public static List<String> parseArgs(String[] rawArgs) {
|
||||
if (rawArgs.length == 0) {
|
||||
return List.of();
|
||||
|
|
|
@ -107,7 +107,7 @@ public final class Main {
|
|||
|
||||
@Option(names = { CONFIG_FILE_SHORT_NAME, CONFIG_FILE_LONG_NAME },
|
||||
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")
|
||||
public void setConfigFile(String 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.configuration.Configuration.getConfigValue;
|
||||
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 java.util.HashSet;
|
||||
|
@ -63,8 +62,6 @@ public final class ShowConfig extends AbstractCommand implements Runnable {
|
|||
printRunTimeConfig(properties, profile);
|
||||
|
||||
if (configArgs.equalsIgnoreCase("all")) {
|
||||
printAllProfilesConfig(properties, profile);
|
||||
|
||||
spec.commandLine().getOut().println("Quarkus Configuration:");
|
||||
properties.get(MicroProfileConfigProvider.NS_QUARKUS).stream().sorted()
|
||||
.forEachOrdered(this::printProperty);
|
||||
|
@ -84,37 +81,10 @@ public final class ShowConfig extends AbstractCommand implements Runnable {
|
|||
spec.commandLine().getOut().println("Runtime Configuration:");
|
||||
|
||||
properties.get(MicroProfileConfigProvider.NS_KEYCLOAK).stream().sorted()
|
||||
.filter(name -> {
|
||||
String canonicalFormat = canonicalFormat(name);
|
||||
|
||||
if (!canonicalFormat.equals(name)) {
|
||||
return uniqueNames.add(canonicalFormat);
|
||||
}
|
||||
return uniqueNames.add(name);
|
||||
})
|
||||
.filter(uniqueNames::add)
|
||||
.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() {
|
||||
Map<String, Set<String>> properties = StreamSupport
|
||||
.stream(getPropertyNames().spliterator(), false)
|
||||
|
@ -147,8 +117,7 @@ public final class ShowConfig extends AbstractCommand implements Runnable {
|
|||
}
|
||||
|
||||
private void printProperty(String property) {
|
||||
String canonicalFormat = canonicalFormat(property);
|
||||
ConfigValue configValue = getConfigValue(canonicalFormat);
|
||||
ConfigValue configValue = getConfigValue(property);
|
||||
|
||||
if (configValue.getValue() == null) {
|
||||
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.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.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.MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX;
|
||||
|
||||
|
@ -97,7 +99,7 @@ public class ConfigArgsConfigSource extends PropertiesConfigSource {
|
|||
return value;
|
||||
}
|
||||
|
||||
return properties.get(propertyName.replace('-', '.'));
|
||||
return properties.get(propertyName.replace(OPTION_PART_SEPARATOR_CHAR, '.'));
|
||||
}
|
||||
|
||||
private static Map<String, String> parseArgument() {
|
||||
|
@ -127,9 +129,6 @@ public class ConfigArgsConfigSource extends PropertiesConfigSource {
|
|||
if (mapper != null) {
|
||||
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;
|
||||
|
||||
import static io.smallrye.config.common.utils.StringUtil.replaceNonAlphanumericByUnderscores;
|
||||
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.function.Function;
|
||||
|
||||
import io.smallrye.config.ConfigValue;
|
||||
import io.smallrye.config.SmallRyeConfig;
|
||||
import io.smallrye.config.SmallRyeConfigProviderResolver;
|
||||
|
||||
import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
|
||||
import org.eclipse.microprofile.config.spi.ConfigSource;
|
||||
|
@ -40,6 +38,9 @@ import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
|
|||
*/
|
||||
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() {
|
||||
|
||||
}
|
||||
|
@ -98,17 +99,14 @@ public final class Configuration {
|
|||
}
|
||||
|
||||
public static String getMappedPropertyName(String key) {
|
||||
for (PropertyMapper mapper : PropertyMappers.getMappers()) {
|
||||
String mappedProperty = mapper.getFrom();
|
||||
List<String> expectedFormats = Arrays.asList(mappedProperty, toCLIFormat(mappedProperty), mappedProperty.toUpperCase().replace('.', '_').replace('-', '_'));
|
||||
PropertyMapper mapper = PropertyMappers.getMapper(key);
|
||||
|
||||
if (expectedFormats.contains(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 ? mappedProperty : mapper.getTo();
|
||||
}
|
||||
if (mapper == null) {
|
||||
return key;
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -131,6 +129,14 @@ public final class Configuration {
|
|||
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) {
|
||||
String value = configSource.getValue(name);
|
||||
|
||||
|
|
|
@ -33,10 +33,12 @@ public class KcEnvConfigSource extends EnvConfigSource {
|
|||
|
||||
private static Map<String, String> buildProperties() {
|
||||
Map<String, String> properties = new HashMap<>();
|
||||
String kcPrefix = replaceNonAlphanumericByUnderscores(MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX.toUpperCase());
|
||||
|
||||
for (Map.Entry<String, String> entry : System.getenv().entrySet()) {
|
||||
String key = entry.getKey();
|
||||
if (key.startsWith(replaceNonAlphanumericByUnderscores(MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX.toUpperCase()))) {
|
||||
|
||||
if (key.startsWith(kcPrefix)) {
|
||||
properties.put(getMappedPropertyName(key), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,6 @@ public class KeycloakConfigSourceProvider implements ConfigSourceProvider {
|
|||
}
|
||||
|
||||
CONFIG_SOURCES.add(new ConfigArgsConfigSource());
|
||||
CONFIG_SOURCES.add(new SysPropConfigSource());
|
||||
CONFIG_SOURCES.add(new KcEnvConfigSource());
|
||||
CONFIG_SOURCES.add(PersistedConfigSource.getInstance());
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.util.Collections;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* A configuration source for {@code keycloak.properties}.
|
||||
* A configuration source for {@code keycloak.conf}.
|
||||
*/
|
||||
public class KeycloakPropertiesConfigSource extends AbstractLocationConfigSourceLoader {
|
||||
|
||||
private static final Pattern DOT_SPLIT = Pattern.compile("\\.");
|
||||
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";
|
||||
|
||||
@Override
|
||||
protected String[] getFileExtensions() {
|
||||
return new String[] { "properties" };
|
||||
return new String[] { "conf" };
|
||||
}
|
||||
|
||||
@Override
|
||||
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 {
|
||||
|
||||
@Override
|
||||
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
|
||||
|
@ -122,7 +123,7 @@ public class KeycloakPropertiesConfigSource extends AbstractLocationConfigSource
|
|||
String homeDir = Environment.getHomeDir();
|
||||
|
||||
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()) {
|
||||
filePath = file.getAbsolutePath();
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
|
||||
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.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -60,7 +63,7 @@ public class MicroProfileConfigProvider implements Config.ConfigProvider {
|
|||
|
||||
public MicroProfileScope(String... 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
|
||||
|
@ -119,14 +122,14 @@ public class MicroProfileConfigProvider implements Config.ConfigProvider {
|
|||
.filter(new Predicate<String>() {
|
||||
@Override
|
||||
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());
|
||||
}
|
||||
|
||||
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 super.getValue(propertyName.replace('-', '.'));
|
||||
return super.getValue(propertyName.replace(Configuration.OPTION_PART_SEPARATOR_CHAR, '.'));
|
||||
}
|
||||
|
||||
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")
|
||||
.build(),
|
||||
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 "
|
||||
+ "if 'cache' is set to 'ispn'.")
|
||||
.defaultValue("udp")
|
||||
|
@ -32,9 +32,9 @@ final class ClusteringPropertyMappers {
|
|||
.isBuildTimeProperty(true)
|
||||
.expectedValues(Arrays.asList("tcp", "udp", "kubernetes", "ec2", "azure", "google"))
|
||||
.build(),
|
||||
builder().from("cache.config-file")
|
||||
builder().from("cache-config-file")
|
||||
.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.")
|
||||
.transformer(new BiFunction<String, ConfigSourceInterceptorContext, String>() {
|
||||
@Override
|
||||
|
|
|
@ -23,7 +23,7 @@ final class DatabasePropertyMappers {
|
|||
.transformer((db, context) -> Database.getDialect(db).orElse(Database.getDialect("h2-file").get()))
|
||||
.hidden(true)
|
||||
.build(),
|
||||
builder().from("db.driver")
|
||||
builder().from("db-driver")
|
||||
.mapFrom("db")
|
||||
.defaultValue(Database.getDriver("h2-file").get())
|
||||
.to("quarkus.datasource.jdbc.driver")
|
||||
|
@ -38,12 +38,12 @@ final class DatabasePropertyMappers {
|
|||
.paramLabel("vendor")
|
||||
.expectedValues(asList(Database.getAliases()))
|
||||
.build(),
|
||||
builder().from("db.tx-type")
|
||||
builder().from("db-tx-type")
|
||||
.defaultValue("xa")
|
||||
.to("quarkus.datasource.jdbc.transactions")
|
||||
.hidden(true)
|
||||
.build(),
|
||||
builder().from("db.url")
|
||||
builder().from("db-url")
|
||||
.to("quarkus.datasource.jdbc.url")
|
||||
.mapFrom("db")
|
||||
.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'. ")
|
||||
.paramLabel("jdbc-url")
|
||||
.build(),
|
||||
builder().from("db.url.host")
|
||||
.to("kc.db.url.host")
|
||||
builder().from("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.")
|
||||
.paramLabel("hostname")
|
||||
.build(),
|
||||
builder().from("db.url.database")
|
||||
.to("kc.db.url.database")
|
||||
builder().from("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.")
|
||||
.paramLabel("dbname")
|
||||
.build(),
|
||||
builder().from("db.url.properties")
|
||||
.to("kc.db.url.properties")
|
||||
builder().from("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.")
|
||||
.paramLabel("properties")
|
||||
.build(),
|
||||
builder().from("db.username")
|
||||
builder().from("db-username")
|
||||
.to("quarkus.datasource.username")
|
||||
.description("The username of the database user.")
|
||||
.paramLabel("username")
|
||||
.build(),
|
||||
builder().from("db.password")
|
||||
builder().from("db-password")
|
||||
.to("quarkus.datasource.password")
|
||||
.description("The password of the database user.")
|
||||
.paramLabel("password")
|
||||
.isMasked(true)
|
||||
.build(),
|
||||
builder().from("db.schema")
|
||||
builder().from("db-schema")
|
||||
.to("quarkus.hibernate-orm.database.default-schema")
|
||||
.description("The database schema to be used.")
|
||||
.paramLabel("schema")
|
||||
.build(),
|
||||
builder().from("db.pool.initial-size")
|
||||
builder().from("db-pool-initial-size")
|
||||
.to("quarkus.datasource.jdbc.initial-size")
|
||||
.description("The initial size of the connection pool.")
|
||||
.paramLabel("size")
|
||||
.build(),
|
||||
builder().from("db.pool.min-size")
|
||||
builder().from("db-pool-min-size")
|
||||
.to("quarkus.datasource.jdbc.min-size")
|
||||
.description("The minimal size of the connection pool.")
|
||||
.paramLabel("size")
|
||||
.build(),
|
||||
builder().from("db.pool.max-size")
|
||||
builder().from("db-pool-max-size")
|
||||
.to("quarkus.datasource.jdbc.max-size")
|
||||
.defaultValue(String.valueOf(100))
|
||||
.description("The maximum size of the connection pool.")
|
||||
|
|
|
@ -8,35 +8,35 @@ final class HostnamePropertyMappers {
|
|||
public static PropertyMapper[] getHostnamePropertyMappers() {
|
||||
return new PropertyMapper[] {
|
||||
builder().from("hostname")
|
||||
.to("kc.spi.hostname.default.hostname")
|
||||
.to("kc.spi-hostname-default-hostname")
|
||||
.description("Hostname for the Keycloak server.")
|
||||
.paramLabel("hostname")
|
||||
.build(),
|
||||
builder().from("hostname.admin")
|
||||
.to("kc.spi.hostname.default.admin")
|
||||
builder().from("hostname-admin")
|
||||
.to("kc.spi-hostname-default-admin")
|
||||
.description("Overrides the hostname for the admin console and APIs.")
|
||||
.paramLabel("url")
|
||||
.build(),
|
||||
builder().from("hostname.strict")
|
||||
.to("kc.spi.hostname.default.strict")
|
||||
builder().from("hostname-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.")
|
||||
.type(Boolean.class)
|
||||
.defaultValue(Boolean.TRUE.toString())
|
||||
.build(),
|
||||
builder().from("hostname.strict-https")
|
||||
.to("kc.spi.hostname.default.strict-https")
|
||||
builder().from("hostname-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.")
|
||||
.hidden(true)
|
||||
.defaultValue(Boolean.TRUE.toString())
|
||||
.type(Boolean.class)
|
||||
.build(),
|
||||
builder().from("hostname.strict-backchannel")
|
||||
.to("kc.spi.hostname.default.strict-backchannel")
|
||||
builder().from("hostname-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.")
|
||||
.type(Boolean.class)
|
||||
.build(),
|
||||
builder().from("hostname.path")
|
||||
.to("kc.spi.hostname.default.path")
|
||||
builder().from("hostname-path")
|
||||
.to("kc.spi-hostname-default-path")
|
||||
.description("This should be set if proxy uses a different context-path for Keycloak.")
|
||||
.paramLabel("path")
|
||||
.build()
|
||||
|
|
|
@ -19,7 +19,7 @@ final class HttpPropertyMappers {
|
|||
|
||||
public static PropertyMapper[] getHttpPropertyMappers() {
|
||||
return new PropertyMapper[] {
|
||||
builder().from("http.enabled")
|
||||
builder().from("http-enabled")
|
||||
.to("quarkus.http.insecure-requests")
|
||||
.defaultValue(Boolean.FALSE.toString())
|
||||
.transformer(HttpPropertyMappers::getHttpEnabledTransformer)
|
||||
|
@ -27,90 +27,90 @@ final class HttpPropertyMappers {
|
|||
.paramLabel(Boolean.TRUE + "|" + Boolean.FALSE)
|
||||
.expectedValues(Arrays.asList(Boolean.TRUE.toString(), Boolean.FALSE.toString()))
|
||||
.build(),
|
||||
builder().from("http.host")
|
||||
builder().from("http-host")
|
||||
.to("quarkus.http.host")
|
||||
.defaultValue("0.0.0.0")
|
||||
.description("The used HTTP Host.")
|
||||
.paramLabel("host")
|
||||
.build(),
|
||||
builder().from("http.relative-path")
|
||||
builder().from("http-relative-path")
|
||||
.to("quarkus.http.root-path")
|
||||
.defaultValue("/")
|
||||
.description("Set the path relative to '/' for serving resources.")
|
||||
.paramLabel("path")
|
||||
.isBuildTimeProperty(true)
|
||||
.build(),
|
||||
builder().from("http.port")
|
||||
builder().from("http-port")
|
||||
.to("quarkus.http.port")
|
||||
.defaultValue(String.valueOf(8080))
|
||||
.description("The used HTTP port.")
|
||||
.paramLabel("port")
|
||||
.build(),
|
||||
builder().from("https.port")
|
||||
builder().from("https-port")
|
||||
.to("quarkus.http.ssl-port")
|
||||
.defaultValue(String.valueOf(8443))
|
||||
.description("The used HTTPS port.")
|
||||
.paramLabel("port")
|
||||
.build(),
|
||||
builder().from("https.client-auth")
|
||||
builder().from("https-client-auth")
|
||||
.to("quarkus.http.ssl.client-auth")
|
||||
.defaultValue("none")
|
||||
.description("Configures the server to require/request client authentication. Possible Values: none, request, required.")
|
||||
.paramLabel("auth")
|
||||
.expectedValues(Arrays.asList("none", "request", "required"))
|
||||
.build(),
|
||||
builder().from("https.cipher-suites")
|
||||
builder().from("https-cipher-suites")
|
||||
.to("quarkus.http.ssl.cipher-suites")
|
||||
.description("The cipher suites to use. If none is given, a reasonable default is selected.")
|
||||
.paramLabel("ciphers")
|
||||
.build(),
|
||||
builder().from("https.protocols")
|
||||
builder().from("https-protocols")
|
||||
.to("quarkus.http.ssl.protocols")
|
||||
.description("The list of protocols to explicitly enable.")
|
||||
.paramLabel("protocols")
|
||||
.defaultValue("TLSv1.3")
|
||||
.build(),
|
||||
builder().from("https.certificate.file")
|
||||
builder().from("https-certificate-file")
|
||||
.to("quarkus.http.ssl.certificate.file")
|
||||
.description("The file path to a server certificate or certificate chain in PEM format.")
|
||||
.paramLabel("file")
|
||||
.build(),
|
||||
builder().from("https.certificate.key-file")
|
||||
builder().from("https-certificate-key-file")
|
||||
.to("quarkus.http.ssl.certificate.key-file")
|
||||
.description("The file path to a private key in PEM format.")
|
||||
.paramLabel("file")
|
||||
.build(),
|
||||
builder().from("https.key-store.file")
|
||||
builder().from("https-key-store-file")
|
||||
.to("quarkus.http.ssl.certificate.key-store-file")
|
||||
.defaultValue(getDefaultKeystorePathValue())
|
||||
.description("The key store which holds the certificate information instead of specifying separate files.")
|
||||
.paramLabel("file")
|
||||
.build(),
|
||||
builder().from("https.key-store.password")
|
||||
builder().from("https-key-store-password")
|
||||
.to("quarkus.http.ssl.certificate.key-store-password")
|
||||
.description("The password of the key store file.")
|
||||
.defaultValue("password")
|
||||
.paramLabel("password")
|
||||
.isMasked(true)
|
||||
.build(),
|
||||
builder().from("https.key-store.type")
|
||||
builder().from("https-key-store-type")
|
||||
.to("quarkus.http.ssl.certificate.key-store-file-type")
|
||||
.description("The type of the key store file. " +
|
||||
"If not given, the type is automatically detected based on the file name.")
|
||||
.paramLabel("type")
|
||||
.build(),
|
||||
builder().from("https.trust-store.file")
|
||||
builder().from("https-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.")
|
||||
.paramLabel("file")
|
||||
.build(),
|
||||
builder().from("https.trust-store.password")
|
||||
builder().from("https-trust-store-password")
|
||||
.to("quarkus.http.ssl.certificate.trust-store-password")
|
||||
.description("The password of the trust store file.")
|
||||
.paramLabel("password")
|
||||
.isMasked(true)
|
||||
.build(),
|
||||
builder().from("https.trust-store.type")
|
||||
builder().from("https-trust-store-type")
|
||||
.to("quarkus.http.ssl.certificate.trust-store-file-type")
|
||||
.defaultValue(getDefaultKeystorePathValue())
|
||||
.description("The type of the trust store file. " +
|
||||
|
@ -131,7 +131,7 @@ final class HttpPropertyMappers {
|
|||
}
|
||||
|
||||
if (!enabled) {
|
||||
ConfigValue proceed = context.proceed("kc.https.certificate.file");
|
||||
ConfigValue proceed = context.proceed("kc.https-certificate-file");
|
||||
|
||||
if (proceed == null || proceed.getValue() == null) {
|
||||
proceed = getMapper("quarkus.http.ssl.certificate.key-store-file").getConfigValue(context);
|
||||
|
|
|
@ -9,7 +9,7 @@ final class MetricsPropertyMappers {
|
|||
|
||||
public static PropertyMapper[] getMetricsPropertyMappers() {
|
||||
return new PropertyMapper[] {
|
||||
builder().from("metrics.enabled")
|
||||
builder().from("metrics-enabled")
|
||||
.to("quarkus.datasource.metrics.enabled")
|
||||
.isBuildTimeProperty(true)
|
||||
.defaultValue(Boolean.FALSE.toString())
|
||||
|
|
|
@ -16,13 +16,18 @@
|
|||
*/
|
||||
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.Collections;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import io.smallrye.config.ConfigSourceInterceptorContext;
|
||||
import io.smallrye.config.ConfigValue;
|
||||
import org.keycloak.quarkus.runtime.cli.Picocli;
|
||||
|
||||
import org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider;
|
||||
|
||||
public class PropertyMapper {
|
||||
|
@ -47,9 +52,9 @@ public class PropertyMapper {
|
|||
private final ConfigCategory category;
|
||||
private final String paramLabel;
|
||||
private final boolean hidden;
|
||||
private final String envVarFormat;
|
||||
private String cliFormat;
|
||||
|
||||
|
||||
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,
|
||||
ConfigCategory category, boolean hidden) {
|
||||
|
@ -65,7 +70,8 @@ public class PropertyMapper {
|
|||
this.expectedValues = expectedValues == null ? Collections.emptyList() : expectedValues;
|
||||
this.category = category != null ? category : ConfigCategory.GENERAL;
|
||||
this.hidden = hidden;
|
||||
setCliFormat(this.from);
|
||||
this.cliFormat = toCliFormat(from);
|
||||
this.envVarFormat = toEnvVarFormat(this.from);
|
||||
}
|
||||
|
||||
public static PropertyMapper.Builder builder(String fromProp, String toProp) {
|
||||
|
@ -87,9 +93,9 @@ public class PropertyMapper {
|
|||
ConfigValue getConfigValue(String name, ConfigSourceInterceptorContext context) {
|
||||
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
|
||||
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
|
||||
|
@ -98,7 +104,7 @@ public class PropertyMapper {
|
|||
if (config == 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
|
||||
String parentKey = MicroProfileConfigProvider.NS_KEYCLOAK + "." + mapFrom;
|
||||
String parentKey = MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX + mapFrom;
|
||||
ConfigValue parentValue = context.proceed(parentKey);
|
||||
|
||||
if (parentValue == null) {
|
||||
|
@ -187,6 +193,10 @@ public class PropertyMapper {
|
|||
return cliFormat;
|
||||
}
|
||||
|
||||
public String getEnvVarFormat() {
|
||||
return envVarFormat;
|
||||
}
|
||||
|
||||
boolean isMask() {
|
||||
return mask;
|
||||
}
|
||||
|
@ -209,10 +219,6 @@ public class PropertyMapper {
|
|||
return null;
|
||||
}
|
||||
|
||||
private void setCliFormat(String from) {
|
||||
cliFormat = Picocli.ARG_PREFIX + PropertyMappers.toCLIFormat(from).substring(3);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private String from;
|
||||
|
|
|
@ -82,7 +82,7 @@ public final class PropertyMappers {
|
|||
&& !Environment.PROFILE.equals(name)
|
||||
&& !"kc.show.config".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) {
|
||||
|
@ -93,16 +93,6 @@ public final class PropertyMappers {
|
|||
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() {
|
||||
return MAPPERS.values().stream()
|
||||
.filter(entry -> !entry.isBuildTime()).collect(Collectors.toList());
|
||||
|
@ -113,10 +103,6 @@ public final class PropertyMappers {
|
|||
.filter(PropertyMapper::isBuildTime).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static String canonicalFormat(String name) {
|
||||
return name.replaceAll("-", "\\.");
|
||||
}
|
||||
|
||||
public static String formatValue(String property, String value) {
|
||||
property = removeProfilePrefixIfNeeded(property);
|
||||
PropertyMapper mapper = getMapper(property);
|
||||
|
@ -170,6 +156,7 @@ public final class PropertyMappers {
|
|||
super.put(mapper.getTo(), mapper);
|
||||
super.put(mapper.getFrom(), mapper);
|
||||
super.put(mapper.getCliFormat(), mapper);
|
||||
super.put(mapper.getEnvVarFormat(), mapper);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,19 +8,19 @@ final class VaultPropertyMappers {
|
|||
public static PropertyMapper[] getVaultPropertyMappers() {
|
||||
return new PropertyMapper[] {
|
||||
builder()
|
||||
.from("vault.file.path")
|
||||
.to("kc.spi.vault.files-plaintext.dir")
|
||||
.from("vault-file-path")
|
||||
.to("kc.spi-vault-files-plaintext-dir")
|
||||
.description("If set, secrets can be obtained by reading the content of files within the given path.")
|
||||
.paramLabel("dir")
|
||||
.build(),
|
||||
builder()
|
||||
.from("vault.hashicorp.")
|
||||
.from("vault-hashicorp-")
|
||||
.to("quarkus.vault.")
|
||||
.description("If set, secrets can be obtained from Hashicorp Vault.")
|
||||
.build(),
|
||||
builder()
|
||||
.from("vault.hashicorp.paths")
|
||||
.to("kc.spi.vault.hashicorp.paths")
|
||||
.from("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.")
|
||||
.paramLabel("paths")
|
||||
.build()
|
||||
|
|
|
@ -210,7 +210,7 @@ public final class DefaultHostnameProvider implements HostnameProvider, Hostname
|
|||
|
||||
defaultPath = config.get("path");
|
||||
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");
|
||||
strictBackChannel = config.getBoolean("strict-backchannel", false);
|
||||
|
||||
|
|
|
@ -100,11 +100,11 @@ public final class Database {
|
|||
@Override
|
||||
public String apply(String 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
|
||||
+ "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"),
|
||||
|
@ -114,13 +114,13 @@ public final class Database {
|
|||
"com.mysql.cj.jdbc.MysqlXADataSource",
|
||||
"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")
|
||||
),
|
||||
MARIADB("mariadb",
|
||||
"org.mariadb.jdbc.MySQLDataSource",
|
||||
"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")
|
||||
),
|
||||
POSTGRES("postgresql",
|
||||
|
@ -134,7 +134,7 @@ public final class Database {
|
|||
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",
|
||||
"org.keycloak.connections.jpa.updater.liquibase.PostgresPlusDatabase"),
|
||||
"postgres", "postgres-95"
|
||||
|
@ -151,14 +151,14 @@ public final class Database {
|
|||
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"),
|
||||
"mssql", "mssql-2012"
|
||||
),
|
||||
ORACLE("oracle",
|
||||
"oracle.jdbc.xa.client.OracleXADataSource",
|
||||
"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")
|
||||
);
|
||||
|
||||
|
|
|
@ -176,7 +176,7 @@ public final class QuarkusJpaConnectionProviderFactory implements JpaConnectionP
|
|||
|
||||
@Override
|
||||
public String getSchema() {
|
||||
return Configuration.getRawValue("kc.db.schema");
|
||||
return Configuration.getRawValue("kc.db-schema");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -74,11 +74,11 @@ public class CacheManagerFactory {
|
|||
|
||||
private boolean isStartEagerly() {
|
||||
// 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() {
|
||||
return Integer.getInteger("kc.cache.ispn.start-timeout", 120);
|
||||
return Integer.getInteger("kc.cache-ispn-start-timeout", 120);
|
||||
}
|
||||
|
||||
private void shutdownThreadPool() {
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
# Default and non-production grade database vendor
|
||||
db=h2-file
|
||||
db.username = sa
|
||||
db.password = keycloak
|
||||
db-username = sa
|
||||
db-password = keycloak
|
||||
|
||||
# Insecure requests are disabled by default
|
||||
http.enabled=false
|
||||
http-enabled=false
|
||||
|
||||
# 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
|
||||
%dev.http.enabled=true
|
||||
%dev.hostname.strict=false
|
||||
%dev.hostname.strict-https=false
|
||||
%dev.http-enabled=true
|
||||
%dev.hostname-strict=false
|
||||
%dev.hostname-strict-https=false
|
||||
%dev.cache=local
|
||||
%dev.spi.theme.cache-themes=false
|
||||
%dev.spi.theme.cache-templates=false
|
||||
%dev.spi.theme.static-max-age=-1
|
||||
%dev.spi-theme-cache-themes=false
|
||||
%dev.spi-theme-cache-templates=false
|
||||
%dev.spi-theme-static-max-age=-1
|
||||
|
||||
# The default configuration when running in import or export mode
|
||||
%import_export.http.enabled=true
|
||||
%import_export.hostname.strict=false
|
||||
%import_export.hostname.strict-https=false
|
||||
%import_export.http-enabled=true
|
||||
%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
|
|
@ -128,14 +128,14 @@ public class ConfigurationTest {
|
|||
Config.Scope config = initConfig("vault", FilesPlainTextVaultProviderFactory.PROVIDER_ID);
|
||||
assertEquals("/foo/bar", config.get("dir"));
|
||||
assertTrue(config.getPropertyNames()
|
||||
.contains("kc.spi.vault.".concat(FilesPlainTextVaultProviderFactory.PROVIDER_ID).concat(".dir")));
|
||||
.contains("kc.spi-vault-".concat(FilesPlainTextVaultProviderFactory.PROVIDER_ID).concat("-dir")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSysPropPriorityOverEnvVar() {
|
||||
public void testEnvVarPriorityOverSysProps() {
|
||||
putEnvVar("KC_SPI_HOSTNAME_DEFAULT_FRONTEND_URL", "http://envvar.unittest");
|
||||
System.setProperty("kc.spi.hostname.default.frontend-url", "http://propvar.unittest");
|
||||
assertEquals("http://propvar.unittest", initConfig("hostname", "default").get("frontendUrl"));
|
||||
System.setProperty("kc.spi-hostname-default-frontend-url", "http://propvar.unittest");
|
||||
assertEquals("http://envvar.unittest", initConfig("hostname", "default").get("frontendUrl"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -203,13 +203,13 @@ public class ConfigurationTest {
|
|||
assertEquals("secrets", config.get("dir"));
|
||||
|
||||
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");
|
||||
assertEquals(1, config.getPropertyNames().size());
|
||||
assertEquals("http://c.jwk.url", config.get("static-jwk-url"));
|
||||
|
||||
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");
|
||||
config = initConfig("client-registration", "openid-connect");
|
||||
assertEquals(1, config.getPropertyNames().size());
|
||||
|
@ -279,8 +279,8 @@ public class ConfigurationTest {
|
|||
|
||||
@Test
|
||||
public void testDatabaseProperties() {
|
||||
System.setProperty("kc.db.url.properties", ";;test=test;test1=test1");
|
||||
System.setProperty("kc.db.url.path", "test-dir");
|
||||
System.setProperty("kc.db-url-properties", ";;test=test;test1=test1");
|
||||
System.setProperty("kc.db-url-path", "test-dir");
|
||||
System.setProperty(CLI_ARGS, "--db=h2-file");
|
||||
SmallRyeConfig config = createConfig();
|
||||
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("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");
|
||||
config = createConfig();
|
||||
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");
|
||||
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());
|
||||
}
|
||||
|
||||
|
@ -368,8 +368,8 @@ public class ConfigurationTest {
|
|||
@Test
|
||||
public void testDatabaseDriverSetExplicitly() {
|
||||
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.tx-type", "enabled");
|
||||
System.setProperty("kc.db-driver", "com.microsoft.sqlserver.jdbc.SQLServerDriver");
|
||||
System.setProperty("kc.db-tx-type", "enabled");
|
||||
assertTrue(System.getProperty(CLI_ARGS, "").contains("mssql"));
|
||||
SmallRyeConfig config = createConfig();
|
||||
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());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveMetricsOption() {
|
||||
System.setProperty(CLI_ARGS, "--metrics-enabled=true");
|
||||
SmallRyeConfig config = createConfig();
|
||||
assertEquals("true", config.getConfigValue("quarkus.datasource.metrics.enabled").getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOptionValueWithEqualSign() {
|
||||
System.setProperty(CLI_ARGS, "--db-password=my_secret=");
|
||||
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) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
spi.hostname.default.frontend-url = ${keycloak.frontendUrl:http://filepropdefault.unittest}
|
||||
%user-profile.spi.hostname.default.frontend-url = http://filepropprofile.unittest
|
||||
spi-hostname-default-frontend-url = ${keycloak.frontendUrl:http://filepropdefault.unittest}
|
||||
%user-profile.spi-hostname-default-frontend-url = http://filepropprofile.unittest
|
||||
|
||||
# Default Non-Production Grade Datasource
|
||||
quarkus.datasource.db-kind=h2
|
|
@ -204,7 +204,7 @@ public class CLITestExtension extends QuarkusMainTestExtension {
|
|||
configureDevServices();
|
||||
setProperty("kc.db", database.alias());
|
||||
// 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"));
|
||||
Assertions.assertTrue(result.getOutput()
|
||||
.contains("Quarkus Configuration"));
|
||||
Assertions.assertTrue(result.getOutput()
|
||||
.contains("Profile \"import_export\" Configuration"));
|
||||
}
|
||||
|
||||
@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) {
|
||||
String output = result.getOutput();
|
||||
Assertions.assertFalse(output.contains("testpw1"));
|
||||
Assertions.assertFalse(output.contains("testpw2"));
|
||||
Assertions.assertFalse(output.contains("testpw3"));
|
||||
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));
|
||||
Assertions.assertTrue(output.contains("kc.db-password = " + PropertyMappers.VALUE_MASK));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ public class MSSQLStartDatabaseTest extends AbstractStartDabataseTest {
|
|||
*/
|
||||
@Override
|
||||
@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) {
|
||||
CLIResult cliResult = (CLIResult) result;
|
||||
cliResult.assertStartedDevMode();
|
||||
|
|
|
@ -28,21 +28,21 @@ import io.quarkus.test.junit.main.LaunchResult;
|
|||
public class CustomTransactionDistTest {
|
||||
|
||||
@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) {
|
||||
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");
|
||||
}
|
||||
|
||||
@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) {
|
||||
CLIResult cliResult = (CLIResult) result;
|
||||
cliResult.assertError("Driver is not an XA dataSource, while XA has been enabled in the configuration of the default datasource");
|
||||
}
|
||||
|
||||
@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) {
|
||||
CLIResult cliResult = (CLIResult) result;
|
||||
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>
|
||||
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>
|
||||
Set a Java system property
|
||||
-h, --help This help message.
|
||||
|
|
|
@ -14,7 +14,7 @@ Options:
|
|||
|
||||
-cf, --config-file <file>
|
||||
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>
|
||||
Set a Java system property
|
||||
-h, --help This help message.
|
||||
|
|
|
@ -14,7 +14,7 @@ Options:
|
|||
|
||||
-cf, --config-file <file>
|
||||
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>
|
||||
Set a Java system property
|
||||
-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.
|
||||
|
||||
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
|
||||
|
|
|
@ -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