Skip to content

Conversation

@qvalentin
Copy link
Contributor

@qvalentin qvalentin commented Apr 19, 2025

What does this PR do?

This PR adds an option to automatically detect the Kubernetes schema by parsing the contents of the document. In case a Kubernetes GroupVersionKind (GVK) is detected, the matching schema is retrieved from the CRD catalog.

What issues does this PR fix or reference?

#605

Is it tested? How?

Tests for parsing the Kubernetes Group Version Kind have been added

Updated version of #962 including the following changes:

  • only run the auto-detect for files that are registered with the kubernetes schema
  • check if the Kubernetes GroupVersionKind is already defined in the main kubernetes schema, if so, don't look it up in the CRD catalog
  • add config option for crd catalog uri
  • more tests

TODO:

  • final testing
  • add new options to readme

@qvalentin qvalentin changed the title Crd feat: auto-detect Kubernetes crd schema Apr 19, 2025
@tricktron
Copy link

@qvalentin Thanks for the nice work. I actually started working on this as well: https://github.com/tricktron/yaml-language-server/tree/f-kubernetes-improvements

However, I just hardcoded the core kubernetes groups but yours looks better in my opinion. I then actually got sidetracked by adding some more features to my https://github.com/tricktron/crd2jsonschema tool so that I could easily test end-to-end with the newest openshift and tekton crds.

Maybe you can also take over some tests from my my branch, e.g. main...tricktron:yaml-language-server:f-kubernetes-improvements#diff-5d1a1b48130b3cb749d3ae36d72e52f8882d6fa5dc9eaedc5d6e606e411b176cR1194-R1219

And lastly, we should then probably add some documentation as well. This might be a breaking change for the helm language server where you hardcode the kubernetes schemas to templates/**. E.g. this is not needed anymore with this pr and I think it even results in some errors if I remember correctly from my e2e tests. Anyway, I won´t have much time to look at this until next Wednesday but still wanted to give you a fast feedback.

@qvalentin
Copy link
Contributor Author

@tricktron I took a look at the schemaValidation.test.ts but since in my logic the customSchemaProvider has higher priority then the CRD logic the tests don't work with my branch.

But I might copy the config options format.

@qvalentin
Copy link
Contributor Author

Hi @msivasubramaniaan what are your thoughts on this?

ricoberger added a commit to ricoberger/yaml-language-server that referenced this pull request Sep 9, 2025
Add an option to overwrite the default Kubernetes schema URL with a
custom one, by setting a `YAMLLS_KUBERNETES_SCHEMA_URL` environment
variable.

See
- redhat-developer#998
- redhat-developer#824
- redhat-developer#841
- redhat-developer#962
- redhat-developer#1050

Main use case is to use
https://github.com/ricoberger/kubernetes-json-schema, which contains the
schema for Kubernetes and the CRDs I'm using.
@qvalentin qvalentin requested a review from datho7561 as a code owner December 18, 2025 11:42
@datho7561 datho7561 moved this to Todo in Java Tooling Dec 18, 2025
@datho7561
Copy link
Contributor

I'll try to take a look at this sometime this afternoon, it seems really helpful.

@datho7561
Copy link
Contributor

datho7561 commented Dec 18, 2025

The tests are failing it seems, with a type error

@coveralls
Copy link

coveralls commented Dec 19, 2025

Coverage Status

coverage: 83.637% (-0.04%) from 83.677%
when pulling ba55b1a on qvalentin:crd
into 769a8f7 on redhat-developer:main.

@datho7561
Copy link
Contributor

datho7561 commented Dec 19, 2025

I'm trying out:

apiVersion: route.openshift.io/v1
kind: Route
spec:

It seems it was trying to use a custom schema provider instead of the crd schema autodetection, so I made this change:

diff --git a/src/languageservice/services/yamlSchemaService.ts b/src/languageservice/services/yamlSchemaService.ts
index 432851f..9102233 100644
--- a/src/languageservice/services/yamlSchemaService.ts
+++ b/src/languageservice/services/yamlSchemaService.ts
@@ -430,6 +430,22 @@ export class YAMLSchemaService extends JSONSchemaService {
       return resolveSchemaForResource([modelineSchema]);
     }

+    if (this.yamlSettings?.kubernetesCRDStoreEnabled) {
+      for (const entry of this.filePatternAssociations) {
+        if (entry.uris && entry.uris[0] == KUBERNETES_SCHEMA_URL && entry.matchesPattern(resource)) {
+          return resolveSchemaForResource([KUBERNETES_SCHEMA_URL]).then((schema) => {
+            const kubeSchema = autoDetectKubernetesSchemaFromDocument(
+              doc,
+              this.yamlSettings.kubernetesCRDStoreUrl ?? CRD_CATALOG_URL,
+              schema
+            );
+            if (kubeSchema) {
+              return resolveSchemaForResource([kubeSchema]);
+            }
+          });
+        }
+      }
+    }
     if (this.customSchemaProvider) {
       return this.customSchemaProvider(resource)
         .then((schemaUri) => {
@@ -473,22 +489,6 @@ export class YAMLSchemaService extends JSONSchemaService {
           }
         );
     }
-    if (this.yamlSettings?.kubernetesCRDStoreEnabled) {
-      for (const entry of this.filePatternAssociations) {
-        if (entry.uris && entry.uris[0] == KUBERNETES_SCHEMA_URL && entry.matchesPattern(resource)) {
-          return resolveSchemaForResource([KUBERNETES_SCHEMA_URL]).then((schema) => {
-            const kubeSchema = autoDetectKubernetesSchemaFromDocument(
-              doc,
-              this.yamlSettings.kubernetesCRDStoreUrl ?? CRD_CATALOG_URL,
-              schema
-            );
-            if (kubeSchema) {
-              return resolveSchemaForResource([kubeSchema]);
-            }
-          });
-        }
-      }
-    }
     return resolveSchema();
   }

After I do that and try to validate the YAML, I get "Unable to load schema..." as an error in the YAML, since the calculated URL doesn't line up with the location of the schema in the repo (the OpenShift CRDs are split across multiple group ids, whereas in the repo with the CRDs all the schemas are in the folder "openshift/v4.11-strict").

After this I decided to try out:

apiVersion: mysql.oracle.com/v2
kind: InnoDBCluster
spec:

And that appears to work after applying the above patch, but the patch appears to break many other tests.

@qvalentin
Copy link
Contributor Author

qvalentin commented Dec 19, 2025

Hi @datho7561 I'm not sure what should have higher priority, a custom schema provider or the crd check. I would guess the custom schema provider?

I'm just using the lsp with neovim where no custom schema provider is active. I wonder which provider is active in your setup.

So the mysql example is working for me, but indeed the openshift one is not.
I wonder if there is anything we can do for those schemas that do not respect the common convention of apiVersion and Kind for the schema url.

Edit: I took a quick look at the catalog and it seems openshift is the only directory that is not using an API group name. I would say it's just a bad example and should be treated separately.

@datho7561
Copy link
Contributor

@qvalentin

I wonder which provider is active in your setup.

I'm using vscode-yaml; when vscode-yaml is used, there's a custom schema provider active in yaml-language-server that sends a custom LSP request custom/schema/request to the client (vscode-yaml). If vscode-yaml provides a schema in the response, then that one is used, and if vscode-yaml provides an empty response, resolveSchema is called. This means that even if no custom schema is provided, the code to resolve the CRD schema is never called when a custom schema provider is present (which is always for vscode-yaml).

If you move the CRD resolving code into the resolveSchema function instead, that seems to fix it. Then, you can clean up the code by adding the code into the existing loop over the file associations. I'll add a commit that does this.

I wonder if there is anything we can do for those schemas that do not respect the common convention of apiVersion and Kind for the schema url.

I have written a hack to get the correct URL for OpenShift CRDs, I'll also push this as a commit.


// eslint-disable-next-line @typescript-eslint/no-explicit-any
const resolveSchema = (): any => {
const resolveSchema = async (): Promise<any> => {

Check warning

Code scanning / ESLint

Disallow the `any` type Warning

Unexpected any. Specify a different type.
@datho7561 datho7561 moved this from Todo to Pending review in Java Tooling Dec 30, 2025
ricoberger added a commit to ricoberger/yaml-language-server that referenced this pull request Jan 7, 2026
Add an option to overwrite the default Kubernetes schema URL with a
custom one, by setting a `YAMLLS_KUBERNETES_SCHEMA_URL` environment
variable.

See
- redhat-developer#998
- redhat-developer#824
- redhat-developer#841
- redhat-developer#962
- redhat-developer#1050

Main use case is to use
https://github.com/ricoberger/kubernetes-json-schema, which contains the
schema for Kubernetes and the CRDs I'm using.
@datho7561
Copy link
Contributor

@qvalentin I think this feature is ready for merge after the changes I made. Let me know if you have objections to anything I changed or if it doesn't work for you. I'm planning on merging this Monday otherwise.

rowahl and others added 7 commits January 12, 2026 12:04
The CRD schema resolving logic now runs even if a custom schema provider
is present,
allowing this to work properly in vscode-yaml.

Signed-off-by: David Thompson <[email protected]>
The CRD schemas for OpenShift are layed out slightly different from
everything else in the CRD schema repo in order to provide different
sets of schemas for different versions of OpenShift.

Signed-off-by: David Thompson <[email protected]>
@datho7561 datho7561 merged commit 5268a03 into redhat-developer:main Jan 12, 2026
4 checks passed
@github-project-automation github-project-automation bot moved this from Pending review to Done in Java Tooling Jan 12, 2026
datho7561 added a commit to datho7561/vscode-yaml that referenced this pull request Jan 12, 2026
See redhat-developer/yaml-language-server#1050

Settings to enable/disable the feature and change the repository used to
find CRD schemas.

Use
https://raw.githubusercontent.com/nlamirault/crd-schema-store/refs/heads/main/schemas
to test an alternate store of CRD schemas.

Signed-off-by: David Thompson <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

6 participants