#!/bin/bash
#
# cs_show_scores
#
# (c) 2018-2019 SUSE LLC
# GNU General Public License v2. No warranty.
# Author: L.Pinne
#
# Version: 2019-11-28
#
# (c) Apr 2009, Author: Dominik Klein
# Display scores of Linux-HA resources
#

if [ "$1" = "--help" ] || [ "$1" = "-h" ]
then
	echo "cs_show_scores - basically parsing \"crm resource scores\""
	echo "Usage: "
	echo "$0 (to display score information for all resources on all nodes sorted by resource name)"
	echo "$0 node (to display score information for all resources on all nodes sorted by nodename)"
	echo "$0 <resource-id> (to display score information for a specific resource on all nodes)"
	echo "$0 <resource-id> <nodename> (to display score information for a specific resource on a specific node)"
	echo "$0 <resource-id> <nodename> singlescore (to display just the score number (not additional info) for a specific resource on a specific node)"
	exit 0
fi

tmpfile=/tmp/dkshowscorestmpfiledk
tmpfile2=/tmp/dkshowscorestmpfile2dk


#if [ `crmadmin -D | cut -d' ' -f4` != `uname -n|tr "[:upper:]" "[:lower:]"` ] 
  #then echo "Warning: Script is not running on DC. This will be slow."
#fi

sortby=1
if [ "$1" = "node" ] 
then
	sortby=3
fi

default_stickiness=$(crm_attribute -G -n default-resource-stickiness -Q 2>/dev/null); export default_stickiness
default_migrationthreshold=$(crm_attribute -G -n migration-threshold -t rsc_defaults -Q 2>/dev/null); export default_migrationthreshold

if [ -n "$1" ] && [ "$1" != "node" ]
then
      resource=$1
fi
if [ -n "$2" ]
then
      nodename=$2
fi

#2>&1 ptest -Ls | grep -E "$resource" | grep -E "$nodename" > $tmpfile
crm resource scores | grep -E "$resource" | grep -E "$nodename" > $tmpfile

parseline() { 
	if ! echo "$@"|grep -q "promotion score"; then
		shift;
	fi
	res=$1; shift; shift; shift; shift; 
	# shellcheck disable=SC2001
	node=$(echo "$1"|sed 's/:$//'); shift;
	score=$1; 
}

get_stickiness() {
	res="$1"
	# get meta attribute resource_stickiness
	if ! stickiness=$(crm_resource -g resource-stickiness -r "$res" --meta -Q 2>/dev/null)
	then
		# if no resource-specific stickiness is confiugured, use the default value
		stickiness="$default_stickiness"
	fi

	# get meta attribute resource_failure_stickiness
	if ! migrationthreshold=$(crm_resource -g migration-threshold -r "$res" --meta -Q 2>/dev/null)
	then
		# if that doesnt exist, use the default value
		migrationthreshold="$default_migrationthreshold"
	fi	
}

get_failcount() { #usage $0 res node
        failcount=$(crm_failcount -G -r "$1" -U "$2" -Q 2>/dev/null|grep -o "^[0-9]*$")
}

#determine the longest resource name to adjust width of the first column
max_res_id_len=0
#for res_id in $(tail -n +2 $tmpfile | sed 's/^[a-zA-Z_-]*\:\ //' | cut -d " " -f 1 | sort | uniq); do
for res_id in $(sed 's/^[a-zA-Z_-]*\:\ //' $tmpfile | cut -d " " -f 1 | sort | uniq); do
	# shellcheck disable=SC2000
	res_id_len=$(echo "$res_id"|wc -c)
	[ "$res_id_len" -gt "$max_res_id_len" ] && export max_res_id_len=$res_id_len;
done

#same for nodenames
max_node_id_len=0
for node_id in $(sed 's/^[a-zA-Z_-]*\:\ //' $tmpfile | cut -d " " -f 5 | grep -v "^$" | sort | uniq | sed 's/\://'); do
	# shellcheck disable=SC2000
	node_id_len=$(echo "$node_id"|wc -c)
	[ "$node_id_len" -gt "$max_node_id_len" ] && export max_node_id_len=$node_id_len;
done

# we'll later add "_(master)" to master scores, so add 9 chars to max_res_id_len
max_res_id_len=$((max_res_id_len + 9))

# display allocation scores
grep native_color $tmpfile | while read -r line
do
	unset node res score stickiness failcount migrationthreshold
	# shellcheck disable=SC2086
	parseline $line
	get_stickiness "$res"
	get_failcount "$res" "$node"
	printf "%-${max_res_id_len}s%-10s%-${max_node_id_len}s%-11s%-9s%-16s\n" "$res" "$score" "$node" "$stickiness" "$failcount" "$migrationthreshold"
done >> $tmpfile2

# display promotion scores
grep "promotion score" $tmpfile | while read -r line
do
	unset node res score stickiness failcount migrationthreshold
	# shellcheck disable=SC2086
	parseline $line
	# Skip if node=none. Sometimes happens for clones but is internally mapped to another clone instance, so this is skipped
	[ "$node" = "none" ] && continue
	# shellcheck disable=SC2126
	inflines=$(grep "promotion score" $tmpfile | grep "$res" | grep 1000000 | wc -l)
	if [ "$inflines" -eq 1 ]
	then
		# [10:24] <beekhof> the non INFINITY values are the true ones
		# [10:25] <kleind> except for when the actually resulting score is [-]INFINITY
		# [10:25] <beekhof> yeah
		actualline=$(grep "promotion score" $tmpfile | grep "$res" | grep -v 1000000)
		# shellcheck disable=SC2086
		parseline $actualline
	fi
	get_stickiness "$res"
	get_failcount "$res" "$node"
	res=$res"_(master)"
	printf "%-${max_res_id_len}s%-10s%-${max_node_id_len}s%-11s%-9s%-16s\n" "$res" "$score" "$node" "$stickiness" "$failcount" "$migrationthreshold"
done | sort | uniq >> $tmpfile2

if [ "$3" = "singlescore" ]
then
	sed 's/  */ /g' $tmpfile2 | cut -d ' ' -f 2 | tail -n 1
else
	# Heading
	printf "%-${max_res_id_len}s%-10s%-${max_node_id_len}s%-11s%-9s%-16s\n" "Resource" "Score" "Node" "Stickiness" "#Fail" "Migration-Threshold"
	sort -k $sortby $tmpfile2
fi

rm $tmpfile $tmpfile2
#
