summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2007-12-31 15:12:12 -0600
committerLuke Kanies <luke@madstop.com>2007-12-31 15:12:12 -0600
commit1dfcb63e0f9de1fd2f15c98ee9a6f242e3fb9325 (patch)
tree2a68cf9ed5718789b69f8fdadbffc39f382d5421 /lib
parent4e8bc40ad7a9c128e778dbafda6dadbade215c94 (diff)
parent33e319a8be8e35fbe4a9ecb7e3185453b8239a83 (diff)
downloadpuppet-1dfcb63e0f9de1fd2f15c98ee9a6f242e3fb9325.tar.gz
puppet-1dfcb63e0f9de1fd2f15c98ee9a6f242e3fb9325.tar.xz
puppet-1dfcb63e0f9de1fd2f15c98ee9a6f242e3fb9325.zip
Merge branch 'nagios' into 0.24.x
Diffstat (limited to 'lib')
-rwxr-xr-xlib/puppet/external/nagios.rb50
-rwxr-xr-xlib/puppet/external/nagios/base.rb421
-rw-r--r--lib/puppet/external/nagios/grammar.ry188
-rw-r--r--lib/puppet/external/nagios/makefile9
-rw-r--r--lib/puppet/external/nagios/parser.rb816
-rw-r--r--lib/puppet/provider/naginator.rb55
-rwxr-xr-xlib/puppet/provider/parsedfile.rb8
-rw-r--r--lib/puppet/type/nagios_command.rb3
-rw-r--r--lib/puppet/type/nagios_contact.rb3
-rw-r--r--lib/puppet/type/nagios_contactgroup.rb3
-rw-r--r--lib/puppet/type/nagios_host.rb3
-rw-r--r--lib/puppet/type/nagios_hostextinfo.rb3
-rw-r--r--lib/puppet/type/nagios_hostgroup.rb3
-rw-r--r--lib/puppet/type/nagios_hostgroupescalation.rb3
-rw-r--r--lib/puppet/type/nagios_service.rb3
-rw-r--r--lib/puppet/type/nagios_servicedependency.rb3
-rw-r--r--lib/puppet/type/nagios_serviceescalation.rb3
-rw-r--r--lib/puppet/type/nagios_serviceextinfo.rb3
-rw-r--r--lib/puppet/type/nagios_timeperiod.rb3
-rw-r--r--lib/puppet/util/nagios_maker.rb56
20 files changed, 1638 insertions, 1 deletions
diff --git a/lib/puppet/external/nagios.rb b/lib/puppet/external/nagios.rb
new file mode 100755
index 000000000..78459fcb6
--- /dev/null
+++ b/lib/puppet/external/nagios.rb
@@ -0,0 +1,50 @@
+#!/usr/local/bin/ruby -w
+
+#--------------------
+# A script to retrieve hosts from ldap and create an importable
+# cfservd file from them
+#
+# $Id: nagios.rb,v 1.3 2004/06/09 20:32:46 luke Exp $
+
+require 'digest/md5'
+#require 'ldap'
+require 'puppet/external/nagios/parser.rb'
+require 'puppet/external/nagios/base.rb'
+
+module Nagios
+ NAGIOSVERSION = '1.1'
+ # yay colors
+ PINK = ""
+ GREEN = ""
+ YELLOW = ""
+ SLATE = ""
+ ORANGE = ""
+ BLUE = ""
+ NOCOLOR = ""
+ RESET = ""
+
+ def self.version
+ NAGIOSVERSION
+ end
+
+ class Config
+ def Config.import(config)
+
+ text = String.new
+
+ File.open(config) { |file|
+ file.each { |line|
+ text += line
+ }
+ }
+ parser = Nagios::Parser.new
+ return parser.parse(text)
+ end
+
+ def Config.each
+ Nagios::Object.objects.each { |object|
+ yield object
+ }
+ end
+ end
+end
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$
diff --git a/lib/puppet/external/nagios/grammar.ry b/lib/puppet/external/nagios/grammar.ry
new file mode 100644
index 000000000..f50818f1a
--- /dev/null
+++ b/lib/puppet/external/nagios/grammar.ry
@@ -0,0 +1,188 @@
+# vim: syntax=ruby
+class Nagios::Parser
+
+token DEFINE NAME STRING PARAM LCURLY RCURLY VALUE RETURN COMMENT INLINECOMMENT
+
+rule
+decls: decl { return val[0] if val[0] }
+ | decls decl {
+ if val[1].nil?
+ result = val[0]
+ else
+ if val[0].nil?
+ result = val[1]
+ else
+ result = [ val[0], val[1] ].flatten
+ end
+ end
+ }
+ ;
+
+decl: object { result = [val[0]] }
+ | RETURN { result = nil }
+ | comment
+ ;
+
+comment: COMMENT RETURN { result = nil }
+ ;
+
+object: DEFINE NAME LCURLY RETURN vars RCURLY {
+ result = Nagios::Base.create(val[1],val[4])
+ }
+ ;
+
+vars: var
+ | vars var {
+ val[1].each {|p,v|
+ val[0][p] = v
+ }
+ result = val[0]
+ }
+ ;
+
+var: PARAM VALUE icomment returns { result = {val[0],val[1]} }
+ ;
+
+returns: RETURN
+ | returns RETURN
+ ;
+
+icomment: # nothing
+ | INLINECOMMENT
+ ;
+
+end
+
+----inner
+
+def parse(src)
+ @src = src
+
+ # state variables
+ @invar = false
+ @inobject = false
+ @done = false
+
+ @line = 0
+ @yydebug = true
+
+ begin
+ do_parse
+ rescue SyntaxError
+ $stderr.print "#{$!}\n"
+ exit
+ end
+end
+
+# The lexer. Very simple.
+def token
+ @src.sub!(/\A\n/,'')
+ if $&
+ @line += 1
+ return [ :RETURN, "\n" ]
+ end
+
+ if @done
+ return nil
+ end
+ yytext = String.new
+
+
+ # remove comments from this line
+ @src.sub!(/\A[ \t]*;.*\n/,"\n")
+ if $&
+ return [:INLINECOMMENT, ""]
+ end
+
+ @src.sub!(/\A#.*\n/,"\n")
+ if $&
+ return [:COMMENT, ""]
+ end
+
+ @src.sub!(/#.*/,'')
+
+ if @src.length == 0
+ @done = true
+ return [false, '$']
+ end
+
+ if @invar
+ @src.sub!(/\A[ \t]+/,'')
+ @src.sub!(/\A([^;\n]+)(\n|;)/,'\2')
+ if $1
+ yytext += $1
+ end
+ @invar = false
+ return [:VALUE, yytext]
+ else
+ @src.sub!(/\A[\t ]*(\S+)([\t ]*|$)/,'')
+ if $1
+ yytext = $1
+ case yytext
+ when 'define'
+ #puts "got define"
+ return [:DEFINE, yytext]
+ when '{'
+ #puts "got {"
+ @inobject = true
+ return [:LCURLY, yytext]
+ else
+ unless @inobject
+ #puts "got type: #{yytext}"
+ if yytext =~ /\W/
+ giveback = yytext.dup
+ giveback.sub!(/^\w+/,'')
+ #puts "giveback " + giveback
+ #puts "yytext " + yytext
+ yytext.sub!(/\W.*$/,'')
+ #puts "yytext " + yytext
+ #puts "all [#{giveback} #{yytext} #{orig}]"
+ @src = giveback + @src
+ end
+ return [:NAME, yytext]
+ else
+ if yytext == '}'
+ #puts "got closure: #{yytext}"
+ @inobject = false
+ return [:RCURLY, '}']
+ end
+
+ unless @invar
+ @invar = true
+ return [:PARAM, $1]
+ else
+ end
+ end
+ end
+ end
+ end
+end
+
+def next_token
+ token
+end
+
+def yydebug
+ 1
+end
+
+def yywrap
+ 0
+end
+
+def on_error(token, value, vstack )
+ msg = ""
+ unless value.nil?
+ msg = "line #{@line}: syntax error at '#{value}'"
+ else
+ msg = "line #{@line}: syntax error at '#{token}'"
+ end
+ unless @src.size > 0
+ msg = "line #{@line}: Unexpected end of file"
+ end
+ if token == '$end'.intern
+ puts "okay, this is silly"
+ else
+ raise SyntaxError, msg
+ end
+end
diff --git a/lib/puppet/external/nagios/makefile b/lib/puppet/external/nagios/makefile
new file mode 100644
index 000000000..fc14564b7
--- /dev/null
+++ b/lib/puppet/external/nagios/makefile
@@ -0,0 +1,9 @@
+all: parser.rb
+
+debug: parser.rb setdebug
+
+parser.rb: grammar.ry
+ racc -E -oparser.rb grammar.ry
+
+setdebug:
+ perl -pi -e 's{\@yydebug =.*$$}{\@yydebug = true}' parser.rb
diff --git a/lib/puppet/external/nagios/parser.rb b/lib/puppet/external/nagios/parser.rb
new file mode 100644
index 000000000..b7e2c21d8
--- /dev/null
+++ b/lib/puppet/external/nagios/parser.rb
@@ -0,0 +1,816 @@
+#
+# DO NOT MODIFY!!!!
+# This file is automatically generated by racc 1.4.4
+# from racc grammer file "grammar.ry".
+#
+#
+# parser.rb: generated by racc (runtime embedded)
+#
+
+###### racc/parser.rb
+
+unless $".index 'racc/parser.rb'
+$".push 'racc/parser.rb'
+
+self.class.module_eval <<'..end /usr/lib/ruby/1.8/racc/parser.rb modeval..id1306b79176', '/usr/lib/ruby/1.8/racc/parser.rb', 1
+#
+# parser.rb
+#
+# Copyright (c) 1999-2003 Minero Aoki <aamine@loveruby.net>
+#
+# This program is free software.
+# You can distribute/modify this program under the same terms of ruby.
+#
+# As a special exception, when this code is copied by Racc
+# into a Racc output file, you may use that output file
+# without restriction.
+#
+# $raccId: parser.rb,v 1.4 2003/11/03 13:41:47 aamine Exp $
+#
+
+unless defined?(NotImplementedError)
+ NotImplementedError = NotImplementError
+end
+
+module Racc
+ class ParseError < StandardError; end
+end
+unless defined?(::ParseError)
+ ParseError = Racc::ParseError
+end
+
+
+module Racc
+
+ unless defined?(Racc_No_Extentions)
+ Racc_No_Extentions = false
+ end
+
+ class Parser
+
+ Racc_Runtime_Version = '1.4.4'
+ Racc_Runtime_Revision = '$raccRevision: 1.4 $'.split[1]
+
+ Racc_Runtime_Core_Version_R = '1.4.4'
+ Racc_Runtime_Core_Revision_R = '$raccRevision: 1.4 $'.split[1]
+ begin
+ require 'racc/cparse'
+ # Racc_Runtime_Core_Version_C = (defined in extension)
+ Racc_Runtime_Core_Revision_C = Racc_Runtime_Core_Id_C.split[2]
+ unless new.respond_to?(:_racc_do_parse_c, true)
+ raise LoadError, 'old cparse.so'
+ end
+ if Racc_No_Extentions
+ raise LoadError, 'selecting ruby version of racc runtime core'
+ end
+
+ Racc_Main_Parsing_Routine = :_racc_do_parse_c
+ Racc_YY_Parse_Method = :_racc_yyparse_c
+ Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_C
+ Racc_Runtime_Core_Revision = Racc_Runtime_Core_Revision_C
+ Racc_Runtime_Type = 'c'
+ rescue LoadError
+ Racc_Main_Parsing_Routine = :_racc_do_parse_rb
+ Racc_YY_Parse_Method = :_racc_yyparse_rb
+ Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_R
+ Racc_Runtime_Core_Revision = Racc_Runtime_Core_Revision_R
+ Racc_Runtime_Type = 'ruby'
+ end
+
+ def Parser.racc_runtime_type
+ Racc_Runtime_Type
+ end
+
+ private
+
+ def _racc_setup
+ @yydebug = false unless self.class::Racc_debug_parser
+ @yydebug = false unless defined?(@yydebug)
+ if @yydebug
+ @racc_debug_out = $stderr unless defined?(@racc_debug_out)
+ @racc_debug_out ||= $stderr
+ end
+ arg = self.class::Racc_arg
+ arg[13] = true if arg.size < 14
+ arg
+ end
+
+ def _racc_init_sysvars
+ @racc_state = [0]
+ @racc_tstack = []
+ @racc_vstack = []
+
+ @racc_t = nil
+ @racc_val = nil
+
+ @racc_read_next = true
+
+ @racc_user_yyerror = false
+ @racc_error_status = 0
+ end
+
+ ###
+ ### do_parse
+ ###
+
+ def do_parse
+ __send__(Racc_Main_Parsing_Routine, _racc_setup(), false)
+ end
+
+ def next_token
+ raise NotImplementedError, "#{self.class}\#next_token is not defined"
+ end
+
+ def _racc_do_parse_rb( arg, in_debug )
+ action_table, action_check, action_default, action_pointer,
+ goto_table, goto_check, goto_default, goto_pointer,
+ nt_base, reduce_table, token_table, shift_n,
+ reduce_n, use_result, * = arg
+
+ _racc_init_sysvars
+ tok = act = i = nil
+ nerr = 0
+
+ catch(:racc_end_parse) {
+ while true
+ if i = action_pointer[@racc_state[-1]]
+ if @racc_read_next
+ if @racc_t != 0 # not EOF
+ tok, @racc_val = next_token()
+ unless tok # EOF
+ @racc_t = 0
+ else
+ @racc_t = (token_table[tok] or 1) # error token
+ end
+ racc_read_token(@racc_t, tok, @racc_val) if @yydebug
+ @racc_read_next = false
+ end
+ end
+ i += @racc_t
+ unless i >= 0 and
+ act = action_table[i] and
+ action_check[i] == @racc_state[-1]
+ act = action_default[@racc_state[-1]]
+ end
+ else
+ act = action_default[@racc_state[-1]]
+ end
+ while act = _racc_evalact(act, arg)
+ ;
+ end
+ end
+ }
+ end
+
+ ###
+ ### yyparse
+ ###
+
+ def yyparse( recv, mid )
+ __send__(Racc_YY_Parse_Method, recv, mid, _racc_setup(), true)
+ end
+
+ def _racc_yyparse_rb( recv, mid, arg, c_debug )
+ action_table, action_check, action_default, action_pointer,
+ goto_table, goto_check, goto_default, goto_pointer,
+ nt_base, reduce_table, token_table, shift_n,
+ reduce_n, use_result, * = arg
+
+ _racc_init_sysvars
+ tok = nil
+ act = nil
+ i = nil
+ nerr = 0
+
+ catch(:racc_end_parse) {
+ until i = action_pointer[@racc_state[-1]]
+ while act = _racc_evalact(action_default[@racc_state[-1]], arg)
+ ;
+ end
+ end
+ recv.__send__(mid) do |tok, val|
+# $stderr.puts "rd: tok=#{tok}, val=#{val}"
+ unless tok
+ @racc_t = 0
+ else
+ @racc_t = (token_table[tok] or 1) # error token
+ end
+ @racc_val = val
+ @racc_read_next = false
+
+ i += @racc_t
+ unless i >= 0 and
+ act = action_table[i] and
+ action_check[i] == @racc_state[-1]
+ act = action_default[@racc_state[-1]]
+# $stderr.puts "02: act=#{act}"
+# $stderr.puts "curstate=#{@racc_state[-1]}"
+ else
+# $stderr.puts "01: act=#{act}"
+ end
+
+ while act = _racc_evalact(act, arg)
+ ;
+ end
+
+ while not (i = action_pointer[@racc_state[-1]]) or
+ not @racc_read_next or
+ @racc_t == 0 # $
+ unless i and i += @racc_t and
+ i >= 0 and
+ act = action_table[i] and
+ action_check[i] == @racc_state[-1]
+ act = action_default[@racc_state[-1]]
+# $stderr.puts "04: act=#{act}"
+ else
+# $stderr.puts "03: act=#{act}"
+ end
+ while act = _racc_evalact(act, arg)
+ ;
+ end
+ end
+ end
+ }
+ end
+
+ ###
+ ### common
+ ###
+
+ def _racc_evalact( act, arg )
+# $stderr.puts "ea: act=#{act}"
+ action_table, action_check, action_default, action_pointer,
+ goto_table, goto_check, goto_default, goto_pointer,
+ nt_base, reduce_table, token_table, shift_n,
+ reduce_n, use_result, * = arg
+nerr = 0 # tmp
+
+ if act > 0 and act < shift_n
+ #
+ # shift
+ #
+ if @racc_error_status > 0
+ @racc_error_status -= 1 unless @racc_t == 1 # error token
+ end
+ @racc_vstack.push @racc_val
+ @racc_state.push act
+ @racc_read_next = true
+ if @yydebug
+ @racc_tstack.push @racc_t
+ racc_shift @racc_t, @racc_tstack, @racc_vstack
+ end
+
+ elsif act < 0 and act > -reduce_n
+ #
+ # reduce
+ #
+ code = catch(:racc_jump) {
+ @racc_state.push _racc_do_reduce(arg, act)
+ false
+ }
+ if code
+ case code
+ when 1 # yyerror
+ @racc_user_yyerror = true # user_yyerror
+ return -reduce_n
+ when 2 # yyaccept
+ return shift_n
+ else
+ raise RuntimeError, '[Racc Bug] unknown jump code'
+ end
+ end
+
+ elsif act == shift_n
+ #
+ # accept
+ #
+ racc_accept if @yydebug
+ throw :racc_end_parse, @racc_vstack[0]
+
+ elsif act == -reduce_n
+ #
+ # error
+ #
+ case @racc_error_status
+ when 0
+ unless arg[21] # user_yyerror
+ nerr += 1
+ on_error @racc_t, @racc_val, @racc_vstack
+ end
+ when 3
+ if @racc_t == 0 # is $
+ throw :racc_end_parse, nil
+ end
+ @racc_read_next = true
+ end
+ @racc_user_yyerror = false
+ @racc_error_status = 3
+ while true
+ if i = action_pointer[@racc_state[-1]]
+ i += 1 # error token
+ if i >= 0 and
+ (act = action_table[i]) and
+ action_check[i] == @racc_state[-1]
+ break
+ end
+ end
+
+ throw :racc_end_parse, nil if @racc_state.size <= 1
+ @racc_state.pop
+ @racc_vstack.pop
+ if @yydebug
+ @racc_tstack.pop
+ racc_e_pop @racc_state, @racc_tstack, @racc_vstack
+ end
+ end
+ return act
+
+ else
+ raise RuntimeError, "[Racc Bug] unknown action #{act.inspect}"
+ end
+
+ racc_next_state(@racc_state[-1], @racc_state) if @yydebug
+
+ nil
+ end
+
+ def _racc_do_reduce( arg, act )
+ action_table, action_check, action_default, action_pointer,
+ goto_table, goto_check, goto_default, goto_pointer,
+ nt_base, reduce_table, token_table, shift_n,
+ reduce_n, use_result, * = arg
+ state = @racc_state
+ vstack = @racc_vstack
+ tstack = @racc_tstack
+
+ i = act * -3
+ len = reduce_table[i]
+ reduce_to = reduce_table[i+1]
+ method_id = reduce_table[i+2]
+ void_array = []
+
+ tmp_t = tstack[-len, len] if @yydebug
+ tmp_v = vstack[-len, len]
+ tstack[-len, len] = void_array if @yydebug
+ vstack[-len, len] = void_array
+ state[-len, len] = void_array
+
+ # tstack must be updated AFTER method call
+ if use_result
+ vstack.push __send__(method_id, tmp_v, vstack, tmp_v[0])
+ else
+ vstack.push __send__(method_id, tmp_v, vstack)
+ end
+ tstack.push reduce_to
+
+ racc_reduce(tmp_t, reduce_to, tstack, vstack) if @yydebug
+
+ k1 = reduce_to - nt_base
+ if i = goto_pointer[k1]
+ i += state[-1]
+ if i >= 0 and (curstate = goto_table[i]) and goto_check[i] == k1
+ return curstate
+ end
+ end
+ goto_default[k1]
+ end
+
+ def on_error( t, val, vstack )
+ raise ParseError, sprintf("\nparse error on value %s (%s)",
+ val.inspect, token_to_str(t) || '?')
+ end
+
+ def yyerror
+ throw :racc_jump, 1
+ end
+
+ def yyaccept
+ throw :racc_jump, 2
+ end
+
+ def yyerrok
+ @racc_error_status = 0
+ end
+
+ #
+ # for debugging output
+ #
+
+ def racc_read_token( t, tok, val )
+ @racc_debug_out.print 'read '
+ @racc_debug_out.print tok.inspect, '(', racc_token2str(t), ') '
+ @racc_debug_out.puts val.inspect
+ @racc_debug_out.puts
+ end
+
+ def racc_shift( tok, tstack, vstack )
+ @racc_debug_out.puts "shift #{racc_token2str tok}"
+ racc_print_stacks tstack, vstack
+ @racc_debug_out.puts
+ end
+
+ def racc_reduce( toks, sim, tstack, vstack )
+ out = @racc_debug_out
+ out.print 'reduce '
+ if toks.empty?
+ out.print ' <none>'
+ else
+ toks.each {|t| out.print ' ', racc_token2str(t) }
+ end
+ out.puts " --> #{racc_token2str(sim)}"
+
+ racc_print_stacks tstack, vstack
+ @racc_debug_out.puts
+ end
+
+ def racc_accept
+ @racc_debug_out.puts 'accept'
+ @racc_debug_out.puts
+ end
+
+ def racc_e_pop( state, tstack, vstack )
+ @racc_debug_out.puts 'error recovering mode: pop token'
+ racc_print_states state
+ racc_print_stacks tstack, vstack
+ @racc_debug_out.puts
+ end
+
+ def racc_next_state( curstate, state )
+ @racc_debug_out.puts "goto #{curstate}"
+ racc_print_states state
+ @racc_debug_out.puts
+ end
+
+ def racc_print_stacks( t, v )
+ out = @racc_debug_out
+ out.print ' ['
+ t.each_index do |i|
+ out.print ' (', racc_token2str(t[i]), ' ', v[i].inspect, ')'
+ end
+ out.puts ' ]'
+ end
+
+ def racc_print_states( s )
+ out = @racc_debug_out
+ out.print ' ['
+ s.each {|st| out.print ' ', st }
+ out.puts ' ]'
+ end
+
+ def racc_token2str( tok )
+ self.class::Racc_token_to_s_table[tok] or
+ raise RuntimeError, "[Racc Bug] can't convert token #{tok} to string"
+ end
+
+ def token_to_str( t )
+ self.class::Racc_token_to_s_table[t]
+ end
+
+ end
+
+end
+..end /usr/lib/ruby/1.8/racc/parser.rb modeval..id1306b79176
+end # end of racc/parser.rb
+
+
+module Nagios
+
+ class Parser < Racc::Parser
+
+module_eval <<'..end grammar.ry modeval..id458299781d', 'grammar.ry', 57
+
+def parse(src)
+ @src = src
+
+ # state variables
+ @invar = false
+ @inobject = false
+ @done = false
+
+ @line = 0
+ @yydebug = true
+
+ begin
+ do_parse
+ rescue SyntaxError
+ $stderr.print "#{$!}\n"
+ exit
+ end
+end
+
+# The lexer. Very simple.
+def token
+ @src.sub!(/\A\n/,'')
+ if $&
+ @line += 1
+ return [ :RETURN, "\n" ]
+ end
+
+ if @done
+ return nil
+ end
+ yytext = String.new
+
+
+ # remove comments from this line
+ @src.sub!(/\A[ \t]*;.*\n/,"\n")
+ if $&
+ return [:INLINECOMMENT, ""]
+ end
+
+ @src.sub!(/\A#.*\n/,"\n")
+ if $&
+ return [:COMMENT, ""]
+ end
+
+ @src.sub!(/#.*/,'')
+
+ if @src.length == 0
+ @done = true
+ return [false, '$']
+ end
+
+ if @invar
+ @src.sub!(/\A[ \t]+/,'')
+ @src.sub!(/\A([^;\n]+)(\n|;)/,'\2')
+ if $1
+ yytext += $1
+ end
+ @invar = false
+ return [:VALUE, yytext]
+ else
+ @src.sub!(/\A[\t ]*(\S+)([\t ]*|$)/,'')
+ if $1
+ yytext = $1
+ case yytext
+ when 'define'
+ #puts "got define"
+ return [:DEFINE, yytext]
+ when '{'
+ #puts "got {"
+ @inobject = true
+ return [:LCURLY, yytext]
+ else
+ unless @inobject
+ #puts "got type: #{yytext}"
+ if yytext =~ /\W/
+ giveback = yytext.dup
+ giveback.sub!(/^\w+/,'')
+ #puts "giveback " + giveback
+ #puts "yytext " + yytext
+ yytext.sub!(/\W.*$/,'')
+ #puts "yytext " + yytext
+ #puts "all [#{giveback} #{yytext} #{orig}]"
+ @src = giveback + @src
+ end
+ return [:NAME, yytext]
+ else
+ if yytext == '}'
+ #puts "got closure: #{yytext}"
+ @inobject = false
+ return [:RCURLY, '}']
+ end
+
+ unless @invar
+ @invar = true
+ return [:PARAM, $1]
+ else
+ end
+ end
+ end
+ end
+ end
+end
+
+def next_token
+ token
+end
+
+def yydebug
+ 1
+end
+
+def yywrap
+ 0
+end
+
+def on_error(token, value, vstack )
+ msg = ""
+ unless value.nil?
+ msg = "line #{@line}: syntax error at '#{value}'"
+ else
+ msg = "line #{@line}: syntax error at '#{token}'"
+ end
+ unless @src.size > 0
+ msg = "line #{@line}: Unexpected end of file"
+ end
+ if token == '$end'.intern
+ puts "okay, this is silly"
+ else
+ raise SyntaxError, msg
+ end
+end
+..end grammar.ry modeval..id458299781d
+
+##### racc 1.4.4 generates ###
+
+racc_reduce_table = [
+ 0, 0, :racc_error,
+ 1, 13, :_reduce_1,
+ 2, 13, :_reduce_2,
+ 1, 14, :_reduce_3,
+ 1, 14, :_reduce_4,
+ 1, 14, :_reduce_none,
+ 2, 16, :_reduce_6,
+ 6, 15, :_reduce_7,
+ 1, 17, :_reduce_none,
+ 2, 17, :_reduce_9,
+ 4, 18, :_reduce_10,
+ 1, 20, :_reduce_none,
+ 2, 20, :_reduce_none,
+ 0, 19, :_reduce_none,
+ 1, 19, :_reduce_none ]
+
+racc_reduce_n = 15
+
+racc_shift_n = 26
+
+racc_action_table = [
+ 9, 15, 1, 20, 1, 14, 12, 13, 11, 6,
+ 7, 6, 7, 15, 18, 8, 21, 23, 25 ]
+
+racc_action_check = [
+ 2, 16, 2, 16, 0, 12, 8, 9, 7, 2,
+ 2, 0, 0, 14, 15, 1, 18, 22, 24 ]
+
+racc_action_pointer = [
+ 2, 12, 0, nil, nil, nil, nil, -1, 0, 7,
+ nil, nil, -4, nil, 8, 6, -4, nil, 5, nil,
+ nil, nil, 8, nil, 9, nil ]
+
+racc_action_default = [
+ -15, -15, -15, -1, -3, -5, -4, -15, -15, -15,
+ -2, -6, -15, 26, -15, -15, -15, -8, -13, -9,
+ -7, -14, -15, -11, -10, -12 ]
+
+racc_goto_table = [
+ 17, 3, 19, 10, 2, 16, 22, 24 ]
+
+racc_goto_check = [
+ 6, 2, 6, 2, 1, 5, 7, 8 ]
+
+racc_goto_pointer = [
+ nil, 4, 1, nil, nil, -9, -14, -12, -15 ]
+
+racc_goto_default = [
+ nil, nil, nil, 4, 5, nil, nil, nil, nil ]
+
+racc_token_table = {
+ false => 0,
+ Object.new => 1,
+ :DEFINE => 2,
+ :NAME => 3,
+ :STRING => 4,
+ :PARAM => 5,
+ :LCURLY => 6,
+ :RCURLY => 7,
+ :VALUE => 8,
+ :RETURN => 9,
+ :COMMENT => 10,
+ :INLINECOMMENT => 11 }
+
+racc_use_result_var = true
+
+racc_nt_base = 12
+
+Racc_arg = [
+ racc_action_table,
+ racc_action_check,
+ racc_action_default,
+ racc_action_pointer,
+ racc_goto_table,
+ racc_goto_check,
+ racc_goto_default,
+ racc_goto_pointer,
+ racc_nt_base,
+ racc_reduce_table,
+ racc_token_table,
+ racc_shift_n,
+ racc_reduce_n,
+ racc_use_result_var ]
+
+Racc_token_to_s_table = [
+'$end',
+'error',
+'DEFINE',
+'NAME',
+'STRING',
+'PARAM',
+'LCURLY',
+'RCURLY',
+'VALUE',
+'RETURN',
+'COMMENT',
+'INLINECOMMENT',
+'$start',
+'decls',
+'decl',
+'object',
+'comment',
+'vars',
+'var',
+'icomment',
+'returns']
+
+Racc_debug_parser = false
+
+##### racc system variables end #####
+
+ # reduce 0 omitted
+
+module_eval <<'.,.,', 'grammar.ry', 6
+ def _reduce_1( val, _values, result )
+ return val[0] if val[0]
+ result
+ end
+.,.,
+
+module_eval <<'.,.,', 'grammar.ry', 18
+ def _reduce_2( val, _values, result )
+ if val[1].nil?
+ result = val[0]
+ else
+ if val[0].nil?
+ result = val[1]
+ else
+ result = [ val[0], val[1] ].flatten
+ end
+ end
+ result
+ end
+.,.,
+
+module_eval <<'.,.,', 'grammar.ry', 20
+ def _reduce_3( val, _values, result )
+ result = [val[0]]
+ result
+ end
+.,.,
+
+module_eval <<'.,.,', 'grammar.ry', 21
+ def _reduce_4( val, _values, result )
+ result = nil
+ result
+ end
+.,.,
+
+ # reduce 5 omitted
+
+module_eval <<'.,.,', 'grammar.ry', 25
+ def _reduce_6( val, _values, result )
+ result = nil
+ result
+ end
+.,.,
+
+module_eval <<'.,.,', 'grammar.ry', 31
+ def _reduce_7( val, _values, result )
+ result = Nagios::Base.create(val[1],val[4])
+ result
+ end
+.,.,
+
+ # reduce 8 omitted
+
+module_eval <<'.,.,', 'grammar.ry', 40
+ def _reduce_9( val, _values, result )
+ val[1].each {|p,v|
+ val[0][p] = v
+ }
+ result = val[0]
+ result
+ end
+.,.,
+
+module_eval <<'.,.,', 'grammar.ry', 42
+ def _reduce_10( val, _values, result )
+ result = {val[0],val[1]}
+ result
+ end
+.,.,
+
+ # reduce 11 omitted
+
+ # reduce 12 omitted
+
+ # reduce 13 omitted
+
+ # reduce 14 omitted
+
+ def _reduce_none( val, _values, result )
+ result
+ end
+
+ end # class Parser
+
+end # module Nagios
diff --git a/lib/puppet/provider/naginator.rb b/lib/puppet/provider/naginator.rb
new file mode 100644
index 000000000..8e8a3d65e
--- /dev/null
+++ b/lib/puppet/provider/naginator.rb
@@ -0,0 +1,55 @@
+# Created by Luke Kanies on 2007-11-27.
+# Copyright (c) 2007. All rights reserved.
+
+require 'puppet'
+require 'puppet/provider/parsedfile'
+require 'puppet/external/nagios'
+
+# The base class for all Naginator providers.
+class Puppet::Provider::Naginator < Puppet::Provider::ParsedFile
+ # Retrieve the associated class from Nagios::Base.
+ def self.nagios_type
+ unless defined?(@nagios_type) and @nagios_type
+ name = resource_type.name.to_s.sub(/^nagios_/, '')
+ unless @nagios_type = Nagios::Base.type(name.to_sym)
+ raise Puppet::DevError, "Could not find nagios type '%s'" % name
+ end
+
+ # And add our 'ensure' settings, since they aren't a part of
+ # Naginator by default
+ @nagios_type.send(:attr_accessor, :ensure, :target, :on_disk)
+ end
+ @nagios_type
+ end
+
+ def self.parse(text)
+ Nagios::Parser.new.parse(text)
+ end
+
+ def self.to_file(records)
+ header + records.collect { |record| record.to_s }.join("\n")
+ end
+
+ def self.skip_record?(record)
+ false
+ end
+
+ def self.valid_attr?(klass, attr_name)
+ nagios_type.parameters.include?(attr_name)
+ end
+
+ def initialize(resource = nil)
+ if resource.is_a?(Nagios::Base)
+ # We don't use a duplicate here, because some providers (ParsedFile, at least)
+ # use the hash here for later events.
+ @property_hash = resource
+ elsif resource
+ @resource = resource if resource
+ # LAK 2007-05-09: Keep the model stuff around for backward compatibility
+ @model = resource
+ @property_hash = self.class.nagios_type.new
+ else
+ @property_hash = self.class.nagios_type.new
+ end
+ end
+end
diff --git a/lib/puppet/provider/parsedfile.rb b/lib/puppet/provider/parsedfile.rb
index 76654c4f4..b4a4a3b91 100755
--- a/lib/puppet/provider/parsedfile.rb
+++ b/lib/puppet/provider/parsedfile.rb
@@ -180,7 +180,7 @@ class Puppet::Provider::ParsedFile < Puppet::Provider
matchers = resources.dup
@records.each do |record|
# Skip things like comments and blank lines
- next if record_type(record[:record_type]).text?
+ next if skip_record?(record)
if name = record[:name] and resource = resources[name]
resource.provider = new(record)
@@ -243,6 +243,12 @@ class Puppet::Provider::ParsedFile < Puppet::Provider
end
end
+ # Should we skip the record? Basically, we skip text records.
+ # This is only here so subclasses can override it.
+ def self.skip_record?(record)
+ record_type(record[:record_type]).text?
+ end
+
# Initialize the object if necessary.
def self.target_object(target)
@target_objects[target] ||= filetype.new(target)
diff --git a/lib/puppet/type/nagios_command.rb b/lib/puppet/type/nagios_command.rb
new file mode 100644
index 000000000..0d0e11b17
--- /dev/null
+++ b/lib/puppet/type/nagios_command.rb
@@ -0,0 +1,3 @@
+require 'puppet/util/nagios_maker'
+
+Puppet::Util::NagiosMaker.create_nagios_type :command
diff --git a/lib/puppet/type/nagios_contact.rb b/lib/puppet/type/nagios_contact.rb
new file mode 100644
index 000000000..d5a1f3cba
--- /dev/null
+++ b/lib/puppet/type/nagios_contact.rb
@@ -0,0 +1,3 @@
+require 'puppet/util/nagios_maker'
+
+Puppet::Util::NagiosMaker.create_nagios_type :contact
diff --git a/lib/puppet/type/nagios_contactgroup.rb b/lib/puppet/type/nagios_contactgroup.rb
new file mode 100644
index 000000000..b8f14c07b
--- /dev/null
+++ b/lib/puppet/type/nagios_contactgroup.rb
@@ -0,0 +1,3 @@
+require 'puppet/util/nagios_maker'
+
+Puppet::Util::NagiosMaker.create_nagios_type :contactgroup
diff --git a/lib/puppet/type/nagios_host.rb b/lib/puppet/type/nagios_host.rb
new file mode 100644
index 000000000..f2e03f6fb
--- /dev/null
+++ b/lib/puppet/type/nagios_host.rb
@@ -0,0 +1,3 @@
+require 'puppet/util/nagios_maker'
+
+Puppet::Util::NagiosMaker.create_nagios_type :host
diff --git a/lib/puppet/type/nagios_hostextinfo.rb b/lib/puppet/type/nagios_hostextinfo.rb
new file mode 100644
index 000000000..da8e08dd8
--- /dev/null
+++ b/lib/puppet/type/nagios_hostextinfo.rb
@@ -0,0 +1,3 @@
+require 'puppet/util/nagios_maker'
+
+Puppet::Util::NagiosMaker.create_nagios_type :hostextinfo
diff --git a/lib/puppet/type/nagios_hostgroup.rb b/lib/puppet/type/nagios_hostgroup.rb
new file mode 100644
index 000000000..e1943beec
--- /dev/null
+++ b/lib/puppet/type/nagios_hostgroup.rb
@@ -0,0 +1,3 @@
+require 'puppet/util/nagios_maker'
+
+Puppet::Util::NagiosMaker.create_nagios_type :hostgroup
diff --git a/lib/puppet/type/nagios_hostgroupescalation.rb b/lib/puppet/type/nagios_hostgroupescalation.rb
new file mode 100644
index 000000000..21b39f681
--- /dev/null
+++ b/lib/puppet/type/nagios_hostgroupescalation.rb
@@ -0,0 +1,3 @@
+require 'puppet/util/nagios_maker'
+
+Puppet::Util::NagiosMaker.create_nagios_type :hostgroupescalation
diff --git a/lib/puppet/type/nagios_service.rb b/lib/puppet/type/nagios_service.rb
new file mode 100644
index 000000000..22b987f56
--- /dev/null
+++ b/lib/puppet/type/nagios_service.rb
@@ -0,0 +1,3 @@
+require 'puppet/util/nagios_maker'
+
+Puppet::Util::NagiosMaker.create_nagios_type :service
diff --git a/lib/puppet/type/nagios_servicedependency.rb b/lib/puppet/type/nagios_servicedependency.rb
new file mode 100644
index 000000000..0e3340c6e
--- /dev/null
+++ b/lib/puppet/type/nagios_servicedependency.rb
@@ -0,0 +1,3 @@
+require 'puppet/util/nagios_maker'
+
+Puppet::Util::NagiosMaker.create_nagios_type :servicedependency
diff --git a/lib/puppet/type/nagios_serviceescalation.rb b/lib/puppet/type/nagios_serviceescalation.rb
new file mode 100644
index 000000000..cb2af1545
--- /dev/null
+++ b/lib/puppet/type/nagios_serviceescalation.rb
@@ -0,0 +1,3 @@
+require 'puppet/util/nagios_maker'
+
+Puppet::Util::NagiosMaker.create_nagios_type :serviceescalation
diff --git a/lib/puppet/type/nagios_serviceextinfo.rb b/lib/puppet/type/nagios_serviceextinfo.rb
new file mode 100644
index 000000000..6bdc70900
--- /dev/null
+++ b/lib/puppet/type/nagios_serviceextinfo.rb
@@ -0,0 +1,3 @@
+require 'puppet/util/nagios_maker'
+
+Puppet::Util::NagiosMaker.create_nagios_type :serviceextinfo
diff --git a/lib/puppet/type/nagios_timeperiod.rb b/lib/puppet/type/nagios_timeperiod.rb
new file mode 100644
index 000000000..25a06d3ed
--- /dev/null
+++ b/lib/puppet/type/nagios_timeperiod.rb
@@ -0,0 +1,3 @@
+require 'puppet/util/nagios_maker'
+
+Puppet::Util::NagiosMaker.create_nagios_type :timeperiod
diff --git a/lib/puppet/util/nagios_maker.rb b/lib/puppet/util/nagios_maker.rb
new file mode 100644
index 000000000..f1f85466f
--- /dev/null
+++ b/lib/puppet/util/nagios_maker.rb
@@ -0,0 +1,56 @@
+require 'puppet/external/nagios'
+require 'puppet/external/nagios/base'
+require 'puppet/provider/naginator'
+
+module Puppet::Util::NagiosMaker
+ # Create a new nagios type, using all of the parameters
+ # from the parser.
+ def self.create_nagios_type(name)
+ name = name.to_sym
+ full_name = ("nagios_" + name.to_s).to_sym
+
+ raise(Puppet::DevError, "No nagios type for %s" % name) unless nagtype = Nagios::Base.type(name)
+
+ type = Puppet::Type.newtype(full_name) {}
+
+ type.ensurable
+
+ type.newparam(nagtype.namevar, :namevar => true) do
+ desc "The name parameter for Nagios type %s" % nagtype.name
+ end
+
+ # We deduplicate the parameters because it makes sense to allow Naginator to have dupes.
+ nagtype.parameters.uniq.each do |param|
+ next if param == nagtype.namevar
+
+ # We can't turn these parameter names into constants, so at least for now they aren't
+ # supported.
+ next if param.to_s =~ /^[0-9]/
+
+ type.newproperty(param) do
+ desc "Nagios configuration file parameter."
+ end
+ end
+
+ type.newproperty(:target) do
+ desc 'target'
+
+ defaultto do
+ resource.class.defaultprovider.default_target
+ end
+ end
+
+ provider = type.provide(:naginator, :parent => Puppet::Provider::Naginator, :default_target => "/etc/nagios/#{full_name.to_s}.cfg") {}
+
+ type.desc "The Nagios type #{name.to_s}. This resource type is autogenerated using the
+ model developed in Naginator_, and all of the Nagios types are generated using the
+ same code and the same library.
+
+ This type generates Nagios configuration statements in Nagios-parseable configuration
+ files. By default, the statements will be added to ``#{provider.default_target}, but
+ you can send them to a different file by setting their ``target`` attribute.
+
+ .. _naginator: http://reductivelabs.com/trac/naginator
+ "
+ end
+end