8000 fix: map just logging env wildcards to . by shawkins · Pull Request #40834 · keycloak/keycloak · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

fix: map just logging env wildcards to . #40834

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions docs/guides/server/configuration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,13 @@ PowerShell handles quotes differently. It interprets the quoted string before pa

=== Formats for environment variable keys with special characters

Some configuration keys, such as those for logging, may contain characters such as `_` or `$` - e.g. `kc.log-level-package.class_name`. Non-alphanumeric characters in your configuration key must be converted to `\_` in the corresponding environment variable key.
Non-alphanumeric characters in your configuration key must be converted to `_` in the corresponding environment variable key.

The automatic handling of the environment variable key may not preserve the intended key. For example `KC_LOG_LEVEL_PACKAGE_CLASS_NAME` will become `kc.log-level-package.class.name` because logging properties default to replacing `_` in the "wildcard"
part of the key with `.` as that is what is most commonly needed in a class / package name. However this does not match the intent of `kc.log-level-package.class_name`.
Environment variables are converted back to normal option keys by lower-casing the name and replacing `\_` with `-`. Logging wildcards are the exception as `_` in the category is replaced with `.` instead. Logging categories are commonly class / package names, which are more likely to use `.` rather than `-`.

WARNING: Automatic mapping of the environment variable key to option key may not preserve the intended key

For example `kc.log-level-package.class_name` will become the environment variable key `KC_LOG_LEVEL_PACKAGE_CLASS_NAME`. That will automatically be mapped to `kc.log-level-package.class.name` because `_` in the logging category will be replaced by `.`. Unfortunately this does not match the intent of `kc.log-level-package.class_name`.

You have a couple of options in this case:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@
import java.util.regex.Pattern;
import java.util.stream.Stream;

import org.keycloak.config.LoggingOptions;
import org.keycloak.config.Option;
import org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider;

import io.smallrye.config.ConfigSourceInterceptorContext;
import io.smallrye.config.ConfigValue;

import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX;
Expand All @@ -30,6 +29,7 @@ public class WildcardPropertyMapper<T> extends PropertyMapper<T> {
private final String fromPrefix;
private String toPrefix;
private String toSuffix;
private Character replacementChar = null;

public WildcardPropertyMapper(Option<T> option, String to, BooleanSupplier enabled, String enabledWhen, ValueMapper mapper, String mapFrom, ValueMapper parentMapper,
String paramLabel, boolean mask, BiConsumer<PropertyMapper<T>, ConfigValue> validator,
Expand All @@ -42,6 +42,10 @@ public WildcardPropertyMapper(Option<T> option, String to, BooleanSupplier enabl
throw new IllegalArgumentException("Invalid wildcard from format. Wildcard must be at the end of the option.");
}

if (option == LoggingOptions.LOG_LEVEL_CATEGORY) {
replacementChar = '.';
}

if (to != null) {
if (!to.startsWith(NS_QUARKUS_PREFIX) && !to.startsWith(NS_KEYCLOAK_PREFIX)) {
throw new IllegalArgumentException("Wildcards should map to Quarkus or Keycloak options (option '%s' mapped to '%s'). If not, PropertyMappers logic will need adjusted".formatted(option.getKey(), to));
Expand Down Expand Up @@ -119,7 +123,10 @@ public boolean matchesWildcardOptionName(String name) {

public Optional<String> getKcKeyForEnvKey(String envKey, String transformedKey) {
if (transformedKey.startsWith(fromPrefix)) {
return Optional.ofNullable(getFrom(envKey.substring(fromPrefix.length()).toLowerCase().replace("_", ".")));
if (replacementChar != null) {
return Optional.ofNullable(getFrom(envKey.substring(fromPrefix.length()).toLowerCase().replace('_', replacementChar)));
}
return Optional.of(transformedKey);
}
return Optional.empty();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
import org.hibernate.dialect.PostgreSQLDialect;
import org.junit.Test;
import org.keycloak.quarkus.runtime.Environment;
import org.keycloak.quarkus.runtime.configuration.ConfigArgsConfigSource;
import org.keycloak.quarkus.runtime.configuration.Configuration;
import org.mariadb.jdbc.MariaDbDataSource;
import org.postgresql.xa.PGXADataSource;

import java.util.Map;

import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
Expand Down Expand Up @@ -402,17 +402,18 @@ public void envVarsHandling() {
"db-kind-user-store", "postgres",
"db-url-full-user-store", "jdbc:postgresql://localhost/KEYCLOAK",
"db-username-user-store", "my-username",
"db-kind-my-store", "mariadb",
"db-kind-my.store", "mariadb"
"db-kind-my-store", "mariadb"
));

assertExternalConfig(Map.of(
"quarkus.datasource.\"user-store\".db-kind", "postgresql",
"quarkus.datasource.\"user-store\".jdbc.url", "jdbc:postgresql://localhost/KEYCLOAK",
"quarkus.datasource.\"user-store\".username", "my-username",
"quarkus.datasource.\"my-store\".db-kind", "mariadb",
"quarkus.datasource.\"my.store\".db-kind", "mariadb"
"quarkus.datasource.\"my-store\".db-kind", "mariadb"
));

assertThat(Configuration.getPropertyNames(), hasItem("quarkus.datasource.\"my-store\".db-kind"));
assertThat(Configuration.getPropertyNames(), not(hasItem("quarkus.datasource.\"my.store\".db-kind")));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public void multipleDatasourcesPrint(CLIResult result) {
@WithEnvVars({"KC_DB_KIND_USERS", "postgres", "KC_DB_KIND_MY_AWESOME_CLIENTS", "mariadb"})
@Launch({"build"})
public void specifiedViaEnvVars(CLIResult result) {
result.assertMessage("Multiple datasources are specified: <default>, my.awesome.clients, users");
result.assertMessage("Multiple datasources are specified: <default>, my-awesome-clients, users");
result.assertBuild();
}

Expand Down
Loading
0