Skip to content

Instantly share code, notes, and snippets.

@jamezrin
Last active December 30, 2024 01:15
Show Gist options
  • Save jamezrin/eb0245d944a16904f9652c438e44da41 to your computer and use it in GitHub Desktop.
Save jamezrin/eb0245d944a16904f9652c438e44da41 to your computer and use it in GitHub Desktop.
Fish Shell script to handle the deletion of a namespace stuck at termination
function k8s_managens --description "k8s_managens <namespace> [--delete] [--timeout <timeout>] [--force-finalizers]"
set -l options (fish_opt -s d -l delete --long-only)
set options $options (fish_opt -s t -l timeout --required-val --long-only)
set options $options (fish_opt -s f -l force-finalizers --long-only)
argparse $options -- $argv
if test (count $argv) -eq 0
echo "Usage: k8s_managens <namespace> [--delete] [--timeout <timeout>] [--force-finalizers]"
return 1
end
# Parse arguments/flags
set namespace $argv[1]
set -l delete $_flag_delete
set -l force_finalizers $_flag_force_finalizers
set -l timeout "10s"
if test -n "$_flag_timeout"
set timeout $_flag_timeout
end
# Check that the namespace exists
kubectl get namespace $namespace > /dev/null 2>&1
if test $status -ne 0
echo "Namespace $namespace does not exist"
return 1
end
# Getting all api-resource types for getting everything as "kubectl get all" does not
# actually return "all" resource types. See https://github.com/kubernetes/kubectl/issues/151
echo "Getting api resource types in the cluster"
set -l api_resources (kubectl api-resources --verbs=list --namespaced -o name)
set -l api_resources_count (count $api_resources)
# Get all resources of each type and append to the array "resources"
set -l resources
set -l api_resources_counter 0
for api_resource in $api_resources
set api_resources_counter (math $api_resources_counter + 1)
printf "\r\033[KChecking resource type $api_resources_counter/$api_resources_count (type: $api_resource)"
set -a resources (kubectl get --show-kind --ignore-not-found $api_resource -n $namespace -o name)
end
# Exit early if not using the "delete" flag
set -l resource_count (count $resources)
printf "\r\033[KFound $resource_count resources in namespace $namespace"
echo
if not test -n "$delete"
echo "Resources in the $namespace namespace:"
echo $resources
echo "Running without "delete" flag. Exiting without making any changes to the cluster"
return 0
end
# Try to delete namespace gracefully
echo "Trying to delete namespace $namespace (timeout: $timeout)"
kubectl delete namespace $namespace --timeout=$timeout --wait --ignore-not-found > /dev/null 2>&1
if test $status -eq 0
echo "Gracefully deleted namespace $namespace without extra measures"
return 0
end
if not test -n "$force_finalizers"
echo "Error deleting namespace $namespace, use --force-finalizers to force deletion"
return 1
end
# Patch finalizers of the namespace and delete
echo "Patching finalizers of $namespace and trying to delete again"
kubectl patch namespace $namespace --type json --patch='[{"op": "remove", "path": "/spec/finalizers"}]' > /dev/null 2>&1
kubectl delete namespace $namespace --timeout=$timeout --wait --ignore-not-found > /dev/null 2>&1
if test $status -eq 0
echo "Successfully deleted namespace $namespace after patching namespace finalizers"
return 0
end
# Patch finalizers of resources in namespace
echo "Patching resources finalizers of $namespace and trying to delete again"
set -l resource_counter 0
for resource in $resources
set resource_counter (math $resource_counter + 1)
printf "\r\033[KPatching finalizers of resource $resource_counter/$resource_count (currently: $resource)"
kubectl patch $resource -n $namespace --type json --patch='[{"op": "remove", "path": "/metadata/finalizers"}]' > /dev/null 2>&1
kubectl delete $resource -n $namespace --timeout=$timeout --ignore-not-found > /dev/null 2>&1
end
printf "\r\033[KPatched finalizers of $resource_count resources, trying to delete namespace one last time"
echo
# Try to delete namespace again after patching finalizers
kubectl delete namespace $namespace --timeout=$timeout --wait --ignore-not-found > /dev/null 2>&1
if test $status -eq 0
echo "Successfully deleted namespace $namespace after patching resource finalizers"
return 0
end
# Exit after all attempts
echo "Error deleting namespace $namespace after all attempts, status of the namespace:"
kubectl describe namespace $namespace
return 1
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment