diff options
Diffstat (limited to 'lib/puppet/external/nagios/base.rb')
-rwxr-xr-x | lib/puppet/external/nagios/base.rb | 421 |
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$ |