Skip to content

Instantly share code, notes, and snippets.

@mpangrazzi
Created October 6, 2023 20:28
Show Gist options
  • Save mpangrazzi/a3c755645816a1b189b8fcf726f876fe to your computer and use it in GitHub Desktop.
Save mpangrazzi/a3c755645816a1b189b8fcf726f876fe to your computer and use it in GitHub Desktop.
Update Helm release namespace without having to delete and recreate it.
#!/bin/bash
#
# This script will patch a Helm release secret and move it to another namespace.
# It will also delete the original secret after the patching is done.
# It's useful when you want to move a Helm release to another namespace without having to delete and recreate it.
#
# Credits for the original idea: https://blog.random.io/moving-helm-release-to-another-kubernetes-namespace
#
# Requirements:
# - kubectl
# - helm
# - jq (https://github.com/jqlang/jq)
# - oq (https://github.com/Blacksmoke16/oq)
SOURCE_NAMESPACE=source-namespace
TARGET_NAMESPACE=target-namespace
RELEASE_NAME=release-name
RELEASE_VERSION=1
RELEASE_SECRET="sh.helm.release.v1.${RELEASE_NAME}.v${RELEASE_VERSION}"
# Get the original release secret
kubectl -n $SOURCE_NAMESPACE get secret $RELEASE_SECRET -o yaml > "${RELEASE_NAME}_orig.yaml"
# Decode the release secret data
oq -i yaml -r '.data.release' "${RELEASE_NAME}_orig.yaml" | base64 -D | base64 -D | gzip -d > "${RELEASE_NAME}_orig_secret_decoded.txt"
# Log the current namespace present in release secret data
CURRENT_NAMESPACE=$(cat "${RELEASE_NAME}_orig_secret_decoded.txt" | jq -r .namespace)
echo "current namespace: $CURRENT_NAMESPACE"
# Patch the release secret data with the new namespace
NEW_VALUE=$(cat "${RELEASE_NAME}_orig_secret_decoded.txt" | jq -c ".namespace=\"$TARGET_NAMESPACE\"" | gzip -c | base64 | base64)
oq -i yaml -o yaml --arg new "$NEW_VALUE" '.data.release = $new' "${RELEASE_NAME}_orig.yaml" > "${RELEASE_NAME}_patched.yaml"
# Check the patched file logging the new namespace
NEW_NAMESPACE=$(oq -i yaml -r '.data.release' "${RELEASE_NAME}_patched.yaml" | base64 -D | base64 -D | gzip -d | jq .namespace)
echo "new namespace: $NEW_NAMESPACE"
# Update the namespace of the secret as we did with the release data
oq -i yaml -o yaml --arg new "$TARGET_NAMESPACE" '.metadata.namespace = $new' "${RELEASE_NAME}_patched.yaml" > "${RELEASE_NAME}_patched_final.yaml"
# User confirmation before applying the patched file and deleting the original secret.
# It's a good idea to check "${RELEASE_NAME}_patched_final.yaml" file before applying it.
echo "Patched file: ${RELEASE_NAME}_patched_final.yaml"
read -p "Continue (y/n)?" CONT
if [ "$CONT" = "y" ]; then
kubectl apply -f "${RELEASE_NAME}_patched_final.yaml" && \
helm ls -A && \
kubectl -n $SOURCE_NAMESPACE delete secret $RELEASE_SECRET
else
echo "Aborted"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment