aboutsummaryrefslogtreecommitdiff
path: root/lib/mauve/configuration.rb
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.rb
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.rb')
-rw-r--r--lib/mauve/configuration.rb454
1 files changed, 9 insertions, 445 deletions
diff --git a/lib/mauve/configuration.rb b/lib/mauve/configuration.rb
index 2794c03..67b76ab 100644
--- a/lib/mauve/configuration.rb
+++ b/lib/mauve/configuration.rb
@@ -1,13 +1,5 @@
-# encoding: UTF-8
-require 'object_builder'
-require 'mauve/server'
-require 'mauve/web_interface'
-require 'mauve/person'
-require 'mauve/notification'
-require 'mauve/alert_group'
-require 'mauve/people_list'
require 'mauve/source_list'
-require 'mauve/heartbeat'
+require 'mauve/people_list'
# Seconds, minutes, hours, days, and weeks... More than that, we
# really should not need it.
@@ -23,6 +15,7 @@ class Integer
alias_method :week, :weeks
end
+
module Mauve
## Configuration object for Mauve.
@@ -30,28 +23,6 @@ module Mauve
#
# @TODO Write some more documentation. This is woefully inadequate.
#
- #
- # == How to add a new class to the configuration?
- #
- # - Add a method to ConfigurationBuilder such that your new object
- # maybe created. Call it created_NEW_OBJ.
- #
- # - Create a new class inheriting from ObjectBuilder with at least a
- # builder_setup() method. This should create the new object you want.
- #
- # - Define attributes for the new class are defined as "is_attribute".
- #
- # - Methods for the new class are defined as methods or missing_method
- # depending on what one wishes to do. Remember to define a method
- # with "instance_eval(&block)" if you want to call said block within
- # the new class.
- #
- # - Add a "is_builder "<name>", BuilderCLASS" clause in the
- # ConfigurationBuilder class.
- #
- # That should be it.
- #
- # @author Matthew Bloch, Yann Golanski
class Configuration
class << self
@@ -60,426 +31,19 @@ module Mauve
attr_accessor :server
attr_accessor :last_alert_group
- attr_reader :notification_methods
- attr_reader :people
- attr_reader :alert_groups
- attr_reader :people_lists
- attr_reader :source_lists
- attr_reader :logger
+ attr_reader :notification_methods
+ attr_reader :people
+ attr_reader :alert_groups
+ attr_reader :people_lists
+ attr_reader :source_lists
def initialize
@notification_methods = {}
@people = {}
- @people_lists = {}
+ @people_lists = Hash.new{|h,k| h[k] = Mauve::PeopleList.new(k)}
+ @source_lists = Hash.new{|h,k| h[k] = Mauve::SourceList.new(k)}
@alert_groups = []
- @source_lists = SourceList.new()
- @logger = Log4r::Logger.new("Mauve")
- end
-
- end
-
- class LoggerOutputterBuilder < 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
-
- def method_missing(name, value=nil)
- if value.nil?
- result.send(name.to_sym)
- else
- @args[name.to_sym] = value
- end
- end
-
- end
-
- class LoggerBuilder < ObjectBuilder
-
- is_builder "outputter", LoggerOutputterBuilder
-
-
- def builder_setup
- logger = Log4r::Logger.new("Mauve")
- @default_format = nil
- @default_level = Log4r::RootLogger.instance.level
- end
-
- def result
- @result = Log4r::Logger['Mauve']
- end
-
- def default_format(f)
- @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
- 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
-
- class ProcessorBuilder < ObjectBuilder
- is_attribute "sleep_interval"
- is_attribute "transmission_cache_expire_time"
-
- def builder_setup
- @result = Processor.instance
- end
- end
-
- class UDPServerBuilder < ObjectBuilder
- is_attribute "port"
- is_attribute "ip"
- is_attribute "sleep_interval"
-
- def builder_setup
- @result = UDPServer.instance
- end
- end
-
- class TimerBuilder < ObjectBuilder
- is_attribute "sleep_interval"
-
- def builder_setup
- @result = Timer.instance
- end
- end
-
- class HeartbeatBuilder < ObjectBuilder
- is_attribute "destination"
- is_attribute "interval"
-
- def builder_setup
- @result = Heartbeat.instance
- end
- end
-
- class HTTPServerBuilder < ObjectBuilder
-
- is_attribute "port"
- is_attribute "ip"
- is_attribute "document_root"
- is_attribute "session_secret"
- is_attribute "base_url"
-
- def builder_setup
- @result = HTTPServer.instance
- end
- end
-
- class NotifierBuilder < ObjectBuilder
- is_attribute "sleep_interval"
-
- def builder_setup
- @result = Notifier.instance
- end
- end
-
- class ServerBuilder < ObjectBuilder
-
- is_builder "web_interface", HTTPServerBuilder
- is_builder "listener", UDPServerBuilder
- is_builder "processor", ProcessorBuilder
- is_builder "timer", TimerBuilder
- is_builder "notifier", NotifierBuilder
- is_builder "heartbeat", HeartbeatBuilder
-
- is_attribute "hostname"
- is_attribute "database"
- is_attribute "initial_sleep"
-
- def builder_setup
- @result = Mauve::Server.instance
- @args = {}
- end
-
- def result
- @result.configure(@args)
- @result
- end
-
- def created_web_interface(web_interface)
- @web_interface = web_interface
- end
-
- def created_listener(listener)
- @listener = listener
- end
-
- def created_processor(processor)
- @processor = processor
- end
-
- def created_notifier(notifier)
- @notifier = notifier
- end
-
- def created_heartbeat(heartbeat)
- @heartbeat = heartbeat
- end
- end
-
- class NotificationMethodBuilder < 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
-
- class PersonBuilder < ObjectBuilder
-
- def builder_setup(username)
- @result = 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
-
- class NotificationBuilder < 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 = 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 AlertGroupBuilder < ObjectBuilder
-
- def builder_setup(name=anonymous_name)
- @result = AlertGroup.new(name)
- @context.last_alert_group = @result
end
- is_block_attribute "includes"
- is_attribute "acknowledgement_time"
- is_attribute "level"
-
- is_builder "notify", NotificationBuilder
-
- def created_notify(notification)
- @result.notifications ||= []
- @result.notifications << notification
- end
-
end
-
- # New list of persons.
- # @author Yann Golanski
- class PeopleListBuilder < ObjectBuilder
-
- # Create a new instance and adds it.
- def builder_setup(label)
- @result = PeopleList.new(label)
- end
-
- is_attribute "list"
-
- end
-
- # New list of sources.
- # @author Yann Golanski
- class AddSourceListBuilder < ObjectBuilder
-
- # Create the temporary object.
- def builder_setup(label)
- @result = AddSoruceList.new(label)
- end
-
- # List of IP addresses or hostnames.
- is_attribute "list"
-
- end
-
-
- # this should live in AlertGroupBuilder but can't due to
- # http://briancarper.net/blog/ruby-instance_eval_constant_scoping_broken
- #
- module ConfigConstants
- URGENT = :urgent
- NORMAL = :normal
- LOW = :low
- end
-
- class ConfigurationBuilder < ObjectBuilder
-
- include ConfigConstants
-
- is_builder "server", ServerBuilder
- is_builder "notification_method", NotificationMethodBuilder
- is_builder "person", PersonBuilder
- is_builder "alert_group", AlertGroupBuilder
- is_builder "people_list", PeopleListBuilder
- is_builder "add_source_list", AddSourceListBuilder
- is_builder "logger", LoggerBuilder
-
- def initialize
- @context = @result = Configuration.new
- # FIXME: need to test blocks that are not immediately evaluated
- end
-
- def created_server(server)
- raise BuildError.new("Only one 'server' clause can be specified") if
- @result.server
- @result.server = server
- end
-
- 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
-
- def created_person(person)
- name = person.username
- raise BuildException.new("Duplicate person '#{name}'") if
- @result.people[name]
- @result.people[person.username] = person
- end
-
- 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
-
- # Create a new instance of people_list.
- #
- # @param [PeopleList] people_list The new list of persons.
- # @return [NULL] nada.
- def created_people_list(people_list)
- label = people_list.label
- raise BuildException.new("Duplicate people_list '#{label}'") if @result.people_lists[label]
- @result.people_lists[label] = people_list
- end
-
- # Create a new list of sources.
- #
- # @param [] add_source_list
- # @return [NULL] nada.
- def created_add_source_list(add_source_list)
- @result.source_lists.create_new_list(add_source_list.label,
- add_source_list.list)
- end
-
- end
-
end