8000 Operator CRD with generated ServerConfiguration from refactored config by andreaTP · Pull Request #11929 · keycloak/keycloak · GitHub
[go: up one dir, main page]

Skip to content

Operator CRD with generated ServerConfiguration from refactored config - #11929

Merged
pedroigor merged 1 commit into
keycloak:mainfrom
andreaTP:shared-config
May 26, 2022
Merged

pedroigor merged 1 commit into
keycloak:mainfrom
andreaTP:shared-config

Conversation

@andreaTP
@andreaTP andreaTP commented May 10, 2022 •
Copy link
Copy Markdown
Contributor

Initial work to resolve: #10866

A possible plan to get this to main would be:

  • get this refactoring in (as it doesn't break anything else and prepare the "structure")
  • port all of the options in a separate PR
  • use the generated serverConfig in a third follow up PR

@vmuzikar
vmuzikar self-requested a review May 12, 2022 06:33
@vmuzikar vmuzikar left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andreaTP Nice job, I like this approach! 👍 Although I fought a bit with my IDE to make it index the generated class.

Added a few comments but mostly just suggestions for polishing.

The remaining issue we have to tackle is how to handle the exceptions in a nice way – how to make some propety hidden from Quarkus or the Operator.

Comment thread config/pom.xml Resolved
Comment thread operator/maven-plugin/pom.xml Resolved
Comment thread operator/maven-plugin/pom.xml Resolved
@andreaTP
andreaTP force-pushed the shared-config branch 3 times, most recently from cc7d17e to 7649588 Compare May 16, 2022 15:18
@andreaTP
andreaTP marked this pull request as ready for review May 16, 2022 15:21
@andreaTP
andreaTP requested review from DGuhr and pedroigor May 16, 2022 15:21
@andreaTP andreaTP changed the title [DRAFT] Demo operator CRD with generated ServerConfiguration 2 Operator CRD with generated ServerConfiguration from refactored config May 16, 2022
Comment thread dist-config/pom.xml Resolved
Comment thread dist-config/pom.xml Resolved
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is also another example of how we should be obtaining all available options from the server configuration?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, and it can/will be used by the following modules.

I aim to get this first "example" in, and to bulk move the encoding of all the options in a follow-up PR to help with reviews and split up work.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we replace this class and Option now we have similar types in from the new module?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can replace some of this, unfortunately, looks like SPIs configuration is still not covered:

for (Spi loadSpi : providerManager.loadSpis().stream().sorted(Comparator.comparing(Spi::getName)).collect(Collectors.toList())) {
for (ProviderFactory providerFactory : providerManager.load(loadSpi).stream().sorted(Comparator.comparing(ProviderFactory::getId)).collect(Collectors.toList())) {
List<ProviderConfigProperty> configMetadata = providerFactory.getConfigMetadata();
if (configMetadata == null) {
continue;
}
String optionPrefix = NS_KEYCLOAK_PREFIX + String.join(OPTION_PART_SEPARATOR, ArrayUtils.insert(0, new String[] {loadSpi.getName(), providerFactory.getId()}, "spi"));
List<Option> options = configMetadata.stream()
.map(m -> new Option(Configuration.toDashCase(optionPrefix.concat("-") + m.getName()), ConfigCategory.GENERAL, false,
m.getHelpText(),
m.getDefaultValue() == null ? "none" : m.getDefaultValue().toString(),
m.getOptions() == null ? (m.getType() == null ? Collections.emptyList() : Collections.singletonList(m.getType())) : m.getOptions()))
.sorted(Comparator.comparing(Option::getKey)).collect(Collectors.toList());
if (!options.isEmpty()) {
providerOptions.computeIfAbsent(toDashCase(loadSpi.getName()), k -> new LinkedHashMap<>()).put(toDashCase(providerFactory.getId()), options);
}
}
}

In this PR I took out the docs bit to be able to perform the change incrementally (i.e. with subsequent non-breaking PRs)
E.g. the docs sub-module will rely on the new configuration only after we move all the configuration keys to the new encoding.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although we don't have yet a proper support for exposing SPI configuration options, the new module should be able to provide them similarly to what you did to HttpOptions.

The difference here is that these options are dynamic as they come from whatever provider is installed on the server. In the future, and that is related to the extension story, it should also resolve options from custom providers.

If you want, I can look at this closer and try to come up with something to support this.

@pedroigor
pedroigor commented May 16, 2022 •
Copy link
Copy Markdown
Contributor

@andreaTP Nice work, looks like you are in the right direction :) Looks like we can also refactor the PropertyMapper a bit more such as:

  • Methods to format an option to CLI and ENV formats should now be available from the Option 8000 . For instance, it should be useful even in the operator to proper validate or document the options that can be set using CLI or ENV.

  • Some fields in PropertyMapper can probably be removed now that we have the same defined in Option.

  • Make the PropertyMapper strictly related to Quarkus configuration mapping (e.g.: transformers).

@DGuhr DGuhr left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolutely the right direction, thanks for that 👍 👍

One thing I'd still love to see (in a further step) is validations in this package. Imo the general validation rules are not dependant on the runtime - they depend on the (way less often changed) standards, e.g. "what is a valid range for a port"? could be answered the same for wildfly, quarkus and pretty much every httpserver out there. As a result, this package should imo be the place to define the validations, e.g. Option defining a Predicate/Function, and perhaps to not impose delays a way to skip the validations in favor of better startup times, bc. they are known to be working.

This would then also enable e.g. the possibility to write an IDE plugin that checks your configuration files for validity even before starting up.

But as said: Nice step in the right direction 👍 rest is for the future.

@andreaTP
Copy link
Copy Markdown
Contributor Author

@pedroigor I'll look into the further refactoring you proposed, seems good to me!

@DGuhr I agree on the "validation" bits, but this change is going to be invasive enough without them, will follow up as soon as this encoding is more stable (I already have a pretty good idea on how to do it 🙂 ).

Thanks for the feedback everyone!

@andreaTP
Copy link
Copy Markdown
Contributor Author

@pedroigor I have attempted to follow your suggestions:

  • Methods to format an option to CLI and ENV formats should now be available from the Option. For instance, it should be useful even in the operator to proper validate or document the options that can be set using CLI or ENV.

Unfortunately found out that the env and cli encodings are dependent on Picocli and Smallrye Config stuff, I would very much prefer to keep the Configuration module agnostic and dependency-free.

  • Some fields in PropertyMapper can probably be removed now that we have the same defined in Option.

Now PropertyMapper internally uses an Option but still exposes the "full" API, we can clean up the implementation after the next step (e.g. when all configurations are coming from the config module)

Comment thread pom.xml Resolved
@andreaTP
Copy link
Copy Markdown
Contributor Author

@pedroigor @vmuzikar @DGuhr ready for the next round of review, please consider that this is not the "final" PR and more cleanup will be done in the follow-up PRs to bring the task to completion. 🙏

The goal here is to get the "infrastructure setup" for the new configuration in place, along with one example property already ported over.

Comment thread dist-config/pom.xml Resolved
Comment thread pom.xml Resolved
@vmuzikar vmuzikar left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andreaTP Thanks for the update, really nice work! :)

Added a few comments. Mainly just nitpics to make the compiler happy and/or to align with best practices. The only thing that's blocking merge from my PoV, is the added dependency on commons-text.

Comment thread dist-config/pom.xml Resolved
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, just a nitpick. My IDE is complaining about using Optional as a field and for a good reason actually.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure what to do here, I changed everything to Optional because of a previous comment on this PR ...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. I assume you are referring to this: #11929 (comment) (CC @DGuhr).

I'm not fussy on it, we could leave it as is. Just from my PoV the point in the mentioned article:

The class is definitively not intended for use as a property

as well as a note in the official docs:

Optional is primarily intended for use as a method return type where there is a clear need to represent "no result,"

