#!/bin/bash
#
# Author: Raimund Sacherer (rsachere@redhat.com)
#
# Changes: 2025-03-20  V1:  Initial Version
#                      V2:  Removed `jq` as a requirement and made collecting log collections excludeable.
#                           Moved version checking to after parameter processing so --help does not need
#                           to wait for the version check to finish up.
#                      V3:  There is no tar, nor zip, nor cpio in the ODF Toolbox container, so if for some
#                           reason you need or prefer to run the data collection in the ODF toolbox, you
#                           have to `download` the collected data with the `--odf-download` parameter. We
#                           detect running inside an ODF toolbox.
#                      V4:  renamed --odf-download to --toolbox-download. Fixed some issues with downloads
#                           attaching `)` to the filename. Moved bash version check before creating the
#                           associative array.
#                      V5:  added `ceph versions` and `ceph fs status` to collected data.
#                      V6:  added `ceph crash info` loop and --no-crash parameter. Collected by default.
#                      V7:  added `--rbd-image-info` parameter which is *not* collected by default.
#                           added `ceph pg dump_stuck`
#          2025-07-29  V8:  added `--mon-sessions` parameter which is *not* collected by default.
#          2025-07-29  V9:  added `ceph osd info`
#          2025-09-16 V10:  added `rados df`
#                           added config log json export
#                           raised config log to 50000
#                           included mon-sessions by default
#          2025-10-17 V11:  fixed rados df collection
#                           fixed collection of RGW running configurations
#                           included RGW realm/zonegroup/zones/bucket stats and varios RGW stats data
#                           included the STDERR output of each command in a stderr.output file
#          2025-10-21 V12:  Fixed ERROR_FILE when run from within an ODF ceph toolbox container.
#          2025-11-28 V13:  Added --cluster parameter for clusters which have the name changed from default `ceph`.
#          2025-12-06 V14:  Added `ceph df` output
#                           Default to use the rooks operator, but have an override --odf-use-toolbox to use the
#                           ODF toolbox when it would be needed. Should help in cases the toolbox is not installed
#                           by default.
#          2026-05-15 V15:  Added ability to take dump_osd_network as well, --osd-dump-network and define a
#                           new threshold with --osd-dump-network-threshold=xxx
#          2026-06-04 V16:  Fixed 'date -Isec' incompatibility with MAC OS
#
# Please note that this is not to be treated as a Red Hat official binary / software,
# and feel free to go though the source code to look for what's happening behind the scenes.
#
#
# SPDX-License-Identifier: MIT-0
# MAINTAINER: rsachere@redhat.com
#
RH_VERSION=16
RH_KCS="https://access.redhat.com/solutions/7112212"

#
# START COMMON HELPER SCRIPTS

printf -v COLOR_RED '\e[0;31m'
printf -v COLOR_GREEN '\e[0;32m'
printf -v COLOR_CLEAR '\e[0m'

function print_disclaimer () {

	# Only print disclaimer when run from a shell (STDIN connected to a Terminal), do not print when run for example from inside a cronjob.
	if [ -t 0 ] ; then
		echo
		echo " *********************************************************************************************"
		echo "  Please note that this is ${COLOR_RED}not to be treated${COLOR_CLEAR} as a ${COLOR_RED}Red Hat${COLOR_CLEAR} official binary / software,         "
		echo "  and feel free to go through the source code to look for what's happening behind the scenes. "
		echo " *********************************************************************************************"
		echo
		if [ -n "${RH_VERSION}" ] ; then
			echo "${0} - Version: ${RH_VERSION}"
		else
			echo "${0}"
		fi
		echo
		if [ -n "${RH_KCS}" ] ; then
			echo "For details please see the KCS ${RH_KCS}"
		fi
		echo
	fi
}

