fix: add a reload period property (#32715)
closes: #23771 Signed-off-by: Steve Hawkins <shawkins@redhat.com>
This commit is contained in:
parent
92e435f192
commit
f0bf290c28
13 changed files with 79 additions and 2 deletions
|
@ -142,6 +142,10 @@ The deprecated `proxy` option was removed. This option was deprecated in {projec
|
||||||
|
|
||||||
The `proxy-trusted-addresses` can be used when the `proxy-headers` option is set to specify a allowlist of trusted proxy addresses. If the proxy address for a given request is not trusted, then the respective proxy header values will not be used.
|
The `proxy-trusted-addresses` can be used when the `proxy-headers` option is set to specify a allowlist of trusted proxy addresses. If the proxy address for a given request is not trusted, then the respective proxy header values will not be used.
|
||||||
|
|
||||||
|
= Option to reload trust and key material added
|
||||||
|
|
||||||
|
The `https-certificates-reload-period` option can be set to define the reloading period of key store, trust store, and certificate files referenced by https-* options. Use -1 to disable reloading. Defaults to 1h (one hour).
|
||||||
|
|
||||||
= Property `origin` in the `UserRepresentation` is deprecated
|
= Property `origin` in the `UserRepresentation` is deprecated
|
||||||
|
|
||||||
The `origin` property in the `UserRepresentation` is deprecated and planned to be removed in future releases.
|
The `origin` property in the `UserRepresentation` is deprecated and planned to be removed in future releases.
|
||||||
|
|
|
@ -85,4 +85,9 @@ NOTE: Management interface properties are inherited from the main HTTP server, i
|
||||||
It means when mTLS is set, it is also enabled for the management interface.
|
It means when mTLS is set, it is also enabled for the management interface.
|
||||||
To override the behavior, use the `https-management-client-auth` property.
|
To override the behavior, use the `https-management-client-auth` property.
|
||||||
|
|
||||||
|
== Certificate and Key Reloading
|
||||||
|
|
||||||
|
By default {project_name} will reload the certificates, keys, and keystores specified in `https-*` options every hour. For environments where your server keys may need frequent rotation, this allows that to happen without a server restart. You may override the default via the `https-certificates-reload-period` option. Interval on which to reload key store, trust store, and certificate files referenced by https-* options.
|
||||||
|
The value may be a java.time.Duration value, an integer number of seconds, or an integer followed by one of the time units [ms, h, m, s, d]. Must be greater than 30 seconds. Use -1 to disable.
|
||||||
|
|
||||||
</@tmpl.guide>
|
</@tmpl.guide>
|
||||||
|
|
|
@ -63,6 +63,12 @@ public class HttpOptions {
|
||||||
.defaultValue(Arrays.asList("TLSv1.3,TLSv1.2"))
|
.defaultValue(Arrays.asList("TLSv1.3,TLSv1.2"))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
public static final Option<String> HTTPS_CERTIFICATES_RELOAD_PERIOD = new OptionBuilder<>("https-certificates-reload-period", String.class)
|
||||||
|
.category(OptionCategory.HTTP)
|
||||||
|
.description("Interval on which to reload key store, trust store, and certificate files referenced by https-* options. May be a java.time.Duration value, an integer number of seconds, or an integer followed by one of [ms, h, m, s, d]. Must be greater than 30 seconds. Use -1 to disable.")
|
||||||
|
.defaultValue("1h")
|
||||||
|
.build();
|
||||||
|
|
||||||
public static final Option<File> HTTPS_CERTIFICATE_FILE = new OptionBuilder<>("https-certificate-file", File.class)
|
public static final Option<File> HTTPS_CERTIFICATE_FILE = new OptionBuilder<>("https-certificate-file", File.class)
|
||||||
.category(OptionCategory.HTTP)
|
.category(OptionCategory.HTTP)
|
||||||
.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.")
|
||||||
|
|
|
@ -68,6 +68,12 @@ public final class HttpPropertyMappers {
|
||||||
.to("quarkus.http.ssl.protocols")
|
.to("quarkus.http.ssl.protocols")
|
||||||
.paramLabel("protocols")
|
.paramLabel("protocols")
|
||||||
.build(),
|
.build(),
|
||||||
|
fromOption(HttpOptions.HTTPS_CERTIFICATES_RELOAD_PERIOD)
|
||||||
|
.to("quarkus.http.ssl.certificate.reload-period")
|
||||||
|
// -1 means no reload
|
||||||
|
.transformer((value, context) -> "-1".equals(value.get()) ? null : value)
|
||||||
|
.paramLabel("reload period")
|
||||||
|
.build(),
|
||||||
fromOption(HttpOptions.HTTPS_CERTIFICATE_FILE)
|
fromOption(HttpOptions.HTTPS_CERTIFICATE_FILE)
|
||||||
.to(QUARKUS_HTTPS_CERT_FILES)
|
.to(QUARKUS_HTTPS_CERT_FILES)
|
||||||
.transformer(HttpPropertyMappers.validatePath(QUARKUS_HTTPS_CERT_FILES))
|
.transformer(HttpPropertyMappers.validatePath(QUARKUS_HTTPS_CERT_FILES))
|
||||||
|
|
|
@ -160,7 +160,12 @@ public class PropertyMapper<T> {
|
||||||
|
|
||||||
// we always fallback to the current value from the property we are mapping
|
// we always fallback to the current value from the property we are mapping
|
||||||
if (transformedValue == null) {
|
if (transformedValue == null) {
|
||||||
return context.proceed(name);
|
return ConfigValue.builder()
|
||||||
|
.withName(name)
|
||||||
|
.withValue(null)
|
||||||
|
.withRawValue(config.getValue())
|
||||||
|
.withConfigSourceName(config.getConfigSourceName())
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
return transformedValue;
|
return transformedValue;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
package org.keycloak.quarkus.runtime.configuration.test;
|
package org.keycloak.quarkus.runtime.configuration.test;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.keycloak.quarkus.runtime.Environment.isWindows;
|
import static org.keycloak.quarkus.runtime.Environment.isWindows;
|
||||||
import static org.keycloak.quarkus.runtime.configuration.ConfigArgsConfigSource.CLI_ARGS;
|
import static org.keycloak.quarkus.runtime.configuration.ConfigArgsConfigSource.CLI_ARGS;
|
||||||
|
@ -475,4 +476,14 @@ public class ConfigurationTest extends AbstractConfigurationTest {
|
||||||
ConfigValue secret = config.getConfigValue("my.secret");
|
ConfigValue secret = config.getConfigValue("my.secret");
|
||||||
assertEquals("secret", secret.getValue());
|
assertEquals("secret", secret.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReloadPeriod() {
|
||||||
|
ConfigArgsConfigSource.setCliArgs("");
|
||||||
|
assertEquals("1h", createConfig().getConfigValue("quarkus.http.ssl.certificate.reload-period").getValue());
|
||||||
|
ConfigArgsConfigSource.setCliArgs("--https-certificates-reload-period=-1");
|
||||||
|
assertNull(createConfig().getConfigValue("quarkus.http.ssl.certificate.reload-period").getValue());
|
||||||
|
ConfigArgsConfigSource.setCliArgs("--https-certificates-reload-period=2h");
|
||||||
|
assertEquals("2h", createConfig().getConfigValue("quarkus.http.ssl.certificate.reload-period").getValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,12 +31,16 @@ import java.util.concurrent.CompletableFuture;
|
||||||
import static io.restassured.RestAssured.when;
|
import static io.restassured.RestAssured.when;
|
||||||
import static org.hamcrest.CoreMatchers.hasItem;
|
import static org.hamcrest.CoreMatchers.hasItem;
|
||||||
import static org.hamcrest.CoreMatchers.not;
|
import static org.hamcrest.CoreMatchers.not;
|
||||||
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
|
import io.quarkus.test.junit.main.Launch;
|
||||||
|
import io.quarkus.test.junit.main.LaunchResult;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Vaclav Muzikar <vmuzikar@redhat.com>
|
* @author Vaclav Muzikar <vmuzikar@redhat.com>
|
||||||
*/
|
*/
|
||||||
@DistributionTest(keepAlive = true)
|
@DistributionTest(keepAlive = true, enableTls = true)
|
||||||
@RawDistOnly(reason = "Containers are immutable")
|
@RawDistOnly(reason = "Containers are immutable")
|
||||||
public class HttpDistTest {
|
public class HttpDistTest {
|
||||||
@Test
|
@Test
|
||||||
|
@ -55,4 +59,10 @@ public class HttpDistTest {
|
||||||
assertThat("Some of the requests should be properly rejected", statusCodes, hasItem(503));
|
assertThat("Some of the requests should be properly rejected", statusCodes, hasItem(503));
|
||||||
assertThat("None of the requests should throw an unhandled exception", statusCodes, not(hasItem(500)));
|
assertThat("None of the requests should throw an unhandled exception", statusCodes, not(hasItem(500)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Launch({"start-dev", "--https-certificates-reload-period=wrong"})
|
||||||
|
public void testHttpCertificateReloadPeriod(LaunchResult result) {
|
||||||
|
assertThat(result.getErrorOutput(), containsString("Text cannot be parsed to a Duration"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,6 +153,11 @@ HTTP(S):
|
||||||
The file path to a server certificate or certificate chain in PEM format.
|
The file path to a server certificate or certificate chain in PEM format.
|
||||||
--https-certificate-key-file <file>
|
--https-certificate-key-file <file>
|
||||||
The file path to a private key in PEM format.
|
The file path to a private key in PEM format.
|
||||||
|
--https-certificates-reload-period <reload period>
|
||||||
|
Interval on which to reload key store, trust store, and certificate files
|
||||||
|
referenced by https-* options. May be a java.time.Duration value, an integer
|
||||||
|
number of seconds, or an integer followed by one of [ms, h, m, s, d]. Must
|
||||||
|
be greater than 30 seconds. Use -1 to disable. Default: 1h.
|
||||||
--https-cipher-suites <ciphers>
|
--https-cipher-suites <ciphers>
|
||||||
The cipher suites to use. If none is given, a reasonable default is selected.
|
The cipher suites to use. If none is given, a reasonable default is selected.
|
||||||
--https-client-auth <auth>
|
--https-client-auth <auth>
|
||||||
|
|
|
@ -188,6 +188,11 @@ HTTP(S):
|
||||||
The file path to a server certificate or certificate chain in PEM format.
|
The file path to a server certificate or certificate chain in PEM format.
|
||||||
--https-certificate-key-file <file>
|
--https-certificate-key-file <file>
|
||||||
The file path to a private key in PEM format.
|
The file path to a private key in PEM format.
|
||||||
|
--https-certificates-reload-period <reload period>
|
||||||
|
Interval on which to reload key store, trust store, and certificate files
|
||||||
|
referenced by https-* options. May be a java.time.Duration value, an integer
|
||||||
|
number of seconds, or an integer followed by one of [ms, h, m, s, d]. Must
|
||||||
|
be greater than 30 seconds. Use -1 to disable. Default: 1h.
|
||||||
--https-cipher-suites <ciphers>
|
--https-cipher-suites <ciphers>
|
||||||
The cipher suites to use. If none is given, a reasonable default is selected.
|
The cipher suites to use. If none is given, a reasonable default is selected.
|
||||||
--https-client-auth <auth>
|
--https-client-auth <auth>
|
||||||
|
|
|
@ -154,6 +154,11 @@ HTTP(S):
|
||||||
The file path to a server certificate or certificate chain in PEM format.
|
The file path to a server certificate or certificate chain in PEM format.
|
||||||
--https-certificate-key-file <file>
|
--https-certificate-key-file <file>
|
||||||
The file path to a private key in PEM format.
|
The file path to a private key in PEM format.
|
||||||
|
--https-certificates-reload-period <reload period>
|
||||||
|
Interval on which to reload key store, trust store, and certificate files
|
||||||
|
referenced by https-* options. May be a java.time.Duration value, an integer
|
||||||
|
number of seconds, or an integer followed by one of [ms, h, m, s, d]. Must
|
||||||
|
be greater than 30 seconds. Use -1 to disable. Default: 1h.
|
||||||
--https-cipher-suites <ciphers>
|
--https-cipher-suites <ciphers>
|
||||||
The cipher suites to use. If none is given, a reasonable default is selected.
|
The cipher suites to use. If none is given, a reasonable default is selected.
|
||||||
--https-client-auth <auth>
|
--https-client-auth <auth>
|
||||||
|
|
|
@ -189,6 +189,11 @@ HTTP(S):
|
||||||
The file path to a server certificate or certificate chain in PEM format.
|
The file path to a server certificate or certificate chain in PEM format.
|
||||||
--https-certificate-key-file <file>
|
--https-certificate-key-file <file>
|
||||||
The file path to a private key in PEM format.
|
The file path to a private key in PEM format.
|
||||||
|
--https-certificates-reload-period <reload period>
|
||||||
|
Interval on which to reload key store, trust store, and certificate files
|
||||||
|
referenced by https-* options. May be a java.time.Duration value, an integer
|
||||||
|
number of seconds, or an integer followed by one of [ms, h, m, s, d]. Must
|
||||||
|
be greater than 30 seconds. Use -1 to disable. Default: 1h.
|
||||||
--https-cipher-suites <ciphers>
|
--https-cipher-suites <ciphers>
|
||||||
The cipher suites to use. If none is given, a reasonable default is selected.
|
The cipher suites to use. If none is given, a reasonable default is selected.
|
||||||
--https-client-auth <auth>
|
--https-client-auth <auth>
|
||||||
|
|
|
@ -136,6 +136,11 @@ HTTP(S):
|
||||||
The file path to a server certificate or certificate chain in PEM format.
|
The file path to a server certificate or certificate chain in PEM format.
|
||||||
--https-certificate-key-file <file>
|
--https-certificate-key-file <file>
|
||||||
The file path to a private key in PEM format.
|
The file path to a private key in PEM format.
|
||||||
|
--https-certificates-reload-period <reload period>
|
||||||
|
Interval on which to reload key store, trust store, and certificate files
|
||||||
|
referenced by https-* options. May be a java.time.Duration value, an integer
|
||||||
|
number of seconds, or an integer followed by one of [ms, h, m, s, d]. Must
|
||||||
|
be greater than 30 seconds. Use -1 to disable. Default: 1h.
|
||||||
--https-cipher-suites <ciphers>
|
--https-cipher-suites <ciphers>
|
||||||
The cipher suites to use. If none is given, a reasonable default is selected.
|
The cipher suites to use. If none is given, a reasonable default is selected.
|
||||||
--https-key-store-file <file>
|
--https-key-store-file <file>
|
||||||
|
|
|
@ -171,6 +171,11 @@ HTTP(S):
|
||||||
The file path to a server certificate or certificate chain in PEM format.
|
The file path to a server certificate or certificate chain in PEM format.
|
||||||
--https-certificate-key-file <file>
|
--https-certificate-key-file <file>
|
||||||
The file path to a private key in PEM format.
|
The file path to a private key in PEM format.
|
||||||
|
--https-certificates-reload-period <reload period>
|
||||||
|
Interval on which to reload key store, trust store, and certificate files
|
||||||
|
referenced by https-* options. May be a java.time.Duration value, an integer
|
||||||
|
number of seconds, or an integer followed by one of [ms, h, m, s, d]. Must
|
||||||
|
be greater than 30 seconds. Use -1 to disable. Default: 1h.
|
||||||
--https-cipher-suites <ciphers>
|
--https-cipher-suites <ciphers>
|
||||||
The cipher suites to use. If none is given, a reasonable default is selected.
|
The cipher suites to use. If none is given, a reasonable default is selected.
|
||||||
--https-key-store-file <file>
|
--https-key-store-file <file>
|
||||||
|
|
Loading…
Reference in a new issue