helm-schema icon indicating copy to clipboard operation
helm-schema copied to clipboard

Root-level `oneOf`?

Open mircea-pavel-anton opened this issue 1 year ago • 2 comments

Say I have a helm chart with this values.yaml:

---
# @schema
# required: true
# type: string
# @schema
valueA: ""

# @schema
# required: false
# type: string
# @schema
valueB: ""

# @schema
# required: false
# type: string
# @schema
valueC: ""

And what I want is to have valueA always required, but then only one of valueB or valueC. They are mutually exclusive.

If I generate the schema, I get this:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "additionalProperties": false,
  "properties": {
    "global": {
      "description": "Global values are values that can be accessed from any chart or subchart by exactly the same name.",
      "required": [],
      "title": "global",
      "type": "object"
    },
    "valueA": {
      "default": "",
      "required": [],
      "title": "valueA",
      "type": "string"
    },
    "valueB": {
      "default": "",
      "required": [],
      "title": "valueB",
      "type": "string"
    },
    "valueC": {
      "default": "",
      "required": [],
      "title": "valueC",
      "type": "string"
    }
  },
  "required": [
    "valueA"
  ],
  "type": "object"
}

Which is expected, and what I want essentially is to also include this block:

  "oneOf": [
    {
      "required": [
        "valueB"
      ]
    },
    {
      "required": [
        "valueC"
      ]
    }
  ],

To get this:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "additionalProperties": false,
  "properties": {
    "global": {
      "description": "Global values are values that can be accessed from any chart or subchart by exactly the same name.",
      "required": [],
      "title": "global",
      "type": "object"
    },
    "valueA": {
      "default": "",
      "required": [],
      "title": "valueA",
      "type": "string"
    },
    "valueB": {
      "default": "",
      "required": [],
      "title": "valueB",
      "type": "string"
    },
    "valueC": {
      "default": "",
      "required": [],
      "title": "valueC",
      "type": "string"
    }
  },
  "required": [
    "valueA"
  ],
  "oneOf": [
    {
      "required": [
        "valueB"
      ]
    },
    {
      "required": [
        "valueC"
      ]
    }
  ],
  "type": "object"
}

It is not clear to me how to do this with the current comment-annotations

mircea-pavel-anton avatar Sep 10 '24 21:09 mircea-pavel-anton

Currently not possible

dadav avatar Sep 11 '24 07:09 dadav

Leaving it here for others running into the same limitation.

I was able to work around this by adding a validation in my templates:

{{- if .Values.valueB }} 
   {{- if .Values.valueC }} 
     {{- fail "Value B and C are mutually exclusive!" }} 
   {{- end }} 
{{- end }}

Granted, this is not an ideal solution as it will fail at apply-time, but it ultimately achieves the same goal... Mostly

mircea-pavel-anton avatar Sep 11 '24 08:09 mircea-pavel-anton