File: //proc/self/root/usr/lib/ruby/site_ruby/1.8/puppet/external/nagios/base.rb
# 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 #{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 #{self.name} has no name var"
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
@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
}
if @namevar == :_naginator_name
self['_naginator_name'] = self['name']
end
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.first
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)
unless self.class.namevar.to_s == "name"
send(self.class.namevar.to_s + "=", value)
end
end
def namevar
(self.type + "_name").intern
end
def parammap(param)
unless defined?(@map)
map = {
self.namevar => "cn"
}
map.update(self.class.map) if self.class.map
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
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|
next if self.class.suppress.include?(name)
ldapname = self.parammap(name)
str += ldapname + ": #{value}\n"
}
str += "\n"
end
def to_s
str = "define #{self.type} {\n"
@parameters.keys.sort.each { |param|
value = @parameters[param]
str += %{\t%-30s %s\n} % [ param,
if value.is_a? Array
value.join(",").sub(';', '\;')
else
value.to_s.sub(';', '\;')
end
]
}
str += "}\n"
str
end
# The type of object we are.
def type
self.class.name
end
# object types
newtype :host do
setparameters :host_name, :alias, :display_name, :address, :parents,
:hostgroups, :check_command, :initial_state, :max_check_attempts,
:check_interval, :retry_interval, :active_checks_enabled,
:passive_checks_enabled, :check_period, :obsess_over_host,
:check_freshness, :freshness_threshold, :event_handler,
:event_handler_enabled, :low_flap_threshold, :high_flap_threshold,
:flap_detection_enabled, :flap_detection_options,
:failure_prediction_enabled, :process_perf_data,
:retain_status_information, :retain_nonstatus_information, :contacts,
:contact_groups, :notification_interval, :first_notification_delay,
:notification_period, :notification_options, :notifications_enabled,
:stalking_options, :notes, :notes_url, :action_url, :icon_image,
:icon_image_alt, :vrml_image, :statusmap_image, "2d_coords".intern,
"3d_coords".intern,
:register, :use,
:realm, :poller_tag, :business_impact
setsuperior "person"
map :address => "ipHostNumber"
end
newtype :hostgroup do
setparameters :hostgroup_name, :alias, :members, :hostgroup_members, :notes,
:notes_url, :action_url,
:register, :use,
:realm
end
newtype :service do
attach :host => :host_name
setparameters :host_name, :hostgroup_name, :service_description,
:display_name, :servicegroups, :is_volatile, :check_command,
:initial_state, :max_check_attempts, :check_interval, :retry_interval,
:normal_check_interval, :retry_check_interval, :active_checks_enabled,
:passive_checks_enabled, :parallelize_check, :check_period,
:obsess_over_service, :check_freshness, :freshness_threshold,
:event_handler, :event_handler_enabled, :low_flap_threshold,
:high_flap_threshold, :flap_detection_enabled,:flap_detection_options,
:process_perf_data, :failure_prediction_enabled, :retain_status_information,
:retain_nonstatus_information, :notification_interval,
:first_notification_delay, :notification_period, :notification_options,
:notifications_enabled, :contacts, :contact_groups, :stalking_options,
:notes, :notes_url, :action_url, :icon_image, :icon_image_alt,
:register, :use,
:_naginator_name,
:poller_tag, :business_impact
suppress :host_name
setnamevar :_naginator_name
end
newtype :servicegroup do
setparameters :servicegroup_name, :alias, :members, :servicegroup_members,
:notes, :notes_url, :action_url,
:register, :use
end
newtype :contact do
setparameters :contact_name, :alias, :contactgroups,
:host_notifications_enabled, :service_notifications_enabled,
:host_notification_period, :service_notification_period,
:host_notification_options, :service_notification_options,
:host_notification_commands, :service_notification_commands,
:email, :pager, :address1, :address2, :address3, :address4,
:address5, :address6, :can_submit_commands, :retain_status_information,
:retain_nonstatus_information,
:register, :use
setsuperior "person"
end
newtype :contactgroup do
setparameters :contactgroup_name, :alias, :members, :contactgroup_members,
:register, :use
end
# TODO - We should support generic time periods here eg "day 1 - 15"
newtype :timeperiod do
setparameters :timeperiod_name, :alias, :sunday, :monday, :tuesday,
:wednesday, :thursday, :friday, :saturday, :exclude,
:register, :use
end
newtype :command do
setparameters :command_name, :command_line,
:poller_tag
end
newtype :servicedependency do
setparameters :dependent_host_name, :dependent_hostgroup_name,
:dependent_service_description, :host_name, :hostgroup_name,
:service_description, :inherits_parent, :execution_failure_criteria,
:notification_failure_criteria, :dependency_period,
:register, :use,
:_naginator_name
setnamevar :_naginator_name
end
newtype :serviceescalation do
setparameters :host_name, :hostgroup_name, :servicegroup_name,
:service_description, :contacts, :contact_groups,
:first_notification, :last_notification, :notification_interval,
:escalation_period, :escalation_options,
:register, :use,
:_naginator_name
setnamevar :_naginator_name
end
newtype :hostdependency do
setparameters :dependent_host_name, :dependent_hostgroup_name, :host_name,
:hostgroup_name, :inherits_parent, :execution_failure_criteria,
:notification_failure_criteria, :dependency_period,
:register, :use,
:_naginator_name
setnamevar :_naginator_name
end
newtype :hostescalation do
setparameters :host_name, :hostgroup_name, :contacts, :contact_groups,
:first_notification, :last_notification, :notification_interval,
:escalation_period, :escalation_options,
:register, :use,
:_naginator_name
setnamevar :_naginator_name
end
newtype :hostextinfo do
setparameters :host_name, :notes, :notes_url, :icon_image, :icon_image_alt,
:vrml_image, :statusmap_image, "2d_coords".intern, "3d_coords".intern,
:register, :use
setnamevar :host_name
end
newtype :serviceextinfo do
setparameters :host_name, :service_description, :notes, :notes_url,
:action_url, :icon_image, :icon_image_alt,
:register, :use,
:_naginator_name
setnamevar :_naginator_name
end
end