Class: Nagios::Objects

Inherits:
Object
  • Object
show all
Defined in:
lib/nagios/objects.rb

Overview

DESCRIPTION

Nagios::Objects – class for parsing Nagios’ objects.cache file. Objects.cache file keeps information about lists of objects being monitored by Nagios. It is created by Nagios process on (re)start. Since it is machine-generated file syntax should not vary from file to file.

Class implements 2 methods at the time of writing:

  • constructor - that only creates an instance and

  • parse method - that does actual parsing and populates instance variable @objects

SYNOPSIS

require 'nagios/objects'

 nagios = Nagios::Objects.new("test/objects.cache").new.parse
 print nagios.objects[:contactgroup]

Files

Location of objects.cache file depends on Nagios configuration (in many cases varies from one UNIX/Linux ditribution to another) and is defined by directive in nagios.cfg file.

On Debian system objects.cache it is in /var/cache/nagios3/objects.cache:

object_cache_file=/var/cache/nagios3/objects.cache

Parsed data hash

irb(main):010:0> pp nagios.objects
 {:timeperiod=>
  {"24x7"=>
    {:timeperiod_name=>"24x7",
     :alias=>"24 Hours A Day, 7 Days A Week",
     :sunday=>"00:00-24:00",
     :monday=>"00:00-24:00",
     :tuesday=>"00:00-24:00",
     :wednesday=>"00:00-24:00",
     :thursday=>"00:00-24:00",
     :friday=>"00:00-24:00",
     :saturday=>"00:00-24:00"},
   "never"=>{:timeperiod_name=>"never", :alias=>"Never"},

Author

Dmytro Kovalov, [email protected] 2011, Dec, 27 - First working version

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ Objects

Returns a new instance of Objects.

Parameters:

  • path (String)

    UNIX path to the objects.cache file

See Also:

  • parse


62
63
64
65
66
67
# File 'lib/nagios/objects.rb', line 62

def initialize path
  raise "File #{path} does not exist" unless File.exist? path
  raise "File #{path} is not readable" unless File.readable? path
  @path = path
  @objects = {}
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(sym, *args, &block) ⇒ Object

Replace standard method_missing with dynamic search methods. Calls internally self.find.

find_*_by and find_all_*. find_all returns Array of hashes.

Parameters:

  • sym (Symbol)

    Should be in the form find(_all)?_<resource>by<attribute>. Similar to ActiveResource find_* dynamic methods. Depending on the name of the method called (find or find_all) will pass message to self.find method, that will call Array#find or Array.find_all accordingly.

Raises:

  • (NoMethodError)

See Also:



199
200
201
202
203
204
205
206
207
208
# File 'lib/nagios/objects.rb', line 199

def method_missing sym, *args, &block
  raise(NoMethodError, "No such method #{sym.to_s} for #{self.class}") unless sym.to_s =~ /^(find(_all)?)_(.*)_by_(.*)$/
  # message - either 'find' of 'find_all'
  # resource - type of objects to search: host, hostgroup etc.
  # attribute - name of the attribute to do search by: :host_name, :check_command
  # @param *args String or Regexp to search objects
  message,resource,attribute  = $1, $3, $4

  self.find resource,message,attribute,args[0]
end

Instance Attribute Details

#objectsObject

Parsed objects



73
74
75
# File 'lib/nagios/objects.rb', line 73

def objects
  @objects
end

#pathObject

PATH to the objects.cache file



70
71
72
# File 'lib/nagios/objects.rb', line 70

def path
  @path
end

Instance Method Details

#find(resource, message, attribute, pattern) ⇒ Object

Basic find function for resources.

Parameters:

  • resource (Symbol)

    Resource to search from: :host, :hostgroup, etc.

  • attribute (Symbol)

    Attribute to use in search. For example, find host by hostname or address, etc. anything that’s defined for this resource

  • message (Symbol)

    Is either ‘find’ or ‘find_all’ passed from caller. In case of ‘find’ returns 1 hash, ‘find_all’ - Array of Hash’es.

  • pattern (String, Regexp)

    Search pattern



171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/nagios/objects.rb', line 171

def find resource, message, attribute, pattern
  self.send(resource.to_sym).values.send(message) do |a| 
    case pattern
    when String
      a[attribute.to_sym] == pattern
    when Regexp
      a[attribute.to_sym] =~ pattern
    else
      raise 'Unknown pattern for search'
    end
    
  end
end

#parseObject

Read objects.cache file and parse it.

Method reads file by blocks. Each block defines one object, definition starts with ‘define <type> {’ and ends with ‘}’. Each block has a ‘<type>_name’ line which defines name of the instance of the object.

Code of the ‘parse()’ method assumes, that _name line is always first in the block! This can be not always the case.

Example of a block:

define contactgroup {
        contactgroup_name       admins
        alias   Nagios Administrators
        members root
        }

Example of a parsed object:

nagios.objects[:contactgroup]
=> {"admins"=>{:contactgroup_name=>"admins", :alias=>"Nagios Administrators", :members=>"root"}}

nagios.contactgroup
=> {"admins"=>{:contactgroup_name=>"admins", :alias=>"Nagios Administrators", :members=>"root"}}

Services are a bit different from other objects, since they are related to hosts, all host’s services are nested under hostname, as:

nagios.service =>
   {"airport"=>
      {"PING"=>
        { :host_name=>"airport",
          :service_description=>"PING",

Convenience methods

Method parse creates helper methods for every type of object after parsing. Same property can be accessed either using Hash @objects (i.e. nagios.objects) or convenience method: nagios.host.



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/nagios/objects.rb', line 122

def parse
  block = {}
  content = File.readlines path
  handler = nil
  content.each do |line|
    case
    when line =~ /^\s*$/ then next # Skip empty lines
    when line =~ /^\s*#/ then next # Skip comments
    when line =~ /(\w+) \{/        # Block starts as "define host {"
      block = {}
      handler = $1.to_sym
    when line =~ /\}/              # End of block
      #
      # Process it. Each block type has line <type>_name in the definition: host_name, command_name
      #
      @objects[handler] ||= {}
      case handler
      when :service
        #
        # Service has service_description,  not name. Nest service
        # hashes under hostnames.
        #
        next unless block[:host_name]
        @objects[handler][block[:host_name]] ||= { }
        @objects[handler][block[:host_name]][block["#{handler.to_s}_description".to_sym]] = block 
      else
        @objects[handler][block["#{handler.to_s}_name".to_sym]] = block 
      end
      block = { }
   when line =~ /^\s*(\w+)\s+([^\{\}]+)$/  # Build Hash from key-value pairs like: "max_check_attempts      10"
      block[$1.to_sym] = $2.strip
    end
  end

  # Create instance methods for easy access to properties
  @objects.each do |key,val|
    instance_variable_set("@#{key}", val)
    instance_eval "def #{key}; return #{val}; end"
  end
  self
end