function print_parameter_help () {
	#
	# Print automatically the parameter names and their comments from the Parameter Handling code.
	# ` NL ` in the comment splits it into multi lines, max of 3 lines, for readability.
	#
	# The idea is to not needing multiple edits in different places in the code, just modify
	# the parameter handling and have the help created automatically.
	#
	cat $0 | awk '/# PARAMETERS/,/# PARAMETERSOFF/ {
		param = "" ; value = "" ;
		if( $1 ~ /^-.*)/ ) {
			if($0 ~ /\|/) {
				if($0 ~/=/) {
					param = gensub(/\s(-[^=]*)=.*/, "\\1", 1)
					value = gensub(/-[^=]*=/, "", "g")
					value = "=" gensub(/^\s*/, "", 1, value)
				}
			}
			if(param == "") {
				param = gensub(/\s(-.*)/, "\\1", 1)
				value = ""
			}
			param = gensub(/\)/, "", "g", param)
			param = gensub(/^\s*/, "", "g", param)
			param = gensub(/\*/, "<VALUE>", "g", param)
			value = gensub(/\)/, "", "g", value)
			getline
			line = gensub(/\s*#/, "", 1)
			print param value "\t" line
		}
	}' | sed -e 's/^#.*//g' -e 's/\s*#//g' | awk -F' NL ' '{print $1"\n'$'\t''"$2; if ($3) { print "\n'$'\t''"$3 }}' | column -t -s $'\t'
}


function version_check () {

	# Only check for a version if STDIN is actually a terminal, e.g. do not check versions when started from inside a cron job for example
	if [ -t 0 ] ; then
		if [ ! -z "${RH_VERSION}" -a ! -z "${RH_KCS}" ] ; then
			printf "\r${COLOR_GREEN}Version check ...${COLOR_CLEAR}"
			# Add current timestamp to curl request, as sometimes sites are cached (even though headers forbid that).
			# Allo for max 3 seconds connection time and max 5 second overall time (secure/dark sites, slow connections)
			CURRENT_VERSION=$(curl "${RH_KCS}?$(date -Iseconds)" --connect-timeout 3 --max-time 5 --silent  | tr -d '\n' | grep -o '<h1 class="title">\(.*\)</h1>' | grep -o 'V[0-9]*')
			printf "\r                                                                             "

			if [ ! -z "${CURRENT_VERSION}" -a "${CURRENT_VERSION}" != "V${RH_VERSION}" ] ; then
				echo 
				echo "${COLOR_RED}! ATTENTION !${COLOR_CLEAR} This script is version V${RH_VERSION} but a new version ${CURRENT_VERSION} is available."
				echo "${COLOR_RED}! ATTENTION !${COLOR_CLEAR} Consider downloading the new version from ${COLOR_GREEN}${RH_KCS}${COLOR_CLEAR} before proceeding."
				echo
				read -n 1 -p "Press ${COLOR_RED}y${COLOR_CLEAR} to continue, ${COLOR_GREEN}n${COLOR_CLEAR} to abort > "
				echo

				if [ "${REPLY}" != "y" ] ; then
					exit
				fi
			fi
		fi
	fi
}


function bash_version_check () {
	AT_LEAST_VERSION=$1

	if [ ${BASH_VERSINFO[0]} -lt ${AT_LEAST_VERSION} ] ; then

		echo
		echo "${COLOR_RED}! ATTENTION !${COLOR_CLEAR} This script needs at least Bash version ${AT_LEAST_VERSION}."
		echo "${COLOR_RED}! ATTENTION !${COLOR_CLEAR} Your current version is ${BASH_VERSION}. Please consider upgrading or"
		echo "${COLOR_RED}! ATTENTION !${COLOR_CLEAR} run this script from another node with a newer bash version."
		echo
		exit 65
	fi
}


function inside_odf () {
	local INSIDE_ODF=0

	if [[ ${HOSTNAME} == rook-ceph-tools-* ]] ; then
	    INSIDE_ODF=1
	fi

	return $INSIDE_ODF
}


# END COMMON HELPER SCRIPTS
#

print_disclaimer

# Function to draw progress bar
progressBar () {
	if [ ${QUIET} -eq 0 ] ; then
		printf "\r%${COLUMNS}s" ""
		printf "\rStep: ${1}"
	fi
}


function tar_files () {
	local FILENAME=""
	local SIZE=0

	if [ ${NO_STDERR} -eq 1 ] ; then
		progressBar "Removing STDERR File"
		rm "${ERROR_FILE}"
		sleep 1
	fi

	if [ -e "${LOGPATH}" ] ; then
		FILENAME="${LOGPATH}.txz"
		progressBar "Taring collection"
		tar -c -J -f "${FILENAME}" "${LOGPATH}" 2> /dev/null
	fi
}


