Merge "Remove migrate_helm_release.py script"
This commit is contained in:
commit
86379201b4
@ -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()
|
@ -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
|
Loading…
x
Reference in New Issue
Block a user