Skip to content

feat(sweep): cleanup detectors — orphaned Services, unused PVCs, idle namespaces, zombies#17

Merged
mayur-tolexo merged 1 commit into
mainfrom
feat/sweep-cleanup-detectors
Jun 2, 2026
Merged

feat(sweep): cleanup detectors — orphaned Services, unused PVCs, idle namespaces, zombies#17
mayur-tolexo merged 1 commit into
mainfrom
feat/sweep-cleanup-detectors

Conversation

@mayur-tolexo

Copy link
Copy Markdown
Owner

Implements the roadmap's cleanup detectors (Phase 3) as a new read-only command, kubetidy sweep — the literal "tidy" beyond rightsizing.

What it finds

  • orphaned Services — selector matches no pods (a dead routing target)
  • unused PVCs — not mounted by any pod, with an estimated $/mo storage cost
  • idle namespaces — no running workloads (system namespaces excluded)
  • zombie workloads — Deployments/StatefulSets scaled to 0 replicas
kubetidy · prod · cleanup sweep

  Found 9 cleanup opportunities · ~$24/mo reclaimable

  orphaned service (2)
    • data/old-grpc                no pods match its selector · app=old-grpc
  unused pvc (3)
    • logs/archive-2023            not mounted by any pod · 180Gi · ~$18/mo
    • data/cache-snapshot          not mounted by any pod · 50Gi · ~$5/mo
  idle namespace (2)
    • poc-old                      no running workloads
  zombie workload (2)
    • ops/old-redis (StatefulSet)  scaled to 0 replicas

  Read-only: review before deleting. kubetidy never deletes anything.

How

  • internal/cleanup — pure detectors over listed objects (Detect(Inputs) []Finding), fully fake-testable. PVC cost = requested size × --storage-cost ($/GiB-month, default 0.10).
  • internal/cli/sweep.go — gathers Services/Pods/PVCs/Deployments/StatefulSets/DaemonSets/Namespaces via client-go and renders a grouped, dollar-aware table (or --output json). sweepWithClients is hermetically tested with fake clientsets.
  • Named sweep because cleanup is already an alias for uninstall.
  • Read-only by design — consistent with kubetidy's "never mutates" ethos.

Docs

README sweep section, ROADMAP item checked off, CHANGELOG (v0.1.2).

Tests

internal/cleanup 92.5% (each detector + cost + totals), sweepWithClients + render covered. Full go build/vet/gofmt/test ./... + golangci-lint (0 issues) green.

Possible follow-ups

  • sweepdiff/pr to emit kubectl delete / GitOps deletions for review.
  • More detectors: completed/failed Jobs, ConfigMaps/Secrets referenced by nothing, unbound PVs.

… namespaces, zombies

New `kubetidy sweep` command (Phase 3 "cleanup detectors") — the literal tidy beyond
rightsizing. Read-only; it surfaces removable junk and never deletes anything:

- orphaned Services — selector matches no pods (dead routing target)
- unused PVCs — not mounted by any pod, with an estimated $/mo storage cost
- idle namespaces — no running workloads (system namespaces excluded)
- zombie workloads — Deployments/StatefulSets scaled to 0 replicas

- internal/cleanup: pure detectors over listed objects (Detect(Inputs) []Finding),
  fully fake-testable; estimates PVC cost from requested size × --storage-cost.
- internal/cli/sweep.go: gathers objects via client-go and renders a grouped,
  dollar-aware table (or --output json); `sweepWithClients` is hermetically tested.
- Named `sweep` because `cleanup` is already an alias for `uninstall`.
- docs: README sweep section, ROADMAP checked off, CHANGELOG (v0.1.2).

Coverage: cleanup 92.5%. Full build/vet/fmt/test/lint green.
@mayur-tolexo
mayur-tolexo merged commit 79adff5 into main Jun 2, 2026
2 checks passed
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.

1 participant