@cryptotaxi247 / netdata-1 / commits / fa854bdde

Generalize the recipient finding logic and reduce the boilerplate code. (#3960)

* Generalize the recipient finding logic and reduce the boilerplate code. This generalizes the recipient finding logic in alarm-notify.sh by converting it to utilize computed variable names in a loop instead of having it all serialized. It also handles declaration of the `SEND_*`, `DEFAULT_RECIPIENT_*`, and `role_recipients_*` variables in a similar manner. Overall, this significantly reduces the amount of boilerplate code needed to add a new notification method. By just adding the variable tag (in lowercase) to the `method_names` variable near the top, you get automatic declarations of the above mentioned variables and are automatically hooked into the recipient finding logic. There are two oddities that this has had to work around: * Kafka: The kafka notification support does not do anything with recipients. I know nothing about Kafka myself, so I'm just leaving this alone. Because it doesn't want the whole recipient handling, it's explicitly left out of the `method_names` variable, and the `SEND_KAFKA` variable is explicitly declared. * EMail: The email handling has two peculiarities to it: - There is a default value for `DEFAULT_RECIPIENT_EMAIL` explicitly defined in alarm-notify.sh. We just declare the variable in the nromal loop, and then assign it down with the other email related config variables. - Recipient names need to be separated by a comma and a space, not just a space like everything else wants. This is achieved by some creative usage of the `cut` command and the `$IFS` variable. Ideally, this wouldn't be needed, but spaces in email addresses are valid (as stupid as that fact is), so we have to account for that. * Address code comments by @ktsaou. * Improve the efficiency of the recipient finding loop. This relocates the loop that finds recipients for each method after all the other checks for each method, and adds a bit of logic at the top of the loop to skip methods that are disabled. This avoids running the recipient finding logic for methods that are disabled for any other reason, which should significantly improve performance for the common case of users only configuring one of the notification methods. * Fix one more code issue pointed out by @ktsaou. * Avoid multiple forks when finding email recipients. * Add a unit test mode for the recipient parsing logic. This adds a unit-test mode for alarm-notify.sh that covers the recipient parsing logic and the criticality filtering logic. Invocation for this testing is as follows: alarm-notify,sh unittest <role> <cfg> <status> <old_status> Where `<role>` is the name of the role to use for testing, `<cfg>` is the path to the config file to load for testing, and `<status>` and `<old_status>` are the simulated current and previous status for the test alarm. The unit testing mode will run all the logic up to and including the recipient parsing loop, print out the parsed recipient lists, and then exit. The lines for the parsed recipient lists look like this: results: <method>: foo bar baz Where `<method>` is the delivery method for these recipients. * Renamed variables to improve clarity as suggested by @ktsaou. * Split email handling from the main recipient loop. * Fixes to unittest mode. * Fix incorrect variable name. * Fix typo.

Austin S. Hemmelgarn committed Nov 28, 2018 at 15:54 UTC fa854bdde6a67c49f4cba980dd936441af5fb8f9
1 file changed +141 -369
health/notifications/alarm-notify.sh.in
+141 -369
@@ -142,6 +142,29 @@ docurl() {
142 return $?
143 }
144
145 +# -----------------------------------------------------------------------------
146 +# List of all the notification mechanisms we support.
147 +# Used in a couple of places to write more compact code.
148 +
149 +method_names="
150 +email
151 +pushover
152 +pushbullet
153 +telegram
154 +slack
155 +alerta
156 +flock
157 +discord
158 +hipchat
159 +twilio
160 +messagebird
161 +pd
162 +fleep
163 +syslog
164 +custom
165 +msteam
166 +"
167 +
168 # -----------------------------------------------------------------------------
169 # this is to be overwritten by the config file
170
@@ -167,26 +190,34 @@ custom_sender() {
190 # -----------------------------------------------------------------------------
191 # parse command line parameters
192
170 -roles="${1}" # the roles that should be notified for this event
171 -host="${2}" # the host generated this event
172 -unique_id="${3}" # the unique id of this event
173 -alarm_id="${4}" # the unique id of the alarm that generated this event
174 -event_id="${5}" # the incremental id of the event, for this alarm id
175 -when="${6}" # the timestamp this event occurred
176 -name="${7}" # the name of the alarm, as given in netdata health.d entries
177 -chart="${8}" # the name of the chart (type.id)
178 -family="${9}" # the family of the chart
179 -status="${10}" # the current status : REMOVED, UNINITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL
180 -old_status="${11}" # the previous status: REMOVED, UNINITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL
181 -value="${12}" # the current value of the alarm
182 -old_value="${13}" # the previous value of the alarm
183 -src="${14}" # the line number and file the alarm has been configured
184 -duration="${15}" # the duration in seconds of the previous alarm state
185 -non_clear_duration="${16}" # the total duration in seconds this is/was non-clear
186 -units="${17}" # the units of the value
187 -info="${18}" # a short description of the alarm
188 -value_string="${19}" # friendly value (with units)
189 -old_value_string="${20}" # friendly old value (with units)
193 +if [ ${1} = "unittest" ] ; then
194 + unittest=1 # enable unit testing mode
195 + roles="${2}" # the role that should be used for unit testing
196 + cfgfile="${3}" # the location of the config file to use for unit testing
197 + status="${4}" # the current status : REMOVED, UNINITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL
198 + old_status="${5}" # the previous status: REMOVED, UNINITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL
199 +else
200 + roles="${1}" # the roles that should be notified for this event
201 + host="${2}" # the host generated this event
202 + unique_id="${3}" # the unique id of this event
203 + alarm_id="${4}" # the unique id of the alarm that generated this event
204 + event_id="${5}" # the incremental id of the event, for this alarm id
205 + when="${6}" # the timestamp this event occurred
206 + name="${7}" # the name of the alarm, as given in netdata health.d entries
207 + chart="${8}" # the name of the chart (type.id)
208 + family="${9}" # the family of the chart
209 + status="${10}" # the current status : REMOVED, UNINITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL
210 + old_status="${11}" # the previous status: REMOVED, UNINITIALIZED, UNDEFINED, CLEAR, WARNING, CRITICAL
211 + value="${12}" # the current value of the alarm
212 + old_value="${13}" # the previous value of the alarm
213 + src="${14}" # the line number and file the alarm has been configured
214 + duration="${15}" # the duration in seconds of the previous alarm state
215 + non_clear_duration="${16}" # the total duration in seconds this is/was non-clear
216 + units="${17}" # the units of the value
217 + info="${18}" # a short description of the alarm
218 + value_string="${19}" # friendly value (with units)
219 + old_value_string="${20}" # friendly old value (with units)
220 +fi
221
222 # -----------------------------------------------------------------------------
223 # find a suitable hostname to use, if netdata did not supply a hostname
@@ -229,112 +260,71 @@ curl=
260 sendmail=
261
262 # enable / disable features
232 -SEND_SLACK="YES"
233 -SEND_MSTEAM="YES"
234 -SEND_ALERTA="YES"
235 -SEND_FLOCK="YES"
236 -SEND_DISCORD="YES"
237 -SEND_PUSHOVER="YES"
238 -SEND_TWILIO="YES"
239 -SEND_HIPCHAT="YES"
240 -SEND_MESSAGEBIRD="YES"
241 -SEND_KAVENEGAR="YES"
242 -SEND_TELEGRAM="YES"
243 -SEND_EMAIL="YES"
244 -SEND_PUSHBULLET="YES"
245 -SEND_KAFKA="YES"
246 -SEND_PD="YES"
247 -SEND_FLEEP="YES"
248 -SEND_IRC="YES"
249 -SEND_AWSSNS="YES"
250 -SEND_SYSLOG="NO"
251 -SEND_CUSTOM="YES"
263 +for method_name in ${method_names^^} ; do
264 + declare SEND_${method_name}="YES"
265 + declare DEFAULT_RECIPIENT_${method_name}
266 +done
267 +
268 +for method_name in ${method_names} ; do
269 + declare -A role_recipients_${method_name}
270 +done
271
272 # slack configs
273 SLACK_WEBHOOK_URL=
255 -DEFAULT_RECIPIENT_SLACK=
256 -declare -A role_recipients_slack=()
274
275 # Microsoft Team configs
276 MSTEAM_WEBHOOK_URL=
260 -DEFAULT_RECIPIENT_MSTEAM=
261 -declare -A role_recipients_msteam=()
277
278 # rocketchat configs
279 ROCKETCHAT_WEBHOOK_URL=
265 -DEFAULT_RECIPIENT_ROCKETCHAT=
266 -declare -A role_recipients_rocketchat=()
280
281 # alerta configs
282 ALERTA_WEBHOOK_URL=
283 ALERTA_API_KEY=
271 -DEFAULT_RECIPIENT_ALERTA=
272 -declare -A role_recipients_alerta=()
284
285 # flock configs
286 FLOCK_WEBHOOK_URL=
276 -DEFAULT_RECIPIENT_FLOCK=
277 -declare -A role_recipients_flock=()
287
288 # discord configs
289 DISCORD_WEBHOOK_URL=
281 -DEFAULT_RECIPIENT_DISCORD=
282 -declare -A role_recipients_discord=()
290
291 # pushover configs
292 PUSHOVER_APP_TOKEN=
286 -DEFAULT_RECIPIENT_PUSHOVER=
287 -declare -A role_recipients_pushover=()
293
294 # pushbullet configs
295 PUSHBULLET_ACCESS_TOKEN=
296 PUSHBULLET_SOURCE_DEVICE=
292 -DEFAULT_RECIPIENT_PUSHBULLET=
293 -declare -A role_recipients_pushbullet=()
297
298 # twilio configs
299 TWILIO_ACCOUNT_SID=
300 TWILIO_ACCOUNT_TOKEN=
301 TWILIO_NUMBER=
299 -DEFAULT_RECIPIENT_TWILIO=
300 -declare -A role_recipients_twilio=()
302
303 # hipchat configs
304 HIPCHAT_SERVER=
305 HIPCHAT_AUTH_TOKEN=
305 -DEFAULT_RECIPIENT_HIPCHAT=
306 -declare -A role_recipients_hipchat=()
306
307 # messagebird configs
308 MESSAGEBIRD_ACCESS_KEY=
309 MESSAGEBIRD_NUMBER=
311 -DEFAULT_RECIPIENT_MESSAGEBIRD=
312 -declare -A role_recipients_messagebird=()
310
311 # kavenegar configs
312 KAVENEGAR_API_KEY=""
313 KAVENEGAR_SENDER=""
317 -DEFAULT_RECIPIENT_KAVENEGAR=()
318 -declare -A role_recipients_kavenegar=""
314
315 # telegram configs
316 TELEGRAM_BOT_TOKEN=
322 -DEFAULT_RECIPIENT_TELEGRAM=
323 -declare -A role_recipients_telegram=()
317
318 # kafka configs
319 +SEND_KAFKA="YES"
320 KAFKA_URL=
321 KAFKA_SENDER_IP=
322
323 # pagerduty.com configs
324 PD_SERVICE_KEY=
331 -DEFAULT_RECIPIENT_PD=
332 -declare -A role_recipients_pd=()
325
326 # fleep.io configs
327 FLEEP_SENDER="${host}"
336 -DEFAULT_RECIPIENT_FLEEP=
337 -declare -A role_recipients_fleep=()
328
329 # Amazon SNS configs
330 DEFAULT_RECIPIENT_AWSSNS=
@@ -343,40 +333,38 @@ declare -A role_recipients_awssns=()
333
334 # syslog configs
335 SYSLOG_FACILITY=
346 -declare -A role_recipients_syslog=()
347 -
348 -# custom configs
349 -DEFAULT_RECIPIENT_CUSTOM=
350 -declare -A role_recipients_custom=()
336
337 # email configs
338 EMAIL_SENDER=
354 -DEFAULT_RECIPIENT_EMAIL="root"
339 EMAIL_CHARSET=$(locale charmap 2>/dev/null)
340 EMAIL_THREADING=
357 -declare -A role_recipients_email=()
341 +DEFAULT_RECIPIENT_EMAIL="root"
342
343 # irc configs
344 IRC_NICKNAME=
345 IRC_REALNAME=
362 -DEFAULT_RECIPIENT_IRC=
346 IRC_NETWORK=
364 -declare -A role_recipients_irc=()
347
348 # load the stock and user configuration files
349 # these will overwrite the variables above
350
369 -for CONFIG in "${NETDATA_STOCK_CONFIG_DIR}/health_alarm_notify.conf" "${NETDATA_USER_CONFIG_DIR}/health_alarm_notify.conf"
370 -do
371 - if [ -f "${CONFIG}" ]
372 - then
373 - debug "Loading config file '${CONFIG}'..."
374 - source "${CONFIG}"
375 - [ $? -ne 0 ] && error "Failed to load config file '${CONFIG}'."
376 - else
377 - warning "Cannot find file '${CONFIG}'."
378 - fi
379 -done
351 +if [ ${unittest} ] ;
352 + then
353 + source "${cfgfile}"
354 + [ $? -ne 0 ] && error "Failed to load requested config file." && exit 1
355 +else
356 + for CONFIG in "${NETDATA_STOCK_CONFIG_DIR}/health_alarm_notify.conf" "${NETDATA_USER_CONFIG_DIR}/health_alarm_notify.conf"
357 + do
358 + if [ -f "${CONFIG}" ]
359 + then
360 + debug "Loading config file '${CONFIG}'..."
361 + source "${CONFIG}"
362 + [ $? -ne 0 ] && error "Failed to load config file '${CONFIG}'."
363 + else
364 + warning "Cannot find file '${CONFIG}'."
365 + fi
366 + done
367 +fi
368
369 # If we didn't autodetect the character set for e-mail and it wasn't
370 # set by the user, we need to set it to a reasonable default. UTF-8
@@ -443,285 +431,6 @@ filter_recipient_by_criticality() {
431 return 1
432 }
433
446 -# -----------------------------------------------------------------------------
447 -# find the recipients' addresses per method
448 -
449 -declare -A arr_slack=()
450 -declare -A arr_msteam=()
451 -declare -A arr_rocketchat=()
452 -declare -A arr_alerta=()
453 -declare -A arr_flock=()
454 -declare -A arr_discord=()
455 -declare -A arr_pushover=()
456 -declare -A arr_pushbullet=()
457 -declare -A arr_twilio=()
458 -declare -A arr_hipchat=()
459 -declare -A arr_telegram=()
460 -declare -A arr_pd=()
461 -declare -A arr_email=()
462 -declare -A arr_custom=()
463 -declare -A arr_messagebird=()
464 -declare -A arr_kavenegar=()
465 -declare -A arr_fleep=()
466 -declare -A arr_irc=()
467 -declare -A arr_syslog=()
468 -declare -A arr_awssns=()
469 -
470 -# netdata may call us with multiple roles, and roles may have multiple but
471 -# overlapping recipients - so, here we find the unique recipients.
472 -for x in ${roles//,/ }
473 -do
474 - # the roles 'silent' and 'disabled' mean:
475 - # don't send a notification for this role
476 - [ "${x}" = "silent" -o "${x}" = "disabled" ] && continue
477 -
478 - # email
479 - a="${role_recipients_email[${x}]}"
480 - [ -z "${a}" ] && a="${DEFAULT_RECIPIENT_EMAIL}"
481 - for r in ${a//,/ }
482 - do
483 - [ "${r}" != "disabled" ] && filter_recipient_by_criticality email "${r}" && arr_email[${r/|*/}]="1"
484 - done
485 -
486 - # pushover
487 - a="${role_recipients_pushover[${x}]}"
488 - [ -z "${a}" ] && a="${DEFAULT_RECIPIENT_PUSHOVER}"
489 - for r in ${a//,/ }
490 - do
491 - [ "${r}" != "disabled" ] && filter_recipient_by_criticality pushover "${r}" && arr_pushover[${r/|*/}]="1"
492 - done
493 -
494 - # pushbullet
495 - a="${role_recipients_pushbullet[${x}]}"
496 - [ -z "${a}" ] && a="${DEFAULT_RECIPIENT_PUSHBULLET}"
497 - for r in ${a//,/ }
498 - do
499 - [ "${r}" != "disabled" ] && filter_recipient_by_criticality pushbullet "${r}" && arr_pushbullet[${r/|*/}]="1"
500 - done
501 -
502 - # twilio
503 - a="${role_recipients_twilio[${x}]}"
504 - [ -z "${a}" ] && a="${DEFAULT_RECIPIENT_TWILIO}"
505 - for r in ${a//,/ }
506 - do
507 - [ "${r}" != "disabled" ] && filter_recipient_by_criticality twilio "${r}" && arr_twilio[${r/|*/}]="1"
508 - done
509 -
510 - # hipchat
511 - a="${role_recipients_hipchat[${x}]}"
512 - [ -z "${a}" ] && a="${DEFAULT_RECIPIENT_HIPCHAT}"
513 - for r in ${a//,/ }
514 - do
515 - [ "${r}" != "disabled" ] && filter_recipient_by_criticality hipchat "${r}" && arr_hipchat[${r/|*/}]="1"
516 - done
517 -
518 - # messagebird
519 - a="${role_recipients_messagebird[${x}]}"
520 - [ -z "${a}" ] && a="${DEFAULT_RECIPIENT_MESSAGEBIRD}"
521 - for r in ${a//,/ }
522 - do
523 - [ "${r}" != "disabled" ] && filter_recipient_by_criticality messagebird "${r}" && arr_messagebird[${r/|*/}]="1"
524 - done
525 -
526 - # kavenegar
527 - a="${role_recipients_kavenegar[${x}]}"
528 - [ -z "${a}" ] && a="${DEFAULT_RECIPIENT_KAVENEGAR}"
529 - for r in ${a//,/ }
530 - do
531 - [ "${r}" != "disabled" ] && filter_recipient_by_criticality kavenegar "${r}" && arr_kavenegar[${r/|*/}]="1"
532 - done
533 -
534 - # telegram
535 - a="${role_recipients_telegram[${x}]}"
536 - [ -z "${a}" ] && a="${DEFAULT_RECIPIENT_TELEGRAM}"
537 - for r in ${a//,/ }
538 - do
539 - [ "${r}" != "disabled" ] && filter_recipient_by_criticality telegram "${r}" && arr_telegram[${r/|*/}]="1"
540 - done
541 -
542 - # slack
543 - a="${role_recipients_slack[${x}]}"
544 - [ -z "${a}" ] && a="${DEFAULT_RECIPIENT_SLACK}"
545 - for r in ${a//,/ }
546 - do
547 - [ "${r}" != "disabled" ] && filter_recipient_by_criticality slack "${r}" && arr_slack[${r/|*/}]="1"
548 - done
549 -
550 - # Microsoft Team
551 - a="${role_recipients_msteam[${x}]}"
552 - [ -z "${a}" ] && a="${DEFAULT_RECIPIENT_MSTEAM}"
553 - for r in ${a//,/ }
554 - do
555 - [ "${r}" != "disabled" ] && filter_recipient_by_criticality msteam "${r}" && arr_msteam[${r/|*/}]="1"
556 - done
557 -
558 - # rocketchat
559 - a="${role_recipients_rocketchat[${x}]}"
560 - [ -z "${a}" ] && a="${DEFAULT_RECIPIENT_ROCKETCHAT}"
561 - for r in ${a//,/ }
562 - do
563 - [ "${r}" != "disabled" ] && filter_recipient_by_criticality rocketchat "${r}" && arr_rocketchat[${r/|*/}]="1"
564 - done
565 -
566 - # alerta
567 - a="${role_recipients_alerta[${x}]}"
568 - [ -z "${a}" ] && a="${DEFAULT_RECIPIENT_ALERTA}"
569 - for r in ${a//,/ }
570 - do
571 - [ "${r}" != "disabled" ] && filter_recipient_by_criticality alerta "${r}" && arr_alerta[${r/|*/}]="1"
572 - done
573 -
574 - # flock
575 - a="${role_recipients_flock[${x}]}"
576 - [ -z "${a}" ] && a="${DEFAULT_RECIPIENT_FLOCK}"
577 - for r in ${a//,/ }
578 - do
579 - [ "${r}" != "disabled" ] && filter_recipient_by_criticality flock "${r}" && arr_flock[${r/|*/}]="1"
580 - done
581 -
582 - # discord
583 - a="${role_recipients_discord[${x}]}"
584 - [ -z "${a}" ] && a="${DEFAULT_RECIPIENT_DISCORD}"
585 - for r in ${a//,/ }
586 - do
587 - [ "${r}" != "disabled" ] && filter_recipient_by_criticality discord "${r}" && arr_discord[${r/|*/}]="1"
588 - done
589 -
590 - # pagerduty.com
591 - a="${role_recipients_pd[${x}]}"
592 - [ -z "${a}" ] && a="${DEFAULT_RECIPIENT_PD}"
593 - for r in ${a//,/ }
594 - do
595 - [ "${r}" != "disabled" ] && filter_recipient_by_criticality pd "${r}" && arr_pd[${r/|*/}]="1"
596 - done
597 -
598 - # fleep.io
599 - a="${role_recipients_fleep[${x}]}"
600 - [ -z "${a}" ] && a="${DEFAULT_RECIPIENT_FLEEP}"
601 - for r in ${a//,/ }
602 - do
603 - [ "${r}" != "disabled" ] && filter_recipient_by_criticality fleep "${r}" && arr_fleep[${r/|*/}]="1"
604 - done
605 -
606 - # irc
607 - a="${role_recipients_irc[${x}]}"
608 - [ -z "${a}" ] && a="${DEFAULT_RECIPIENT_IRC}"
609 - for r in ${a//,/ }
610 - do
611 - [ "${r}" != "disabled" ] && filter_recipient_by_criticality irc "${r}" && arr_irc[${r/|*/}]="1"
612 - done
613 -
614 - # amazon sns
615 - a="${role_recipients_awssns[${x}]}"
616 - [ -z "${a}" ] && a="${DEFAULT_RECIPIENT_AWSSNS}"
617 - for r in ${a//,/ }
618 - do
619 - [ "${r}" != "disabled" ] && filter_recipient_by_criticality awssns "${r}" && arr_awssns[${r/|*/}]="1"
620 - done
621 -
622 - # syslog
623 - a="${role_recipients_syslog[${x}]}"
624 - [ -z "${a}" ] && a="${DEFAULT_RECIPIENT_SYSLOG}"
625 - for r in ${a//,/ }
626 - do
627 - [ "${r}" != "disabled" ] && filter_recipient_by_criticality syslog "${r}" && arr_syslog[${r/|*/}]="1"
628 - done
629 -
630 - # custom
631 - a="${role_recipients_custom[${x}]}"
632 - [ -z "${a}" ] && a="${DEFAULT_RECIPIENT_CUSTOM}"
633 - for r in ${a//,/ }
634 - do
635 - [ "${r}" != "disabled" ] && filter_recipient_by_criticality custom "${r}" && arr_custom[${r/|*/}]="1"
636 - done
637 -
638 -done
639 -
640 -# build the list of slack recipients (channels)
641 -to_slack="${!arr_slack[*]}"
642 -[ -z "${to_slack}" ] && SEND_SLACK="NO"
643 -
644 -# build the list of Microsoft team recipients (channels)
645 -to_msteam="${!arr_msteam[*]}"
646 -[ -z "${to_msteam}" ] && SEND_MSTEAM="NO"
647 -
648 -# build the list of rocketchat recipients (channels)
649 -to_rocketchat="${!arr_rocketchat[*]}"
650 -[ -z "${to_rocketchat}" ] && SEND_ROCKETCHAT="NO"
651 -
652 -# build the list of alerta recipients (channels)
653 -to_alerta="${!arr_alerta[*]}"
654 -[ -z "${to_alerta}" ] && SEND_ALERTA="NO"
655 -
656 -# build the list of flock recipients (channels)
657 -to_flock="${!arr_flock[*]}"
658 -[ -z "${to_flock}" ] && SEND_FLOCK="NO"
659 -
660 -# build the list of discord recipients (channels)
661 -to_discord="${!arr_discord[*]}"
662 -[ -z "${to_discord}" ] && SEND_DISCORD="NO"
663 -
664 -# build the list of pushover recipients (user tokens)
665 -to_pushover="${!arr_pushover[*]}"
666 -[ -z "${to_pushover}" ] && SEND_PUSHOVER="NO"
667 -
668 -# build the list of pushbulet recipients (user tokens)
669 -to_pushbullet="${!arr_pushbullet[*]}"
670 -[ -z "${to_pushbullet}" ] && SEND_PUSHBULLET="NO"
671 -
672 -# build the list of twilio recipients (phone numbers)
673 -to_twilio="${!arr_twilio[*]}"
674 -[ -z "${to_twilio}" ] && SEND_TWILIO="NO"
675 -
676 -# build the list of hipchat recipients (rooms)
677 -to_hipchat="${!arr_hipchat[*]}"
678 -[ -z "${to_hipchat}" ] && SEND_HIPCHAT="NO"
679 -
680 -# build the list of messagebird recipients (phone numbers)
681 -to_messagebird="${!arr_messagebird[*]}"
682 -[ -z "${to_messagebird}" ] && SEND_MESSAGEBIRD="NO"
683 -
684 -# build the list of kavenegar recipients (phone numbers)
685 -to_kavenegar="${!arr_kavenegar[*]}"
686 -[ -z "${to_kavenegar}" ] && SEND_KAVENEGAR="NO"
687 -
688 -# check array of telegram recipients (chat ids)
689 -to_telegram="${!arr_telegram[*]}"
690 -[ -z "${to_telegram}" ] && SEND_TELEGRAM="NO"
691 -
692 -# build the list of pagerduty recipients (service keys)
693 -to_pd="${!arr_pd[*]}"
694 -[ -z "${to_pd}" ] && SEND_PD="NO"
695 -
696 -# build the list of fleep recipients (conversation webhooks)
697 -to_fleep="${!arr_fleep[*]}"
698 -[ -z "${to_fleep}" ] && SEND_FLEEP="NO"
699 -
700 -# build the list of custom recipients
701 -to_custom="${!arr_custom[*]}"
702 -[ -z "${to_custom}" ] && SEND_CUSTOM="NO"
703 -
704 -# build the list of email recipients (email addresses)
705 -to_email=
706 -for x in "${!arr_email[@]}"
707 -do
708 - [ ! -z "${to_email}" ] && to_email="${to_email}, "
709 - to_email="${to_email}${x}"
710 -done
711 -[ -z "${to_email}" ] && SEND_EMAIL="NO"
712 -
713 -# build the list of irc recipients (channels)
714 -to_irc="${!arr_irc[*]}"
715 -[ -z "${to_irc}" ] && SEND_IRC="NO"
716 -
717 -# build the list of awssns recipients (facilities, servers, and prefixes)
718 -to_awssns="${!arr_awssns[*]}"
719 -[ -z "${to_awssns}" ] && SEND_AWSSNS="NO"
720 -
721 -# build the list of syslog recipients (facilities, servers, and prefixes)
722 -to_syslog="${!arr_syslog[*]}"
723 -[ -z "${to_syslog}" ] && SEND_SYSLOG="NO"
724 -
434 # -----------------------------------------------------------------------------
435 # verify the delivery methods supported
436
@@ -859,6 +568,69 @@ if [ "${SEND_AWSSNS}" = "YES" -a -z "${aws}" ]
568 fi
569 fi
570
571 +# -----------------------------------------------------------------------------
572 +# find the recipients' addresses per method
573 +
574 +# netdata may call us with multiple roles, and roles may have multiple but
575 +# overlapping recipients - so, here we find the unique recipients.
576 +for method_name in ${method_names} ; do
577 + send_var="SEND_${method_name^^}"
578 + if [ ${!send_var} = "NO" ] ; then
579 + continue
580 + fi
581 +
582 + declare -A arr_var=()
583 +
584 + for x in ${roles//,/ } ; do
585 + # the roles 'silent' and 'disabled' mean:
586 + # don't send a notification for this role
587 + [ "${x}" = "silent" -o "${x}" = "disabled" ] && continue
588 +
589 + role_recipients_var="role_recipients_${method_name}"
590 + role_recipients=${!role_recipients_var}
591 + default_recipient_var="DEFAULT_RECIPIENT_${method_name^^}"
592 +
593 + a="${role_recipients[${x}]}"
594 + [ -z "${a}" ] && a="${!default_recipient_var}"
595 + for r in ${a//,/ } ; do
596 + [ "${r}" != "disabled" ] && filter_recipient_by_criticality ${method_name} "${r}" && arr_var[${r/|*/}]="1"
597 + done
598 + done
599 +
600 + # build the list of recipients
601 + to_var="to_${method_name}"
602 + declare to_${method_name}="${!arr_var[*]}"
603 +
604 + [ -z "${!to_var}" ] && declare ${send_var}="NO"
605 +done
606 +
607 +# -----------------------------------------------------------------------------
608 +# handle fixup of the email recipient list.
609 +
610 +fix_to_email() {
611 + to_email=
612 + while [ ! -z "${1}" ]
613 + do
614 + [ ! -z "${to_email}" ] && to_email="${to_email}, "
615 + to_email="${to_email}${1}"
616 + shift 1
617 + done
618 +}
619 +
620 +# ${to_email} without quotes here
621 +fix_to_email ${to_email}
622 +
623 +# -----------------------------------------------------------------------------
624 +# handle output if we're running in unit test mode
625 +if [ ${unittest} ] ; then
626 + for method_name in ${method_names} ; do
627 + to_var="to_${method_name}"
628 + echo "results: ${method_name}: ${!to_var}"
629 + done
630 + exit 0
631 +fi
632 +
633 +# -----------------------------------------------------------------------------
634 # check that we have at least a method enabled
635 if [ "${SEND_EMAIL}" != "YES" \
636 -a "${SEND_PUSHOVER}" != "YES" \