Forked from lisawolderiksen/secrets_without_certificates.sh
Last active
March 27, 2022 11:03
-
-
Save joaocc/8af204a09a9e72bd86a3e7dfb53ee8b1 to your computer and use it in GitHub Desktop.
Script to detect "orphaned" TLS secrets when Cert manager (cainjector) complains about "unable to fetch certificate that owns the secret", because deleting a Certificate will not (default) delete the Secret. (Ref. https://cert-manager.io/docs/usage/certificate/#cleaning-up-secrets-when-certificates-are-deleted)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
set -eo pipefail | |
set -x | |
while [ "$1" != "" ] | |
do | |
bash secrets_without_certificates.sh -n "$1" | |
shift | |
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# one liner | |
for nn in ns1, ns2, ns3; do bash secrets_without_certificates.sh -n "$nn"; done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
set -eo pipefail | |
# set -x | |
usage() { | |
cat << EOF | |
This script detects TLS secrets which refer to certificates that don't exist (anymore). | |
This is the case when error "unable to fetch certificate that owns the secret" occurs in cert-manager (cainjector) logs. | |
The reason is that a certificate has been removed without the secret being deleted. | |
The solution is to clean up by deleting any secret which belonged to a certificate that no longer exists. | |
Usage: $0 [-n namespace] [-v] | |
$0 | |
-n | --namespace <namespace> (optional, default="istio-system") | |
-v | --verbose (optional) | |
-h | --help (displays help and exits) | |
Examples: | |
Check the TLS secrets and matching certificates in the "istio-system" namespace, print only the end result | |
$0 | |
Check the TLS secrets and matching certificates in the "mynamespace" namespace, print only the end result | |
$0 -n mynamespace | |
Check the TLS secrets and matching certificates in the "istio-system" namespace, print info about all TLS secrets and certificates | |
$0 -v | |
EOF | |
} | |
namespace="istio-system" | |
printfLog='silentPrintf' | |
# Read commandline arguments | |
while [ "$1" != "" ] | |
do | |
case $1 in | |
-n | --namespace ) | |
shift | |
namespace=$1 | |
;; | |
-v | --verbose ) | |
shift | |
printfLog='printf' | |
;; | |
-h | --help ) | |
usage | |
exit | |
;; | |
* ) | |
usage | |
exit 1 | |
esac | |
shift | |
done | |
# Don't print a string. | |
# This method is used when -v/--verbose is NOT specified. | |
silentPrintf() { | |
: | |
} | |
secrets_with_certificate_name=$(kubectl get secret -n $namespace -o jsonpath="{range .items[?(.type=='kubernetes.io/tls')]}{.metadata.name},{.metadata.annotations.cert-manager\.io/certificate-name} {end}") | |
$printfLog "Listing secrets (of type kubernetes.io/tls) with their annotated certificate:\n" | |
for i in ${secrets_with_certificate_name[@]}; do | |
$printfLog "$i \n" | |
done | |
$printfLog "\nListing certificates:\n" | |
$printfLog "$(kubectl get certificate -n $namespace|awk '{print $1}'|grep -v "NAME")\n" | |
secrets_without_certs=("") | |
$printfLog "\nLooking for certificates matching the secrets:\n" | |
for secret_with_cert_name in ${secrets_with_certificate_name[@]}; do | |
IFS="," read -a details <<< "$secret_with_cert_name" | |
secret_name=${details[0]} | |
cert=${details[1]} | |
$printfLog "Secret $secret_name is made using cert $cert. Looking for that cert...\n" | |
certmatch=$(kubectl get certificate -n $namespace -o jsonpath="{range .items[?(.metadata.name=='$cert')]}{.metadata.name} {end}") | |
if [[ $certmatch == "" ]]; then | |
secrets_without_certs+=("$secret_name") | |
$printfLog "\n##### WARNING: Secret $secret_name has no matching certificate ($cert) and should be deleted. #####\n\n" | |
else | |
$printfLog "Certificate found.\n" | |
fi | |
done | |
printf "\nAll secrets that have no matching certificates (and should therefore be cleaned up):\n" | |
for i in ${secrets_without_certs[@]}; do | |
printf "%s \n", "$i" | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment