8000 [DRAFT] Demo operator CRD with generated ServerConfiguration by andreaTP · Pull Request #11806 · keycloak/keycloak · GitHub
[go: up one dir, main page]

Skip to content

[DRAFT] Demo operator CRD with generated ServerConfiguration - #11806

Closed
andreaTP wants to merge 2 commits into
keycloak:mainfrom
andreaTP:demo-generated-server-config
Closed

andreaTP wants to merge 2 commits into
keycloak:mainfrom
andreaTP:demo-generated-server-config

Conversation

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

This is a demo showing a possible (initial)flow from Quarkus distribution server configuration to Operator CRD typed generation.

  • started from the excellent work of @DGuhr regarding typing configuration values (in this demo applied to a single field http-port)
  • implemented a maven-plugin to generate the needed POJOs from the aggregated PropertyMappers
  • added the generated classes to the KeycloakSpec and got a CRD generated

A few considerations:

  • if we agree on the configuration typing changes we can move that forward independently first 🙂
  • the maven-plugin and the codegen is pretty much hacked together (don't look at code-style etc. it only serves demo purposes)
  • by using a maven-plugin to generate sources for the operator we do not have issues around classpath/Quarkus versions/etc. etc. nor we need a completely independent maven sub-project to refactor the configuration (even if it would be nice, but it's decoupled).
  • I noticed a bunch of "edge-cases" with the current configuration, but let's tackle them one by one

cc. @DGuhr @vmuzikar @pedroigor

Exploratory work to target #10866

Comment thread operator/pom.xml Resolved
Comment thread quarkus/maven-plugin/pom.xml Resolved

import java.util.Objects;

public class Property {
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'm wondering if this type should be added to the configuration API itself. We are using a similar structure when generating docs. See

.

E870
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 was wondering if I should try to re-use the docs generation, but I have no problems in including Property/Options as an extra class in the org.keycloak.quarkus.runtime.configuration package.

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 think that would be awesome but I don't think it is a blocker.

Comment thread quarkus/maven-plugin/pom.xml Resolved
.to("quarkus.http.port")
.defaultValue(String.valueOf(8080))
.type(Integer.class)
.converter(Integer::parseInt)
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.

Perhaps infer the converter based on the type and make the config even simpler?

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 like to keep the converter separated here since it's explicitly handled by the Picocli implementation and it can be used for multiple different purposes.

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'm not saying you should remove the converter method from the API but infer the converter based on the type. The code above would just use:

type(Integer.class)

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.

What you are proposing is partially overlapping with picocli functionalities.
E.g. specifying an explicit type will make the default converter redundant IIUC

@pedroigor pedroigor May 3, 2022 •
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 think we are talking about the same thing :) Let me ask then: Why do we need to explicitly set the converter?

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.

it was a nice extension point to build upon validation etc., I can probably take it off from the follow-up PRs to reduce the scope of the task

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>keycloak-docs-parent</artifactId>
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 know it's just a demo but wanted to point out that we're inheriting from docs module for some reason. Is that intended?

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 intended, will be removed if/when we bring this forward

Comment thread quarkus/maven-plugin/pom.xml Resolved
if (configurations.containsKey(k)) {
Set<Property> tmpValue = configurations.get(k);
tmpValue.add(v);
configurations.put(k, tmpValue);
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 a nitpick (for when this is not a demo anymore :)). I believe you don’t need to put the Set back again into the Map. It's already a reference.

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.

yup

import static io.smallrye.config.common.utils.StringUtil.replaceNonAlphanumericByUnderscores;

@Mojo(name = "keycloak-operator-codegen", defaultPhase = LifecyclePhase.GENERATE_SOURCES)
public class CodegenMojo extends AbstractMojo {
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.

Was wondering if we should not have have it the other way around. Some POJO with few custom annotations on top of field as the source of truth. This would get translated into the mappers. Might be a bit cleaner than a maven plugin for basically generating classes on the fly?

In any case, might be worth exploring what Store.X team will be doing. As mentioned, I think it is related to this, so might make sense to align on it.

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.

Was wondering if we should not have have it the other way around. Some POJO with few custom annotations on top of field as the source of truth.

This would require a pretty invasive change on how the CLI and configuration work as of today, I would like to hear from @pedroigor and @DGuhr

But, also, let's first open a GH "discussion" about the desired outcome and tackle the technical implementation as a separate subject.

@DGuhr DGuhr May 4, 2022 •
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.

My PoC actually had a POJO inside that could be used/extended as source of truth (the pojo is actually applicable to all sorts of "PortConfiguration", so the actual configurationkey POJO would extend it and add e.g. name, description, and so on), and I am pretty paranoid due to bad experiences when it comes to code generators, so +1 from my side. Nevertheless I totally agree this is more invasive, needs a bit of boilerplate work and should be discussed first.

For the problem space / the discussion part, a primer:
e.g. I thought the goal here was not only for the operator to get the config classes, but to extract a configuration package with its own api/interface, that could be used by any frontend, be it tools like https://github.com/adorsys/keycloak-config-cli or "I want to write my own keycloak configuration service using e.g. jbang", or "i want to set keycloak configuration using an existing tool like spring cloud config server" or even "I want to have an intellij / vscode plugin to show me when I have an invalid configuration even before starting up anything, so immediately when typing e.g. proxy=reencrypt, http-enabled=true". This, together with a --no-validate flag or sth around these lines that skips validation at startup bc. "hey, i know what i am doing and it was validated beforehand", would lead to the outcome that configuring keycloak would be much more flexible to do with whatever tool you want, would be decoupled from the actual runtime keycloak lives in, as the config is "self-contained" (given we also abstract away the "to" part from the mappers, this could even lead to a wildfly configuration frontend ;) ) bc validating could be done without even invoking keycloak, so at startup we would have nearly no impact on performance.

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.

@DGuhr +1 to that it'd also be beneficial in general – decoupling our configuration logic from Quarkus.

@andreaTP
Copy link
Copy Markdown
Contributor Author

Superseded by: #11929

@andreaTP andreaTP closed this May 16, 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.

5 participants

0