8000 Client API v2 CLI client: provide help and autocomplete based on Keycloak version of the logged session by michalvavrik · Pull Request #47525 · keycloak/keycloak · GitHub
[go: up one dir, main page]

Skip to content

Client API v2 CLI client: provide help and autocomplete based on Keycloak version of the logged session - #47525

Merged
vmuzikar merged 1 commit into
keycloak:mainfrom
michalvavrik:feature/admin-api-v2-cli-fetching
Apr 10, 2026
Merged

vmuzikar merged 1 commit into
keycloak:mainfrom
michalvavrik:feature/admin-api-v2-cli-fetching

Conversation

@michalvavrik
@michalvavrik michalvavrik commented Mar 27, 2026 •
Copy link
Copy Markdown
Member

More about OpenAPI document fetching:

When Admin CLI is used with a different Keycloak server version, we need to update help and autocomplete according to OpenAPI document, which describes what endpoints and schemas can be used. This can only be done when the Keycloak server has enabled (currently experimental) OpenAPI feature and users specify OpenAPI path. The management path and port can be changed by user, therefore we ask them to specify OpenAPI URL entirely.

This feature is only provided for the current session (when user is logged in into some server). We cannot easily provide help and autocomplete based on inline arguments like --server because it is bit chicken-egg problem (injected options are available after you provided command to PicoCLI, so we would need to do a lot manually).

Here is how it works:

mvavrik@fedora:~/sources/keycloak$ kcadm.sh --v2 config credentials --server http://localhost:8080 --realm master --user admin --password admin
Logging into http://localhost:8080 as user admin of realm master
OpenAPI descriptor cached for http://localhost:8080 (version 999.0.0-SNAPSHOT)

or for non-default management port:

mvavrik@fedora:~/sources/keycloak$ kcadm.sh --v2 config credentials --server http://localhost:8080 --realm master --user admin --password admin
Logging into http://localhost:8080 as user admin of realm master
mvavrik@fedora:~/sources/keycloak$ kcadm.sh --v2 config openapi http://localhost:9004/openapi
OpenAPI descriptor cached for http://localhost:8080 (version 999.0.0-SNAPSHOT)

or alternatively:

mvavrik@fedora:~/sources/keycloak$ kcadm.sh --v2 config credentials --server http://localhost:8080 --realm master --user admin --password admin --openapi-url http://localhost:9004/openapi
Logging into http://localhost:8080 as user admin of realm master
OpenAPI descriptor cached for http://localhost:8080 (version 999.0.0-SNAPSHOT)

After that, command structure reflects the OpenAPI document, including help and autocomplete. If you switch server using config credentials, command changes as well. If the server you are communicating does not provide OpenAPI endpoint, we silently fallback to the default OpenAPI document (bundled with the command). However,
the kcadm.sh --v2 config openapi fails if the OpenAPI endpoint wasn't available.

@michalvavrik
michalvavrik requested review from a team as code owners March 27, 2026 13:11
@michalvavrik
michalvavrik force-pushed the feature/admin-api-v2-cli-fetching branch from 05f7fc3 to 1b16c5f Compare March 27, 2026 14:19
@michalvavrik
Copy link
Copy Markdown
Member Author

I'll make couple of changes based on discussion in WG, so making it draft for a day or two. I'll update it and ping you all when it is ready for a review again.

@michalvavrik
michalvavrik marked this pull request as draft March 30, 2026 11:35
@michalvavrik
michalvavrik marked this pull request as ready for review April 1, 2026 09:25
@michalvavrik
michalvavrik force-pushed the feature/admin-api-v2-cli-fetching branch from 1b16c5f to 191b702 Compare April 1, 2026 09:26
@michalvavrik
Copy link
Copy Markdown
Member Author

@keycloak/cloud-native please review

@michalvavrik
michalvavrik force-pushed the feature/admin-api-v2-cli-fetching branch from 191b702 to 4a04f63 Compare April 7, 2026 18:23
@michalvavrik
Copy link
Copy Markdown
Member Author

resolved merge conflicts, @keycloak/cloud-native please review

@shawkins
shawkins commented Apr 8, 2026
Copy link
Copy Markdown
Contributor

