Created
February 4, 2022 21:58
-
-
Save ravilach/867c340379683ef0e40eb94a2fbefbe5 to your computer and use it in GitHub Desktop.
Shipa Support Bundler
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 | |
usage() { | |
local -r _exitCode="${1}" | |
local -r _errorMessage="${2}" | |
if [[ -n "${_errorMessage}" ]]; then | |
printf >&2 "[ERROR] %s\n\n" "${_errorMessage}" | |
fi | |
echo " Connects to a Kubernetes cluster, pulls a diagnostic information and creates a bundle for Shipa Support." | |
echo >&2 " Usage: $0 [-o output_base_dir] [-s control_plan_namespace] [-m managed_namespace_1 managed_namespace_2 managed_namespace_n...] [-h]" | |
echo >&2 -e "\t-o | --out output_base_dir [Optional] Base directory to store the diagnostics data in. Defaults to the current directory." | |
echo >&2 -e "\t-s | --system control_plan_namespace [Optional] The name of the Shipa control plane namespace. Only applicable to self-hosted installation. Defaults to shipa-system." | |
echo >&2 -e "\t-m | --managed managed_namespace [Optional] The name of the Shipa managed namespace(s). Space separated list. Can be provided more than once. Defaults to shipa." | |
echo >&2 -e "\t-h | --help Print this message" | |
echo >&2 "" | |
echo >&2 " Example:" | |
echo >&2 -e "\t\t$0 --out /tmp/diagnostics --system none --managed my-framework-namespace" | |
exit ${_exitCode} | |
} | |
get_resource_diagnostics() { | |
local -r _target_namespace="${1}" | |
local -r _resource_type_long="${2}" | |
local -r _show_wide="${3:-"false"}" | |
local -r _resource_type="$(echo "${_resource_type_long}" | awk -F'.' '{print $1}')" | |
[[ "${_show_wide}" != "false" ]] && _flag="-o wide" | |
echo "" | tee -a ${GENERAL} | |
echo "[INFO] ${_target_namespace} ${_resource_type} (details in ${_target_namespace}-${_resource_type}.yaml):" | tee -a ${GENERAL} | |
kubectl get ${_resource_type_long} -n ${_target_namespace} ${_flag} 2>&1 | tee -a ${GENERAL} | |
kubectl get ${_resource_type_long} -n ${_target_namespace} -o yaml 2>&1 >${_target_namespace}-${_resource_type}.yaml | |
} | |
get_pod_logs() { | |
local -r _target_namespace="${1}" | |
echo "" | tee -a ${GENERAL} | |
echo "[INFO] Pulling ${_target_namespace} pod logs and storing them under ${_target_namespace}-pod-logs directory" | tee -a ${GENERAL} | |
mkdir -p ${_target_namespace}-pod-logs | |
pushd ${_target_namespace}-pod-logs >/dev/null | |
for _pod in $(kubectl get pods -n ${_target_namespace} -o name); do | |
for _container in $(kubectl get ${_pod} -n ${_target_namespace} -o jsonpath='{range .spec.containers[*]}{@.name} {end}{range .spec.initContainers[*]}{@.name} {end}'); do | |
echo "[INFO] Pulling logs for ${_pod}/${_container}" | tee -a ${GENERAL} | |
kubectl logs -n ${_target_namespace} ${_pod} -c ${_container} 2>&1 >"${_pod//\//__}__${_container}.log" | |
done | |
done | |
popd >/dev/null | |
} | |
get_namespace_diagnostics() { | |
local -r _target_namespace="${1}" | |
echo "" | tee -a ${GENERAL} | |
kubectl get ns ${_target_namespace} 2>/dev/null && NS_FOUND="true" || NS_FOUND="false" | |
if [[ "${NS_FOUND}" == "true" ]]; then | |
echo "[INFO] Found '${_target_namespace}' namespace." | tee -a ${GENERAL} | |
else | |
echo "[INFO] '${_target_namespace}' namespace does not exist. Skipping ${_target_namespace} checks." | tee -a ${GENERAL} | |
return | |
fi | |
mkdir -p ${_target_namespace} | |
pushd ${_target_namespace} >/dev/null | |
get_resource_diagnostics ${_target_namespace} events | |
get_resource_diagnostics ${_target_namespace} deployments.apps | |
get_resource_diagnostics ${_target_namespace} daemonsets.apps | |
get_resource_diagnostics ${_target_namespace} statefulsets.apps | |
get_resource_diagnostics ${_target_namespace} replicasets.apps | |
get_resource_diagnostics ${_target_namespace} services | |
get_resource_diagnostics ${_target_namespace} ingresses.networking.k8s.io | |
get_resource_diagnostics ${_target_namespace} jobs.batch wide | |
get_resource_diagnostics ${_target_namespace} pods wide | |
get_pod_logs ${_target_namespace} | |
popd >/dev/null | |
} | |
SHIPA_SYSTEM="${SHIPA_SYSTEM:-"shipa-system"}" | |
DIAGNOSTICS_DIR=${DIAGNOSTICS_DIR:-"./"} | |
MANAGED_NAMESPACES="" | |
while [ -n "$1" ]; do | |
case "$1" in | |
-o | --out) | |
shift | |
DIAGNOSTICS_DIR="${1}" | |
;; | |
-s | --system) | |
shift | |
SHIPA_SYSTEM="${1}" | |
;; | |
-m | --managed) | |
while [[ -n "${2}" && ! "${2}" =~ ^- ]]; do | |
shift | |
MANAGED_NAMESPACES+=" ${1}" | |
done | |
;; | |
-h | --help) | |
usage 0 | |
;; | |
*) | |
usage 1 "Invalid parameter '$1'" | |
;; | |
esac | |
shift | |
done | |
# get full name of the output root directory | |
DIAGNOSTICS_DIR="$(cd "$(dirname "${DIAGNOSTICS_DIR}")" >/dev/null 2>&1 && pwd)" | |
# set default managed namespace and ensure list has unique entries only | |
MANAGED_NAMESPACES="$(echo "${MANAGED_NAMESPACES:-"shipa"}" | sed 's/^ //; s/ /\n/g' | awk '!a[$0]++' | grep -v "${SHIPA_SYSTEM}\\|cert-manager")" | |
type -p kubectl || ( | |
usage 1 "kubectl cannot be found on your system. Ensure that kubectl is installed and on your path." | |
) | |
type -p tar && CREATE_BUNDLE="true" || ( | |
echo >&2 "[ERROR] tar cannot be found on your system. Logs will be collected, but the support bundle will not be created." | |
CREATE_BUNDLE="false" | |
) | |
mkdir -p ${DIAGNOSTICS_DIR} | |
if [[ ! -d "${DIAGNOSTICS_DIR}" ]]; then | |
usage 1 "${DIAGNOSTICS_DIR} does not exist and could not be created." | |
fi | |
export OUT_DIR="$(echo "shipa-diagnostics-$(date +%s)")" | |
echo "[INFO] Creating diagnostics sub directory '${OUT_DIR}'." | |
pushd ${DIAGNOSTICS_DIR} >/dev/null | |
mkdir -p "${OUT_DIR}" | |
pushd "${OUT_DIR}" >/dev/null | |
GENERAL="${PWD}/overview.log" | |
if [[ "$(basename $PWD)" != "${OUT_DIR}" ]]; then | |
popd >/dev/null | |
popd >/dev/null | |
usage 1 "Unable to create diagnostics sub directory '${OUT_DIR}'." | |
fi | |
rm -rf * | |
echo "[INFO] Testing connection to cluster." | tee -a ${GENERAL} | |
kubectl get ns 2>&1 >/dev/null | |
if [[ $? -ne 0 ]]; then | |
popd >/dev/null | |
popd >/dev/null | |
usage 1 "Could not connect to cluster with context '$(kubectl config current-context)'." | |
fi | |
echo "[INFO] Using kubectl context '$(kubectl config current-context)'." | tee -a ${GENERAL} | |
for _target_namespace in ${SHIPA_SYSTEM} cert-manager ${MANAGED_NAMESPACES}; do | |
get_namespace_diagnostics ${_target_namespace} | |
done | |
echo "" | |
popd >/dev/null | |
if [[ "${CREATE_BUNDLE}" == "true" ]]; then | |
tar -zcf ${OUT_DIR}.tar.gz ${OUT_DIR} && echo "[INFO] Support bundle was created as ${OUT_DIR}.tar.gz" || echo >&2 "[ERROR] Could not create support bundle." | |
fi | |
popd >/dev/null | |
echo "[INFO] Diagnostics data was sent to ${DIAGNOSTICS_DIR}/${OUT_DIR}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment