Search code examples
kubernetes-helmjsonschemahelm3

How do I support multiple top level namespaces in a single json schema document? This is for helm sub charts


I know "namespace" isn't the right term, but I had trouble finding this use case explained in the json schema docs or online.

I use json schema for a helm sub chart. Without going into helm specifics this means this schema is going to be used to validate a yaml doc that looks like this (in the sub charts own project):

# values.yaml in mysubchart
propOne:
 derp: 123
 herp: abc

And also yaml docs that look like this (in the parent chart project):

# values.yaml in mysubchart
mysubchart:
    propOne:
     derp: 123
     herp: abc

So I have two docs i want to validate with the same schema. The only difference is one of the docs has a single top level field everything is nested under (mysubchart:)

Is it possible to support both docs with the same json schema? Helm will validate the schema with helm lint without issue, but I also want users to be able to point their editors to a json schema I publish to validate the values yamls in the parent chart and get autocomplete, etc.

EDIT

I tried this but it doesn't validate for either yaml doc:

{
    "$defs": {
        "mychart": {
            "$schema": "http://json-schema.org/schema#",
            "title": "test",
            "description": "test",
            "type": "object",
            "required": [
                "propOne",
                "propTwo"
            ],
            "properties": {
                "propOne": {
                    "description": "sdkfjlsdfjlksdjf",
                    "type": "string"
                },
                "propTwo": {
                    "description": "sdkfjlsdfjlksdjf",
                    "type": "string"
                },
            }
        },
    },
    "oneOf": [
        {
            "$ref": "#/$defs/mychart"
        },
        {
            "properties": {
                "mychart": {
                    "$defs": "#/$defs/mychart"
                }
            }
        }
    ]
}

It looks like this works for validating my first yaml doc:

"anyOf": [
    {
        "$ref": "#/$defs/mychart"
    }
] 

But adding the second element with properties to try to validate the second doc screws it up and neither validates correctly

This works I was missing the required:mysubchart part of the config


Solution

  • You can combine multiple schemas with oneOf, and move the common elements into a definition referenced by both schemas:

      $defs:
        chart:
          type: object
          required: [ propOne ]
          properties:
            propOne:
              required: [ derp, herp ]
              properties:
                derp:
                  type: integer
                herp:
                  type: string
      type: object
      oneOf:
      - $ref: '#/$defs/chart'
      - required: [ mysubchart ]
        properties:
          mysubchart:
            $defs: '#/$defs/chart'
    

    If you are using an implementation that only supports draft7 or earlier, then change $defs to definitions.

    Combining schemas is covered at https://json-schema.org/understanding-json-schema/reference/combining.html.