shopt -s checkwinsize; (:);


#
# Defaults
ODF=0
ODF_NS="openshift-storage"
ODF_USE_TOOLS_POD=0
ODF_CONFIG_FILE="/var/lib/rook/openshift-storage/openshift-storage.config"
OSD_DUMP_NETWORK=0
OSD_DUMP_NETWORK_THRESHOLD=1000
SUDO=""
KEEP=0
TOOLS_POD=""
CEPH_CLUSTER="ceph"
LOGPATH="./ceph_supportdata_$(date -Iminutes | sed -e 's/:/_/g' -e 's/+/_/g')"
ERROR_FILE="${LOGPATH}/stderr.output"
QUIET=0
PROGRAMS=""
INSIDE_ODF=0
ODF_DOWNLOAD=0
RUNNING_CONFIG=1
LOG_CLUSTER_LINES=100000
LOG_AUDIT_LINES=10000
LOG_CEPHADM_LINES=10000
COLLECT_CRASH=1
RBD_IMAGE_INFO=0
MON_SESSIONS=1
RGW_DATA=1
RGW_BUCKET_STATS=0
NO_STDERR=0

inside_odf
INSIDE_ODF=$?

if [ ${INSIDE_ODF} -eq 1 ] ; then
	LOGPATH="odf_data_collection"
	ERROR_FILE="${LOGPATH}/stderr.output"
fi

bash_version_check 4

typeset -A commands

#
# All possible ommands to be executed to collect the output:
commands=(
	[ceph_status]='status'
	[ceph_report]='report'
	[ceph_versions]='versions'
	[ceph_health_detail]='health detail'
	[ceph_log_cluster]='log last ${LOG_CLUSTER_LINES} --level debug --channel cluster'
	[ceph_log_audit]='log last ${LOG_AUDIT_LINES} --level debug --channel audit'
	[ceph_log_cephadm]='log last ${LOG_CEPHADM_LINES} --level debug --channel cephadm'
	[ceph_config_log]='config log 50000'
	[ceph_config_log_json]='config log 50000 --format json-pretty'
	[ceph_mgr_module_ls]='mgr module ls'
	[ceph_mgr_module_ls_json]='mgr module ls --format json-pretty'
	[ceph_osd_perf]='osd perf'
	[ceph_osd_perf_json]='osd perf --format json-pretty'
	[ceph_fs_status]='fs status'
	[ceph_fs_status_json]='fs status --format json-pretty'
	[ceph_crash_ls]='crash ls'
	[ceph_crash_ls_json]='crash ls --format json-pretty'
	[ceph_time_sync_status]='time-sync-status'
	[ceph_time_sync_status_json]='time-sync-status --format json-pretty'
	[ceph_config_key]='config-key dump'
	[ceph_config_key_json]='config-key dump --format json-pretty'
	[ceph_balancer_status]='balancer status'
	[ceph_balancer_status_json]='balancer status --format json-pretty'
	[ceph_balancer_ls]='balancer ls'
	[ceph_balancer_ls_json]='balancer ls --format json-pretty'
	[ceph_pg_dump]='pg dump'
	[ceph_pg_dump_json]='pg dump --format json-pretty'
	[ceph_pg_dump_stuck]='pg dump_stuck'
	[ceph_pg_dump_stuck_json]='pg dump_stuck --format json-pretty'
	[ceph_df]='df'
	[ceph_df_json]='df --format json-pretty'
	[ceph_df_detail]='df detail'
	[ceph_df_detail_json]='df detail --format json-pretty'
	[ceph_device_ls]='device ls'
	[ceph_device_ls_json]='device ls --format json-pretty'
	[ceph_osd_info]='osd info'
	[ceph_osd_info_json]='osd info --format json-pretty'
	[ceph_osd_df_tree]='osd df tree'
	[ceph_osd_df_tree_json]='osd df tree --format json-pretty'
	[ceph_orch_ps]='orch ps'
	[ceph_orch_ps_json]='orch ps --format json-pretty'
	[ceph_orch_ls]='orch ls'
	[ceph_orch_ls_export]='orch ls --export'
	[ceph_orch_ls_json]='orch ls --format json-pretty'
	[ceph_config_dump]='config dump'
	[ceph_config_dump_json]='config dump --format json-pretty'
	[ceph_orch_ls]='orch ls'
	[ceph_orch_device_ls]='orch device ls'
	[ceph_orch_device_ls_json]='orch device ls --format json-pretty'
	[ceph_orch_host_ls]='orch host ls'
	[ceph_orch_host_ls_json]='orch host ls --format json-pretty'
	[ceph_osd_dump]='osd dump'
	[ceph_osd_dump_json]='osd dump --format json-pretty'
	[ceph_osd_pool_ls_detail]='osd pool ls detail'
	[ceph_osd_pool_ls_detail_json]='osd pool ls detail --format json-pretty'
	[ceph_osd_pool_autoscale_status]='osd pool autoscale-status'
	[ceph_osd_pool_autoscale_status_json]='osd pool autoscale-status --format json-pretty'
	[ceph_healthcheck_history_ls]='healthcheck history ls'
	[ceph_healthcheck_history_ls_json]='healthcheck history ls --format json-pretty'
	[rados_df]='df'
	[rados_df_json]='df --format json-pretty'
)


