v0.7.13 — External protocols, serve layer, new condition operators, two breaking changes
validation.external and mutation.external
External calls can now fire at admission time, not only reconcile time:
validation:
external:
- name: healthCheck
url: "{{ .spec.serviceUrl }}/health"
fires:
reconcile: false # admission-only
rules:
- field: "{{ .external.healthCheck.status }}"
equals: "200"
action: deny
message: "health check failed"
Results propagate into all template contexts, including status fields and resource templates.
External protocol clients
external: blocks support native protocol clients alongside HTTP:
| Protocol | protocol: value |
|---|---|
| Prometheus | prometheus |
| Redis | redis |
| PostgreSQL | postgres |
| MongoDB | mongo |
| Kafka | kafka |
Results available at external.<name>.* in all template contexts.
New condition operators
gte, lte, between, notBetween, notIn, notContains, regex, notPrefix, notSuffix — available in when:, or:, and validation.rules.
Fixes: gt/lt in validation rules were accidentally inclusive; operator: in was never evaluated in validation rules (silently always passed).
operator: unique
Check that a field value is unique across all CRs of this CRD. Authoritative at reconcile time; best-effort early rejection at admission time.
Breaking: labels/annotations move to native map syntax
# before
labels:
- key: app
value: "{{ .metadata.name }}"
# after
labels:
app: "{{ .metadata.name }}"
Applies to selector:, labelSelector:, and fieldSelector: too.
Breaking: envFrom.secretRef/configMapRef move to struct
# before
envFrom:
secretRef: [myapp-creds]
# after
envFrom:
secretRef:
- name: myapp-creds
prefix: "DB_"
serve labels/annotations — expose metadata as serve fields
serve:
labels:
team:
label: "Team"
required: true
Written to metadata.labels/metadata.annotations on apply. required: true synthesizes a server-side exists validation rule; type: enum synthesizes an in rule.
serve.fields.path — nested spec paths
path: app.resources.cpu maps a flat serve field to a nested spec location.
validation.rules link: field
Names the serve field a validation rule concerns, so clients can highlight the offending form field by name:
validation:
rules:
- field: '{{ getLabel . "team" }}'
link: team
operator: exists
kubectl.apply — admission rejection tests
kubectl:
apply:
- file: ./cr-invalid.yaml
exitCode: 1
outputContains: "spec.domain must be unique"
Assert that an apply should be rejected, and what the message contains.