lib/flapjack/cli/notifier.rb in flapjack-0.4.12 vs lib/flapjack/cli/notifier.rb in flapjack-0.5.1
- old
+ new
@@ -1,246 +1,108 @@
#!/usr/bin/env ruby
-require 'rubygems'
require 'ostruct'
require 'optparse'
require 'log4r'
require 'log4r/outputter/syslogoutputter'
-require File.join(File.dirname(__FILE__), '..', 'database')
-require File.join(File.dirname(__FILE__), '..', 'notifier')
-require File.join(File.dirname(__FILE__), '..', 'result')
+require File.join(File.dirname(__FILE__), '..', 'inifile')
module Flapjack
- class NotifierOptions
- def self.parse(args)
- options = OpenStruct.new
- opts = OptionParser.new do |opts|
- # the available command line options
- opts.on('-b', '--beanstalk HOST', 'location of the beanstalkd') do |host|
- options.host = host
+ module Notifier
+ class Options
+ def self.parse(args)
+ options = OpenStruct.new
+ opts = OptionParser.new do |opts|
+ opts.on('-r', '--recipients FILE', 'recipients file') do |filename|
+ options.recipients_filename = filename
+ end
+ opts.on('-c', '--config FILE', 'config file') do |filename|
+ options.config_filename = filename
+ end
+ opts.on_tail("-h", "--help", "Show this message") do
+ puts opts
+ exit
+ end
end
- opts.on('-p', '--port PORT', 'beanstalkd port') do |port|
- options.port = port.to_i
- end
- opts.on('-r', '--recipients FILE', 'recipients file') do |recipients|
- options.recipients = recipients.to_s
- end
- opts.on('-c', '--config FILE', 'config file') do |config|
- options.config_filename = config.to_s
- end
- opts.on('-d', '--database-uri URI', 'location of the checks database') do |db|
- options.database_uri = db.to_s
- end
- opts.on_tail("-h", "--help", "Show this message") do
+
+ # parse the options
+ begin
+ opts.parse!(args)
+ rescue OptionParser::MissingArgument => e
+ # if an --option is missing it's argument
+ puts e.message.capitalize + "\n\n"
puts opts
- exit
+ exit 1
end
- end
- # parse the options
- begin
- opts.parse!(args)
- rescue OptionParser::MissingArgument => e
- # if an --option is missing it's argument
- puts e.message.capitalize + "\n\n"
- puts opts
- exit 1
- end
-
- # default the host + port
- options.host ||= 'localhost'
- options.port ||= 11300
+ # validation of command line arguments
+ @errors = []
+ # check that recipients file exists
+ if options.recipients_filename
+ unless File.exists?(options.recipients_filename)
+ @errors << "The specified recipients file doesn't exist!"
+ end
+ else
+ @errors << "You need to specify a recipients file with --recipients."
+ end
- @errors = []
- # check that recipients file exists
- if options.recipients
- unless File.exists?(options.recipients.to_s)
- @errors << "The specified recipients file doesn't exist!"
+ # check that config file exists
+ if options.config_filename
+ unless File.exists?(options.config_filename.to_s)
+ @errors << "The specified config file doesn't exist!"
+ end
+ else
+ options.config_filename = "/etc/flapjack/flapjack-notifier.conf"
+ unless File.exists?(options.config_filename)
+ @errors << "The default config file (#{options.config_filename}) doesn't exist."
+ @errors << "Please set one up, or specify one with --config."
+ end
end
- else
- @errors << "You need to specify a recipients file with [-r|--recipients]."
- end
+
- # check that config file exists
- if options.config_filename
- unless File.exists?(options.config_filename.to_s)
- @errors << "The specified config file doesn't exist!"
+ # if there are errors, print them out and exit
+ if @errors.size > 0
+ puts "Errors:"
+ @errors.each do |error|
+ puts " - #{error}"
+ end
+ puts
+ puts opts
+ exit 2
end
- else
- options.config_filename ||= "/etc/flapjack/flapjack-notifier.yaml"
- unless File.exists?(options.config_filename.to_s)
- @errors << "The default config file (#{options.config_filename}) doesn't exist!"
- @errors << "Set one up, or specify one with [-c|--config]."
- end
- end
+
+ # config loader
- # if there are errors, print them out and exit
- if @errors.size > 0
- puts "Errors:"
- @errors.each do |error|
- puts " - #{error}"
- end
- puts
- puts opts
- exit 2
- end
-
- options
- end
- end
-
- class NotifierCLI
- attr_accessor :log, :recipients, :results_queue, :config
- attr_accessor :notifier, :notifiers
- attr_accessor :condition
-
- def initialize(opts={})
- @log = opts[:logger]
- @log ||= Log4r::Logger.new("notifier")
- end
-
- def setup_loggers
- @log.add(Log4r::StdoutOutputter.new('notifier'))
- @log.add(Log4r::SyslogOutputter.new('notifier'))
- end
-
- def setup_recipients(opts={})
-
- if opts[:yaml]
- yaml = opts[:yaml]
- else
- opts[:filename] ||= File.join(Dir.pwd, "recipients.yaml")
- yaml = YAML::load(File.read(opts[:filename]))
- end
-
- # FIXME: add error detection for passing in dumb things
+ # holder for transport + persistence config
+ options.transport = OpenStruct.new
+ options.persistence = OpenStruct.new
- @recipients = yaml.map do |r|
- OpenStruct.new(r)
- end
- end
+ config = Flapjack::Inifile.read(options.config_filename)
- def setup_config(opts={})
- if opts[:yaml]
- yaml = opts[:yaml]
- else
- opts[:filename] ||= File.join(Dir.pwd, "flapjack-notifier.yaml")
- yaml = YAML::load(File.read(opts[:filename]))
- end
-
- @config = OpenStruct.new(yaml)
- end
-
- def setup_database(opts={})
- uri = (opts[:database_uri] || @config.database_uri)
- raise ArgumentError, "database URI wasn't specified!" unless uri
- DataMapper.setup(:default, uri)
- validate_database
- end
-
- def validate_database
- begin
- DataMapper.repository(:default).adapter.execute("SELECT 'id' FROM 'checks';")
- rescue Sqlite3Error
- @log.warning("The specified database doesn't appear to have any structure!")
- @log.warning("You need to investigate this.")
- end
- # FIXME: add more rescues in here!
- end
-
- def initialize_notifiers(opts={})
- notifiers_directory = opts[:notifiers_directory]
- notifiers_directory ||= File.expand_path(File.join(File.dirname(__FILE__), '..', 'notifiers'))
-
- raise ArgumentError, "notifiers directory doesn't exist!" unless File.exists?(notifiers_directory)
-
- @notifiers = []
-
- @config.notifiers.each_pair do |notifier, config|
- filename = File.join(notifiers_directory, notifier.to_s, 'init')
- if File.exists?(filename + '.rb')
- @log.debug("Loading the #{notifier.to_s.capitalize} notifier")
- require filename
- config.merge!(:logger => @log, :website_uri => @config.website_uri)
- @notifiers << Flapjack::Notifiers.const_get("#{notifier.to_s.capitalize}").new(config)
- else
- @log.warning("Flapjack::Notifiers::#{notifier.to_s.capitalize} doesn't exist!")
+ %w(transport persistence).each do |backend|
+ options.send("#{backend}=", config[backend].symbolize_keys)
end
- end
- @notifiers
- end
-
- # Sets up notifier to do the grunt work of notifying people when checks
- # return badly.
- #
- # Accepts a list of recipients (:recipients) and a logger (:logger) as
- # arguments. If neither of these are specified, it will default to an
- # existing list of recipients and the current logger.
- #
- # Sets up and returns @notifier, an instance of Flapjack::Notifier
- def setup_notifier(opts={})
- recipients = (opts[:recipients] || @recipients)
- log = (opts[:logger] || @log)
- initialize_notifiers
- notifiers = @notifiers # should we accept a list of notifiers?
- @notifier = Flapjack::Notifier.new(:logger => log,
- :notifiers => notifiers,
- :recipients => recipients)
- end
-
- def process_loop
- @log.info("Processing results...")
- loop do
- process_result
- end
- end
-
- # FIXME: we're doing a lookup twice - optimise out
- def save_result(result)
- if check = Check.get(result.id)
- check.status = result.retval
- check.save
- else
- @log.error("Got result for check #{result.id}, but it doesn't exist!")
- end
- end
-
- # FIXME: we're doing a lookup twice - optimise out
- def any_parents_warning_or_critical?(result)
- if check = Check.get(result.id)
- check.worst_parent_status > 0 ? true : false
- else
- @log.error("Got result for check #{result.id}, but it doesn't exist!")
- end
- end
-
- def process_result
- @log.debug("Waiting for new result...")
- result_job = @results_queue.reserve # blocks until a job is reserved
- result = Flapjack::Result.new(YAML::load(result_job.body))
-
- @log.info("Processing result for check '#{result.id}'")
- if result.warning? || result.critical?
- if any_parents_warning_or_critical?(result)
- @log.info("Not notifying on check '#{result.id}' as parent is failing.")
- else
- @log.info("Creating event for check '#{result.id}'")
- # FIXME: this will be a performance hit
- event = ::Event.new(:check_id => result.id)
- raise unless event.save
+ # base config (config.blah)
+ config['notifier'].each_pair do |key, value|
+ normalised_key = key.gsub('-', '_')
+ values = value.split(/,*\s+/)
+ options.send("#{normalised_key}=", values)
+ end
- @log.info("Notifying on check '#{result.id}'")
- @notifier.notify!(result, event)
+ # list of notifiers to load + their config
+ notifiers_to_load = options.notifiers
+ options.notifiers = {}
+ notifiers_to_load.each do |notifier|
+ options.notifiers[notifier] = config["#{notifier}-notifier"].symbolize_keys
end
- end
- @log.info("Storing status of check in database")
- save_result(result)
+ # holder for recipients list
+ recipients = Flapjack::Inifile.read(options.recipients_filename)
+ options.recipients = recipients.all
- @log.debug("Deleting result for check '#{result.id}' from queue")
- result_job.delete
+ options
+ end
end
-
end
-
+
end