for i in "$@" ; do
	case $i in # PARAMETERS

		--odf)
			#Run against an ODF cluster. The command `oc` must be in the path and be able to communicate with the Openshift cluster.
			ODF=1
			SUDO=""
			;;

		--toolbox-download)
			#When run from inside the toolbox container use this execution to get the data out of the toolbox. NL This should not be run from inside the toolbox container. The command `oc` must be in the path and be able to communicate with the Openshift cluster.
			ODF=1
			SUDO=""
			ODF_DOWNLOAD=1
			LOGPATH="odf_data_collection"
			;;

		--odf-use-toolbox)
			#Use the ODF Toolbox container instead of the ODF Rook Operator Container.
			ODF=1
			SUDO=""
			ODF_CONFIG_FILE="/etc/ceph/ceph.conf"
			ODF_USE_TOOLS_POD=1
			;;

		--odf-name-space=*)
			#Namespace for ODF, defaults to 'openshift-storage'.
			ODF_NS="${i#*=}"
			;;

		--rbd-image-info)
			#Get RBD image info from all images in all pools configured with the RBD Application. Not collected by default.
			RBD_IMAGE_INFO=1
			;;

		--osd_dump_network)
			#Get OSD Network Ping Times. Not collected by default.
			OSD_DUMP_NETWORK=1
			;;

		--osd_dump_network_threshold=*)
			#Adjust threshold for OSD Network Ping Times. Default 1000ms.
			OSD_DUMP_NETWORK_THRESHOLD="${i#*=}"
			;;

		--rgw-bucket-stats)
			#Do collect RGW bucket stats for all zones. Not collected by default.
			RGW_BUCKET_STATS=1
			;;

		--no-mon-sessions)
			#Do not collect MON Sessions from all available MONs.
			MON_SESSIONS=0
			;;

		--no-config)
			#Do not collect current running configurations for ceph services and daemons.
			RUNNING_CONFIG=0
			;;

		--no-crash)
			#Do not collect crash details
			COLLECT_CRASH=0
			;;

		--no-logs)
			#Do not collect any of the cluster, audit or cephadm or config logs.
			unset 'commands[ceph_log_cluster]'
			unset 'commands[ceph_log_audit]'
			unset 'commands[ceph_log_cephadm]'
			unset 'commands[ceph_config_log]'
			;;

		--no-cluster-log)
			#Do not collect the cluster log.
			unset 'commands[ceph_log_cluster]'
			;;

		--no-audit-log)
			#Do not collect the audit log.
			unset 'commands[ceph_log_audit]'
			;;

		--no-cephadm-log)
			#Do not collect the cephadm log.
			unset 'commands[ceph_log_cephadm]'
			;;

		--no-config-log)
			#Do not collect the ceph config log
			unset 'commands[ceph_config_log]'
			;;

		--no-rgw-data)
			#Do not collect RGW related data.
			RGW_DATA=0
			;;

		--no-stderr-output)
			#Do not collect STDERR output for executed commands.
			NO_STDERR=1
			;;

		--quiet)
			#Do not print the progressbar with status information.
			QUIET=1
			;;

		--keep)
			#Do not remove the created log folder after compressing.
			KEEP=1
			;;

		--sudo)
			#Add sudo in front of ceph commands.
			SUDO="sudo"
			;;

		--logpath=*)
			#Path where gathered data should be stored. NL The path will be created if it does not exist and will be removed unless --keep is provided. NL Make sure to have enough space available.
			LOGPATH="${i#*=}"
			ERROR_FILE="${LOGPATH}/stderr.output"
			;;

		--log_cluster_lines=*)
			#Amount of lines to try to get from the cluster log. 100.000 lines by default.
			LOG_CLUSTER_LINES="${i#*=}"
			;;

		--log_audit_lines=*)
			#Amount of lines to try to get from the audit log. 10.000 lines by default.
			LOG_AUDIT_LINES="${i#*=}"
			;;

		--log_cephadm_lines=*)
			#Amount of lines to try to get from the cephadm log. 10.000 lines by default.
			LOG_CEPHADM_LINES="${i#*=}"
			;;

		--cluster=*)
			#Name of the cluster, defaults to 'ceph'.
			CEPH_CLUSTER="${i#*=}"
			;;

		-h|--help)
			#Print this helpscreen.
			print_disclaimer
			print_parameter_help
			echo
			echo
			echo "Data collected by the script:"
			(for operation in "${!commands[@]}" ; do
					if [[ $operation == ceph* ]] ; then
						echo -e "\tceph ${commands[$operation]}"
					fi
					if [[ $operation == rados* ]] ; then
						echo -e "\trados ${commands[$operation]}"
					fi
			done) | sort

			shift
			exit 0
			;;

		*)
			echo

			echo "Command option \`${i}\` unknown." >&2
			echo
			${0} --help
			exit 66
			;;

	esac # PARAMETERSOFF
