Skip to content

docs(resourceselector): Document namespace selection and exclusion - #663

Open
aaronmhmr wants to merge 1 commit into
gianlucam76:mainfrom
aaronmhmr:docs/namespace-exclusion
Open

docs(resourceselector): Document namespace selection and exclusion#663
aaronmhmr wants to merge 1 commit into
gianlucam76:mainfrom
aaronmhmr:docs/namespace-exclusion

Conversation

@aaronmhmr

Copy link
Copy Markdown
Contributor

Closes #373.

In #373 I asked for an excludedNamespaces field. @gianlucam76 replied that this is already possible, and he is right — but there is a third route that is nicer than either option in that thread, and none of it is documented.

The capability already exists

namespaceSelector is declared as a plain string (api/v1alpha1/cleaner_types.go:110) and parsed with labels.Parse() (internal/controller/executor/worker.go:501). That is the full apimachinery selector parser, so it accepts set-based operators, including notin. Kubernetes separately labels every namespace with kubernetes.io/metadata.name (the NamespaceDefaultLabelName admission plugin, default since v1.22).

Put together, namespaces can be excluded by name today, with no new API field and no manual labelling:

namespaceSelector: "kubernetes.io/metadata.name notin (kube-system,cattle-system,cert-manager)"

This is more declarative than an ignore-list inside the Lua evaluate, and needs no pre-labelling of namespaces.

But it is undiscoverable

  • namespaceSelector appears zero times in docs/.
  • kubernetes.io/metadata.name appears zero times in the repository.
  • The "Resource Selection" page is about aggregatedSelection and never documents namespace or namespaceSelector.

So this PR is documentation only — no code, no API change.

What this adds

A purely additive change to docs/getting_started/features/resourceselector/resourceselector.md. Nothing existing is moved or reworded:

  • Selecting Namespaces — the namespace and namespaceSelector fields, how they combine, and what happens when neither is set. Single-namespace and label-based selection.
  • Excluding Namespaces — the notin idiom, plus the failed-pods example from Feature Request: Add Namespace Exclusion to Cleaner Resource #373 with the namespace check removed from the Lua.
  • A warning admonition and a caveats note (per-resourceSelector; requires k8s >= 1.22; not applicable to cluster-scoped kinds).

Both new sections land in the page ToC and search index, so no nav change was needed.

Verification

Docs build clean with the project toolchain (zensical buildNo issues found), and every snippet in the new text was executed on a kind cluster (Kubernetes v1.36.1) running k8s-cleaner from manifest/manifest.yaml.

Four identically failed pods (Failed / Error / exit 1, so all matching the Lua) were created in kube-system, cert-manager, my-app and default, then the documented Cleaner was applied. Controller log:

getMatchingResources: found a match  resource="Pod:my-app/failer"
getMatchingResources: found a match  resource="Pod:default/failer"
deleting resource                    resource="Pod:my-app/failer"
deleting resource                    resource="Pod:default/failer"

The two protected pods were never even considered as candidates — namespaceSelector filtered them out at collection time, before the Lua ran. They survived; the other two were deleted.

One thing worth your call, @gianlucam76

While verifying, I hit this in internal/controller/executor/worker.go:422:

if len(namespaces) > 0 {
    result, err = collectFromNamespaces(ctx, config, namespaces, &resourceId, &options)
} else {
    result, err = collectWithOptions(ctx, config, &resourceId, &options)   // all namespaces
}

A namespaceSelector that matches zero namespaces does not narrow the Cleaner to nothing — it falls back to scanning every namespace. With action: Delete, a typo in an exclusion selector could therefore widen its blast radius rather than shrink it.

I have not treated this as a bug in the docs. The warning box states it neutrally as behaviour and gives users a kubectl command to check their selector first. Whether the fail-open default itself should change is your call — happy to open a separate issue if you would like.

The namespaceSelector field is parsed as a full Kubernetes label selector,
so it already supports set-based operators. Combined with the automatic
kubernetes.io/metadata.name label, this allows namespaces to be excluded by
name without any new API field. Neither namespaceSelector nor this idiom was
documented.

Documents the namespace and namespaceSelector fields, single-namespace and
label-based selection, and the exclusion idiom, with a worked example that
skips protected namespaces such as kube-system.

Closes gianlucam76#373

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Amin Mohammadian <aminmhmr@gmail.com>
@aaronmhmr
aaronmhmr force-pushed the docs/namespace-exclusion branch from 5e00491 to 20d5654 Compare July 13, 2026 09:38
@gianlucam76
gianlucam76 requested a review from egrosdou01 July 13, 2026 12:27
@gianlucam76

Copy link
Copy Markdown
Owner

Thank you @aminmr

Good for me. @egrosdou01 covers the documentation so I added her as reviewer.

Meanwhile I will address the OVS scanner issue which is unrelated to this PR

@gianlucam76

Copy link
Copy Markdown
Owner

@egrosdou01 can you please review this? thanks

@egrosdou01

Copy link
Copy Markdown
Collaborator

@gianlucam76 Only small wording issues. If @aaronmhmr does not have time to update the docu, feel free to merge it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Add Namespace Exclusion to Cleaner Resource

3 participants