Files
argocd-apps/schemas/bind.unkin.net/bindcluster_v1alpha1.json
T
unkinben e030f07986 Add primary (write) Services to authoritative + externaldns (#229)
**Stacked on #228** (needs operator v0.1.5). Merge #228 first; the diff collapses to just this after.

## Why
Writes (RFC2136/nsupdate) must go to pod-0 — the round-robin read Service would land them on a secondary (rejected). Adds a dedicated write endpoint per cluster (operator v0.1.5 `primaryService`).

## Changes
- `bind-authoritative`: LoadBalancer write endpoint on **198.18.200.9** (`bind-authoritative-primary`)
- `bind-externaldns`: ClusterIP write endpoint (`bind-externaldns-primary`, for in-cluster writers)
- regenerate the bindcluster kubeconform schema (primaryService + externalTrafficPolicy)

## Deferred
external-dns is **not** repointed at `bind-externaldns-primary` yet: it authenticates with the existing TSIG key, which the operator-generated key won't match until the planned Vault-sync + secret-reflection features exist. Until then external-dns keeps writing to the puppet externaldns.

## Validated
kustomize build + kubeconform (3 BindClusters valid against the v0.1.5 schema).

---------

Co-authored-by: BenVincent <benvin@main.unkin.net>
Reviewed-on: #229
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-05 16:37:49 +10:00

935 lines
33 KiB
JSON

{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"apiVersion": {
"type": "string"
},
"kind": {
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"properties": {
"affinity": {
"properties": {
"nodeAffinity": {
"properties": {
"preferredDuringSchedulingIgnoredDuringExecution": {
"items": {
"properties": {
"preference": {
"properties": {
"matchExpressions": {
"items": {
"properties": {
"key": {
"type": "string"
},
"operator": {
"type": "string"
},
"values": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchFields": {
"items": {
"properties": {
"key": {
"type": "string"
},
"operator": {
"type": "string"
},
"values": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"weight": {
"format": "int32",
"type": "integer"
}
},
"required": [
"preference",
"weight"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"requiredDuringSchedulingIgnoredDuringExecution": {
"properties": {
"nodeSelectorTerms": {
"items": {
"properties": {
"matchExpressions": {
"items": {
"properties": {
"key": {
"type": "string"
},
"operator": {
"type": "string"
},
"values": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchFields": {
"items": {
"properties": {
"key": {
"type": "string"
},
"operator": {
"type": "string"
},
"values": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"nodeSelectorTerms"
],
"type": "object",
"x-kubernetes-map-type": "atomic"
}
},
"type": "object"
},
"podAffinity": {
"properties": {
"preferredDuringSchedulingIgnoredDuringExecution": {
"items": {
"properties": {
"podAffinityTerm": {
"properties": {
"labelSelector": {
"properties": {
"matchExpressions": {
"items": {
"properties": {
"key": {
"type": "string"
},
"operator": {
"type": "string"
},
"values": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchLabels": {
"additionalProperties": {
"type": "string"
},
"type": "object"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"matchLabelKeys": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"mismatchLabelKeys": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"namespaceSelector": {
"properties": {
"matchExpressions": {
"items": {
"properties": {
"key": {
"type": "string"
},
"operator": {
"type": "string"
},
"values": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchLabels": {
"additionalProperties": {
"type": "string"
},
"type": "object"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"namespaces": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"topologyKey": {
"type": "string"
}
},
"required": [
"topologyKey"
],
"type": "object"
},
"weight": {
"format": "int32",
"type": "integer"
}
},
"required": [
"podAffinityTerm",
"weight"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"requiredDuringSchedulingIgnoredDuringExecution": {
"items": {
"properties": {
"labelSelector": {
"properties": {
"matchExpressions": {
"items": {
"properties": {
"key": {
"type": "string"
},
"operator": {
"type": "string"
},
"values": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchLabels": {
"additionalProperties": {
"type": "string"
},
"type": "object"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"matchLabelKeys": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"mismatchLabelKeys": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"namespaceSelector": {
"properties": {
"matchExpressions": {
"items": {
"properties": {
"key": {
"type": "string"
},
"operator": {
"type": "string"
},
"values": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchLabels": {
"additionalProperties": {
"type": "string"
},
"type": "object"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"namespaces": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"topologyKey": {
"type": "string"
}
},
"required": [
"topologyKey"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"type": "object"
},
"podAntiAffinity": {
"properties": {
"preferredDuringSchedulingIgnoredDuringExecution": {
"items": {
"properties": {
"podAffinityTerm": {
"properties": {
"labelSelector": {
"properties": {
"matchExpressions": {
"items": {
"properties": {
"key": {
"type": "string"
},
"operator": {
"type": "string"
},
"values": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchLabels": {
"additionalProperties": {
"type": "string"
},
"type": "object"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"matchLabelKeys": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"mismatchLabelKeys": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"namespaceSelector": {
"properties": {
"matchExpressions": {
"items": {
"properties": {
"key": {
"type": "string"
},
"operator": {
"type": "string"
},
"values": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchLabels": {
"additionalProperties": {
"type": "string"
},
"type": "object"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"namespaces": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"topologyKey": {
"type": "string"
}
},
"required": [
"topologyKey"
],
"type": "object"
},
"weight": {
"format": "int32",
"type": "integer"
}
},
"required": [
"podAffinityTerm",
"weight"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"requiredDuringSchedulingIgnoredDuringExecution": {
"items": {
"properties": {
"labelSelector": {
"properties": {
"matchExpressions": {
"items": {
"properties": {
"key": {
"type": "string"
},
"operator": {
"type": "string"
},
"values": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchLabels": {
"additionalProperties": {
"type": "string"
},
"type": "object"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"matchLabelKeys": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"mismatchLabelKeys": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"namespaceSelector": {
"properties": {
"matchExpressions": {
"items": {
"properties": {
"key": {
"type": "string"
},
"operator": {
"type": "string"
},
"values": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"required": [
"key",
"operator"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"matchLabels": {
"additionalProperties": {
"type": "string"
},
"type": "object"
}
},
"type": "object",
"x-kubernetes-map-type": "atomic"
},
"namespaces": {
"items": {
"type": "string"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
},
"topologyKey": {
"type": "string"
}
},
"required": [
"topologyKey"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-type": "atomic"
}
},
"type": "object"
}
},
"type": "object"
},
"allowNewZones": {
"default": true,
"type": "boolean"
},
"catalogZoneRef": {
"type": "string"
},
"extraOptions": {
"items": {
"type": "string"
},
"type": "array"
},
"forwarders": {
"items": {
"type": "string"
},
"type": "array"
},
"image": {
"default": "internetsystemsconsortium/bind9:9.20",
"type": "string"
},
"imagePullPolicy": {
"type": "string"
},
"mode": {
"default": "authoritative",
"enum": [
"authoritative",
"resolver"
],
"type": "string"
},
"nodeSelector": {
"additionalProperties": {
"type": "string"
},
"type": "object"
},
"primaryService": {
"properties": {
"annotations": {
"additionalProperties": {
"type": "string"
},
"type": "object"
},
"externalTrafficPolicy": {
"enum": [
"Cluster",
"Local"
],
"type": "string"
},
"loadBalancerIP": {
"type": "string"
},
"type": {
"enum": [
"ClusterIP",
"LoadBalancer",
"NodePort"
],
"type": "string"
}
},
"type": "object"
},
"recursion": {
"type": "boolean"
},
"replicas": {
"default": 3,
"format": "int32",
"minimum": 1,
"type": "integer"
},
"resources": {
"properties": {
"claims": {
"items": {
"properties": {
"name": {
"type": "string"
},
"request": {
"type": "string"
}
},
"required": [
"name"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-map-keys": [
"name"
],
"x-kubernetes-list-type": "map"
},
"limits": {
"additionalProperties": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"x-kubernetes-int-or-string": true
},
"type": "object"
},
"requests": {
"additionalProperties": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"x-kubernetes-int-or-string": true
},
"type": "object"
}
},
"type": "object"
},
"service": {
"properties": {
"annotations": {
"additionalProperties": {
"type": "string"
},
"type": "object"
},
"externalTrafficPolicy": {
"enum": [
"Cluster",
"Local"
],
"type": "string"
},
"loadBalancerIP": {
"type": "string"
},
"type": {
"enum": [
"ClusterIP",
"LoadBalancer",
"NodePort"
],
"type": "string"
}
},
"type": "object"
},
"storageClassName": {
"type": "string"
},
"storageSize": {
"default": "1Gi",
"type": "string"
},
"tolerations": {
"items": {
"properties": {
"effect": {
"type": "string"
},
"key": {
"type": "string"
},
"operator": {
"type": "string"
},
"tolerationSeconds": {
"format": "int64",
"type": "integer"
},
"value": {
"type": "string"
}
},
"type": "object"
},
"type": "array"
}
},
"required": [
"mode"
],
"type": "object"
},
"status": {
"properties": {
"conditions": {
"items": {
"properties": {
"lastTransitionTime": {
"format": "date-time",
"type": "string"
},
"message": {
"maxLength": 32768,
"type": "string"
},
"observedGeneration": {
"format": "int64",
"minimum": 0,
"type": "integer"
},
"reason": {
"maxLength": 1024,
"minLength": 1,
"pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
"type": "string"
},
"status": {
"enum": [
"True",
"False",
"Unknown"
],
"type": "string"
},
"type": {
"maxLength": 316,
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
"type": "string"
}
},
"required": [
"lastTransitionTime",
"message",
"reason",
"status",
"type"
],
"type": "object"
},
"type": "array",
"x-kubernetes-list-map-keys": [
"type"
],
"x-kubernetes-list-type": "map"
},
"observedGeneration": {
"format": "int64",
"type": "integer"
},
"phase": {
"type": "string"
},
"primaryPod": {
"type": "string"
},
"primaryService": {
"type": "string"
},
"readyReplicas": {
"format": "int32",
"type": "integer"
},
"replicas": {
"format": "int32",
"type": "integer"
}
},
"type": "object"
}
},
"type": "object"
}