Merge "Remove migrate_helm_release.py script"

This commit is contained in:
Zuul 2023-03-27 18:49:47 +00:00 committed by Gerrit Code Review
commit 86379201b4
2 changed files with 0 additions and 412 deletions

View File

@ -1,247 +0,0 @@
#!/usr/bin/python
#
# Copyright (c) 2022 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# This script will perform helm v2 to helm v3 resource migration. This includes
# using the helm 2to3 plugin along with labeling and annotating cluster
# resources associated with the helm release so that it is managable by helm v3
#
import keyring
import psycopg2
import subprocess
import sys
import os
from controllerconfig.common import log
from psycopg2.extras import RealDictCursor
LOG = log.get_logger(__name__)
def main():
if len(sys.argv) != 2:
raise Exception("Release name should be specified")
log.configure()
release = sys.argv[1]
LOG.info("Starting to migrate release {}".format(release))
conn = init_connection()
migrate_release(conn, release)
def init_connection():
helmv2_db_pw = keyring.get_password("helmv2", "database")
if not helmv2_db_pw:
raise Exception("Unable to get password to access helmv2 database.")
return psycopg2.connect(user="admin-helmv2",
password=helmv2_db_pw,
host="localhost",
database="helmv2")
def migrate_release(conn, release):
release_info = get_release_info(conn, release)
release_name = release_info["name"]
create_configmap(release_info)
helm2to3_migrate(release_name)
update_release_resources(release_name)
cleanup_release(conn, release_name)
def get_release_info(conn, release):
release_info = None
with conn:
with conn.cursor(cursor_factory=RealDictCursor) as cur:
cur.execute("select * from releases where name = %s", (release,))
release_info = cur.fetchone()
if not release_info:
raise Exception("Release name is not present in the DB")
return release_info
def create_configmap(release_info):
configmap_label_name = release_info["name"]
configmap = """
apiVersion: v1
kind: ConfigMap
metadata:
name: {key}
namespace: kube-system
labels:
NAME: {name}
STATUS: {status}
OWNER: {owner}
VERSION: "{version}"
data:
release: {release}
""".format(key=release_info["key"],
name=configmap_label_name,
status=release_info["status"],
owner=release_info["owner"],
version=release_info["version"],
release=release_info["body"])
configmap_path = os.path.join("/tmp", configmap_label_name + ".yaml")
with open(configmap_path, "w") as f:
f.write(configmap)
cmd = "kubectl --kubeconfig=/etc/kubernetes/admin.conf apply -f {}" \
.format(configmap_path)
execute_command(cmd)
LOG.info("Configmap {} created".format(configmap_label_name))
os.remove(configmap_path)
def helm2to3_migrate(release_name):
cmd = ("helm 2to3 convert --kubeconfig=/etc/kubernetes/admin.conf "
"--tiller-out-cluster -s configmaps {}".format(release_name))
execute_command(cmd)
LOG.info("Migrated {} helm2 release to helm3".format(release_name))
def get_api_resources(namespaced=True):
if namespaced:
namespace_arg = ' --namespaced=true'
else:
namespace_arg = ' --namespaced=false'
# Get all API resources
try:
api_resources = []
api_resources_query = subprocess.check_output(
("kubectl --kubeconfig=/etc/kubernetes/admin.conf api-resources "
" --verbs=list {} -o name".format(namespace_arg)),
shell=True, stderr=subprocess.STDOUT).decode('utf-8')
if api_resources_query:
api_resources = [a for a in api_resources_query.split("\n") if a]
except Exception as e:
LOG.info("Exception {} occured when trying to get kubernetes API "
"resources".format(e))
raise
return api_resources
def update_release_resources(release_name):
""" Properly label resources to support Helm v3
Per https://github.com/helm/helm-2to3/issues/147, existing cluster
resources deployed by helm v2 are not labeled properly for helm v3.
Search for deployed resources based on release name and adjust the
labeling.
"""
LOG.info("Gathering namespaced kubernetes API resources...")
namespaced_api_resources = get_api_resources(namespaced=True)
LOG.info("Gathering non-namespaced kubernetes API resources...")
nonamespaced_api_resources = get_api_resources(namespaced=False)
# Get all helm release resources
release_resources = []
for r in namespaced_api_resources + nonamespaced_api_resources:
if r in nonamespaced_api_resources:
awk_print = '{print $1}'
else:
awk_print = '{print "-n "$1" "$2}'
LOG.info("Searching for {} resource related to {}...".format(
r, release_name))
try:
cmd = ("kubectl --kubeconfig=/etc/kubernetes/admin.conf get -A "
"-l app.kubernetes.io/instance={} --show-kind "
"--ignore-not-found --no-headers {}".format(
release_name, r))
release_query = subprocess.Popen(cmd, shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
output_filter = subprocess.Popen(['awk', awk_print],
stdin=release_query.stdout,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True)
release_query.stdout.close()
resource_list, err = output_filter.communicate()
if output_filter.returncode != 0:
LOG.info("Command failed:\n {}\n{}\n{}".format(
cmd, resource_list, err))
raise Exception("Failed to execute command: %s" % cmd)
if resource_list:
resources = [r for r in resource_list.split("\n") if r]
release_resources += resources
except Exception as e:
LOG.info("Exception {} occured when trying to check for {} use of "
"API resource {}".format(e, release_name, r))
continue
# Dump the resources need to be labeled/annotated
for r in release_resources:
LOG.info("Found {} resource: {}".format(release_name, r))
# Label the resources appropriately to support the release upgrade
for tiller_managed_resource in release_resources:
try:
labeling_out = subprocess.check_output(
('kubectl --kubeconfig=/etc/kubernetes/admin.conf label '
'--overwrite {} '
'"app.kubernetes.io/managed-by=Helm"'.format(
tiller_managed_resource)),
shell=True, stderr=subprocess.STDOUT).decode('utf-8')
LOG.info(labeling_out)
except Exception as e:
LOG.info("Exception {} occured when trying to label '{}'".format(
e, tiller_managed_resource))
continue
if "-n " in tiller_managed_resource:
# Extract and annotate the namespaced resource
# Ex: '-n metrics-server deployment.apps/ms-metrics-server'
components = [c for c in tiller_managed_resource.split(" ") if c]
namespace = components[1]
try:
annotate_out = subprocess.check_output(
('kubectl --kubeconfig=/etc/kubernetes/admin.conf annotate'
' --overwrite {} "meta.helm.sh/release-name={}" '
'"meta.helm.sh/release-namespace={}"'.format(
tiller_managed_resource, release_name, namespace)),
shell=True, stderr=subprocess.STDOUT).decode('utf-8')
LOG.info(annotate_out)
except Exception as e:
LOG.info("Exception {} occured when trying to annotate "
"'{}'".format(e, tiller_managed_resource))
continue
def cleanup_release(conn, release_name):
cmd = ("helm 2to3 cleanup --kubeconfig=/etc/kubernetes/admin.conf "
"--release-cleanup --tiller-out-cluster -s configmaps "
"--skip-confirmation --name {}".format(release_name))
execute_command(cmd)
with conn:
with conn.cursor() as cur:
cur.execute("delete from releases where name = %s",
(release_name,))
LOG.info("Cleaned up helm2 data for {}".format(release_name))
def execute_command(cmd):
sub = subprocess.Popen(cmd, shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = sub.communicate()
if sub.returncode != 0:
LOG.info("Command failed:\n %s\n%s\n%s" % (cmd, stdout, stderr))
raise Exception("Failed to execute command: %s" % cmd)
return stdout
if __name__ == "__main__":
main()

View File

@ -1,165 +0,0 @@
#!/bin/bash
# vim: tabstop=4 shiftwidth=4 expandtab
#
# Copyright (c) 2020-2023 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# This migration script is used for migrating helmV2 applications helmrelease to
# helmV3, therefore this enables armada apps to be upgrade to FluxCD apps in a
# platform upgrade: It will:
# - Install helm-2to3 plugin
# - Move helm2 config to helm3
# - Run migration script for each release
set -ef
NAME=$(basename $0)
# The migration scripts are passed these parameters:
FROM_RELEASE=$1
TO_RELEASE=$2
ACTION=$3
PATH=$PATH:/usr/local/sbin:/usr/bin
# This will log to /var/log/platform.log
function log {
logger -p local1.info $1
}
function install_helm_2to3 {
log "$NAME: Installing helm 2to3 plugin"
if ! helm plugin list | grep 2to3; then
export HELM_LINTER_PLUGIN_NO_INSTALL_HOOK=true
helm plugin install /usr/local/share/helm/plugins/2to3
else
log "$NAME: helm 2to3 already present"
fi
}
function get_helmv2_config {
log "$NAME: Retreiving helm config from Armada's tiller container."
JSONPATH='{range .items[*]}{"\n"}{@.metadata.name}:{@.metadata.deletionTimestamp}{range @.status.conditions[*]}{":"}{@.type}={@.status}{end}{end}'
ARMADA_PODS=( $(kubectl get pods -n armada \
--kubeconfig=/etc/kubernetes/admin.conf \
--selector=application=armada,component=api \
--field-selector status.phase=Running \
--output=jsonpath="${JSONPATH}") )
if [ ${#ARMADA_PODS[@]} -eq 0 ]; then
log "$NAME: ERROR - Could not find armada pod."
exit 1
fi
# Get first available Running and Ready armada pod, with tiller container
POD=""
for LINE in "${ARMADA_PODS[@]}"; do
# match only Ready pods with nil deletionTimestamp
if [[ $LINE =~ ::.*Ready=True ]]; then
# extract pod name, it is first element delimited by :
A=$( cut -d ':' -f 1 - <<< "${LINE}" )
P=${A[0]}
else
continue
fi
kubectl --kubeconfig=/etc/kubernetes/admin.conf \
cp armada/${P}:tmp/.helm "$HOME"/.helm -c tiller
RC=$?
if [ ${RC} -eq 0 ]; then
log "$NAME: helmv2 config copied to /home/sysadmin/.helm"
break
else
log "$NAME: ERROR - failed to copy helm config from helmv2 (tiller) to host. (RETURNED: $RC)"
exit 1
fi
done
yes | helm 2to3 move config
RC=$?
if [ ${RC} -eq 0 ]; then
log "$NAME: helmV2 release info and config moved to helmv3"
else
log "$NAME: ERROR - failed to migrate release info to helmv3. (RETURNED: $RC)"
exit 1
fi
}
function migrate_apps {
log "$NAME: Migrating helm releases"
HELM_REL=$(KUBECONFIG=/etc/kubernetes/admin.conf helmv2-cli -- helm list -a | tail -n+2 | awk '{print $1}')
for rel in ${HELM_REL}; do
case $rel in
# SUPPORTED: auditd-1.0-20.tgz -> 65-k8s-app-upgrade.sh
ns-auditd)
log "$NAME: migrating helm release $rel."
/usr/bin/migrate_helm_release.py $rel
;;
# SPECIAL HANDLE: cert-manager-1.0-26.tgz -> 64-upgrade-cert-manager.sh
cm-cert-manager | cm-cert-manager-psp-rolebinding)
log "$NAME: helm release $rel is being migrated with a dedicated upgrade script."
;;
# SUPPORTED: metrics-server-1.0-8.tgz -> 65-k8s-app-upgrade.sh
ms-metrics-server-psp-rolebinding | ms-metrics-server)
log "$NAME: migrating helm release $rel."
/usr/bin/migrate_helm_release.py $rel
;;
# SUPPORTED: nginx-ingress-controller-1.1-18.tgz -> 65-k8s-app-upgrade.sh
ic-nginx-ingress )
log "$NAME: migrating helm release $rel."
/usr/bin/migrate_helm_release.py $rel
;;
# SPECIAL HANDLE: oidc-auth-apps-1.0-61.tgz -> 82-upgrade-oidc.py
oidc-dex | oidc-oidc-client | oidc-auth-secret-observer)
log "$NAME: helm release $rel is being migrated with a dedicated upgrade script."
;;
# SUPPORTED: platform-integ-apps-1.0-44.tgz -> 65-k8s-app-upgrade.sh
stx-ceph-pools-audit | stx-cephfs-provisioner | stx-rbd-provisioner)
log "$NAME: migrating helm release $rel."
/usr/bin/migrate_helm_release.py $rel
;;
# NOT SUPPORTED: portieris-1.0-33.tgz
portieris-portieris-psp-rolebinding | portieris-portieris-certs | portieris-portieris)
log "$NAME: migration of helm release $rel is not currently supported."
;;
# SUPPORTED: ptp-notification-1.0-52.tgz -> 65-k8s-app-upgrade.sh
ptp-ptp-notification-psp-rolebinding | ptp-ptp-notification)
log "$NAME: migrating helm release $rel."
/usr/bin/migrate_helm_release.py $rel
;;
# SUPPORTED: snmp-1.0-25.tgz -> 65-k8s-app-upgrade.sh
ns-snmp)
log "$NAME: migrating helm release $rel."
/usr/bin/migrate_helm_release.py $rel
;;
# NOT SUPPORTED: vault-1.0-23.tgz
sva-vault-psp-rolebinding | sva-vault)
log "$NAME: migration of helm release $rel is not currently supported."
;;
# For Openstack's helm releases.
osh-openstack-*)
log "$NAME: migrating helm release $rel."
/usr/bin/migrate_helm_release_openstack.py $rel
;;
*)
log "$NAME: migration of UNKNOWN helm release $rel is not currently supported."
;;
esac
done
}
if [ "$ACTION" == "activate" ]; then
# TODO: double check the inclusive condition.
if [[ "$TO_RELEASE" == "22.12" && "$FROM_RELEASE" == "22.06" ]]; then
log "upgrade to 22.12, skip"
exit 0
fi
log "$NAME: Starting Helm release migration from release $FROM_RELEASE to $TO_RELEASE with action $ACTION"
install_helm_2to3
get_helmv2_config
migrate_apps
helm plugin uninstall 2to3
fi
exit 0