From 2008c8caf4f282280383197c3f215250e92b4bd6 Mon Sep 17 00:00:00 2001 From: William Hirigoyen Date: Tue, 26 Mar 2024 18:00:59 +0100 Subject: [PATCH] =?UTF-8?q?Am=C3=A9liorations=20diverses=20UI,=20message?= =?UTF-8?q?=20de=20d=C3=A9sactivation=20dans=20alerts=5Fwrapper,=20couleur?= =?UTF-8?q?s...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nagios-nrpe/files/alerts_switch | 37 +++++--- nagios-nrpe/files/alerts_wrapper | 6 +- nagios-nrpe/files/monitoringctl | 113 +++++++++++++++---------- nagios-nrpe/files/monitoringctl_common | 18 +++- nagios-nrpe/tasks/wrapper.yml | 2 +- 5 files changed, 118 insertions(+), 58 deletions(-) diff --git a/nagios-nrpe/files/alerts_switch b/nagios-nrpe/files/alerts_switch index d7e59346..7db8d7b6 100755 --- a/nagios-nrpe/files/alerts_switch +++ b/nagios-nrpe/files/alerts_switch @@ -21,36 +21,42 @@ function show_help() { cat <] - $PROGNAME enable +Usage: $PROGNAME disable [-d|--during ] [--message ''] + $PROGNAME enable [--message ''] $PROGNAME help -WRAPPER_NAME: The name given to '--name' option of 'alerts_wrapper'. -DURATION: Duration of alert disabling. - Can be '1d' for 1 day, '5m' for 5 minutes or more complex - expressions like '1w2d10m42s' (if no time unit is provided, - hour is assumed) - Default value: 1h +WRAPPER_NAME: The name given to '--name' option of 'alerts_wrapper'. +DURATION: Duration of alert disabling. + Can be '1d' for 1 day, '5m' for 5 minutes or more complex + expressions like '1w2d10m42s' (if no time unit is provided, + hour is assumed) + Default value: 1h +DISABLE_MESSAGE: Message that will be logged and printed by alerts_wrapper + when alert is disabled. +ENABLE_MESSAGE: Message that will be logged when alert is enabled END } function disable_alerts() { - # $1: wrapper name, $2: duration_sec + # $1: wrapper name, $2: duration_sec, $3: disable message now_secs=$(date +"%s") disable_until_secs=$(( now_secs + ${2} )) disable_file_path="$(get_disable_file_path "${1}")" echo "${disable_until_secs}" > "${disable_file_path}" + echo "$(logname || echo unknown): \"${3}\"" >> "${disable_file_path}" chmod 0644 "${disable_file_path}" log "${1} alerts disabled by $(logname || echo unknown)" + log "Disable message: ${3}" } function enable_alerts() { - # $1: wrapper name + # $1: wrapper name, $2: enable message disable_file_path="$(get_disable_file_path "${1}")" if [ -e "${disable_file_path}" ]; then rm "${disable_file_path}" fi log "${1} alerts enabled by $(logname || echo unknown)" + log "Enable message: ${2}" } function main() { @@ -62,7 +68,7 @@ function main() { enable_alerts "${wrapper}" done else - enable_alerts "${wrapper_name}" + enable_alerts "${wrapper_name}" "${message}" fi elif [ "${action}" == 'disable' ]; then duration_sec=$(time_to_seconds "${duration}") @@ -71,7 +77,7 @@ function main() { disable_alerts "${wrapper}" "${duration_sec}" done else - disable_alerts "${wrapper_name}" "${duration_sec}" + disable_alerts "${wrapper_name}" "${duration_sec}" "${message}" fi elif [ "${action}" == 'help' ]; then show_help @@ -95,6 +101,13 @@ while :; do error "Missing --during argument." fi shift; shift;; + -m|--message) + if [ "$#" -gt 1 ]; then + message="${2}" + else + error "Missing --message argument." + fi + shift; shift;; *) if [ -n "${1}" ]; then if is_wrapper "${1}" || [ "${1}" == "all" ]; then diff --git a/nagios-nrpe/files/alerts_wrapper b/nagios-nrpe/files/alerts_wrapper index e5391430..d326a329 100755 --- a/nagios-nrpe/files/alerts_wrapper +++ b/nagios-nrpe/files/alerts_wrapper @@ -65,7 +65,11 @@ function main() { enable_delay="$(enable_delay "${enable_time}")" delay_str="$(delay_to_string "${enable_delay}")" enable_date="$(date --date "+${enable_delay} seconds" "+%d %h %Y at %H:%M:%S")" - echo "ALERT DISABLED until ${enable_date} (${delay_str} left) - ${check_stdout}" + disable_msg="$(get_disable_message "${wrapper_name}")" + if [ -n "${disable_msg}" ]; then + disable_msg="- ${disable_msg} " + fi + echo "ALERT DISABLED until ${enable_date} (${delay_str} left) ${disable_msg}- Check output: ${check_stdout}" else echo "${check_stdout}" fi diff --git a/nagios-nrpe/files/monitoringctl b/nagios-nrpe/files/monitoringctl index 830ca83d..eae56e1d 100755 --- a/nagios-nrpe/files/monitoringctl +++ b/nagios-nrpe/files/monitoringctl @@ -42,7 +42,7 @@ ACTIONS: status [CHECK_NAME|all] Print whether alerts are enabled or not (silenced). - If alerts are disabled (silenced), show comment and time left before automatic re-enabling. + If alerts are disabled (silenced), show disable message and time left before automatic re-enabling. check [--bypass-nrpe] CHECK_NAME @@ -51,12 +51,12 @@ ACTIONS: -b, --bypass-nrpe Execute directly command from NRPE configuration, as user nagios, without passing the request to NRPE. - disable CHECK_NAME|all [--during DURATION] --comment 'COMMENT' + disable CHECK_NAME|all [--during DURATION] [--message 'DISABLE MESSAGE'] - Disable (silence) CHECK_NAME or all alerts for DURATION and write COMMENT into the log. + Disable (silence) CHECK_NAME or all alerts for DURATION and write DISABLE MESSAGE into the log. Checks output is still printed, so alerts history won't be lost. - enable CHECK_NAME|all --comment 'COMMENT' + enable CHECK_NAME|all [--message 'ENABLE MESSAGE'] Re-enable CHECK_NAME or all alerts @@ -64,9 +64,9 @@ ACTIONS: Show NPRE command(s) configured for CHECK_NAME -COMMENT: +MESSAGE: - Comment string to be written in log (mandatory). + Message to be written in log and disabled check output (mandatory, will be asked dynamically if not provided). DURATION: @@ -129,7 +129,7 @@ function check() { if [ -z "${1}" ] || [ "${1}" = "all" ]; then err_msg="Check command not found in NRPE configuration." else - err_mgs="Warning: no command found in NRPE configuration for check '${check}'. Aborted." + err_mgs="Error: no command found in NRPE configuration for check '${check}'. Aborted." fi fi fi @@ -137,8 +137,12 @@ function check() { check_output="$(${request_command})" rc="$?" check_output="$(echo "${check_output}" | tr '\n' ' ')" - if [ "${#check_output}" -gt 60 ]; then - check_output="$(echo "${check_output}" | cut -c-60) [...]" + if [ -z "${1}" ] || [ "${1}" = "all" ]; then + term_cols="$(tput cols)" + + if [ "${#check_output}" -gt 60 ]; then + check_output="$(echo "${check_output}" | cut -c-80) [...]" + fi fi else check_output="${err_msg}" @@ -166,6 +170,7 @@ function check() { rc_str="Unknown" color="${purple}" esac + if [ -z "${1}" ] || [ "${1}" = "all" ]; then str_out="${str_out}${color}${check}\t${rc_str}\t${check_output}${nocolor}\n" fi @@ -180,7 +185,7 @@ function check() { } function disable_alerts() { - # $1: check name, $2: comment + # $1: check name, $2: disable message if ! command -v alerts_switch &> /dev/null; then error "Error: script 'alerts_switch' is not installed. Aborted." fi @@ -191,11 +196,22 @@ function disable_alerts() { checks="${1}" fi + if [ -z "${2}" ]; then + echo -n "> Please provide a disable message (for logging and check output): " + read -r message + echo '' + if [ -z "${message}" ]; then + error "Error: disable message is mandatory." + fi + else + message="${2}" + fi + # Verify that checks to disable are wrapped unwrappeds="$(not_wrapped_checks)" unwrapped_checks="$(comm -12 <(echo "${checks}") <(echo "${unwrappeds}"))" if [ -n "${unwrapped_checks}" ]; then - >&2 printf "Warning: some checks have no alerts_wrapper, they will not be disabled:" + >&2 printf "${orange}Warning:${nocolor} some checks are not configured, they will not be disabled:" for unwrapped in ${unwrapped_checks}; do >&2 printf " %s" "${unwrapped}" done @@ -212,20 +228,27 @@ function disable_alerts() { else check_txt="Check ${1}" fi + main_msg="${check_txt} will be disabled for ${duration}${default_msg}." + main_msg_len="${#main_msg}" + line="$(printf '─%.0s' $(eval "echo {1.."${main_msg_len}"}"))" cat < Confirm (y/N)? " read -r answer if [ "${answer}" != "Y" ] && [ "${answer}" != "y" ]; then - echo "Canceled." && exit 0 + echo -e "${orange}Canceled.${nocolor}" && exit 0 fi log "Action disable ${1} requested for ${duration} by user $(logname || echo unknown)." - log "Comment: '${2}'" # Log a warning if a check has no wrapper if [ -n "${unwrapped_checks}" ]; then @@ -235,14 +258,13 @@ EOF done fi - log "Executing 'alerts_switch disable ${1} --during \"${duration}\"'" - alerts_switch disable "${1}" --during "${duration}" + alerts_switch disable "${1}" --during "${duration}" --message "${message}" - echo "${1} alerts are now disabled for ${duration}" + echo -e "${orange}Check ${1} alerts are now disabled for ${duration}${nocolor}" } function enable_alerts() { - # $1: wrapper name, $2: comment + # $1: wrapper name, $2: enable message if [ "${1}" != "all" ]; then is_disabled="$(is_disabled "${1}")" if [ "${is_disabled}" = "False" ]; then @@ -251,12 +273,21 @@ function enable_alerts() { fi fi - log "Action enable ${1} requested by user $(logname || echo unknown)." - log "Comment: '${2}'" - log "Executing 'alerts_switch enable ${1}'" - alerts_switch enable "${1}" + if [ -z "${2}" ]; then + echo -n "> Please provide an enable message (for logging): " + read -r message + echo '' + if [ -z "${message}" ]; then + error "Error: disable message is mandatory." + fi + else + message="${2}" + fi - echo "${1} alerts are now enabled." + log "Action enable ${1} requested by user $(logname || echo unknown)." + alerts_switch enable "${1}" --message "${message}" + + echo -e "${green}Check ${1} alerts are now enabled.${nocolor}" } # Show NRPE command(s) configured for a check @@ -286,15 +317,16 @@ function alerts_status() { checks="${1}" fi - header="Check\tStatus\tRe-enable time" - underline="-----\t------\t--------------" + header="Check\tStatus\tRe-enable time\tDisable message" + underline="-----\t------\t--------------\t---------------" str_out="${header}\n${underline}\n" for check in $checks; do enable_str="" status_str="Enabled" + disable_msg="" if ! is_wrapped "${check}"; then - status_str="Not wrapped" + status_str="Not configured" else is_disabled="$(is_disabled "${check}")" if [ "${is_disabled}" = "True" ]; then @@ -304,6 +336,7 @@ function alerts_status() { delay_str="$(delay_to_string "${enable_delay}")" enable_date="$(date --date "+${enable_delay} seconds" "+%d %h %Y at %H:%M:%S")" enable_str="${enable_date} (${delay_str} left)" + disable_msg="$(get_disable_message "${check}")" fi fi case "${status_str}" in @@ -316,7 +349,7 @@ function alerts_status() { *) color="${red}" esac - str_out="${str_out}${color}${check}\t${status_str}\t${enable_str}${nocolor}\n" + str_out="${str_out}${color}${check}\t${status_str}\t${enable_str}${nocolor}\t${disable_msg}\n" done echo -e "${str_out}" | column -t -s $'\t' @@ -339,7 +372,7 @@ fi # Default arguments and options action="" -comment="" +message="" duration="${default_disabled_time}" bypass_nrpe="False" default_duration="True" @@ -370,11 +403,11 @@ while :; do fi default_duration="False" shift; shift;; - -c|--comment) + -m|--message) if [ "$#" -lt 2 ]; then - usage_error "Option --comment: missing comment string." + usage_error "Option --message: missing message string." fi - comment="${2}" + message="${2}" shift; shift;; status|check|enable|disable|show) action="${1}" @@ -404,7 +437,7 @@ while :; do check_name="${1}" else if is_check "${1}"; then - error "Error: check '${1}' has no alerts_wrapper, it cannot be disabled. Aborted." + error "Error: check '${1}' is not configured, it cannot be disabled. Aborted." else # We use the word "check" for the end user, # but this is actually "unknown wrapper" @@ -433,12 +466,6 @@ case "${action}" in ;; esac -if [ "${action}" = "enable" ] || [ "${action}" = "disable" ]; then - if [ -z "${comment}" ]; then - usage_error "Action ${action}: missing --comment argument." - fi -fi - if [ ! "${action}" = "disable" ]; then if [ "${default_duration}" = "False" ]; then usage_error "Action ${action}: there is no --during option." @@ -456,10 +483,10 @@ case "${action}" in show_check_commands "${check_name}" ;; enable) - enable_alerts "${check_name}" "${comment}" + enable_alerts "${check_name}" "${message}" ;; disable) - disable_alerts "${check_name}" "${comment}" + disable_alerts "${check_name}" "${message}" ;; esac diff --git a/nagios-nrpe/files/monitoringctl_common b/nagios-nrpe/files/monitoringctl_common index 65f42ec5..544e8af4 100644 --- a/nagios-nrpe/files/monitoringctl_common +++ b/nagios-nrpe/files/monitoringctl_common @@ -75,7 +75,11 @@ function time_to_seconds() { function get_enable_time() { # $1: wrapper name disable_file_path="$(get_disable_file_path "${1}")" - enable_secs="$(grep -v -E "^\s*#" "${disable_file_path}" | grep -E "^[0-9]+$" | head -n1 | awk '{print $1}')" + if [ ! -e "${disable_file_path}" ]; then + return + fi + + enable_secs="$(grep -v -E "^\s*#" "${disable_file_path}" | sed '/^$/d' | head -n1 | awk '/^[0-9]+$/ {print $1}')" # If file is empty, use file last change date plus default disabled time if [ -z "${enable_secs}" ]; then file_last_change_secs="$(stat -c %Z "${disable_file_path}")" @@ -85,6 +89,18 @@ function get_enable_time() { echo "${enable_secs}" } +# Print disable message +function get_disable_message() { + # $1: wrapper name + disable_file_path="$(get_disable_file_path "${1}")" + if [ ! -e "${disable_file_path}" ]; then + return + fi + + disable_msg="$(sed '/^$/d' "${disable_file_path}" | tail -n+2 | tr '\n' ' ' | awk '{$1=$1;print}')" + echo "${disable_msg}" +} + function now_secs() { date +"%s" } diff --git a/nagios-nrpe/tasks/wrapper.yml b/nagios-nrpe/tasks/wrapper.yml index 781325f2..90a05e96 100644 --- a/nagios-nrpe/tasks/wrapper.yml +++ b/nagios-nrpe/tasks/wrapper.yml @@ -71,7 +71,7 @@ dest: /usr/local/sbin/monitoringctl owner: root group: root - mode: "0750" + mode: "0755" force: true - name: "copy monitoringctl_common lib"