diff options
Diffstat (limited to 'lib/mauve/configuration_builders')
-rw-r--r-- | lib/mauve/configuration_builders/alert_group.rb | 101 | ||||
-rw-r--r-- | lib/mauve/configuration_builders/logger.rb | 64 | ||||
-rw-r--r-- | lib/mauve/configuration_builders/notification_method.rb | 34 | ||||
-rw-r--r-- | lib/mauve/configuration_builders/person.rb | 41 | ||||
-rw-r--r-- | lib/mauve/configuration_builders/server.rb | 102 |
5 files changed, 264 insertions, 78 deletions
diff --git a/lib/mauve/configuration_builders/alert_group.rb b/lib/mauve/configuration_builders/alert_group.rb index 9561d4d..c652de8 100644 --- a/lib/mauve/configuration_builders/alert_group.rb +++ b/lib/mauve/configuration_builders/alert_group.rb @@ -7,59 +7,81 @@ require 'mauve/notification' module Mauve module ConfigurationBuilders - + # + # This corresponds to a new "notify" clause an the alert_group config. + # class Notification < ObjectBuilder - def builder_setup(*who) - who = who.map do |username| - #raise BuildException.new("You haven't declared who #{username} is") unless - # @context.people[username] - #@context.people[username] - if @context.people[username] - @context.people[username] - elsif @context.people_lists[username] - @context.people_lists[username] - else - raise BuildException.new("You have not declared who #{username} is") + # Sets up the notification + # + # @param [Array] who List of usernames or people_lists to notify + # @raise [ArgumentError] if a username doesn't exist. + # + # @return [Mauve::Notification] New notification instance. + def builder_setup(*who) + who = who.map do |username| + #raise BuildException.new("You haven't declared who #{username} is") unless + # @context.people[username] + #@context.people[username] + if @context.people[username] + @context.people[username] + elsif @context.people_lists[username] + @context.people_lists[username] + else + raise ArgumentError.new("You have not declared who #{username} is") + end end + @result = Mauve::Notification.new(who, @context.last_alert_group.level) end - @result = Mauve::Notification.new(who, @context.last_alert_group.level) - end - - is_attribute "every" - is_block_attribute "during" - ##is_attribute "hours_in_day" - ##is_attribute "unacknowledged" - end - - class AlertGroup < ObjectBuilder - - def builder_setup(name=anonymous_name) - @result = Mauve::AlertGroup.new(name) - @context.last_alert_group = @result + + is_attribute "every" + is_block_attribute "during" end - is_block_attribute "includes" - is_attribute "acknowledgement_time" - is_attribute "level" + # This corresponds to a new alert_group clause + # + class AlertGroup < ObjectBuilder + + # Sets up the alert group, and sets the last_alert_group context. + # + # @param [String] name Name of the new alert group + # + # @return [Mauve::AlertGroup] New alert group instance + def builder_setup(name="anonymous_name") + @result = Mauve::AlertGroup.new(name) + @context.last_alert_group = @result + end - is_builder "notify", Notification + is_block_attribute "includes" + is_attribute "acknowledgement_time" + is_attribute "level" + is_builder "notify", Mauve::ConfigurationBuilders::Notification + + # Method called after the notify clause has been sorted. Adds new + # notification clause to the result. + # + # @param [Mauve::Notification] notification + # + def created_notify(notification) + @result.notifications ||= [] + @result.notifications << notification + end - def created_notify(notification) - @result.notifications ||= [] - @result.notifications << notification end end - end - - # this should live in AlertGroup but can't due to + # These constants define the levels available for alert groups. + # + # This should live in AlertGroup but can't due to # http://briancarper.net/blog/ruby-instance_eval_constant_scoping_broken # module AlertGroupConstants + # Urgent level URGENT = :urgent + # Normal level NORMAL = :normal + # Low level LOW = :low end @@ -70,9 +92,14 @@ module Mauve is_builder "alert_group", ConfigurationBuilders::AlertGroup + # Called after an alert group is created. Checks to make sure that no more than one alert group shares a name. + # + # @param [Mauve::AlertGroup] alert_group The new AlertGroup + # @raise [ArgumentError] if an AlertGroup with the same name already exists. + # def created_alert_group(alert_group) name = alert_group.name - raise BuildException.new("Duplicate alert_group '#{name}'") unless @result.alert_groups.select { |g| g.name == name }.empty? + raise ArgumentError.new("Duplicate alert_group '#{name}'") unless @result.alert_groups.select { |g| g.name == name }.empty? @result.alert_groups << alert_group end diff --git a/lib/mauve/configuration_builders/logger.rb b/lib/mauve/configuration_builders/logger.rb index 3f60dfe..d757d88 100644 --- a/lib/mauve/configuration_builders/logger.rb +++ b/lib/mauve/configuration_builders/logger.rb @@ -7,31 +7,48 @@ module Mauve class LoggerOutputter < ObjectBuilder + # Set up a Log4r::Outputter + # + # @param [String] outputter Outputter basic class name, like Stderr, Stdin, File. + # def builder_setup(outputter) @outputter = outputter.capitalize+"Outputter" begin Log4r.const_get(@outputter) - rescue + rescue NameError require "log4r/outputter/#{@outputter.downcase}" end - @outputter_name = "Mauve-"+5.times.collect{rand(36).to_s(36)}.join + @outputter_name = anonymous_name @args = {} end + # The new outputter + # + # @return [Log4r::Outputter] def result @result ||= Log4r.const_get(@outputter).new("Mauve", @args) end + # Set the formatter for this outputter (see Log4r::PatternFormatter for + # allowed patterns). SyntaxError is caught in the ObjectBuilder#parse + # method. + # + # @param [String] f The format + # + # @return [Log4r::PatternFormatter] def format(f) result.formatter = Log4r::PatternFormatter.new(:pattern => f) end - # # This is needed to be able to pass arbitrary arguments to Log4r - # outputters. + # outputters. Missing methods / bad arguments are caught in the + # ObjectBuilder#parse method. + # + # @param [String] name + # @param [Object] value # def method_missing(name, value=nil) if value.nil? @@ -47,38 +64,59 @@ module Mauve is_builder "outputter", LoggerOutputter + # Set up the new logger + # def builder_setup @result = Log4r::Logger['Mauve'] || Log4r::Logger.new('Mauve') @default_format = nil @default_level = Log4r::RootLogger.instance.level end + # Set the default format. Syntax erros are caught in the + # ObjectBuilder#parse method. + # + # @param [String] f Any format pattern allowed by Log4r::PatternFormatter. + # + # @return [Log4r::PatternFormatter] def default_format(f) - begin - @default_formatter = Log4r::PatternFormatter.new(:pattern => f) - rescue SyntaxError - raise BuildException.new "Bad log format #{f.inspect}" - end + @default_formatter = Log4r::PatternFormatter.new(:pattern => f) + # # Set all current outputters # result.outputters.each do |o| o.formatter = @default_formatter if o.formatter.is_a?(Log4r::DefaultFormatter) end + + @default_formatter end + # Set the default log level. + # + # @param [Integer] l The log level. + # @raise [ArgumentError] If the log level is bad + # + # @return [Integer] The log level set. def default_level(l) if Log4r::Log4rTools.valid_level?(l) @default_level = l else - raise "Bad default level set for the logger #{l}.inspect" + raise ArgumentError.new "Bad default level set for the logger #{l.inspect}" end result.outputters.each do |o| o.level = @default_level if o.level == Log4r::RootLogger.instance.level end + + @default_level end + # This is called once an outputter has been created. It sets the default + # formatter and level, if these have been already set. + # + # @param [Log4r::Outputter] outputter Newly created outputter. + # + # @return [Log4r::Outputter] The adjusted outputter. def created_outputter(outputter) # # Set the formatter and level for any newly created outputters @@ -92,7 +130,6 @@ module Mauve end result.outputters << outputter -# result.outputter.write("Created logger") end end end @@ -104,10 +141,15 @@ module Mauve module LoggerConstants Log4r.define_levels(*Log4r::Log4rConfig::LogLevels) # ensure levels are loaded + # Debug logging DEBUG = Log4r::DEBUG + # Info logging INFO = Log4r::INFO + # Warn logging WARN = Log4r::WARN + # Error logging ERROR = Log4r::ERROR + # Fatal logging FATAL = Log4r::FATAL end diff --git a/lib/mauve/configuration_builders/notification_method.rb b/lib/mauve/configuration_builders/notification_method.rb index 1192078..9596587 100644 --- a/lib/mauve/configuration_builders/notification_method.rb +++ b/lib/mauve/configuration_builders/notification_method.rb @@ -1,27 +1,46 @@ require 'mauve/notifiers' require 'mauve/configuration_builder' -# encoding: UTF-8 module Mauve module ConfigurationBuilders class NotificationMethod < ObjectBuilder + # + # Set up the notification. Missing notifiers are caught via NameError in + # the ObjectBuilder#parse method. + # + # @param [String] name Name of the notifier + # def builder_setup(name) - @notification_type = name.capitalize + notifiers_base = Mauve::Notifiers + + @notifier_type = notifiers_base.const_get(name.capitalize) + @name = name provider("Default") end + # This allows use of multiple notification providers, e.g. in the case of + # SMS. + # + # Missing providers are caught via NameError in the ObjectBuilder#parse + # method. + # def provider(name) - notifiers_base = Mauve::Notifiers - notifiers_type = notifiers_base.const_get(@notification_type) - @provider_class = notifiers_type.const_get(name) + @provider_class = @notifier_type.const_get(name) end + # Returns the result for this builder, depending on the configuration + # def result @result ||= @provider_class.new(@name) end - + + # This catches all methods available for a provider, as needed. + # + # Missing methods / bad arguments etc. are caught in the + # ObjectBuilder#parse method, via NoMethodError. + # def method_missing(name, value=nil) if value result.send("#{name}=".to_sym, value) @@ -38,6 +57,9 @@ module Mauve class ConfigurationBuilder < ObjectBuilder is_builder "notification_method", ConfigurationBuilders::NotificationMethod + # Method called after a notification method has been created to check for duplicate names. + # + # @raise [BuildException] when a duplicate notification method is found. def created_notification_method(notification_method) name = notification_method.name raise BuildException.new("Duplicate notification '#{name}'") if @result.notification_methods[name] diff --git a/lib/mauve/configuration_builders/person.rb b/lib/mauve/configuration_builders/person.rb index 1c012f2..c5314c5 100644 --- a/lib/mauve/configuration_builders/person.rb +++ b/lib/mauve/configuration_builders/person.rb @@ -15,29 +15,21 @@ module Mauve is_block_attribute "urgent" is_block_attribute "normal" is_block_attribute "low" - - def all(&block); urgent(&block); normal(&block); low(&block); end - - def password (pwd) - @result.password = pwd.to_s - end - - def holiday_url (url) - @result.holiday_url = url.to_s - end + is_attribute "password" + is_attribute "sms" + is_attribute "holiday_url" + is_attribute "email" + is_attribute "xmpp" + is_attribute "sms" - def email(e) - @result.email = e.to_s - end + # Sets the block for all levels of alert + # + # @param [Block] block + def all(&block); urgent(&block); normal(&block); low(&block); end - def xmpp(x) - @result.xmpp = x.to_s - end - - def sms(x) - @result.sms = x.to_s - end - + # Notification suppression hash + # + # @param [Hash] h def suppress_notifications_after(h) raise ArgumentError.new("notification_threshold must be specified as e.g. (10 => 1.minute)") unless h.kind_of?(Hash) @@ -54,9 +46,14 @@ module Mauve is_builder "person", ConfigurationBuilders::Person + # Method called once a person has been created to check for duplicate names + # + # @param [Mauve::Person] person + # @raise [ArgumentError] if a person has already been declared. + # def created_person(person) name = person.username - raise BuildException.new("Duplicate person '#{name}'") if @result.people[name] + raise ArgumentError.new("Duplicate person '#{name}'") if @result.people[name] # # Add a default notification threshold # diff --git a/lib/mauve/configuration_builders/server.rb b/lib/mauve/configuration_builders/server.rb index 3a9f5ec..c000144 100644 --- a/lib/mauve/configuration_builders/server.rb +++ b/lib/mauve/configuration_builders/server.rb @@ -5,74 +5,157 @@ require 'mauve/configuration_builder' module Mauve module ConfigurationBuilders + # + # This is the HTTP server + # class HTTPServer < ObjectBuilder + # The port the http server listens on is_attribute "port" + # The IP address the http server listens on. IPv6 is *NOT* OK. is_attribute "ip" + # Where all the templates are kept is_attribute "document_root" + # The secret for the cookies is_attribute "session_secret" + # The base URL of the server. is_attribute "base_url" + # Sets up a Mauve::HTTPServer singleton as the result + # + # @return [Mauve::HTTPServer] def builder_setup @result = Mauve::HTTPServer.instance end end + # + # This is the UDP server. + # class UDPServer < ObjectBuilder + # This is the port the server listens on is_attribute "port" + # This is the IP address the server listens on. IPv6 is OK! e.g. [::] for all addresses is_attribute "ip" + # This is the sleep interval for the UDP server. is_attribute "poll_every" + # Sets up a Mauve::UDPServer singleton as the result + # + # @return [Mauve::UDPServer] def builder_setup @result = Mauve::UDPServer.instance end end + # + # This is the thread that pulls packets from the queue for processing. + # class Processor < ObjectBuilder + # This is the interval between polls of the packet queue. is_attribute "poll_every" + # This is the timeout for the transmission cache, which allows duplicate packets to be discarded. is_attribute "transmission_cache_expire_time" + # Sets up a Mauve::Processor singleton as the result + # + # @return [Mauve::Processor] def builder_setup @result = Mauve::Processor.instance end end + # + # This is the Timer singleton. + # class Timer < ObjectBuilder + # + # This is the interval at which the Timer thread is run. This will limit + # the rate at which notifications can be sent, if set. + # is_attribute "poll_every" + # Sets up a Mauve::Timer singleton as the result + # + # @return [Mauve::Timer] def builder_setup @result = Mauve::Timer.instance end end class Notifier < ObjectBuilder + # + # This is the interval at which the notification queue is polled for new + # notifications to be sent. This will not have any rate-limiting effect. + # is_attribute "poll_every" + # Sets up a Mauve::Notifier singleton as the result + # + # @return [Mauve::Notifier] def builder_setup @result = Mauve::Notifier.instance end end + # + # This sends a mauve heartbeat to another Mauve instance elsewhere + # class Heartbeat < ObjectBuilder + # + # The destination for the heartbeat + # is_attribute "destination" + + # + # The detail field for the heartbeat + # is_attribute "detail" + + # + # The summary field for the heartbeat. + # is_attribute "summary" + + # + # How long to raise an alert after the last heartbeat. + # is_attribute "raise_after" + + # + # The interval between heartbeats + # is_attribute "send_every" - + + # Sets up a Mauve::Heartbeat singleton as the result + # + # @return [Mauve::Heartbeat] def builder_setup @result = Mauve::Heartbeat.instance end end class Pop3Server < ObjectBuilder + # + # The IP adderess the Pop3 server listens on + # is_attribute "ip" + + # + # The POP3 server port + # is_attribute "port" + # Sets up a Mauve::Pop3Server singleton as the result + # + # @return [Mauve::Pop3Server] def builder_setup @result = Mauve::Pop3Server.instance end end + # + # This is the main Server singleton. + # class Server < ObjectBuilder # # Set up second-level builders @@ -85,8 +168,19 @@ module Mauve is_builder "heartbeat", Heartbeat is_builder "pop3_server", Pop3Server + # + # The name of the server this instance of Mauve is running on + # is_attribute "hostname" + + # + # The database definition + # is_attribute "database" + + # + # The period of sleep during which no heartbeats are raised. + # is_attribute "initial_sleep" def builder_setup @@ -102,8 +196,12 @@ module Mauve is_builder "server", ConfigurationBuilders::Server + # This is called once the server object has been created. + # + # @raise [SyntaxError] if more than one server clause has been defined. + # def created_server(server) - raise BuildError.new("Only one 'server' clause can be specified") if @result.server + raise SyntaxError.new("Only one 'server' clause can be specified") if @result.server @result.server = server end |