module Sensu::Plugin::Utils
Public Instance Methods
api_request(method, path) { |req| ... }
click to toggle source
# File lib/sensu-plugin/utils.rb, line 220 def api_request(method, path, &_blk) if api_settings.nil? raise 'api.json settings not found.' end use_ssl = api_settings['ssl'].is_a?(Hash) || api_settings['host'].start_with?('https') hostname = api_settings['host'].gsub(/https?:\/\//, '') req = net_http_req_class(method).new(path) if api_settings['user'] && api_settings['password'] req.basic_auth(api_settings['user'], api_settings['password']) end yield(req) if block_given? res = Net::HTTP.start(hostname, api_settings['port'], use_ssl: use_ssl) do |http| http.request(req) end res end
api_settings()
click to toggle source
Return a hash of API settings derived first from ENV if set, then Sensu
config `api` scope if configured, and finally falling back to to ipv4 localhost address on default API port.
@return [Hash]
# File lib/sensu-plugin/utils.rb, line 200 def api_settings return @api_settings if @api_settings if ENV['SENSU_API_URL'] uri = URI(ENV['SENSU_API_URL']) ssl = uri.scheme == 'https' ? {} : nil @api_settings = { 'ssl' => ssl, 'host' => uri.host, 'port' => uri.port, 'user' => uri.user, 'password' => uri.password } else @api_settings = settings['api'] || {} @api_settings['host'] ||= '127.0.0.1' @api_settings['port'] ||= 4567 end @api_settings end
api_settings=(api_settings)
click to toggle source
Override API settings (for testing purposes)
@param api_settings
[Hash] @return [Hash]
# File lib/sensu-plugin/utils.rb, line 191 def api_settings=(api_settings) @api_settings = api_settings end
cast_bool_values_int(value)
click to toggle source
# File lib/sensu-plugin/utils.rb, line 281 def cast_bool_values_int(value) case value when 'true', true 1 when 'false', false 0 else value end end
config_files()
click to toggle source
# File lib/sensu-plugin/utils.rb, line 8 def config_files if ENV['SENSU_LOADED_TEMPFILE'] && File.file?(ENV['SENSU_LOADED_TEMPFILE']) IO.read(ENV['SENSU_LOADED_TEMPFILE']).split(':') elsif ENV['SENSU_CONFIG_FILES'] ENV['SENSU_CONFIG_FILES'].split(':') else ['/etc/sensu/config.json'] + Dir['/etc/sensu/conf.d/**/*.json'] end end
deep_merge(hash_one, hash_two)
click to toggle source
# File lib/sensu-plugin/utils.rb, line 267 def deep_merge(hash_one, hash_two) merged = hash_one.dup hash_two.each do |key, value| merged[key] = if hash_one[key].is_a?(Hash) && value.is_a?(Hash) deep_merge(hash_one[key], value) elsif hash_one[key].is_a?(Array) && value.is_a?(Array) hash_one[key].concat(value).uniq else value end end merged end
event()
click to toggle source
# File lib/sensu-plugin/utils.rb, line 28 def event @event end
event=(value)
click to toggle source
# File lib/sensu-plugin/utils.rb, line 32 def event=(value) @event = value end
load_config(filename)
click to toggle source
# File lib/sensu-plugin/utils.rb, line 18 def load_config(filename) JSON.parse(File.open(filename, 'r').read) rescue {} end
map_go_event_into_ruby(orig_event = nil, map_annotation = nil)
click to toggle source
Helper method to convert Sensu
Go event into Sensu
Ruby event
This is here to help keep Sensu Plugin community handlers working until they natively support Go events Takes Go event json object as argument Returns event with Sensu Ruby mapping included Note: The Sensu Ruby mapping overwrites some attributes so the resulting event cannot be used in a Sensu Go workflow. The top level boolean attribute "go_event_mapped_into_ruby" will be set to true as a hint to indicate this is a mapped event object.
# File lib/sensu-plugin/utils.rb, line 59 def map_go_event_into_ruby(orig_event = nil, map_annotation = nil) orig_event ||= @event map_annotation ||= ENV['SENSU_MAP_ANNOTATION'] if ENV['SENSU_MAP_ANNOTATION'] map_annotation ||= 'sensu.io.json_attributes' # return orig_event if already mapped return orig_event if orig_event['go_event_mapped_into_ruby'] # Deep copy of orig_event event = Marshal.load(Marshal.dump(orig_event)) # Trigger mapping code if enity exists and client does not client_missing = event['client'].nil? || event['client'].empty? if event.key?('entity') && client_missing ## # create the client hash from the entity hash ## event['client'] = event['entity'] ## # Fill in missing client attributes ## event['client']['subscribers'] ||= event['entity']['subscriptions'] ## # Map entity metadata into client attributes # Note this is potentially destructive as it may overwrite existing client attributes. ## if event['entity'].key?('metadata') ## # Map metadata annotation 'name' to client name attribute ## event['client']['name'] ||= event['entity']['metadata']['name'] ## # Map special metadata annotation defined in map_annotation as json string and convert to client attributes # Note this is potentially destructive as it may overwrite existing client attributes. ## if event['entity']['metadata'].key?('annotations') && event['entity']['metadata']['annotations'].key?(map_annotation) json_hash = JSON.parse(event['entity']['metadata']['annotations'][map_annotation]) event['client'].update(json_hash) end end ## # Fill in renamed check attributes expected in Sensu Ruby event # subscribers, source ## event['check']['subscribers'] ||= event['check']['subscriptions'] event['check']['source'] ||= event['check']['proxy_entity_name'] ## # Mimic Sensu Ruby event action based on Go event state # action used in logs and fluentd plugins handlers ## action_state_mapping = { 'flapping' => 'flapping', 'passing' => 'resolve', 'failing' => 'create' } state = event['check']['state'] || 'unknown::go_event' # Attempt to map Go event state to Sensu Ruby event action event['action'] ||= action_state_mapping[state.downcase] # Fallback action is Go event state event['action'] ||= state ## # Mimic Sensu Ruby event history based on Go event history # Note: This overwrites the same history attribute # Go history is an array of hashes, each hash includes status # Sensu Ruby history is an array of statuses ## if event['check']['history'] # Let's save the original history original_history = Marshal.load(Marshal.dump(event['check']['history'])) event['check']['original_history'] = original_history legacy_history = [] event['check']['history'].each do |h| legacy_history << h['status'].to_i.to_s || '3' end event['check']['history'] = legacy_history end ## # Map check metadata into client attributes # Note this is potentially destructive as it may overwrite existing check attributes. ## if event['check'].key?('metadata') ## # Map metadata annotation 'name' to client name attribute ## event['check']['name'] ||= event['check']['metadata']['name'] ## # Map special metadata annotation defined in map_annotation as json string and convert to check attributes # Note this is potentially destructive as it may overwrite existing check attributes. ## if event['check']['metadata'].key?('annotations') && event['check']['metadata']['annotations'].key?(map_annotation) json_hash = JSON.parse(event['check']['metadata']['annotations'][map_annotation]) event['check'].update(json_hash) end end ## # Setting flag indicating this function has already been called ## event['go_event_mapped_into_ruby'] = true end # return the updated event event end
net_http_req_class(method)
click to toggle source
# File lib/sensu-plugin/utils.rb, line 174 def net_http_req_class(method) case method.to_s.upcase when 'GET' Net::HTTP::Get when 'POST' Net::HTTP::Post when 'DELETE' Net::HTTP::Delete when 'PUT' Net::HTTP::Put end end
paginated_get(path, options = {})
click to toggle source
Use API query parameters to paginate HTTP GET requests, iterating over the results until an empty set is returned.
@param path [String] @param options [Hash] @return [Array]
# File lib/sensu-plugin/utils.rb, line 245 def paginated_get(path, options = {}) limit = options.fetch('limit', 500) offset = 0 results = [] loop do query_path = "#{path}?limit=#{limit}&offset=#{offset}" response = api_request(:GET, query_path) unless response.is_a?(Net::HTTPOK) unknown("Non-OK response from API query: #{get_uri(query_path)}") end data = JSON.parse(response.body) # when the data is empty, we have hit the end break if data.empty? # If API lacks pagination support, it will # return same data on subsequent iterations break if results.any? { |r| r == data } results << data offset += limit end results.flatten end
read_event(file)
click to toggle source
# File lib/sensu-plugin/utils.rb, line 36 def read_event(file) @event = ::JSON.parse(file.read) @event['occurrences'] ||= 1 @event['check'] ||= {} @event['client'] ||= {} rescue => e puts 'error reading event: ' + e.message exit 0 end
settings()
click to toggle source
# File lib/sensu-plugin/utils.rb, line 24 def settings @settings ||= config_files.map { |f| load_config(f) }.reduce { |a, b| deep_merge(a, b) } end