are clear to me that it should not be used as field types.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, I have mixed feelings about it, maybe we can briefly discuss this point in 2/3 weeks and decide what to do with it.

Comment thread operator/README.md Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just out of curiosity. Can't we install the Maven plugin and operator in a single step? It'd provide a better UX, IMHO.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will check, in general, for local development, we need to install the maven-plugin once and iterate with the operator build.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a quick test (mvn clean install in operator module with local mvn repo cleaned of any traces of the Operator) and seemed to work fine. Maven seems smart enough to build the plugin dependency first.

Comment thread pom.xml Resolved
@andreaTP
Copy link
Copy Markdown
Contributor Author

@vmuzikar can you please double-check that I have answered/followed your comments?
There are very few places left, especially when we had diverging comments/opinions by reviewers, but it might already be "good enough" as an iteration and we can fix things on top at a later stage, wdyt?

@andreaTP
Copy link
Copy Markdown
Contributor Author

apparently some of those changes have broken the build, will fix it by EOD.

@vmuzikar vmuzikar left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andreaTP Thanks for the update. LGTM, just found a bug in the camel case method, I believe.

it might already be "good enough" as an iteration and we can fix things on top at a later stage, wdyt?

+1, we just need to agree on the follow-up steps (if there are any) :)

@andreaTP
Copy link
Copy Markdown
Contributor Author

I finished fixing the open points, and squashed the commits. This should be ready for a final round @pedroigor @vmuzikar

@vmuzikar vmuzikar left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andreaTP Thank you for the update!

Just for the visibility, the last thing I'd like to align on is this: #11929 (comment).

@andreaTP
Copy link
Copy Markdown
Contributor Author

@vmuzikar removed the redundant mvn commands, should be good to go 🙂

vmuzikar
vmuzikar previously approved these changes May 25, 2022
@vmuzikar vmuzikar left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andreaTP Nice work, LGTM!

@vmuzikar
vmuzikar requested a review from pedroigor May 25, 2022 07:00
@pedroigor
pedroigor commented May 25, 2022 •
Copy link
Copy Markdown
Contributor

Unfortunately found out that the env and cli encodings are dependent on Picocli and Smallrye Config stuff, I would very much prefer to keep the Configuration module agnostic and dependency-free.

Sorry, if I was not clear. I meant methods like

, or , or . Do they depend on Picocli and Smallrye to badly that we can't bring them to the new module?

I would say that formatting is a must for this new module.

@andreaTP
Copy link
Copy Markdown
Contributor Author

@pedroigor I have attempted to move those and this is the result:

  • toDashCase and toCliFormat can be moved
  • toEnvVarFormat depends on io.smallrye.config.common.utils.StringUtil.replaceNonAlphanumericByUnderscores

In general, I believe that this PR is already big enough, do you agree to tackle this improvement separately? Do you wanna open a new Issue for it?

@andreaTP
Copy link
Copy Markdown
Contributor Author

@vmuzikar needed to rebase because of conflicts, would you mind to re-approve?

@pedroigor
Copy link
Copy Markdown
Contributor

@pedroigor I have attempted to move those and this is the result:

  • toDashCase and toCliFormat can be moved
  • toEnvVarFormat depends on io.smallrye.config.common.utils.StringUtil.replaceNonAlphanumericByUnderscores

In general, I believe that this PR is already big enough, do you agree to tackle this improvement separately? Do you wanna open a new Issue for it?

It should be fine to borrow that code from SmallRye and have it on our side.

But yeah, you have a good baseline, I'll look at these points later and collaborate with some changes.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although we don't have yet a proper support for exposing SPI configuration options, the new module should be able to provide them similarly to what you did to HttpOptions.

The difference here is that these options are dynamic as they come from whatever provider is installed on the server. In the future, and that is related to the extension story, it should also resolve options from custom providers.

If you want, I can look at this closer and try to come up with something to support this.

Comment thread dist-config/pom.xml Resolved
@pedroigor
pedroigor merged commit d667102 into keycloak:main May 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Separate configuration from Quarkus server runtime

5 participants

0