It's not necessarily an issue to be solved for this pr, but it would be good to think about the version flag - that is what meaning will the -v2 flag have across resources? That is does "-v2 client list" have a consistent meaning with "-v2 user list" or will the user need to know down to a resource what -vN flag to use? And how will the cli logic adapt when a v3 is needed?

cc @vmuzikar

8000

@michalvavrik
Copy link
Copy Markdown
Member Author

hey, I am afraid I only have unsatisfactory answers, partly because I may not be catching all your thoughts:

It's not necessarily an issue to be solved for this pr, but it would be good to think about the version flag - that is what meaning will the -v2 flag have across resources?

--v2 flag picks API version (like when API manager allows you to choose API version), not a resource

That is does "-v2 client list" have a consistent meaning with "-v2 user list" or will the user need to know down to a resource what -vN flag to use?

Doesn't that really depends on how is the User API written, not this CLI? So I can't answer that because I don't know how will we write it. If we use the same logic, as was suggested by making API "generic", it won't be an issue.

Also, I think this question could be asked for the JS and Java client as well? They are in the same situation.

And how will the cli logic adapt when a v3 is needed?

I somehow expected that if the Keycloak server supports v2, over time we will pick it as a default, so it could always work like: stable api (v2) is a default and then other APIs (like deprecated v1) and experimental v3` API needs their respective flags. But we never talked about it or I don't remember, so I have no idea what is really intended for future API versions.

@shawkins
shawkins commented Apr 8, 2026
Copy link
Copy Markdown
Contributor

I somehow expected that if the Keycloak server supports v2, over time we will pick it as a default

That's related to the point I'm making - all of our resources are independently versioned. We'll have a clients v2, users v2, v3, etc. Any new constructs may start their numbering at v1. So if I omit the --v flag in the cli, there can't be a single default version. We'd have to determine that per resource.

Let me rephase what I'm saying this way - how would a user of the cli know what --vN flag to use, or what vN flag is in use should there be a default?

@michalvavrik
michalvavrik commented Apr 8, 2026 •
Copy link
Copy Markdown
Member Author

I somehow expected that if the Keycloak server supports v2, over time we will pick it as a default

That's related to the point I'm making - all of our resources are independently versioned. We'll have a clients v2, users v2, v3, etc. Any new constructs may start their numbering at v1. So if I omit the --v flag in the cli, there can't be a single default version. We'd have to determine that per resource.

I didn't know that resources can be independently versioned, that clarifies your previous comment for sure. It is wild though, the idea that I am using client resource version 1 and realm resource version 3, so we will recommend that with Keycloak version X we recommend to use resource-one 5 and resource-two 1. I think it would be better to version APIs, not each part of API, but that is not for me to decide.

In that case, following answer is only what I think, it wasn't agreed in any discussion:

Let me rephase what I'm saying this way - how would a user of the cli know what --vN flag to use

The same way you will know which API version you should use, that is: you pick the latest stable flag at the moment when you write your client-side logic and you stick with it until deprecation forces you to migrate. And that should be discoverable when you leave out the --vVERSION, it should show you defaults.

or what vN flag is in use should there be a default?

I think we should have defaults (like eventually default should be --v2), but we need to explicitly mention to users which API version are they using, so that they can add it explicitly to their command and avoid changes when the default changes.

Not sure if it is clear what I say, so for example consider situation when --v1 is a default for list resource, in which case all following:

# aka --v2 position is irrelevant
kcadm.sh --v2 client list
kcadm.sh client --v2 list
kcadm.sh client list

shows same, as well as all kcadm.sh --v5 should show resources that has API v5 and not show any resource that has not that API version.

@michalvavrik
michalvavrik commented Apr 8, 2026 •
Copy link
Copy Markdown
Member Author

And if resources are really versioned, not APIs, then I expect that I will have to tweak logic bit to make sure that version is not per YAML/JSON, but it is per resource. I'd prefer not do it in this PR as it blocks me from follow-ups that I have ready.

And defaults must be per-resource as well, so no global --v2 default.

@shawkins
shawkins commented Apr 8, 2026
Copy link
Copy Markdown
Contributor

I think it would be better to version APIs, not each part of API, but that is not for me to decide.

Sorry if some of my descriptions are hard to follow. To clarify the strategy is currently to have:

admin/api/clients/vX
admin/api/users/vY
admin/api/foo/vZ

Where X, Y, and Z can independently be any number of versions.

And that should be discoverable when you leave out the --vVERSION, it should show you defaults.

Yes, I'd like it to be clear somehere in that case what version is in use - especially because the version is not currently reflected in the resources (unlike Kubernetes, which populates an apiVersion field).

@michalvavrik
Copy link
Copy Markdown
Member Author

I think it would be better to version APIs, not each part of API, but that is not for me to decide.

Sorry if some of my descriptions are hard to follow. To clarify the strategy is currently to have:

admin/api/clients/vX admin/api/users/vY admin/api/foo/vZ

Where X, Y, and Z can independently be any number of versions.

Yeah, what you mention is clear from path and org.keycloak.admin.api.AdminApi, I just never realized it is per resource, because I didn't expect that is how it should work.

And that should be discoverable when you leave out the --vVERSION, it should show you defaults.

Yes, I'd like it to be clear somehere in that case what version is in use - especially because the version is not currently reflected in the resources (unlike Kubernetes, which populates an apiVersion field).

I think we can add it to help when user prints it out and we can print it to STD ERR (leaving std out for response body) when the flag is not explicitly included in the command so that user know.

Anyway, thanks for pointing it out, it means I'll have to make tweaks to the CLI generation as I call everything v2 but it will have to be more generic, including class names. It will make this PR larger though. I'll look into it tomorrow.

@shawkins
shawkins commented Apr 8, 2026
Copy link
Copy Markdown
Contributor

because I didn't expect that is how it should work.

There were quite a few discussions on this topic as you can imagine.

It will make this PR larger though. I'll look into it tomorrow.

If you want to capture it as a follow-up I'm good with that as well.

@michalvavrik
Copy link
Copy Markdown
Member Author

If you want to capture it as a follow-up I'm good with that as well.

This PR is basically about "fetch OpenAPI from Keycloak server", while what you pointed out is also valid for the default (bundled) OpenAPI document, so I'd suggest that I handle it in a separate PR. It will make reviews easier. I'll create a new sub-task tomorrow (and update this comment with a link). Thanks

@michalvavrik
Copy link
Copy Markdown
Member Author

Follow-up: #47881

Copilot AI 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.

Pull request overview

This PR enhances the Admin CLI Client API v2 mode to adapt its generated commands/help/autocomplete to the Keycloak server version of the current logged-in session by fetching and caching the server’s OpenAPI descriptor (with graceful fallback to the bundled descriptor when auto-fetch isn’t available).

Changes:

  • Add OpenAPI descriptor fetching (config openapi) and login-time auto-fetch (config credentials --openapi-url) with on-disk caching keyed by server.
  • Update v2 CLI help/autocomplete behavior and tests to reflect the new Ope 8BD0 nAPI-driven command structure.
  • Refactor/expand test coverage for caching, fallback behavior, and non-default management port scenarios.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
rest/admin-v2/tests/src/test/java/org/keycloak/tests/admin/cli/v2/AbstractKcAdmV2CLITest.java Adds shared helpers for v2 CLI integration tests (cache dir/config wiring).
rest/admin-v2/tests/src/test/java/org/keycloak/tests/admin/cli/v2/KcAdmV2ClientCLITest.java Adds test ensuring OpenAPI auto-fetch failure during login is graceful (no registry, warning emitted).
rest/admin-v2/tests/src/test/java/org/keycloak/tests/admin/cli/v2/KcAdmV2OpenApiFetchCLITest.java New integration tests for fetching/caching OpenAPI from URL/file and failure modes.
rest/admin-v2/tests/src/test/java/org/keycloak/tests/admin/cli/v2/KcAdmV2OpenApiUrlCLITest.java New integration test for --openapi-url on non-default management port and recovery via config openapi.
integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/KcAdmMain.java Passes CLI args into v2 root command so it can detect --config early (before picocli parsing).
integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/commands/ConfigCmd.java Adds v2-aware usage output (includes openapi subcommand and updated help hint).
integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/v2/KcAdmV2Cmd.java Loads cached server-specific descriptor when available; wires in config openapi and v2 config credentials.
integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/v2/KcAdmV2Completer.java Supports completion using a caller-provided cache dir (enables cached-descriptor completion tests).
integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/v2/KcAdmV2ConfigCredentialsCmd.java Adds --openapi-url and auto-fetch-on-login behavior with warnings on failure.
integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/v2/KcAdmV2ConfigOpenApiCmd.java New config openapi command to fetch/load OpenAPI from URL or local file and cache it for the current server.
integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/v2/KcAdmV2DescriptorBuilder.java Switches descriptor JSON read/write to shared OutputUtil.MAPPER.
integration/client-cli/admin-cli/src/main/java/org/keycloak/client/admin/cli/v2/KcAdmV2DescriptorCache.java New cache implementation storing a registry and descriptor files (shared across servers with same version).
integration/client-cli/admin-cli/src/main/java/org/keycloak/client/cli/common/BaseConfigCredentialsCmd.java Adds hook (printExtraOptions) so v2 credentials can extend the help output cleanly.
integration/client-cli/admin-cli/src/test/java/org/keycloak/client/admin/cli/commands/v2/KcAdmV2CachedDescriptorHelpTest.java New tests verifying help/autocomplete use cached descriptor when a server entry exists, otherwise fallback.
integration/client-cli/admin-cli/src/test/java/org/keycloak/client/admin/cli/commands/v2/KcAdmV2CompleterTest.java Extends autocomplete tests to cover v2 config subcommands and new options.
integration/client-cli/admin-cli/src/test/java/org/keycloak/client/admin/cli/commands/v2/KcAdmV2DescriptorCacheTest.java New unit tests for cache registry behavior and descriptor file sharing/removal.
integration/client-cli/admin-cli/src/test/java/org/keycloak/client/admin/cli/commands/v2/KcAdmV2HelpTest.java Extends help tests for completion instructions and OpenAPI-related help/args.

@michalvavrik
michalvavrik force-pushed the feature/admin-api-v2-cli-fetching branch from 4a04f63 to c0dfe6b Compare April 9, 2026 15:44
@michalvavrik
michalvavrik requested a review from Copilot April 9, 2026 15:45
Copilot AI 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.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated no new comments.

@michalvavrik
michalvavrik force-pushed the feature/admin-api-v2-cli-fetching branch from c0dfe6b to 3561646 Compare April 9, 2026 15:54
* Closes: keycloak#47171
* Adds information about autocomplete to the v2 help

**More about OpenAPI document fetching:**

When Admin CLI is used with a different Keycloak server version, we need to update help and autocomplete according to OpenAPI document, which describes what endpoints and schemas can be used. This can only be done when the Keycloak server has enabled (currently experimental) OpenAPI feature and users specify OpenAPI path. The management path and port can be changed by user, therefore we ask them to specify OpenAPI URL entirely.

This feature is only provided for the current session (when user is logged in into some server). We cannot easily provide help and autocomplete based on inline arguments like `--server` because it is bit chicken-egg problem (injected options are available after you provided command to PicoCLI, so we would need to do a lot manually).

Here is how it works:

```bash
mvavrik@fedora:~/sources/keycloak$ kcadm.sh --v2 config credentials --server http://localhost:8080 --realm master --user admin --password admin
Logging into http://localhost:8080 as user admin of realm master
OpenAPI descriptor cached for http://localhost:8080 (version 999.0.0-SNAPSHOT)

