mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-09 15:02:05 -03:30
fix: rationalizing cli using hidden options vs hard errors (#43945)
closes: #43940 Signed-off-by: Steve Hawkins <shawkins@redhat.com>
This commit is contained in:
parent
39d1fa2825
commit
f7a0bb7cbd
@ -23,6 +23,7 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.keycloak.config.OptionCategory;
|
||||
import org.keycloak.quarkus.runtime.cli.command.AbstractCommand;
|
||||
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper;
|
||||
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
|
||||
import org.keycloak.utils.StringUtil;
|
||||
@ -31,7 +32,6 @@ import picocli.CommandLine;
|
||||
import picocli.CommandLine.Model.ArgGroupSpec;
|
||||
import picocli.CommandLine.Model.OptionSpec;
|
||||
|
||||
import static org.keycloak.quarkus.runtime.cli.OptionRenderer.undecorateDuplicitOptionName;
|
||||
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers.getMapper;
|
||||
import static org.keycloak.utils.StringUtil.removeSuffix;
|
||||
|
||||
@ -44,10 +44,14 @@ public final class Help extends CommandLine.Help {
|
||||
private static final int HELP_WIDTH = 100;
|
||||
private static final String DEFAULT_OPTION_LIST_HEADING = "Options:";
|
||||
private static final String DEFAULT_COMMAND_LIST_HEADING = "Commands:";
|
||||
private static boolean ALL_OPTIONS;
|
||||
|
||||
private boolean all;
|
||||
|
||||
Help(CommandLine.Model.CommandSpec commandSpec, ColorScheme colorScheme) {
|
||||
super(commandSpec, colorScheme);
|
||||
if (commandSpec.userObject() instanceof AbstractCommand ac) {
|
||||
all = ac.isHelpAll();
|
||||
}
|
||||
configureUsageMessage(commandSpec);
|
||||
}
|
||||
|
||||
@ -163,11 +167,11 @@ public final class Help extends CommandLine.Help {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ALL_OPTIONS) {
|
||||
if (all) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String optionName = undecorateDuplicitOptionName(option.longestName());
|
||||
String optionName = option.longestName();
|
||||
|
||||
OptionCategory category = null;
|
||||
if (option.group() != null && option.group().heading() != null) {
|
||||
@ -190,7 +194,4 @@ public final class Help extends CommandLine.Help {
|
||||
return PropertyMappers.isSupported(mapper);
|
||||
}
|
||||
|
||||
public static void setAllOptions(boolean allOptions) {
|
||||
ALL_OPTIONS = allOptions;
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,7 +26,6 @@ import picocli.CommandLine.Help.IParamLabelRenderer;
|
||||
import picocli.CommandLine.Model.OptionSpec;
|
||||
|
||||
import static org.keycloak.quarkus.runtime.cli.Picocli.NO_PARAM_LABEL;
|
||||
import static org.keycloak.utils.StringUtil.removeSuffix;
|
||||
|
||||
import static picocli.CommandLine.Help.Ansi.OFF;
|
||||
|
||||
@ -34,7 +33,6 @@ public class OptionRenderer implements CommandLine.Help.IOptionRenderer {
|
||||
|
||||
private static final String OPTION_NAME_SEPARATOR = ", ";
|
||||
private static final Text EMPTY_TEXT = OFF.text("");
|
||||
public static final String DUPLICIT_OPTION_SUFFIX = " "; // works good (not perfect) for alphabetical sorting with non-duplicit options
|
||||
|
||||
@Override
|
||||
public Text[][] render(OptionSpec option, IParamLabelRenderer paramLabelRenderer, ColorScheme scheme) {
|
||||
@ -65,7 +63,8 @@ public class OptionRenderer implements CommandLine.Help.IOptionRenderer {
|
||||
}
|
||||
|
||||
private Text createLongName(OptionSpec option, ColorScheme scheme) {
|
||||
Text name = scheme.optionText(undecorateDuplicitOptionName(option.longestName()));
|
||||
String longestName = option.longestName();
|
||||
Text name = scheme.optionText(longestName);
|
||||
String paramLabel = formatParamLabel(option);
|
||||
|
||||
if (StringUtil.isNotBlank(paramLabel) && !NO_PARAM_LABEL.equals(paramLabel) && !option.usageHelp() && !option.versionHelp()) {
|
||||
@ -85,11 +84,4 @@ public class OptionRenderer implements CommandLine.Help.IOptionRenderer {
|
||||
return "<" + label + ">";
|
||||
}
|
||||
|
||||
public static String decorateDuplicitOptionName(String name) {
|
||||
return name + DUPLICIT_OPTION_SUFFIX;
|
||||
}
|
||||
|
||||
public static String undecorateDuplicitOptionName(String name) {
|
||||
return removeSuffix(name, DUPLICIT_OPTION_SUFFIX);
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,6 +27,7 @@ import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
@ -42,7 +43,7 @@ import org.keycloak.quarkus.runtime.Messages;
|
||||
import org.keycloak.quarkus.runtime.cli.command.AbstractAutoBuildCommand;
|
||||
import org.keycloak.quarkus.runtime.cli.command.AbstractCommand;
|
||||
import org.keycloak.quarkus.runtime.cli.command.AbstractNonServerCommand;
|
||||
import org.keycloak.quarkus.runtime.cli.command.HelpAllMixin;
|
||||
import org.keycloak.quarkus.runtime.cli.command.Build;
|
||||
import org.keycloak.quarkus.runtime.cli.command.Main;
|
||||
import org.keycloak.quarkus.runtime.configuration.ConfigArgsConfigSource;
|
||||
import org.keycloak.quarkus.runtime.configuration.Configuration;
|
||||
@ -76,9 +77,6 @@ import picocli.CommandLine.ParseResult;
|
||||
import static java.lang.String.format;
|
||||
|
||||
import static org.keycloak.quarkus.runtime.Environment.getProviderFiles;
|
||||
import static org.keycloak.quarkus.runtime.Environment.isRebuildCheck;
|
||||
import static org.keycloak.quarkus.runtime.cli.OptionRenderer.decorateDuplicitOptionName;
|
||||
import static org.keycloak.quarkus.runtime.cli.command.AbstractAutoBuildCommand.OPTIMIZED_BUILD_OPTION_LONG;
|
||||
import static org.keycloak.quarkus.runtime.configuration.Configuration.isUserModifiable;
|
||||
import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX;
|
||||
|
||||
@ -93,9 +91,7 @@ public class Picocli {
|
||||
public static final String ARG_SHORT_PREFIX = "-";
|
||||
public static final String NO_PARAM_LABEL = "none";
|
||||
|
||||
private static class IncludeOptions {
|
||||
boolean includeRuntime;
|
||||
boolean includeBuildTime;
|
||||
private record IncludeOptions(boolean includeRuntime, boolean includeBuildTime) {
|
||||
}
|
||||
|
||||
private final ExecutionExceptionHandler errorHandler = new ExecutionExceptionHandler();
|
||||
@ -133,15 +129,15 @@ public class Picocli {
|
||||
|
||||
CommandLine cl = commandLineList.get(commandLineList.size() - 1);
|
||||
|
||||
AbstractCommand currentCommand = null;
|
||||
AbstractCommand currentCommand;
|
||||
if (cl.getCommand() instanceof AbstractCommand ac) {
|
||||
currentCommand = ac;
|
||||
} else {
|
||||
currentCommand = null;
|
||||
}
|
||||
initConfig(cliArgs, currentCommand);
|
||||
initConfig(currentCommand);
|
||||
|
||||
if (!unrecognizedArgs.isEmpty()) {
|
||||
IncludeOptions options = Optional.ofNullable(currentCommand).map(c -> getIncludeOptions(cliArgs, c, c.getName())).orElse(new IncludeOptions());
|
||||
Set<OptionCategory> allowedCategories = Set.copyOf(Optional.ofNullable(currentCommand).map(AbstractCommand::getOptionCategories).orElse(List.of()));
|
||||
// TODO: further refactor this as these args should be the source for ConfigArgsConfigSource
|
||||
unrecognizedArgs.removeIf(arg -> {
|
||||
boolean hasArg = false;
|
||||
@ -151,11 +147,8 @@ public class Picocli {
|
||||
}
|
||||
PropertyMapper<?> mapper = PropertyMappers.getMapperByCliKey(arg);
|
||||
if (mapper != null) {
|
||||
if (!allowedCategories.contains(mapper.getCategory()) || (mapper.isBuildTime() && !options.includeBuildTime) || (mapper.isRunTime() && !options.includeRuntime)) {
|
||||
return false;
|
||||
}
|
||||
if (!hasArg) {
|
||||
addCommandOptions(cliArgs, cl);
|
||||
addCommandOptions(cl, currentCommand);
|
||||
throw new MissingParameterException(cl, cl.getCommandSpec().optionsMap().get(arg), null);
|
||||
}
|
||||
return true;
|
||||
@ -163,13 +156,13 @@ public class Picocli {
|
||||
return false;
|
||||
});
|
||||
if (!unrecognizedArgs.isEmpty()) {
|
||||
addCommandOptions(cliArgs, cl);
|
||||
addCommandOptions(cl, currentCommand);
|
||||
throw new KcUnmatchedArgumentException(cl, unrecognizedArgs);
|
||||
}
|
||||
}
|
||||
|
||||
if (isHelpRequested(result)) {
|
||||
addCommandOptions(cliArgs, cl);
|
||||
addCommandOptions(cl, currentCommand);
|
||||
}
|
||||
|
||||
// ParseResult retain memory. Clear it, so it's not on the stack while the command runs
|
||||
@ -219,17 +212,15 @@ public class Picocli {
|
||||
|
||||
/**
|
||||
* Additional validation and handling of deprecated options
|
||||
*
|
||||
* @param cliArgs
|
||||
* @param abstractCommand
|
||||
*/
|
||||
public void validateConfig(List<String> cliArgs, AbstractCommand abstractCommand) {
|
||||
if (cliArgs.contains(OPTIMIZED_BUILD_OPTION_LONG) && !wasBuildEverRun()) {
|
||||
public void validateConfig() {
|
||||
AbstractCommand abstractCommand = this.getParsedCommand().orElseThrow();
|
||||
if (abstractCommand.isOptimized() && !wasBuildEverRun()) {
|
||||
throw new PropertyException(Messages.optimizedUsedForFirstStartup());
|
||||
}
|
||||
warnOnDuplicatedOptionsInCli();
|
||||
|
||||
IncludeOptions options = getIncludeOptions(cliArgs, abstractCommand, abstractCommand.getName());
|
||||
IncludeOptions options = getIncludeOptions(abstractCommand);
|
||||
|
||||
if (!options.includeBuildTime && !options.includeRuntime) {
|
||||
return;
|
||||
@ -249,6 +240,7 @@ public class Picocli {
|
||||
final Set<String> deprecatedInUse = new LinkedHashSet<>();
|
||||
final Set<String> missingOption = new LinkedHashSet<>();
|
||||
final Set<String> ambiguousSpi = new LinkedHashSet<>();
|
||||
final Set<String> unnecessary = new LinkedHashSet<>();
|
||||
final LinkedHashMap<String, String> secondClassOptions = new LinkedHashMap<>();
|
||||
|
||||
final Set<PropertyMapper<?>> disabledMappers = new HashSet<>();
|
||||
@ -259,8 +251,6 @@ public class Picocli {
|
||||
disabledMappers.addAll(PropertyMappers.getDisabledRuntimeMappers().values());
|
||||
}
|
||||
|
||||
var categories = new HashSet<>(abstractCommand.getOptionCategories());
|
||||
|
||||
// first validate the advertised property names
|
||||
// - this allows for efficient resolution of wildcard values and checking spi options
|
||||
Configuration.getPropertyNames().forEach(name -> {
|
||||
@ -277,37 +267,26 @@ public class Picocli {
|
||||
if (mapper == null) {
|
||||
return; // TODO: need to look for disabled Wildcard mappers
|
||||
}
|
||||
String from = mapper.forKey(name).getFrom();
|
||||
if (!name.equals(from)) {
|
||||
var forKey = mapper.forKey(name);
|
||||
if (!name.equals(forKey.getFrom())) {
|
||||
ConfigValue value = getUnmappedValue(name);
|
||||
if (value.getValue() != null && isUserModifiable(value)) {
|
||||
secondClassOptions.put(name, from);
|
||||
secondClassOptions.put(name, forKey.getFrom());
|
||||
}
|
||||
}
|
||||
if (!mapper.hasWildcard()) {
|
||||
return; // non-wildcard options will be validated in the next pass
|
||||
}
|
||||
if (!categories.contains(mapper.getCategory())) {
|
||||
return; // not of interest to this command
|
||||
// TODO: due to picking values up from the env and auto-builds, this probably isn't correct
|
||||
// - the same issue exists with the second pass
|
||||
}
|
||||
validateProperty(abstractCommand, options, ignoredRunTime, disabledBuildTime, disabledRunTime,
|
||||
deprecatedInUse, missingOption, disabledMappers, mapper, from);
|
||||
deprecatedInUse, missingOption, disabledMappers.contains(mapper), forKey, unnecessary);
|
||||
});
|
||||
|
||||
// second pass validate any property mapper not seen in the first pass
|
||||
// - this will catch required values, anything missing from the property names
|
||||
List<PropertyMapper<?>> mappers = new ArrayList<>();
|
||||
for (OptionCategory category : categories) {
|
||||
Optional.ofNullable(PropertyMappers.getRuntimeMappers().get(category)).ifPresent(mappers::addAll);
|
||||
Optional.ofNullable(PropertyMappers.getBuildTimeMappers().get(category)).ifPresent(mappers::addAll);
|
||||
}
|
||||
|
||||
for (PropertyMapper<?> mapper : mappers) {
|
||||
// - this will catch required values, anything missing from the property names, or disabled
|
||||
for (PropertyMapper<?> mapper : PropertyMappers.getMappers()) {
|
||||
if (!mapper.hasWildcard()) {
|
||||
validateProperty(abstractCommand, options, ignoredRunTime, disabledBuildTime, disabledRunTime,
|
||||
deprecatedInUse, missingOption, disabledMappers, mapper, mapper.getFrom());
|
||||
deprecatedInUse, missingOption, disabledMappers.contains(mapper), mapper, unnecessary);
|
||||
}
|
||||
}
|
||||
|
||||
@ -317,7 +296,7 @@ public class Picocli {
|
||||
for (PropertyMapper<?> mapper : disabledMappers) {
|
||||
if (!mapper.hasWildcard()) {
|
||||
validateProperty(abstractCommand, options, ignoredRunTime, disabledBuildTime, disabledRunTime,
|
||||
deprecatedInUse, missingOption, disabledMappers, mapper, mapper.getFrom());
|
||||
deprecatedInUse, missingOption, disabledMappers.contains(mapper), mapper, unnecessary);
|
||||
}
|
||||
}
|
||||
|
||||
@ -344,6 +323,9 @@ public class Picocli {
|
||||
secondClassOptions.forEach((key, firstClass) -> {
|
||||
warn("Please use the first-class option `%s` instead of `%s`".formatted(firstClass, key));
|
||||
});
|
||||
if (!unnecessary.isEmpty()) {
|
||||
info("The following options were specified, but are typically not relevant for this command: " + String.join("\n", unnecessary));
|
||||
}
|
||||
} finally {
|
||||
DisabledMappersInterceptor.enable(disabledMappersInterceptorEnabled);
|
||||
}
|
||||
@ -402,38 +384,14 @@ public class Picocli {
|
||||
private void validateProperty(AbstractCommand abstractCommand, IncludeOptions options,
|
||||
final List<String> ignoredRunTime, final Set<String> disabledBuildTime, final Set<String> disabledRunTime,
|
||||
final Set<String> deprecatedInUse, final Set<String> missingOption,
|
||||
final Set<PropertyMapper<?>> disabledMappers, PropertyMapper<?> mapper, String from) {
|
||||
boolean disabled, PropertyMapper<?> mapper, final Set<String> unnecessary) {
|
||||
if (mapper.isBuildTime() && !options.includeBuildTime) {
|
||||
return; // no need to validate as we've already checked for changes in the build time state
|
||||
}
|
||||
|
||||
ConfigValue configValue = getUnmappedValue(from);
|
||||
ConfigValue configValue = getUnmappedValue(mapper.getFrom());
|
||||
String configValueStr = configValue.getValue();
|
||||
|
||||
// don't consider missing or anything below standard env properties
|
||||
if (configValueStr != null && !isUserModifiable(configValue)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (disabledMappers.contains(mapper)) {
|
||||
// add an error message if there's a value, no enabled propertymapper, and it's not a cli value
|
||||
// as some cli options may be directly on the command and not
|
||||
// backed by a property mapper - if they are disabled that should have already been handled as
|
||||
// an unrecognized arg
|
||||
if (configValueStr != null && PropertyMappers.getMapper(from) == null
|
||||
&& !PropertyMapper.isCliOption(configValue)) {
|
||||
handleDisabled(mapper.isRunTime() ? disabledRunTime : disabledBuildTime, mapper);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (mapper.isRunTime() && !options.includeRuntime) {
|
||||
if (configValueStr != null) {
|
||||
ignoredRunTime.add(mapper.getFrom());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (configValueStr == null) {
|
||||
if (mapper.isRequired()) {
|
||||
handleRequired(missingOption, mapper);
|
||||
@ -441,9 +399,33 @@ public class Picocli {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isUserModifiable(configValue)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (disabled) {
|
||||
// add an error message if no enabled propertymapper, and it's not a cli value
|
||||
// as some cli options may be directly on the command and not backed by a property mapper
|
||||
// - if they are disabled that should have already been handled as an unrecognized arg
|
||||
if (PropertyMappers.getMapper(mapper.getFrom()) == null
|
||||
&& !PropertyMapper.isCliOption(configValue)) {
|
||||
handleDisabled(mapper.isRunTime() ? disabledRunTime : disabledBuildTime, mapper);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (mapper.isRunTime() && !options.includeRuntime) {
|
||||
ignoredRunTime.add(mapper.getFrom());
|
||||
return;
|
||||
}
|
||||
|
||||
mapper.validate(configValue);
|
||||
|
||||
mapper.getDeprecatedMetadata().ifPresent(metadata -> handleDeprecated(deprecatedInUse, mapper, configValueStr, metadata));
|
||||
|
||||
if (mapper.isRunTime() && PropertyMapper.isCliOption(configValue) && abstractCommand.isHiddenCategory(mapper.getCategory())) {
|
||||
unnecessary.add(mapper.getCliFormat());
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkRuntimeSpiOptions(String key, final List<String> ignoredRunTime) {
|
||||
@ -656,96 +638,63 @@ public class Picocli {
|
||||
return new PrintWriter(System.out, true);
|
||||
}
|
||||
|
||||
private IncludeOptions getIncludeOptions(List<String> cliArgs, AbstractCommand abstractCommand, String commandName) {
|
||||
IncludeOptions result = new IncludeOptions();
|
||||
private IncludeOptions getIncludeOptions(AbstractCommand abstractCommand) {
|
||||
if (abstractCommand == null) {
|
||||
return result;
|
||||
return new IncludeOptions(false, false);
|
||||
}
|
||||
result.includeRuntime = abstractCommand.includeRuntime();
|
||||
result.includeBuildTime = abstractCommand.includeBuildTime();
|
||||
|
||||
if (!result.includeBuildTime && !result.includeRuntime) {
|
||||
return result;
|
||||
} else if (result.includeRuntime && !result.includeBuildTime) {
|
||||
result.includeBuildTime = !cliArgs.contains(OPTIMIZED_BUILD_OPTION_LONG);
|
||||
} else if (result.includeBuildTime && !result.includeRuntime) {
|
||||
result.includeRuntime = isRebuildCheck();
|
||||
}
|
||||
return result;
|
||||
boolean autoBuild = abstractCommand instanceof AbstractAutoBuildCommand;
|
||||
boolean includeBuildTime = abstractCommand instanceof Build || (autoBuild && !abstractCommand.isOptimized());
|
||||
return new IncludeOptions(autoBuild, includeBuildTime);
|
||||
}
|
||||
|
||||
private void addCommandOptions(List<String> cliArgs, CommandLine command) {
|
||||
if (command != null && command.getCommand() instanceof AbstractCommand) {
|
||||
IncludeOptions options = getIncludeOptions(cliArgs, command.getCommand(), command.getCommandName());
|
||||
private void addCommandOptions(CommandLine command, AbstractCommand ac) {
|
||||
IncludeOptions options = getIncludeOptions(ac);
|
||||
|
||||
if (!options.includeBuildTime && !options.includeRuntime) {
|
||||
return;
|
||||
}
|
||||
|
||||
addOptionsToCli(command, options);
|
||||
if (!options.includeBuildTime && !options.includeRuntime) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void addOptionsToCli(CommandLine commandLine, IncludeOptions includeOptions) {
|
||||
final Map<OptionCategory, List<PropertyMapper<?>>> mappers = new EnumMap<>(OptionCategory.class);
|
||||
|
||||
// Since we can't run sanitizeDisabledMappers sooner, PropertyMappers.getRuntime|BuildTimeMappers() at this point
|
||||
// contain both enabled and disabled mappers. Actual filtering is done later (help command, validations etc.).
|
||||
if (includeOptions.includeRuntime) {
|
||||
mappers.putAll(PropertyMappers.getRuntimeMappers());
|
||||
}
|
||||
PropertyMappers.getRuntimeMappers().entrySet().forEach(e -> mappers.put(e.getKey(), new ArrayList<>(e.getValue())));
|
||||
PropertyMappers.getBuildTimeMappers().entrySet().forEach(e -> mappers.computeIfAbsent(e.getKey(), category -> new ArrayList<>()).addAll(e.getValue()));
|
||||
|
||||
if (includeOptions.includeBuildTime) {
|
||||
combinePropertyMappers(mappers, PropertyMappers.getBuildTimeMappers());
|
||||
}
|
||||
|
||||
addMappedOptionsToArgGroups(commandLine, mappers);
|
||||
addMappedOptionsToArgGroups(command, mappers, ac, options);
|
||||
}
|
||||
|
||||
private static <T extends Map<OptionCategory, List<PropertyMapper<?>>>> void combinePropertyMappers(T origMappers, T additionalMappers) {
|
||||
for (var entry : additionalMappers.entrySet()) {
|
||||
final List<PropertyMapper<?>> result = origMappers.getOrDefault(entry.getKey(), new ArrayList<>());
|
||||
result.addAll(entry.getValue());
|
||||
origMappers.put(entry.getKey(), result);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addMappedOptionsToArgGroups(CommandLine commandLine, Map<OptionCategory, List<PropertyMapper<?>>> propertyMappers) {
|
||||
private static void addMappedOptionsToArgGroups(CommandLine commandLine, Map<OptionCategory, List<PropertyMapper<?>>> propertyMappers, AbstractCommand ac, IncludeOptions options) {
|
||||
CommandSpec cSpec = commandLine.getCommandSpec();
|
||||
for (OptionCategory category : ((AbstractCommand) commandLine.getCommand()).getOptionCategories()) {
|
||||
List<PropertyMapper<?>> mappersInCategory = propertyMappers.get(category);
|
||||
|
||||
if (mappersInCategory == null) {
|
||||
//picocli raises an exception when an ArgGroup is empty, so ignore it when no mappings found for a category.
|
||||
continue;
|
||||
}
|
||||
for (Entry<OptionCategory, List<PropertyMapper<?>>> entry : propertyMappers.entrySet()) {
|
||||
Set<String> names = new HashSet<String>();
|
||||
OptionCategory category = entry.getKey();
|
||||
|
||||
ArgGroupSpec.Builder argGroupBuilder = ArgGroupSpec.builder()
|
||||
.heading(category.getHeading() + ":")
|
||||
.order(category.getOrder())
|
||||
.validate(false);
|
||||
|
||||
final Set<String> alreadyPresentArgs = new HashSet<>();
|
||||
|
||||
for (PropertyMapper<?> mapper : mappersInCategory) {
|
||||
for (PropertyMapper<?> mapper : entry.getValue()) {
|
||||
String name = mapper.getCliFormat();
|
||||
// Picocli doesn't allow to have multiple options with the same name. We need this in help-all which also prints
|
||||
// currently disabled options which might have a duplicate among enabled options. This is to register the disabled
|
||||
// options with a unique name in Picocli. To keep it simple, it adds just a suffix to the options, i.e. there cannot
|
||||
// be more that 1 disabled option with a unique name.
|
||||
if (cSpec.optionsMap().containsKey(name)) {
|
||||
name = decorateDuplicitOptionName(name);
|
||||
|
||||
boolean hidden = mapper.isHidden() || ac.isHiddenCategory(mapper.getCategory())
|
||||
|| (!options.includeBuildTime && mapper.isBuildTime())
|
||||
|| (!options.includeRuntime && mapper.isRunTime());
|
||||
|
||||
if (hidden && ac.isHelpAll()) {
|
||||
continue; // doesn't need defined
|
||||
}
|
||||
|
||||
if (cSpec.optionsMap().containsKey(name) || alreadyPresentArgs.contains(name)) {
|
||||
//when key is already added, don't add.
|
||||
continue;
|
||||
if (cSpec.optionsMap().containsKey(name)) {
|
||||
continue; // command is dominant
|
||||
}
|
||||
|
||||
if (ac.isHelpAll() && !names.add(name)) {
|
||||
continue; // we sometimes duplicate mappers within the same command
|
||||
}
|
||||
|
||||
OptionSpec.Builder optBuilder = OptionSpec.builder(name)
|
||||
.description(getDecoratedOptionDescription(mapper))
|
||||
.completionCandidates(() -> mapper.getExpectedValues().iterator())
|
||||
.hidden(mapper.isHidden());
|
||||
.hidden(hidden);
|
||||
|
||||
if (mapper.getParamLabel() != null) {
|
||||
optBuilder.paramLabel(mapper.getParamLabel());
|
||||
@ -770,8 +719,6 @@ public class Picocli {
|
||||
optBuilder.type(String.class);
|
||||
}
|
||||
|
||||
alreadyPresentArgs.add(name);
|
||||
|
||||
argGroupBuilder.addArg(optBuilder.build());
|
||||
}
|
||||
|
||||
@ -938,14 +885,14 @@ public class Picocli {
|
||||
QuarkusEntryPoint.main();
|
||||
}
|
||||
|
||||
public void initConfig(List<String> cliArgs, AbstractCommand command) {
|
||||
public void initConfig(AbstractCommand command) {
|
||||
if (Configuration.isInitialized()) {
|
||||
throw new IllegalStateException("Config should not be initialized until profile is determined");
|
||||
}
|
||||
this.parsedCommand = Optional.ofNullable(command);
|
||||
|
||||
if (!Environment.isRebuilt() && command instanceof AbstractAutoBuildCommand
|
||||
&& !cliArgs.contains(OPTIMIZED_BUILD_OPTION_LONG)) {
|
||||
&& !command.isOptimized()) {
|
||||
Environment.setRebuildCheck(true);
|
||||
}
|
||||
|
||||
@ -953,7 +900,7 @@ public class Picocli {
|
||||
.or(() -> parsedCommand.map(AbstractCommand::getInitProfile)).orElse(Environment.PROD_PROFILE_VALUE);
|
||||
|
||||
Environment.setProfile(profile);
|
||||
if (!cliArgs.contains(HelpAllMixin.HELP_ALL_OPTION)) {
|
||||
if (parsedCommand.filter(AbstractCommand::isHelpAll).isEmpty()) {
|
||||
parsedCommand.ifPresent(PropertyMappers::sanitizeDisabledMappers);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,10 +3,8 @@ package org.keycloak.quarkus.runtime.cli;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.keycloak.quarkus.runtime.cli.command.AbstractCommand;
|
||||
import org.keycloak.quarkus.runtime.cli.command.Start;
|
||||
import org.keycloak.quarkus.runtime.configuration.KcUnmatchedArgumentException;
|
||||
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper;
|
||||
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
|
||||
@ -22,8 +20,6 @@ import picocli.CommandLine.UnmatchedArgumentException;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
import static org.keycloak.quarkus.runtime.cli.command.AbstractAutoBuildCommand.OPTIMIZED_BUILD_OPTION_LONG;
|
||||
|
||||
public class ShortErrorMessageHandler implements IParameterExceptionHandler {
|
||||
|
||||
@Override
|
||||
@ -59,17 +55,8 @@ public class ShortErrorMessageHandler implements IParameterExceptionHandler {
|
||||
errorMessage = "Unknown option: '" + cliKey + "'";
|
||||
}
|
||||
} else {
|
||||
AbstractCommand command = cmd.getCommand();
|
||||
if (!command.getOptionCategories().contains(mapper.getCategory())) {
|
||||
errorMessage = format("Option: '%s' not valid for command %s", cliKey, cmd.getCommandName());
|
||||
} else {
|
||||
if (Stream.of(args).anyMatch(OPTIMIZED_BUILD_OPTION_LONG::equals) && mapper.isBuildTime() && Start.NAME.equals(cmd.getCommandName())) {
|
||||
errorMessage = format("Build time option: '%s' not usable with pre-built image and --optimized", cliKey);
|
||||
} else {
|
||||
final var optionType = mapper.isRunTime() ? "Run time" : "Build time";
|
||||
errorMessage = format("%s option: '%s' not usable with %s", optionType, cliKey, cmd.getCommandName());
|
||||
}
|
||||
}
|
||||
final var optionType = mapper.isRunTime() ? "Run time" : "Build time";
|
||||
errorMessage = format("%s option: '%s' not usable with %s", optionType, cliKey, cmd.getCommandName());
|
||||
}
|
||||
} else if (ex instanceof MissingParameterException mpe) {
|
||||
if (mpe.getMissing().size() == 1) {
|
||||
|
||||
@ -18,14 +18,11 @@
|
||||
package org.keycloak.quarkus.runtime.cli.command;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.keycloak.config.OptionCategory;
|
||||
import org.keycloak.quarkus.runtime.Environment;
|
||||
import org.keycloak.quarkus.runtime.cli.Picocli;
|
||||
import org.keycloak.quarkus.runtime.configuration.ConfigArgsConfigSource;
|
||||
@ -101,7 +98,7 @@ public abstract class AbstractAutoBuildCommand extends AbstractCommand {
|
||||
}
|
||||
}
|
||||
|
||||
public void directBuild() {
|
||||
void directBuild() {
|
||||
Build build = new Build();
|
||||
build.dryRunMixin = this.dryRunMixin;
|
||||
build.setPicocli(picocli);
|
||||
@ -148,13 +145,15 @@ public abstract class AbstractAutoBuildCommand extends AbstractCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OptionCategory> getOptionCategories() {
|
||||
EnumSet<OptionCategory> excludedCategories = excludedCategories();
|
||||
return super.getOptionCategories().stream().filter(optionCategory -> !excludedCategories.contains(optionCategory)).collect(Collectors.toList());
|
||||
public boolean isHelpAll() {
|
||||
return helpAllMixin != null ? helpAllMixin.allOptions : false;
|
||||
}
|
||||
|
||||
protected EnumSet<OptionCategory> excludedCategories() {
|
||||
return EnumSet.of(OptionCategory.IMPORT, OptionCategory.EXPORT);
|
||||
abstract protected OptimizedMixin getOptimizedMixin();
|
||||
|
||||
@Override
|
||||
public boolean isOptimized() {
|
||||
return Optional.ofNullable(getOptimizedMixin()).map(o -> o.optimized).orElse(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -17,15 +17,12 @@
|
||||
|
||||
package org.keycloak.quarkus.runtime.cli.command;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.keycloak.config.OptionCategory;
|
||||
import org.keycloak.quarkus.runtime.Environment;
|
||||
import org.keycloak.quarkus.runtime.cli.Picocli;
|
||||
import org.keycloak.quarkus.runtime.configuration.ConfigArgsConfigSource;
|
||||
import org.keycloak.quarkus.runtime.configuration.PersistedConfigSource;
|
||||
|
||||
import picocli.CommandLine;
|
||||
@ -91,28 +88,15 @@ public abstract class AbstractCommand implements Callable<Integer> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this command should include runtime options for the CLI.
|
||||
* @param category
|
||||
* @return true if runtime options for the given category should be hidden from the cli
|
||||
*/
|
||||
public boolean includeRuntime() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this command should include build time options for the CLI.
|
||||
*/
|
||||
public boolean includeBuildTime() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all option categories which are available for this command.
|
||||
*/
|
||||
public List<OptionCategory> getOptionCategories() {
|
||||
return Arrays.asList(OptionCategory.values());
|
||||
public boolean isHiddenCategory(OptionCategory category) {
|
||||
return category == OptionCategory.IMPORT || category == OptionCategory.EXPORT;
|
||||
}
|
||||
|
||||
protected void validateConfig() {
|
||||
picocli.validateConfig(ConfigArgsConfigSource.getAllCliArgs(), this);
|
||||
picocli.validateConfig();
|
||||
}
|
||||
|
||||
public abstract String getName();
|
||||
@ -140,6 +124,18 @@ public abstract class AbstractCommand implements Callable<Integer> {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if a form of help all was used. Only valid if this is the parsed command.
|
||||
*/
|
||||
public abstract boolean isHelpAll();
|
||||
|
||||
/**
|
||||
* @return true if --optimized was used. Only valid if this is the parsed command.
|
||||
*/
|
||||
public boolean isOptimized() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls whether the command actually starts the server
|
||||
*/
|
||||
|
||||
@ -17,8 +17,7 @@
|
||||
|
||||
package org.keycloak.quarkus.runtime.cli.command;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import org.keycloak.config.OptionCategory;
|
||||
import org.keycloak.quarkus.runtime.Environment;
|
||||
@ -31,30 +30,26 @@ public abstract class AbstractNonServerCommand extends AbstractAutoBuildCommand
|
||||
@CommandLine.Mixin
|
||||
OptimizedMixin optimizedMixin = new OptimizedMixin();
|
||||
|
||||
private static EnumSet<OptionCategory> hidden = EnumSet.of(OptionCategory.HTTP, OptionCategory.HTTP_ACCESS_LOG,
|
||||
OptionCategory.PROXY, OptionCategory.HOSTNAME_V1, OptionCategory.HOSTNAME_V2, OptionCategory.METRICS,
|
||||
OptionCategory.SECURITY, OptionCategory.CACHE, OptionCategory.HEALTH, OptionCategory.MANAGEMENT);
|
||||
|
||||
@Override
|
||||
public String getDefaultProfile() {
|
||||
return Environment.NON_SERVER_MODE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OptionCategory> getOptionCategories() {
|
||||
return super.getOptionCategories().stream().filter(optionCategory ->
|
||||
optionCategory != OptionCategory.HTTP &&
|
||||
optionCategory != OptionCategory.PROXY &&
|
||||
optionCategory != OptionCategory.HOSTNAME_V1 &&
|
||||
optionCategory != OptionCategory.HOSTNAME_V2 &&
|
||||
optionCategory != OptionCategory.METRICS &&
|
||||
optionCategory != OptionCategory.SECURITY &&
|
||||
optionCategory != OptionCategory.CACHE &&
|
||||
optionCategory != OptionCategory.HEALTH).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean includeRuntime() {
|
||||
return true;
|
||||
public boolean isHiddenCategory(OptionCategory category) {
|
||||
return super.isHiddenCategory(category) || hidden.contains(category);
|
||||
}
|
||||
|
||||
public void onStart(QuarkusKeycloakApplication application) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OptimizedMixin getOptimizedMixin() {
|
||||
return optimizedMixin;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -101,4 +101,9 @@ public abstract class AbstractUpdatesCommand extends AbstractAutoBuildCommand {
|
||||
Config.init(configProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OptimizedMixin getOptimizedMixin() {
|
||||
return optimizedMixin;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -17,8 +17,6 @@
|
||||
|
||||
package org.keycloak.quarkus.runtime.cli.command;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
import org.keycloak.common.util.IoUtils;
|
||||
import org.keycloak.config.BootstrapAdminOptions;
|
||||
import org.keycloak.config.OptionCategory;
|
||||
@ -109,8 +107,8 @@ public class BootstrapAdminService extends AbstractNonServerCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EnumSet<OptionCategory> excludedCategories() {
|
||||
return EnumSet.of(OptionCategory.IMPORT, OptionCategory.EXPORT, OptionCategory.BOOTSTRAP_ADMIN);
|
||||
public boolean isHiddenCategory(OptionCategory category) {
|
||||
return category == OptionCategory.BOOTSTRAP_ADMIN || super.isHiddenCategory(category);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -17,8 +17,6 @@
|
||||
|
||||
package org.keycloak.quarkus.runtime.cli.command;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
import org.keycloak.common.util.IoUtils;
|
||||
import org.keycloak.config.BootstrapAdminOptions;
|
||||
import org.keycloak.config.OptionCategory;
|
||||
@ -109,8 +107,8 @@ public class BootstrapAdminUser extends AbstractNonServerCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EnumSet<OptionCategory> excludedCategories() {
|
||||
return EnumSet.of(OptionCategory.IMPORT, OptionCategory.EXPORT, OptionCategory.BOOTSTRAP_ADMIN);
|
||||
public boolean isHiddenCategory(OptionCategory category) {
|
||||
return category == OptionCategory.BOOTSTRAP_ADMIN || super.isHiddenCategory(category);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -106,11 +106,6 @@ public final class Build extends AbstractCommand {
|
||||
.ifPresent(s -> System.setProperty(QUARKUS_REMOVED_ARTIFACTS_PROPERTY, s));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean includeBuildTime() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void checkProfileAndDb() {
|
||||
if (Environment.isDevProfile()) {
|
||||
String cmd = picocli.getParsedCommand().map(AbstractCommand::getName).orElse(getName());
|
||||
@ -149,4 +144,10 @@ public final class Build extends AbstractCommand {
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHelpAll() {
|
||||
return helpAllMixin != null ? helpAllMixin.allOptions : false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -17,8 +17,6 @@
|
||||
|
||||
package org.keycloak.quarkus.runtime.cli.command;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
import org.keycloak.config.OptionCategory;
|
||||
import org.keycloak.exportimport.ExportImportConfig;
|
||||
|
||||
@ -44,8 +42,11 @@ public final class Export extends AbstractNonServerCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EnumSet<OptionCategory> excludedCategories() {
|
||||
return EnumSet.of(OptionCategory.IMPORT);
|
||||
public boolean isHiddenCategory(OptionCategory category) {
|
||||
if (category == OptionCategory.EXPORT) {
|
||||
return false;
|
||||
}
|
||||
return super.isHiddenCategory(category);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -17,8 +17,6 @@
|
||||
|
||||
package org.keycloak.quarkus.runtime.cli.command;
|
||||
|
||||
import org.keycloak.quarkus.runtime.cli.Help;
|
||||
|
||||
import picocli.CommandLine;
|
||||
|
||||
public final class HelpAllMixin {
|
||||
@ -26,7 +24,6 @@ public final class HelpAllMixin {
|
||||
public static final String HELP_ALL_OPTION = "--help-all";
|
||||
|
||||
@CommandLine.Option(names = {HELP_ALL_OPTION}, usageHelp = true, description = "This same help message but with additional options.")
|
||||
public void setHelpAll(boolean allOptions) {
|
||||
Help.setAllOptions(true);
|
||||
}
|
||||
boolean allOptions;
|
||||
|
||||
}
|
||||
|
||||
@ -17,8 +17,6 @@
|
||||
|
||||
package org.keycloak.quarkus.runtime.cli.command;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
import org.keycloak.config.OptionCategory;
|
||||
import org.keycloak.exportimport.ExportImportConfig;
|
||||
|
||||
@ -47,8 +45,11 @@ public final class Import extends AbstractNonServerCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EnumSet<OptionCategory> excludedCategories() {
|
||||
return EnumSet.of(OptionCategory.EXPORT);
|
||||
public boolean isHiddenCategory(OptionCategory category) {
|
||||
if (category == OptionCategory.IMPORT) {
|
||||
return false;
|
||||
}
|
||||
return super.isHiddenCategory(category);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -28,6 +28,6 @@ public final class OptimizedMixin {
|
||||
description = "Use this option to achieve an optimal startup time if you have previously built a server image using the 'build' command.",
|
||||
paramLabel = NO_PARAM_LABEL,
|
||||
order = 1)
|
||||
Boolean optimized;
|
||||
boolean optimized;
|
||||
|
||||
}
|
||||
|
||||
@ -136,4 +136,10 @@ public final class ShowConfig extends AbstractCommand {
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHelpAll() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -51,11 +51,6 @@ public final class Start extends AbstractAutoBuildCommand {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean includeRuntime() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return NAME;
|
||||
@ -65,4 +60,10 @@ public final class Start extends AbstractAutoBuildCommand {
|
||||
public boolean isServing() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OptimizedMixin getOptimizedMixin() {
|
||||
return optimizedMixin;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -46,11 +46,6 @@ public final class StartDev extends AbstractAutoBuildCommand {
|
||||
return Environment.DEV_PROFILE_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean includeRuntime() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return NAME;
|
||||
@ -60,4 +55,9 @@ public final class StartDev extends AbstractAutoBuildCommand {
|
||||
public boolean isServing() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OptimizedMixin getOptimizedMixin() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,11 +79,6 @@ public class UpdateCompatibilityCheck extends AbstractUpdatesCommand {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean includeRuntime() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateConfig() {
|
||||
super.validateConfig();
|
||||
|
||||
@ -60,11 +60,6 @@ public class UpdateCompatibilityMetadata extends AbstractUpdatesCommand {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean includeRuntime() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateConfig() {
|
||||
super.validateConfig();
|
||||
|
||||
@ -23,8 +23,6 @@ import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
|
||||
|
||||
import picocli.CommandLine;
|
||||
|
||||
import static org.keycloak.quarkus.runtime.cli.OptionRenderer.DUPLICIT_OPTION_SUFFIX;
|
||||
|
||||
/**
|
||||
* Custom CommandLine.UnmatchedArgumentException with amended suggestions
|
||||
*/
|
||||
@ -42,8 +40,7 @@ public class KcUnmatchedArgumentException extends CommandLine.UnmatchedArgumentE
|
||||
public List<String> getSuggestions() {
|
||||
// filter out disabled mappers
|
||||
return super.getSuggestions().stream()
|
||||
.filter(f -> PropertyMappers.getKcKeyFromCliKey(f).filter(PropertyMappers::isDisabledMapper).isEmpty()
|
||||
&& !f.endsWith(DUPLICIT_OPTION_SUFFIX))
|
||||
.filter(f -> PropertyMappers.getKcKeyFromCliKey(f).filter(PropertyMappers::isDisabledMapper).isEmpty())
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
||||
@ -542,15 +542,14 @@ public class PropertyMapper<T> {
|
||||
* <p>
|
||||
* f.e. check whether existing feature is referenced
|
||||
* <pre>
|
||||
* kc.feature-enabled-<feature>:v1
|
||||
* kc.feature-<feature>:v1
|
||||
* → (key, value) -> is key a feature? if not, fail
|
||||
*
|
||||
* @param validator validator with parameters (wildcardKey, value)
|
||||
*/
|
||||
public Builder<T> wildcardKeysValidator(BiConsumer<String, String> validator) {
|
||||
addValidator((mapper, configValue) -> {
|
||||
var wildcardMapper = (WildcardPropertyMapper<?>) mapper;
|
||||
var key = wildcardMapper.extractWildcardValue(configValue.getName()).orElseThrow(() -> new PropertyException("Cannot determine wildcard key."));
|
||||
var key = mapper.getNamedProperty().orElseThrow(() -> new PropertyException("Cannot determine wildcard key."));
|
||||
validator.accept(key, configValue.getValue());
|
||||
});
|
||||
return this;
|
||||
|
||||
@ -23,7 +23,6 @@ import java.io.StringWriter;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.function.Consumer;
|
||||
@ -105,10 +104,10 @@ public class PicocliTest extends AbstractConfigurationTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initConfig(List<String> cliArgs, AbstractCommand command) {
|
||||
public void initConfig(AbstractCommand command) {
|
||||
KeycloakConfigSourceProvider.reload();
|
||||
boolean checkBuild = Environment.isRebuildCheck();
|
||||
super.initConfig(cliArgs, command);
|
||||
super.initConfig(command);
|
||||
if (!checkBuild && PersistedConfigSource.getInstance().getConfigValueProperties().isEmpty()) {
|
||||
System.getProperties().remove(Environment.KC_CONFIG_REBUILD_CHECK);
|
||||
}
|
||||
@ -373,6 +372,13 @@ public class PicocliTest extends AbstractConfigurationTest {
|
||||
assertEquals(CommandLine.ExitCode.OK, nonRunningPicocli.exitCode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unnecessaryExportOption() {
|
||||
NonRunningPicocli nonRunningPicocli = pseudoLaunch("export", "--dir=data", "--http-enabled=true");
|
||||
assertThat(nonRunningPicocli.getOutString(), containsString("The following options were specified, but are typically not relevant for this command: --http-enabled"));
|
||||
assertEquals(CommandLine.ExitCode.OK, nonRunningPicocli.exitCode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReaugFromProdToDev() {
|
||||
build("build", "--db=dev-file");
|
||||
@ -621,9 +627,9 @@ public class PicocliTest extends AbstractConfigurationTest {
|
||||
public void buildOptionChangedWithOptimized() {
|
||||
build("build", "--db=dev-file");
|
||||
|
||||
NonRunningPicocli nonRunningPicocli = pseudoLaunch("start", "--optimized", "--db=dev-mem");
|
||||
NonRunningPicocli nonRunningPicocli = pseudoLaunch("start", "--optimized", "--db=dev-mem", "--http-enabled=true", "--hostname-strict=false");
|
||||
assertEquals(CommandLine.ExitCode.USAGE, nonRunningPicocli.exitCode);
|
||||
assertTrue(nonRunningPicocli.getErrString().contains("Build time option: '--db' not usable with pre-built image and --optimized"));
|
||||
assertTrue(nonRunningPicocli.getErrString(), nonRunningPicocli.getErrString().contains("The following build time options have values that differ from what is persisted - the new values will NOT be used until another build is run: kc.db"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -828,7 +834,6 @@ public class PicocliTest extends AbstractConfigurationTest {
|
||||
nonRunningPicocli = pseudoLaunch("start-dev", "--log=%s".formatted(logHandlerName), "--log-%s-async-queue-length=768".formatted(logHandlerOptionsName));
|
||||
assertEquals(CommandLine.ExitCode.USAGE, nonRunningPicocli.exitCode);
|
||||
assertThat(nonRunningPicocli.getErrString(), containsString("Disabled option: '--log-%s-async-queue-length'. Available only when %s is activated and asynchronous logging is enabled".formatted(logHandlerOptionsName, logHandlerFullName)));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@ -65,8 +65,9 @@ class BuildCommandDistTest {
|
||||
|
||||
@Test
|
||||
@Launch({ "build", "--db=postgres", "--db-username=myuser", "--db-password=mypassword", "--http-enabled=true" })
|
||||
void testFailRuntimeOptions(CLIResult cliResult) {
|
||||
cliResult.assertError("Run time option: '--db-username' not usable with build");
|
||||
void testIgnoreRuntimeOptions(CLIResult cliResult) {
|
||||
cliResult.assertMessage("The following run time options were found, but will be ignored during build time: kc.db-username, kc.http-enabled, kc.db-password");
|
||||
cliResult.assertBuild();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@ -147,69 +147,6 @@ Feature:
|
||||
--features-disabled <feature>
|
||||
Disables a set of one or more features. Possible values are: <...>.
|
||||
|
||||
HTTP Access log:
|
||||
|
||||
--http-access-log-enabled <true|false>
|
||||
If HTTP access logging is enabled. By default this will log records in
|
||||
console. Default: false.
|
||||
|
||||
Management:
|
||||
|
||||
--http-management-port <port>
|
||||
Port of the management interface. Relevant only when something is exposed on
|
||||
the management interface - see the guide for details. Default: 9000.
|
||||
--http-management-relative-path <path>
|
||||
Set the path relative to '/' for serving resources from management interface.
|
||||
The path must start with a '/'. If not given, the value is inherited from
|
||||
HTTP options. Relevant only when something is exposed on the management
|
||||
interface - see the guide for details. Default: /.
|
||||
--http-management-scheme <scheme>
|
||||
Configures the management interface scheme. If 'inherited', the management
|
||||
interface will inherit the HTTPS settings of the main interface. If 'http',
|
||||
the management interface will be accessible via HTTP - it will not inherit
|
||||
HTTPS settings and cannot be configured for HTTPS. Possible values are:
|
||||
http, inherited. Default: inherited.
|
||||
--https-management-certificate-file <file>
|
||||
The file path to a server certificate or certificate chain in PEM format for
|
||||
the management server. If not given, the value is inherited from HTTP
|
||||
options. Relevant only when something is exposed on the management interface
|
||||
- see the guide for details. Available only when http-management-scheme is
|
||||
inherited.
|
||||
--https-management-certificate-key-file <file>
|
||||
The file path to a private key in PEM format for the management server. If not
|
||||
given, the value is inherited from HTTP options. Relevant only when
|
||||
something is exposed on the management interface - see the guide for
|
||||
details. Available only when http-management-scheme is inherited.
|
||||
--https-management-certificates-reload-period <reload period>
|
||||
Interval on which to reload key store, trust store, and certificate files
|
||||
referenced by https-management-* options for the management server. May be
|
||||
an ISO 8601 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. If not given, the value is inherited from HTTP options. Relevant
|
||||
only when something is exposed on the management interface - see the guide
|
||||
for details. Default: 1h. Available only when http-management-scheme is
|
||||
inherited.
|
||||
--https-management-client-auth <auth>
|
||||
Configures the management interface to require/request client authentication.
|
||||
If not given, the value is inherited from HTTP options. Relevant only when
|
||||
something is exposed on the management interface - see the guide for
|
||||
details. Possible values are: none, request, required. Default: none.
|
||||
--https-management-key-store-file <file>
|
||||
The key store which holds the certificate information instead of specifying
|
||||
separate files for the management server. If not given, the value is
|
||||
inherited from HTTP options. Relevant only when something is exposed on the
|
||||
management interface - see the guide for details. Available only when
|
||||
http-management-scheme is inherited.
|
||||
--https-management-key-store-password <password>
|
||||
The password of the key store file for the management server. If not given,
|
||||
the value is inherited from HTTP options. Relevant only when something is
|
||||
exposed on the management interface - see the guide for details. Default:
|
||||
password. Available only when http-management-scheme is inherited.
|
||||
--legacy-observability-interface <true|false>
|
||||
DEPRECATED. If metrics/health endpoints should be exposed on the main HTTP
|
||||
server (not recommended). If set to true, the management interface is
|
||||
disabled. Default: false.
|
||||
|
||||
Vault:
|
||||
|
||||
--vault <provider> Enables a vault provider. Possible values are: file, keystore.
|
||||
|
||||
@ -149,69 +149,6 @@ Feature:
|
||||
--features-disabled <feature>
|
||||
Disables a set of one or more features. Possible values are: <...>.
|
||||
|
||||
HTTP Access log:
|
||||
|
||||
--http-access-log-enabled <true|false>
|
||||
If HTTP access logging is enabled. By default this will log records in
|
||||
console. Default: false.
|
||||
|
||||
Management:
|
||||
|
||||
--http-management-port <port>
|
||||
Port of the management interface. Relevant only when something is exposed on
|
||||
the management interface - see the guide for details. Default: 9000.
|
||||
--http-management-relative-path <path>
|
||||
Set the path relative to '/' for serving resources from management interface.
|
||||
The path must start with a '/'. If not given, the value is inherited from
|
||||
HTTP options. Relevant only when something is exposed on the management
|
||||
interface - see the guide for details. Default: /.
|
||||
--http-management-scheme <scheme>
|
||||
Configures the management interface scheme. If 'inherited', the management
|
||||
interface will inherit the HTTPS settings of the main interface. If 'http',
|
||||
the management interface will be accessible via HTTP - it will not inherit
|
||||
HTTPS settings and cannot be configured for HTTPS. Possible values are:
|
||||
http, inherited. Default: inherited.
|
||||
--https-management-certificate-file <file>
|
||||
The file path to a server certificate or certificate chain in PEM format for
|
||||
the management server. If not given, the value is inherited from HTTP
|
||||
options. Relevant only when something is exposed on the management interface
|
||||
- see the guide for details. Available only when http-management-scheme is
|
||||
inherited.
|
||||
--https-management-certificate-key-file <file>
|
||||
The file path to a private key in PEM format for the management server. If not
|
||||
given, the value is inherited from HTTP options. Relevant only when
|
||||
something is exposed on the management interface - see the guide for
|
||||
details. Available only when http-management-scheme is inherited.
|
||||
--https-management-certificates-reload-period <reload period>
|
||||
Interval on which to reload key store, trust store, and certificate files
|
||||
referenced by https-management-* options for the management server. May be
|
||||
an ISO 8601 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. If not given, the value is inherited from HTTP options. Relevant
|
||||
only when something is exposed on the management interface - see the guide
|
||||
for details. Default: 1h. Available only when http-management-scheme is
|
||||
inherited.
|
||||
--https-management-client-auth <auth>
|
||||
Configures the management interface to require/request client authentication.
|
||||
If not given, the value is inherited from HTTP options. Relevant only when
|
||||
something is exposed on the management interface - see the guide for
|
||||
details. Possible values are: none, request, required. Default: none.
|
||||
--https-management-key-store-file <file>
|
||||
The key store which holds the certificate information instead of specifying
|
||||
separate files for the management server. If not given, the value is
|
||||
inherited from HTTP options. Relevant only when something is exposed on the
|
||||
management interface - see the guide for details. Available only when
|
||||
http-management-scheme is inherited.
|
||||
--https-management-key-store-password <password>
|
||||
The password of the key store file for the management server. If not given,
|
||||
the value is inherited from HTTP options. Relevant only when something is
|
||||
exposed on the management interface - see the guide for details. Default:
|
||||
password. Available only when http-management-scheme is inherited.
|
||||
--legacy-observability-interface <true|false>
|
||||
DEPRECATED. If metrics/health endpoints should be exposed on the main HTTP
|
||||
server (not recommended). If set to true, the management interface is
|
||||
disabled. Default: false.
|
||||
|
||||
Vault:
|
||||
|
||||
--vault <provider> Enables a vault provider. Possible values are: file, keystore.
|
||||
|
||||
@ -142,69 +142,6 @@ Feature:
|
||||
--features-disabled <feature>
|
||||
Disables a set of one or more features. Possible values are: <...>.
|
||||
|
||||
HTTP Access log:
|
||||
|
||||
--http-access-log-enabled <true|false>
|
||||
If HTTP access logging is enabled. By default this will log records in
|
||||
console. Default: false.
|
||||
|
||||
Management:
|
||||
|
||||
--http-management-port <port>
|
||||
Port of the management interface. Relevant only when something is exposed on
|
||||
the management interface - see the guide for details. Default: 9000.
|
||||
--http-management-relative-path <path>
|
||||
Set the path relative to '/' for serving resources from management interface.
|
||||
The path must start with a '/'. If not given, the value is inherited from
|
||||
HTTP options. Relevant only when something is exposed on the management
|
||||
interface - see the guide for details. Default: /.
|
||||
--http-management-scheme <scheme>
|
||||
Configures the management interface scheme. If 'inherited', the management
|
||||
interface will inherit the HTTPS settings of the main interface. If 'http',
|
||||
the management interface will be accessible via HTTP - it will not inherit
|
||||
HTTPS settings and cannot be configured for HTTPS. Possible values are:
|
||||
http, inherited. Default: inherited.
|
||||
--https-management-certificate-file <file>
|
||||
The file path to a server certificate or certificate chain in PEM format for
|
||||
the management server. If not given, the value is inherited from HTTP
|
||||
options. Relevant only when something is exposed on the management interface
|
||||
- see the guide for details. Available only when http-management-scheme is
|
||||
inherited.
|
||||
--https-management-certificate-key-file <file>
|
||||
The file path to a private key in PEM format for the management server. If not
|
||||
given, the value is inherited from HTTP options. Relevant only when
|
||||
something is exposed on the management interface - see the guide for
|
||||
details. Available only when http-management-scheme is inherited.
|
||||
--https-management-certificates-reload-period <reload period>
|
||||
Interval on which to reload key store, trust store, and certificate files
|
||||
referenced by https-management-* options for the management server. May be
|
||||
an ISO 8601 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. If not given, the value is inherited from HTTP options. Relevant
|
||||
only when something is exposed on the management interface - see the guide
|
||||
for details. Default: 1h. Available only when http-management-scheme is
|
||||
inherited.
|
||||
--https-management-client-auth <auth>
|
||||
Configures the management interface to require/request client authentication.
|
||||
If not given, the value is inherited from HTTP options. Relevant only when
|
||||
something is exposed on the management interface - see the guide for
|
||||
details. Possible values are: none, request, required. Default: none.
|
||||
--https-management-key-store-file <file>
|
||||
The key store which holds the certificate information instead of specifying
|
||||
separate files for the management server. If not given, the value is
|
||||
inherited from HTTP options. Relevant only when something is exposed on the
|
||||
management interface - see the guide for details. Available only when
|
||||
http-management-scheme is inherited.
|
||||
--https-management-key-store-password <password>
|
||||
The password of the key store file for the management server. If not given,
|
||||
the value is inherited from HTTP options. Relevant only when something is
|
||||
exposed on the management interface - see the guide for details. Default:
|
||||
password. Available only when http-management-scheme is inherited.
|
||||
--legacy-observability-interface <true|false>
|
||||
DEPRECATED. If metrics/health endpoints should be exposed on the main HTTP
|
||||
server (not recommended). If set to true, the management interface is
|
||||
disabled. Default: false.
|
||||
|
||||
Vault:
|
||||
|
||||
--vault <provider> Enables a vault provider. Possible values are: file, keystore.
|
||||
|
||||
@ -142,83 +142,6 @@ Feature:
|
||||
--features-disabled <feature>
|
||||
Disables a set of one or more features. Possible values are: <...>.
|
||||
|
||||
HTTP Access log:
|
||||
|
||||
--http-access-log-enabled <true|false>
|
||||
If HTTP access logging is enabled. By default this will log records in
|
||||
console. Default: false.
|
||||
--http-access-log-exclude <PARAM>
|
||||
A regular expression that can be used to exclude some paths from logging. For
|
||||
instance, '/realms/my-realm/.*' will exclude all subsequent endpoints for
|
||||
realm 'my-realm' from the log. Available only when HTTP Access log is
|
||||
enabled.
|
||||
--http-access-log-pattern <PARAM>
|
||||
The HTTP access log pattern. You can use the available named formats, or use
|
||||
custom format described in Quarkus documentation. Possible values are:
|
||||
common, combined, long, or a custom one. Default: common. Available only
|
||||
when HTTP Access log is enabled.
|
||||
|
||||
Management:
|
||||
|
||||
--http-management-health-enabled <true|false>
|
||||
If health endpoints should be exposed on the management interface. If false,
|
||||
health endpoints will be exposed on the main interface. Default: true.
|
||||
Available only when health is enabled.
|
||||
--http-management-port <port>
|
||||
Port of the management interface. Relevant only when something is exposed on
|
||||
the management interface - see the guide for details. Default: 9000.
|
||||
--http-management-relative-path <path>
|
||||
Set the path relative to '/' for serving resources from management interface.
|
||||
The path must start with a '/'. If not given, the value is inherited from
|
||||
HTTP options. Relevant only when something is exposed on the management
|
||||
interface - see the guide for details. Default: /.
|
||||
--http-management-scheme <scheme>
|
||||
Configures the management interface scheme. If 'inherited', the management
|
||||
interface will inherit the HTTPS settings of the main interface. If 'http',
|
||||
the management interface will be accessible via HTTP - it will not inherit
|
||||
HTTPS settings and cannot be configured for HTTPS. Possible values are:
|
||||
http, inherited. Default: inherited.
|
||||
--https-management-certificate-file <file>
|
||||
The file path to a server certificate or certificate chain in PEM format for
|
||||
the management server. If not given, the value is inherited from HTTP
|
||||
options. Relevant only when something is exposed on the management interface
|
||||
- see the guide for details. Available only when http-management-scheme is
|
||||
inherited.
|
||||
--https-management-certificate-key-file <file>
|
||||
The file path to a private key in PEM format for the management server. If not
|
||||
given, the value is inherited from HTTP options. Relevant only when
|
||||
something is exposed on the management interface - see the guide for
|
||||
details. Available only when http-management-scheme is inherited.
|
||||
--https-management-certificates-reload-period <reload period>
|
||||
Interval on which to reload key store, trust store, and certificate files
|
||||
referenced by https-management-* options for the management server. May be
|
||||
an ISO 8601 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. If not given, the value is inherited from HTTP options. Relevant
|
||||
only when something is exposed on the management interface - see the guide
|
||||
for details. Default: 1h. Available only when http-management-scheme is
|
||||
inherited.
|
||||
--https-management-client-auth <auth>
|
||||
Configures the management interface to require/request client authentication.
|
||||
If not given, the value is inherited from HTTP options. Relevant only when
|
||||
something is exposed on the management interface - see the guide for
|
||||
details. Possible values are: none, request, required. Default: none.
|
||||
--https-management-key-store-file <file>
|
||||
The key store which holds the certificate information instead of specifying
|
||||
separate files for the management server. If not given, the value is
|
||||
inherited from HTTP options. Relevant only when something is exposed on the
|
||||
management interface - see the guide for details. Available only when
|
||||
http-management-scheme is inherited.
|
||||
--https-management-key-store-password <password>
|
||||
The password of the key store file for the management server. If not given,
|
||||
the value is inherited from HTTP options. Relevant only when something is
|
||||
exposed on the management interface - see the guide for details. Default:
|
||||
password. Available only when http-management-scheme is inherited.
|
||||
--legacy-observability-interface <true|false>
|
||||
DEPRECATED. If metrics/health endpoints should be exposed on the main HTTP
|
||||
server (not recommended). If set to true, the management interface is
|
||||
disabled. Default: false.
|
||||
|
||||
Vault:
|
||||
|
||||
--vault <provider> Enables a vault provider. Possible values are: file, keystore.
|
||||
|
||||
@ -142,69 +142,6 @@ Feature:
|
||||
--features-disabled <feature>
|
||||
Disables a set of one or more features. Possible values are: <...>.
|
||||
|
||||
HTTP Access log:
|
||||
|
||||
--http-access-log-enabled <true|false>
|
||||
If HTTP access logging is enabled. By default this will log records in
|
||||
console. Default: false.
|
||||
|
||||
Management:
|
||||
|
||||
--http-management-port <port>
|
||||
Port of the management interface. Relevant only when something is exposed on
|
||||
the management interface - see the guide for details. Default: 9000.
|
||||
--http-management-relative-path <path>
|
||||
Set the path relative to '/' for serving resources from management interface.
|
||||
The path must start with a '/'. If not given, the value is inherited from
|
||||
HTTP options. Relevant only when something is exposed on the management
|
||||
interface - see the guide for details. Default: /.
|
||||
--http-management-scheme <scheme>
|
||||
Configures the management interface scheme. If 'inherited', the management
|
||||
interface will inherit the HTTPS settings of the main interface. If 'http',
|
||||
the management interface will be accessible via HTTP - it will not inherit
|
||||
HTTPS settings and cannot be configured for HTTPS. Possible values are:
|
||||
http, inherited. Default: inherited.
|
||||
--https-management-certificate-file <file>
|
||||
The file path to a server certificate or certificate chain in PEM format for
|
||||
the management server. If not given, the value is inherited from HTTP
|
||||
options. Relevant only when something is exposed on the management interface
|
||||
- see the guide for details. Available only when http-management-scheme is
|
||||
inherited.
|
||||
--https-management-certificate-key-file <file>
|
||||
The file path to a private key in PEM format for the management server. If not
|
||||
given, the value is inherited from HTTP options. Relevant only when
|
||||
something is exposed on the management interface - see the guide for
|
||||
details. Available only when http-management-scheme is inherited.
|
||||
--https-management-certificates-reload-period <reload period>
|
||||
Interval on which to reload key store, trust store, and certificate files
|
||||
referenced by https-management-* options for the management server. May be
|
||||
an ISO 8601 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. If not given, the value is inherited from HTTP options. Relevant
|
||||
only when something is exposed on the management interface - see the guide
|
||||
for details. Default: 1h. Available only when http-management-scheme is
|
||||
inherited.
|
||||
--https-management-client-auth <auth>
|
||||
Configures the management interface to require/request client authentication.
|
||||
If not given, the value is inherited from HTTP options. Relevant only when
|
||||
something is exposed on the management interface - see the guide for
|
||||
details. Possible values are: none, request, required. Default: none.
|
||||
--https-management-key-store-file <file>
|
||||
The key store which holds the certificate information instead of specifying
|
||||
separate files for the management server. If not given, the value is
|
||||
inherited from HTTP options. Relevant only when something is exposed on the
|
||||
management interface - see the guide for details. Available only when
|
||||
http-management-scheme is inherited.
|
||||
--https-management-key-store-password <password>
|
||||
The password of the key store file for the management server. If not given,
|
||||
the value is inherited from HTTP options. Relevant only when something is
|
||||
exposed on the management interface - see the guide for details. Default:
|
||||
password. Available only when http-management-scheme is inherited.
|
||||
--legacy-observability-interface <true|false>
|
||||
DEPRECATED. If metrics/health endpoints should be exposed on the main HTTP
|
||||
server (not recommended). If set to true, the management interface is
|
||||
disabled. Default: false.
|
||||
|
||||
Vault:
|
||||
|
||||
--vault <provider> Enables a vault provider. Possible values are: file, keystore.
|
||||
|
||||
@ -142,83 +142,6 @@ Feature:
|
||||
--features-disabled <feature>
|
||||
Disables a set of one or more features. Possible values are: <...>.
|
||||
|
||||
HTTP Access log:
|
||||
|
||||
--http-access-log-enabled <true|false>
|
||||
If HTTP access logging is enabled. By default this will log records in
|
||||
console. Default: false.
|
||||
--http-access-log-exclude <PARAM>
|
||||
A regular expression that can be used to exclude some paths from logging. For
|
||||
instance, '/realms/my-realm/.*' will exclude all subsequent endpoints for
|
||||
realm 'my-realm' from the log. Available only when HTTP Access log is
|
||||
enabled.
|
||||
--http-access-log-pattern <PARAM>
|
||||
The HTTP access log pattern. You can use the available named formats, or use
|
||||
custom format described in Quarkus documentation. Possible values are:
|
||||
common, combined, long, or a custom one. Default: common. Available only
|
||||
when HTTP Access log is enabled.
|
||||
|
||||
Management:
|
||||
|
||||
--http-management-health-enabled <true|false>
|
||||
If health endpoints should be exposed on the management interface. If false,
|
||||
health endpoints will be exposed on the main interface. Default: true.
|
||||
Available only when health is enabled.
|
||||
--http-management-port <port>
|
||||
Port of the management interface. Relevant only when something is exposed on
|
||||
the management interface - see the guide for details. Default: 9000.
|
||||
--http-management-relative-path <path>
|
||||
Set the path relative to '/' for serving resources from management interface.
|
||||
The path must start with a '/'. If not given, the value is inherited from
|
||||
HTTP options. Relevant only when something is exposed on the management
|
||||
interface - see the guide for details. Default: /.
|
||||
--http-management-scheme <scheme>
|
||||
Configures the management interface scheme. If 'inherited', the management
|
||||
interface will inherit the HTTPS settings of the main interface. If 'http',
|
||||
the management interface will be accessible via HTTP - it will not inherit
|
||||
HTTPS settings and cannot be configured for HTTPS. Possible values are:
|
||||
http, inherited. Default: inherited.
|
||||
--https-management-certificate-file <file>
|
||||
The file path to a server certificate or certificate chain in PEM format for
|
||||
the management server. If not given, the value is inherited from HTTP
|
||||
options. Relevant only when something is exposed on the management interface
|
||||
- see the guide for details. Available only when http-management-scheme is
|
||||
inherited.
|
||||
--https-management-certificate-key-file <file>
|
||||
The file path to a private key in PEM format for the management server. If not
|
||||
given, the value is inherited from HTTP options. Relevant only when
|
||||
something is exposed on the management interface - see the guide for
|
||||
details. Available only when http-management-scheme is inherited.
|
||||
--https-management-certificates-reload-period <reload period>
|
||||
Interval on which to reload key store, trust store, and certificate files
|
||||
referenced by https-management-* options for the management server. May be
|
||||
an ISO 8601 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. If not given, the value is inherited from HTTP options. Relevant
|
||||
only when something is exposed on the management interface - see the guide
|
||||
for details. Default: 1h. Available only when http-management-scheme is
|
||||
inherited.
|
||||
--https-management-client-auth <auth>
|
||||
Configures the management interface to require/request client authentication.
|
||||
If not given, the value is inherited from HTTP options. Relevant only when
|
||||
something is exposed on the management interface - see the guide for
|
||||
details. Possible values are: none, request, required. Default: none.
|
||||
--https-management-key-store-file <file>
|
||||
The key store which holds the certificate information instead of specifying
|
||||
separate files for the management server. If not given, the value is
|
||||
inherited from HTTP options. Relevant only when something is exposed on the
|
||||
management interface - see the guide for details. Available only when
|
||||
http-management-scheme is inherited.
|
||||
--https-management-key-store-password <password>
|
||||
The password of the key store file for the management server. If not given,
|
||||
the value is inherited from HTTP options. Relevant only when something is
|
||||
exposed on the management interface - see the guide for details. Default:
|
||||
password. Available only when http-management-scheme is inherited.
|
||||
--legacy-observability-interface <true|false>
|
||||
DEPRECATED. If metrics/health endpoints should be exposed on the main HTTP
|
||||
server (not recommended). If set to true, the management interface is
|
||||
disabled. Default: false.
|
||||
|
||||
Vault:
|
||||
|
||||
--vault <provider> Enables a vault provider. Possible values are: file, keystore.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user