diff options
author | Patrick J Cherry <patrick@bytemark.co.uk> | 2011-07-22 16:55:01 +0100 |
---|---|---|
committer | Patrick J Cherry <patrick@bytemark.co.uk> | 2011-07-22 16:55:01 +0100 |
commit | fd23821950f0562a8995735105cd31fdc6d55933 (patch) | |
tree | 967df2f5647803a6c46f4d52003b2231c1de72cb /lib/mauve/configuration_builders | |
parent | d3a3cfef9650b08f62db62bd7e86b673f9d77d0b (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.rb | 81 | ||||
-rw-r--r-- | lib/mauve/configuration_builders/logger.rb | 120 | ||||
-rw-r--r-- | lib/mauve/configuration_builders/notification_method.rb | 50 | ||||
-rw-r--r-- | lib/mauve/configuration_builders/person.rb | 60 | ||||
-rw-r--r-- | lib/mauve/configuration_builders/server.rb | 102 |
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 |