{ "$schema": "https://json-schema.org/draft-07/schema#", "title": "xxx values", "description": "Reference values schema (issue #68). Copy this file alongside the rest of template-chart and replace every xxx. Two rules carry the whole idea: additionalProperties is false on every chart-owned object level, so a key the chart does not read is rejected at render time instead of being silently ignored; and the objects that go verbatim into the Kubernetes pod spec (probes, security contexts, global, free-form annotations) stay open, because the chart does not interpret their contents and cannot judge which keys are meaningful. The hardening, probe and resources blocks additionally accept null - see the note on that in the definitions below.", "type": "object", "additionalProperties": false, "properties": { "global": { "description": "Helm's conventional cross-chart values. Unused by this chart, kept open so an umbrella install cannot break on it.", "type": "object" }, "scaleDown": { "type": "boolean" }, "secrets": { "type": "object", "additionalProperties": false, "properties": { "xxxSecretRef": { "description": "op:// item path. Name the key exactly as the template reads it - a plausible abbreviation is a dead key, and this schema is what turns it into a named error instead of a missing secret.", "type": ["string", "null"] } } }, "xxx": { "type": "object", "additionalProperties": false, "properties": { "replicas": { "type": "integer", "minimum": 0 }, "resources": { "$ref": "#/definitions/resources" }, "livenessProbe": { "$ref": "#/definitions/probe" }, "readinessProbe": { "$ref": "#/definitions/probe" }, "startupProbe": { "$ref": "#/definitions/probe" }, "securityContext": { "$ref": "#/definitions/securityContext" }, "ports": { "description": "Rendered verbatim as the container's ports list; kept open because the chart does not interpret the entries.", "type": ["array", "null"] }, "env": { "$ref": "#/definitions/env" } } }, "storage": { "description": "The data PVC. Deliberately NOT null-safe: an erased block yields an invalid PVC, which fails loudly. Issue #99 covers only the silent class - an error that shows itself needs no fallback, and every extra bit of template logic has to be read by someone.", "type": "object", "additionalProperties": false, "properties": { "amount": { "type": ["string", "null"] }, "storageClass": { "type": ["string", "null"] } } }, "ingress": { "type": "object", "additionalProperties": false, "properties": { "enabled": { "description": "Gates the whole Ingress template (issue #93). Whether switching it off also frees domain depends on the chart: if anything outside the Ingress template reads ingress.domain, that read needs its own required() and the value stays mandatory. Check, do not assume (guideline 1).", "type": "boolean" }, "clusterIssuer": { "type": ["string", "null"] }, "domain": { "type": ["string", "null"] }, "className": { "type": ["string", "null"] }, "annotations": { "description": "Extra Ingress annotations, merged with the cert-manager annotation the chart always sets. Free-form keys by nature, so this object stays open. No counterpart in Gateway mode: the Gateway API has no annotation channel, so these are gone when httpRoute.enabled is used instead.", "type": "object" } } }, "httpRoute": { "description": "Gateway-API alternative to the Ingress (Gitea #114). Mutually exclusive with ingress.enabled - the render aborts when both are true. The chart renders only an HTTPRoute with parentRefs; class and certificate sit on the Gateway and belong to the platform. The Gateway-API CRDs must be present in the cluster, because the chart cannot detect them.", "type": "object", "additionalProperties": false, "properties": { "enabled": { "type": "boolean" }, "parentRefs": { "description": "The Gateway(s) the route attaches to. Required while httpRoute.enabled is true, and enforced in the template (an empty list aborts the render) - a JSON Schema \"required\" cannot do it, because the key ships as an empty list and is therefore present. Entries are the Gateway API's ParentReference and are passed through unchanged.", "type": "array", "items": { "$ref": "#/definitions/parentRef" } }, "hostnames": { "description": "Empty means [ingress.domain], so the hostname has a single source of truth.", "type": "array", "items": { "type": "string" } } } } }, "definitions": { "parentRef": { "description": "A Gateway API ParentReference, passed verbatim into HTTPRoute.spec.parentRefs. Deliberately left OPEN (no additionalProperties: false), for the same reason probes and security contexts are: Kubernetes owns this schema, the Gateway API adds fields to it across releases, and a closed list here would reject a field only upstream knows about. What a chart can assert is that \"name\" is there - it is required by the API, and a reference without it attaches to nothing, which is the silent failure the render aborts over.", "type": "object", "required": ["name"] }, "resources": { "description": "May be null / empty: the chart then falls back to its default requests and computed limits (issue #99) instead of rendering a container without resource accounting.", "type": ["object", "null"], "additionalProperties": false, "properties": { "limitFactor": { "type": "number", "exclusiveMinimum": 0 }, "requests": { "$ref": "#/definitions/resourceList" }, "limits": { "$ref": "#/definitions/resourceList" } } }, "resourceList": { "description": "Both spellings of the ephemeral-storage key are accepted because the resources helper normalizes camelCase to the Kubernetes key.", "type": ["object", "null"], "additionalProperties": false, "properties": { "cpu": { "type": ["string", "number", "null"] }, "memory": { "type": ["string", "number", "null"] }, "ephemeral-storage": { "type": ["string", "number", "null"] }, "ephemeralStorage": { "type": ["string", "number", "null"] } } }, "env": { "type": "array", "items": { "type": "object", "additionalProperties": false, "required": ["name"], "properties": { "name": { "type": "string" }, "value": { "type": "string" }, "valueFrom": { "type": "object", "additionalProperties": false, "properties": { "secretKeyRef": { "$ref": "#/definitions/keyRef" }, "configMapKeyRef": { "$ref": "#/definitions/keyRef" } } } } } }, "keyRef": { "type": "object", "additionalProperties": false, "required": ["name", "key"], "properties": { "name": { "type": "string" }, "key": { "type": "string" } } }, "securityContext": { "description": "May be null / empty at any level: the chart then falls back to its hardening defaults (issue #99) instead of rendering an unhardened workload. Where a chart deviates from the repo hardening standard on purpose, its fallback reproduces the DEVIATION, not the standard (guideline 4).", "type": ["object", "null"], "additionalProperties": false, "properties": { "pod": { "description": "Merged onto the chart's pod hardening defaults and rendered as the pod's securityContext; kept open because the chart does not interpret the individual fields.", "type": ["object", "null"] }, "container": { "description": "Merged onto the chart's container hardening defaults and rendered as the container's securityContext; kept open because the chart does not interpret the individual fields.", "type": ["object", "null"] } } }, "probe": { "description": "Merged onto the chart's probe defaults and rendered as a container probe; kept open because the chart does not interpret the individual fields. May be null / empty, which means the defaults apply (issue #99) rather than the probe disappearing. The chart's default MUST carry the probe's context - port name, Host header, exec command - not just its timings (guideline 5).", "type": ["object", "null"] } } }