summaryrefslogtreecommitdiffstats
path: root/lib/puppet/external/nagios/base.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/puppet/external/nagios/base.rb')
-rwxr-xr-xlib/puppet/external/nagios/base.rb421
1 files changed, 421 insertions, 0 deletions
diff --git a/lib/puppet/external/nagios/base.rb b/lib/puppet/external/nagios/base.rb
new file mode 100755
index 000000000..efc3982b4
--- /dev/null
+++ b/lib/puppet/external/nagios/base.rb
@@ -0,0 +1,421 @@
+# The base class for all of our Nagios object types. Everything else
+# is mostly just data.
+class Nagios::Base
+
+ class UnknownNagiosType < RuntimeError # When an unknown type is asked for by name.
+ end
+
+ include Enumerable
+
+ class << self
+ attr_accessor :parameters, :derivatives, :ocs, :name, :att
+ attr_accessor :ldapbase
+
+ attr_writer :namevar
+
+ attr_reader :superior
+ end
+
+ # Attach one class to another.
+ def self.attach(hash)
+ @attach ||= {}
+ hash.each do |n, v| @attach[n] = v end
+ end
+
+ # Convert a parameter to camelcase
+ def self.camelcase(param)
+ param.gsub(/_./) do |match|
+ match.sub(/_/,'').capitalize
+ end
+ end
+
+ # Uncamelcase a parameter.
+ def self.decamelcase(param)
+ param.gsub(/[A-Z]/) do |match|
+ "_" + match.downcase
+ end
+ end
+
+ # Create a new instance of a given class.
+ def self.create(name, args = {})
+ name = name.intern if name.is_a? String
+
+ if @types.include?(name)
+ @types[name].new(args)
+ else
+ raise UnknownNagiosType, "Unknown type %s" % name
+ end
+ end
+
+ # Yield each type in turn.
+ def self.eachtype
+ @types.each do |name, type|
+ yield [name, type]
+ end
+ end
+
+ # Create a mapping.
+ def self.map(hash)
+ @map ||= {}
+ hash.each do |n, v| @map[n] = v end
+ end
+
+ # Return a mapping (or nil) for a param
+ def self.mapping(name)
+ name = name.intern if name.is_a? String
+ if defined? @map
+ @map[name]
+ else
+ nil
+ end
+ end
+
+ # Return the namevar for the canonical name.
+ def self.namevar
+ if defined? @namevar
+ return @namevar
+ else
+ if parameter?(:name)
+ return :name
+ elsif tmp = (self.name.to_s + "_name").intern and parameter?(tmp)
+ @namevar = tmp
+ return @namevar
+ else
+ raise "Type %s has no name var" % self.name
+ end
+ end
+ end
+
+ # Create a new type.
+ def self.newtype(name, &block)
+ name = name.intern if name.is_a? String
+
+ @types ||= {}
+
+ # Create the class, with the correct name.
+ t = Class.new(self)
+ t.name = name
+
+ # Everyone gets this. There should probably be a better way, and I
+ # should probably hack the attribute system to look things up based on
+ # this "use" setting, but, eh.
+ t.parameters = [:use]
+
+ const_set(name.to_s.capitalize,t)
+
+ # Evaluate the passed block. This should usually define all of the work.
+ t.class_eval(&block)
+
+ @types[name] = t
+ end
+
+ # Define both the normal case and camelcase method for a parameter
+ def self.paramattr(name)
+ camel = camelcase(name)
+ param = name
+
+ [name, camel].each do |method|
+ define_method(method) do
+ @parameters[param]
+ end
+
+ define_method(method.to_s + "=") do |value|
+ @parameters[param] = value
+ end
+ end
+
+ end
+
+ # Is the specified name a valid parameter?
+ def self.parameter?(name)
+ name = name.intern if name.is_a? String
+ return @parameters.include?(name)
+ end
+
+ # Manually set the namevar
+ def self.setnamevar(name)
+ name = name.intern if name.is_a? String
+ @namevar = name
+ end
+
+ # Set the valid parameters for this class
+ def self.setparameters(*array)
+ @parameters += array
+ end
+
+ # Set the superior ldap object class. Seems silly to include this
+ # in this class, but, eh.
+ def self.setsuperior(name)
+ @superior = name
+ end
+
+ # Parameters to suppress in output.
+ def self.suppress(name)
+ @suppress ||= []
+ @suppress << name
+ end
+
+ # Whether a given parameter is suppressed.
+ def self.suppress?(name)
+ defined? @suppress and @suppress.include?(name)
+ end
+
+ # Return our name as the string.
+ def self.to_s
+ self.name.to_s
+ end
+
+ # Return a type by name.
+ def self.type(name)
+ name = name.intern if name.is_a? String
+
+ @types[name]
+ end
+
+ # Convenience methods.
+ def [](param)
+ send(param)
+ end
+
+ # Convenience methods.
+ def []=(param,value)
+ send(param.to_s + "=", value)
+ end
+
+ # Iterate across all ofour set parameters.
+ def each
+ @parameters.each { |param,value|
+ yield(param,value)
+ }
+ end
+
+ # Initialize our object, optionally with a list of parameters.
+ def initialize(args = {})
+ @parameters = {}
+
+ args.each { |param,value|
+ self[param] = value
+ }
+ end
+
+ # Handle parameters like attributes.
+ def method_missing(mname, *args)
+ pname = mname.to_s
+ pname.sub!(/=/, '')
+
+ if self.class.parameter?(pname)
+ if pname =~ /A-Z/
+ pname = self.class.decamelcase(pname)
+ end
+ self.class.paramattr(pname)
+
+ # Now access the parameters directly, to make it at least less
+ # likely we'll end up in an infinite recursion.
+ if mname.to_s =~ /=$/
+ @parameters[pname] = *args
+ else
+ return @parameters[mname]
+ end
+ else
+ super
+ end
+ end
+
+ # Retrieve our name, through a bit of redirection.
+ def name
+ send(self.class.namevar)
+ end
+
+ # This is probably a bad idea.
+ def name=(value)
+ send(self.class.namevar.to_s + "=", value)
+ end
+
+ def namevar
+ return (self.type + "_name").intern
+ end
+
+ def parammap(param)
+ unless defined? @map
+ map = {
+ self.namevar => "cn"
+ }
+ if self.class.map
+ map.update(self.class.map)
+ end
+ end
+ if map.include?(param)
+ return map[param]
+ else
+ return "nagios-" + param.id2name.gsub(/_/,'-')
+ end
+ end
+
+ def parent
+ unless defined? self.class.attached
+ puts "Duh, you called parent on an unattached class"
+ return
+ end
+
+ klass,param = self.class.attached
+ unless @parameters.include?(param)
+ puts "Huh, no attachment param"
+ return
+ end
+ klass[@parameters[param]]
+ end
+
+ # okay, this sucks
+ # how do i get my list of ocs?
+ def to_ldif
+ base = self.class.ldapbase
+ str = self.dn + "\n"
+ ocs = Array.new
+ if self.class.ocs
+ # i'm storing an array, so i have to flatten it and stuff
+ kocs = self.class.ocs
+ ocs.push(*kocs)
+ end
+ ocs.push "top"
+ oc = self.class.to_s
+ oc.sub!(/Nagios/,'nagios')
+ oc.sub!(/::/,'')
+ ocs.push oc
+ ocs.each { |oc|
+ str += "objectclass: " + oc + "\n"
+ }
+ @parameters.each { |name,value|
+ if self.class.suppress.include?(name)
+ next
+ end
+ ldapname = self.parammap(name)
+ str += ldapname + ": " + value + "\n"
+ }
+ str += "\n"
+ str
+ end
+
+ def to_s
+ str = "define #{self.type} {\n"
+
+ self.each { |param,value|
+ str += %{\t%-30s %s\n} % [ param,
+ if value.is_a? Array
+ value.join(",")
+ else
+ value
+ end
+ ]
+ }
+
+ str += "}\n"
+
+ str
+ end
+
+ # The type of object we are.
+ def type
+ self.class.name
+ end
+
+ # object types
+ newtype :command do
+ setparameters :command_name, :command_line
+ end
+
+ newtype :contact do
+ setparameters :contact_name, :alias, :host_notification_period,
+ :host_notification_commands, :service_notification_period,
+ :service_notification_commands,
+ :email, :pager, :service_notification_options, :host_notification_options
+
+ setsuperior "person"
+ end
+
+ newtype :contactgroup do
+ setparameters :contactgroup_name, :alias, :members
+ end
+
+ newtype :host do
+ setparameters :host_name, :notifications_enabled, :event_handler_enabled,
+ :flap_detection_enabled, :process_perf_data, :retain_status_information,
+ :retain_nonstatus_information, :register, :use, :alias,
+ :address, :check_command, :max_check_attempts, :notification_interval,
+ :notification_period, :notification_options, :checks_enabled,
+ :failure_prediction_enabled, :parents
+
+ setsuperior "person"
+
+ map :address => "ipHostNumber"
+ end
+
+ newtype :hostextinfo do
+ auxiliary = true
+
+ setparameters :host_name, :notes_url, :icon_image, :icon_image_alt, :vrml_image,
+ "2d_coords".intern, "3d_coords".intern
+
+ setnamevar :host_name
+ end
+
+ newtype :hostgroup do
+ setparameters :hostgroup_name, :alias, :contact_groups, :members
+ end
+
+ newtype :hostgroupescalation do
+ auxiliary = true
+ setparameters :hostgroup_name, :first_notification, :last_notification,
+ :contact_groups, :notification_interval
+
+ setnamevar :hostgroup_name
+ end
+
+ newtype :service do
+ attach :host => :host_name
+ setparameters :name, :active_checks_enabled, :passive_checks_enabled,
+ :parallelize_check, :obsess_over_service, :check_freshness,
+ :notifications_enabled, :event_handler_enabled,
+ :flap_detection_enabled, :process_perf_data,
+ :retain_status_information, :retain_nonstatus_information, :register,
+ :is_volatile, :check_period, :max_check_attempts,
+ :normal_check_interval, :retry_check_interval, :contact_groups,
+ :notification_interval, :notification_period, :notification_options,
+ :service_description, :host_name, :freshness_threshold,
+ :check_command
+
+ suppress :host_name
+
+ setnamevar :service_description
+ end
+
+ newtype :servicedependency do
+ auxiliary = true
+ setparameters :host_name, :service_description, :dependent_host_name,
+ :dependent_service_description, :execution_failure_criteria,
+ :notification_failure_criteria
+
+ setnamevar :host_name
+ end
+
+ newtype :serviceescalation do
+ setparameters :host_name, :service_description, :first_notification,
+ :last_notification, :contact_groups, :notification_interval
+
+ setnamevar :host_name
+ end
+
+ newtype :serviceextinfo do
+ auxiliary = true
+
+ setparameters :host_name, :service_description, :icon_image, :icon_image_alt
+
+ setnamevar :host_name
+ end
+
+ newtype :timeperiod do
+ setparameters :timeperiod_name, :alias, :sunday, :monday, :tuesday, :wednesday,
+ :thursday, :friday, :saturday
+ end
+end
+
+# $Id$