From 4391e32cc7819b55c04f9c10639baf87ce85a2d4 Mon Sep 17 00:00:00 2001 From: ric-sysdig Date: Fri, 7 Nov 2025 09:24:47 +0100 Subject: [PATCH 1/2] first release of support-util.sh --- support_util/README.md | 47 +++++ support_util/support-utils.sh | 377 ++++++++++++++++++++++++++++++++++ 2 files changed, 424 insertions(+) create mode 100644 support_util/README.md create mode 100755 support_util/support-utils.sh diff --git a/support_util/README.md b/support_util/README.md new file mode 100644 index 00000000..3e198a32 --- /dev/null +++ b/support_util/README.md @@ -0,0 +1,47 @@ +# support-util + +This script supports only orchestrated environment, speeding up the data/log collection for Sysdig pods. +Data collection for Sysdig pods will always include: +- getting `ConfigMap` +- getting `DaemonSet` definition +- getting `Deployment` definition +- getting Kubernetes version +- getting nodes +- getting stats for nodes, especially CPU and Memory, where Sysdig pods are running +- a count of cluster objects, like: + - Deployments + - ReplicaSets + - Namespaces + - ConfigMaps + - Pods + +that we may need if you're having sizing issue with clusterShield. + +# Supported Sysdig product + +Below the list of supported product + +- Sysdig `agent` (deployed with `sysdig-deploy` chart) +- Sysdig `cluster-shield` (deployed with `sysdig-deploy` chart) +- Sysdig `node-analyzer` (deployed with `sysdig-deploy` chart), `kspm-analyzer`, `host-scanner` and `runtime-scanner` +- Sysdig `kspm-collector` (deployed with `sysdig-deploy` chart) +- Sysdig `host-shield` (deployed with `shield` chart) + +# Supported k8s version +The script uses `kubectl` or `oc` standard commands, like `get pod`, `get deployment` and so on. +Environments used for the test are Kubernetes v1.28 and greater and OpenShift v4.12 and greater. + +# Note for airgapped environment or enviroment with limited access to Internet +The script execute a curl on a S3 url provided by Sysdig support, if your env is airgapped or with limited access to Internet, you can just hit `Control+c` when the script ask for such S3 url, and share the archive as attachment of the case. + +# Usage + +The script takes in input two parameters: +- `namespace` (mandatory) +- `podName` (optional) + +If you do not pass the `podName` parameter, the script will collect what is described at the beginning of this README. If `podName` is passed, the script will collect the information related to the specific pod, plus what is included in the list of data collection. + +At the end of the execution, please remove the archive file and the directory created by the script. + +**WARNING - If your cluster have a good amount of nodes, 10 or more, please make sure to have a good amount of space available in the host where you'll run the script since log size, and their number, can vary based on the number of sysdig pod running in your cluster** diff --git a/support_util/support-utils.sh b/support_util/support-utils.sh new file mode 100755 index 00000000..95f945e5 --- /dev/null +++ b/support_util/support-utils.sh @@ -0,0 +1,377 @@ +#!/bin/bash + +namespace=$1 +podName=$2 + +function initVar() +{ + # Ensure namespace is provided + if [ -z "$namespace" ]; then + echo "Error: namespace is a required parameter." + echo "Usage: $0 namespace [podName]" + exit 1 + fi + + DEST_DIR=$(pwd) + SYSDIG_SUPPORT_DIR="sysdig-support" + [ ! -d "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}" ] && mkdir -p "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}" + + ACTIVITY_LOG="${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/activity.log" + function log_activity() { + local MESSAGE="$1" + echo "$(date '+%Y-%m-%d %H:%M:%S') | $MESSAGE" >> "${ACTIVITY_LOG}" + } + echo "Sysdig Support Script Activity Log - $(date)" > "${ACTIVITY_LOG}" + log_activity "Initialized activity log and created/confirmed output folder." + + local CURR_DATE=$(date '+%Y-%m-%d_%H%M%S') + ARCHIVE_NAME="support-util-${CURR_DATE}.tar.gz" + LABEL_IDENTIFIER="app.kubernetes.io/instance" + + #DO NOT CHANGE THE SECTION BELOW, UNLESS YOU'RE USING CUSTOM NAMES + SYSDIG_KSPMA_CONTAINER_NAME="sysdig-kspm-analyzer" + SYSDIG_HS_CONTAINER_NAME="sysdig-host-scanner" + SYSDIG_RS_CONTAINER_NAME="sysdig-runtime-scanner" + SYSDIG_AGENT_CONTAINER_NAME="sysdig" + SYSDIG_CS_DIR="clusterShield" + AGENT_LOG_DIR="opt/draios/logs/" + AGENT_DRAGENT_DIR="opt/draios/etc/kubernetes/config/..data" + IS_AIRGAPPED=false + SYSDIG_CS_ENDPOINT="healthz" + SYSDIG_CS_MONITORING_PORT=8080 + ERR_RC_TAR=8 + ERR_RC_CURL=9 + +[ ! -d "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}" ] && mkdir -p ${DEST_DIR}/${SYSDIG_SUPPORT_DIR} + +export DEST_DIR +export ARCHIVE_NAME +export ERR_RC_TAR +export ERR_RC_CURL +export AGENT_LOG_DIR +export SYSDIG_CS_DIR +export IS_AIRGAPPED + + printf "All the data will be saved using the path ${DEST_DIR}/${SYSDIG_SUPPORT_DIR}\n" + log_activity "Data directory set to ${DEST_DIR}/${SYSDIG_SUPPORT_DIR}" + + printf "Please put your executable to access your k8s cluster, kubectl or oc\n" + read k8sCmd + log_activity "User selected Kubernetes CLI: ${k8sCmd}" + + export k8sCmd + +SYSDIG_APP_NAME=$($k8sCmd get pods -n $namespace -o go-template='{{ range .items }}{{ index .metadata.labels "'${LABEL_IDENTIFIER}'" }}{{ "\n" }}{{end}}'| head -1) +SYSDIG_AGENT_PREFIX="${SYSDIG_APP_NAME}-agent-[a-zA-Z0-9]|${SYSDIG_APP_NAME}-shield-host-[a-zA-Z0-9]|${SYSDIG_APP_NAME}-host-[a-zA-Z0-9]|${SYSDIG_APP_NAME}-[a-zA-Z0-9]" +SYSDIG_CS_PREFIX="${SYSDIG_APP_NAME}-clustershield-[a-zA-Z0-9]|${SYSDIG_APP_NAME}-shield-cluster-[a-zA-Z0-9]|${SYSDIG_APP_NAME}-cluster-[a-zA-Z0-9]" +SYSDIG_CS_SH_PREFIX="${SYSDIG_APP_NAME}-cluster-[a-zA-Z0-9]" +SYSDIG_NA_PREFIX="${SYSDIG_APP_NAME}-node-analyzer-[a-zA-Z0-9]" +SYSDIG_KSPMC_PREFIX="${SYSDIG_APP_NAME}-kspmcollector-[a-zA-Z0-9]" +export SYSDIG_AGENT_PREFIX +export SYSDIG_CS_PREFIX + + log_activity "initVar completed." +} + +function disclaimer() +{ + log_activity "Displayed disclaimer to user." + printf "This script will collect some information from your cluster, no changes will be made.\nPlease ensure that KUBECTL or OC executable are available in your PATH.\n" + printf "Please ensure that you have access, at least, to the namespace where sysdig pods are currently running.\n" + printf "Please press Enter to continue.\n" + read go + log_activity "User confirmed disclaimer and continued." + clear + log_activity "Screen cleared after disclaimer." +} + +function isAirgapped() +{ + +printf "The script use a curl command to upload the archive file created into your case\n" +printf "Please put y if your environment has restrictions on internet access or no internet access. \n Put n if your env do not have any kind of restrictions for internet access\n" +read answer +clear + +} + +function collectArtifacts() +{ + log_activity "Starting collectArtifacts (namespace: ${namespace}, pod: ${podName:-ALL})" + if [ -z "${podName}" ]; then + printf "Getting all sysdig pods configuration, this could take a while\n" + log_activity "Collecting cluster info (version output)." + $k8sCmd version -o json > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/cluster_info.json" + log_activity "Collected cluster_info.json." + + $k8sCmd get po --sort-by='.status.containerStatuses[0].restartCount' --no-headers -n "${namespace}" -o wide > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/running_pods.txt" + log_activity "Saved running_pods.txt." + + if [[ "$k8sCmd" == "oc" ]]; then + $k8sCmd adm top pod -n "${namespace}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/top_pods.txt" + log_activity "Collected pod resource usage (oc mode)." + else + $k8sCmd top pod -n "${namespace}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/top_pods.txt" || printf "Metrics server not installed or ready, moving forward\n" + log_activity "Collected pod resource usage (kubectl mode)." + fi + + $k8sCmd describe po -n "${namespace}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/describe_pods.txt" + $k8sCmd get cm -o yaml -n "${namespace}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/configmap.txt" + $k8sCmd get ds -o yaml -n "${namespace}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/daemonset.txt" + $k8sCmd get deploy -o yaml -n "${namespace}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/deployment.txt" + log_activity "Saved configmap.txt, daemonset.txt, deployment.txt, describe_pods.txt" + + $k8sCmd describe nodes > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/nodes.txt" + log_activity "Saved nodes.txt." + + printf "Configuration collection completed for all Sysdig pods\n" + log_activity "Configuration collection completed for all pods." + else + printf "Getting the pod configuration for the pod ${podName}\n" + log_activity "Collecting cluster info for specific pod (${podName})." + $k8sCmd version -o json > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/cluster_info.json" + if [[ "$k8sCmd" == "oc" ]]; then + $k8sCmd adm top pod -n "${namespace}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/top_pods.txt" + log_activity "Collected pod resource usage (oc mode)." + else + $k8sCmd top pod -n "${namespace}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/top_pods.txt" || printf "Metrics server not installed or ready, moving forward\n" + log_activity "Collected pod resource usage (kubectl mode)." + fi + $k8sCmd get po ${podName} -n "${namespace}" -o wide > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/${podName}_node.txt" + log_activity "Saved ${podName}_node.txt." + $k8sCmd describe po ${podName} -n "${namespace}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/describe_pods_${podName}.txt" + log_activity "Saved describe_pods_${podName}.txt." + $k8sCmd get cm -o yaml -n "${namespace}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/configmap.txt" + $k8sCmd get ds -o yaml -n "${namespace}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/daemonset.txt" + $k8sCmd get deploy -o yaml -n "${namespace}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/deployment.txt" + log_activity "Saved configmap.txt, daemonset.txt, deployment.txt." + $k8sCmd describe nodes > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/nodes.txt" + log_activity "Saved nodes.txt." + printf "Configuration collection completed for pod ${podName}\n" + log_activity "Configuration collection completed for pod ${podName}." + fi + + printf "Collecting cluster object counts\n" + deployments=$($k8sCmd get deployments --all-namespaces --no-headers 2>/dev/null | wc -l) + replicasets=$($k8sCmd get replicasets --all-namespaces --no-headers 2>/dev/null | wc -l) + namespaces=$($k8sCmd get namespaces --no-headers 2>/dev/null | wc -l) + configmaps=$($k8sCmd get configmaps --all-namespaces --no-headers 2>/dev/null | wc -l) + pods=$($k8sCmd get pods --all-namespaces --no-headers 2>/dev/null | wc -l) + { + echo "Cluster Object Counts:" + echo "-----------------------" + echo "Deployments : $deployments" + echo "ReplicaSets : $replicasets" + echo "Namespaces : $namespaces" + echo "ConfigMaps : $configmaps" + echo "Pods : $pods" + } > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/cluster_object_counts.txt" + log_activity "Saved cluster_object_counts.txt with deployments:$deployments, replicasets:$replicasets, namespaces:$namespaces, configmaps:$configmaps, pods:$pods." + CS_POD_IP=`cat ${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/running_pods.txt|grep -E ${SYSDIG_CS_PREFIX}|head -1|awk '{print $6}'` + log_activity "collectArtifacts completed." +} + +function getLogs() +{ + log_activity "Starting getLogs (namespace: ${namespace}, pod: ${podName:-ALL})" + local csAttempt=0 + local drAgentAttempt=0 + if [ -z "${podName}" ]; then + printf "Getting all sysdig logs, this could take a while\n" + for pod in $(awk '{print $1}' < "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/running_pods.txt"); do + printf "Getting log of pod ${pod}\n" + log_activity "Attempting log collection for pod ${pod}." + if [[ $pod != *"clustershield"* && $pod != *"node-analyzer"* && $pod != *"shield-cluster"* && $pod != *"kspmcollector"* && $pod =~ $SYSDIG_AGENT_PREFIX ]]; then + mkdir -p "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${pod}" + $k8sCmd -n "${namespace}" cp "$pod:${AGENT_LOG_DIR}." "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${pod}" 2>/dev/null + if [ $? -eq 0 ]; then + log_activity "Copied agent log files for pod ${pod}." + else + log_activity "ERROR: Failed to copy logs for pod ${pod} (possibly recycled)." + fi + if [[ $CS_POD_IP != "" && $csAttempt -eq 0 ]]; then + log_activity "Tryng to perform curl against cluster shield health endpoint" + $k8sCmd exec $pod -n "${namespace}" -- curl http://${CS_POD_IP}:${SYSDIG_CS_MONITORING_PORT}/${SYSDIG_CS_ENDPOINT} > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/csFeaturesStatus.txt" 2>/dev/null || printf "Unable to call CS health endpoint, moving forward\n" + ((csAttempt++)) + fi + if [[ $drAgentAttempt -eq 0 ]]; then + log_activity "Getting dragent.yaml from pod ${pod}" + $k8sCmd -n "${namespace}" cp "$pod:${AGENT_DRAGENT_DIR}/dragent.yaml" "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/dragent.yaml" 2>/dev/null + log_activity "Getting dragent.yaml from pod ${pod} completed!" + ((drAgentAttempt++)) + fi + + fi + if [[ $pod =~ $SYSDIG_CS_PREFIX || $pod =~ $SYSDIG_CS_SH_PREFIX ]]; then + mkdir -p "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${SYSDIG_CS_DIR}" + $k8sCmd -n "${namespace}" logs "$pod" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${SYSDIG_CS_DIR}/${pod}.log" 2>/dev/null + if [ $? -eq 0 ]; then + log_activity "Collected cluster shield log for pod ${pod}." + else + log_activity "ERROR: Failed to collect cluster shield log for pod ${pod} (pod not found)." + fi + fi + if [[ $pod =~ $SYSDIG_NA_PREFIX ]]; then + mkdir -p "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs" + $k8sCmd -n "${namespace}" logs "${pod}" -c "${SYSDIG_KSPMA_CONTAINER_NAME}" > /dev/null 2>&1 && \ + $k8sCmd -n "${namespace}" logs "${pod}" -c "${SYSDIG_KSPMA_CONTAINER_NAME}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${pod}_${SYSDIG_KSPMA_CONTAINER_NAME}.log" && \ + log_activity "Collected kspm-analyzer logs for pod ${pod}." || \ + log_activity "kspm-analyzer not installed for pod ${pod}." + $k8sCmd -n "${namespace}" logs "${pod}" -c "${SYSDIG_HS_CONTAINER_NAME}" > /dev/null 2>&1 && \ + $k8sCmd -n "${namespace}" logs "${pod}" -c "${SYSDIG_HS_CONTAINER_NAME}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${pod}_${SYSDIG_HS_CONTAINER_NAME}.log" && \ + log_activity "Collected host-scanner logs for pod ${pod}." || \ + log_activity "host-scanner not installed for pod ${pod}." + $k8sCmd -n "${namespace}" logs "${pod}" -c "${SYSDIG_RS_CONTAINER_NAME}" > /dev/null 2>&1 && \ + $k8sCmd -n "${namespace}" logs "${pod}" -c "${SYSDIG_RS_CONTAINER_NAME}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${pod}_${SYSDIG_RS_CONTAINER_NAME}.log" && \ + log_activity "Collected runtime-scanner logs for pod ${pod}." || \ + log_activity "runtime-scanner not installed for pod ${pod}." + fi + if [[ $pod =~ $SYSDIG_KSPMC_PREFIX ]]; then + mkdir -p "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs" + $k8sCmd -n "${namespace}" logs "${pod}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${pod}.log" 2>/dev/null + if [ $? -eq 0 ]; then + log_activity "Collected kspmcollector log for pod ${pod}." + else + log_activity "ERROR: Failed to collect kspmcollector log for pod ${pod} (pod not found)." + fi + fi + done + log_activity "Log collection completed for all pods." + else + log_activity "Attempting log collection for pod ${podName}." + if [[ $podName != *"clustershield"* && $podName != *"node-analyzer"* && $podName != *"shield-cluster"* && $podName != *"kspmcollector"* && $podName =~ $SYSDIG_AGENT_PREFIX ]]; then + printf "Collecting log for pod ${podName}\n" + mkdir -p "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${podName}" + $k8sCmd -n "${namespace}" cp "${podName}:${AGENT_LOG_DIR}." "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${podName}" 2>/dev/null + if [ $? -eq 0 ]; then + printf "Log collected for pod ${podName}\n" + log_activity "Collected agent log for pod ${podName}." + else + log_activity "ERROR: Failed to collect agent log for pod ${podName} (possibly recycled)." + fi + fi + if [[ $podName =~ $SYSDIG_CS_PREFIX || $podName =~ $SYSDIG_CS_SH_PREFIX ]]; then + printf "Collecting log for pod ${podName}\n" + mkdir -p "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${SYSDIG_CS_DIR}" + $k8sCmd -n "${namespace}" logs "${podName}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${SYSDIG_CS_DIR}/${podName}.log" 2>/dev/null + if [ $? -eq 0 ]; then + printf "Log collected for pod ${podName}\n" + log_activity "Collected cluster shield log for pod ${podName}." + else + log_activity "ERROR: Failed to collect cluster shield log for pod ${podName} (pod not found)." + fi + fi + if [[ $podName =~ $SYSDIG_NA_PREFIX ]]; then + printf "Collecting log for pod ${podName}\n" + mkdir -p "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs" + $k8sCmd -n "${namespace}" logs "${podName}" -c "${SYSDIG_KSPMA_CONTAINER_NAME}" > /dev/null 2>&1 && \ + $k8sCmd -n "${namespace}" logs "${podName}" -c "${SYSDIG_KSPMA_CONTAINER_NAME}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${podName}_${SYSDIG_KSPMA_CONTAINER_NAME}.log" && \ + log_activity "Collected kspm-analyzer log for pod ${podName}." || \ + log_activity "kspm-analyzer not installed for pod ${podName}." + $k8sCmd -n "${namespace}" logs "${podName}" -c "${SYSDIG_HS_CONTAINER_NAME}" > /dev/null 2>&1 && \ + $k8sCmd -n "${namespace}" logs "${podName}" -c "${SYSDIG_HS_CONTAINER_NAME}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${podName}_${SYSDIG_HS_CONTAINER_NAME}.log" && \ + log_activity "Collected host-scanner log for pod ${podName}." || \ + log_activity "host-scanner not installed for pod ${podName}." + $k8sCmd -n "${namespace}" logs "${podName}" -c "${SYSDIG_RS_CONTAINER_NAME}" > /dev/null 2>&1 && \ + $k8sCmd -n "${namespace}" logs "${podName}" -c "${SYSDIG_RS_CONTAINER_NAME}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${podName}_${SYSDIG_RS_CONTAINER_NAME}.log" && \ + log_activity "Collected runtime-scanner log for pod ${podName}." || \ + log_activity "runtime-scanner not installed for pod ${podName}." + printf "Log collected for pod ${podName}\n" + fi + if [[ $podName =~ $SYSDIG_KSPMC_PREFIX ]]; then + printf "Collecting log for pod ${podName}\n" + mkdir -p "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs" + $k8sCmd -n "${namespace}" logs "${podName}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${podName}.log" 2>/dev/null + if [ $? -eq 0 ]; then + printf "Log collected for pod ${podName}\n" + log_activity "Collected kspmcollector log for pod ${podName}." + else + log_activity "ERROR: Failed to collect kspmcollector log for pod ${podName} (pod not found)." + fi + fi + log_activity "Log collection completed for pod ${podName}." + fi + log_activity "getLogs completed." +} + +function compressAndUpload() +{ + cd "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}" + printf "Creating archive file ${ARCHIVE_NAME}\n" + log_activity "Starting archive creation: ${ARCHIVE_NAME}." + errorMessage=$(tar czf "${ARCHIVE_NAME}" * 2>&1) + if [ $? -eq 0 ]; then + printf "Archive file created successfully, ready for upload!\n" + log_activity "Archive ${ARCHIVE_NAME} created successfully." + else + printf "Something went wrong\n" + printf "%s\n" "$errorMessage" + log_activity "Failed to create archive (${ARCHIVE_NAME}): $errorMessage" + exit "${ERR_RC_TAR}" + fi +if [ $answer == "y" ]; + then + printf "The archive has been saved in the path ${DEST_DIR}/${SYSDIG_SUPPORT_DIR} , archive name is ${ARCHIVE_NAME}\n" + IS_AIRGAPPED="true" + cleanArtifacts $IS_AIRGAPPED + printf "Script execution completed, exit \n" + exit 0 + else + + printf "Please put the S3 link provided by Sysdig Support, the script will upload the archive on the case.\n" + read SYSDIG_UPLOAD_URL + log_activity "User provided S3 upload URL: ${SYSDIG_UPLOAD_URL}" + + printf "The status of the upload will not be shown, please be patient\n" + log_activity "Uploading ${ARCHIVE_NAME} to S3 (${SYSDIG_UPLOAD_URL})..." + httpRetCode=$(curl -s -S -o /dev/null -w "%{http_code}" -X PUT --url "${SYSDIG_UPLOAD_URL}" -H "Content-Disposition: attachment; filename=${ARCHIVE_NAME}" -T "${ARCHIVE_NAME}") + if [ $httpRetCode -eq 200 ]; then + printf "Archive file uploaded successfully!\n" + log_activity "Archive uploaded successfully to S3." + cleanArtifacts + else + printf "Something went wrong\n" + log_activity "S3 upload failed with curl exit code $httpRetCode" + exit "${ERR_RC_CURL}" + fi + + printf "Script execution completed!\n" + log_activity "Script execution completed." +fi +} + +function cleanArtifacts +{ + +printf "Cleanup started\n" +log_activity "Script Cleanup Started" + +cd ${DEST_DIR}/${SYSDIG_SUPPORT_DIR} + +printf "Removing cluster_info.json file\n" +rm cluster_info.json || printf "File not found, or not enough privileges, moving forward\n" +printf "Removing txt file\n" + for i in $(ls *.txt); do + printf "removing $i \n" + rm $i + done + if [ $IS_AIRGAPPED == "false" ]; + then + printf "Removing archive file $ARCHIVE_NAME\n" + rm $ARCHIVE_NAME + fi + +printf "Removing the logs directory\n" +rm -fr logs + +printf "Cleanup completed!\n" +log_activity "Script Cleanup completed" +} + +# Main workflow +initVar +disclaimer +isAirgapped +collectArtifacts +getLogs +compressAndUpload From a9fbcf52b93f7dd16ad2e73edabc83c7657db726 Mon Sep 17 00:00:00 2001 From: ric-sysdig Date: Fri, 30 Jan 2026 11:02:23 +0100 Subject: [PATCH 2/2] resolved most of the points reported in the PR review --- support_util/README.md | 2 +- support_util/support-utils.sh | 396 +++++++++++++++++++++------------- 2 files changed, 247 insertions(+), 151 deletions(-) diff --git a/support_util/README.md b/support_util/README.md index 3e198a32..65002ba6 100644 --- a/support_util/README.md +++ b/support_util/README.md @@ -32,7 +32,7 @@ The script uses `kubectl` or `oc` standard commands, like `get pod`, `get deploy Environments used for the test are Kubernetes v1.28 and greater and OpenShift v4.12 and greater. # Note for airgapped environment or enviroment with limited access to Internet -The script execute a curl on a S3 url provided by Sysdig support, if your env is airgapped or with limited access to Internet, you can just hit `Control+c` when the script ask for such S3 url, and share the archive as attachment of the case. +If your env is airgapped or with limited access to Internet, please follow the instructions provided by the script. # Usage diff --git a/support_util/support-utils.sh b/support_util/support-utils.sh index 95f945e5..11e685b9 100755 --- a/support_util/support-utils.sh +++ b/support_util/support-utils.sh @@ -8,13 +8,13 @@ function initVar() # Ensure namespace is provided if [ -z "$namespace" ]; then echo "Error: namespace is a required parameter." - echo "Usage: $0 namespace [podName]" + echo "Usage: $0 namespace [podName - optional]" exit 1 fi DEST_DIR=$(pwd) SYSDIG_SUPPORT_DIR="sysdig-support" - [ ! -d "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}" ] && mkdir -p "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}" + mkdir -p $DEST_DIR/$SYSDIG_SUPPORT_DIR ACTIVITY_LOG="${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/activity.log" function log_activity() { @@ -26,23 +26,49 @@ function initVar() local CURR_DATE=$(date '+%Y-%m-%d_%H%M%S') ARCHIVE_NAME="support-util-${CURR_DATE}.tar.gz" - LABEL_IDENTIFIER="app.kubernetes.io/instance" - #DO NOT CHANGE THE SECTION BELOW, UNLESS YOU'RE USING CUSTOM NAMES + #DO NOT CHANGE THE SECTION BELOW, UNLESS YOU'RE USING CUSTOM NAMES + SYSDIG_KSPM_IMAGE_NAME="kspm-analyzer" + SYSDIG_HS_IMAGE_NAME="host-scanner" + SYSDIG_RS_IMAGE_NAME="runtime-scanner" SYSDIG_KSPMA_CONTAINER_NAME="sysdig-kspm-analyzer" SYSDIG_HS_CONTAINER_NAME="sysdig-host-scanner" SYSDIG_RS_CONTAINER_NAME="sysdig-runtime-scanner" SYSDIG_AGENT_CONTAINER_NAME="sysdig" + SYSDIG_NA_IMAGE_NAME="${SYSDIG_KSPM_IMAGE_NAME}|${SYSDIG_HS_IMAGE_NAME}|${SYSDIG_RS_IMAGE_NAME}" + SYSDIG_AGENT_IMAGE_NAME="agent-slim|agent" + SYSDIG_CS_IMAGE_NAME="cluster-shield" + SYSDIG_KSPM_COLLECTOR_IMAGE_NAME="kspm-collector" SYSDIG_CS_DIR="clusterShield" AGENT_LOG_DIR="opt/draios/logs/" AGENT_DRAGENT_DIR="opt/draios/etc/kubernetes/config/..data" IS_AIRGAPPED=false SYSDIG_CS_ENDPOINT="healthz" SYSDIG_CS_MONITORING_PORT=8080 + SYSDIG_AGENT_IMMUTABLE_LABEL="app.kubernetes.io/name" + SYSDIG_KSPM_COLLECTOR_IMMUTABLE_LABEL="app.kubernetes.io/instance" + SYSDIG_NA_IMMUTABLE_LABEL="app.kubernetes.io/instance" + SYSDIG_SHIELD_IMMUTABLE_LABEL="sysdig/component" + SYSDIG_AGENT_KMODULE_NAME="agent-kmodule" + SYSDIG_DS_NAME="" + SYSDIG_DEPLOY_NAME="" + JSONPATH_SEARCH="{range .items[*]}{.metadata.name}{'\t'}{.spec.template.spec.containers[0].image}{'\n'}{end}" + AGENT_CP_RETRY=3 + DS_FIND_ATTEMPT_RETRY=1 + DP_FIND_ATTEMPT_RETRY=1 + DS_COUNTER_RETRY=0 + DP_COUNTER_RETRY=0 ERR_RC_TAR=8 ERR_RC_CURL=9 - -[ ! -d "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}" ] && mkdir -p ${DEST_DIR}/${SYSDIG_SUPPORT_DIR} + ERR_RC_NOTHING_FOUND=10 + SYSDIG_AGENT_APP_NAME="" + SYSDIG_NA_APP_NAME="" + SYSDIG_CS_APP_NAME="" + SYSDIG_KSPM_COLLECTOR_APP_NAME="" + SYSDIG_AGENT_PREFIX="" + SYSDIG_NA_PREFIX="" + SYSDIG_CS_PREFIX="" + SYSDIG_KSPMC_PREFIX="" export DEST_DIR export ARCHIVE_NAME @@ -52,25 +78,90 @@ export AGENT_LOG_DIR export SYSDIG_CS_DIR export IS_AIRGAPPED - printf "All the data will be saved using the path ${DEST_DIR}/${SYSDIG_SUPPORT_DIR}\n" - log_activity "Data directory set to ${DEST_DIR}/${SYSDIG_SUPPORT_DIR}" + printf "All the data will be saved using the path %s \n" "$DEST_DIR/$SYSDIG_SUPPORT_DIR" + log_activity "Data directory set to $DEST_DIR/$SYSDIG_SUPPORT_DIR" printf "Please put your executable to access your k8s cluster, kubectl or oc\n" read k8sCmd - log_activity "User selected Kubernetes CLI: ${k8sCmd}" + log_activity "User selected Kubernetes CLI: $k8sCmd" export k8sCmd - -SYSDIG_APP_NAME=$($k8sCmd get pods -n $namespace -o go-template='{{ range .items }}{{ index .metadata.labels "'${LABEL_IDENTIFIER}'" }}{{ "\n" }}{{end}}'| head -1) -SYSDIG_AGENT_PREFIX="${SYSDIG_APP_NAME}-agent-[a-zA-Z0-9]|${SYSDIG_APP_NAME}-shield-host-[a-zA-Z0-9]|${SYSDIG_APP_NAME}-host-[a-zA-Z0-9]|${SYSDIG_APP_NAME}-[a-zA-Z0-9]" -SYSDIG_CS_PREFIX="${SYSDIG_APP_NAME}-clustershield-[a-zA-Z0-9]|${SYSDIG_APP_NAME}-shield-cluster-[a-zA-Z0-9]|${SYSDIG_APP_NAME}-cluster-[a-zA-Z0-9]" -SYSDIG_CS_SH_PREFIX="${SYSDIG_APP_NAME}-cluster-[a-zA-Z0-9]" -SYSDIG_NA_PREFIX="${SYSDIG_APP_NAME}-node-analyzer-[a-zA-Z0-9]" -SYSDIG_KSPMC_PREFIX="${SYSDIG_APP_NAME}-kspmcollector-[a-zA-Z0-9]" -export SYSDIG_AGENT_PREFIX -export SYSDIG_CS_PREFIX + printf "Performing init vars\n" +while [[ -z $SYSDIG_DS_NAME ]] && [[ $DS_COUNTER_RETRY -le $DS_FIND_ATTEMPT_RETRY ]]; do +DS_LIST=$( + $k8sCmd get ds -l "${SYSDIG_SHIELD_IMMUTABLE_LABEL}" -n $namespace -o=jsonpath="${JSONPATH_SEARCH}" 2>/dev/null + $k8sCmd get ds -l "${SYSDIG_AGENT_IMMUTABLE_LABEL}" -n $namespace -o=jsonpath="${JSONPATH_SEARCH}" 2>/dev/null + $k8sCmd get ds -l "${SYSDIG_NA_IMMUTABLE_LABEL}" -n $namespace -o=jsonpath="${JSONPATH_SEARCH}" 2>/dev/null + ) +SYSDIG_DS_NAME=$(echo -e "${DS_LIST}" | grep . | sort | uniq) +log_activity "Ds name found $SYSDIG_DS_NAME" +(( DS_COUNTER_RETRY ++ )) +done + +while [[ -z $SYSDIG_DEPLOY_NAME ]] && [[ $DP_COUNTER_RETRY -le $DP_FIND_ATTEMPT_RETRY ]]; do + +DEPLOY_LIST=$( + $k8sCmd get deploy -l "${SYSDIG_SHIELD_IMMUTABLE_LABEL}" -n $namespace -o=jsonpath="${JSONPATH_SEARCH}" 2>/dev/null + $k8sCmd get deploy -l "${SYSDIG_KSPM_COLLECTOR_IMMUTABLE_LABEL}" -n $namespace -o=jsonpath="${JSONPATH_SEARCH}" 2>/dev/null + ); +SYSDIG_DEPLOY_NAME=$(echo -e "${DEPLOY_LIST}"|grep .|sort |uniq) +log_activity "Dp name found $SYSDIG_DEPLOY_NAME" +(( DP_COUNTER_RETRY ++ )) +done + +if [[ -z $SYSDIG_DS_NAME ]] && [[ -z $SYSDIG_DEPLOY_NAME ]]; then + printf -- "-----------------------------------------------------------------------\n" + printf "RESULT: No Sysdig components found in namespace: '%s'\n" "$namespace" + printf -- "-----------------------------------------------------------------------\n" + printf "Possible reasons:\n" + printf " 1. The namespace provided is incorrect.\n" + printf " 2. The components (DaemonSet/Deployment) are not yet deployed.\n" + printf " 3. The components are installed in a DIFFERENT namespace.\n\n" + printf "NOTE: If your installation is split (e.g., Agent/Shield, Nodeanalyzer and/or ClusterShield in different\n" + printf "namespaces), please run this script separately for each namespace.\n" + printf -- "-----------------------------------------------------------------------" + exit $ERR_RC_NOTHING_FOUND +fi + + +#split the app name and the image name +while IFS=$'\t' read -r APP_NAME IMAGE_NAME; do + if [[ "$IMAGE_NAME" =~ $SYSDIG_AGENT_IMAGE_NAME ]]; then + SYSDIG_AGENT_APP_NAME=$APP_NAME + log_activity "Got agent, or shield, application name: $SYSDIG_AGENT_APP_NAME" + fi + if [[ "$IMAGE_NAME" =~ $SYSDIG_NA_IMAGE_NAME ]]; then + SYSDIG_NA_APP_NAME=$APP_NAME + log_activity "Got node-analyzer application name: $SYSDIG_NA_APP_NAME" + fi +done <<< "${SYSDIG_DS_NAME}" + + + +while IFS=$'\t' read -r APP_NAME IMAGE_NAME; do + if [[ "$IMAGE_NAME" =~ $SYSDIG_CS_IMAGE_NAME ]]; then + SYSDIG_CS_APP_NAME=$APP_NAME + log_activity "Got clusterShield application name: $SYSDIG_CS_APP_NAME" + fi + if [[ "$IMAGE_NAME" =~ $SYSDIG_KSPM_COLLECTOR_IMAGE_NAME ]]; then + SYSDIG_KSPM_COLLECTOR_APP_NAME=$APP_NAME + log_activity "Got kspmcollector application name: $SYSDIG_KSPM_COLLECTOR_APP_NAME" + fi +done <<< "${SYSDIG_DEPLOY_NAME}" + +[[ -n "${SYSDIG_AGENT_APP_NAME//[[:space:]]/}" ]] && export SYSDIG_AGENT_PREFIX="${SYSDIG_AGENT_APP_NAME}-[a-zA-Z0-9]{5}$" +[[ -n "${SYSDIG_CS_APP_NAME//[[:space:]]/}" ]] && export SYSDIG_CS_PREFIX="${SYSDIG_CS_APP_NAME}-[a-zA-Z0-9]" +[[ -n "${SYSDIG_NA_APP_NAME//[[:space:]]/}" ]] && export SYSDIG_NA_PREFIX="${SYSDIG_NA_APP_NAME}-[a-zA-Z0-9]" +[[ -n "${SYSDIG_KSPM_COLLECTOR_APP_NAME//[[:space:]]/}" ]] && export SYSDIG_KSPMC_PREFIX="${SYSDIG_KSPM_COLLECTOR_APP_NAME}-[a-zA-Z0-9]" + + printf "Init vars completed\n" log_activity "initVar completed." + + log_activity "Prefix for hostShield/agent $SYSDIG_AGENT_PREFIX" + log_activity "Prefix for clusterShield $SYSDIG_CS_PREFIX" + log_activity "Prefix for nodeAnalyzer $SYSDIG_NA_PREFIX" + log_activity "Prefix for kspmCollector $SYSDIG_KSPMC_PREFIX" } function disclaimer() @@ -89,8 +180,9 @@ function isAirgapped() { printf "The script use a curl command to upload the archive file created into your case\n" -printf "Please put y if your environment has restrictions on internet access or no internet access. \n Put n if your env do not have any kind of restrictions for internet access\n" +printf "Please put y if your environment has restrictions on internet access or no internet access, or if you just want to generate the archive. \n Put n if your env do not have any kind of restrictions for internet access, this will require the S3 bucket url provided by Sysdig support\n" read answer +log_activity "Selected $answer as response for internet restrictions" clear } @@ -98,57 +190,59 @@ clear function collectArtifacts() { log_activity "Starting collectArtifacts (namespace: ${namespace}, pod: ${podName:-ALL})" - if [ -z "${podName}" ]; then + if [ -z $podName ]; then printf "Getting all sysdig pods configuration, this could take a while\n" log_activity "Collecting cluster info (version output)." - $k8sCmd version -o json > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/cluster_info.json" + $k8sCmd version -o json > $DEST_DIR/$SYSDIG_SUPPORT_DIR/cluster_info.json log_activity "Collected cluster_info.json." - $k8sCmd get po --sort-by='.status.containerStatuses[0].restartCount' --no-headers -n "${namespace}" -o wide > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/running_pods.txt" + $k8sCmd get po --sort-by='.status.containerStatuses[0].restartCount' --no-headers -n $namespace -o wide > $DEST_DIR/$SYSDIG_SUPPORT_DIR/running_pods.txt log_activity "Saved running_pods.txt." if [[ "$k8sCmd" == "oc" ]]; then - $k8sCmd adm top pod -n "${namespace}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/top_pods.txt" + $k8sCmd adm top pod -n $namespace > $DEST_DIR/$SYSDIG_SUPPORT_DIR/top_pods.txt log_activity "Collected pod resource usage (oc mode)." else - $k8sCmd top pod -n "${namespace}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/top_pods.txt" || printf "Metrics server not installed or ready, moving forward\n" + $k8sCmd top pod -n $namespace > $DEST_DIR/$SYSDIG_SUPPORT_DIR/top_pods.txt || printf "Metrics server not installed or ready, moving forward\n" log_activity "Collected pod resource usage (kubectl mode)." fi - $k8sCmd describe po -n "${namespace}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/describe_pods.txt" - $k8sCmd get cm -o yaml -n "${namespace}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/configmap.txt" - $k8sCmd get ds -o yaml -n "${namespace}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/daemonset.txt" - $k8sCmd get deploy -o yaml -n "${namespace}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/deployment.txt" + $k8sCmd describe po -n $namespace > $DEST_DIR/$SYSDIG_SUPPORT_DIR/describe_pods.txt + $k8sCmd get cm -o yaml -n $namespace > $DEST_DIR/$SYSDIG_SUPPORT_DIR/configmap.txt + $k8sCmd get ds -o yaml -n $namespace > $DEST_DIR/$SYSDIG_SUPPORT_DIR/daemonset.txt + $k8sCmd get deploy -o yaml -n $namespace > $DEST_DIR/$SYSDIG_SUPPORT_DIR/deployment.txt log_activity "Saved configmap.txt, daemonset.txt, deployment.txt, describe_pods.txt" - $k8sCmd describe nodes > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/nodes.txt" + $k8sCmd describe nodes > $DEST_DIR/$SYSDIG_SUPPORT_DIR/nodes.txt log_activity "Saved nodes.txt." printf "Configuration collection completed for all Sysdig pods\n" log_activity "Configuration collection completed for all pods." else - printf "Getting the pod configuration for the pod ${podName}\n" - log_activity "Collecting cluster info for specific pod (${podName})." - $k8sCmd version -o json > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/cluster_info.json" + printf "Getting the pod configuration for the pod %s\n" "$podName" + $k8sCmd get po --sort-by='.status.containerStatuses[0].restartCount' --no-headers -n $namespace -o wide > $DEST_DIR/$SYSDIG_SUPPORT_DIR/running_pods.txt + log_activity "Saved running_pods.txt." + log_activity "Collecting cluster info for specific pod $podName" + $k8sCmd version -o json > $DEST_DIR/$SYSDIG_SUPPORT_DIR/cluster_info.json if [[ "$k8sCmd" == "oc" ]]; then - $k8sCmd adm top pod -n "${namespace}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/top_pods.txt" + $k8sCmd adm top pod -n $namespace > $DEST_DIR/$SYSDIG_SUPPORT_DIR/top_pods.txt log_activity "Collected pod resource usage (oc mode)." else - $k8sCmd top pod -n "${namespace}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/top_pods.txt" || printf "Metrics server not installed or ready, moving forward\n" + $k8sCmd top pod -n $namespace > $DEST_DIR/$SYSDIG_SUPPORT_DIR/top_pods.txt || printf "Metrics server not installed or ready, moving forward\n" log_activity "Collected pod resource usage (kubectl mode)." fi - $k8sCmd get po ${podName} -n "${namespace}" -o wide > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/${podName}_node.txt" + $k8sCmd get po $podName -n $namespace -o wide > $DEST_DIR/$SYSDIG_SUPPORT_DIR/${podName}_node.txt log_activity "Saved ${podName}_node.txt." - $k8sCmd describe po ${podName} -n "${namespace}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/describe_pods_${podName}.txt" + $k8sCmd describe po $podName -n $namespace > $DEST_DIR/$SYSDIG_SUPPORT_DIR/describe_pods_${podName}.txt log_activity "Saved describe_pods_${podName}.txt." - $k8sCmd get cm -o yaml -n "${namespace}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/configmap.txt" - $k8sCmd get ds -o yaml -n "${namespace}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/daemonset.txt" - $k8sCmd get deploy -o yaml -n "${namespace}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/deployment.txt" + $k8sCmd get cm -o yaml -n $namespace > $DEST_DIR/$SYSDIG_SUPPORT_DIR/configmap.txt + $k8sCmd get ds -o yaml -n $namespace > $DEST_DIR/$SYSDIG_SUPPORT_DIR/daemonset.txt + $k8sCmd get deploy -o yaml -n $namespace > $DEST_DIR/$SYSDIG_SUPPORT_DIR/deployment.txt log_activity "Saved configmap.txt, daemonset.txt, deployment.txt." - $k8sCmd describe nodes > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/nodes.txt" + $k8sCmd describe nodes > $DEST_DIR/$SYSDIG_SUPPORT_DIR/nodes.txt log_activity "Saved nodes.txt." - printf "Configuration collection completed for pod ${podName}\n" - log_activity "Configuration collection completed for pod ${podName}." + printf "Configuration collection completed for pod %s \n" "$podName" + log_activity "Configuration collection completed for pod $podName" fi printf "Collecting cluster object counts\n" @@ -158,160 +252,161 @@ function collectArtifacts() configmaps=$($k8sCmd get configmaps --all-namespaces --no-headers 2>/dev/null | wc -l) pods=$($k8sCmd get pods --all-namespaces --no-headers 2>/dev/null | wc -l) { - echo "Cluster Object Counts:" - echo "-----------------------" - echo "Deployments : $deployments" - echo "ReplicaSets : $replicasets" - echo "Namespaces : $namespaces" - echo "ConfigMaps : $configmaps" - echo "Pods : $pods" - } > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/cluster_object_counts.txt" + printf "Cluster Object Counts:\n" + printf -- "-----------------------\n" + printf "Deployments : $deployments\n" + printf "ReplicaSets : $replicasets\n" + printf "Namespaces : $namespaces\n" + printf "ConfigMaps : $configmaps\n" + printf "Pods : $pods" + } > $DEST_DIR/$SYSDIG_SUPPORT_DIR/cluster_object_counts.txt log_activity "Saved cluster_object_counts.txt with deployments:$deployments, replicasets:$replicasets, namespaces:$namespaces, configmaps:$configmaps, pods:$pods." - CS_POD_IP=`cat ${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/running_pods.txt|grep -E ${SYSDIG_CS_PREFIX}|head -1|awk '{print $6}'` + [ ! -z $SYSDIG_CS_APP_NAME ] && CS_POD_IP=`cat $DEST_DIR/$SYSDIG_SUPPORT_DIR/running_pods.txt|grep -E $SYSDIG_CS_PREFIX|head -1|awk '{print $6}'` || printf "ClusterShield is not running, or not available\n" log_activity "collectArtifacts completed." } function getLogs() { - log_activity "Starting getLogs (namespace: ${namespace}, pod: ${podName:-ALL})" + log_activity "Starting getLogs (namespace: $namespace, pod: ${podName:-ALL})" local csAttempt=0 local drAgentAttempt=0 - if [ -z "${podName}" ]; then + if [ -z $podName ]; then printf "Getting all sysdig logs, this could take a while\n" - for pod in $(awk '{print $1}' < "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/running_pods.txt"); do - printf "Getting log of pod ${pod}\n" - log_activity "Attempting log collection for pod ${pod}." - if [[ $pod != *"clustershield"* && $pod != *"node-analyzer"* && $pod != *"shield-cluster"* && $pod != *"kspmcollector"* && $pod =~ $SYSDIG_AGENT_PREFIX ]]; then - mkdir -p "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${pod}" - $k8sCmd -n "${namespace}" cp "$pod:${AGENT_LOG_DIR}." "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${pod}" 2>/dev/null - if [ $? -eq 0 ]; then - log_activity "Copied agent log files for pod ${pod}." + for pod in $(awk '{print $1}' < "$DEST_DIR/$SYSDIG_SUPPORT_DIR/running_pods.txt"); do + printf "Getting log of pod %s \n" "$pod" + log_activity "Attempting log collection for pod $pod" + if [[ -n "$SYSDIG_AGENT_PREFIX" ]] && [[ $pod =~ $SYSDIG_AGENT_PREFIX ]]; then + mkdir -p $DEST_DIR/$SYSDIG_SUPPORT_DIR/logs/$pod + $k8sCmd -n $namespace cp $pod:${AGENT_LOG_DIR}. $DEST_DIR/$SYSDIG_SUPPORT_DIR/logs/$pod --retries=$AGENT_CP_RETRY 2>/dev/null + if [[ $? -eq 0 ]] ; then + log_activity "Copied agent log files for pod $pod." else - log_activity "ERROR: Failed to copy logs for pod ${pod} (possibly recycled)." + log_activity "ERROR: Failed to copy logs for pod $pod (possibly recycled)." fi if [[ $CS_POD_IP != "" && $csAttempt -eq 0 ]]; then - log_activity "Tryng to perform curl against cluster shield health endpoint" - $k8sCmd exec $pod -n "${namespace}" -- curl http://${CS_POD_IP}:${SYSDIG_CS_MONITORING_PORT}/${SYSDIG_CS_ENDPOINT} > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/csFeaturesStatus.txt" 2>/dev/null || printf "Unable to call CS health endpoint, moving forward\n" - ((csAttempt++)) + log_activity "Tryng to perform curl against cluster shield health endpoint. If no error are reported, the call has been performed successfully" + $k8sCmd exec $pod -n $namespace -- curl "http://${CS_POD_IP}:${SYSDIG_CS_MONITORING_PORT}/${SYSDIG_CS_ENDPOINT}"> $DEST_DIR/$SYSDIG_SUPPORT_DIR/csFeaturesStatus.txt 2>/dev/null || log_activity "Unable to call CS health endpoint, moving forward" + ((csAttempt++)) fi if [[ $drAgentAttempt -eq 0 ]]; then - log_activity "Getting dragent.yaml from pod ${pod}" - $k8sCmd -n "${namespace}" cp "$pod:${AGENT_DRAGENT_DIR}/dragent.yaml" "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/dragent.yaml" 2>/dev/null - log_activity "Getting dragent.yaml from pod ${pod} completed!" + log_activity "Getting dragent.yaml from pod $pod" + $k8sCmd -n $namespace cp $pod:$AGENT_DRAGENT_DIR/dragent.yaml $DEST_DIR/$SYSDIG_SUPPORT_DIR/dragent.yaml 2>/dev/null + log_activity "Getting dragent.yaml from pod $pod completed!" ((drAgentAttempt++)) fi fi - if [[ $pod =~ $SYSDIG_CS_PREFIX || $pod =~ $SYSDIG_CS_SH_PREFIX ]]; then - mkdir -p "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${SYSDIG_CS_DIR}" - $k8sCmd -n "${namespace}" logs "$pod" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${SYSDIG_CS_DIR}/${pod}.log" 2>/dev/null - if [ $? -eq 0 ]; then - log_activity "Collected cluster shield log for pod ${pod}." + if [[ -n "$SYSDIG_CS_PREFIX" ]] && [[ $pod =~ $SYSDIG_CS_PREFIX ]]; then + mkdir -p $DEST_DIR/$SYSDIG_SUPPORT_DIR/logs/$SYSDIG_CS_DIR + $k8sCmd -n $namespace logs $pod > $DEST_DIR/$SYSDIG_SUPPORT_DIR/logs/$SYSDIG_CS_DIR/$pod.log 2>/dev/null + if [[ $? -eq 0 ]]; then + log_activity "Collected cluster shield log for pod $pod" else - log_activity "ERROR: Failed to collect cluster shield log for pod ${pod} (pod not found)." + log_activity "ERROR: Failed to collect cluster shield log for pod $pod (pod not found)." fi fi - if [[ $pod =~ $SYSDIG_NA_PREFIX ]]; then - mkdir -p "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs" - $k8sCmd -n "${namespace}" logs "${pod}" -c "${SYSDIG_KSPMA_CONTAINER_NAME}" > /dev/null 2>&1 && \ - $k8sCmd -n "${namespace}" logs "${pod}" -c "${SYSDIG_KSPMA_CONTAINER_NAME}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${pod}_${SYSDIG_KSPMA_CONTAINER_NAME}.log" && \ - log_activity "Collected kspm-analyzer logs for pod ${pod}." || \ - log_activity "kspm-analyzer not installed for pod ${pod}." - $k8sCmd -n "${namespace}" logs "${pod}" -c "${SYSDIG_HS_CONTAINER_NAME}" > /dev/null 2>&1 && \ - $k8sCmd -n "${namespace}" logs "${pod}" -c "${SYSDIG_HS_CONTAINER_NAME}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${pod}_${SYSDIG_HS_CONTAINER_NAME}.log" && \ - log_activity "Collected host-scanner logs for pod ${pod}." || \ - log_activity "host-scanner not installed for pod ${pod}." - $k8sCmd -n "${namespace}" logs "${pod}" -c "${SYSDIG_RS_CONTAINER_NAME}" > /dev/null 2>&1 && \ - $k8sCmd -n "${namespace}" logs "${pod}" -c "${SYSDIG_RS_CONTAINER_NAME}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${pod}_${SYSDIG_RS_CONTAINER_NAME}.log" && \ - log_activity "Collected runtime-scanner logs for pod ${pod}." || \ - log_activity "runtime-scanner not installed for pod ${pod}." + if [[ -n "$SYSDIG_NA_PREFIX" ]] && [[ $pod =~ $SYSDIG_NA_PREFIX ]]; then + mkdir -p $DEST_DIR/$SYSDIG_SUPPORT_DIR/logs/$pod + $k8sCmd -n $namespace logs $pod -c $SYSDIG_KSPMA_CONTAINER_NAME > /dev/null 2>&1 && \ + $k8sCmd -n $namespace logs $pod -c $SYSDIG_KSPMA_CONTAINER_NAME > $DEST_DIR/$SYSDIG_SUPPORT_DIR/logs/$pod/${pod}_${SYSDIG_KSPMA_CONTAINER_NAME}.log && \ + log_activity "Collected kspm-analyzer logs for pod $pod" || \ + log_activity "kspm-analyzer not installed for pod $pod" + $k8sCmd -n $namespace logs $pod -c $SYSDIG_HS_CONTAINER_NAME > /dev/null 2>&1 && \ + $k8sCmd -n $namespace logs $pod -c $SYSDIG_HS_CONTAINER_NAME > $DEST_DIR/$SYSDIG_SUPPORT_DIR/logs/$pod/${pod}_${SYSDIG_HS_CONTAINER_NAME}.log && \ + log_activity "Collected host-scanner logs for pod $pod" || \ + log_activity "host-scanner not installed for pod $pod" + $k8sCmd -n $namespace logs $pod -c $SYSDIG_RS_CONTAINER_NAME > /dev/null 2>&1 && \ + $k8sCmd -n $namespace logs $pod -c $SYSDIG_RS_CONTAINER_NAME > $DEST_DIR/$SYSDIG_SUPPORT_DIR/logs/$pod/${pod}_${SYSDIG_RS_CONTAINER_NAME}.log && \ + log_activity "Collected runtime-scanner logs for pod $pod" || \ + log_activity "runtime-scanner not installed for pod $pod" fi - if [[ $pod =~ $SYSDIG_KSPMC_PREFIX ]]; then - mkdir -p "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs" - $k8sCmd -n "${namespace}" logs "${pod}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${pod}.log" 2>/dev/null + if [[ -n "$SYSDIG_KSPMC_PREFIX" ]] && [[ $pod =~ $SYSDIG_KSPMC_PREFIX ]]; then + mkdir -p $DEST_DIR/$SYSDIG_SUPPORT_DIR/logs/$pod + $k8sCmd -n $namespace logs $pod > $DEST_DIR/$SYSDIG_SUPPORT_DIR/logs/$pod/$pod.log 2>/dev/null if [ $? -eq 0 ]; then - log_activity "Collected kspmcollector log for pod ${pod}." + log_activity "Collected kspmcollector log for pod $pod" else - log_activity "ERROR: Failed to collect kspmcollector log for pod ${pod} (pod not found)." + log_activity "ERROR: Failed to collect kspmcollector log for pod $pod (pod not found)." fi fi done log_activity "Log collection completed for all pods." else log_activity "Attempting log collection for pod ${podName}." - if [[ $podName != *"clustershield"* && $podName != *"node-analyzer"* && $podName != *"shield-cluster"* && $podName != *"kspmcollector"* && $podName =~ $SYSDIG_AGENT_PREFIX ]]; then - printf "Collecting log for pod ${podName}\n" - mkdir -p "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${podName}" - $k8sCmd -n "${namespace}" cp "${podName}:${AGENT_LOG_DIR}." "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${podName}" 2>/dev/null + if [[ $podName =~ $SYSDIG_AGENT_PREFIX ]]; then + printf "Collecting log for pod %s\n" "$podName" + mkdir -p $DEST_DIR/$SYSDIG_SUPPORT_DIR/logs/$podName + $k8sCmd -n $namespace cp $podName:${AGENT_LOG_DIR}. $DEST_DIR/$SYSDIG_SUPPORT_DIR/logs/$podName --retries=$AGENT_CP_RETRY 2>/dev/null if [ $? -eq 0 ]; then - printf "Log collected for pod ${podName}\n" - log_activity "Collected agent log for pod ${podName}." + printf "Log collected for pod %s\n" "$podName" + log_activity "Collected agent log for pod $podName " else - log_activity "ERROR: Failed to collect agent log for pod ${podName} (possibly recycled)." + log_activity "ERROR: Failed to collect agent log for pod $podName (possibly recycled)." fi + $k8sCmd -n $namespace cp $podName:$AGENT_DRAGENT_DIR/dragent.yaml $DEST_DIR/$SYSDIG_SUPPORT_DIR/dragent.yaml 2>/dev/null fi - if [[ $podName =~ $SYSDIG_CS_PREFIX || $podName =~ $SYSDIG_CS_SH_PREFIX ]]; then - printf "Collecting log for pod ${podName}\n" - mkdir -p "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${SYSDIG_CS_DIR}" - $k8sCmd -n "${namespace}" logs "${podName}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${SYSDIG_CS_DIR}/${podName}.log" 2>/dev/null + if [[ $podName =~ $SYSDIG_CS_PREFIX ]]; then + printf "Collecting log for pod %s\n" "$podName" + mkdir -p $DEST_DIR/$SYSDIG_SUPPORT_DIR/logs/$SYSDIG_CS_DIR + $k8sCmd -n $namespace logs $podName > $DEST_DIR/$SYSDIG_SUPPORT_DIR/logs/$SYSDIG_CS_DIR/$podName.log 2>/dev/null if [ $? -eq 0 ]; then - printf "Log collected for pod ${podName}\n" + printf "Log collected for pod %s\n" "$podName" log_activity "Collected cluster shield log for pod ${podName}." else log_activity "ERROR: Failed to collect cluster shield log for pod ${podName} (pod not found)." fi fi if [[ $podName =~ $SYSDIG_NA_PREFIX ]]; then - printf "Collecting log for pod ${podName}\n" - mkdir -p "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs" - $k8sCmd -n "${namespace}" logs "${podName}" -c "${SYSDIG_KSPMA_CONTAINER_NAME}" > /dev/null 2>&1 && \ - $k8sCmd -n "${namespace}" logs "${podName}" -c "${SYSDIG_KSPMA_CONTAINER_NAME}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${podName}_${SYSDIG_KSPMA_CONTAINER_NAME}.log" && \ - log_activity "Collected kspm-analyzer log for pod ${podName}." || \ - log_activity "kspm-analyzer not installed for pod ${podName}." - $k8sCmd -n "${namespace}" logs "${podName}" -c "${SYSDIG_HS_CONTAINER_NAME}" > /dev/null 2>&1 && \ - $k8sCmd -n "${namespace}" logs "${podName}" -c "${SYSDIG_HS_CONTAINER_NAME}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${podName}_${SYSDIG_HS_CONTAINER_NAME}.log" && \ - log_activity "Collected host-scanner log for pod ${podName}." || \ - log_activity "host-scanner not installed for pod ${podName}." - $k8sCmd -n "${namespace}" logs "${podName}" -c "${SYSDIG_RS_CONTAINER_NAME}" > /dev/null 2>&1 && \ - $k8sCmd -n "${namespace}" logs "${podName}" -c "${SYSDIG_RS_CONTAINER_NAME}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${podName}_${SYSDIG_RS_CONTAINER_NAME}.log" && \ - log_activity "Collected runtime-scanner log for pod ${podName}." || \ - log_activity "runtime-scanner not installed for pod ${podName}." - printf "Log collected for pod ${podName}\n" + printf "Collecting log for pod %s\n" "$podName" + mkdir -p $DEST_DIR/$SYSDIG_SUPPORT_DIR/logs/$podName + $k8sCmd -n $namespace logs $podName -c $SYSDIG_KSPMA_CONTAINER_NAME > /dev/null 2>&1 && \ + $k8sCmd -n $namespace logs $podName -c $SYSDIG_KSPMA_CONTAINER_NAME > $DEST_DIR/$SYSDIG_SUPPORT_DIR/logs/$podName/${podName}_$SYSDIG_KSPMA_CONTAINER_NAME.log && \ + log_activity "Collected kspm-analyzer log for pod $podName" || \ + log_activity "kspm-analyzer not installed for pod $podName" + $k8sCmd -n $namespace logs $podName -c $SYSDIG_HS_CONTAINER_NAME > /dev/null 2>&1 && \ + $k8sCmd -n $namespace logs $podName -c $SYSDIG_HS_CONTAINER_NAME > $DEST_DIR/$SYSDIG_SUPPORT_DIR/logs/$podName/${podName}_$SYSDIG_HS_CONTAINER_NAME.log && \ + log_activity "Collected host-scanner log for pod $podName" || \ + log_activity "host-scanner not installed for pod $podName" + $k8sCmd -n $namespace logs $podName -c $SYSDIG_RS_CONTAINER_NAME > /dev/null 2>&1 && \ + $k8sCmd -n $namespace logs $podName -c $SYSDIG_RS_CONTAINER_NAME > $DEST_DIR/$SYSDIG_SUPPORT_DIR/logs/$podName/${podName}_$SYSDIG_RS_CONTAINER_NAME.log && \ + log_activity "Collected runtime-scanner log for pod $podName" || \ + log_activity "runtime-scanner not installed for pod $podName" + printf "Log collected for pod %s\n" "$podName" fi if [[ $podName =~ $SYSDIG_KSPMC_PREFIX ]]; then - printf "Collecting log for pod ${podName}\n" - mkdir -p "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs" - $k8sCmd -n "${namespace}" logs "${podName}" > "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}/logs/${podName}.log" 2>/dev/null + printf "Collecting log for pod %s\n" "$podName" + mkdir -p $DEST_DIR/$SYSDIG_SUPPORT_DIR/logs/$podName + $k8sCmd -n $namespace logs $podName > $DEST_DIR/$SYSDIG_SUPPORT_DIR/logs/$podName/$podName.log 2>/dev/null if [ $? -eq 0 ]; then - printf "Log collected for pod ${podName}\n" - log_activity "Collected kspmcollector log for pod ${podName}." + printf "Log collected for pod %s\n" "$podName" + log_activity "Collected kspmcollector log for pod $podName" else - log_activity "ERROR: Failed to collect kspmcollector log for pod ${podName} (pod not found)." + log_activity "ERROR: Failed to collect kspmcollector log for pod $podName" fi fi - log_activity "Log collection completed for pod ${podName}." + log_activity "Log collection completed for pod $podName" fi log_activity "getLogs completed." } function compressAndUpload() { - cd "${DEST_DIR}/${SYSDIG_SUPPORT_DIR}" - printf "Creating archive file ${ARCHIVE_NAME}\n" - log_activity "Starting archive creation: ${ARCHIVE_NAME}." - errorMessage=$(tar czf "${ARCHIVE_NAME}" * 2>&1) + cd $DEST_DIR/$SYSDIG_SUPPORT_DIR + printf "Creating archive file %s\n" "$ARCHIVE_NAME" + log_activity "Starting archive creation: $ARCHIVE_NAME" + errorMessage=$(tar czf $ARCHIVE_NAME * 2>&1) if [ $? -eq 0 ]; then printf "Archive file created successfully, ready for upload!\n" - log_activity "Archive ${ARCHIVE_NAME} created successfully." + log_activity "Archive $ARCHIVE_NAME created successfully." else printf "Something went wrong\n" printf "%s\n" "$errorMessage" - log_activity "Failed to create archive (${ARCHIVE_NAME}): $errorMessage" - exit "${ERR_RC_TAR}" + log_activity "Failed to create archive $ARCHIVE_NAME : $errorMessage" + exit $ERR_RC_TAR fi if [ $answer == "y" ]; then - printf "The archive has been saved in the path ${DEST_DIR}/${SYSDIG_SUPPORT_DIR} , archive name is ${ARCHIVE_NAME}\n" + printf "The archive has been saved in the path $DEST_DIR/$SYSDIG_SUPPORT_DIR , archive name is $ARCHIVE_NAME\n" IS_AIRGAPPED="true" cleanArtifacts $IS_AIRGAPPED printf "Script execution completed, exit \n" @@ -320,10 +415,10 @@ if [ $answer == "y" ]; printf "Please put the S3 link provided by Sysdig Support, the script will upload the archive on the case.\n" read SYSDIG_UPLOAD_URL - log_activity "User provided S3 upload URL: ${SYSDIG_UPLOAD_URL}" + log_activity "User provided S3 upload URL: $SYSDIG_UPLOAD_URL" printf "The status of the upload will not be shown, please be patient\n" - log_activity "Uploading ${ARCHIVE_NAME} to S3 (${SYSDIG_UPLOAD_URL})..." + log_activity "Uploading $ARCHIVE_NAME to S3 $SYSDIG_UPLOAD_URL" httpRetCode=$(curl -s -S -o /dev/null -w "%{http_code}" -X PUT --url "${SYSDIG_UPLOAD_URL}" -H "Content-Disposition: attachment; filename=${ARCHIVE_NAME}" -T "${ARCHIVE_NAME}") if [ $httpRetCode -eq 200 ]; then printf "Archive file uploaded successfully!\n" @@ -332,7 +427,8 @@ if [ $answer == "y" ]; else printf "Something went wrong\n" log_activity "S3 upload failed with curl exit code $httpRetCode" - exit "${ERR_RC_CURL}" + printf "The archive has been saved in the path $DEST_DIR/$SYSDIG_SUPPORT_DIR" + exit $ERR_RC_CURL fi printf "Script execution completed!\n" @@ -346,20 +442,20 @@ function cleanArtifacts printf "Cleanup started\n" log_activity "Script Cleanup Started" -cd ${DEST_DIR}/${SYSDIG_SUPPORT_DIR} +cd $DEST_DIR/$SYSDIG_SUPPORT_DIR printf "Removing cluster_info.json file\n" -rm cluster_info.json || printf "File not found, or not enough privileges, moving forward\n" +rm -f cluster_info.json +printf "Removing dragent.yaml file\n" +rm -f dragent.yaml printf "Removing txt file\n" - for i in $(ls *.txt); do - printf "removing $i \n" - rm $i - done - if [ $IS_AIRGAPPED == "false" ]; - then - printf "Removing archive file $ARCHIVE_NAME\n" - rm $ARCHIVE_NAME - fi +rm -f *.txt + +if [ $IS_AIRGAPPED == "false" ]; + then + printf "Removing archive file $ARCHIVE_NAME \n" + rm $ARCHIVE_NAME +fi printf "Removing the logs directory\n" rm -fr logs @@ -374,4 +470,4 @@ disclaimer isAirgapped collectArtifacts getLogs -compressAndUpload +compressAndUpload \ No newline at end of file