Skip to content

Commit 2453cf0

Browse files
committed
init
1 parent aed4498 commit 2453cf0

File tree

2 files changed

+156
-0
lines changed

2 files changed

+156
-0
lines changed

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Krew prune plugin
2+
=================
3+
4+
> Krew plugin which delete secrets or configmaps that are not being used in a
5+
given namespace. It checks from mounted volumes, env, envFrom and
6+
imagePullSecrets.
7+
8+
## Getting started
9+
10+
Install as a kubectl plugin using [krew](https://krew.dev). Refer to the
11+
[Krew documentation](https://krew.dev) to get started.
12+
13+
```bash
14+
$ kubectl krew install prune
15+
16+
# Usage:
17+
$ kubectl prune <resource type> <namespace>
18+
19+
# delete unused secrets
20+
$ kubectl prune secrets my-namespace
21+
22+
# delete unused configmaps
23+
$ kubectl prune configmaps my-namespace
24+
```

kubectl-prune.sh

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#!/usr/bin/env bash
2+
# Krew plugin which delete secrets or configmaps that are not being used in a
3+
# given namespace. It checks from mounted volumes, env, envFrom and
4+
# imagePullSecrets.
5+
#
6+
# Usage:
7+
# ./kubectl-prune.sh [RESOURCE (secrets|configmaps)] [NAMESPACE]
8+
# Example:
9+
# ./kubectl-prune.sh secrets my-namespace
10+
11+
set -e
12+
13+
resource=$1
14+
namespace=$2
15+
16+
case "$resource" in
17+
"secrets" | "secret")
18+
# get all secrets
19+
available_resources=$(kubectl get secrets -n $namespace \
20+
-o jsonpath='{.items[*].metadata.name}' | xargs -n1 | uniq)
21+
22+
# get secrets mounted as volume
23+
secrets_volumes_pods=$(kubectl get pods -n $namespace \
24+
-o jsonpath='{.items[*].spec.volumes[*].secret.secretName}')
25+
secrets_volumes_cronjobs=$(kubectl get cronjobs -n $namespace \
26+
-o jsonpath='{.items[*].spec.jobTemplate.spec.template.spec.volumes[*].secret.secretName}')
27+
28+
# get secrets mounted as environment variable from env
29+
secrets_env_pods=$(kubectl get pods -n $namespace \
30+
-o jsonpath='{.items[*].spec.containers[*].env[*].valueFrom.secretKeyRef.name}')
31+
secrets_env_cronjobs=$(kubectl get cronjobs -n $namespace \
32+
-o jsonpath='{.items[*].spec.jobTemplate.spec.template.spec.containers[*].env.valueFrom.secretKeyRef.name}')
33+
34+
# get secrets mounted as environment variable from envFrom
35+
secrets_envfrom_pods=$(kubectl get pods -n $namespace \
36+
-o jsonpath='{.items[*].spec.containers[*].envFrom[*].secretRef.name}')
37+
secrets_envfrom_cronjobs=$(kubectl get cronjobs -n $namespace \
38+
-o jsonpath='{.items[*].spec.jobTemplate.spec.template.spec.containers[*].envFrom[*].secretRef.name}')
39+
40+
# get secrets from image pull secrets
41+
secrets_image_pull_secrets=$(kubectl get pods -n $namespace \
42+
-o jsonpath='{.items[*].spec.imagePullSecrets[*].name}')
43+
44+
used_resource=$(echo "
45+
${secrets_volumes_pods}
46+
${secrets_volumes_cronjobs}
47+
${secrets_env_pods}
48+
${secrets_env_cronjobs}
49+
${secrets_envfrom_pods}
50+
${secrets_envfrom_cronjobs}
51+
${secrets_image_pull_secrets}
52+
" | xargs -n1 | uniq)
53+
;;
54+
"configmaps" | "configmap" | "cm")
55+
# get all configmaps
56+
available_resources=$(kubectl get configmaps -n $namespace \
57+
-o jsonpath='{.items[*].metadata.name}' | xargs -n1 | uniq)
58+
59+
# get configmaps mounted as volume
60+
configmaps_volumes_pods=$(kubectl get pods -n $namespace \
61+
-o jsonpath='{.items[*].spec.volumes[*].configMap.name}')
62+
configmaps_volumes_cronjobs=$(kubectl get cronjobs -n $namespace \
63+
-o jsonpath='{.items[*].spec.jobTemplate.spec.template.spec.volumes[*].configMap.name}')
64+
65+
# get secrets mounted as environment variable from env
66+
configmaps_env_pods=$(kubectl get pods -n $namespace \
67+
-o jsonpath='{.items[*].spec.containers[*].env[*].valueFrom.configMapKeyRef.name}')
68+
configmaps_env_cronjobs=$(kubectl get cronjobs -n $namespace \
69+
-o jsonpath='{.items[*].spec.jobTemplate.spec.template.spec.containers[*].env.valueFrom.configMapKeyRef.name}')
70+
71+
# get secrets mounted as environment variable from envFrom
72+
configmaps_envfrom_pods=$(kubectl get pods -n $namespace \
73+
-o jsonpath='{.items[*].spec.containers[*].envFrom[*].configMapRef.name}')
74+
configmaps_envfrom_cronjobs=$(kubectl get cronjobs -n $namespace \
75+
-o jsonpath='{.items[*].spec.jobTemplate.spec.template.spec.containers[*].envFrom[*].configMapRef.name}')
76+
77+
used_resource=$(echo "
78+
${configmaps_volumes_pods}
79+
${configmaps_volumes_cronjobs}
80+
${configmaps_env_pods}
81+
${configmaps_env_cronjobs}
82+
${configmaps_envfrom_pods}
83+
${configmaps_envfrom_cronjobs}
84+
${configmaps_image_pull_secrets}
85+
" | xargs -n1 | uniq)
86+
;;
87+
*)
88+
echo "Resource ${resource} not found."
89+
echo "Usage:"
90+
echo " kubectl prune [RESOURCE (secrets|configmaps)] [NAMESPACE]"
91+
echo "Example:"
92+
echo " kubectl prune secrets my-namespace"
93+
exit 1
94+
;;
95+
esac
96+
97+
resource_name_list=""
98+
for available_name in $available_resources
99+
do
100+
delete=true
101+
for resource_name in $used_resource
102+
do
103+
if [ "$available_name" == "$resource_name" ]
104+
then
105+
delete=false
106+
break
107+
fi
108+
done
109+
110+
if [ "$delete" == "true" ]
111+
then
112+
resource_name_list="${available_name} ${resource_name_list}"
113+
fi
114+
done
115+
116+
if [ "$resource_name_list" == "" ]
117+
then
118+
echo "No resource found."
119+
exit 0
120+
fi
121+
122+
echo "About to delete the following resources: ${resource_name_list}"
123+
124+
# confirmation prompt
125+
read -p "Delete listed resources? (yes/no): " -r
126+
if [[ $REPLY =~ ^[Yy]es$ ]]
127+
then
128+
for resource_name in $resource_name_list
129+
do
130+
kubectl delete $resource $resource_name -n $namespace
131+
done
132+
fi

0 commit comments

Comments
 (0)