ruby-nagios 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ pkg
data/README.md ADDED
@@ -0,0 +1,92 @@
1
+ What?
2
+ =====
3
+ Have you ever had to disable alerts, retry a check
4
+ or acknowledge outages on a large amount of service
5
+ with Nagios and hated the web UI for it?
6
+
7
+ This is a CLI tool and Ruby library that parses your
8
+ status log file and let you query it for information
9
+ or create external commands to be piped into the nagios
10
+ command file.
11
+
12
+ You can get this software here on GitHub or via RubyGems
13
+ as *ruby-nagios*
14
+
15
+ Using on the CLI?
16
+ =================
17
+ Find out what services match a regular expression:
18
+
19
+ nagsrv --list-services --with-service /puppet/
20
+ puppet-freshness
21
+ puppetd
22
+ puppetmaster
23
+
24
+ Find hosts with the service /puppet/:
25
+
26
+ nagsrv --list-hosts --with-service /puppet/
27
+ dev1.your.net
28
+ dev2.your.net
29
+ .
30
+ .
31
+
32
+ Disable notifications for them all on all hosts:
33
+
34
+ nagsrv.rb --disable-notify --with-service /puppet/
35
+ [1263129006] DISABLE_SVC_NOTIFICATIONS;dev1.your.net;puppet-freshness
36
+ [1263129006] DISABLE_SVC_NOTIFICATIONS;dev1.your.net;puppetd
37
+ [1263129006] DISABLE_SVC_NOTIFICATIONS;dev1.your.net;puppet-freshness
38
+ .
39
+ .
40
+ .
41
+
42
+ Only do it for hosts matching /dev2/:
43
+
44
+ nagsrv.rb --disable-notify --with-service /puppet/ --for-host /dev2/
45
+ [1263129038] DISABLE_SVC_NOTIFICATIONS;dev2.your.net;puppet-freshness
46
+ [1263129038] DISABLE_SVC_NOTIFICATIONS;dev2.your.net;puppetd
47
+
48
+ You can do ack's, force checks etc, see the help or
49
+ comments in the nagsrv.rb script. To actually get
50
+ nagios to do these actions just redirect the output
51
+ from these commands to the Nagios CMD file. On my
52
+ machine that is /var/log/nagios/rw/nagios.cmd.
53
+
54
+ Using from Ruby?
55
+ ================
56
+
57
+ You can also do the same from within Ruby easily,
58
+ the library lets you search host by any property
59
+ on a service, here we'll find all hosts with
60
+ service /puppet/ on host /dev2/:
61
+
62
+ require 'rubygems'
63
+ require 'nagios/status'
64
+ nagios = Nagios::Status.new
65
+ nagios.parsestatus("status.log")
66
+
67
+ options = {:forhost => "/dev2/", :action => "${host}",
68
+ :withservice => "/puppet/"}
69
+ services = nagios.find_services(options)
70
+
71
+ puts services.join("\n")
72
+
73
+ This will in this case just print:
74
+
75
+ dev2.your.net
76
+
77
+ If you didn't specify the :action string it would
78
+ just return an array of services found. The :action
79
+ string is a template that lets you return the matches
80
+ in any format you like, here's a template to Acknowledge
81
+ services:
82
+
83
+ "[${tstamp}] ACKNOWLEDGE_SVC_PROBLEM;;${host};${service};1 \
84
+ ;0;1;#{ENV['USER']};Acknowledged from CLI"
85
+
86
+ The only variables it supports now is ${host}, ${service}
87
+ and ${tstamp} we can easily add more if needed.
88
+
89
+ Contact?
90
+ ========
91
+
92
+ R.I.Pienaar / rip@devco.net / @ripienaar / http://devco.net/
data/bin/nagsrv CHANGED
@@ -52,8 +52,7 @@
52
52
  # Please open an issue at ruby-nagios.googlecode.com
53
53
  # with any queries
54
54
 
55
- require 'nagios/status'
56
-
55
+ require 'nagios'
57
56
  require 'optparse'
58
57
 
59
58
  statusfile = "status.log"
data/lib/nagios.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'nagios/config'
2
+ require 'nagios/objects'
3
+ require 'nagios/status'
4
+
5
+ class String
6
+ unless method_defined?("each")
7
+ alias_method :each, :each_line
8
+ end
9
+ end
@@ -0,0 +1,64 @@
1
+ module Nagios
2
+
3
+ =begin rdoc
4
+
5
+ Configuration parser for Nagios. Constructor parses Nagios' main
6
+ config file and returns an object: each configuration option's value
7
+ assigned to an instance variable and attribute reader method is
8
+ created.
9
+
10
+ Can be used as:
11
+
12
+ require 'nagios/config'
13
+ nagios = Nagios::Config.new "lib/ruby-nagios/test/data/nagios.cfg"
14
+
15
+ nagios.log_file
16
+ => "/var/log/nagios3/nagios.log"
17
+
18
+ nagios.status_file
19
+ => "/var/cache/nagios3/status.dat"
20
+
21
+
22
+ =end
23
+ class Config
24
+
25
+ DEFAULT_CONFIG = "/etc/nagios*/nagios.cfg"
26
+
27
+ # Read and parse configuration file.
28
+ #
29
+ # @param [String] config_file PATH to the configuration file. If
30
+ # PATH is not provided method will look for configuration file
31
+ # +nagios.cfg+ in +/etc/nagios*+ directory.
32
+ # @note If you have more than one /etc/nagios* directories then
33
+ # only first one will be used. For example, Debian can have
34
+ # both Nagios 2 and 3 installed. In the latter case
35
+ # configuration file is +/etc/nagios3/nagios.cfg+.
36
+ # @author Dmytro Kovalov, dmytro.kovalov@gmail.com
37
+ def initialize config_file=nil
38
+ @config = config_file || Dir.glob(DEFAULT_CONFIG).first
39
+
40
+ raise "No configuration file option and no files in #{DEFAULT_CONFIG} " unless @config
41
+ raise "Configuration file #{@config} does not exist" unless File.exist? @config
42
+ raise "Configuration file #{@config} is not readable" unless File.readable? @config
43
+
44
+ File.readlines(@config).map{ |l| l.sub(/#.*$/,'')}.delete_if { |l| l=~ /^$/}.each do |l|
45
+ key,val = l.strip.split('=',2)
46
+ raise "Incorrect configuration line #{l}" unless key && val
47
+
48
+ case key
49
+ when /cfg_(file|dir)/ # There could be multiple entries for cfg_dir/file
50
+ instance_variable_set("@#{key}", (instance_variable_get("@#{key}") || []) << val )
51
+ else
52
+ instance_variable_set("@#{key}", val)
53
+ instance_eval val =~ /^[\d\.-]+/ ?
54
+ "def #{key}; return #{val}; end" :
55
+ "def #{key}; return %Q{#{val}}; end"
56
+ end
57
+ end
58
+ end
59
+
60
+ # Special case for cfg_file and cfg_dir: they are Arrays
61
+ attr_reader :cfg_file, :cfg_dir
62
+
63
+ end
64
+ end
@@ -0,0 +1,189 @@
1
+ module Nagios
2
+
3
+ =begin rdoc
4
+
5
+ = DESCRIPTION
6
+
7
+ Nagios::Objects -- class for parsing Nagios' objects.cache
8
+ file. Objects.cache file keeps information about lists of objects
9
+ being monitored by Nagios. It is created by Nagios process on
10
+ (re)start. Since it is machine-generated file syntax should not vary
11
+ from file to file.
12
+
13
+ Class implements 2 methods at the time of writing:
14
+ * constructor - that only creates an instance and
15
+ * parse method - that does actual parsing and populates instance variable @objects
16
+
17
+ = SYNOPSIS
18
+
19
+ require 'nagios/objects'
20
+
21
+ nagios = Nagios::Objects.new("test/objects.cache").new.parse
22
+ print nagios.objects[:contactgroup]
23
+
24
+ == Files
25
+
26
+ Location of objects.cache file depends on Nagios configuration (in
27
+ many cases varies from one UNIX/Linux ditribution to another) and is
28
+ defined by directive in nagios.cfg file.
29
+
30
+ On Debian system objects.cache it is in
31
+ /var/cache/nagios3/objects.cache:
32
+
33
+ object_cache_file=/var/cache/nagios3/objects.cache
34
+
35
+ == Parsed data hash
36
+
37
+ irb(main):010:0> pp nagios.objects
38
+ {:timeperiod=>
39
+ {"24x7"=>
40
+ {:timeperiod_name=>"24x7",
41
+ :alias=>"24 Hours A Day, 7 Days A Week",
42
+ :sunday=>"00:00-24:00",
43
+ :monday=>"00:00-24:00",
44
+ :tuesday=>"00:00-24:00",
45
+ :wednesday=>"00:00-24:00",
46
+ :thursday=>"00:00-24:00",
47
+ :friday=>"00:00-24:00",
48
+ :saturday=>"00:00-24:00"},
49
+ "never"=>{:timeperiod_name=>"never", :alias=>"Never"},
50
+
51
+ = Author
52
+
53
+ Dmytro Kovalov, dmytro.kovalov@gmail.com
54
+ 2011, Dec, 27 - First working version
55
+
56
+ =end
57
+
58
+ class Objects
59
+
60
+ # @param [String] path UNIX path to the objects.cache file
61
+ # @see Nagios::Objects.parse
62
+ def initialize path
63
+ raise "File does not exist" unless File.exist? path
64
+ raise "File is not readable" unless File.readable? path
65
+ @objects_file = path
66
+ @objects = {}
67
+ end
68
+
69
+ # PATH to the objects.cache file
70
+ attr_accessor :objects_file
71
+
72
+ # Parsed objects
73
+ attr_accessor :objects
74
+
75
+
76
+ =begin rdoc
77
+
78
+ Read objects.cache file and parse it.
79
+
80
+ Method reads file by blocks. Each block defines one object, definition
81
+ starts with 'define <type> {' and ends with '}'. Each block has a
82
+ '<type>_name' line which defines name of the instance of the
83
+ object.
84
+
85
+ Code of the 'parse()' method assumes, that _name line is always first
86
+ in the block! This can be not always the case.
87
+
88
+ Example of a block:
89
+
90
+ define contactgroup {
91
+ contactgroup_name admins
92
+ alias Nagios Administrators
93
+ members root
94
+ }
95
+
96
+ Example of a parsed object:
97
+
98
+ nagios.objects[:contactgroup]
99
+ => {"admins"=>{:contactgroup_name=>"admins", :alias=>"Nagios Administrators", :members=>"root"}}
100
+
101
+ nagios.contactgroup
102
+ => {"admins"=>{:contactgroup_name=>"admins", :alias=>"Nagios Administrators", :members=>"root"}}
103
+
104
+ === Convenience methods
105
+
106
+ Method parse creates helper methods for every type of object after
107
+ parsing. Same property can be accessed either using Hash @objects
108
+ (i.e. nagios.objects[:host]) or convenience method: nagios.host.
109
+
110
+ =end
111
+ def parse
112
+ block = {}
113
+ content = File.readlines objects_file
114
+ handler = nil
115
+ content.each do |line|
116
+ case
117
+ when line =~ /^\s*$/ then next # Skip empty lines
118
+ when line =~ /^\s*#/ then next # Skip comments
119
+ when line =~ /(\w+) \{/ # Block starts as "define host {"
120
+ block = {}
121
+ handler = $1.to_sym
122
+ when line =~ /\}/ # End of block
123
+ #
124
+ # Process it. Each block type has line <type>_name in the definition: host_name, command_name
125
+ #
126
+ @objects[handler] ||= {}
127
+ @objects[handler][block["#{handler.to_s}_name".to_sym]] = block
128
+ block = { }
129
+ when line =~ /^\s*(\w+)\s+([^\{\}]+)$/ # Build Hash from key-value pairs like: "max_check_attempts 10"
130
+ block[$1.to_sym] = $2.strip
131
+ end
132
+ end
133
+
134
+ # Create instance methods for easy access to properties
135
+ @objects.each do |key,val|
136
+ instance_variable_set("@#{key}", val)
137
+ instance_eval "def #{key}; return #{val}; end"
138
+ end
139
+ self
140
+ end
141
+
142
+ # Basic find function for resources.
143
+ # @param [Symbol] resource Resource to search from: :host, :hostgroup, etc.
144
+ # @param [Symbol] attribute Attribute to use in search. For example, find host by hostname or address, etc. anything that's defined for this resource
145
+ # @param [Symbol] message Is either 'find' or 'find_all' passed from caller. In case of 'find' returns 1 hash, 'find_all' - Array of Hash'es.
146
+ # @param [String] or [Regexp] pattern Search pattern
147
+
148
+ def find resource, message, attribute, pattern
149
+ self.send(resource.to_sym).values.send(message) do |a|
150
+ case pattern
151
+ when String
152
+ a[attribute.to_sym] == pattern
153
+ when Regexp
154
+ a[attribute.to_sym] =~ pattern
155
+ else
156
+ raise 'Unknown pattern for search'
157
+ end
158
+
159
+ end
160
+ end
161
+
162
+ # Replace standard +method_missing+ with dynamic search methods. Calls internally self.find.
163
+ #
164
+ # @see find
165
+ #
166
+ # @param [Symbol] sym Should be in the form
167
+ # find(_all)?_<resource>_by_<attribute>. Similar to
168
+ # ActiveResource find_* dynamic methods. Depending on the name
169
+ # of the mthod called (find or find_all) will pass message to
170
+ # self.find method, that will call {Array.find} or
171
+ # {Array.find_all} accordingly.
172
+ #
173
+ # find_*_by and find_all_*. find_all returns Array of
174
+ # hashes.
175
+
176
+ def method_missing sym, *args, &block
177
+ raise(NoMethodError, "No such method #{sym.to_s} for #{self.class}") unless sym.to_s =~ /^(find(_all)?)_(.*)_by_(.*)$/
178
+ # message - either 'find' of 'find_all'
179
+ # resource - type of objects to search: host, hostgroup etc.
180
+ # attribute - name of the attribute to do search by: :host_name, :check_command
181
+ # @param *args String or Regexp to search objects
182
+ message,resource,attribute = $1, $3, $4
183
+
184
+ self.find resource,message,attribute,args[0]
185
+ end
186
+
187
+ end
188
+ end
189
+
data/ruby-nagios.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  spec = Gem::Specification.new do |s|
2
2
  s.name = 'ruby-nagios'
3
- s.version = "0.0.1"
3
+ s.version = "0.0.2"
4
4
  s.author = 'R.I.Pienaar'
5
5
  s.email = 'rip@devco.net'
6
6
  s.homepage = 'http://devco.net/'
metadata CHANGED
@@ -1,88 +1,68 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: ruby-nagios
3
- version: !ruby/object:Gem::Version
4
- hash: 29
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 0
9
- - 1
10
- version: 0.0.1
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - R.I.Pienaar
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2012-04-18 00:00:00 +01:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
12
+ date: 2012-07-07 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
22
15
  name: rake
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &4747960 !ruby/object:Gem::Requirement
25
17
  none: false
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- hash: 3
30
- segments:
31
- - 0
32
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
33
22
  type: :development
34
- version_requirements: *id001
23
+ prerelease: false
24
+ version_requirements: *4747960
35
25
  description: Manage alerts, checks and acks in bulk
36
26
  email: rip@devco.net
37
- executables:
27
+ executables:
38
28
  - check_check
39
29
  - nagsrv
40
30
  extensions: []
41
-
42
31
  extra_rdoc_files: []
43
-
44
- files:
32
+ files:
33
+ - .gitignore
45
34
  - COPYING
46
- - README
35
+ - README.md
47
36
  - Rakefile
48
37
  - bin/check_check
49
38
  - bin/nagsrv
39
+ - lib/nagios.rb
40
+ - lib/nagios/config.rb
41
+ - lib/nagios/objects.rb
50
42
  - lib/nagios/status.rb
51
- - pkg/ruby-nagios-0.0.1.gem
52
43
  - ruby-nagios.gemspec
53
- has_rdoc: true
54
44
  homepage: http://devco.net/
55
45
  licenses: []
56
-
57
46
  post_install_message:
58
47
  rdoc_options: []
59
-
60
- require_paths:
48
+ require_paths:
61
49
  - lib
62
- required_ruby_version: !ruby/object:Gem::Requirement
50
+ required_ruby_version: !ruby/object:Gem::Requirement
63
51
  none: false
64
- requirements:
65
- - - ">="
66
- - !ruby/object:Gem::Version
67
- hash: 3
68
- segments:
69
- - 0
70
- version: "0"
71
- required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
57
  none: false
73
- requirements:
74
- - - ">="
75
- - !ruby/object:Gem::Version
76
- hash: 3
77
- segments:
78
- - 0
79
- version: "0"
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
80
62
  requirements: []
81
-
82
63
  rubyforge_project:
83
- rubygems_version: 1.3.7
64
+ rubygems_version: 1.8.11
84
65
  signing_key:
85
66
  specification_version: 3
86
67
  summary: Ruby library for managing Nagios
87
68
  test_files: []
88
-
data/README DELETED
@@ -1,5 +0,0 @@
1
- Have you ever had to disable alerts, retry a check or acknowledge outages on a large amount of services with Nagios and hated the web UI for it?
2
-
3
- This is a CLI tool and Ruby library that parses your status log file and let you query it for information or create external commands to be piped into the nagios command file.
4
-
5
- See http://code.google.com/p/ruby-nagios/ for more information
Binary file