Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: support for Kubernetes CRDs #132

Open
lionelvillard opened this issue Mar 6, 2019 · 10 comments
Open

Feature Request: support for Kubernetes CRDs #132

lionelvillard opened this issue Mar 6, 2019 · 10 comments

Comments

@lionelvillard
Copy link

I tried to use yaml.schemas to associate kubernetes CRD schemas but this is not working. I added this entry to vscode user settings:

"yaml.schemas": {
        "file:///path/to/application-swagger-latest.json": "/**"
    }

I also tried:

"yaml.schemas": {
        ./path/to/application-swagger-latest.json": "/**"
    }

with no success.

@JPinkney
Copy link
Contributor

JPinkney commented Mar 7, 2019

I'm not sure where "./path/to/application-swagger-latest.json" to points too but the path has to be relative to the root of the folder you have opened

For example, if the project hierarchy is:

Myfolder (this being the root)
  - my_schema.json
  - my_file.yaml

you should just need to do

"yaml.schemas": {
        "./my_schema.json": "/**"
}

and it should pick it up in my_file.yaml. If it doesn't not let me know and I can try and look into it further!

@lionelvillard
Copy link
Author

I tried multiple configurations, no success so far. My environment is vscode with only one folder open. After changing the configuration I reloaded the window.

First configuration:

schemas/
  application-swagger-latest.json
  app.yaml

user settings:

"yaml.schemas": {
        "./schemas/application-swagger-latest.json": "./schemas/app.yaml"
    }

I get this error: Unable to load schema from 'kubernetes://schema/app.k8s.io@application': No content.

Second configuration:

./
  application-swagger-latest.json
  app.yaml

user settings:

"yaml.schemas": {
        "./application-swagger-latest.json": "./app.yaml"
    }

Error: I get this error: Unable to load schema from 'kubernetes://schema/app.k8s.io@application': No content.

Maybe schema extension does not work for Kubernetes YAMLs?

@JPinkney
Copy link
Contributor

JPinkney commented Mar 7, 2019

So if you're getting that error that means that its at least attempting to associate the schema to the file. Is there anyway you can post the schema and the contents of the text file. Presumably kubernetes://schema/app.k8s.io@application error is because it thinks its an address where it can grab content from but I don't know enough about kubernetes to know whether that is an actually somewhere that it can grab content from or if the problem is that the language server is attempting to resolve it when it shouldn't.

@lionelvillard
Copy link
Author

the schema is this one:

{
  "oneOf": [
    {
      "$ref": "#/definitions/com.github.kubernetes-sigs.application.pkg.apis.app.v1beta1.Application"
    }
  ],
  "definitions": {
    "com.github.kubernetes-sigs.application.pkg.apis.app.v1beta1.Application": {
      "description": "Application is the Schema for the applications API",
      "type": "object",
      "properties": {
        "apiVersion": {
          "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources",
          "type": "string"
        },
        "kind": {
          "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds",
          "type": "string"
        },
        "metadata": {
          "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta"
        },
        "spec": {
          "$ref": "#/definitions/com.github.kubernetes-sigs.application.pkg.apis.app.v1beta1.ApplicationSpec"
        },
        "status": {
          "$ref": "#/definitions/com.github.kubernetes-sigs.application.pkg.apis.app.v1beta1.ApplicationStatus"
        }
      },
      "x-kubernetes-group-version-kind": [
        {
          "group": "app.k8s.io",
          "version": "v1beta1",
          "kind": "Application"
        }
      ]
    },
...

@julianKatz
Copy link

I'd love to see a way to easily exempt certain files from validation. That would be enough for me day-to-day. For example, any file named my_custom_resource.yaml would be exempt from validation.

Is there a way to do that with the current glob support?

@Cerebus
Copy link

Cerebus commented Jan 25, 2023

If anyone is still following this, the underlying problem seems to be that the OpenAPIv3 doesn't validate against JSON schema, mainly b/c of circular references. The published K8s Open schemas are converted using openapi2jsonschema.

So--

  • kubectl get --raw /openapi/v2 and snag your cluster schema
  • openapi2jsonschema --stand-alone --kubernetes --expanded on your OpenAPIv3 JSON, putting them in a directory somewhere (-o flag)
  • "yaml.schemas": { ./path/to/your/dir/all.json": "/**" }

Caveats--

  • CRDs don't resolve. I'm sure there's a reason. The schemas (schemae?) are there, but the LSP won't suggest them (e.g., in apiVersion: value completions).

ETA: I am getting back an interesting error:

[server-notification] Wed Jan 25 10:44:05 2023:
(:jsonrpc "2.0" :method "textDocument/publishDiagnostics" :params
          (:uri "file:///Users/some/path/examples/meteor-load/base/cm.yaml" :diagnostics
                [(:range
                  (:start
                   (:line 1 :character 0)
                   :end
                   (:line 1 :character 1))
                  :message "Matches multiple schemas when only one must validate." :severity 1 :code 0 :source "yaml-schema: file:///Users/some/path/prototype/scratch/prototype-standalone/all.json" :data
                  (:schemaUri
                   ["file:///Users/some/path/prototype/scratch/prototype-standalone/all.json"]))]))

This doesn't seem to be affecting anything, b/c standard K8s resources are validating/completing, but CRDs do not. So...working as designed, maybe?

@Cerebus
Copy link

Cerebus commented Jan 25, 2023

Ok, this is progress of a sort:

  • openapi2json --kubernetes, no other flags required. This generates all the individual CRD JSON schema files.
  • Some CRDs validate properly, others do not. E.g., I can't get cert-manager.io/v1 resources to validate, but flink.apache.org/v1beta1 does:
[client-request] (id:74) Wed Jan 25 14:02:36 2023:
(:jsonrpc "2.0" :id 74 :method "textDocument/completion" :params
          (:textDocument
           (:uri "file:///Users/some/path/prototype/examples/meteor-load/base/flink.yaml")
           :position
           (:line 6 :character 5)
           :context
           (:triggerKind 1)))
[server-reply] (id:74) Wed Jan 25 14:02:36 2023:
(:jsonrpc "2.0" :id 74 :result
          (:items
           [(:kind 10 :label "flinkConfiguration" :insertText "flinkConfiguration:\n  " :insertTextFormat 2 :documentation "" :textEdit
                   (:range
                    (:start
                     (:line 6 :character 2)
                     :end
                     (:line 6 :character 5))
                    :newText "flinkConfiguration:\n  "))
            (:kind 10 :label "flinkVersion" :insertText "flinkVersion: " :insertTextFormat 2 :documentation "" :textEdit
                   (:range
                    (:start
                     (:line 6 :character 2)
                     :end
                     (:line 6 :character 5))
                    :newText "flinkVersion: "))
            (:kind 10 :label "image" :insertText "image: " :insertTextFormat 2 :documentation "" :textEdit
                   (:range
                    (:start
                     (:line 6 :character 2)
                     :end
                     (:line 6 :character 5))
                    :newText "image: "))
            (:kind 10 :label "imagePullPolicy" :insertText "imagePullPolicy: " :insertTextFormat 2 :documentation "" :textEdit
                   (:range
                    (:start
                     (:line 6 :character 2)
                     :end
                     (:line 6 :character 5))
                    :newText "imagePullPolicy: "))
            (:kind 10 :label "ingress" :insertText "ingress:\n  " :insertTextFormat 2 :documentation "" :textEdit
                   (:range
                    (:start
                     (:line 6 :character 2)
                     :end
                     (:line 6 :character 5))
                    :newText "ingress:\n  "))
            (:kind 10 :label "job" :insertText "job:\n  " :insertTextFormat 2 :documentation "" :textEdit
                   (:range
                    (:start
                     (:line 6 :character 2)
                     :end
                     (:line 6 :character 5))
                    :newText "job:\n  "))
            (:kind 10 :label "jobManager" :insertText "jobManager:\n  " :insertTextFormat 2 :documentation "" :textEdit
                   (:range
                    (:start
                     (:line 6 :character 2)
                     :end
                     (:line 6 :character 5))
                    :newText "jobManager:\n  "))
            (:kind 10 :label "logConfiguration" :insertText "logConfiguration:\n  " :insertTextFormat 2 :documentation "" :textEdit
                   (:range
                    (:start
                     (:line 6 :character 2)
                     :end
                     (:line 6 :character 5))
                    :newText "logConfiguration:\n  "))
            (:kind 10 :label "mode" :insertText "mode: " :insertTextFormat 2 :documentation "" :textEdit
                   (:range
                    (:start
                     (:line 6 :character 2)
                     :end
                     (:line 6 :character 5))
                    :newText "mode: "))
            (:kind 10 :label "podTemplate" :insertText "podTemplate:\n  " :insertTextFormat 2 :documentation "" :textEdit
                   (:range
                    (:start
                     (:line 6 :character 2)
                     :end
                     (:line 6 :character 5))
                    :newText "podTemplate:\n  "))
            (:kind 10 :label "restartNonce" :insertText "restartNonce: ${1:0}" :insertTextFormat 2 :documentation "" :textEdit
                   (:range
                    (:start
                     (:line 6 :character 2)
                     :end
                     (:line 6 :character 5))
                    :newText "restartNonce: ${1:0}"))
            (:kind 10 :label "serviceAccount" :insertText "serviceAccount: " :insertTextFormat 2 :documentation "" :textEdit
                   (:range
                    (:start
                     (:line 6 :character 2)
                     :end
                     (:line 6 :character 5))
                    :newText "serviceAccount: "))
            (:kind 10 :label "taskManager" :insertText "taskManager:\n  " :insertTextFormat 2 :documentation "" :textEdit
                   (:range
                    (:start
                     (:line 6 :character 2)
                     :end
                     (:line 6 :character 5))
                    :newText "taskManager:\n  "))]
           :isIncomplete :json-false))

So clearly this is an issue with the CRDs. Maybe it's down to the version of kubebuilder or whatever, or specific options therein.

@Cerebus
Copy link

Cerebus commented Jan 25, 2023

There's some kind of parse error in here, b/c if I explicitly ask for completion at point, where point is a blank line immediately after the kind, I get a completion offering the fields name, uid, fieldPath, namespace, and resourceVersion. None of which appear in this specific kind. 🤔

image

From the description strings, name and uid seem to be coming from BoundObjectReference, while fieldPath, namespace, and resourceVersion are coming from ObjectReference.

@Cerebus
Copy link

Cerebus commented Jan 25, 2023

And this is really weird:
image

@samos667
Copy link

samos667 commented Apr 18, 2024

My behavior is really funny too. I test with flux CRD "Kustomization". This is my schema config:

"https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json" = "*.k8s.ccrd.flux.k.yaml",
"https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v1.29.4/all.json"="*.k8s.*.yaml",

When I edit a file name test.k8s.crrd.flux.k.yaml, in spec when I ask completion with this "r".
image

I got "replicas" as possibility (+ all other possibilities in a spec:) and when I select it and go in normal mode, I got this message:
image

That tell me I'm wrong and it's totally true.

I have found only this way to manage schema detection work. If someone have a better solution to get custom CRD work I take it !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants