|
| 1 | +#!/usr/bin/env bash |
| 2 | + |
| 3 | +# |
| 4 | +# mdb_operator_diagnostic_data.sh |
| 5 | +# |
| 6 | +# Use this script to gather data about your MongoDB Enterprise Kubernetes Operator |
| 7 | +# and the MongoDB Resources deployed with it. |
| 8 | +# |
| 9 | + |
| 10 | +# |
| 11 | +# shellcheck disable=SC2119 |
| 12 | +# shellcheck disable=SC2039 |
| 13 | +# |
| 14 | + |
| 15 | +usage() { |
| 16 | + local script_name |
| 17 | + script_name=$(basename "${0}") |
| 18 | + echo "Usage:" |
| 19 | + echo "${script_name} <namespace> <mdb_resource_name> [<operator_name>] [--private]" |
| 20 | +} |
| 21 | + |
| 22 | +contains() { |
| 23 | + local e match=$1 |
| 24 | + shift |
| 25 | + for e; do [[ "$e" == "$match" ]] && return 0; done |
| 26 | + return 1 |
| 27 | +} |
| 28 | + |
| 29 | +if [ -z "${2}" ]; then |
| 30 | + usage |
| 31 | + exit 1 |
| 32 | +fi |
| 33 | + |
| 34 | +namespace="${1}" |
| 35 | +mdb_resource="${2}" |
| 36 | +operator_name="${3:-mongodb-enterprise-operator}" |
| 37 | +current_date="$(date +%Y-%m-%d_%H_%M)" |
| 38 | + |
| 39 | +contains "--private" "$@" |
| 40 | +private_mode=$? |
| 41 | + |
| 42 | +log_dir="logs_${current_date}" |
| 43 | +mkdir -p "${log_dir}" &> /dev/null |
| 44 | + |
| 45 | + |
| 46 | +if ! kubectl get "namespace/${namespace}" &> /dev/null; then |
| 47 | + echo "Error fetching namespace. Make sure name ${namespace} for Namespace is correct." |
| 48 | + exit 1 |
| 49 | +fi |
| 50 | + |
| 51 | +if ! kubectl -n "${namespace}" get "mdb/${mdb_resource}" &> /dev/null; then |
| 52 | + echo "Error fetching the MongoDB resource. Make sure the ${mdb_resource} is correct." |
| 53 | + exit 1 |
| 54 | +fi |
| 55 | + |
| 56 | +if ! kubectl -n "${namespace}" get "deployment/${operator_name}" &> /dev/null; then |
| 57 | + echo "Error fetching the MongoDB Operator Deployment. Make sure the deployment/${operator_name} exist and it is running." |
| 58 | + exit 1 |
| 59 | +fi |
| 60 | + |
| 61 | +if [ ${private_mode} == 0 ]; then |
| 62 | + echo "+ Running on private mode. Make sure you don't share the results of this run outside your organization." |
| 63 | +fi |
| 64 | + |
| 65 | +echo "++ Versions" |
| 66 | +mdb_operator_pod=$(kubectl -n "${namespace}" get pods -l "app=${operator_name}" -o name | cut -d'/' -f 2) |
| 67 | +echo "+ Operator Pod: pod/${mdb_operator_pod}" |
| 68 | + |
| 69 | +mdb_operator_filename="operator.yaml" |
| 70 | +echo "+ Saving Operator Deployment into ${mdb_operator_filename}" |
| 71 | +kubectl -n "${namespace}" get "deployment/${operator_name}" -o yaml > "${log_dir}/${mdb_operator_filename}" |
| 72 | + |
| 73 | +echo "+ Kubernetes Version Reported by kubectl" |
| 74 | +kubectl version |
| 75 | + |
| 76 | +if type oc &> /dev/null; then |
| 77 | + echo "+ Kubernetes Version Reported by oc" |
| 78 | + oc version |
| 79 | +fi |
| 80 | + |
| 81 | +operator_logs_filename="${operator_name}_${current_date}.logs" |
| 82 | +echo "+ Saving Operator logs to file ${operator_logs_filename}" |
| 83 | +kubectl -n "${namespace}" logs "deployment/${operator_name}" > "${log_dir}/${operator_logs_filename}" |
| 84 | + |
| 85 | +database_container_pretty_name=$(kubectl -n "${namespace}" exec -it "${mdb_resource}-0" -- cat /etc/*release | grep "PRETTY_NAME" | cut -d'=' -f 2) |
| 86 | +operator_container_pretty_name=$(kubectl -n "${namespace}" exec -it "${mdb_operator_pod}" -- cat /etc/*release | grep "PRETTY_NAME" | cut -d'=' -f 2) |
| 87 | +echo "+ Operator is running on: ${operator_container_pretty_name}" |
| 88 | +echo "+ Database is running on: ${database_container_pretty_name}" |
| 89 | + |
| 90 | +echo "++ Kubernetes Cluster Ecosystem" |
| 91 | +echo "+ Kubectl Cluster Information" |
| 92 | +kubectl cluster-info |
| 93 | + |
| 94 | +if [ ${private_mode} == 0 ]; then |
| 95 | + kubectl_cluster_info_filename="kubectl_cluster_info_${current_date}.logs" |
| 96 | + echo "+ Saving Cluster Info to file ${kubectl_cluster_info_filename} (this might take a few minutes)" |
| 97 | + kubectl cluster-info dump | gzip > "${log_dir}/${kubectl_cluster_info_filename}.gz" |
| 98 | +else |
| 99 | + echo "= Skipping Kubectl cluster information dump, use --private to enable." |
| 100 | +fi |
| 101 | + |
| 102 | +kubectl_sc_dump_filename="kubectl_storage_class_${current_date}.yaml" |
| 103 | +kubectl get storageclass -o yaml > "${log_dir}/${kubectl_sc_dump_filename}" |
| 104 | + |
| 105 | +nodes_filename="nodes.yaml" |
| 106 | +echo "+ Nodes" |
| 107 | +kubectl get nodes |
| 108 | + |
| 109 | +echo "+ Saving Nodes full state to ${nodes_filename}" |
| 110 | +kubectl get nodes -o yaml > "${log_dir}/${nodes_filename}" |
| 111 | + |
| 112 | +echo "++ MongoDB Resource Running Environment" |
| 113 | +crd_filename="crd_mdb.yaml" |
| 114 | +echo "+ Saving MDB Customer Resource Definition into ${crd_filename}" |
| 115 | +kubectl -n "${namespace}" get crd/mongodb.mongodb.com -o yaml > "${crd_filename}" |
| 116 | + |
| 117 | +project_filename="project.yaml" |
| 118 | +mdb_resource_name="mdb/${mdb_resource}" |
| 119 | +project_name=$(kubectl -n "${namespace}" get "${mdb_resource_name}" -o jsonpath='{.spec.project}') |
| 120 | +credentials_name=$(kubectl -n "${namespace}" get "${mdb_resource_name}" -o jsonpath='{.spec.credentials}') |
| 121 | + |
| 122 | +resource_filename="mdb_object_${mdb_resource}.yaml" |
| 123 | +echo "+ MongoDB Resource Status" |
| 124 | +kubectl -n "${namespace}" get "${mdb_resource_name}" -o yaml > "${log_dir}/${resource_filename}" |
| 125 | + |
| 126 | +echo "+ Saving Project YAML file to ${project_filename}" |
| 127 | +kubectl -n "${namespace}" get "configmap/${project_name}" -o yaml > "${log_dir}/${project_filename}" |
| 128 | + |
| 129 | +credentials_user=$(kubectl -n "${namespace}" get "secret/${credentials_name}" -o jsonpath='{.data.user}' | base64 --decode) |
| 130 | +echo "+ User configured is (credentials.user): ${credentials_user}" |
| 131 | + |
| 132 | +echo "= To get the Secret Public API Key use: kubectl -n ${namespace} get secret/${credentials_name} -o jsonpath='{.data.publicApiKey}' | base64 --decode)" |
| 133 | + |
| 134 | +statefulset_filename="statefulset.yaml" |
| 135 | +echo "+ Saving StatefulSet state to ${statefulset_filename}" |
| 136 | +kubectl -n "${namespace}" get "sts/${mdb_resource}" -o yaml > "${log_dir}/${statefulset_filename}" |
| 137 | + |
| 138 | +echo "+ Deployment Pods" |
| 139 | +kubectl -n "${namespace}" get pods | grep -E "^${mdb_resource}-[0-9]+" |
| 140 | + |
| 141 | +echo "+ Saving Pods state to ${mdb_resource}-N.logs" |
| 142 | +pods_in_namespace=$(kubectl -n "${namespace}" get pods -o name | cut -d'/' -f 2 | grep -E "^${mdb_resource}-[0-9]+") |
| 143 | +for pod in ${pods_in_namespace}; do |
| 144 | + kubectl -n "${namespace}" logs "${pod}" > "${log_dir}/${pod}.log" |
| 145 | + kubectl -n "${namespace}" get event --field-selector "involvedObject.name=${pod}" > "${log_dir}/${pod}_events.log" |
| 146 | +done |
| 147 | + |
| 148 | +echo "+ Persistent Volumes" |
| 149 | +kubectl -n "${namespace}" get pv |
| 150 | + |
| 151 | +echo "+ Persistent Volume Claims" |
| 152 | +kubectl -n "${namespace}" get pvc |
| 153 | + |
| 154 | +pv_filename="persistent_volumes.yaml" |
| 155 | +echo "+ Saving Persistent Volumes state to ${pv_filename}" |
| 156 | +kubectl -n "${namespace}" get pv -o yaml > "${log_dir}/${pv_filename}" |
| 157 | + |
| 158 | +pvc_filename="persistent_volume_claims.yaml" |
| 159 | +echo "+ Saving Persistent Volumes Claims state to ${pvc_filename}" |
| 160 | +kubectl -n "${namespace}" get pvc -o yaml > "${log_dir}/${pvc_filename}" |
| 161 | + |
| 162 | +services_filename="services.yaml" |
| 163 | +echo "+ Services" |
| 164 | +kubectl -n "${namespace}" get services |
| 165 | + |
| 166 | +echo "+ Saving Services state to ${services_filename}" |
| 167 | +kubectl -n "${namespace}" get services -o yaml > "${log_dir}/${services_filename}" |
| 168 | + |
| 169 | +echo "+ Saving Events for the Namespace" |
| 170 | +kubectl -n "${namespace}" get events > "${log_dir}/events.log" |
| 171 | + |
| 172 | +echo "+ Certificates (no private keys are captured)" |
| 173 | +csr_filename="csr.text" |
| 174 | +kubectl get csr | grep "${namespace}" |
| 175 | +echo "+ Saving Certificate state into ${csr_filename}" |
| 176 | +kubectl describe "$(kubectl get csr -o name | grep ${namespace})" |
| 177 | + |
| 178 | +echo "++ MongoDBUser Resource Status" |
| 179 | +mdbusers_filename="mdbu.yaml" |
| 180 | +kubectl -n "${namespace}" get mdbu |
| 181 | +echo "+ Saving MongoDBUsers to ${mdbusers_filename}" |
| 182 | +kubectl -n "${namespace}" get mdbu > "${log_dir}/${mdbusers_filename}" |
| 183 | + |
| 184 | +crdu_filename="crd_mdbu.yaml" |
| 185 | +echo "+ Saving MongoDBUser Customer Resource Definition into ${crdu_filename}" |
| 186 | +kubectl -n "${namespace}" get crd/mongodbusers.mongodb.com -o yaml > "${log_dir}/${crdu_filename}" |
| 187 | + |
| 188 | + |
| 189 | +echo "++ Compressing files" |
| 190 | +compressed_logs_filename="${namespace}__${mdb_resource}__${current_date}.tar.gz" |
| 191 | +tar -czf "${compressed_logs_filename}" -C "${log_dir}" . |
| 192 | + |
| 193 | +echo "- All logs have been captured and compressed into the file ${compressed_logs_filename}." |
| 194 | +echo "- If support is needed, please attach this file to an email to provide you with a better support experience." |
| 195 | +echo "- If there are additional logs that your organization is capturing, they should be made available in case of a support request." |
0 commit comments