done

version_check

if [ "${SUDO}" == "sudo" ] ; then
	PROGRAMS="${PROGRAMS} sudo"
fi


if [ ${ODF} -eq 0 ] ; then
	PROGRAMS="${PROGRAMS} ceph"
fi


for program in ${PROGRAMS} ; do
	which ${program} > /dev/null 2>&1

	if [ ! $? -eq 0 ] ; then
		echo "Please install program `${program}`."
		exit 65
	fi
done

#
# If run with `--odf` we need oc in the past and executeable
if [ ${ODF} -eq 1 ] ; then
	which oc > /dev/null 2>&1

	if [ ! $? -eq 0 ] ; then
		echo "The program 'oc' can not be executed, please make sure it is in the path and you can run oc against the OCP cluster."
		exit 65
	fi

	oc whoami 1>/dev/null

	if [ ! $? -eq 0 ] ; then
		echo "Running 'oc' seems to have some issues, we can not comunicate with the OCP cluster."
		exit 66
	fi

	if [ ${ODF_USE_TOOLS_POD} -eq 1 ] ; then
		ODF_POD="$(oc get pods -n ${ODF_NS} -l app=rook-ceph-tools -o name)"
	else
		ODF_POD="$(oc get pods -n ${ODF_NS} -l app=rook-ceph-operator -o name)"
	fi
fi



send_command() {
	local ERROR_CHKSUM=""
	local EXIT_CODE=0
	local CONFIG=""

	ERROR_CHKSUM=$(sha256sum "${ERROR_FILE}" | awk '{print $1}')

	if [ ${ODF} -eq 0 ] ; then
		${SUDO} ${1} --cluster ${CEPH_CLUSTER} ${2} ${3} ${4} ${5} ${6} ${7} ${8} ${9} 2>>"${ERROR_FILE}"
		EXIT_CODE=$?
	else
		oc exec -n ${ODF_NS} ${ODF_POD} -iq -- ${1} --cluster ${CEPH_CLUSTER} -c ${ODF_CONFIG_FILE} ${2} ${3} ${4} ${5} ${6} ${7} ${8} ${9} 2>>"${ERROR_FILE}" </dev/null
		EXIT_CODE=$?
		CONFIG="-c ${ODF_CONFIG_FILE}"
	fi

	if [ "${ERROR_CHKSUM}" != "$(sha256sum "${ERROR_FILE}" | awk '{print $1}')" ] ; then
		>> "${ERROR_FILE}" echo
		>> "${ERROR_FILE}" echo "Above output occured at $(date -Iseconds) for command"
		>> "${ERROR_FILE}" echo "${SUDO} ${1} --cluster ${CEPH_CLUSTER} ${CONFIG} ${2} ${3} ${4} ${5} ${6} ${7} ${8} ${9}"
		>> "${ERROR_FILE}" echo "-------------------------------------------------------------"
		>> "${ERROR_FILE}" echo
	fi

	return $EXIT_CODE
}

