bin/handler-victorops.rb
#!/usr/bin/env ruby
# frozen_string_literal: true
# This handler creates and resolves victorops incidents
#
# Released under the same terms as Sensu (the MIT license); see LICENSE
# for details.
#
# arguments:
# - settingsname: Sensu settings name, defaults to victorops
# - routingkey: VictorOps routing key
#
# NOTE: This plugin is Sensu Go enabled. To use this plugin with Sensu Go, add --map_go_event_into_ruby as part of the command.
# Example:
# handler-victorops.rb --map_go_event_into_ruby
require 'sensu-handler'
require 'uri'
require 'net/http'
require 'net/https'
require 'json'
class VictorOps < Sensu::Handler
option :api_url,
description: 'VictorOps API URL without routing key. Or use envvar VICTOROPS_API_URL.',
short: '-a APIURL',
long: '--api-url APIURL',
default: nil
option :settingsname,
description: 'Sensu settings name',
short: '-n NAME',
long: '--name NAME',
default: 'victorops'
option :routing_key,
description: 'Routing key. Or use envvar VICTOROPS_ROUTING_KEY.',
short: '-r KEY',
long: '--routingkey KEY',
default: nil
option :dryrun,
description: 'Report settings, and take no action',
long: '--dryrun',
boolean: true,
default: false
def set_api_url
# validate that we have an api url - environment variables take precedence
api_url = ENV['VICTOROPS_API_URL']
api_url = config[:api_url] if api_url.nil?
if api_url.nil?
# validate that we have a settings name
if defined?(settings[config[:settingsname]]) && !settings[config[:settingsname]].nil?
api_url = settings[config[:settingsname]]['api_url']
else
raise "victorops.rb sensu setting '#{config[:settingsname]}' not found or empty" unless config[:dryrun]
end
end
return api_url if defined?(api_url) && !api_url.nil?
raise "victorops.rb sensu setting '#{config[:settingsname]}.api_url' not found or empty" unless config[:dryrun]
end
def set_routing_key
# validate that we have a routing key - environment variables take precedence
routing_key = ENV['VICTOROPS_ROUTING_KEY']
routing_key = config[:routing_key] if routing_key.nil?
if routing_key.nil?
# validate that we have a settings name in the config
if defined?(settings[config[:settingsname]]) && !settings[config[:settingsname]].nil?
routing_key = settings[config[:settingsname]]['routing_key']
else
raise "victorops.rb sensu setting '#{config[:settingsname]}' not found or empty" unless config[:dryrun]
end
end
return routing_key if defined?(routing_key) && !routing_key.nil?
raise 'routing key not defined, should be in Sensu settings or passed via command arguments' unless config[:dryrun]
end
def dry_run(api_url, routing_key, uri, payload)
return unless config[:dryrun]
puts 'Dryrun: reporting settings and exiting'
puts " option settingsname set: #{config[:settingsname]}"
puts 'Determing API_URL to use:'
if ENV['VICTOROPS_API_URL']
puts " envvar VICTOROPS_API_URL set: #{ENV['VICTOROPS_API_URL']}"
else
puts ' envvar VICTOROPS_API_URL not set'
end
if config[:api_url]
puts " option api-url set: #{config[:api_url]}"
else
puts ' option api-url not set'
end
if settings[config[:settingsname]]
puts " settings api_url set: #{settings[config[:settingsname]]['api_url']}" if settings[config[:settingsname]]['api_url']
else
puts " setting name: #{config[:settingsname]} does not exist"
end
puts " using: #{api_url}"
puts 'Determing ROUTING_KEY to use:'
if ENV['VICTOROPS_ROUTING_KEY']
puts " envvar VICTOROPS_ROUTING_KEY set: #{ENV['VICTOROPS_ROUTING_KEY']}"
else
puts ' envvar VICTOROPS_ROUTING_KEY not set'
end
if config[:routing_key]
puts " option routingkey set: #{config[:routing_key]}"
else
puts ' option routingkey not set'
end
if settings[config[:settingsname]]
puts " settings routing_key set: #{settings[config[:settingsname]]['routing_key']}" if settings[config[:settingsname]]['routing_key']
else
puts " setting name: #{config[:settingsname]} does not exist"
end
puts " using: #{routing_key}"
puts " #{@event['action']}"
puts "VictorOps Message URI: #{uri}"
puts " Message type: #{payload[:message_type]}"
end
def handle
# validate that we have a client defined
unless defined?(@event['client']) && !@event['client']['name'].nil?
raise 'victorops.rb sensu client not found or has no name. If using with Sensu Go please ensure you have enabled event mapping'
end
api_url = set_api_url
routing_key = set_routing_key
incident_key = @event['client']['name'] + '/' + @event['check']['name']
description = @event['check']['notification']
description ||= [@event['client']['name'], @event['check']['name'], @event['check']['output']].join(' : ')
host = @event['client']['name']
entity_id = incident_key
state_message = description
case @event['action']
when 'create'
message_type = case @event['check']['status']
when 1
'WARNING'
else
'CRITICAL'
end
when 'resolve'
message_type = 'RECOVERY'
end
payload = {}
payload[:message_type] = message_type
payload[:state_message] = state_message.chomp
payload[:entity_id] = entity_id
payload[:host_name] = host
payload[:monitoring_tool] = 'sensu'
# Add in client data
payload[:check] = @event['check']
payload[:client] = @event['client']
uri = URI("#{api_url.chomp('/')}/#{routing_key}")
https = Net::HTTP.new(uri.host, uri.port)
https.use_ssl = true
if config[:dryrun]
dry_run(api_url, routing_key, uri, payload)
return
end
begin
Timeout.timeout(10) do
request = Net::HTTP::Post.new(uri.path)
request.body = payload.to_json
response = https.request(request)
if response.code == '200'
puts "victorops -- #{@event['action'].capitalize}'d incident -- #{incident_key}"
else
puts "victorops -- failed to #{@event['action']} incident -- #{incident_key}"
puts "victorops -- response: #{response.inspect}"
end
end
rescue Timeout::Error
puts 'victorops -- timed out while attempting to ' + @event['action'] + ' a incident -- ' + incident_key
end
end
end