Skip to content

sozercan/unstuck

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

6 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Unstuck

CI Go Report Card

A CLI tool to diagnose and remediate Kubernetes resources stuck in Terminating state due to unsatisfiable finalizers, missing controllers, deleted CRDs, or blocking webhooks.

Motivation

If you've ever run kubectl delete namespace and watched it hang forever, you know the frustration. The namespace sits in Terminating state, and you're left searching Stack Overflow for arcane kubectl commands involving finalizers, JSON patches, and API proxies.

I got tired of copy-pasting the same commands over and over, so I built unstuck to automate the diagnosis and remediation process. Instead of manually hunting down stuck resources and crafting patch commands, you can now run a single command to understand what's wrong and fix it safely.

Features

  • Diagnose stuck namespaces, CRDs, and resources
  • Identify blocking finalizers, discovery failures, and webhook issues
  • Generate remediation plans with escalating risk levels
  • Execute fixes with dry-run support and audit logging

Installation

go install github.com/sozercan/unstuck/cmd/unstuck@latest

Quick Start

Diagnose a Stuck Namespace

unstuck diagnose namespace cert-manager

Example output:

DIAGNOSIS: Namespace "cert-manager"
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Status:         Terminating (since 2h ago)
Root Cause:     CR instances stuck with unsatisfied finalizers

BLOCKERS (3 found)
β”Œβ”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ #  β”‚ Resource                            β”‚ Finalizer                      β”‚ Status   β”‚
β”œβ”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 1  β”‚ Certificate/my-cert                 β”‚ cert-manager.io/finalizer      β”‚ Stuck    β”‚
β”‚ 2  β”‚ Certificate/another-cert            β”‚ cert-manager.io/finalizer      β”‚ Stuck    β”‚
β”‚ 3  β”‚ Issuer/letsencrypt-prod             β”‚ cert-manager.io/finalizer      β”‚ Stuck    β”‚
β””β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

RECOMMENDATION
3 resources are stuck in Terminating. Use `unstuck plan namespace cert-manager` to generate remediation steps.

Diagnose a Stuck CRD

unstuck diagnose crd certificates.cert-manager.io

Diagnose a Specific Resource

unstuck diagnose certificate my-cert -n cert-manager

JSON Output (for automation)

unstuck diagnose namespace cert-manager -o json | jq '.blockers | length'

Generate a Remediation Plan

unstuck plan namespace cert-manager

Dry-Run (Preview Changes)

unstuck apply namespace cert-manager --dry-run

Execute Remediation

# Execute with confirmation prompts
unstuck apply namespace cert-manager

# Skip prompts (for automation)
unstuck apply namespace cert-manager --yes

Commands

diagnose

Analyze a stuck Kubernetes resource (read-only).

unstuck diagnose <type> <name> [flags]

Supported types:

  • namespace / ns - Diagnose a namespace
  • crd - Diagnose a CustomResourceDefinition
  • <resource> - Diagnose any resource type (e.g., certificate, pod)

Flags:

  • -n, --namespace - Namespace for resource targets
  • -o, --output - Output format: text, json (auto-detects TTY)
  • -v, --verbose - Verbose output with conditions

plan

Generate a remediation plan for a stuck resource.

unstuck plan <type> <name> [flags]

Flags:

  • --max-escalation - Maximum escalation level (0-4, default: 2)
  • --allow-force - Allow Level 3-4 actions in the plan

apply

Execute the remediation plan.

unstuck apply <type> <name> [flags]

Flags:

  • --dry-run - Show what would be done without making changes
  • -y, --yes - Skip confirmation prompts
  • --continue-on-error - Continue even if some actions fail
  • --max-escalation - Maximum escalation level (0-4, default: 2)
  • --allow-force - Allow Level 3-4 actions

Global Flags

Flag Default Description
--kubeconfig ~/.kube/config Path to kubeconfig
--context current Kubernetes context to use
--timeout 5m Overall operation timeout

Escalation Levels

Unstuck uses escalation levels to manage risk:

Level Name Risk Description
0 Informational None Diagnosis only
1 Clean Deletion Low Retry with controller
2 Finalizer Removal Medium Remove finalizers from resources
3 CRD Finalizer High Remove CRD cleanup finalizer
4 Force Finalize Critical Force-finalize namespace

Exit Codes

Code Meaning
0 Success / Resource is healthy
1 Error / Resource not found
2 Partial success

Development

Prerequisites

  • Go 1.25+
  • kubectl configured with cluster access
  • kind (for integration tests)

Build

make build

Test

# Unit tests
make test-unit

# Integration tests (requires kind cluster)
make test-integration

Lint

make lint

License

MIT

About

🩹 CLI tool to unstick Kubernetes resources stuck in Terminating state

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published