Monedula
monedula-gitops docs menu

KafkaUser

Field reference for the KafkaUser resource (gitops.monedula.dev/v1alpha1): every spec and status field with its type, default and validation rules.

Reference 20 of 20

Reference for monedula-gitops v1.0.0

Updated 9 October 2026

On this page

Summary

apiVersiongitops.monedula.dev/v1alpha1
kindKafkaUser
ScopeNamespaced
kubectl get columnsCluster, Phase, Username, Mechanism, Age

KafkaUserSpec carries CEL transition rules (x-kubernetes-validations) that enforce identity immutability AT THE APISERVER, so the default install (webhooks disabled) cannot silently orphan broker state by renaming identity fields. The rules reference oldSelf, so they run only on UPDATE - create is unrestricted. username is immutable ONCE SET: an update from unset/empty to set is allowed (defaulting resolves username from metadata.name in-memory, so making the default explicit later must not be rejected). Note the CEL rule cannot compare against metadata.name from spec scope, so unset→set admits any value; the webhook (when enabled) additionally rejects an unset→set update whose value differs from metadata.name (resolved-name comparison). The !has() disjunct is defensive for a future pointer/optional refactor of Username; today the field is a plain string, so the .size() == 0 disjunct is what fires for never-set values. CEL messages are static (no old/new value interpolation) - the webhook supplies the richer old -> new messages.

Rules enforced by the API server:

  • spec.username is immutable once set (a rename is a delete + create of a different principal)
  • spec.clusterRef.name is immutable (repointing a user orphans the previous cluster's credential)

Example

kafka-user.yaml
apiVersion: gitops.monedula.dev/v1alpha1
kind: KafkaUser
metadata:
  name: sample-user
  namespace: monedula-system
spec:
  clusterRef:
    name: sample-cluster
  username: sample-user
  mechanism: SCRAM-SHA-512
  # iterations: 8192
  password:
    valueFrom:
      secretKeyRef:
        name: sample-user-credentials
        key: password
  # Alternative: let the operator generate and own the password Secret
  # (operator mode only; the CLI has no way to invent a value out of thin air).
  # password:
  #   generate: {}

Spec

spec.clusterRef object required
spec.clusterRef.name string required
spec.deletionPolicy string

DeletionPolicy defaults to Delete: the credential is this CR's entire reason to exist, so orphaning it on delete is the unusual case, unlike topics/ACLs.

One of: Delete, Orphan

spec.iterations integer

Iterations is the SCRAM iteration count. Nil means "use the Kafka broker default" and is NOT drift-compared (an unset value never triggers drift just because the broker reports its own default back).

format: int32, min: 4096, max: 16384

spec.mechanism string

Mechanism defaults to SCRAM-SHA-512 when empty.

One of: SCRAM-SHA-256, SCRAM-SHA-512

spec.password object

Password is required; validation enforces its presence (kept as a pointer so a missing/malformed block produces a clear shape error rather than a silently-empty struct).

spec.password.generate object

GeneratePassword is currently empty (future: length/charset knobs).

spec.password.valueFrom object
spec.password.valueFrom.configMapKeyRef object

ConfigMapKeyRef reads a ConfigMap key (operator mode only). Uses the same {Name, Key} shape as SecretKeyRef; no Secret is involved.

spec.password.valueFrom.configMapKeyRef.key string required
spec.password.valueFrom.configMapKeyRef.name string required
spec.password.valueFrom.env string
spec.password.valueFrom.file string
spec.password.valueFrom.inline string

Inline is the literal value verbatim (intended for schema bodies).

spec.password.valueFrom.secretKeyRef object
spec.password.valueFrom.secretKeyRef.key string required
spec.password.valueFrom.secretKeyRef.name string required
spec.username string

Username defaults from metadata.name when empty (defaulting webhook / CLI defaulting package).

Status

Written by the operator; read-only for users.

status.appliedPasswordRef object

AppliedPasswordRef records the Secret+ResourceVersion whose value was last upserted to Kafka (referenced/valueFrom mode only).

status.appliedPasswordRef.resourceVersion string
status.appliedPasswordRef.secretName string
status.conditions array<object>
status.conditions[].lastTransitionTime string required

lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.

format: date-time

status.conditions[].message string required

message is a human readable message indicating details about the transition. This may be an empty string.

max length: 32768

status.conditions[].observedGeneration integer

observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.

format: int64, min: 0

status.conditions[].reason string required

reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.

pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$, min length: 1, max length: 1024

status.conditions[].status string required

status of the condition, one of True, False, Unknown.

One of: True, False, Unknown

status.conditions[].type string required

type of condition in CamelCase or in foo.example.com/CamelCase.

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])$, max length: 316

status.generatedSecretName string

GeneratedSecretName is set in generate mode: the name of the operator-owned Secret holding the generated password.

status.lastAppliedTime string

format: date-time

status.lastCheckedTime string

format: date-time

status.observedGeneration integer

format: int64

status.phase string