|
|
# 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)
unless self.class.namevar.to_s == "name"
send(self.class.namevar.to_s + "=", value)
end
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, :register, :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, :contact_groups, :check_period
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 :hostescalation do
setparameters :name, :first_notification, :last_notification,
:notification_interval, :contact_groups,
:escalation_options, :register, :hostgroup_name
setnamevar :name
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, :hostgroup_name, :event_handler, :servicegroups, :host
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, :hostgroup_name,
:dependent_hostgroup_name
setnamevar :host_name
end
newtype :serviceescalation do
setparameters :host_name, :service_description, :first_notification,
:last_notification, :contact_groups, :notification_interval, :hostgroup_name
setnamevar :host_name
end
newtype :servicegroup do
setparameters :servicegroup_name, :alias
setnamevar :servicegroup_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$
|