```

or for non-default management port:

```bash
mvavrik@fedora:~/sources/keycloak$ kcadm.sh --v2 config credentials --server http://localhost:8080 --realm master --user admin --password admin
Logging into http://localhost:8080 as user admin of realm master
mvavrik@fedora:~/sources/keycloak$ kcadm.sh --v2 config openapi http://localhost:9004/openapi
OpenAPI descriptor cached for http://localhost:8080 (version 999.0.0-SNAPSHOT)
```

or alternatively:

```bash
mvavrik@fedora:~/sources/keycloak$ kcadm.sh --v2 config credentials --server http://localhost:8080 --realm master --user admin --password admin --openapi-url http://localhost:9004/openapi
Logging into http://localhost:8080 as user admin of realm master
OpenAPI descriptor cached for http://localhost:8080 (version 999.0.0-SNAPSHOT)
```

After that, command structure reflects the OpenAPI document, including help and autocomplete. If you switch server using `config credentials`, command changes as well. If the server you are communicating does not provide OpenAPI endpoint, we silently fallback to the default OpenAPI document (bundled with the command). However,
the `kcadm.sh --v2 config openapi` fails if the OpenAPI endpoint wasn't available.

Signed-off-by: Michal Vavřík <michal.vavrik@aol.com>
@michalvavrik
michalvavrik force-pushed the feature/admin-api-v2-cli-fetching branch from 3561646 to 030e66f Compare April 9, 2026 15:57
@shawkins shawkins 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.

Thank you @michalvavrik

Approving based upon my initial reivew and running kcadm, the follow-up issue, and that the copilot review items were addressed.

@michalvavrik
Copy link
Copy Markdown
Member Author

hey @mabartos || @Pepo48 || @vmuzikar I'd love to make some progress on follow-ups once this is done (there is quite many of them), it would be grand if you could find a time to review. Thank you

@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.

LGTM, thanks, nice work @michalvavrik

@vmuzikar
vmuzikar merged commit d4cd088 into keycloak:main Apr 10, 2026
85 checks passed
@michalvavrik
michalvavrik deleted the feature/admin-api-v2-cli-fetching branch April 10, 2026 16:49
@stianst stianst mentioned this pull request Jun 1, 2026
sashyo pushed a commit to tide-foundation/keycloak-IGA that referenced this pull request Jul 20, 2026
…keycloak#47525)

* Closes: keycloak#47171
* Adds information about autocomplete to the v2 help

**More about OpenAPI document fetching:**

When Admin CLI is used with a different Keycloak server version, we need to update help and autocomplete according to OpenAPI document, which describes what endpoints and schemas can be used. This can only be done when the Keycloak server has enabled (currently experimental) OpenAPI feature and users specify OpenAPI path. The management path and port can be changed by user, therefore we ask them to specify OpenAPI URL entirely.

This feature is only provided for the current session (when user is logged in into some server). We cannot easily provide help and autocomplete based on inline arguments like `--server` because it is bit chicken-egg problem (injected options are available after you provided command to PicoCLI, so we would need to do a lot manually).

Here is how it works:

```bash
mvavrik@fedora:~/sources/keycloak$ kcadm.sh --v2 config credentials --server http://localhost:8080 --realm master --user admin --password admin
Logging into http://localhost:8080 as user admin of realm master
OpenAPI descriptor cached for http://localhost:8080 (version 999.0.0-SNAPSHOT)

