Fixing env vars precedence over conf file (#12638)

Closes #12413
This commit is contained in:
Pedro Igor
2022-06-22 10:13:58 -03:00
committed by GitHub
parent 12093753e9
commit 95528e77bb
7 changed files with 50 additions and 10 deletions
@@ -33,7 +33,7 @@ public class Options {
options = PropertyMappers.getMappers().stream()
.filter(m -> !m.isHidden())
.filter(propertyMapper -> Objects.nonNull(propertyMapper.getDescription()))
.map(m -> new Option(m.getFrom(), m.getCategory(), m.isBuildTime(), m.getDescription(), (String) m.getDefaultValue().map(d -> d.toString()).orElse(null), m.getExpectedValues()))
.map(m -> new Option(m.getFrom(), m.getCategory(), m.isBuildTime(), m.getDescription(), (String) m.getDefaultValue().map(Object::toString).orElse(null), m.getExpectedValues()))
.sorted(Comparator.comparing(Option::getKey))
.collect(Collectors.toMap(Option::getKey, o -> o, (o1, o2) -> o1, LinkedHashMap::new)); // Need to ignore duplicate keys??
ProviderManager providerManager = Providers.getProviderManager(Thread.currentThread().getContextClassLoader());
@@ -260,7 +260,7 @@ public final class Picocli {
if (runtimeValue == null && isNotBlank(persistedValue)) {
PropertyMapper mapper = PropertyMappers.getMapper(propertyName);
if (mapper != null && persistedValue.equals(mapper.getDefaultValue().orElse(null))) {
if (mapper != null && persistedValue.equals(mapper.getDefaultValue().map(Object::toString).orElse(null))) {
// same as default
continue;
}
@@ -121,13 +121,15 @@ public class ConfigArgsConfigSource extends PropertiesConfigSource {
properties.put(key, value);
String mappedPropertyName = getMappedPropertyName(key);
properties.put(mappedPropertyName, value);
PropertyMapper mapper = PropertyMappers.getMapper(mappedPropertyName);
PropertyMapper mapper = PropertyMappers.getMapper(key);
if (mapper != null) {
String to = mapper.getTo();
if (to != null) {
properties.put(mapper.getTo(), value);
}
properties.put(mapper.getFrom(), value);
}
}
@@ -18,11 +18,13 @@
package org.keycloak.quarkus.runtime.configuration;
import static io.smallrye.config.common.utils.StringUtil.replaceNonAlphanumericByUnderscores;
import static org.keycloak.quarkus.runtime.configuration.Configuration.getMappedPropertyName;
import java.util.HashMap;
import java.util.Map;
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper;
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
import io.smallrye.config.EnvConfigSource;
public class KcEnvConfigSource extends EnvConfigSource {
@@ -37,9 +39,22 @@ public class KcEnvConfigSource extends EnvConfigSource {
for (Map.Entry<String, String> entry : System.getenv().entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
if (key.startsWith(kcPrefix)) {
properties.put(getMappedPropertyName(key), entry.getValue());
properties.put(key, value);
PropertyMapper mapper = PropertyMappers.getMapper(key);
if (mapper != null) {
String to = mapper.getTo();
if (to != null) {
properties.put(to, value);
}
properties.put(mapper.getFrom(), value);
}
}
}
@@ -54,4 +54,8 @@ public interface KeycloakDistribution {
default void removeProperty(String name) {
throw new RuntimeException("Not implemented");
}
default void setEnvVar(String kc_db_username, String bad) {
throw new RuntimeException("Not implemented");
}
}
@@ -36,7 +36,9 @@ import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.*;
import java.util.function.Consumer;
@@ -77,6 +79,7 @@ public final class RawKeycloakDistribution implements KeycloakDistribution {
private boolean removeBuildOptionsAfterBuild;
private ExecutorService outputExecutor;
private boolean inited = false;
private Map<String, String> envVars = new HashMap<>();
public RawKeycloakDistribution(boolean debug, boolean manualStop, boolean reCreate, boolean removeBuildOptionsAfterBuild) {
this.debug = debug;
@@ -112,6 +115,7 @@ public final class RawKeycloakDistribution implements KeycloakDistribution {
}
if (!manualStop) {
stop();
envVars.clear();
}
}
@@ -132,7 +136,6 @@ public final class RawKeycloakDistribution implements KeycloakDistribution {
keycloak.destroy();
keycloak.waitFor(10, TimeUnit.SECONDS);
exitCode = keycloak.exitValue();
} catch (Exception cause) {
if (Environment.isWindows()) {
try {
@@ -412,6 +415,8 @@ public final class RawKeycloakDistribution implements KeycloakDistribution {
builder.environment().put("KEYCLOAK_ADMIN", "admin");
builder.environment().put("KEYCLOAK_ADMIN_PASSWORD", "admin");
builder.environment().putAll(envVars);
keycloak = builder.start();
}
@@ -425,6 +430,11 @@ public final class RawKeycloakDistribution implements KeycloakDistribution {
updateProperties(properties -> properties.put(key, value), distPath.resolve("conf").resolve("keycloak.conf").toFile());
}
@Override
public void setEnvVar(String key, String value) {
this.envVars.put(key, value);
}
@Override
public void removeProperty(String name) {
updateProperties(new Consumer<Properties>() {
@@ -21,6 +21,7 @@ import org.junit.jupiter.api.Test;
import org.keycloak.it.junit5.extension.CLIResult;
import org.keycloak.it.junit5.extension.DistributionTest;
import org.keycloak.it.junit5.extension.WithDatabase;
import org.keycloak.it.utils.KeycloakDistribution;
import io.quarkus.test.junit.main.Launch;
import io.quarkus.test.junit.main.LaunchResult;
@@ -35,4 +36,12 @@ public class DatabaseOptionsDistTest {
CLIResult cliResult = (CLIResult) result;
cliResult.assertStartedDevMode();
}
@Test
void testEnvVarPrecedenceOverConfFile(KeycloakDistribution distribution) {
distribution.setEnvVar("KC_DB_USERNAME", "bad");
CLIResult result = distribution.run("start-dev");
result.assertMessage("FATAL: password authentication failed for user \"bad\"");
}
}