summaryrefslogtreecommitdiffstats
path: root/health
diff options
context:
space:
mode:
authorPaweł Krupa <pawel@krupa.net.pl>2019-02-12 11:45:03 +0100
committerGitHub <noreply@github.com>2019-02-12 11:45:03 +0100
commit1509e497018fef3e3c4bc8e1afdbd33eada0fcdf (patch)
tree0bdaf69fa618e4b872c9ca40e746634f92141139 /health
parent8f6970f8a2ddce62206c41b656683135eaf5b642 (diff)
Lint alarm notify (#5164)
* manually lint alarm-notify.sh code * run automatic bash formatter (shfmt) * bring back unused variable
Diffstat (limited to 'health')
-rwxr-xr-xhealth/notifications/alarm-notify.sh.in2356
1 files changed, 1134 insertions, 1222 deletions
diff --git a/health/notifications/alarm-notify.sh.in b/health/notifications/alarm-notify.sh.in
index dd3cda9178..04c0d2e06e 100755
--- a/health/notifications/alarm-notify.sh.in
+++ b/health/notifications/alarm-notify.sh.in
@@ -1,4 +1,5 @@
#!/usr/bin/env bash
+#shellcheck source=/dev/null disable=SC2086,SC2154
# netdata
# real-time performance and health monitoring, done right!
@@ -35,40 +36,36 @@
# -----------------------------------------------------------------------------
# testing notifications
-
-if [ \( "${1}" = "test" -o "${2}" = "test" \) -a "${#}" -le 2 ]
-then
- if [ "${2}" = "test" ]
- then
- recipient="${1}"
- else
- recipient="${2}"
- fi
-
- [ -z "${recipient}" ] && recipient="sysadmin"
-
- id=1
- last="CLEAR"
- test_res=0
- for x in "WARNING" "CRITICAL" "CLEAR"
- do
- echo >&2
- echo >&2 "# SENDING TEST ${x} ALARM TO ROLE: ${recipient}"
-
- "${0}" "${recipient}" "$(hostname)" 1 1 "${id}" "$(date +%s)" "test_alarm" "test.chart" "test.family" "${x}" "${last}" 100 90 "${0}" 1 $((0 + id)) "units" "this is a test alarm to verify notifications work" "new value" "old value" "evaluated expression" "expression variable values" 0 0
- if [ $? -ne 0 ]
- then
- echo >&2 "# FAILED"
- test_res=1
- else
- echo >&2 "# OK"
- fi
-
- last="${x}"
- id=$((id + 1))
- done
-
- exit $test_res
+if { [ "${1}" = "test" ] || [ "${2}" = "test" ]; } && [ "${#}" -le 2 ]; then
+ if [ "${2}" = "test" ]; then
+ recipient="${1}"
+ else
+ recipient="${2}"
+ fi
+
+ [ -z "${recipient}" ] && recipient="sysadmin"
+
+ id=1
+ last="CLEAR"
+ test_res=0
+ for x in "WARNING" "CRITICAL" "CLEAR"; do
+ echo >&2
+ echo >&2 "# SENDING TEST ${x} ALARM TO ROLE: ${recipient}"
+
+ "${0}" "${recipient}" "$(hostname)" 1 1 "${id}" "$(date +%s)" "test_alarm" "test.chart" "test.family" "${x}" "${last}" 100 90 "${0}" 1 $((0 + id)) "units" "this is a test alarm to verify notifications work" "new value" "old value" "evaluated expression" "expression variable values" 0 0
+ #shellcheck disable=SC2181
+ if [ $? -ne 0 ]; then
+ echo >&2 "# FAILED"
+ test_res=1
+ else
+ echo >&2 "# OK"
+ fi
+
+ last="${x}"
+ id=$((id + 1))
+ done
+
+ exit $test_res
fi
export PATH="${PATH}:/sbin:/usr/sbin:/usr/local/sbin"
@@ -79,68 +76,67 @@ export LC_ALL=C
PROGRAM_NAME="$(basename "${0}")"
logdate() {
- date "+%Y-%m-%d %H:%M:%S"
+ date "+%Y-%m-%d %H:%M:%S"
}
log() {
- local status="${1}"
- shift
+ local status="${1}"
+ shift
- echo >&2 "$(logdate): ${PROGRAM_NAME}: ${status}: ${*}"
+ echo >&2 "$(logdate): ${PROGRAM_NAME}: ${status}: ${*}"
}
warning() {
- log WARNING "${@}"
+ log WARNING "${@}"
}
error() {
- log ERROR "${@}"
+ log ERROR "${@}"
}
info() {
- log INFO "${@}"
+ log INFO "${@}"
}
fatal() {
- log FATAL "${@}"
- exit 1
+ log FATAL "${@}"
+ exit 1
}
debug=${NETDATA_ALARM_NOTIFY_DEBUG-0}
debug() {
- [ "${debug}" = "1" ] && log DEBUG "${@}"
+ [ "${debug}" = "1" ] && log DEBUG "${@}"
}
docurl() {
- if [ -z "${curl}" ]
- then
- error "\${curl} is unset."
- return 1
- fi
-
- if [ "${debug}" = "1" ]
- then
- echo >&2 "--- BEGIN curl command ---"
- printf >&2 "%q " ${curl} "${@}"
- echo >&2
- echo >&2 "--- END curl command ---"
-
- local out=$(mktemp /tmp/netdata-health-alarm-notify-XXXXXXXX)
- local code=$(${curl} ${curl_options} --write-out %{http_code} --output "${out}" --silent --show-error "${@}")
- local ret=$?
- echo >&2 "--- BEGIN received response ---"
- cat >&2 "${out}"
- echo >&2
- echo >&2 "--- END received response ---"
- echo >&2 "RECEIVED HTTP RESPONSE CODE: ${code}"
- rm "${out}"
- echo "${code}"
- return ${ret}
- fi
-
- ${curl} ${curl_options} --write-out %{http_code} --output /dev/null --silent --show-error "${@}"
- return $?
+ if [ -z "${curl}" ]; then
+ error '${curl} is unset.'
+ return 1
+ fi
+
+ if [ "${debug}" = "1" ]; then
+ echo >&2 "--- BEGIN curl command ---"
+ printf >&2 "%q " ${curl} "${@}"
+ echo >&2
+ echo >&2 "--- END curl command ---"
+
+ local out code ret
+ out=$(mktemp /tmp/netdata-health-alarm-notify-XXXXXXXX)
+ code=$(${curl} ${curl_options} --write-out "%{http_code}" --output "${out}" --silent --show-error "${@}")
+ ret=$?
+ echo >&2 "--- BEGIN received response ---"
+ cat >&2 "${out}"
+ echo >&2
+ echo >&2 "--- END received response ---"
+ echo >&2 "RECEIVED HTTP RESPONSE CODE: ${code}"
+ rm "${out}"
+ echo "${code}"
+ return ${ret}
+ fi
+
+ ${curl} ${curl_options} --write-out "%{http_code}" --output /dev/null --silent --show-error "${@}"
+ return $?
}
# -----------------------------------------------------------------------------
@@ -166,94 +162,92 @@ custom
msteam
kavenegar
prowl
+awssns
"
# -----------------------------------------------------------------------------
# this is to be overwritten by the config file
custom_sender() {
- info "not sending custom notification for ${status} of '${host}.${chart}.${name}'"
+ info "not sending custom notification for ${status} of '${host}.${chart}.${name}'"
}
-
# -----------------------------------------------------------------------------
# check for BASH v4+ (required for associative arrays)
-[ $(( ${BASH_VERSINFO[0]} )) -lt 4 ] && \
- fatal "BASH version 4 or later is required (this is ${BASH_VERSION})."
+if [ ${BASH_VERSINFO[0]} -lt 4 ]; then
+ fatal "BASH version 4 or later is required (this is ${BASH_VERSION})."
+fi
# -----------------------------------------------------------------------------
# defaults to allow running this script by hand
-[ -z "${NETDATA_USER_CONFIG_DIR}" ] && NETDATA_USER_CONFIG_DIR="@configdir_POST@"
+[ -z "${NETDATA_USER_CONFIG_DIR}" ] && NETDATA_USER_CONFIG_DIR="@configdir_POST@"
[ -z "${NETDATA_STOCK_CONFIG_DIR}" ] && NETDATA_STOCK_CONFIG_DIR="@libconfigdir_POST@"
-[ -z "${NETDATA_CACHE_DIR}" ] && NETDATA_CACHE_DIR="@cachedir_POST@"
-[ -z "${NETDATA_REGISTRY_URL}" ] && NETDATA_REGISTRY_URL="https://registry.my-netdata.io"
+[ -z "${NETDATA_CACHE_DIR}" ] && NETDATA_CACHE_DIR="@cachedir_POST@"
+[ -z "${NETDATA_REGISTRY_URL}" ] && NETDATA_REGISTRY_URL="https://registry.my-netdata.io"
# -----------------------------------------------------------------------------
# parse command line parameters
-if [ ${1} = "unittest" ] ; then
- unittest=1 # enable unit testing mode
- roles="${2}" # the role that should be used for unit testing
- cfgfile="${3}" # the location of the config file to use for unit testing
- status="${4}" # the current status : REMOVED, UNINITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL
- old_status="${5}" # the previous status: REMOVED, UNINITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL
+if [ ${1} = "unittest" ]; then
+ unittest=1 # enable unit testing mode
+ roles="${2}" # the role that should be used for unit testing
+ cfgfile="${3}" # the location of the config file to use for unit testing
+ status="${4}" # the current status : REMOVED, UNINITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL
+ old_status="${5}" # the previous status: REMOVED, UNINITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL
else
- roles="${1}" # the roles that should be notified for this event
- args_host="${2}" # the host generated this event
- unique_id="${3}" # the unique id of this event
- alarm_id="${4}" # the unique id of the alarm that generated this event
- event_id="${5}" # the incremental id of the event, for this alarm id
- when="${6}" # the timestamp this event occurred
- name="${7}" # the name of the alarm, as given in netdata health.d entries
- chart="${8}" # the name of the chart (type.id)
- family="${9}" # the family of the chart
- status="${10}" # the current status : REMOVED, UNINITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL
- old_status="${11}" # the previous status: REMOVED, UNINITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL
- value="${12}" # the current value of the alarm
- old_value="${13}" # the previous value of the alarm
- src="${14}" # the line number and file the alarm has been configured
- duration="${15}" # the duration in seconds of the previous alarm state
- non_clear_duration="${16}" # the total duration in seconds this is/was non-clear
- units="${17}" # the units of the value
- info="${18}" # a short description of the alarm
- value_string="${19}" # friendly value (with units)
- old_value_string="${20}" # friendly old value (with units)
- calc_expression="${21}" # contains the expression that was evaluated to trigger the alarm
- calc_param_values="${22}" # the values of the parameters in the expression, at the time of the evaluation
- total_warnings="${23}" # Total number of alarms in WARNING state
- total_critical="${24}" # Total number of alarms in CRITICAL state
+ roles="${1}" # the roles that should be notified for this event
+ args_host="${2}" # the host generated this event
+ unique_id="${3}" # the unique id of this event
+ alarm_id="${4}" # the unique id of the alarm that generated this event
+ event_id="${5}" # the incremental id of the event, for this alarm id
+ when="${6}" # the timestamp this event occurred
+ name="${7}" # the name of the alarm, as given in netdata health.d entries
+ chart="${8}" # the name of the chart (type.id)
+ family="${9}" # the family of the chart
+ status="${10}" # the current status : REMOVED, UNINITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL
+ old_status="${11}" # the previous status: REMOVED, UNINITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL
+ value="${12}" # the current value of the alarm
+ old_value="${13}" # the previous value of the alarm
+ src="${14}" # the line number and file the alarm has been configured
+ duration="${15}" # the duration in seconds of the previous alarm state
+ non_clear_duration="${16}" # the total duration in seconds this is/was non-clear
+ units="${17}" # the units of the value
+ info="${18}" # a short description of the alarm
+ value_string="${19}" # friendly value (with units)
+ # shellcheck disable=SC2034 variable is unused, but https://github.com/netdata/netdata/pull/5164#discussion_r255572947
+ old_value_string="${20}" # friendly old value (with units), previously named "old_value_string"
+ calc_expression="${21}" # contains the expression that was evaluated to trigger the alarm
+ calc_param_values="${22}" # the values of the parameters in the expression, at the time of the evaluation
+ total_warnings="${23}" # Total number of alarms in WARNING state
+ total_critical="${24}" # Total number of alarms in CRITICAL state
fi
-
# -----------------------------------------------------------------------------
# find a suitable hostname to use, if netdata did not supply a hostname
-if [ -z ${args_host} ]
- then
- this_host=$(hostname -s 2>/dev/null)
- host="${this_host}"
- args_host="${this_host}"
+if [ -z ${args_host} ]; then
+ this_host=$(hostname -s 2>/dev/null)
+ host="${this_host}"
+ args_host="${this_host}"
else
- host="${args_host}"
+ host="${args_host}"
fi
# -----------------------------------------------------------------------------
# screen statuses we don't need to send a notification
# don't do anything if this is not WARNING, CRITICAL or CLEAR
-if [ "${status}" != "WARNING" -a "${status}" != "CRITICAL" -a "${status}" != "CLEAR" ]
-then
- info "not sending notification for ${status} of '${host}.${chart}.${name}'"
- exit 1
+if [ "${status}" != "WARNING" ] && [ "${status}" != "CRITICAL" ] && [ "${status}" != "CLEAR" ]; then
+ info "not sending notification for ${status} of '${host}.${chart}.${name}'"
+ exit 1
fi
# don't do anything if this is CLEAR, but it was not WARNING or CRITICAL
-if [ "${clear_alarm_always}" != "YES" -a "${old_status}" != "WARNING" -a "${old_status}" != "CRITICAL" -a "${status}" = "CLEAR" ]
-then
- info "not sending notification for ${status} of '${host}.${chart}.${name}' (last status was ${old_status})"
- exit 1
+if [ "${clear_alarm_always}" != "YES" ] && [ "${old_status}" != "WARNING" ] && [ "${old_status}" != "CRITICAL" ] && [ "${status}" = "CLEAR" ]; then
+ info "not sending notification for ${status} of '${host}.${chart}.${name}' (last status was ${old_status})"
+ exit 1
fi
# -----------------------------------------------------------------------------
@@ -277,13 +271,13 @@ curl=
sendmail=
# enable / disable features
-for method_name in ${method_names^^} ; do
- declare SEND_${method_name}="YES"
- declare DEFAULT_RECIPIENT_${method_name}
+for method_name in ${method_names^^}; do
+ declare SEND_${method_name}="YES"
+ declare DEFAULT_RECIPIENT_${method_name}
done
-for method_name in ${method_names} ; do
- declare -A role_recipients_${method_name}
+for method_name in ${method_names}; do
+ declare -A role_recipients_${method_name}
done
# slack configs
@@ -344,9 +338,7 @@ PD_SERVICE_KEY=
FLEEP_SENDER="${host}"
# Amazon SNS configs
-DEFAULT_RECIPIENT_AWSSNS=
AWSSNS_MESSAGE_FORMAT=
-declare -A role_recipients_awssns=()
# syslog configs
SYSLOG_FACILITY=
@@ -355,7 +347,6 @@ SYSLOG_FACILITY=
EMAIL_SENDER=
EMAIL_CHARSET=$(locale charmap 2>/dev/null)
EMAIL_THREADING=
-DEFAULT_RECIPIENT_EMAIL="root"
# irc configs
IRC_NICKNAME=
@@ -365,95 +356,88 @@ IRC_NETWORK=
# load the stock and user configuration files
# these will overwrite the variables above
-if [ ${unittest} ] ;
- then
- source "${cfgfile}"
- [ $? -ne 0 ] && error "Failed to load requested config file." && exit 1
+if [ ${unittest} ]; then
+ if source "${cfgfile}"; then
+ error "Failed to load requested config file."
+ exit 1
+ fi
else
- for CONFIG in "${NETDATA_STOCK_CONFIG_DIR}/health_alarm_notify.conf" "${NETDATA_USER_CONFIG_DIR}/health_alarm_notify.conf"
- do
- if [ -f "${CONFIG}" ]
- then
- debug "Loading config file '${CONFIG}'..."
- source "${CONFIG}"
- [ $? -ne 0 ] && error "Failed to load config file '${CONFIG}'."
- else
- warning "Cannot find file '${CONFIG}'."
- fi
- done
+ for CONFIG in "${NETDATA_STOCK_CONFIG_DIR}/health_alarm_notify.conf" "${NETDATA_USER_CONFIG_DIR}/health_alarm_notify.conf"; do
+ if [ -f "${CONFIG}" ]; then
+ debug "Loading config file '${CONFIG}'..."
+ source "${CONFIG}" || error "Failed to load config file '${CONFIG}'."
+ else
+ warning "Cannot find file '${CONFIG}'."
+ fi
+ done
fi
# If we didn't autodetect the character set for e-mail and it wasn't
# set by the user, we need to set it to a reasonable default. UTF-8
# should be correct for almost all modern UNIX systems.
-if [ -z ${EMAIL_CHARSET} ]
- then
- EMAIL_CHARSET="UTF-8"
+if [ -z ${EMAIL_CHARSET} ]; then
+ EMAIL_CHARSET="UTF-8"
fi
# If we've been asked to use FQDN's for the URL's in the alarm, do so,
# unless we're sending an alarm for a slave system which we can't get the
# FQDN of easily.
-if [ "${use_fqdn}" = "YES" -a "${host}" = "$(hostname -s 2>/dev/null)" ]
- then
- host="$(hostname -f 2>/dev/null)"
+if [ "${use_fqdn}" = "YES" ] && [ "${host}" = "$(hostname -s 2>/dev/null)" ]; then
+ host="$(hostname -f 2>/dev/null)"
fi
# -----------------------------------------------------------------------------
# filter a recipient based on alarm event severity
filter_recipient_by_criticality() {
- local method="${1}" x="${2}" r s
- shift
-
- r="${x/|*/}" # the recipient
- s="${x/*|/}" # the severity required for notifying this recipient
-
- # no severity filtering for this person
- [ "${r}" = "${s}" ] && return 0
-
- # the severity is invalid
- s="${s^^}"
- if [ "${s}" != "CRITICAL" ]
- then
- error "SEVERITY FILTERING for ${x} VIA ${method}: invalid severity '${s,,}', only 'critical' is supported."
- return 0
- fi
-
- # create the status tracking directory for this user
- [ ! -d "${NETDATA_CACHE_DIR}/alarm-notify/${method}/${r}" ] && \
- mkdir -p "${NETDATA_CACHE_DIR}/alarm-notify/${method}/${r}"
-
- case "${status}" in
- CRITICAL)
- # make sure he will get future notifications for this alarm too
- touch "${NETDATA_CACHE_DIR}/alarm-notify/${method}/${r}/${alarm_id}"
- debug "SEVERITY FILTERING for ${x} VIA ${method}: ALLOW: the alarm is CRITICAL (will now receive next status change)"
- return 0
- ;;
-
- WARNING)
- if [ -f "${NETDATA_CACHE_DIR}/alarm-notify/${method}/${r}/${alarm_id}" ]
- then
- # we do not remove the file, so that he will get future notifications of this alarm
- debug "SEVERITY FILTERING for ${x} VIA ${method}: ALLOW: recipient has been notified for this alarm in the past (will still receive next status change)"
- return 0
- fi
- ;;
-
- *)
- if [ -f "${NETDATA_CACHE_DIR}/alarm-notify/${method}/${r}/${alarm_id}" ]
- then
- # remove the file, so that he will only receive notifications for CRITICAL states for this alarm
- rm "${NETDATA_CACHE_DIR}/alarm-notify/${method}/${r}/${alarm_id}"
- debug "SEVERITY FILTERING for ${x} VIA ${method}: ALLOW: recipient has been notified for this alarm (will only receive CRITICAL notifications from now on)"
- return 0
- fi
- ;;
- esac
-
- debug "SEVERITY FILTERING for ${x} VIA ${method}: BLOCK: recipient should not receive this notification"
- return 1
+ local method="${1}" x="${2}" r s
+ shift
+
+ r="${x/|*/}" # the recipient
+ s="${x/*|/}" # the severity required for notifying this recipient
+
+ # no severity filtering for this person
+ [ "${r}" = "${s}" ] && return 0
+
+ # the severity is invalid
+ s="${s^^}"
+ if [ "${s}" != "CRITICAL" ]; then
+ error "SEVERITY FILTERING for ${x} VIA ${method}: invalid severity '${s,,}', only 'critical' is supported."
+ return 0
+ fi
+
+ # create the status tracking directory for this user
+ [ ! -d "${NETDATA_CACHE_DIR}/alarm-notify/${method}/${r}" ] &&
+ mkdir -p "${NETDATA_CACHE_DIR}/alarm-notify/${method}/${r}"
+
+ case "${status}" in
+ CRITICAL)
+ # make sure he will get future notifications for this alarm too
+ touch "${NETDATA_CACHE_DIR}/alarm-notify/${method}/${r}/${alarm_id}"
+ debug "SEVERITY FILTERING for ${x} VIA ${method}: ALLOW: the alarm is CRITICAL (will now receive next status change)"
+ return 0
+ ;;
+
+ WARNING)
+ if [ -f "${NETDATA_CACHE_DIR}/alarm-notify/${method}/${r}/${alarm_id}" ]; then
+ # we do not remove the file, so that he will get future notifications of this alarm
+ debug "SEVERITY FILTERING for ${x} VIA ${method}: ALLOW: recipient has been notified for this alarm in the past (will still receive next status change)"
+ return 0
+ fi
+ ;;
+
+ *)
+ if [ -f "${NETDATA_CACHE_DIR}/alarm-notify/${method}/${r}/${alarm_id}" ]; then
+ # remove the file, so that he will only receive notifications for CRITICAL states for this alarm
+ rm "${NETDATA_CACHE_DIR}/alarm-notify/${method}/${r}/${alarm_id}"
+ debug "SEVERITY FILTERING for ${x} VIA ${method}: ALLOW: recipient has been notified for this alarm (will only receive CRITICAL notifications from now on)"
+ return 0
+ fi
+ ;;
+ esac
+
+ debug "SEVERITY FILTERING for ${x} VIA ${method}: BLOCK: recipient should not receive this notification"
+ return 1
}
# -----------------------------------------------------------------------------
@@ -481,107 +465,100 @@ filter_recipient_by_criticality() {
[ -z "${PUSHBULLET_ACCESS_TOKEN}" ] && SEND_PUSHBULLET="NO"
# check twilio
-[ -z "${TWILIO_ACCOUNT_TOKEN}" -o -z "${TWILIO_ACCOUNT_SID}" -o -z "${TWILIO_NUMBER}" ] && SEND_TWILIO="NO"
+{ [ -z "${TWILIO_ACCOUNT_TOKEN}" ] || [ -z "${TWILIO_ACCOUNT_SID}" ] || [ -z "${TWILIO_NUMBER}" ]; } && SEND_TWILIO="NO"
# check hipchat
[ -z "${HIPCHAT_AUTH_TOKEN}" ] && SEND_HIPCHAT="NO"
# check messagebird
-[ -z "${MESSAGEBIRD_ACCESS_KEY}" -o -z "${MESSAGEBIRD_NUMBER}" ] && SEND_MESSAGEBIRD="NO"
+{ [ -z "${MESSAGEBIRD_ACCESS_KEY}" ] || [ -z "${MESSAGEBIRD_NUMBER}" ]; } && SEND_MESSAGEBIRD="NO"
# check kavenegar
-[ -z "${KAVENEGAR_API_KEY}" -o -z "${KAVENEGAR_SENDER}" ] && SEND_KAVENEGAR="NO"
+{ [ -z "${KAVENEGAR_API_KEY}" ] || [ -z "${KAVENEGAR_SENDER}" ]; } && SEND_KAVENEGAR="NO"
# check telegram
[ -z "${TELEGRAM_BOT_TOKEN}" ] && SEND_TELEGRAM="NO"
# check kafka
-[ -z "${KAFKA_URL}" -o -z "${KAFKA_SENDER_IP}" ] && SEND_KAFKA="NO"
+{ [ -z "${KAFKA_URL}" ] || [ -z "${KAFKA_SENDER_IP}" ]; } && SEND_KAFKA="NO"
# check irc
[ -z "${IRC_NETWORK}" ] && SEND_IRC="NO"
# check fleep
-[ -z "${FLEEP_SERVER}" -o -z "${FLEEP_SENDER}" ] && SEND_FLEEP="NO"
-
-# if we need curl, check for the curl command
-if [ \( \
- "${SEND_PUSHOVER}" = "YES" \
- -o "${SEND_SLACK}" = "YES" \
- -o "${SEND_ROCKETCHAT}" = "YES" \
- -o "${SEND_ALERTA}" = "YES" \
- -o "${SEND_PD}" = "YES" \
- -o "${SEND_FLOCK}" = "YES" \
- -o "${SEND_DISCORD}" = "YES" \
- -o "${SEND_HIPCHAT}" = "YES" \
- -o "${SEND_TWILIO}" = "YES" \
- -o "${SEND_MESSAGEBIRD}" = "YES" \
- -o "${SEND_KAVENEGAR}" = "YES" \
- -o "${SEND_TELEGRAM}" = "YES" \
- -o "${SEND_PUSHBULLET}" = "YES" \
- -o "${SEND_KAFKA}" = "YES" \
- -o "${SEND_FLEEP}" = "YES" \
- -o "${SEND_PROWL}" = "YES" \
- -o "${SEND_CUSTOM}" = "YES" \
- -o "${SEND_MSTEAM}" = "YES" \
- \) -a -z "${curl}" ]
- then
- curl="$(which curl 2>/dev/null || command -v curl 2>/dev/null)"
- if [ -z "${curl}" ]
- then
- error "Cannot find curl command in the system path. Disabling all curl based notifications."
- SEND_PUSHOVER="NO"
- SEND_PUSHBULLET="NO"
- SEND_TELEGRAM="NO"
- SEND_SLACK="NO"
- SEND_MSTEAM="NO"
- SEND_ROCKETCHAT="NO"
- SEND_ALERTA="NO"
- SEND_PD="NO"
- SEND_FLOCK="NO"
- SEND_DISCORD="NO"
- SEND_TWILIO="NO"
- SEND_HIPCHAT="NO"
- SEND_MESSAGEBIRD="NO"
- SEND_KAVENEGAR="NO"
- SEND_KAFKA="NO"
- SEND_FLEEP="NO"
- SEND_PROWL="NO"
- SEND_CUSTOM="NO"
- fi
+#shellcheck disable=SC2153
+{ [ -z "${FLEEP_SERVER}" ] || [ -z "${FLEEP_SENDER}" ]; } && SEND_FLEEP="NO"
+
+if [ "${SEND_PUSHOVER}" = "YES" ] ||
+ [ "${SEND_SLACK}" = "YES" ] ||
+ [ "${SEND_ROCKETCHAT}" = "YES" ] ||
+ [ "${SEND_ALERTA}" = "YES" ] ||
+ [ "${SEND_PD}" = "YES" ] ||
+ [ "${SEND_FLOCK}" = "YES" ] ||
+ [ "${SEND_DISCORD}" = "YES" ] ||
+ [ "${SEND_HIPCHAT}" = "YES" ] ||
+ [ "${SEND_TWILIO}" = "YES" ] ||
+ [ "${SEND_MESSAGEBIRD}" = "YES" ] ||
+ [ "${SEND_KAVENEGAR}" = "YES" ] ||
+ [ "${SEND_TELEGRAM}" = "YES" ] ||
+ [ "${SEND_PUSHBULLET}" = "YES" ] ||
+ [ "${SEND_KAFKA}" = "YES" ] ||
+ [ "${SEND_FLEEP}" = "YES" ] ||
+ [ "${SEND_PROWL}" = "YES" ] ||
+ [ "${SEND_CUSTOM}" = "YES" ] ||
+ [ "${SEND_MSTEAM}" = "YES" ]; then
+ # if we need curl, check for the curl command
+ if [ -z "${curl}" ]; then
+ curl="$(command -v curl 2>/dev/null)"
+ fi
+ if [ -z "${curl}" ]; then
+ error "Cannot find curl command in the system path. Disabling all curl based notifications."
+ SEND_PUSHOVER="NO"
+ SEND_PUSHBULLET="NO"
+ SEND_TELEGRAM="NO"
+ SEND_SLACK="NO"
+ SEND_MSTEAM="NO"
+ SEND_ROCKETCHAT="NO"
+ SEND_ALERTA="NO"
+ SEND_PD="NO"
+ SEND_FLOCK="NO"
+ SEND_DISCORD="NO"
+ SEND_TWILIO="NO"
+ SEND_HIPCHAT="NO"
+ SEND_MESSAGEBIRD="NO"
+ SEND_KAVENEGAR="NO"
+ SEND_KAFKA="NO"
+ SEND_FLEEP="NO"
+ SEND_PROWL="NO"
+ SEND_CUSTOM="NO"
+ fi
fi
# if we need sendmail, check for the sendmail command
-if [ "${SEND_EMAIL}" = "YES" -a -z "${sendmail}" ]
- then
- sendmail="$(which sendmail 2>/dev/null || command -v sendmail 2>/dev/null)"
- if [ -z "${sendmail}" ]
- then
- debug "Cannot find sendmail command in the system path. Disabling email notifications."
- SEND_EMAIL="NO"
- fi
+if [ "${SEND_EMAIL}" = "YES" ] && [ -z "${sendmail}" ]; then
+ sendmail="$(command -v sendmail 2>/dev/null)"
+ if [ -z "${sendmail}" ]; then
+ debug "Cannot find sendmail command in the system path. Disabling email notifications."
+ SEND_EMAIL="NO"
+ fi
fi
# if we need logger, check for the logger command
-if [ "${SEND_SYSLOG}" = "YES" -a -z "${logger}" ]
- then
- logger="$(which logger 2>/dev/null || command -v logger 2>/dev/null)"
- if [ -z "${logger}" ]
- then
- debug "Cannot find logger command in the system path. Disabling syslog notifications."
- SEND_SYSLOG="NO"
- fi
+if [ "${SEND_SYSLOG}" = "YES" ] && [ -z "${logger}" ]; then
+ logger="$(command -v logger 2>/dev/null)"
+ if [ -z "${logger}" ]; then
+ debug "Cannot find logger command in the system path. Disabling syslog notifications."
+ SEND_SYSLOG="NO"
+ fi
fi
# if we need aws, check for the aws command
-if [ "${SEND_AWSSNS}" = "YES" -a -z "${aws}" ]
- then
- aws="$(which aws 2>/dev/null || command -v aws 2>/dev/null)"
- if [ -z "${aws}" ]
- then
- debug "Cannot find aws command in the system path. Disabling Amazon SNS notifications."
- SEND_AWSSNS="NO"
- fi
+if [ "${SEND_AWSSNS}" = "YES" ] && [ -z "${aws}" ]; then
+ aws="$(command -v aws 2>/dev/null)"
+ if [ -z "${aws}" ]; then
+ debug "Cannot find aws command in the system path. Disabling Amazon SNS notifications."
+ SEND_AWSSNS="NO"
+ fi
fi
# -----------------------------------------------------------------------------
@@ -589,47 +566,48 @@ fi
# netdata may call us with multiple roles, and roles may have multiple but
# overlapping recipients - so, here we find the unique recipients.
-for method_name in ${method_names} ; do
- send_var="SEND_${method_name^^}"
- if [ ${!send_var} = "NO" ] ; then
- continue
- fi
-
- declare -A arr_var=()
-
- for x in ${roles//,/ } ; do
- # the roles 'silent' and 'disabled' mean:
- # don't send a notification for this role
- [ "${x}" = "silent" -o "${x}" = "disabled" ] && continue
-
- role_recipients="role_recipients_${method_name}[$x]"
- default_recipient_var="DEFAULT_RECIPIENT_${method_name^^}"
-
- a="${!role_recipients}"
- [ -z "${a}" ] && a="${!default_recipient_var}"
- for r in ${a//,/ } ; do
- [ "${r}" != "disabled" ] && filter_recipient_by_criticality ${method_name} "${r}" && arr_var[${r/|*/}]="1"
- done
- done
-
- # build the list of recipients
- to_var="to_${method_name}"
- declare to_${method_name}="${!arr_var[*]}"
-
- [ -z "${!to_var}" ] && declare ${send_var}="NO"
+for method_name in ${method_names}; do
+ send_var="SEND_${method_name^^}"
+ if [ "${!send_var}" = "NO" ]; then
+ continue
+ fi
+
+ declare -A arr_var=()
+
+ for x in ${roles//,/ }; do
+ # the roles 'silent' and 'disabled' mean:
+ # don't send a notification for this role
+ if [ "${x}" = "silent" ] || [ "${x}" = "disabled" ]; then
+ continue
+ fi
+
+ role_recipients="role_recipients_${method_name}[$x]"
+ default_recipient_var="DEFAULT_RECIPIENT_${method_name^^}"
+
+ a="${!role_recipients}"
+ [ -z "${a}" ] && a="${!default_recipient_var}"
+ for r in ${a//,/ }; do
+ [ "${r}" != "disabled" ] && filter_recipient_by_criticality ${method_name} "${r}" && arr_var[${r/|*/}]="1"
+ done
+ done
+
+ # build the list of recipients
+ to_var="to_${method_name}"
+ declare to_${method_name}="${!arr_var[*]}"
+
+ [ -z "${!to_var}" ] && declare ${send_var}="NO"
done
# -----------------------------------------------------------------------------
# handle fixup of the email recipient list.
fix_to_email() {
- to_email=
- while [ ! -z "${1}" ]
- do
- [ ! -z "${to_email}" ] && to_email="${to_email}, "
- to_email="${to_email}${1}"
- shift 1
- done
+ to_email=
+ while [ -n "${1}" ]; do
+ [ -n "${to_email}" ] && to_email="${to_email}, "
+ to_email="${to_email}${1}"
+ shift 1
+ done
}
# ${to_email} without quotes here
@@ -637,41 +615,45 @@ fix_to_email ${to_email}
# -----------------------------------------------------------------------------
# handle output if we're running in unit test mode
-if [ ${unittest} ] ; then
- for method_name in ${method_names} ; do
- to_var="to_${method_name}"
- echo "results: ${method_name}: ${!to_var}"
- done
- exit 0
+if [ ${unittest} ]; then
+ for method_name in ${method_names}; do
+ to_var="to_${method_name}"
+ echo "results: ${method_name}: ${!to_var}"
+ done
+ exit 0
fi
# -----------------------------------------------------------------------------
# check that we have at least a method enabled
-if [ "${SEND_EMAIL}" != "YES" \
- -a "${SEND_PUSHOVER}" != "YES" \
- -a "${SEND_TELEGRAM}" != "YES" \
- -a "${SEND_SLACK}" != "YES" \
- -a "${SEND_ROCKETCHAT}" != "YES" \
- -a "${SEND_ALERTA}" != "YES" \
- -a "${SEND_FLOCK}" != "YES" \
- -a "${SEND_DISCORD}" != "YES" \
- -a "${SEND_TWILIO}" != "YES" \
- -a "${SEND_HIPCHAT}" != "YES" \
- -a "${SEND_MESSAGEBIRD}" != "YES" \
- -a "${SEND_KAVENEGAR}" != "YES" \
- -a "${SEND_PUSHBULLET}" != "YES" \
- -a "${SEND_KAFKA}" != "YES" \
- -a "${SEND_PD}" != "YES" \
- -a "${SEND_FLEEP}" != "YES" \
- -a "${SEND_CUSTOM}" != "YES" \
- -a "${SEND_IRC}" != "YES" \
- -a "${SEND_AWSSNS}" != "YES" \
- -a "${SEND_PROWL}" != "YES" \
- -a "${SEND_SYSLOG}" != "YES" \
- -a "${SEND_MSTEAM}" != "YES" \
- ]
- then
- fatal "All notification methods are disabled. Not sending notification for host '${host}', chart '${chart}' to '${roles}' for '${name}' = '${value}' for status '${status}'."
+proceed=0
+for method in "${SEND_EMAIL}" \
+ "${SEND_PUSHOVER}" \
+ "${SEND_TELEGRAM}" \
+ "${SEND_SLACK}" \
+ "${SEND_ROCKETCHAT}" \
+ "${SEND_ALERTA}" \
+ "${SEND_FLOCK}" \
+ "${SEND_DISCORD}" \
+ "${SEND_TWILIO}" \
+ "${SEND_HIPCHAT}" \
+ "${SEND_MESSAGEBIRD}" \
+ "${SEND_KAVENEGAR}" \
+ "${SEND_PUSHBULLET}" \
+ "${SEND_KAFKA}" \
+ "${SEND_PD}" \
+ "${SEND_FLEEP}" \
+ "${SEND_CUSTOM}" \
+ "${SEND_IRC}" \
+ "${SEND_AWSSNS}" \
+ "${SEND_SYSLOG}" \
+ "${SEND_MSTEAM}"; do
+ if [ "${method}" == "YES" ]; then
+ proceed=1
+ break
+ fi
+done
+if [ "$proceed" -eq 0 ]; then
+ fatal "All notification methods are disabled. Not sending notification for host '${host}', chart '${chart}' to '${roles}' for '${name}' = '${value}' for status '${status}'."
fi
# -----------------------------------------------------------------------------
@@ -684,36 +666,35 @@ date=$(date --date=@${when} "${date_format}" 2>/dev/null)
# ----------------------------------------------------------------------------
# prepare some extra headers if we've been asked to thread e-mails
-if [ "${SEND_EMAIL}" == "YES" -a "${EMAIL_THREADING}" != "NO" ] ; then
- email_thread_headers="In-Reply-To: <${chart}-${name}@${host}>\nReferences: <${chart}-${name}@${host}>"
+if [ "${SEND_EMAIL}" == "YES" ] && [ "${EMAIL_THREADING}" != "NO" ]; then
+ email_thread_headers="In-Reply-To: <${chart}-${name}@${host}>\\nReferences: <${chart}-${name}@${host}>"
else
- email_thread_headers=
+ email_thread_headers=
fi
# -----------------------------------------------------------------------------
# function to URL encode a string
urlencode() {
- local string="${1}" strlen encoded pos c o
-
- strlen=${#string}
- for (( pos=0 ; pos<strlen ; pos++ ))
- do
- c=${string:${pos}:1}
- case "${c}" in
- [-_.~a-zA-Z0-9])
- o="${c}"
- ;;
-
- *)
- printf -v o '%%%02x' "'${c}"
- ;;
- esac
- encoded+="${o}"
- done
-
- REPLY="${encoded}"
- echo "${REPLY}"
+ local string="${1}" strlen encoded pos c o
+
+ strlen=${#string}
+ for ((pos = 0; pos < strlen; pos++)); do
+ c=${string:pos:1}
+ case "${c}" in
+ [-_.~a-zA-Z0-9])
+ o="${c}"
+ ;;
+
+ *)
+ printf -v o '%%%02x' "'${c}"
+ ;;
+ esac
+ encoded+="${o}"
+ done
+
+ REPLY="${encoded}"
+ echo "${REPLY}"
}
# -----------------------------------------------------------------------------
@@ -721,238 +702,217 @@ urlencode() {
# using DAYS, MINUTES, SECONDS
duration4human() {
- local s="${1}" d=0 h=0 m=0 ds="day" hs="hour" ms="minute" ss="second" ret
- d=$(( s / 86400 ))
- s=$(( s - (d * 86400) ))
- h=$(( s / 3600 ))
- s=$(( s - (h * 3600) ))
- m=$(( s / 60 ))
- s=$(( s - (m * 60) ))
-
- if [ ${d} -gt 0 ]
- then
- [ ${m} -ge 30 ] && h=$(( h + 1 ))
- [ ${d} -gt 1 ] && ds="days"
- [ ${h} -gt 1 ] && hs="hours"
- if [ ${h} -gt 0 ]
- then
- ret="${d} ${ds} and ${h} ${hs}"
- else
- ret="${d} ${ds}"
- fi
- elif [ ${h} -gt 0 ]
- then
- [ ${s} -ge 30 ] && m=$(( m + 1 ))
- [ ${h} -gt 1 ] && hs="hours"
- [ ${m} -gt 1 ] && ms="minutes"
- if [ ${m} -gt 0 ]
- then
- ret="${h} ${hs} and ${m} ${ms}"
- else
- ret="${h} ${hs}"
- fi
- elif [ ${m} -gt 0 ]
- then
- [ ${m} -gt 1 ] && ms="minutes"
<