```

or for non-default management port:

```bash
mvavrik@fedora:~/sources/keycloak$ kcadm.sh --v2 config credentials --server http://localhost:8080 --realm master --user admin --password admin
Logging into http://localhost:8080 as user admin of realm master
mvavrik@fedora:~/sources/keycloak$ kcadm.sh --v2 config openapi http://localhost:9004/openapi
OpenAPI descriptor cached for http://localhost:8080 (version 999.0.0-SNAPSHOT)
```

or alternatively:

```bash
mvavrik@fedora:~/sources/keycloak$ kcadm.sh --v2 config credentials --server http://localhost:8080 --realm master --user admin --password admin --openapi-url http://localhost:9004/openapi
Logging into http://localhost:8080 as user admin of realm master
OpenAPI descriptor cached for http://localhost:8080 (version 999.0.0-SNAPSHOT)
```

After that, command structure reflects the OpenAPI document, including help and autocomplete. If you switch server using `config credentials`, command changes as well. If the server you are communicating does not provide OpenAPI endpoint, we silently fallback to the default OpenAPI document (bundled with the command). However,
the `kcadm.sh --v2 config openapi` fails if the OpenAPI endpoint wasn't available.

Signed-off-by: Michal Vavřík <michal.vavrik@aol.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fetch OpenAPI document from server and adjut Client API v2 CLI client according to the server it communicates it

4 participants

0