ADR-0205: Watch opt-in and opt-out labels¶
kollect.dev/watchlabels andwatchMode: All|OptIndecide which objects get collected.
Theme: 02 · API & tenancy · Status: Current
Context¶
Platform teams need a discoverable, kubectl-friendly way to exclude noisy namespaces or
workloads from inventory without editing every KollectTarget, and to run opt-in collection
in shared clusters where most tenants should be ignored by default.
Flux uses a similar pattern on Kustomizations:
metadata:
annotations:
kustomize.toolkit.fluxcd.io/reconcile: disabled
Kollect needs parallel semantics for collection watch — explicit enable/disable signals on namespaces and resources that the collection engine honors before attribute extraction.
Decision¶
Label and annotation keys¶
| Key | On | Values | Meaning |
|---|---|---|---|
kollect.dev/watch |
Namespace, namespaced resource | enabled, disabled |
Resource/namespace watch opt-in or opt-out |
kollect.dev/namespace-watch |
Namespace (annotation) | enabled, disabled |
Applies to all resources in the namespace unless a resource label overrides |
Constants live in api/v1alpha1/constants.go.
KollectTarget.spec.watchMode¶
| Mode | Default | Behavior |
|---|---|---|
All |
yes | Collect objects matching selectors except those explicitly disabled |
OptIn |
no | Collect only objects/namespaces explicitly enabled |
Validated by CEL enum on the CRD and the KollectTarget validating webhook.
Precedence (engine ShouldCollect)¶
- Resource label
kollect.dev/watch: disabled— always skip (wins over everything). - Resource label
kollect.dev/watch: enabled— collect (overrides namespace disabled). - Namespace label
kollect.dev/watch: disabledor annotationkollect.dev/namespace-watch: disabled— skip all resources in namespace (unless step 2). watchMode: OptIn— require namespace or resourceenabled; otherwise skip.watchMode: All(default) — collect when selectors match and no opt-out applies.
The collection engine evaluates watch labels after namespace/label selectors and before attribute extraction. Items removed from the watch set are dropped from the in-memory store on update events.
Examples¶
Opt-out a namespace (All mode target still matches selectors):
apiVersion: v1
kind: Namespace
metadata:
name: kube-system
annotations:
kollect.dev/namespace-watch: disabled
Opt-in cluster (target uses watchMode: OptIn):
apiVersion: kollect.dev/v1alpha1
kind: KollectTarget
spec:
watchMode: OptIn
profileRef: deployment-images
apiVersion: v1
kind: Namespace
metadata:
name: team-a
labels:
kollect.dev/watch: enabled
Opt-out one Deployment in an otherwise watched namespace:
metadata:
labels:
kollect.dev/watch: disabled
Consequences¶
- Operators can document a single label key for both namespaces and workloads.
- Namespace annotations avoid relabeling every resource for bulk opt-out.
- Opt-in mode supports multi-tenant clusters without per-namespace target forks.
- Namespace metadata is cached when targets register; label/annotation changes propagate on target reconcile and informer resync (12h), not via a dedicated Namespace watch (future improvement if needed).
- Collection policy (namespace allow/deny,
resourceRules, CELmatchPolicy) is evaluated before watch labels — see ADR-0207. Watch labels remain tenant consent, not platform or attribute filtering.
Open questions¶
- DECIDED : Under
watchMode: OptIn, cluster-scoped resources honor a target-level default opt-in (e.g.clusterScopedDefault: Includeon theKollectTarget/KollectClusterTarget), since they have no namespace to inherit from. A per-object opt-out label still wins. Platform targets can inventory Nodes/PVs without labeling each object. - OPEN: Dedicated Namespace informer to refresh watch metadata without waiting for target reconcile?