CRDEntry

3 min read

Each entry in spec.crds is a CRDEntry. The map key becomes the CRD name at runtime — it is never written in the YAML body.

spec:
  crds:
    database:                  # ← this is the name
      enabled: true
      description: string
      crdFile: ./crd.yaml

      apiTypes:                # → apitypes.md
        ...

      namespaced: true
      namespace: default
      workers: 3
      resync: 30s

      dependsOn:
        other-crd:
          condition: healthy

      queue:
        shared: false
        maxQueueDepth: 100
        degradeThreshold: 5

      labelSelector:
        app: my-operator
      fieldSelector:
        metadata.namespace: production

      operatorBox:             # → operatorbox.md
        ...

      conversion:              # → conversion.md
        ...

      validation:              # → validation.md
        ...

      mutation:                # → mutation.md
        ...

      webhooks:
        validation: true
        mutation: true
        operations: [CREATE, UPDATE]

      restrictedNamespaces:
        - kube-system
      allowedNamespaces:
        - dev

      endpoints:
        enabled: true
        health: true
        info: true

      imports:
        - motif: ./motifs/postgres/motif.yaml   # → motif.md
          with:
            image: postgres:14

Identity and mode

FieldTypeDefaultDescription
enabledbooltruefalse skips this CRD entirely — it is not started or watched.
descriptionstringShown in the /katalog endpoint.
modestringautotyped or dynamic. Auto-detected from apiTypes.location.
crdFilestringPath or HTTPS URL to the CRD YAML. Used for CRD-driven API inference in dev mode.

Scope

FieldTypeDefaultDescription
namespacedbooltrueWhether the CRD is namespace-scoped or cluster-scoped.
namespacestringTarget namespace for namespaced CRDs.

Runtime behaviour

FieldTypeDefaultDescription
workersint3Concurrent reconcile goroutines.
resyncduration30sFull re-list interval (e.g. 30s, 5m).
ignoreStatusPatchboolfalseSkip status patch operations.
ignoreObservedGenerationboolfalseSkip the observed-generation idempotency check.
removeFinalizersboolfalseStrip all finalizers on deletion.

dependsOn

CRDs that must reach a condition before this one starts reconciling.

# All three forms are valid:

# map with condition
dependsOn:
  schema-migrator:
    condition: healthy

# scalar shorthand
dependsOn:
  schema-migrator: healthy

# list (bare names — condition defaults to "started")
dependsOn:
  - schema-migrator
ConditionDescription
startedWorkers are running (default when no condition is given).
healthyWorkers running and consecutive failure count is zero.

queue

FieldTypeDefaultDescription
sharedboolfalseUse the shared default workqueue instead of a per-CRD queue.
maxQueueDepthint100 (MAX_QUEUE_DEPTH env)Max items in the queue before new items are dropped.
degradeThresholdint5 (DEGRADE_THRESHOLD env)Consecutive reconcile failures before health transitions to degraded.

webhooks

Per-CRD admission webhook override. Overrides security.webhooks for this CRD only.

FieldTypeDescription
validationboolInclude in ValidatingWebhookConfiguration.
mutationboolInclude in MutatingWebhookConfiguration.
operations[]stringWhich operations trigger the webhook. Default: [CREATE, UPDATE].

restrictedNamespaces / allowedNamespaces

Per-CRD namespace guards. Override security.namespaceProtection lists for this CRD only.

restrictedNamespaces:
  - kube-system
  - production
allowedNamespaces:
  - dev
  - staging

endpoints

endpoints:
  enabled: true
  health: true
  info: true

imports

Motif imports — pull reusable resource templates into this CRD’s reconciler.

imports:
  - motif: ./motifs/postgres/motif.yaml
    with:
      image: postgres:14
  - motif: ghcr.io/orkspace/motifs/nginx:v1
    oci: true
    with:
      port: "8080"

→ Full Motif import schema: motif.md

Sub-schemas

FieldReference
apiTypesapitypes.md
operatorBoxoperatorbox.md
conversionconversion.md
validationvalidation.md
mutationmutation.md