aboutsummaryrefslogtreecommitdiff
path: root/lib/mauve/configuration_builders
diff options
context:
space:
mode:
authorPatrick J Cherry <patrick@bytemark.co.uk>2011-07-22 16:55:01 +0100
committerPatrick J Cherry <patrick@bytemark.co.uk>2011-07-22 16:55:01 +0100
commitfd23821950f0562a8995735105cd31fdc6d55933 (patch)
tree967df2f5647803a6c46f4d52003b2231c1de72cb /lib/mauve/configuration_builders
parentd3a3cfef9650b08f62db62bd7e86b673f9d77d0b (diff)
* Rejigged configuration
* Added --test and --verbose flags for the server config * Started proper test suite * Config parsing now gives more sensible errors + backtrace * Rejigged people and source lists
Diffstat (limited to 'lib/mauve/configuration_builders')
-rw-r--r--lib/mauve/configuration_builders/alert_group.rb81
-rw-r--r--lib/mauve/configuration_builders/logger.rb120
-rw-r--r--lib/mauve/configuration_builders/notification_method.rb50
-rw-r--r--lib/mauve/configuration_builders/person.rb60
-rw-r--r--lib/mauve/configuration_builders/server.rb102
5 files changed, 413 insertions, 0 deletions
diff --git a/lib/mauve/configuration_builders/alert_group.rb b/lib/mauve/configuration_builders/alert_group.rb
new file mode 100644
index 0000000..9561d4d
--- /dev/null
+++ b/lib/mauve/configuration_builders/alert_group.rb
@@ -0,0 +1,81 @@
+# encoding: UTF-8
+require 'object_builder'
+require 'mauve/notification'
+require 'mauve/configuration_builder'
+require 'mauve/alert_group'
+require 'mauve/notification'
+
+module Mauve
+ module ConfigurationBuilders
+
+ 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")
+ end
+ 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
+ end
+
+ is_block_attribute "includes"
+ is_attribute "acknowledgement_time"
+ is_attribute "level"
+
+ is_builder "notify", Notification
+
+ def created_notify(notification)
+ @result.notifications ||= []
+ @result.notifications << notification
+ end
+
+ end
+
+ end
+
+ # this should live in AlertGroup but can't due to
+ # http://briancarper.net/blog/ruby-instance_eval_constant_scoping_broken
+ #
+ module AlertGroupConstants
+ URGENT = :urgent
+ NORMAL = :normal
+ LOW = :low
+ end
+
+
+ class ConfigurationBuilder < ObjectBuilder
+
+ include AlertGroupConstants
+
+ is_builder "alert_group", ConfigurationBuilders::AlertGroup
+
+ 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?
+ @result.alert_groups << alert_group
+ end
+
+ end
+
+end
diff --git a/lib/mauve/configuration_builders/logger.rb b/lib/mauve/configuration_builders/logger.rb
new file mode 100644
index 0000000..a1d0388
--- /dev/null
+++ b/lib/mauve/configuration_builders/logger.rb
@@ -0,0 +1,120 @@
+# encoding: UTF-8
+require 'log4r'
+require 'mauve/configuration_builder'
+
+module Mauve
+ module ConfigurationBuilders
+
+ class LoggerOutputter < ObjectBuilder
+
+ def builder_setup(outputter)
+ @outputter = outputter.capitalize+"Outputter"
+
+ begin
+ Log4r.const_get(@outputter)
+ rescue
+ require "log4r/outputter/#{@outputter.downcase}"
+ end
+
+ @outputter_name = "Mauve-"+5.times.collect{rand(36).to_s(36)}.join
+
+ @args = {}
+ end
+
+ def result
+ @result ||= Log4r.const_get(@outputter).new("Mauve", @args)
+ end
+
+ def format(f)
+ result.formatter = Log4r::PatternFormatter.new(:pattern => f)
+ end
+
+ #
+ # This is needed to be able to pass arbitrary arguments to Log4r
+ # outputters.
+ #
+ def method_missing(name, value=nil)
+ if value.nil?
+ result.send(name.to_sym)
+ else
+ @args[name.to_sym] = value
+ end
+ end
+
+ end
+
+ class Logger < ObjectBuilder
+
+ is_builder "outputter", LoggerOutputter
+
+ def builder_setup
+ @result = Log4r::Logger.new('Mauve')
+ @default_format = nil
+ @default_level = Log4r::RootLogger.instance.level
+ end
+
+ def default_format(f)
+ begin
+ @default_formatter = Log4r::PatternFormatter.new(:pattern => f)
+ rescue SyntaxError
+ raise BuildException.new "Bad log format #{f.inspect}"
+ end
+ #
+ # Set all current outputters
+ #
+ result.outputters.each do |o|
+ o.formatter = @default_formatter if o.formatter.is_a?(Log4r::DefaultFormatter)
+ end
+ end
+
+ def default_level(l)
+ if Log4r::Log4rTools.valid_level?(l)
+ @default_level = l
+ else
+ raise "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
+ end
+
+ def created_outputter(outputter)
+ #
+ # Set the formatter and level for any newly created outputters
+ #
+ if @default_formatter
+ outputter.formatter = @default_formatter if outputter.formatter.is_a?(Log4r::DefaultFormatter)
+ end
+
+ if @default_level
+ outputter.level = @default_level if outputter.level == Log4r::RootLogger.instance.level
+ end
+
+ result.outputters << outputter
+ end
+ end
+ end
+
+ #
+ # this should live in Logger but can't due to
+ # http://briancarper.net/blog/ruby-instance_eval_constant_scoping_broken
+ #
+ module LoggerConstants
+ Log4r.define_levels(*Log4r::Log4rConfig::LogLevels) # ensure levels are loaded
+
+ DEBUG = Log4r::DEBUG
+ INFO = Log4r::INFO
+ WARN = Log4r::WARN
+ ERROR = Log4r::ERROR
+ FATAL = Log4r::FATAL
+ end
+
+ class ConfigurationBuilder < ObjectBuilder
+
+ include LoggerConstants
+
+ is_builder "logger", ConfigurationBuilders::Logger
+
+ end
+end
diff --git a/lib/mauve/configuration_builders/notification_method.rb b/lib/mauve/configuration_builders/notification_method.rb
new file mode 100644
index 0000000..1192078
--- /dev/null
+++ b/lib/mauve/configuration_builders/notification_method.rb
@@ -0,0 +1,50 @@
+require 'mauve/notifiers'
+require 'mauve/configuration_builder'
+
+# encoding: UTF-8
+module Mauve
+ module ConfigurationBuilders
+ class NotificationMethod < ObjectBuilder
+
+ def builder_setup(name)
+ @notification_type = name.capitalize
+ @name = name
+ provider("Default")
+ end
+
+ def provider(name)
+ notifiers_base = Mauve::Notifiers
+ notifiers_type = notifiers_base.const_get(@notification_type)
+ @provider_class = notifiers_type.const_get(name)
+ end
+
+ def result
+ @result ||= @provider_class.new(@name)
+ end
+
+ def method_missing(name, value=nil)
+ if value
+ result.send("#{name}=".to_sym, value)
+ else
+ result.send(name.to_sym)
+ end
+ end
+ end
+ end
+
+ #
+ # Add notification_method to our top-level config builder
+ #
+ class ConfigurationBuilder < ObjectBuilder
+ is_builder "notification_method", ConfigurationBuilders::NotificationMethod
+
+ def created_notification_method(notification_method)
+ name = notification_method.name
+ raise BuildException.new("Duplicate notification '#{name}'") if @result.notification_methods[name]
+ @result.notification_methods[name] = notification_method
+ end
+
+ end
+
+end
+
diff --git a/lib/mauve/configuration_builders/person.rb b/lib/mauve/configuration_builders/person.rb
new file mode 100644
index 0000000..1f2af71
--- /dev/null
+++ b/lib/mauve/configuration_builders/person.rb
@@ -0,0 +1,60 @@
+# encoding: UTF-8
+require 'object_builder'
+require 'mauve/person'
+require 'mauve/configuration_builder'
+
+module Mauve
+ module ConfigurationBuilders
+
+ class Person < ObjectBuilder
+
+ def builder_setup(username)
+ @result = Mauve::Person.new(username)
+ end
+
+ 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
+
+ def email(e)
+ @result.email = e.to_s
+ end
+
+ def xmpp(x)
+ @result.xmpp = x.to_s
+ end
+
+ def sms(x)
+ @result.sms = x.to_s
+ end
+
+ def suppress_notifications_after(h)
+ raise ArgumentError.new("notification_threshold must be specified as e.g. (10 => 1.minute)") unless
+ h.kind_of?(Hash) && h.keys[0].kind_of?(Integer) && h.values[0].kind_of?(Integer)
+ @result.notification_thresholds[h.values[0]] = Array.new(h.keys[0])
+ end
+ end
+ end
+
+ class ConfigurationBuilder < ObjectBuilder
+
+ is_builder "person", ConfigurationBuilders::Person
+
+ def created_person(person)
+ name = person.username
+ raise BuildException.new("Duplicate person '#{name}'") if @result.people[name]
+ @result.people[person.username] = person
+ end
+
+ end
+end
diff --git a/lib/mauve/configuration_builders/server.rb b/lib/mauve/configuration_builders/server.rb
new file mode 100644
index 0000000..0fa811b
--- /dev/null
+++ b/lib/mauve/configuration_builders/server.rb
@@ -0,0 +1,102 @@
+# encoding: UTF-8
+require 'mauve/server'
+require 'mauve/configuration_builder'
+
+module Mauve
+ module ConfigurationBuilders
+
+ class HTTPServer < ObjectBuilder
+ is_attribute "port"
+ is_attribute "ip"
+ is_attribute "document_root"
+ is_attribute "session_secret"
+ is_attribute "base_url"
+
+ def builder_setup
+ @result = Mauve::HTTPServer.instance
+ end
+ end
+
+ class UDPServer < ObjectBuilder
+ is_attribute "port"
+ is_attribute "ip"
+ is_attribute "poll_every"
+
+ def builder_setup
+ @result = Mauve::UDPServer.instance
+ end
+ end
+
+ class Processor < ObjectBuilder
+ is_attribute "poll_every"
+ is_attribute "transmission_cache_expire_time"
+
+ def builder_setup
+ @result = Mauve::Processor.instance
+ end
+ end
+
+ class Timer < ObjectBuilder
+ is_attribute "poll_every"
+
+ def builder_setup
+ @result = Mauve::Timer.instance
+ end
+ end
+
+ class Notifier < ObjectBuilder
+ is_attribute "poll_every"
+
+ def builder_setup
+ @result = Mauve::Notifier.instance
+ end
+ end
+
+ class Heartbeat < ObjectBuilder
+ is_attribute "destination"
+ is_attribute "detail"
+ is_attribute "summary"
+ is_attribute "raise_after"
+ is_attribute "send_every"
+
+ def builder_setup
+ @result = Mauve::Heartbeat.instance
+ end
+ end
+
+ class Server < ObjectBuilder
+ #
+ # Set up second-level builders
+ #
+ is_builder "web_interface", HTTPServer
+ is_builder "listener", UDPServer
+ is_builder "processor", Processor
+ is_builder "timer", Timer
+ is_builder "notifier", Notifier
+ is_builder "heartbeat", Heartbeat
+
+ is_attribute "hostname"
+ is_attribute "database"
+ is_attribute "initial_sleep"
+
+ def builder_setup
+ @result = Mauve::Server.instance
+ end
+ end
+ end
+
+ #
+ # Add server to our top-level config builder
+ #
+ class ConfigurationBuilder < ObjectBuilder
+
+ is_builder "server", ConfigurationBuilders::Server
+
+ def created_server(server)
+ raise BuildError.new("Only one 'server' clause can be specified") if @result.server
+ @result.server = server
+ end
+
+ end
+
+end