aboutsummaryrefslogtreecommitdiff
path: root/lib/mauve/configuration_builders
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mauve/configuration_builders')
-rw-r--r--lib/mauve/configuration_builders/alert_group.rb101
-rw-r--r--lib/mauve/configuration_builders/logger.rb64
-rw-r--r--lib/mauve/configuration_builders/notification_method.rb34
-rw-r--r--lib/mauve/configuration_builders/person.rb41
-rw-r--r--lib/mauve/configuration_builders/server.rb102
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