Skip to content

feat: add namespace detection for finding empty namespaces#490

Closed
matanryngler wants to merge 1 commit intoyonahd:mainfrom
matanryngler:feat/namespace-detection-fresh
Closed

feat: add namespace detection for finding empty namespaces#490
matanryngler wants to merge 1 commit intoyonahd:mainfrom
matanryngler:feat/namespace-detection-fresh

Conversation

@matanryngler
Copy link

Add functionality to detect unused namespaces that contain no resources (excluding default resources like default service account and kube-root-ca.crt).

Changes:

  • Add pkg/kor/namespaces.go with comprehensive resource counting
  • Add cmd/kor/namespaces.go for CLI command (kor namespace, kor ns)
  • Add namespace support to kor all and multi-resource commands
  • Add comprehensive test suite in pkg/kor/namespaces_test.go
  • Add exception configuration in pkg/kor/exceptions/namespaces/
  • Update pkg/kor/kor.go to include ExceptionNamespaces in Config
  • Check 15+ resource types including workloads, services, storage, RBAC
  • Include recent events check to avoid removing actively used namespaces
  • Skip system namespaces (kube-system, kube-public, kube-node-lease)
  • Support standard kor filtering options (labels, age, exceptions)

Usage:

# Find unused namespaces
kor namespace

# Use short aliases
kor ns

# Include in all resources scan
kor all

# Multi-resource query
kor configmap,namespace

# With filtering options
kor namespace --exclude-labels app=system
kor namespace --older-than=7d

Testing:

  • All existing tests pass
  • New comprehensive test suite added
  • Tests cover empty namespaces, namespaces with resources, label filtering, and exception handling

Resolves #92

Add functionality to detect unused namespaces that contain no resources
(excluding default resources like default service account and kube-root-ca.crt).

Changes:
- Add pkg/kor/namespaces.go with comprehensive resource counting
- Add cmd/kor/namespaces.go for CLI command (kor namespace, kor ns)
- Add namespace support to 'kor all' and multi-resource commands
- Add comprehensive test suite in pkg/kor/namespaces_test.go
- Add exception configuration in pkg/kor/exceptions/namespaces/
- Update pkg/kor/kor.go to include ExceptionNamespaces in Config
- Check 15+ resource types including workloads, services, storage, RBAC
- Include recent events check to avoid removing actively used namespaces
- Skip system namespaces (kube-system, kube-public, kube-node-lease)
- Support standard kor filtering options (labels, age, exceptions)

Resolves #92
@codecov-commenter
Copy link

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 47.34982% with 149 lines in your changes missing coverage. Please review.
✅ Project coverage is 44.22%. Comparing base (42443ec) to head (ccae856).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
pkg/kor/namespaces.go 52.14% 85 Missing and 38 partials ⚠️
pkg/kor/all.go 0.00% 12 Missing ⚠️
cmd/kor/namespaces.go 0.00% 10 Missing ⚠️
pkg/kor/multi.go 0.00% 4 Missing ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #490      +/-   ##
==========================================
+ Coverage   44.02%   44.22%   +0.19%     
==========================================
  Files          67       69       +2     
  Lines        4502     4785     +283     
==========================================
+ Hits         1982     2116     +134     
- Misses       2248     2359     +111     
- Partials      272      310      +38     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@yonahd yonahd requested a review from Copilot September 1, 2025 18:53
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds namespace detection functionality to find empty namespaces that contain no resources (excluding default resources like default service account and kube-root-ca.crt configmap). This feature helps identify unused namespaces that can be safely removed from the cluster.

Key changes:

  • Implements comprehensive resource counting across 15+ resource types to determine if a namespace is truly empty
  • Adds CLI commands for namespace detection with standard kor filtering options
  • Integrates namespace detection into existing multi-resource and "all" commands

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
pkg/kor/namespaces.go Core implementation with resource counting logic and namespace processing
pkg/kor/namespaces_test.go Comprehensive test suite covering empty/non-empty namespaces and filtering
cmd/kor/namespaces.go CLI command implementation with aliases (ns, namespaces)
pkg/kor/kor.go Configuration update to include ExceptionNamespaces
pkg/kor/exceptions/namespaces/namespaces.json Exception configuration file for namespaces
pkg/kor/all.go Integration of namespace detection into "all" command
pkg/kor/multi.go Integration into multi-resource commands

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

}

// Default service account token secret (for older Kubernetes versions)
if resourceType == "secret" && name == "default-token-" {
Copy link

Copilot AI Sep 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The string comparison for default token secrets is incorrect. It should check if the name starts with 'default-token-' using strings.HasPrefix(name, 'default-token-') instead of exact equality.

Copilot uses AI. Check for mistakes.
continue
}

if pass, _ := filter.SetObject(&ns).Run(filterOpts); pass {
Copy link

Copilot AI Sep 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable 'filter' is undefined. This should likely be 'filters.Filter' or a similar properly imported/defined filter object.

Suggested change
if pass, _ := filter.SetObject(&ns).Run(filterOpts); pass {
if pass, _ := filters.NewFilter().SetObject(&ns).Run(filterOpts); pass {

Copilot uses AI. Check for mistakes.

if opts.DeleteFlag {
if unusedNamespaces, err = DeleteResource(unusedNamespaces, clientset, "", "Namespace", opts.NoInteractive); err != nil {
fmt.Fprintf(os.Stderr, "Failed to delete Namespace %s: %v\n", unusedNamespaces, err)
Copy link

Copilot AI Sep 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message format is incorrect. It's trying to print the entire slice 'unusedNamespaces' where it should print individual namespace names. This will result in an unreadable error message.

Suggested change
fmt.Fprintf(os.Stderr, "Failed to delete Namespace %s: %v\n", unusedNamespaces, err)
var nsNames []string
for _, ns := range unusedNamespaces {
nsNames = append(nsNames, ns.Name)
}
fmt.Fprintf(os.Stderr, "Failed to delete Namespace(s) %s: %v\n", strings.Join(nsNames, ", "), err)

Copilot uses AI. Check for mistakes.
@isindir
Copy link
Contributor

isindir commented Oct 27, 2025

@Yonald , this looks like a duplication of work to PR which is now fully ready for review and awaiting it from your side: #249

@matanryngler matanryngler closed this by deleting the head repository Feb 13, 2026
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.

Find Empty namespaces

4 participants