ceph_command () {
	send_command ceph $@
}

rbd_command () {
	send_command rbd $@
}

rados_command () {
	send_command rados $@
}

rgw_command() {
	FILE="$1"
	shift

	if [ "${FILE}" == "STDOUT" ] ; then
		send_command radosgw-admin $@
	else
		send_command radosgw-admin $@ > "${FILE}"
		# --FIXME-- > implement sanitizing, + fix the above for ceph and rbd command as well, and move the STDOUT part to send_command
		# and then do sanitation generally for all generated files
	fi
}

if [ ! -d "${LOGPATH}" ] ; then
	mkdir -p "${LOGPATH}"
fi

call_command () {
	local command=""

	command=$(eval "echo ${commands[$operation]}")

	if [[ $operation == ceph* ]] ; then
		{ ceph_command ${command} ; } > "${LOGPATH}/$(echo "ceph ${command}" | sed -e 's/ /_/g')"
	fi

	if [[ $operation == rados* ]] ; then
		{ rados_command ${command} ; } > "${LOGPATH}/$(echo "rados ${command}" | sed -e 's/ /_/g')"
	fi
}

echo                                                                  >> "${ERROR_FILE}"
echo "Script Start at $(date -Iseconds)"                              >> "${ERROR_FILE}"
echo "-------------------------------------------------------------"  >> "${ERROR_FILE}"
echo                                                                  >> "${ERROR_FILE}"

if [ ${ODF_DOWNLOAD} -eq 0 ] ; then

	#
	# One time commands
	#{ ceph_command "tell ${MDS} config diff" ; } > "${LOGPATH}/config/mds_config_diff.txt"

	for operation in "${!commands[@]}" ; do
		progressBar "$operation"
		call_command
	done

	if [ ${RUNNING_CONFIG} -eq 1 ] ; then
		for type in mds mgr mon osd rgw ; do
			for service in $(ceph_command orch ps --daemon_type $type | grep -v NAME | awk '{ print $1 }') ; do
			progressBar "Get config for $service"

			if [[ ${service} == rgw* ]] ; then
				service="client.${service}"
			fi

			ceph_command config show-with-defaults $service --format json-pretty > "${LOGPATH}/$(echo "ceph config show-with-defaults ${service} --format json-pretty" | sed -e 's/ /_/g')"
			done
		done
	fi

	if [ ${COLLECT_CRASH} -eq 1 ] ; then
		mkdir -p "${LOGPATH}/crash_info"
		for crash_id in $(ceph_command crash ls | grep -vE "^ID" | awk '{ print $1}') ; do
			ceph_command crash info ${crash_id} > "${LOGPATH}/crash_info/${crash_id}.json"
		done
	fi

	if [ ${OSD_DUMP_NETWORK} -eq 1 ] ; then
		ACTIVE_MGR=$(ceph_command mgr stat | python3 -c "import sys, json; print(json.load(sys.stdin)['active_name'])")
		ceph_command tell mgr.${ACTIVE_MGR} dump_osd_network ${OSD_DUMP_NETWORK_THRESHOLD} > "${LOGPATH}/ceph_osd_dump_network_--format_json-pretty"
	fi

	if [ ${RBD_IMAGE_INFO} -eq 1 ] ; then
		for pool in $(ceph_command osd pool ls detail  | grep "application rbd" | awk '{print $3}' | sed -e "s/'//g") ; do
			progressBar "Get image ls for pool ${pool}"
			rbd_command --pool ${pool} ls > "${LOGPATH}/rbd_${pool}_ls"
			for image in $(rbd_command --pool ${pool} ls) ; do
				progressBar "Get image info for ${pool}/${image}"
				rbd_command --pool ${pool} info ${image} --format=json >> "${LOGPATH}/rbd_${pool}_image_info.json"
			done
		done
	fi

	if [ ${MON_SESSIONS} -eq 1 ] ; then
		for mon in $(ceph_command mon dump 2>/dev/null | grep -Eo "mon\.[^ ]*") ; do
			progressBar "Get MON Session for Mon ${mon}"
			ceph_command tell $mon sessions > "${LOGPATH}/${mon}.sessions.json"
		done
	fi

	if [ ${RGW_DATA} -eq 1 ] ; then
		for REALM in $(rgw_command STDOUT realm list | jq -r '.realms | @tsv') ; do
			progressBar "Get REALM ${REALM}"
			REALM_ID=$(rgw_command STDOUT realm get --rgw-realm=${REALM} | jq -r '.id')
			RGW_PATH="${LOGPATH}/rgw/realm_${REALM_ID}"
			mkdir -p "${RGW_PATH}"

			rgw_command "${RGW_PATH}/realm_get_${REALM_ID}.json" realm get --rgw-realm=${REALM}

			progressBar "Get User List for Realm ${REALM}"
			rgw_command "${RGW_PATH}/user_list.json" user list --rgw-realm=${REALM}

			progressBar "Get Error Lists for Realm ${REALM}"
			rgw_command "${RGW_PATH}/sync_error_list.json" sync error list --rgw-realm=${REALM}
			rgw_command "${RGW_PATH}/reshard_stale-instances_list.json" reshard stale-instances list --rgw-realm=${REALM}

			progressBar "Get Log Lists for Realm ${REALM}"
			rgw_command "${RGW_PATH}/datalog_list.json" datalog list --rgw-realm=${REALM}
			rgw_command "${RGW_PATH}/datalog_status.json" datalog status --rgw-realm=${REALM}
			rgw_command "${RGW_PATH}/mdlog_list.json" mdlog list --rgw-realm=${REALM}
			rgw_command "${RGW_PATH}/mdlg_status.json" mdlog status --rgw-realm=${REALM}
			rgw_command "${RGW_PATH}/log_list.json" log list --rgw-realm=${REALM}
			rgw_command "${RGW_PATH}/metadata_list.json" metadata list --rgw-realm=${REALM}
			rgw_command "${RGW_PATH}/gc_list.json" gc list --rgw-realm=${REALM}
			rgw_command "${RGW_PATH}/lc_list.json" lc list --rgw-realm=${REALM}

			progressBar "Get Periods ${REALM}"
			rgw_command "${RGW_PATH}/list_periods.json" realm list-periods --rgw-realm=${REALM}
			for PERIOD in $(rgw_command STDOUT period list | jq -r '.periods | @tsv') ; do
				progressBar "Get period ${PERIOD}"
				rgw_command "${RGW_PATH}/period_get_${PERIOD}.json" period get --rgw-realm=${REALM} --period=${PERIOD}
			done

			#
			# Is the zone list a listing per realm? I tried to get zone list for
			# all the differeent zone groups, thinking that then I only get zones for the set
			# zonegroup, but it seems it always shows all zones? Need to check that further
			rgw_command "${RGW_PATH}/zone_list.json" zone list --rgw-realm=${REALM}

			for ZONEGROUP in $(rgw_command STDOUT zonegroup list --rgw-realm=${REALM} | jq -r '.zonegroups | @tsv') ; do
				progressBar "Get zonegroup ${ZONEGROUP}"
				ZONEGROUP_ID=$(rgw_command STDOUT zonegroup get --rgw-realm=${REALM} --rgw-zonegroup=${ZONEGROUP} | jq -r '.id')
				rgw_command "${RGW_PATH}/zonegroup_get_${ZONEGROUP_ID}.json" zonegroup get --rgw-realm=${REALM} --rgw-zonegroup=${ZONEGROUP}

				# See above
				#rgw_command zone list --rgw-realm=${REALM} --rgw-zonegroup=${ZONEGROUP} > "${RGW_PATH}/zone_list_${ZONEGROUP_ID}.json"

				#for ZONE in $(cat "${RGW_PATH}/zone_list_${ZONEGROUP_ID}.json" | jq -r '.zones | @tsv') ; do
				#	progressBar "Get zone ${ZONE}"
				#	ZONE_ID=$(rgw_command zone get --rgw-realm=${REALM} --rgw-zonegroup=${ZONEGROUP} | jq -r '.id')
				#	rgw_command zone get --rgw-realm=${REALM} --rgw-zonegroup=${ZONEGROUP} --rgw-zone=${ZONE} > "${RGW_PATH}/zone_get_${ZONE_ID}.json"
				#done
			done

			# Seems that zone list is global, if not, review and get the data then from inside the zonegroup FOR if the zones are actually zonegroup dependent.
			for ZONE in $(cat "${RGW_PATH}/zone_list.json" | jq -r '.zones | @tsv') ; do
				progressBar "Get zone ${ZONE}"
				ZONE_ID=$(rgw_command STDOUT zone get --rgw-realm=${REALM} --rgw-zone=${ZONE} | jq -r '.id')
				rgw_command "${RGW_PATH}/zone_get_${ZONE_ID}.json" zone get --rgw-realm=${REALM} --rgw-zone=${ZONE}
				rgw_command "${RGW_PATH}/bucket_list_zone_${ZONE_ID}.json" bucket list --allow-unordered --rgw-realm=${REALM} --rgw-zone=${ZONE}

				if [ ${RGW_BUCKET_STATS} -eq 1 ] ; then
					mkdir -p "${RGW_PATH}/bucket_stats_zone_${ZONE_ID}"
					for BUCKET in $(cat "${RGW_PATH}/bucket_list_zone_${ZONE_ID}.json" | jq -r '@tsv') ; do
						progressBar "Get Bucket stats for ${ZONE}, Bucket ${BUCKET}"
						BUCKET_ID=$(rgw_command STDOUT bucket stats --rgw-realm=${REALM} --rgw-zone=${ZONE} --bucket=${BUCKET} | jq -r '.id')
						rgw_command "${RGW_PATH}/bucket_stats_zone_${ZONE_ID}/${BUCKET_ID}.json" bucket stats --rgw-realm=${REALM} --rgw-zone=${ZONE} --bucket=${BUCKET}

