Skip to content

Instantly share code, notes, and snippets.

@peelman
Created December 18, 2021 18:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save peelman/0a906bbcdc10b22c8d21b1de13d12557 to your computer and use it in GitHub Desktop.
Save peelman/0a906bbcdc10b22c8d21b1de13d12557 to your computer and use it in GitHub Desktop.
Veeam VBR Trap Alert Script

Overview

Running Veeam and snmptrapd / snmptt? Want Slack notifications from Veeam for jobs? This script does the following:

  • For Jobs: Posts Success, Warning, or Failure messages to the configured Slack Channel
  • For VMs: Posts Warning or Failure messages to the configured Slack Channel
  • For any unknown messages or weird events, it'll post a generic message containing the pertinent info from the trap.

Traps

Traps work thusly (for Veeam / SNMPtrapd / SNMPtt):

  1. Veeam is configured in its settings to send traps to an IP/Port combination
  2. If a job is configured to send SNMP alerts, a trap will be sent for each VM completed, with the status and any relevant message
  3. Once an entire job completes, successfully or otherwise, if the Job is configured to send SNMP alerts, it sends a trap signifying the status
  4. Your SNMPtrapd handler will listen for and receive the trap, and perform some rudimentary processing, before handing it to snmptt
  5. SNMPtt will do additional processing; translating values from MIBs, doing DNS lookups, logging the trap data, and taking any configured processing steps
  6. Per the included veeam-snmptt.conf, we define an EXEC statement that gets executed for each defined event OID.
  7. The EXEC statement fires the included ruby script, which mutates the trap values into Slack messages, and send them on to a webhook URL.

Requirements

Obviously you need to have SNMPtrapd and SNMPtt running; and you need the slack-notifier gem installed (gem install slack-notifier)

Tested on Ruby 2.7, YMMV.

Contributions

Contributions are welcome; but unfortuantely I can't offer support; you'll have to teach yourself enough to understand how to implement this and make it work.

#!/usr/bin/env ruby
require 'optparse'
require 'uri'
require 'net/https'
require 'slack-notifier'
SLACK_WEBHOOK_URL='<slack webhook url'
@hook_url = SLACK_WEBHOOK_URL
@slack_channel='#veeam-alerts'
@slack_username= "Veeam"
@slack_icon=":veeam:"
@type = "job"
@result = "Unknown"
def parse_args(args = {})
@print = args[:print].nil? ? true : args[:print]
@exit = args[:exit].nil? ? true : args[:exit]
# now, handle the arguments...
@opts = OptionParser.new
@opts.banner = "Usage: #{File.basename($0)} -T <type> -J <jobName> -V <vmName> -R <backupResult> -C <backupComment>"
@opts.on("-T", "--type TYPE", "TYPE; Job or VM") do |type|
@type = type
end
@opts.on("-J", "--job JOB_NAME", "JOB_NAME; Job Name") do |job_name|
@job_name = job_name
end
@opts.on("-V", "--vm VM_NAME", "VM_NAME; VM Name") do |vm_name|
@vm_name = vm_name
end
@opts.on("-R", "--result RESULT", "RESULT; Result") do |result|
@result = result
end
@opts.on("-C", "--comment COMMENT", "COMMENT; Comment") do |comment|
@comment = comment
end
@opts.on_tail("-h", "--help", "Show this message") do
puts @opts
exit
end
@opts.parse!
end
def result_to_emoji(result)
if result == "Success"
return ":white_check_mark:"
elsif result == "Warning"
return ":warning:"
elsif result == "Failed"
return ":x:"
else
return ":pear:"
end
end
def send_slack_message(message)
notifier = Slack::Notifier.new @hook_url, channel: @slack_channel, username: @slack_username
notifier.ping "#{message}", icon_emoji: @slack_icon
end
parse_args()
case @type
when "job"
@slack_username = @job_name
details = "\n*Details:* #{@comment}" unless @comment.empty?
message = "*Job Status*: #{result_to_emoji(@result)} #{@result} #{details}"
when "vm"
@slack_username = @job_name
details = "\n*Details:* #{@comment}" unless @comment.empty?
message = "*Virtual Machine*: #{@vm_name} #{result_to_emoji(@result)} #{@result} #{details}"
else
details = "\n*Details:* #{@comment}" unless @comment.empty?
message = "#{result_to_emoji(@result)} *Unknown Trap*\\n*Status*: #{@result} #{details}"
end
send_slack_message(message) unless @type =="vm" and @result == "Success"
# MIB: VEEAM-MIB (file:/home/npeelman/VeeamBackup.mib) converted on Fri Aug 10 23:23:25 2018 using snmpttconvertmib v1.4
#
# Included in /etc/snmp/snmptt.ini
#
EVENT onBackupJobCompleted .1.3.6.1.4.1.31023.1.1.1.0.1 "Status Events" Normal
FORMAT $*
EXEC /usr/local/bin/send_veeam_alert -T job -J "$2" -R "$3" -C "$4"
SDESC
This trap is sent on backup/replica job completed.
Variables:
1: backupJobId
2: backupJobName
3: backupJobResult
4: backupJobComment
EDESC
#
#
#
EVENT onVmBackupCompleted .1.3.6.1.4.1.31023.1.1.1.0.2 "Status Events" Normal
FORMAT $*
EXEC /usr/local/bin/send_veeam_alert -T vm -J "$1" -V "$2" -R "$4" -C "$5"
SDESC
This trap is sent on vm backup/replica completed.
Variables:
1: backupJobName
2: vmName
3: sourceHostName
4: vmBackupResult
5: vmBackupComment
EDESC
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment