From c87bb7510709b2a1ef04ee96f81328dc4c7f2a6d Mon Sep 17 00:00:00 2001 From: Victor Becerra Date: Mon, 6 May 2024 16:28:53 +0200 Subject: [PATCH 01/10] added readme for support_bundle and fix api_url for V6.9 --- support_bundle/README.md | 37 ++ support_bundle/get_support_bundle.sh | 9 +- .../get_support_bundle_local_api.sh | 497 ++++++++++++++++++ 3 files changed, 539 insertions(+), 4 deletions(-) create mode 100644 support_bundle/README.md create mode 100755 support_bundle/get_support_bundle_local_api.sh diff --git a/support_bundle/README.md b/support_bundle/README.md new file mode 100644 index 00000000..42d1f4a5 --- /dev/null +++ b/support_bundle/README.md @@ -0,0 +1,37 @@ +# Please run the support bundle with the valid API-TOKEN + Replace for your current namespace. + +export API_TOKEN="xxxxx-xxxxx-xxxx-xxxxx" + +./get_support_bundle.sh -a $API_TOKEN -n sysdigcloud + + +# Workaround for uses cases where the access to the API endpoint is limited/restricted. + +Please, before to execute the script,  run these two command to confirm that your port-forwarding and API_TOKEN are working as expected. + +1 - Enable Port-forwarding for svc/sysdigcloud-api + +kubectl port-forward service/sysdigcloud-api -n sysdigcloud 8080 + +2 - (From another linux terminal) call the API license using your Secure API_TOKEN. + +curl -s -k 'http://127.0.0.1:8080/api/license' \ +-H 'Authorization: Bearer xxxxxx-xxxxx-xxxxx-xxxxxx' -H 'Content-Type: application/json' + +If this is working , you should get an output like this : + +{"license":{"version":1,"customer":"xxxx-xxxx-sysdig","maxAgents":5000,"maxTeams":-1,"secureEnabled":true,"trackingCustomerId":"xxxx0000nAxxx","plan":null,"expirationDate":1726876800000,"expirationDateDefined":true}} + +If you got a error like this below, could mean that the Secure api token is not recognized for some reason like a typo or wrong token, and the script will fail. + +{"timestamp":1713168791762,"status":401,"error":"Unauthorized","message":"Bad credentials","path":"/api/license"} + + +3 - Run the script attached (be sure that the port-forwarded is running in a separated terminal) + +Example: +(-d will execute with debug, -s 168h will collect logs from last 7 days) + +bash -x ./get_support_bundle_local_api.sh -n sysdigcloud -a "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx" -d -s 168h + diff --git a/support_bundle/get_support_bundle.sh b/support_bundle/get_support_bundle.sh index 6d76a2a1..36ea3519 100755 --- a/support_bundle/get_support_bundle.sh +++ b/support_bundle/get_support_bundle.sh @@ -150,8 +150,9 @@ main() { if [[ ! -z ${API_KEY} ]]; then BACKEND_VERSION=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get deployment sysdigcloud-api -ojsonpath='{.spec.template.spec.containers[0].image}' | awk 'match($0, /[0-9]\.[0-9]\.[0-9](\.[0-9]+)?/) {print substr($0, RSTART, RLENGTH)}') || true echo ${BACKEND_VERSION} > ${LOG_DIR}/backend_version.txt - if [[ "$BACKEND_VERSION" =~ ^(6) ]]; then - API_URL=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get cm sysdigcloud-collector-config -ojsonpath='{.data.collector-config\.conf}' | awk 'p&&$0~/"/{gsub("\"","");print} /{/{p=0} /sso/{p=1}' | grep serverName | awk '{print $3}') + if [[ "$BACKEND_VERSION" =~ ^(7|6)$ ]]; then + #API_URL=$(kubectl ${KUBE_OPTS} get cm sysdigcloud-collector-config -ojsonpath='{.data.collector-config\.conf}' | awk 'p&&$0~/"/{gsub("\"","");print} /{/{p=0} /sso/{p=1}' | grep serverName | awk '{print $3}') + API_URL=$(kubectl ${KUBE_OPTS} get cm sysdigcloud-collector-config '-ojsonpath={.data.collector-config\.conf}' | grep serverName | head -1 | awk '{print $3}' | sed 's/"//g') # Check that the API_KEY for the Super User is valid and exit CURL_OUT=$(curl -fks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/license" >/dev/null 2>&1) && RETVAL=$? && error=0 || { RETVAL=$? && error=1; } if [[ ${error} -eq 1 ]]; then @@ -190,8 +191,8 @@ main() { # If Secure API key is supplied, collect settings if [[ ! -z ${SECURE_API_KEY} ]]; then BACKEND_VERSION=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get deployment sysdigcloud-api -ojsonpath='{.spec.template.spec.containers[0].image}' | awk 'match($0, /[0-9]\.[0-9]\.[0-9](\.[0-9]+)?/) {print substr($0, RSTART, RLENGTH)}') || true - if [[ "$BACKEND_VERSION" =~ ^(6) ]]; then - API_URL=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get cm sysdigcloud-collector-config -ojsonpath='{.data.collector-config\.conf}' | awk 'p&&$0~/"/{gsub("\"","");print} /{/{p=0} /sso/{p=1}' | grep serverName | awk '{print $3}') + if [[ "$BACKEND_VERSION" =~ ^(7|6)$ ]]; then + API_URL=$(kubectl ${KUBE_OPTS} get cm sysdigcloud-collector-config '-ojsonpath={.data.collector-config\.conf}' | grep serverName | head -1 | awk '{print $3}' | sed 's/"//g') # Check that the SECURE_API_KEY for the Super User is valid and exit CURL_OUT=$(curl -fks -H "Authorization: Bearer ${SECURE_API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/license" >/dev/null 2>&1) && RETVAL=$? && error=0 || { RETVAL=$? && error=1; } if [[ ${error} -eq 1 ]]; then diff --git a/support_bundle/get_support_bundle_local_api.sh b/support_bundle/get_support_bundle_local_api.sh new file mode 100755 index 00000000..36ab0be3 --- /dev/null +++ b/support_bundle/get_support_bundle_local_api.sh @@ -0,0 +1,497 @@ +#!/bin/bash +set -euo pipefail + +trap 'catch' ERR +catch() { + echo "An error has occurred. Please check your input and try again. Run this script with the -d flag for debugging" +} + +#generate sysdigcloud support bundle on kubernetes + +LABELS="" +CONTEXT="" +CONTEXT_OPTS="" +NAMESPACE="sysdig" +LOG_DIR=$(mktemp -d sysdigcloud-support-bundle-XXXX) +SINCE_OPTS="" +SINCE="" +API_KEY="" +SECURE_API_KEY="" +SKIP_LOGS="false" +ELASTIC_CURL="" + + +print_help() { + printf 'Usage: %s [-a|--api-key ] [c|--context ] [-d|--debug] [-l|--labels ] [-n|--namespace ] [-s|--since ] [--skip-logs] [-h|--help]\n' "$0" + printf "\t%s\n" "-a,--api-key: Provide the Superuser API key for advanced data collection" + printf "\t%s\n" "-c,--context: Specify the kubectl context. If not set, the current context will be used." + printf "\t%s\n" "-d,--debug: Enables Debug" + printf "\t%s\n" "-l,--labels: Specify Sysdig pod role label to collect (e.g. api,collector,worker)" + printf "\t%s\n" "-n,--namespace: Specify the Sysdig namespace. (default: ${NAMESPACE})" + printf "\t%s\n" "-s,--since: Specify the timeframe of logs to collect (e.g. -s 1h)" + printf "\t%s\n" "-sa,--secure-api-key: Provide the Secure Superuser API key for advanced data collection" + printf "\t%s\n" "--skip-logs: Skip all log collection. (default: ${SKIP_LOGS})" + printf "\t%s\n" "-h,--help: Prints help" +} + +parse_commandline() { + while test $# -gt 0 + do + _key="$1" + case "$_key" in + -a|--api-key) + test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 + API_KEY="$2" + shift + ;; + -c|--context) + test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 + CONTEXT="$2" + shift + ;; + -d|--debug) + set -x + ;; + -d*) + set -x + ;; + -l|--labels) + test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 + LABELS="$2" + shift + ;; + -n|--namespace) + test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 + NAMESPACE="$2" + shift + ;; + -s|--since) + test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 + SINCE="$2" + shift + ;; + --skip-logs) + SKIP_LOGS="true" + ;; + -h|--help) + print_help + exit 0 + ;; + -h*) + print_help + exit 0 + ;; + -sa|--secure-api-key) + test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 + SECURE_API_KEY="$2" + shift + ;; + esac + shift + done +} + +get_agent_version_metric_limits() { +# function used to get metric JSON data for Agent versions and metric counts for each agent. +# This is taken from the Sysdig Agent and Health Status Dashboard +# arguments: + PARAMS=( + -sk --location --request POST "${API_URL}/api/data/batch?metricCompatibilityValidation=true&emptyValuesAsNull=true" + --header 'X-Sysdig-Product: SDC' + --header "Authorization: Bearer ${API_KEY}" + --header 'Content-Type: application/json' + -d "{\"requests\":[{\"format\":{\"type\":\"data\"},\"time\":{\"from\":${FROM_EPOCH_TIME}000000,\"to\":${TO_EPOCH_TIME}000000,\"sampling\":600000000},\"metrics\":{\"v0\":\"agent.version\",\"v1\":\"agent.mode\",\"v2\":\"metricCount.statsd\",\"v3\":\"metricCount.prometheus\",\"v4\":\"metricCount.appCheck\",\"v5\":\"metricCount.jmx\",\"k1\":\"host.hostName\",\"k2\":\"host.mac\"},\"group\":{\"aggregations\":{\"v0\":\"concat\",\"v1\":\"concat\",\"v2\":\"max\",\"v3\":\"max\",\"v4\":\"avg\",\"v5\":\"avg\"},\"groupAggregations\":{\"v0\":\"concat\",\"v1\":\"concat\",\"v2\":\"sum\",\"v3\":\"sum\",\"v4\":\"avg\",\"v5\":\"avg\"},\"by\":[{\"metric\":\"k1\"},{\"metric\":\"k2\"}],\"configuration\":{\"groups\":[{\"groupBy\":[]}]}},\"paging\":{\"from\":0,\"to\":9999},\"sort\":[{\"v0\":\"desc\"},{\"v1\":\"desc\"},{\"v2\":\"desc\"},{\"v3\":\"desc\"},{\"v4\":\"desc\"},{\"v5\":\"desc\"}],\"scope\":null,\"compareTo\":null}]}" + ) + curl "${PARAMS[@]}" >${LOG_DIR}/metrics/agent_version_metric_limits.json || echo "Curl failed collecting agent_version_metric_limits.json data!" && true +} + +get_metrics() { +# function used to get metric JSON data for particular metrics we are interested in from the agent +# arguments: +# 1 - metric_name +# 2 - segment_by +metric="${1}" +segment_by="${2}" + + PARAMS=( + -sk --location --request POST "${API_URL}/api/data/batch?metricCompatibilityValidation=true&emptyValuesAsNull=true" + --header 'X-Sysdig-Product: SDC' + --header "Authorization: Bearer ${API_KEY}" + --header 'Content-Type: application/json' + -d "{\"requests\":[{\"format\":{\"type\":\"data\"},\"time\":{\"from\":${FROM_EPOCH_TIME}000000,\"to\":${TO_EPOCH_TIME}000000,\"sampling\":600000000},\"metrics\":{\"v0\":\"${metric}\",\"k0\":\"timestamp\",\"k1\":\"${segment_by}\"},\"group\":{\"aggregations\":{\"v0\":\"avg\"},\"groupAggregations\":{\"v0\":\"avg\"},\"by\":[{\"metric\":\"k0\",\"value\":600000000},{\"metric\":\"k1\"}],\"configuration\":{\"groups\":[{\"groupBy\":[]}]}},\"paging\":{\"from\":0,\"to\":9999},\"sort\":[{\"v0\":\"desc\"}],\"scope\":null,\"compareTo\":null}]}'" + ) + curl "${PARAMS[@]}" >${LOG_DIR}/metrics/${metric}_${segment_by}.json || echo "Curl failed collecting ${metric}_${segment_by} data!" && true +} + +main() { + local error + local RETVAL + + API_URL="http://127.0.0.1:8080" + + if [[ ! -z ${CONTEXT} ]]; then + CONTEXT_OPTS="--context=${CONTEXT}" + fi + + if [[ ! -z ${SINCE} ]]; then + SINCE_OPTS="--since ${SINCE}" + fi + + # Set options for kubectl commands + KUBE_OPTS="--namespace ${NAMESPACE} ${CONTEXT_OPTS}" + + #verify that the provided namespace exists + KUBE_OUTPUT=$(kubectl ${CONTEXT_OPTS} get namespace ${NAMESPACE} --no-headers >/dev/null 2>&1) && RETVAL=$? && error=0 || { RETVAL=$? && error=1; } + + if [[ ${error} -eq 1 ]]; then + echo "We could not determine the namespace. Please check the spelling and try again. Return Code: ${RETVAL}" + echo "kubectl ${CONTEXT_OPTS} get ns | grep ${NAMESPACE}" + exit 1 + fi + + # If API key is supplied, check the backend version, and send a GET to the relevant endpoints. + if [[ ! -z ${API_KEY} ]]; then + BACKEND_VERSION=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get deployment sysdigcloud-api -ojsonpath='{.spec.template.spec.containers[0].image}' | awk 'match($0, /[0-9]\.[0-9]\.[0-9](\.[0-9]+)?/) {print substr($0, RSTART, RLENGTH)}') || true + if [[ "$BACKEND_VERSION" =~ ^(6) ]]; then + #API_URL=$(kubectl ${KUBE_OPTS} get cm sysdigcloud-collector-config -ojsonpath='{.data.collector-config\.conf}' | awk 'p&&$0~/"/{gsub("\"","");print} /{/{p=0} /sso/{p=1}' | grep serverName | awk '{print $3}') + # Check that the API_KEY for the Super User is valid and exit + CURL_OUT=$(curl -fks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/license" >/dev/null 2>&1) && RETVAL=$? && error=0 || { RETVAL=$? && error=1; } + if [[ ${error} -eq 1 ]]; then + echo "The API_KEY supplied is Unauthorized. Please check and try again. Return Code: ${RETVAL}" + exit 1 + fi + curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/admin/customer/1/meerkatSettings" >> ${LOG_DIR}/meerkat_settings.json + elif [[ "$BACKEND_VERSION" =~ ^(5) ]] || [[ "$BACKEND_VERSION" =~ ^(4) ]] || [[ "$BACKEND_VERSION" =~ ^(3) ]]; then + #API_URL=$(kubectl ${KUBE_OPTS} get cm sysdigcloud-config -o yaml | grep -i api.url: | head -1 | awk '{print $2}') + API_URL="http://127.0.0.1:8080" + # Check that the API_KEY for the Super User is valid and exit + CURL_OUT=$(curl -fks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/license" >/dev/null 2>&1) && RETVAL=$? && error=0 || { RETVAL=$? && error=1; } + if [[ ${error} -eq 1 ]]; then + echo "The API_KEY supplied is Unauthorized. Please check and try again. Return Code: ${RETVAL}" + exit 1 + fi + + curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/admin/customer/1/fastPathSettings" >> ${LOG_DIR}/fastPath_settings.json + curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/admin/customer/1/indexSettings" >> ${LOG_DIR}/index_settings.json + else + echo "We could not determine the backend version. Exiting." + exit 1 + fi + + curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/license" >> ${LOG_DIR}/license.json + curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/agents/connected?checkStatus=true" >> ${LOG_DIR}/agents_connected.json + curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/admin/customer/1/storageSettings" >> ${LOG_DIR}/storage_settings.json + curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/admin/customer/1/streamsnapSettings" >> ${LOG_DIR}/streamSnap_settings.json + curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/admin/customers/1/snapshotSettings" >> ${LOG_DIR}/snapshot_settings.json + curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/admin/customer/1/planSettings" >> ${LOG_DIR}/plan_settings.json + curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/admin/customer/1/dataRetentionSettings" >> ${LOG_DIR}/dataRetention_settings.json + curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/v2/users/light" >> ${LOG_DIR}/users.json + curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/v2/teams/light" >> ${LOG_DIR}/teams.json + curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/admin/auth/settings" >> ${LOG_DIR}/sso_settings.json + curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/alerts" >> ${LOG_DIR}/alerts.json + + # If Secure API key is supplied, collect settings + if [[ ! -z ${SECURE_API_KEY} ]]; then + BACKEND_VERSION=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get deployment sysdigcloud-api -ojsonpath='{.spec.template.spec.containers[0].image}' | awk 'match($0, /[0-9]\.[0-9]\.[0-9](\.[0-9]+)?/) {print substr($0, RSTART, RLENGTH)}') || true + if [[ "$BACKEND_VERSION" =~ ^(6) ]]; then + #API_URL=$(kubectl ${KUBE_OPTS} get cm sysdigcloud-collector-config -ojsonpath='{.data.collector-config\.conf}' | awk 'p&&$0~/"/{gsub("\"","");print} /{/{p=0} /sso/{p=1}' | grep serverName | awk '{print $3}') + # Check that the SECURE_API_KEY for the Super User is valid and exit + CURL_OUT=$(curl -fks -H "Authorization: Bearer ${SECURE_API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/license" >/dev/null 2>&1) && RETVAL=$? && error=0 || { RETVAL=$? && error=1; } + if [[ ${error} -eq 1 ]]; then + echo "The SECURE_API_KEY supplied is Unauthorized. Please check and try again. Return Code: ${RETVAL}" + exit 1 + fi + elif [[ "$BACKEND_VERSION" =~ ^(5) ]] || [[ "$BACKEND_VERSION" =~ ^(4) ]] || [[ "$BACKEND_VERSION" =~ ^(3) ]]; then + #API_URL=$(kubectl ${KUBE_OPTS} get cm sysdigcloud-config -o yaml | grep -i api.url: | head -1 | awk '{print $2}') + # Check that the API_KEY for the Super User is valid and exit + CURL_OUT=$(curl -fks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/license" >/dev/null 2>&1) && RETVAL=$? && error=0 || { RETVAL=$? && error=1; } + if [[ ${error} -eq 1 ]]; then + echo "The API_KEY supplied is Unauthorized. Please check and try again. Return Code: ${RETVAL}" + exit 1 + fi + else + echo "We cannot determine the backend version. Exiting." + exit 1 + fi + + # Check if ScanningV1 is enabled, and if so, do ... + SCANNING_V1_ENABLED=$(curl -ks ${API_URL}/api/secure/customerSettings -H "Authorization: Bearer ${SECURE_API_KEY}" 2>&1 | grep -Eo "\"scanningV1Enabled\":true") || true + if [[ ${SCANNING_V1_ENABLED} == "\"scanningV1Enabled\":true" ]]; then + echo "Scanning v1 is enabled. Continuing..." + # CURL COMMANDS GO HERE + mkdir -p ${LOG_DIR}/scanning + curl -ks ${API_URL}/api/scanning/v1/resultsDirect?limit=1 -H "Authorization: Bearer ${SECURE_API_KEY}" >> ${LOG_DIR}/scanning/scanningv1.txt + else + echo "Scanning V1 not detected. Continuing..." + fi + + # Check if ScanningV2 is enabled, and if so, do ... + SCANNING_V2_ENABLED=$(curl -ks ${API_URL}/api/secure/customerSettings -H "Authorization: Bearer ${SECURE_API_KEY}" 2>&1 | grep -Eo "\"scanningV2Enabled\":true") || true + if [[ ${SCANNING_V2_ENABLED} == "\"scanningV2Enabled\":true" ]]; then + echo "Scanning v2 is enabled. Continuing..." + curl -ks ${API_URL}/api/scanning/scanresults/v2/results -H "Authorization: Bearer ${SECURE_API_KEY}" >> ${LOG_DIR}/scanning/scanningv2.txt + # CURL COMMANDS GO HERE + else + echo "Scanning V2 not detected. Continuing..." + fi + fi + + if [[ $OSTYPE == 'darwin'* ]]; then + TO_EPOCH_TIME=$(date -jf "%H:%M:%S" $(date +%H):00:00 +%s) + else + TO_EPOCH_TIME=$(date -d "$(date +%H):00:00" +%s) + fi + FROM_EPOCH_TIME=$((TO_EPOCH_TIME-86400)) + METRICS=("syscall.count" "dragent.analyzer.sr" "container.count" "dragent.analyzer.n_drops_buffer" "dragent.analyzer.n_evts") + DEFAULT_SEGMENT="host.hostName" + SYSCALL_SEGMENTS=("host.hostName" "proc.name") + + mkdir -p ${LOG_DIR}/metrics + for metric in ${METRICS[@]}; do + if [ "${metric}" == "syscall.count" ]; then + for segment in ${SYSCALL_SEGMENTS[@]}; do + get_metrics "${metric}" "${segment}" + done + else + get_metrics "${metric}" "${DEFAULT_SEGMENT}" + fi + done + + get_agent_version_metric_limits + fi + + # Configure kubectl command if labels are set + if [[ -z ${LABELS} ]]; then + SYSDIGCLOUD_PODS=$(kubectl ${KUBE_OPTS} get pods --no-headers -o custom-columns=NAME:metadata.name) + else + SYSDIGCLOUD_PODS=$(kubectl ${KUBE_OPTS} -l "role in (${LABELS})" get pods --no-headers -o custom-columns=NAME:metadata.name) + fi + + echo "Using namespace ${NAMESPACE}" + echo "Using context ${CONTEXT}" + + # Collect kubectl cluster dump + CLUSTER_DUMP_DIR="${LOG_DIR}/kubectl-cluster-dump" + mkdir -p ${CLUSTER_DUMP_DIR} + kubectl ${KUBE_OPTS} cluster-info dump --output-directory=${CLUSTER_DUMP_DIR} + + # Collect container logs for each pod + if [[ "${SKIP_LOGS}" == "false" ]]; then + echo "Gathering Logs from ${NAMESPACE} pods" + command='tar czf - /logs/ /opt/draios/ /var/log/sysdigcloud/ /var/log/cassandra/ /tmp/redis.log /var/log/redis-server/redis.log /var/log/mysql/error.log /opt/prod.conf 2>/dev/null || true' + for pod in ${SYSDIGCLOUD_PODS}; do + echo "Getting support logs for ${pod}" + mkdir -p ${LOG_DIR}/${pod} + containers=$(kubectl ${KUBE_OPTS} get pod ${pod} -o json | jq -r '.spec.containers[].name' || echo "") + for container in ${containers}; do + kubectl ${KUBE_OPTS} logs ${pod} -c ${container} ${SINCE_OPTS} > ${LOG_DIR}/${pod}/${container}-kubectl-logs.txt || true + echo "Execing into ${container}" + kubectl ${KUBE_OPTS} exec ${pod} -c ${container} -- bash -c "echo" >/dev/null 2>&1 && RETVAL=$? || RETVAL=$? && true + kubectl ${KUBE_OPTS} exec ${pod} -c ${container} -- sh -c "echo" >/dev/null 2>&1 && RETVAL1=$? || RETVAL1=$? && true + if [ $RETVAL -eq 0 ]; then + kubectl ${KUBE_OPTS} exec ${pod} -c ${container} -- bash -c "${command}" > ${LOG_DIR}/${pod}/${container}-support-files.tgz || true + elif [ $RETVAL1 -eq 0 ]; then + kubectl ${KUBE_OPTS} exec ${pod} -c ${container} -- sh -c "${command}" > ${LOG_DIR}/${pod}/${container}-support-files.tgz || true + else + echo "Skipping log gathering for ${pod}" + fi + done + done + fi + + echo "Gathering pod descriptions" + for pod in ${SYSDIGCLOUD_PODS}; do + echo "Getting pod description for ${pod}" + mkdir -p ${LOG_DIR}/${pod} + kubectl ${KUBE_OPTS} get pod ${pod} -o json > ${LOG_DIR}/${pod}/kubectl-describe.json || true + done + + #Collect Describe Node Output + echo "Collecting node information" + kubectl ${KUBE_OPTS} describe nodes | tee -a ${LOG_DIR}/describe_node_output.log || echo "No permission to describe nodes!" + + NODES=$(kubectl ${KUBE_OPTS} get nodes --no-headers -o custom-columns=NAME:metadata.name) && RETVAL=0 || { RETVAL=$? && echo "No permission to get nodes!"; } + if [[ "${RETVAL}" == "0" ]]; then + mkdir -p ${LOG_DIR}/nodes + for node in ${NODES[@]}; do + kubectl ${KUBE_OPTS} get node ${node} -ojson > ${LOG_DIR}/nodes/${node}-kubectl.json + done + unset RETVAL + fi + + #Collect PV info + kubectl ${KUBE_OPTS} get pv | grep sysdig | tee -a ${LOG_DIR}/pv_output.log || echo "No permission to get PersistentVolumes" + kubectl ${KUBE_OPTS} get pvc | grep sysdig | tee -a ${LOG_DIR}/pvc_output.log + kubectl ${KUBE_OPTS} get storageclass | tee -a ${LOG_DIR}/sc_output.log || echo "No permission to get StorageClasses" + + # Get info on deployments, statefulsets, persistentVolumeClaims, daemonsets, and ingresses + echo "Gathering Manifest Information" + for object in svc deployment sts pvc daemonset ingress replicaset networkpolicy cronjob configmap; do + items=$(kubectl ${KUBE_OPTS} get ${object} -o jsonpath="{.items[*]['metadata.name']}") + mkdir -p ${LOG_DIR}/${object} + for item in ${items}; do + kubectl ${KUBE_OPTS} get ${object} ${item} -o json > ${LOG_DIR}/${object}/${item}-kubectl.json + done + done + + # Fetch container density information + num_nodes=0 + num_pods=0 + num_running_containers=0 + num_total_containers=0 + + printf "%-30s %-10s %-10s %-10s %-10s\n" "Node" "Pods" "Running Containers" "Total Containers" >> ${LOG_DIR}/container_density.txt + for node in $(kubectl ${KUBE_OPTS} get nodes --no-headers -o custom-columns=node:.metadata.name); do + total_pods=$(kubectl ${KUBE_OPTS} get pods -A --no-headers -o wide | grep ${node} |wc -l |xargs) + running_containers=$( kubectl ${KUBE_OPTS} get pods -A --no-headers -o wide |grep ${node} |awk '{print $3}' |cut -f 1 -d/ | awk '{ SUM += $1} END { print SUM }' |xargs) + total_containers=$( kubectl get ${KUBE_OPTS} pods -A --no-headers -o wide |grep ${node} |awk '{print $3}' |cut -f 2 -d/ | awk '{ SUM += $1} END { print SUM }' |xargs) + printf "%-30s %-15s %-20s %-10s\n" "${node}" "${total_pods}" "${running_containers}" "${total_containers}" >> ${LOG_DIR}/container_density.txt + num_nodes=$((num_nodes+1)) + num_pods=$((num_pods+${total_pods})) + num_running_containers=$((num_running_containers+${running_containers})) + num_total_containers=$((num_total_containers+${total_containers})) + done + + printf "\nTotals\n-----\n" >> ${LOG_DIR}/container_density.txt + printf "Nodes: ${num_nodes}\n" >> ${LOG_DIR}/container_density.txt + printf "Pods: ${num_pods}\n" >> ${LOG_DIR}/container_density.txt + printf "Running Containers: ${num_running_containers}\n" >> ${LOG_DIR}/container_density.txt + printf "Containers: ${num_total_containers}\n" >> ${LOG_DIR}/container_density.txt + + # Fetch Cassandra Nodetool output + echo "Fetching Cassandra statistics" + for pod in $(kubectl ${KUBE_OPTS} get pod -l role=cassandra --no-headers -o custom-columns=NAME:metadata.name) + do + mkdir -p ${LOG_DIR}/cassandra/${pod} + kubectl ${KUBE_OPTS} exec -it ${pod} -c cassandra -- nodetool info | tee -a ${LOG_DIR}/cassandra/${pod}/nodetool_info.log + kubectl ${KUBE_OPTS} exec -it ${pod} -c cassandra -- nodetool status | tee -a ${LOG_DIR}/cassandra/${pod}/nodetool_status.log + kubectl ${KUBE_OPTS} exec -it ${pod} -c cassandra -- nodetool getcompactionthroughput | tee -a ${LOG_DIR}/cassandra/${pod}/nodetool_getcompactionthroughput.log + kubectl ${KUBE_OPTS} exec -it ${pod} -c cassandra -- nodetool cfstats | tee -a ${LOG_DIR}/cassandra/${pod}/nodetool_cfstats.log + kubectl ${KUBE_OPTS} exec -it ${pod} -c cassandra -- nodetool cfhistograms draios message_data10 | tee -a ${LOG_DIR}/cassandra/${pod}/nodetool_cfhistograms.log + kubectl ${KUBE_OPTS} exec -it ${pod} -c cassandra -- nodetool proxyhistograms | tee -a ${LOG_DIR}/cassandra/${pod}/nodetool_proxyhistograms.log + kubectl ${KUBE_OPTS} exec -it ${pod} -c cassandra -- nodetool tpstats | tee -a ${LOG_DIR}/cassandra/${pod}/nodetool_tpstats.log + kubectl ${KUBE_OPTS} exec -it ${pod} -c cassandra -- nodetool compactionstats | tee -a ${LOG_DIR}/cassandra/${pod}/nodetool_compactionstats.log + done + + echo "Fetching Elasticsearch health info" + # CHECK HERE IF THE TLS ENV VARIABLE IS SET IN ELASTICSEARCH, AND BUILD THE CURL COMMAND OUT + ELASTIC_POD=$(kubectl ${KUBE_OPTS} get pods -l role=elasticsearch --no-headers -o custom-columns=NAME:metadata.name | head -1) || true + + if [ ! -z ${ELASTIC_POD} ]; then + ELASTIC_IMAGE=$(kubectl ${KUBE_OPTS} get pod ${ELASTIC_POD} -ojsonpath='{.spec.containers[?(@.name == "elasticsearch")].image}' | awk -F '/' '{print $NF}' | cut -f 1 -d ':') || true + + if [[ ${ELASTIC_IMAGE} == "opensearch"* ]]; then + CERTIFICATE_DIRECTORY="/usr/share/opensearch/config" + ELASTIC_TLS="true" + else + CERTIFICATE_DIRECTORY="/usr/share/elasticsearch/config" + ELASTIC_TLS=$(kubectl ${KUBE_OPTS} exec ${ELASTIC_POD} -c elasticsearch -- env | grep -i ELASTICSEARCH_TLS_ENCRYPTION) || true + if [[ ${ELASTIC_TLS} == *"ELASTICSEARCH_TLS_ENCRYPTION=true"* ]]; then + ELASTIC_TLS="true" + fi + fi + + if [[ ${ELASTIC_TLS} == "true" ]]; then + ELASTIC_CURL="curl -s --cacert ${CERTIFICATE_DIRECTORY}/root-ca.pem https://\${ELASTICSEARCH_ADMINUSER}:\${ELASTICSEARCH_ADMIN_PASSWORD}@\$(hostname):9200" + else + ELASTIC_CURL='curl -s -k http://$(hostname):9200' + fi + + for pod in $(kubectl ${KUBE_OPTS} get pods -l role=elasticsearch --no-headers -o custom-columns=NAME:metadata.name) + do + mkdir -p ${LOG_DIR}/elasticsearch/${pod} + + kubectl ${KUBE_OPTS} exec ${pod} -c elasticsearch -- /bin/bash -c "${ELASTIC_CURL}/_cat/health" | tee -a ${LOG_DIR}/elasticsearch/${pod}/elasticsearch_health.log || true + + kubectl ${KUBE_OPTS} exec ${pod} -c elasticsearch -- /bin/bash -c "${ELASTIC_CURL}/_cat/indices" | tee -a ${LOG_DIR}/elasticsearch/${pod}/elasticsearch_indices.log || true + + kubectl ${KUBE_OPTS} exec ${pod} -c elasticsearch -- /bin/bash -c "${ELASTIC_CURL}/_cat/nodes?v" | tee -a ${LOG_DIR}/elasticsearch/${pod}/elasticsearch_nodes.log || true + + kubectl ${KUBE_OPTS} exec ${pod} -c elasticsearch -- /bin/bash -c "${ELASTIC_CURL}/_cluster/allocation/explain?pretty" | tee -a ${LOG_DIR}/elasticsearch/${pod}/elasticsearch_index_allocation.log || true + + echo "Fetching ElasticSearch SSL Certificate Expiration Dates" + kubectl ${KUBE_OPTS} exec ${pod} -c elasticsearch -- openssl x509 -in ${CERTIFICATE_DIRECTORY}/node.pem -noout -enddate | tee -a ${LOG_DIR}/elasticsearch/${pod}/elasticsearch_node_pem_expiration.log || true + kubectl ${KUBE_OPTS} exec ${pod} -c elasticsearch -- openssl x509 -in ${CERTIFICATE_DIRECTORY}/admin.pem -noout -enddate | tee -a ${LOG_DIR}/elasticsearch/${pod}/elasticsearch_admin_pem_expiration.log || true + kubectl ${KUBE_OPTS} exec ${pod} -c elasticsearch -- openssl x509 -in ${CERTIFICATE_DIRECTORY}/root-ca.pem -noout -enddate | tee -a ${LOG_DIR}/elasticsearch/${pod}/elasticsearch_root_ca_pem_expiration.log || true + + + echo "Fetching Elasticsearch Index Versions" + kubectl ${KUBE_OPTS} exec ${pod} -c elasticsearch -- bash -c "${ELASTIC_CURL}/_all/_settings/index.version\*?pretty" | tee -a ${LOG_DIR}/elasticsearch/${pod}/elasticsearch_index_versions.log || true + + echo "Checking Used Elasticsearch Storage - ${pod}" + mountpath=$(kubectl ${KUBE_OPTS} get sts sysdigcloud-elasticsearch -ojsonpath='{.spec.template.spec.containers[].volumeMounts[?(@.name == "data")].mountPath}') + if [ ! -z $mountpath ]; then + kubectl ${KUBE_OPTS} exec ${pod} -c elasticsearch -- du -ch ${mountpath} | grep -i total | awk '{printf "%-13s %10s\n",$1,$2}' | tee -a ${LOG_DIR}/elasticsearch/${pod}/elasticsearch_storage.log || true + else + printf "Error getting ElasticSearch ${pod} mount path\n" | tee -a ${LOG_DIR}/elasticsearch/${pod}/elasticsearch_storage.log + fi + done + else + echo "Unable to fetch ElasticSearch pod to gather health info!" + fi + + # Fetch Cassandra storage info + for pod in $(kubectl ${KUBE_OPTS} get pods -l role=cassandra --no-headers -o custom-columns=NAME:metadata.name) + do + echo "Checking Used Cassandra Storage - ${pod}" + mkdir -p ${LOG_DIR}/cassandra/${pod} + printf "${pod}\n" | tee -a ${LOG_DIR}/cassandra/${pod}/cassandra_storage.log + mountpath=$(kubectl ${KUBE_OPTS} get sts sysdigcloud-cassandra -ojsonpath='{.spec.template.spec.containers[].volumeMounts[?(@.name == "data")].mountPath}') + if [ ! -z $mountpath ]; then + kubectl ${KUBE_OPTS} exec -it ${pod} -c cassandra -- du -ch ${mountpath} | grep -i total | awk '{printf "%-13s %10s\n",$1,$2}' | tee -a ${LOG_DIR}/cassandra/${pod}/cassandra_storage.log || true + else + printf "Error getting Cassandra ${pod} mount path\n" | tee -a ${LOG_DIR}/cassandra/${pod}/cassandra_storage.log + fi + done + + # Fetch postgresql storage info + for pod in $(kubectl ${KUBE_OPTS} get pods -l role=postgresql --no-headers -o custom-columns=NAME:metadata.name) + do + echo "Checking Used PostgreSQL Storage - ${pod}" + mkdir -p ${LOG_DIR}/postgresql/${pod} + printf "${pod}\n" | tee -a ${LOG_DIR}/postgresql/${pod}/postgresql_storage.log + kubectl ${KUBE_OPTS} exec -it ${pod} -c postgresql -- du -ch /var/lib/postgresql | grep -i total | awk '{printf "%-13s %10s\n",$1,$2}' | tee -a ${LOG_DIR}/postgresql/${pod}/postgresql_storage.log || true + done + + # Fetch mysql storage info + for pod in $(kubectl ${KUBE_OPTS} get pods -l role=mysql --no-headers -o custom-columns=NAME:metadata.name) + do + echo "Checking Used MySQL Storage - ${pod}" + mkdir -p ${LOG_DIR}/mysql/${pod} + printf "${pod}\n" | tee -a ${LOG_DIR}/mysql/${pod}/mysql_storage.log + kubectl ${KUBE_OPTS} exec -it ${pod} -c mysql -- du -ch /var/lib/mysql | grep -i total | awk '{printf "%-13s %10s\n",$1,$2}' | tee -a ${LOG_DIR}/mysql/${pod}/mysql_storage.log || true + done + + # Fetch kafka storage info + for pod in $(kubectl ${KUBE_OPTS} get pods -l role=cp-kafka --no-headers -o custom-columns=NAME:metadata.name) + do + echo "Checking Used Kafka Storage - ${pod}" + mkdir -p ${LOG_DIR}/kafka/${pod} + printf "${pod}\n" | tee -a ${LOG_DIR}/kafka/${pod}/kafka_storage.log + kubectl ${KUBE_OPTS} exec -it ${pod} -c broker -- du -ch /opt/kafka/data | grep -i total | awk '{printf "%-13s %10s\n",$1,$2}' | tee -a ${LOG_DIR}/kafka/${pod}/kafka_storage.log || true + done + + # Fetch zookeeper storage info + for pod in $(kubectl ${KUBE_OPTS} get pods -l role=zookeeper --no-headers -o custom-columns=NAME:metadata.name) + do + echo "Checking Used Zookeeper Storage - ${pod}" + mkdir -p ${LOG_DIR}/zookeeper/${pod} + printf "${pod}\n" | tee -a ${LOG_DIR}/zookeeper/${pod}/zookeeper_storage.log + kubectl ${KUBE_OPTS} exec -it ${pod} -c server -- du -ch /var/lib/zookeeper/data | grep -i total | awk '{printf "%-13s %10s\n",$1,$2}' | tee -a ${LOG_DIR}/zookeeper/${pod}/zookeeper_storage.log || true + done + + # Collect the sysdigcloud-config configmap, and write to the log directory + echo "Fetching the sysdigcloud-config ConfigMap" + kubectl ${KUBE_OPTS} get configmap sysdigcloud-config -o yaml | grep -v password | grep -v apiVersion > ${LOG_DIR}/config.yaml || true + + # Generate the bundle name, create a tarball, and remove the temp log directory + BUNDLE_NAME=$(date +%s)_sysdig_cloud_support_bundle.tgz + echo "Creating the ${BUNDLE_NAME} archive now" + tar czf ${BUNDLE_NAME} ${LOG_DIR} + rm -rf ${LOG_DIR} + + echo "Support bundle generated:" ${BUNDLE_NAME} +} + +parse_commandline "$@" +main From cc4672d2ec93c526c7bf3343c34b3be665e42b2b Mon Sep 17 00:00:00 2001 From: Daniele De Lorenzi Date: Thu, 9 May 2024 12:15:30 +0200 Subject: [PATCH 02/10] Added '-la' flag instead of an additional script and fix a bug in a regex Signed-off-by: Daniele De Lorenzi --- support_bundle/README.md | 39 +- support_bundle/get_support_bundle.sh | 57 +- .../get_support_bundle_local_api.sh | 497 ------------------ 3 files changed, 55 insertions(+), 538 deletions(-) delete mode 100755 support_bundle/get_support_bundle_local_api.sh diff --git a/support_bundle/README.md b/support_bundle/README.md index 42d1f4a5..55a9e475 100644 --- a/support_bundle/README.md +++ b/support_bundle/README.md @@ -1,37 +1,12 @@ -# Please run the support bundle with the valid API-TOKEN - Replace for your current namespace. +# On-Premise Support Bundle script +## Usage example +Specify your current namespace with `-n` flag. + +``` export API_TOKEN="xxxxx-xxxxx-xxxx-xxxxx" ./get_support_bundle.sh -a $API_TOKEN -n sysdigcloud +``` - -# Workaround for uses cases where the access to the API endpoint is limited/restricted. - -Please, before to execute the script,  run these two command to confirm that your port-forwarding and API_TOKEN are working as expected. - -1 - Enable Port-forwarding for svc/sysdigcloud-api - -kubectl port-forward service/sysdigcloud-api -n sysdigcloud 8080 - -2 - (From another linux terminal) call the API license using your Secure API_TOKEN. - -curl -s -k 'http://127.0.0.1:8080/api/license' \ --H 'Authorization: Bearer xxxxxx-xxxxx-xxxxx-xxxxxx' -H 'Content-Type: application/json' - -If this is working , you should get an output like this : - -{"license":{"version":1,"customer":"xxxx-xxxx-sysdig","maxAgents":5000,"maxTeams":-1,"secureEnabled":true,"trackingCustomerId":"xxxx0000nAxxx","plan":null,"expirationDate":1726876800000,"expirationDateDefined":true}} - -If you got a error like this below, could mean that the Secure api token is not recognized for some reason like a typo or wrong token, and the script will fail. - -{"timestamp":1713168791762,"status":401,"error":"Unauthorized","message":"Bad credentials","path":"/api/license"} - - -3 - Run the script attached (be sure that the port-forwarded is running in a separated terminal) - -Example: -(-d will execute with debug, -s 168h will collect logs from last 7 days) - -bash -x ./get_support_bundle_local_api.sh -n sysdigcloud -a "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx" -d -s 168h - +*NOTE:* For cases where the access to the API endpoint is limited/restricted use `-la` or `--local-api` flag. diff --git a/support_bundle/get_support_bundle.sh b/support_bundle/get_support_bundle.sh index 36ea3519..936db64b 100755 --- a/support_bundle/get_support_bundle.sh +++ b/support_bundle/get_support_bundle.sh @@ -26,6 +26,7 @@ print_help() { printf "\t%s\n" "-c,--context: Specify the kubectl context. If not set, the current context will be used." printf "\t%s\n" "-d,--debug: Enables Debug" printf "\t%s\n" "-l,--labels: Specify Sysdig pod role label to collect (e.g. api,collector,worker)" + printf "\t%s\n" "-la,--local-api: Uses kubectl port-forward feature for being able to access APIs for advanced data collection (for env that cannot reach APIs via domain/FQDN)" printf "\t%s\n" "-n,--namespace: Specify the Sysdig namespace. (default: ${NAMESPACE})" printf "\t%s\n" "-s,--since: Specify the timeframe of logs to collect (e.g. -s 1h)" printf "\t%s\n" "-sa,--secure-api-key: Provide the Secure Superuser API key for advanced data collection" @@ -59,6 +60,9 @@ parse_commandline() { LABELS="$2" shift ;; + -la|--local-api) + API_LOCAL="true" + ;; -n|--namespace) test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 NAMESPACE="$2" @@ -148,11 +152,19 @@ main() { # If API key is supplied, check the backend version, and send a GET to the relevant endpoints. if [[ ! -z ${API_KEY} ]]; then - BACKEND_VERSION=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get deployment sysdigcloud-api -ojsonpath='{.spec.template.spec.containers[0].image}' | awk 'match($0, /[0-9]\.[0-9]\.[0-9](\.[0-9]+)?/) {print substr($0, RSTART, RLENGTH)}') || true + BACKEND_VERSION=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get deployment sysdigcloud-api -ojsonpath='{.spec.template.spec.containers[0].image}' | awk 'match($0, /[0-9]\.[0-9]+\.[0-9](\.[0-9]+)?/) {print substr($0, RSTART, RLENGTH)}') || true echo ${BACKEND_VERSION} > ${LOG_DIR}/backend_version.txt if [[ "$BACKEND_VERSION" =~ ^(7|6)$ ]]; then - #API_URL=$(kubectl ${KUBE_OPTS} get cm sysdigcloud-collector-config -ojsonpath='{.data.collector-config\.conf}' | awk 'p&&$0~/"/{gsub("\"","");print} /{/{p=0} /sso/{p=1}' | grep serverName | awk '{print $3}') - API_URL=$(kubectl ${KUBE_OPTS} get cm sysdigcloud-collector-config '-ojsonpath={.data.collector-config\.conf}' | grep serverName | head -1 | awk '{print $3}' | sed 's/"//g') + if [[ "$API_LOCAL" == "true" ]]; then + kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} port-forward service/sysdigcloud-api 8080 > /dev/null 2>&1 & + # wait for port-forward to become available + while ! curl -s localhost:8080 > /dev/null 2>&1 ; do + sleep 0.2 + done + API_URL="http://127.0.0.1:8080" + else + API_URL=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get cm sysdigcloud-collector-config '-ojsonpath={.data.collector-config\.conf}' | grep serverName | head -1 | awk '{print $3}' | sed 's/"//g') + fi # Check that the API_KEY for the Super User is valid and exit CURL_OUT=$(curl -fks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/license" >/dev/null 2>&1) && RETVAL=$? && error=0 || { RETVAL=$? && error=1; } if [[ ${error} -eq 1 ]]; then @@ -161,7 +173,16 @@ main() { fi curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/admin/customer/1/meerkatSettings" >> ${LOG_DIR}/meerkat_settings.json elif [[ "$BACKEND_VERSION" =~ ^(5) ]] || [[ "$BACKEND_VERSION" =~ ^(4) ]] || [[ "$BACKEND_VERSION" =~ ^(3) ]]; then - API_URL=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get cm sysdigcloud-config -o yaml | grep -i api.url: | head -1 | awk '{print $2}') + if [[ "$API_LOCAL" == "true" ]]; then + kubectl ${KUBE_OPTS} port-forward service/sysdigcloud-api 8080 > /dev/null 2>&1 & + # wait for port-forward to become available + while ! curl -s localhost:8080 > /dev/null 2>&1 ; do + sleep 0.2 + done + API_URL="http://127.0.0.1:8080" + else + API_URL=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get cm sysdigcloud-config -o yaml | grep -i api.url: | head -1 | awk '{print $2}') + fi # Check that the API_KEY for the Super User is valid and exit CURL_OUT=$(curl -fks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/license" >/dev/null 2>&1) && RETVAL=$? && error=0 || { RETVAL=$? && error=1; } if [[ ${error} -eq 1 ]]; then @@ -190,17 +211,35 @@ main() { # If Secure API key is supplied, collect settings if [[ ! -z ${SECURE_API_KEY} ]]; then - BACKEND_VERSION=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get deployment sysdigcloud-api -ojsonpath='{.spec.template.spec.containers[0].image}' | awk 'match($0, /[0-9]\.[0-9]\.[0-9](\.[0-9]+)?/) {print substr($0, RSTART, RLENGTH)}') || true - if [[ "$BACKEND_VERSION" =~ ^(7|6)$ ]]; then - API_URL=$(kubectl ${KUBE_OPTS} get cm sysdigcloud-collector-config '-ojsonpath={.data.collector-config\.conf}' | grep serverName | head -1 | awk '{print $3}' | sed 's/"//g') + BACKEND_VERSION=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get deployment sysdigcloud-api -ojsonpath='{.spec.template.spec.containers[0].image}' | awk 'match($0, /[0-9]\.[0-9]+\.[0-9](\.[0-9]+)?/) {print substr($0, RSTART, RLENGTH)}') || true + if [[ "$BACKEND_VERSION" =~ ^(7|6)$ ]]; then + if [[ "$API_LOCAL" == "true" ]]; then + kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} port-forward service/sysdigcloud-api 8080 > /dev/null 2>&1 & + # wait for port-forward to become available + while ! curl -s localhost:8080 > /dev/null 2>&1 ; do + sleep 0.2 + done + API_URL="http://127.0.0.1:8080" + else + API_URL=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get cm sysdigcloud-collector-config '-ojsonpath={.data.collector-config\.conf}' | grep serverName | head -1 | awk '{print $3}' | sed 's/"//g') + fi # Check that the SECURE_API_KEY for the Super User is valid and exit CURL_OUT=$(curl -fks -H "Authorization: Bearer ${SECURE_API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/license" >/dev/null 2>&1) && RETVAL=$? && error=0 || { RETVAL=$? && error=1; } if [[ ${error} -eq 1 ]]; then echo "The SECURE_API_KEY supplied is Unauthorized. Please check and try again. Return Code: ${RETVAL}" exit 1 fi - elif [[ "$BACKEND_VERSION" =~ ^(5) ]] || [[ "$BACKEND_VERSION" =~ ^(4) ]] || [[ "$BACKEND_VERSION" =~ ^(3) ]]; then - API_URL=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get cm sysdigcloud-config -o yaml | grep -i api.url: | head -1 | awk '{print $2}') + elif [[ "$BACKEND_VERSION" =~ ^(5) ]] || [[ "$BACKEND_VERSION" =~ ^(4) ]] || [[ "$BACKEND_VERSION" =~ ^(3) ]]; then + if [[ "$API_LOCAL" == "true" ]]; then + kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} port-forward service/sysdigcloud-api 8080 > /dev/null 2>&1 & + # wait for port-forward to become available + while ! curl -s localhost:8080 > /dev/null 2>&1 ; do + sleep 0.2 + done + API_URL="http://127.0.0.1:8080" + else + API_URL=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get cm sysdigcloud-config -o yaml | grep -i api.url: | head -1 | awk '{print $2}') + fi # Check that the API_KEY for the Super User is valid and exit CURL_OUT=$(curl -fks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/license" >/dev/null 2>&1) && RETVAL=$? && error=0 || { RETVAL=$? && error=1; } if [[ ${error} -eq 1 ]]; then diff --git a/support_bundle/get_support_bundle_local_api.sh b/support_bundle/get_support_bundle_local_api.sh deleted file mode 100755 index 36ab0be3..00000000 --- a/support_bundle/get_support_bundle_local_api.sh +++ /dev/null @@ -1,497 +0,0 @@ -#!/bin/bash -set -euo pipefail - -trap 'catch' ERR -catch() { - echo "An error has occurred. Please check your input and try again. Run this script with the -d flag for debugging" -} - -#generate sysdigcloud support bundle on kubernetes - -LABELS="" -CONTEXT="" -CONTEXT_OPTS="" -NAMESPACE="sysdig" -LOG_DIR=$(mktemp -d sysdigcloud-support-bundle-XXXX) -SINCE_OPTS="" -SINCE="" -API_KEY="" -SECURE_API_KEY="" -SKIP_LOGS="false" -ELASTIC_CURL="" - - -print_help() { - printf 'Usage: %s [-a|--api-key ] [c|--context ] [-d|--debug] [-l|--labels ] [-n|--namespace ] [-s|--since ] [--skip-logs] [-h|--help]\n' "$0" - printf "\t%s\n" "-a,--api-key: Provide the Superuser API key for advanced data collection" - printf "\t%s\n" "-c,--context: Specify the kubectl context. If not set, the current context will be used." - printf "\t%s\n" "-d,--debug: Enables Debug" - printf "\t%s\n" "-l,--labels: Specify Sysdig pod role label to collect (e.g. api,collector,worker)" - printf "\t%s\n" "-n,--namespace: Specify the Sysdig namespace. (default: ${NAMESPACE})" - printf "\t%s\n" "-s,--since: Specify the timeframe of logs to collect (e.g. -s 1h)" - printf "\t%s\n" "-sa,--secure-api-key: Provide the Secure Superuser API key for advanced data collection" - printf "\t%s\n" "--skip-logs: Skip all log collection. (default: ${SKIP_LOGS})" - printf "\t%s\n" "-h,--help: Prints help" -} - -parse_commandline() { - while test $# -gt 0 - do - _key="$1" - case "$_key" in - -a|--api-key) - test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 - API_KEY="$2" - shift - ;; - -c|--context) - test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 - CONTEXT="$2" - shift - ;; - -d|--debug) - set -x - ;; - -d*) - set -x - ;; - -l|--labels) - test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 - LABELS="$2" - shift - ;; - -n|--namespace) - test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 - NAMESPACE="$2" - shift - ;; - -s|--since) - test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 - SINCE="$2" - shift - ;; - --skip-logs) - SKIP_LOGS="true" - ;; - -h|--help) - print_help - exit 0 - ;; - -h*) - print_help - exit 0 - ;; - -sa|--secure-api-key) - test $# -lt 2 && die "Missing value for the optional argument '$_key'." 1 - SECURE_API_KEY="$2" - shift - ;; - esac - shift - done -} - -get_agent_version_metric_limits() { -# function used to get metric JSON data for Agent versions and metric counts for each agent. -# This is taken from the Sysdig Agent and Health Status Dashboard -# arguments: - PARAMS=( - -sk --location --request POST "${API_URL}/api/data/batch?metricCompatibilityValidation=true&emptyValuesAsNull=true" - --header 'X-Sysdig-Product: SDC' - --header "Authorization: Bearer ${API_KEY}" - --header 'Content-Type: application/json' - -d "{\"requests\":[{\"format\":{\"type\":\"data\"},\"time\":{\"from\":${FROM_EPOCH_TIME}000000,\"to\":${TO_EPOCH_TIME}000000,\"sampling\":600000000},\"metrics\":{\"v0\":\"agent.version\",\"v1\":\"agent.mode\",\"v2\":\"metricCount.statsd\",\"v3\":\"metricCount.prometheus\",\"v4\":\"metricCount.appCheck\",\"v5\":\"metricCount.jmx\",\"k1\":\"host.hostName\",\"k2\":\"host.mac\"},\"group\":{\"aggregations\":{\"v0\":\"concat\",\"v1\":\"concat\",\"v2\":\"max\",\"v3\":\"max\",\"v4\":\"avg\",\"v5\":\"avg\"},\"groupAggregations\":{\"v0\":\"concat\",\"v1\":\"concat\",\"v2\":\"sum\",\"v3\":\"sum\",\"v4\":\"avg\",\"v5\":\"avg\"},\"by\":[{\"metric\":\"k1\"},{\"metric\":\"k2\"}],\"configuration\":{\"groups\":[{\"groupBy\":[]}]}},\"paging\":{\"from\":0,\"to\":9999},\"sort\":[{\"v0\":\"desc\"},{\"v1\":\"desc\"},{\"v2\":\"desc\"},{\"v3\":\"desc\"},{\"v4\":\"desc\"},{\"v5\":\"desc\"}],\"scope\":null,\"compareTo\":null}]}" - ) - curl "${PARAMS[@]}" >${LOG_DIR}/metrics/agent_version_metric_limits.json || echo "Curl failed collecting agent_version_metric_limits.json data!" && true -} - -get_metrics() { -# function used to get metric JSON data for particular metrics we are interested in from the agent -# arguments: -# 1 - metric_name -# 2 - segment_by -metric="${1}" -segment_by="${2}" - - PARAMS=( - -sk --location --request POST "${API_URL}/api/data/batch?metricCompatibilityValidation=true&emptyValuesAsNull=true" - --header 'X-Sysdig-Product: SDC' - --header "Authorization: Bearer ${API_KEY}" - --header 'Content-Type: application/json' - -d "{\"requests\":[{\"format\":{\"type\":\"data\"},\"time\":{\"from\":${FROM_EPOCH_TIME}000000,\"to\":${TO_EPOCH_TIME}000000,\"sampling\":600000000},\"metrics\":{\"v0\":\"${metric}\",\"k0\":\"timestamp\",\"k1\":\"${segment_by}\"},\"group\":{\"aggregations\":{\"v0\":\"avg\"},\"groupAggregations\":{\"v0\":\"avg\"},\"by\":[{\"metric\":\"k0\",\"value\":600000000},{\"metric\":\"k1\"}],\"configuration\":{\"groups\":[{\"groupBy\":[]}]}},\"paging\":{\"from\":0,\"to\":9999},\"sort\":[{\"v0\":\"desc\"}],\"scope\":null,\"compareTo\":null}]}'" - ) - curl "${PARAMS[@]}" >${LOG_DIR}/metrics/${metric}_${segment_by}.json || echo "Curl failed collecting ${metric}_${segment_by} data!" && true -} - -main() { - local error - local RETVAL - - API_URL="http://127.0.0.1:8080" - - if [[ ! -z ${CONTEXT} ]]; then - CONTEXT_OPTS="--context=${CONTEXT}" - fi - - if [[ ! -z ${SINCE} ]]; then - SINCE_OPTS="--since ${SINCE}" - fi - - # Set options for kubectl commands - KUBE_OPTS="--namespace ${NAMESPACE} ${CONTEXT_OPTS}" - - #verify that the provided namespace exists - KUBE_OUTPUT=$(kubectl ${CONTEXT_OPTS} get namespace ${NAMESPACE} --no-headers >/dev/null 2>&1) && RETVAL=$? && error=0 || { RETVAL=$? && error=1; } - - if [[ ${error} -eq 1 ]]; then - echo "We could not determine the namespace. Please check the spelling and try again. Return Code: ${RETVAL}" - echo "kubectl ${CONTEXT_OPTS} get ns | grep ${NAMESPACE}" - exit 1 - fi - - # If API key is supplied, check the backend version, and send a GET to the relevant endpoints. - if [[ ! -z ${API_KEY} ]]; then - BACKEND_VERSION=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get deployment sysdigcloud-api -ojsonpath='{.spec.template.spec.containers[0].image}' | awk 'match($0, /[0-9]\.[0-9]\.[0-9](\.[0-9]+)?/) {print substr($0, RSTART, RLENGTH)}') || true - if [[ "$BACKEND_VERSION" =~ ^(6) ]]; then - #API_URL=$(kubectl ${KUBE_OPTS} get cm sysdigcloud-collector-config -ojsonpath='{.data.collector-config\.conf}' | awk 'p&&$0~/"/{gsub("\"","");print} /{/{p=0} /sso/{p=1}' | grep serverName | awk '{print $3}') - # Check that the API_KEY for the Super User is valid and exit - CURL_OUT=$(curl -fks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/license" >/dev/null 2>&1) && RETVAL=$? && error=0 || { RETVAL=$? && error=1; } - if [[ ${error} -eq 1 ]]; then - echo "The API_KEY supplied is Unauthorized. Please check and try again. Return Code: ${RETVAL}" - exit 1 - fi - curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/admin/customer/1/meerkatSettings" >> ${LOG_DIR}/meerkat_settings.json - elif [[ "$BACKEND_VERSION" =~ ^(5) ]] || [[ "$BACKEND_VERSION" =~ ^(4) ]] || [[ "$BACKEND_VERSION" =~ ^(3) ]]; then - #API_URL=$(kubectl ${KUBE_OPTS} get cm sysdigcloud-config -o yaml | grep -i api.url: | head -1 | awk '{print $2}') - API_URL="http://127.0.0.1:8080" - # Check that the API_KEY for the Super User is valid and exit - CURL_OUT=$(curl -fks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/license" >/dev/null 2>&1) && RETVAL=$? && error=0 || { RETVAL=$? && error=1; } - if [[ ${error} -eq 1 ]]; then - echo "The API_KEY supplied is Unauthorized. Please check and try again. Return Code: ${RETVAL}" - exit 1 - fi - - curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/admin/customer/1/fastPathSettings" >> ${LOG_DIR}/fastPath_settings.json - curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/admin/customer/1/indexSettings" >> ${LOG_DIR}/index_settings.json - else - echo "We could not determine the backend version. Exiting." - exit 1 - fi - - curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/license" >> ${LOG_DIR}/license.json - curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/agents/connected?checkStatus=true" >> ${LOG_DIR}/agents_connected.json - curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/admin/customer/1/storageSettings" >> ${LOG_DIR}/storage_settings.json - curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/admin/customer/1/streamsnapSettings" >> ${LOG_DIR}/streamSnap_settings.json - curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/admin/customers/1/snapshotSettings" >> ${LOG_DIR}/snapshot_settings.json - curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/admin/customer/1/planSettings" >> ${LOG_DIR}/plan_settings.json - curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/admin/customer/1/dataRetentionSettings" >> ${LOG_DIR}/dataRetention_settings.json - curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/v2/users/light" >> ${LOG_DIR}/users.json - curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/v2/teams/light" >> ${LOG_DIR}/teams.json - curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/admin/auth/settings" >> ${LOG_DIR}/sso_settings.json - curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/alerts" >> ${LOG_DIR}/alerts.json - - # If Secure API key is supplied, collect settings - if [[ ! -z ${SECURE_API_KEY} ]]; then - BACKEND_VERSION=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get deployment sysdigcloud-api -ojsonpath='{.spec.template.spec.containers[0].image}' | awk 'match($0, /[0-9]\.[0-9]\.[0-9](\.[0-9]+)?/) {print substr($0, RSTART, RLENGTH)}') || true - if [[ "$BACKEND_VERSION" =~ ^(6) ]]; then - #API_URL=$(kubectl ${KUBE_OPTS} get cm sysdigcloud-collector-config -ojsonpath='{.data.collector-config\.conf}' | awk 'p&&$0~/"/{gsub("\"","");print} /{/{p=0} /sso/{p=1}' | grep serverName | awk '{print $3}') - # Check that the SECURE_API_KEY for the Super User is valid and exit - CURL_OUT=$(curl -fks -H "Authorization: Bearer ${SECURE_API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/license" >/dev/null 2>&1) && RETVAL=$? && error=0 || { RETVAL=$? && error=1; } - if [[ ${error} -eq 1 ]]; then - echo "The SECURE_API_KEY supplied is Unauthorized. Please check and try again. Return Code: ${RETVAL}" - exit 1 - fi - elif [[ "$BACKEND_VERSION" =~ ^(5) ]] || [[ "$BACKEND_VERSION" =~ ^(4) ]] || [[ "$BACKEND_VERSION" =~ ^(3) ]]; then - #API_URL=$(kubectl ${KUBE_OPTS} get cm sysdigcloud-config -o yaml | grep -i api.url: | head -1 | awk '{print $2}') - # Check that the API_KEY for the Super User is valid and exit - CURL_OUT=$(curl -fks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/license" >/dev/null 2>&1) && RETVAL=$? && error=0 || { RETVAL=$? && error=1; } - if [[ ${error} -eq 1 ]]; then - echo "The API_KEY supplied is Unauthorized. Please check and try again. Return Code: ${RETVAL}" - exit 1 - fi - else - echo "We cannot determine the backend version. Exiting." - exit 1 - fi - - # Check if ScanningV1 is enabled, and if so, do ... - SCANNING_V1_ENABLED=$(curl -ks ${API_URL}/api/secure/customerSettings -H "Authorization: Bearer ${SECURE_API_KEY}" 2>&1 | grep -Eo "\"scanningV1Enabled\":true") || true - if [[ ${SCANNING_V1_ENABLED} == "\"scanningV1Enabled\":true" ]]; then - echo "Scanning v1 is enabled. Continuing..." - # CURL COMMANDS GO HERE - mkdir -p ${LOG_DIR}/scanning - curl -ks ${API_URL}/api/scanning/v1/resultsDirect?limit=1 -H "Authorization: Bearer ${SECURE_API_KEY}" >> ${LOG_DIR}/scanning/scanningv1.txt - else - echo "Scanning V1 not detected. Continuing..." - fi - - # Check if ScanningV2 is enabled, and if so, do ... - SCANNING_V2_ENABLED=$(curl -ks ${API_URL}/api/secure/customerSettings -H "Authorization: Bearer ${SECURE_API_KEY}" 2>&1 | grep -Eo "\"scanningV2Enabled\":true") || true - if [[ ${SCANNING_V2_ENABLED} == "\"scanningV2Enabled\":true" ]]; then - echo "Scanning v2 is enabled. Continuing..." - curl -ks ${API_URL}/api/scanning/scanresults/v2/results -H "Authorization: Bearer ${SECURE_API_KEY}" >> ${LOG_DIR}/scanning/scanningv2.txt - # CURL COMMANDS GO HERE - else - echo "Scanning V2 not detected. Continuing..." - fi - fi - - if [[ $OSTYPE == 'darwin'* ]]; then - TO_EPOCH_TIME=$(date -jf "%H:%M:%S" $(date +%H):00:00 +%s) - else - TO_EPOCH_TIME=$(date -d "$(date +%H):00:00" +%s) - fi - FROM_EPOCH_TIME=$((TO_EPOCH_TIME-86400)) - METRICS=("syscall.count" "dragent.analyzer.sr" "container.count" "dragent.analyzer.n_drops_buffer" "dragent.analyzer.n_evts") - DEFAULT_SEGMENT="host.hostName" - SYSCALL_SEGMENTS=("host.hostName" "proc.name") - - mkdir -p ${LOG_DIR}/metrics - for metric in ${METRICS[@]}; do - if [ "${metric}" == "syscall.count" ]; then - for segment in ${SYSCALL_SEGMENTS[@]}; do - get_metrics "${metric}" "${segment}" - done - else - get_metrics "${metric}" "${DEFAULT_SEGMENT}" - fi - done - - get_agent_version_metric_limits - fi - - # Configure kubectl command if labels are set - if [[ -z ${LABELS} ]]; then - SYSDIGCLOUD_PODS=$(kubectl ${KUBE_OPTS} get pods --no-headers -o custom-columns=NAME:metadata.name) - else - SYSDIGCLOUD_PODS=$(kubectl ${KUBE_OPTS} -l "role in (${LABELS})" get pods --no-headers -o custom-columns=NAME:metadata.name) - fi - - echo "Using namespace ${NAMESPACE}" - echo "Using context ${CONTEXT}" - - # Collect kubectl cluster dump - CLUSTER_DUMP_DIR="${LOG_DIR}/kubectl-cluster-dump" - mkdir -p ${CLUSTER_DUMP_DIR} - kubectl ${KUBE_OPTS} cluster-info dump --output-directory=${CLUSTER_DUMP_DIR} - - # Collect container logs for each pod - if [[ "${SKIP_LOGS}" == "false" ]]; then - echo "Gathering Logs from ${NAMESPACE} pods" - command='tar czf - /logs/ /opt/draios/ /var/log/sysdigcloud/ /var/log/cassandra/ /tmp/redis.log /var/log/redis-server/redis.log /var/log/mysql/error.log /opt/prod.conf 2>/dev/null || true' - for pod in ${SYSDIGCLOUD_PODS}; do - echo "Getting support logs for ${pod}" - mkdir -p ${LOG_DIR}/${pod} - containers=$(kubectl ${KUBE_OPTS} get pod ${pod} -o json | jq -r '.spec.containers[].name' || echo "") - for container in ${containers}; do - kubectl ${KUBE_OPTS} logs ${pod} -c ${container} ${SINCE_OPTS} > ${LOG_DIR}/${pod}/${container}-kubectl-logs.txt || true - echo "Execing into ${container}" - kubectl ${KUBE_OPTS} exec ${pod} -c ${container} -- bash -c "echo" >/dev/null 2>&1 && RETVAL=$? || RETVAL=$? && true - kubectl ${KUBE_OPTS} exec ${pod} -c ${container} -- sh -c "echo" >/dev/null 2>&1 && RETVAL1=$? || RETVAL1=$? && true - if [ $RETVAL -eq 0 ]; then - kubectl ${KUBE_OPTS} exec ${pod} -c ${container} -- bash -c "${command}" > ${LOG_DIR}/${pod}/${container}-support-files.tgz || true - elif [ $RETVAL1 -eq 0 ]; then - kubectl ${KUBE_OPTS} exec ${pod} -c ${container} -- sh -c "${command}" > ${LOG_DIR}/${pod}/${container}-support-files.tgz || true - else - echo "Skipping log gathering for ${pod}" - fi - done - done - fi - - echo "Gathering pod descriptions" - for pod in ${SYSDIGCLOUD_PODS}; do - echo "Getting pod description for ${pod}" - mkdir -p ${LOG_DIR}/${pod} - kubectl ${KUBE_OPTS} get pod ${pod} -o json > ${LOG_DIR}/${pod}/kubectl-describe.json || true - done - - #Collect Describe Node Output - echo "Collecting node information" - kubectl ${KUBE_OPTS} describe nodes | tee -a ${LOG_DIR}/describe_node_output.log || echo "No permission to describe nodes!" - - NODES=$(kubectl ${KUBE_OPTS} get nodes --no-headers -o custom-columns=NAME:metadata.name) && RETVAL=0 || { RETVAL=$? && echo "No permission to get nodes!"; } - if [[ "${RETVAL}" == "0" ]]; then - mkdir -p ${LOG_DIR}/nodes - for node in ${NODES[@]}; do - kubectl ${KUBE_OPTS} get node ${node} -ojson > ${LOG_DIR}/nodes/${node}-kubectl.json - done - unset RETVAL - fi - - #Collect PV info - kubectl ${KUBE_OPTS} get pv | grep sysdig | tee -a ${LOG_DIR}/pv_output.log || echo "No permission to get PersistentVolumes" - kubectl ${KUBE_OPTS} get pvc | grep sysdig | tee -a ${LOG_DIR}/pvc_output.log - kubectl ${KUBE_OPTS} get storageclass | tee -a ${LOG_DIR}/sc_output.log || echo "No permission to get StorageClasses" - - # Get info on deployments, statefulsets, persistentVolumeClaims, daemonsets, and ingresses - echo "Gathering Manifest Information" - for object in svc deployment sts pvc daemonset ingress replicaset networkpolicy cronjob configmap; do - items=$(kubectl ${KUBE_OPTS} get ${object} -o jsonpath="{.items[*]['metadata.name']}") - mkdir -p ${LOG_DIR}/${object} - for item in ${items}; do - kubectl ${KUBE_OPTS} get ${object} ${item} -o json > ${LOG_DIR}/${object}/${item}-kubectl.json - done - done - - # Fetch container density information - num_nodes=0 - num_pods=0 - num_running_containers=0 - num_total_containers=0 - - printf "%-30s %-10s %-10s %-10s %-10s\n" "Node" "Pods" "Running Containers" "Total Containers" >> ${LOG_DIR}/container_density.txt - for node in $(kubectl ${KUBE_OPTS} get nodes --no-headers -o custom-columns=node:.metadata.name); do - total_pods=$(kubectl ${KUBE_OPTS} get pods -A --no-headers -o wide | grep ${node} |wc -l |xargs) - running_containers=$( kubectl ${KUBE_OPTS} get pods -A --no-headers -o wide |grep ${node} |awk '{print $3}' |cut -f 1 -d/ | awk '{ SUM += $1} END { print SUM }' |xargs) - total_containers=$( kubectl get ${KUBE_OPTS} pods -A --no-headers -o wide |grep ${node} |awk '{print $3}' |cut -f 2 -d/ | awk '{ SUM += $1} END { print SUM }' |xargs) - printf "%-30s %-15s %-20s %-10s\n" "${node}" "${total_pods}" "${running_containers}" "${total_containers}" >> ${LOG_DIR}/container_density.txt - num_nodes=$((num_nodes+1)) - num_pods=$((num_pods+${total_pods})) - num_running_containers=$((num_running_containers+${running_containers})) - num_total_containers=$((num_total_containers+${total_containers})) - done - - printf "\nTotals\n-----\n" >> ${LOG_DIR}/container_density.txt - printf "Nodes: ${num_nodes}\n" >> ${LOG_DIR}/container_density.txt - printf "Pods: ${num_pods}\n" >> ${LOG_DIR}/container_density.txt - printf "Running Containers: ${num_running_containers}\n" >> ${LOG_DIR}/container_density.txt - printf "Containers: ${num_total_containers}\n" >> ${LOG_DIR}/container_density.txt - - # Fetch Cassandra Nodetool output - echo "Fetching Cassandra statistics" - for pod in $(kubectl ${KUBE_OPTS} get pod -l role=cassandra --no-headers -o custom-columns=NAME:metadata.name) - do - mkdir -p ${LOG_DIR}/cassandra/${pod} - kubectl ${KUBE_OPTS} exec -it ${pod} -c cassandra -- nodetool info | tee -a ${LOG_DIR}/cassandra/${pod}/nodetool_info.log - kubectl ${KUBE_OPTS} exec -it ${pod} -c cassandra -- nodetool status | tee -a ${LOG_DIR}/cassandra/${pod}/nodetool_status.log - kubectl ${KUBE_OPTS} exec -it ${pod} -c cassandra -- nodetool getcompactionthroughput | tee -a ${LOG_DIR}/cassandra/${pod}/nodetool_getcompactionthroughput.log - kubectl ${KUBE_OPTS} exec -it ${pod} -c cassandra -- nodetool cfstats | tee -a ${LOG_DIR}/cassandra/${pod}/nodetool_cfstats.log - kubectl ${KUBE_OPTS} exec -it ${pod} -c cassandra -- nodetool cfhistograms draios message_data10 | tee -a ${LOG_DIR}/cassandra/${pod}/nodetool_cfhistograms.log - kubectl ${KUBE_OPTS} exec -it ${pod} -c cassandra -- nodetool proxyhistograms | tee -a ${LOG_DIR}/cassandra/${pod}/nodetool_proxyhistograms.log - kubectl ${KUBE_OPTS} exec -it ${pod} -c cassandra -- nodetool tpstats | tee -a ${LOG_DIR}/cassandra/${pod}/nodetool_tpstats.log - kubectl ${KUBE_OPTS} exec -it ${pod} -c cassandra -- nodetool compactionstats | tee -a ${LOG_DIR}/cassandra/${pod}/nodetool_compactionstats.log - done - - echo "Fetching Elasticsearch health info" - # CHECK HERE IF THE TLS ENV VARIABLE IS SET IN ELASTICSEARCH, AND BUILD THE CURL COMMAND OUT - ELASTIC_POD=$(kubectl ${KUBE_OPTS} get pods -l role=elasticsearch --no-headers -o custom-columns=NAME:metadata.name | head -1) || true - - if [ ! -z ${ELASTIC_POD} ]; then - ELASTIC_IMAGE=$(kubectl ${KUBE_OPTS} get pod ${ELASTIC_POD} -ojsonpath='{.spec.containers[?(@.name == "elasticsearch")].image}' | awk -F '/' '{print $NF}' | cut -f 1 -d ':') || true - - if [[ ${ELASTIC_IMAGE} == "opensearch"* ]]; then - CERTIFICATE_DIRECTORY="/usr/share/opensearch/config" - ELASTIC_TLS="true" - else - CERTIFICATE_DIRECTORY="/usr/share/elasticsearch/config" - ELASTIC_TLS=$(kubectl ${KUBE_OPTS} exec ${ELASTIC_POD} -c elasticsearch -- env | grep -i ELASTICSEARCH_TLS_ENCRYPTION) || true - if [[ ${ELASTIC_TLS} == *"ELASTICSEARCH_TLS_ENCRYPTION=true"* ]]; then - ELASTIC_TLS="true" - fi - fi - - if [[ ${ELASTIC_TLS} == "true" ]]; then - ELASTIC_CURL="curl -s --cacert ${CERTIFICATE_DIRECTORY}/root-ca.pem https://\${ELASTICSEARCH_ADMINUSER}:\${ELASTICSEARCH_ADMIN_PASSWORD}@\$(hostname):9200" - else - ELASTIC_CURL='curl -s -k http://$(hostname):9200' - fi - - for pod in $(kubectl ${KUBE_OPTS} get pods -l role=elasticsearch --no-headers -o custom-columns=NAME:metadata.name) - do - mkdir -p ${LOG_DIR}/elasticsearch/${pod} - - kubectl ${KUBE_OPTS} exec ${pod} -c elasticsearch -- /bin/bash -c "${ELASTIC_CURL}/_cat/health" | tee -a ${LOG_DIR}/elasticsearch/${pod}/elasticsearch_health.log || true - - kubectl ${KUBE_OPTS} exec ${pod} -c elasticsearch -- /bin/bash -c "${ELASTIC_CURL}/_cat/indices" | tee -a ${LOG_DIR}/elasticsearch/${pod}/elasticsearch_indices.log || true - - kubectl ${KUBE_OPTS} exec ${pod} -c elasticsearch -- /bin/bash -c "${ELASTIC_CURL}/_cat/nodes?v" | tee -a ${LOG_DIR}/elasticsearch/${pod}/elasticsearch_nodes.log || true - - kubectl ${KUBE_OPTS} exec ${pod} -c elasticsearch -- /bin/bash -c "${ELASTIC_CURL}/_cluster/allocation/explain?pretty" | tee -a ${LOG_DIR}/elasticsearch/${pod}/elasticsearch_index_allocation.log || true - - echo "Fetching ElasticSearch SSL Certificate Expiration Dates" - kubectl ${KUBE_OPTS} exec ${pod} -c elasticsearch -- openssl x509 -in ${CERTIFICATE_DIRECTORY}/node.pem -noout -enddate | tee -a ${LOG_DIR}/elasticsearch/${pod}/elasticsearch_node_pem_expiration.log || true - kubectl ${KUBE_OPTS} exec ${pod} -c elasticsearch -- openssl x509 -in ${CERTIFICATE_DIRECTORY}/admin.pem -noout -enddate | tee -a ${LOG_DIR}/elasticsearch/${pod}/elasticsearch_admin_pem_expiration.log || true - kubectl ${KUBE_OPTS} exec ${pod} -c elasticsearch -- openssl x509 -in ${CERTIFICATE_DIRECTORY}/root-ca.pem -noout -enddate | tee -a ${LOG_DIR}/elasticsearch/${pod}/elasticsearch_root_ca_pem_expiration.log || true - - - echo "Fetching Elasticsearch Index Versions" - kubectl ${KUBE_OPTS} exec ${pod} -c elasticsearch -- bash -c "${ELASTIC_CURL}/_all/_settings/index.version\*?pretty" | tee -a ${LOG_DIR}/elasticsearch/${pod}/elasticsearch_index_versions.log || true - - echo "Checking Used Elasticsearch Storage - ${pod}" - mountpath=$(kubectl ${KUBE_OPTS} get sts sysdigcloud-elasticsearch -ojsonpath='{.spec.template.spec.containers[].volumeMounts[?(@.name == "data")].mountPath}') - if [ ! -z $mountpath ]; then - kubectl ${KUBE_OPTS} exec ${pod} -c elasticsearch -- du -ch ${mountpath} | grep -i total | awk '{printf "%-13s %10s\n",$1,$2}' | tee -a ${LOG_DIR}/elasticsearch/${pod}/elasticsearch_storage.log || true - else - printf "Error getting ElasticSearch ${pod} mount path\n" | tee -a ${LOG_DIR}/elasticsearch/${pod}/elasticsearch_storage.log - fi - done - else - echo "Unable to fetch ElasticSearch pod to gather health info!" - fi - - # Fetch Cassandra storage info - for pod in $(kubectl ${KUBE_OPTS} get pods -l role=cassandra --no-headers -o custom-columns=NAME:metadata.name) - do - echo "Checking Used Cassandra Storage - ${pod}" - mkdir -p ${LOG_DIR}/cassandra/${pod} - printf "${pod}\n" | tee -a ${LOG_DIR}/cassandra/${pod}/cassandra_storage.log - mountpath=$(kubectl ${KUBE_OPTS} get sts sysdigcloud-cassandra -ojsonpath='{.spec.template.spec.containers[].volumeMounts[?(@.name == "data")].mountPath}') - if [ ! -z $mountpath ]; then - kubectl ${KUBE_OPTS} exec -it ${pod} -c cassandra -- du -ch ${mountpath} | grep -i total | awk '{printf "%-13s %10s\n",$1,$2}' | tee -a ${LOG_DIR}/cassandra/${pod}/cassandra_storage.log || true - else - printf "Error getting Cassandra ${pod} mount path\n" | tee -a ${LOG_DIR}/cassandra/${pod}/cassandra_storage.log - fi - done - - # Fetch postgresql storage info - for pod in $(kubectl ${KUBE_OPTS} get pods -l role=postgresql --no-headers -o custom-columns=NAME:metadata.name) - do - echo "Checking Used PostgreSQL Storage - ${pod}" - mkdir -p ${LOG_DIR}/postgresql/${pod} - printf "${pod}\n" | tee -a ${LOG_DIR}/postgresql/${pod}/postgresql_storage.log - kubectl ${KUBE_OPTS} exec -it ${pod} -c postgresql -- du -ch /var/lib/postgresql | grep -i total | awk '{printf "%-13s %10s\n",$1,$2}' | tee -a ${LOG_DIR}/postgresql/${pod}/postgresql_storage.log || true - done - - # Fetch mysql storage info - for pod in $(kubectl ${KUBE_OPTS} get pods -l role=mysql --no-headers -o custom-columns=NAME:metadata.name) - do - echo "Checking Used MySQL Storage - ${pod}" - mkdir -p ${LOG_DIR}/mysql/${pod} - printf "${pod}\n" | tee -a ${LOG_DIR}/mysql/${pod}/mysql_storage.log - kubectl ${KUBE_OPTS} exec -it ${pod} -c mysql -- du -ch /var/lib/mysql | grep -i total | awk '{printf "%-13s %10s\n",$1,$2}' | tee -a ${LOG_DIR}/mysql/${pod}/mysql_storage.log || true - done - - # Fetch kafka storage info - for pod in $(kubectl ${KUBE_OPTS} get pods -l role=cp-kafka --no-headers -o custom-columns=NAME:metadata.name) - do - echo "Checking Used Kafka Storage - ${pod}" - mkdir -p ${LOG_DIR}/kafka/${pod} - printf "${pod}\n" | tee -a ${LOG_DIR}/kafka/${pod}/kafka_storage.log - kubectl ${KUBE_OPTS} exec -it ${pod} -c broker -- du -ch /opt/kafka/data | grep -i total | awk '{printf "%-13s %10s\n",$1,$2}' | tee -a ${LOG_DIR}/kafka/${pod}/kafka_storage.log || true - done - - # Fetch zookeeper storage info - for pod in $(kubectl ${KUBE_OPTS} get pods -l role=zookeeper --no-headers -o custom-columns=NAME:metadata.name) - do - echo "Checking Used Zookeeper Storage - ${pod}" - mkdir -p ${LOG_DIR}/zookeeper/${pod} - printf "${pod}\n" | tee -a ${LOG_DIR}/zookeeper/${pod}/zookeeper_storage.log - kubectl ${KUBE_OPTS} exec -it ${pod} -c server -- du -ch /var/lib/zookeeper/data | grep -i total | awk '{printf "%-13s %10s\n",$1,$2}' | tee -a ${LOG_DIR}/zookeeper/${pod}/zookeeper_storage.log || true - done - - # Collect the sysdigcloud-config configmap, and write to the log directory - echo "Fetching the sysdigcloud-config ConfigMap" - kubectl ${KUBE_OPTS} get configmap sysdigcloud-config -o yaml | grep -v password | grep -v apiVersion > ${LOG_DIR}/config.yaml || true - - # Generate the bundle name, create a tarball, and remove the temp log directory - BUNDLE_NAME=$(date +%s)_sysdig_cloud_support_bundle.tgz - echo "Creating the ${BUNDLE_NAME} archive now" - tar czf ${BUNDLE_NAME} ${LOG_DIR} - rm -rf ${LOG_DIR} - - echo "Support bundle generated:" ${BUNDLE_NAME} -} - -parse_commandline "$@" -main From 9a54520427e16eba1947910c334f93fda71382af Mon Sep 17 00:00:00 2001 From: Daniele De Lorenzi Date: Thu, 9 May 2024 13:10:58 +0200 Subject: [PATCH 03/10] Kill kubectl port-forward session once the script finish Signed-off-by: Daniele De Lorenzi --- support_bundle/get_support_bundle.sh | 40 ++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/support_bundle/get_support_bundle.sh b/support_bundle/get_support_bundle.sh index 936db64b..ef33876c 100755 --- a/support_bundle/get_support_bundle.sh +++ b/support_bundle/get_support_bundle.sh @@ -157,6 +157,16 @@ main() { if [[ "$BACKEND_VERSION" =~ ^(7|6)$ ]]; then if [[ "$API_LOCAL" == "true" ]]; then kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} port-forward service/sysdigcloud-api 8080 > /dev/null 2>&1 & + + # Store the port-forward pid in order to kill the process once we finish + pid=$! + + # kill the port-forward regardless of how this script exits + trap '{ + # echo killing $pid + kill $pid + }' EXIT + # wait for port-forward to become available while ! curl -s localhost:8080 > /dev/null 2>&1 ; do sleep 0.2 @@ -175,6 +185,16 @@ main() { elif [[ "$BACKEND_VERSION" =~ ^(5) ]] || [[ "$BACKEND_VERSION" =~ ^(4) ]] || [[ "$BACKEND_VERSION" =~ ^(3) ]]; then if [[ "$API_LOCAL" == "true" ]]; then kubectl ${KUBE_OPTS} port-forward service/sysdigcloud-api 8080 > /dev/null 2>&1 & + + # Store the port-forward pid in order to kill the process once we finish + pid=$! + + # kill the port-forward regardless of how this script exits + trap '{ + # echo killing $pid + kill $pid + }' EXIT + # wait for port-forward to become available while ! curl -s localhost:8080 > /dev/null 2>&1 ; do sleep 0.2 @@ -215,6 +235,16 @@ main() { if [[ "$BACKEND_VERSION" =~ ^(7|6)$ ]]; then if [[ "$API_LOCAL" == "true" ]]; then kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} port-forward service/sysdigcloud-api 8080 > /dev/null 2>&1 & + + # Store the port-forward pid in order to kill the process once we finish + pid=$! + + # kill the port-forward regardless of how this script exits + trap '{ + # echo killing $pid + kill $pid + }' EXIT + # wait for port-forward to become available while ! curl -s localhost:8080 > /dev/null 2>&1 ; do sleep 0.2 @@ -232,6 +262,16 @@ main() { elif [[ "$BACKEND_VERSION" =~ ^(5) ]] || [[ "$BACKEND_VERSION" =~ ^(4) ]] || [[ "$BACKEND_VERSION" =~ ^(3) ]]; then if [[ "$API_LOCAL" == "true" ]]; then kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} port-forward service/sysdigcloud-api 8080 > /dev/null 2>&1 & + + # Store the port-forward pid in order to kill the process once we finish + pid=$! + + # kill the port-forward regardless of how this script exits + trap '{ + # echo killing $pid + kill $pid + }' EXIT + # wait for port-forward to become available while ! curl -s localhost:8080 > /dev/null 2>&1 ; do sleep 0.2 From f7c1768dc69ae61afa5aaee125848824c8b19f4a Mon Sep 17 00:00:00 2001 From: Daniele De Lorenzi Date: Fri, 5 Jul 2024 20:28:07 +0200 Subject: [PATCH 04/10] Fix backend_version regex Co-authored-by: Mark Breitung --- support_bundle/get_support_bundle.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support_bundle/get_support_bundle.sh b/support_bundle/get_support_bundle.sh index ef33876c..3bfbb9b3 100755 --- a/support_bundle/get_support_bundle.sh +++ b/support_bundle/get_support_bundle.sh @@ -182,7 +182,7 @@ main() { exit 1 fi curl -ks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/admin/customer/1/meerkatSettings" >> ${LOG_DIR}/meerkat_settings.json - elif [[ "$BACKEND_VERSION" =~ ^(5) ]] || [[ "$BACKEND_VERSION" =~ ^(4) ]] || [[ "$BACKEND_VERSION" =~ ^(3) ]]; then + elif [[ "$BACKEND_VERSION" =~ ^(5|4|3)$ ]]; then if [[ "$API_LOCAL" == "true" ]]; then kubectl ${KUBE_OPTS} port-forward service/sysdigcloud-api 8080 > /dev/null 2>&1 & From 2caa8959160bd4c54a9260e1eed953401a069aaa Mon Sep 17 00:00:00 2001 From: Daniele De Lorenzi Date: Fri, 5 Jul 2024 20:29:11 +0200 Subject: [PATCH 05/10] Fix backend_version regex Co-authored-by: Mark Breitung --- support_bundle/get_support_bundle.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support_bundle/get_support_bundle.sh b/support_bundle/get_support_bundle.sh index 3bfbb9b3..3e015521 100755 --- a/support_bundle/get_support_bundle.sh +++ b/support_bundle/get_support_bundle.sh @@ -152,7 +152,7 @@ main() { # If API key is supplied, check the backend version, and send a GET to the relevant endpoints. if [[ ! -z ${API_KEY} ]]; then - BACKEND_VERSION=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get deployment sysdigcloud-api -ojsonpath='{.spec.template.spec.containers[0].image}' | awk 'match($0, /[0-9]\.[0-9]+\.[0-9](\.[0-9]+)?/) {print substr($0, RSTART, RLENGTH)}') || true + BACKEND_VERSION=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get deployment sysdigcloud-api -ojsonpath='{.spec.template.spec.containers[0].image}' | awk -F: '{ print $2 }' | awk -F. '{ print $1 }' || true echo ${BACKEND_VERSION} > ${LOG_DIR}/backend_version.txt if [[ "$BACKEND_VERSION" =~ ^(7|6)$ ]]; then if [[ "$API_LOCAL" == "true" ]]; then From 94a1f731012fe7962f84c87cafd57126bb45a418 Mon Sep 17 00:00:00 2001 From: Daniele De Lorenzi Date: Mon, 8 Jul 2024 11:26:12 +0200 Subject: [PATCH 06/10] Update support_bundle/get_support_bundle.sh Co-authored-by: Mark Breitung --- support_bundle/get_support_bundle.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support_bundle/get_support_bundle.sh b/support_bundle/get_support_bundle.sh index 3e015521..fbe0a113 100755 --- a/support_bundle/get_support_bundle.sh +++ b/support_bundle/get_support_bundle.sh @@ -231,7 +231,7 @@ main() { # If Secure API key is supplied, collect settings if [[ ! -z ${SECURE_API_KEY} ]]; then - BACKEND_VERSION=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get deployment sysdigcloud-api -ojsonpath='{.spec.template.spec.containers[0].image}' | awk 'match($0, /[0-9]\.[0-9]+\.[0-9](\.[0-9]+)?/) {print substr($0, RSTART, RLENGTH)}') || true + BACKEND_VERSION=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get deployment sysdigcloud-api -ojsonpath='{.spec.template.spec.containers[0].image}' | awk -F: '{ print $2 }' | awk -F. '{ print $1 }') || true if [[ "$BACKEND_VERSION" =~ ^(7|6)$ ]]; then if [[ "$API_LOCAL" == "true" ]]; then kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} port-forward service/sysdigcloud-api 8080 > /dev/null 2>&1 & From 8577da75c0620a368e03174151f8465277f00ddf Mon Sep 17 00:00:00 2001 From: Daniele De Lorenzi Date: Mon, 8 Jul 2024 11:26:49 +0200 Subject: [PATCH 07/10] Update support_bundle/get_support_bundle.sh Co-authored-by: Mark Breitung --- support_bundle/get_support_bundle.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support_bundle/get_support_bundle.sh b/support_bundle/get_support_bundle.sh index fbe0a113..2839ba58 100755 --- a/support_bundle/get_support_bundle.sh +++ b/support_bundle/get_support_bundle.sh @@ -259,7 +259,7 @@ main() { echo "The SECURE_API_KEY supplied is Unauthorized. Please check and try again. Return Code: ${RETVAL}" exit 1 fi - elif [[ "$BACKEND_VERSION" =~ ^(5) ]] || [[ "$BACKEND_VERSION" =~ ^(4) ]] || [[ "$BACKEND_VERSION" =~ ^(3) ]]; then + elif [[ "$BACKEND_VERSION" =~ ^(5|4|3)$ ]]; then if [[ "$API_LOCAL" == "true" ]]; then kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} port-forward service/sysdigcloud-api 8080 > /dev/null 2>&1 & From cfe3ecf6132bee2ba1fd5a3f08dc8c8853d5dbe5 Mon Sep 17 00:00:00 2001 From: Daniele De Lorenzi Date: Wed, 10 Jul 2024 17:48:06 +0200 Subject: [PATCH 08/10] fix(support-bundle): Fix syntaxt error that were preventing correct script execution Signed-off-by: Daniele De Lorenzi --- support_bundle/get_support_bundle.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/support_bundle/get_support_bundle.sh b/support_bundle/get_support_bundle.sh index 2839ba58..44db15c0 100755 --- a/support_bundle/get_support_bundle.sh +++ b/support_bundle/get_support_bundle.sh @@ -152,7 +152,7 @@ main() { # If API key is supplied, check the backend version, and send a GET to the relevant endpoints. if [[ ! -z ${API_KEY} ]]; then - BACKEND_VERSION=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get deployment sysdigcloud-api -ojsonpath='{.spec.template.spec.containers[0].image}' | awk -F: '{ print $2 }' | awk -F. '{ print $1 }' || true + BACKEND_VERSION=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get deployment sysdigcloud-api -ojsonpath='{.spec.template.spec.containers[0].image}' | awk -F: '{ print $2 }' | awk -F. '{ print $1 }') || true echo ${BACKEND_VERSION} > ${LOG_DIR}/backend_version.txt if [[ "$BACKEND_VERSION" =~ ^(7|6)$ ]]; then if [[ "$API_LOCAL" == "true" ]]; then @@ -173,7 +173,7 @@ main() { done API_URL="http://127.0.0.1:8080" else - API_URL=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get cm sysdigcloud-collector-config '-ojsonpath={.data.collector-config\.conf}' | grep serverName | head -1 | awk '{print $3}' | sed 's/"//g') + API_URL=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get cm sysdigcloud-collector-config -ojsonpath='{.data.collector-config\.conf}' | grep serverName | head -1 | awk '{print $3}' | sed 's/"//g') fi # Check that the API_KEY for the Super User is valid and exit CURL_OUT=$(curl -fks -H "Authorization: Bearer ${API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/license" >/dev/null 2>&1) && RETVAL=$? && error=0 || { RETVAL=$? && error=1; } @@ -251,7 +251,7 @@ main() { done API_URL="http://127.0.0.1:8080" else - API_URL=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get cm sysdigcloud-collector-config '-ojsonpath={.data.collector-config\.conf}' | grep serverName | head -1 | awk '{print $3}' | sed 's/"//g') + API_URL=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get cm sysdigcloud-collector-config -ojsonpath='{.data.collector-config\.conf}' | grep serverName | head -1 | awk '{print $3}' | sed 's/"//g') fi # Check that the SECURE_API_KEY for the Super User is valid and exit CURL_OUT=$(curl -fks -H "Authorization: Bearer ${SECURE_API_KEY}" -H "Content-Type: application/json" "${API_URL}/api/license" >/dev/null 2>&1) && RETVAL=$? && error=0 || { RETVAL=$? && error=1; } From 9262e93875c969f5261b22116afe918df1d15843 Mon Sep 17 00:00:00 2001 From: Daniele De Lorenzi Date: Wed, 10 Jul 2024 18:59:35 +0200 Subject: [PATCH 09/10] fix(support-bundle): Moved version gathering outside the monitor and secure API if statement Signed-off-by: Daniele De Lorenzi --- support_bundle/get_support_bundle.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/support_bundle/get_support_bundle.sh b/support_bundle/get_support_bundle.sh index 44db15c0..145e9403 100755 --- a/support_bundle/get_support_bundle.sh +++ b/support_bundle/get_support_bundle.sh @@ -150,10 +150,11 @@ main() { exit 1 fi + echo "$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get deployment sysdigcloud-api -ojsonpath='{.spec.template.spec.containers[0].image}' | awk -F: '{ print $2 }')" > ${LOG_DIR}/backend_version.txt + BACKEND_VERSION=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get deployment sysdigcloud-api -ojsonpath='{.spec.template.spec.containers[0].image}' | awk -F: '{ print $2 }' | awk -F. '{ print $1 }') || true + # If API key is supplied, check the backend version, and send a GET to the relevant endpoints. if [[ ! -z ${API_KEY} ]]; then - BACKEND_VERSION=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get deployment sysdigcloud-api -ojsonpath='{.spec.template.spec.containers[0].image}' | awk -F: '{ print $2 }' | awk -F. '{ print $1 }') || true - echo ${BACKEND_VERSION} > ${LOG_DIR}/backend_version.txt if [[ "$BACKEND_VERSION" =~ ^(7|6)$ ]]; then if [[ "$API_LOCAL" == "true" ]]; then kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} port-forward service/sysdigcloud-api 8080 > /dev/null 2>&1 & @@ -231,7 +232,6 @@ main() { # If Secure API key is supplied, collect settings if [[ ! -z ${SECURE_API_KEY} ]]; then - BACKEND_VERSION=$(kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} get deployment sysdigcloud-api -ojsonpath='{.spec.template.spec.containers[0].image}' | awk -F: '{ print $2 }' | awk -F. '{ print $1 }') || true if [[ "$BACKEND_VERSION" =~ ^(7|6)$ ]]; then if [[ "$API_LOCAL" == "true" ]]; then kubectl ${CONTEXT_OPTS} ${KUBE_OPTS} port-forward service/sysdigcloud-api 8080 > /dev/null 2>&1 & From 26abbb6534300197c2d65448a5de40d0a232365b Mon Sep 17 00:00:00 2001 From: Daniele De Lorenzi Date: Thu, 11 Jul 2024 12:21:58 +0200 Subject: [PATCH 10/10] fix(support-bundle): Missing API_LOCAL variable definition Signed-off-by: Daniele De Lorenzi --- support_bundle/get_support_bundle.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/support_bundle/get_support_bundle.sh b/support_bundle/get_support_bundle.sh index 145e9403..2e00e300 100755 --- a/support_bundle/get_support_bundle.sh +++ b/support_bundle/get_support_bundle.sh @@ -8,6 +8,7 @@ catch() { #generate sysdigcloud support bundle on kubernetes +API_LOCAL="" LABELS="" CONTEXT="" CONTEXT_OPTS=""