# --FIXME--
#						Not sure if necessary, think about incorporating it ...
#						if [ ${RGW_BUCKET_INDEX_LOG} -eq 1 ] ; then
#							mkdir -p "${RGW_PATH}/bucket_stats_zone_${ZONE_ID}"
#
#							rgw_command "${RGW_PATH}/bilog_list.json" bilog list --rgw-realm=${REALM}
#							rgw_command "${RGW_PATH}/bilog_status.json" bilog status --rgw-realm=${REALM}
#						fi

					done
				fi

			done
		done
	fi

else
	for ODF_FILE in $(oc exec -n "${ODF_NS}" "${TOOLS_POD}" -i -- ls "/tmp/${LOGPATH}") ; do
		progressBar "Download ${ODF_FILE}"
		oc exec -n ${ODF_NS} ${TOOLS_POD} -i -- sh -c "cat /tmp/${LOGPATH}/${ODF_FILE}" > "${LOGPATH}/${ODF_FILE}"
	done
fi


if [ ${INSIDE_ODF} -eq 0 ] ; then
	tar_files

	if [ ${KEEP} -eq 0 ] ; then
		# We remove each file and directory specifically. We do not use rm -rf which could be desastrous
		# with any form of bug introduced, better be safe then accidentaly removing the wrong data.
		progressBar "Removing temporary folder"
		rm "${LOGPATH}"/* 2>/dev/null
		for subdir in crash_info rgw; do
			if [ -e "${LOGPATH}/${subdir}" ] ; then
				find "${LOGPATH}/${subdir}" -delete
			fi
		done
		rmdir "${LOGPATH}"
	fi
fi

progressBar "${COLOR_GREEN}Finished${COLOR_CLEAR}"

echo
echo
if [ ${INSIDE_ODF} -eq 0 ] ; then
	echo "Please upload file ${LOGPATH}.txz to the case."
else
	echo "Execute '${0} --toolbox-download' from ${COLOR_RED}outside${COLOR_CLEAR} the toolbox on a node where you can execute 'oc'."
fi

exit 0
