ruby-nagios 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1 +1,4 @@
1
1
  pkg
2
+ doc
3
+ .yardoc
4
+ .DS_Store
data/Rakefile CHANGED
@@ -1,2 +1,20 @@
1
1
  require 'bundler'
2
2
  Bundler::GemHelper.install_tasks
3
+
4
+ namespace :spec do
5
+
6
+ desc "Run production configuration test"
7
+ task :config do
8
+ ENV['RSPEC_ENV'] = 'production'
9
+ sh %{rspec -f d --color --fail-fast spec/00_configuration_spec.rb}
10
+ end
11
+
12
+ namespace :test do
13
+
14
+ desc "Run configuration test in `test` environment"
15
+ task :config do
16
+ ENV['RSPEC_ENV'] = 'test'
17
+ sh %{rspec -f d --color spec/00_configuration_spec.rb}
18
+ end
19
+ end
20
+ end
data/bin/check_check CHANGED
@@ -23,12 +23,12 @@ class Nagios::Status::Model
23
23
 
24
24
  def initialize(path)
25
25
  @path = path
26
- @status = Nagios::Status.new
26
+ @status = Nagios::Status.new @path
27
27
  update
28
28
  end # def initialize
29
29
 
30
30
  def update
31
- @status.parsestatus(@path)
31
+ @status.parsestatus
32
32
  end # def update
33
33
 
34
34
  def services(service_pattern=nil, host_pattern=nil)
@@ -160,6 +160,14 @@ def main(args)
160
160
  end # if results[state]
161
161
  end # for each non-OK state
162
162
 
163
+ # If everything is OK, still print detailed output for confirmation
164
+ if total_results == 0 and results["OK"].size > 0
165
+ puts "OK Services:"
166
+ results["OK"].sort { |a,b| a["host_name"] <=> b["host_name"] }.each do |service|
167
+ puts " #{service["host_name"]} => #{service["service_description"]}"
168
+ end
169
+ end
170
+
163
171
  exitcode = 0
164
172
 
165
173
  if settings.down_min_percent
data/bin/nagsrv CHANGED
@@ -77,7 +77,7 @@ OptionParser.new do |opts|
77
77
  end
78
78
 
79
79
  opts.on("--list-services", "List services that match certain criteria") do
80
- listhosts = true
80
+ listservices = true
81
81
  end
82
82
 
83
83
  opts.separator ""
@@ -128,9 +128,9 @@ end.parse!
128
128
 
129
129
  abort "Cannot find #{statusfile}" unless File.exist?(statusfile)
130
130
 
131
- nagios = Nagios::Status.new
131
+ nagios = Nagios::Status.new statusfile
132
132
 
133
- nagios.parsestatus(statusfile)
133
+ nagios.parsestatus
134
134
 
135
135
 
136
136
  # We want hosts so abuse the action field to print just the hostname
@@ -141,6 +141,10 @@ if listhosts
141
141
  forhost = "/." if forhost.size == 0
142
142
  end
143
143
 
144
+ if listservices && action == nil
145
+ action = "${service}"
146
+ end
147
+
144
148
  options = {:forhost => forhost, :notifyenabled => notify, :action => action, :withservice => withservice}
145
149
  services = nagios.find_services(options)
146
150
 
data/lib/nagios/config.rb CHANGED
@@ -2,10 +2,11 @@ module Nagios
2
2
 
3
3
  =begin rdoc
4
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.
5
+ Parser of the main Nagios configuration file -- nagios.cfg.
6
+
7
+ Constructor parses Nagios' main config file and returns an object:
8
+ each configuration option's value assigned to an instance variable and
9
+ attribute reader method is created.
9
10
 
10
11
  Can be used as:
11
12
 
@@ -18,43 +19,82 @@ Can be used as:
18
19
  nagios.status_file
19
20
  => "/var/cache/nagios3/status.dat"
20
21
 
22
+ = Configuration of the module
23
+
24
+ Default search directory and file pattern (Dir.glob) is defined by
25
+ Nagios::DEFAULT[:nagios_cfg_glob] constant. It is set in
26
+ +config/default.rb+ file.
27
+
28
+ @note If you have more than one /etc/nagios* directories then only
29
+ first one will be used. For example, Debian can have both Nagios 2 and
30
+ 3 installed. In the latter case configuration file is
31
+ +/etc/nagios3/nagios.cfg+.
32
+
21
33
 
22
34
  =end
23
35
  class Config
24
36
 
25
- DEFAULT_CONFIG = "/etc/nagios*/nagios.cfg"
26
-
27
- # Read and parse configuration file.
28
- #
37
+ ##
38
+ # Initialize configuration file path. Check existence and
39
+ # readability of the file, raise exception if not.
40
+ #
29
41
  # @param [String] config_file PATH to the configuration file. If
30
42
  # 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
43
+ # +nagios.cfg+ in directory, defined by
44
+ # Nagios::DEFAULT[:nagios_cfg_glob] constant ( ususally
45
+ # /etc/nagios*/nagios.cfg);
46
+ #
37
47
  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
48
+
49
+ @config = config_file || Dir.glob( Nagios::DEFAULT[:nagios_cfg_glob] ).first
50
+ @path = @config
51
+
52
+ @configuration ||= {}
53
+ raise "No configuration file option and no files in #{ DEFAULT[:nagios_cfg_glob] } " unless @config
41
54
  raise "Configuration file #{@config} does not exist" unless File.exist? @config
42
55
  raise "Configuration file #{@config} is not readable" unless File.readable? @config
43
56
 
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
57
+ end
58
+
59
+ # Hash holding all the configuration after parsing. Additionally
60
+ # for every key in the configuration Hash method is created with
61
+ # the same name, which returns the value.
62
+ attr_accessor :configuration
63
+
64
+ # Path to main configuration file nagios.cfg
65
+
66
+ attr_accessor :path
67
+
68
+ ##
69
+ # Read and parse main Nagios configuration file +nagios.cfg+
70
+ #
71
+ #
72
+ # @author Dmytro Kovalov, dmytro.kovalov@gmail.com
73
+ def parse
74
+ idx=0
75
+ File.readlines(@config).map{ |l| l.sub(/\s*#.*$/,'')}.delete_if { |l| l=~ /^\s*$/}.each do |l|
76
+ idx += 1
77
+ key,val = l.chomp.strip.split(/\s*=\s*/,2)
78
+ raise "Incorrect configuration line ##{idx}: '#{l}'" unless key && val
47
79
 
48
80
  case key
49
- when /cfg_(file|dir)/ # There could be multiple entries for cfg_dir/file
81
+ # There could be multiple entries for cfg_dir/file, so these
82
+ # are Arrays.
83
+ when /cfg_(file|dir)/
84
+ @configuration[key] ||= []
85
+ @configuration[key] << val
50
86
  instance_variable_set("@#{key}", (instance_variable_get("@#{key}") || []) << val )
51
87
  else
88
+
89
+ @configuration[key] = val
52
90
  instance_variable_set("@#{key}", val)
53
91
  instance_eval val =~ /^[\d\.-]+/ ?
54
92
  "def #{key}; return #{val}; end" :
55
93
  "def #{key}; return %Q{#{val}}; end"
56
94
  end
57
95
  end
96
+
97
+ self
58
98
  end
59
99
 
60
100
  # Special case for cfg_file and cfg_dir: they are Arrays
@@ -0,0 +1,186 @@
1
+ module Nagios
2
+ class ExternalCommands
3
+ # External commands list in nagios and format to send this to
4
+ # Nagios. Keys of the Hash are names of commands, values are
5
+ # Array's of Nagios variables to be sent. Arrays are converted to
6
+ # ERB templates before printing, command name and all variables
7
+ # joined together by semicolons.
8
+ #
9
+ # Each variable must be defined as attr_accessor, these variables
10
+ # are used in ERB binding.
11
+ #
12
+ # List of all available nagios external commands, formats and
13
+ # descriptions can be obtained from
14
+ # http://www.nagios.org/developerinfo/externalcommands As of the
15
+ # time of writing this list is 157 commands for Nagios 3.x.
16
+ #
17
+ # == Example
18
+ #
19
+ # PROCESS_SERVICE_CHECK_RESULT: %w{host_name service_description return_code plugin_output}
20
+ #
21
+ # converted to template on print:
22
+ #
23
+ # [timestamp] PROCESS_SERVICE_CHECK_RESULT;<%= host_name %>;<%= service_description %>;<%= return_code %>;<%= plugin_output %>\n
24
+ #
25
+ ACTIONS = {
26
+ ACKNOWLEDGE_HOST_PROBLEM: %w{host_name sticky notify persistent author comment},
27
+ ACKNOWLEDGE_SVC_PROBLEM: %w{host_name service_description sticky notify persistent author comment},
28
+ ADD_HOST_COMMENT: %w{host_name persistent author comment},
29
+ ADD_SVC_COMMENT: %w{host_name service_description persistent author comment},
30
+ CHANGE_CONTACT_HOST_NOTIFICATION_TIMEPERIOD: %w{contact_name notification_timeperiod},
31
+ CHANGE_CONTACT_MODATTR: %w{contact_name value},
32
+ CHANGE_CONTACT_MODHATTR: %w{contact_name value},
33
+ CHANGE_CONTACT_MODSATTR: %w{contact_name value},
34
+ CHANGE_CONTACT_SVC_NOTIFICATION_TIMEPERIOD: %w{contact_name notification_timeperiod},
35
+ CHANGE_CUSTOM_CONTACT_VAR: %w{contact_name varname varvalue},
36
+ CHANGE_CUSTOM_HOST_VAR: %w{host_name varname varvalue},
37
+ CHANGE_CUSTOM_SVC_VAR: %w{host_name service_description varname varvalue},
38
+ CHANGE_GLOBAL_HOST_EVENT_HANDLER: %w{event_handler_command},
39
+ CHANGE_GLOBAL_SVC_EVENT_HANDLER: %w{event_handler_command},
40
+ CHANGE_HOST_CHECK_COMMAND: %w{host_name check_command},
41
+ CHANGE_HOST_CHECK_TIMEPERIOD: %w{host_name check_timeperod},
42
+ CHANGE_HOST_CHECK_TIMEPERIOD: %w{host_name timeperiod},
43
+ CHANGE_HOST_EVENT_HANDLER: %w{host_name event_handler_command},
44
+ CHANGE_HOST_MODATTR: %w{host_name value},
45
+ CHANGE_MAX_HOST_CHECK_ATTEMPTS: %w{host_name check_attempts},
46
+ CHANGE_MAX_SVC_CHECK_ATTEMPTS: %w{host_name service_description check_attempts},
47
+ CHANGE_NORMAL_HOST_CHECK_INTERVAL: %w{host_name check_interval},
48
+ CHANGE_NORMAL_SVC_CHECK_INTERVAL: %w{host_name service_description check_interval},
49
+ CHANGE_RETRY_HOST_CHECK_INTERVAL: %w{host_name service_description check_interval},
50
+ CHANGE_RETRY_SVC_CHECK_INTERVAL: %w{host_name service_description check_interval},
51
+ CHANGE_SVC_CHECK_COMMAND: %w{host_name service_description check_command},
52
+ CHANGE_SVC_CHECK_TIMEPERIOD: %w{host_name service_description check_timeperiod},
53
+ CHANGE_SVC_EVENT_HANDLER: %w{host_name service_description event_handler_command},
54
+ CHANGE_SVC_MODATTR: %w{host_name service_description value},
55
+ CHANGE_SVC_NOTIFICATION_TIMEPERIOD: %w{host_name service_description notification_timeperiod},
56
+ DELAY_HOST_NOTIFICATION: %w{host_name notification_time},
57
+ DELAY_SVC_NOTIFICATION: %w{host_name service_description notification_time},
58
+ DEL_ALL_HOST_COMMENTS: %w{host_name},
59
+ DEL_ALL_SVC_COMMENTS: %w{host_name service_description},
60
+ DEL_HOST_COMMENT: %w{comment_id},
61
+ DEL_HOST_DOWNTIME: %w{downtime_id},
62
+ DEL_SVC_COMMENT: %w{comment_id},
63
+ DEL_SVC_DOWNTIME: %w{downtime_id},
64
+ DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST: %w{host_name},
65
+ DISABLE_CONTACTGROUP_HOST_NOTIFICATIONS: %w{contactgroup_name},
66
+ DISABLE_CONTACTGROUP_SVC_NOTIFICATIONS: %w{contactgroup_name},
67
+ DISABLE_CONTACT_HOST_NOTIFICATIONS: %w{contact_name},
68
+ DISABLE_CONTACT_SVC_NOTIFICATIONS: %w{contact_name},
69
+ DISABLE_EVENT_HANDLERS: [],
70
+ DISABLE_FAILURE_PREDICTION: [],
71
+ DISABLE_FLAP_DETECTION: [],
72
+ DISABLE_HOSTGROUP_HOST_CHECKS: %w{hostgroup_name},
73
+ DISABLE_HOSTGROUP_HOST_NOTIFICATIONS: %w{hostgroup_name},
74
+ DISABLE_HOSTGROUP_PASSIVE_HOST_CHECKS: %w{hostgroup_name},
75
+ DISABLE_HOSTGROUP_PASSIVE_SVC_CHECKS: %w{hostgroup_name},
76
+ DISABLE_HOSTGROUP_SVC_CHECKS: %w{hostgroup_name},
77
+ DISABLE_HOSTGROUP_SVC_NOTIFICATIONS: %w{hostgroup_name},
78
+ DISABLE_HOST_AND_CHILD_NOTIFICATIONS: %w{host_name},
79
+ DISABLE_HOST_CHECK: %w{host_name},
80
+ DISABLE_HOST_EVENT_HANDLER: %w{host_name},
81
+ DISABLE_HOST_FLAP_DETECTION: %w{host_name},
82
+ DISABLE_HOST_FRESHNESS_CHECKS: [],
83
+ DISABLE_HOST_NOTIFICATIONS: %w{host_name},
84
+ DISABLE_HOST_SVC_CHECKS: %w{host_name},
85
+ DISABLE_HOST_SVC_NOTIFICATIONS: %w{host_name},
86
+ DISABLE_NOTIFICATIONS: [],
87
+ DISABLE_PASSIVE_HOST_CHECKS: %w{host_name},
88
+ DISABLE_PASSIVE_SVC_CHECKS: %w{host_name service_description},
89
+ DISABLE_PERFORMANCE_DATA: [],
90
+ DISABLE_SERVICEGROUP_HOST_CHECKS: %w{servicegroup_name},
91
+ DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS: %w{servicegroup_name},
92
+ DISABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS: %w{servicegroup_name},
93
+ DISABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS: %w{servicegroup_name},
94
+ DISABLE_SERVICEGROUP_SVC_CHECKS: %w{servicegroup_name},
95
+ DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS: %w{servicegroup_name},
96
+ DISABLE_SERVICE_FLAP_DETECTION: %w{host_name service_description},
97
+ DISABLE_SERVICE_FRESHNESS_CHECKS: [],
98
+ DISABLE_SVC_CHECK: %w{host_name service_description},
99
+ DISABLE_SVC_EVENT_HANDLER: %w{host_name service_description},
100
+ DISABLE_SVC_FLAP_DETECTION: %w{host_name service_description},
101
+ DISABLE_SVC_NOTIFICATIONS: %w{host_name service_description},
102
+ ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST: %w{host_name},
103
+ ENABLE_CONTACTGROUP_HOST_NOTIFICATIONS: %w{contactgroup_name},
104
+ ENABLE_CONTACTGROUP_SVC_NOTIFICATIONS: %w{contactgroup_name},
105
+ ENABLE_CONTACT_HOST_NOTIFICATIONS: %w{contact_name},
106
+ ENABLE_CONTACT_SVC_NOTIFICATIONS: %w{contact_name},
107
+ ENABLE_EVENT_HANDLERS: [],
108
+ ENABLE_FAILURE_PREDICTION: [],
109
+ ENABLE_FLAP_DETECTION: [],
110
+ ENABLE_HOSTGROUP_HOST_CHECKS: %w{hostgroup_name},
111
+ ENABLE_HOSTGROUP_HOST_NOTIFICATIONS: %w{hostgroup_name},
112
+ ENABLE_HOSTGROUP_PASSIVE_HOST_CHECKS: %w{hostgroup_name},
113
+ ENABLE_HOSTGROUP_PASSIVE_SVC_CHECKS: %w{hostgroup_name},
114
+ ENABLE_HOSTGROUP_SVC_CHECKS: %w{hostgroup_name},
115
+ ENABLE_HOSTGROUP_SVC_NOTIFICATIONS: %w{hostgroup_name},
116
+ ENABLE_HOST_AND_CHILD_NOTIFICATIONS: %w{host_name},
117
+ ENABLE_HOST_CHECK: %w{host_name},
118
+ ENABLE_HOST_EVENT_HANDLER: %w{host_name},
119
+ ENABLE_HOST_FLAP_DETECTION: %w{host_name},
120
+ ENABLE_HOST_FRESHNESS_CHECKS: [],
121
+ ENABLE_HOST_NOTIFICATIONS: %w{host_name},
122
+ ENABLE_HOST_SVC_CHECKS: %w{host_name},
123
+ ENABLE_HOST_SVC_NOTIFICATIONS: %w{host_name},
124
+ ENABLE_NOTIFICATIONS: [],
125
+ ENABLE_PASSIVE_HOST_CHECKS: %w{host_name},
126
+ ENABLE_PASSIVE_SVC_CHECKS: %w{host_name service_description},
127
+ ENABLE_PERFORMANCE_DATA: [],
128
+ ENABLE_SERVICEGROUP_HOST_CHECKS: %w{servicegroup_name},
129
+ ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS: %w{servicegroup_name},
130
+ ENABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS: %w{servicegroup_name},
131
+ ENABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS: %w{servicegroup_name},
132
+ ENABLE_SERVICEGROUP_SVC_CHECKS: %w{servicegroup_name},
133
+ ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS: %w{servicegroup_name},
134
+ ENABLE_SERVICE_FRESHNESS_CHECKS: [],
135
+ ENABLE_SVC_CHECK: %w{host_name service_description},
136
+ ENABLE_SVC_EVENT_HANDLER: %w{host_name service_description},
137
+ ENABLE_SVC_FLAP_DETECTION: %w{host_name service_description},
138
+ ENABLE_SVC_NOTIFICATIONS: %w{host_name service_description},
139
+ PROCESS_FILE: %w{file_name delete},
140
+ PROCESS_HOST_CHECK_RESULT: %w{host_name status_code plugin_output},
141
+ PROCESS_SERVICE_CHECK_RESULT: %w{host_name service_description return_code plugin_output},
142
+ READ_STATE_INFORMATION: [],
143
+ REMOVE_HOST_ACKNOWLEDGEMENT: %w{host_name},
144
+ REMOVE_SVC_ACKNOWLEDGEMENT: %w{host_name service_description},
145
+ RESTART_PROGRAM: [],
146
+ SAVE_STATE_INFORMATION: [],
147
+ SCHEDULE_AND_PROPAGATE_HOST_DOWNTIME: %w{host_name start_time end_time fixed trigger_id duration author comment},
148
+ SCHEDULE_AND_PROPAGATE_TRIGGERED_HOST_DOWNTIME: %w{host_name start_time end_time fixed trigger_id duration author comment},
149
+ SCHEDULE_FORCED_HOST_CHECK: %w{host_name check_time},
150
+ SCHEDULE_FORCED_HOST_SVC_CHECKS: %w{host_name check_time},
151
+ SCHEDULE_FORCED_SVC_CHECK: %w{host_name service_description check_time},
152
+ SCHEDULE_HOSTGROUP_HOST_DOWNTIME: %w{hostgroup_name start_time end_time fixed trigger_id duration author comment},
153
+ SCHEDULE_HOSTGROUP_SVC_DOWNTIME: %w{hostgroup_name start_time end_time fixed trigger_id duration author comment},
154
+ SCHEDULE_HOST_CHECK: %w{host_name check_time},
155
+ SCHEDULE_HOST_DOWNTIME: %w{host_name start_time end_time fixed trigger_id duration author comment},
156
+ SCHEDULE_HOST_SVC_CHECKS: %w{host_name check_time},
157
+ SCHEDULE_HOST_SVC_DOWNTIME: %w{host_name start_time end_time fixed trigger_id duration author comment},
158
+ SCHEDULE_SERVICEGROUP_HOST_DOWNTIME: %w{servicegroup_name start_time end_time fixed trigger_id duration author comment},
159
+ SCHEDULE_SERVICEGROUP_SVC_DOWNTIME: %w{servicegroup_name start_time end_time fixed trigger_id duration author comment},
160
+ SCHEDULE_SVC_CHECK: %w{host_name service_description check_time},
161
+ SCHEDULE_SVC_DOWNTIME: %w{host_name service_desription start_time end_time fixed trigger_id duration author comment},
162
+ SEND_CUSTOM_HOST_NOTIFICATION: %w{host_name options author comment},
163
+ SEND_CUSTOM_SVC_NOTIFICATION: %w{host_name service_description options author comment},
164
+ SET_HOST_NOTIFICATION_NUMBER: %w{host_name notification_number},
165
+ SET_SVC_NOTIFICATION_NUMBER: %w{host_name service_description notification_number},
166
+ SHUTDOWN_PROGRAM: [],
167
+ START_ACCEPTING_PASSIVE_HOST_CHECKS: [],
168
+ START_ACCEPTING_PASSIVE_SVC_CHECKS: [],
169
+ START_EXECUTING_HOST_CHECKS: [],
170
+ START_EXECUTING_SVC_CHECKS: [],
171
+ START_OBSESSING_OVER_HOST: %w{host_name},
172
+ START_OBSESSING_OVER_HOST_CHECKS: [],
173
+ START_OBSESSING_OVER_SVC: %w{host_name service_description},
174
+ START_OBSESSING_OVER_SVC_CHECKS: [],
175
+ STOP_ACCEPTING_PASSIVE_HOST_CHECKS: [],
176
+ STOP_ACCEPTING_PASSIVE_SVC_CHECKS: [],
177
+ STOP_EXECUTING_HOST_CHECKS: [],
178
+ STOP_EXECUTING_SVC_CHECKS: [],
179
+ STOP_OBSESSING_OVER_HOST: %w{host_name},
180
+ STOP_OBSESSING_OVER_HOST_CHECKS: [],
181
+ STOP_OBSESSING_OVER_SVC: %w{host_name service_description},
182
+ STOP_OBSESSING_OVER_SVC_CHECKS: []
183
+ }.freeze
184
+ end
185
+ end
186
+
@@ -0,0 +1,142 @@
1
+ module Nagios
2
+
3
+
4
+ # Class Nagios::ExternalCommands is class implementing sending
5
+ # commands to external commands file in Nagios.
6
+ #
7
+ # From nagios.cfg file:
8
+ #
9
+ # This is the file that Nagios checks for external command requests.
10
+ # It is also where the command CGI will write commands that are
11
+ # submitted by users, so it must be writable by the user that the
12
+ # web server is running as (usually 'nobody').
13
+ #
14
+ # == Usage
15
+ #
16
+ # command = Nagios::ExternalCommands.new Nagios::Config.new.parse.command_file
17
+ #
18
+ # command.write :action => :PROCESS_HOST_CHECK_RESULT,
19
+ # :host_name => 'myhost', :status_code => 0, :plugin_output => "PING command OK"
20
+ #
21
+ class ExternalCommands
22
+
23
+ require 'erb'
24
+ require_relative 'external_commands/list'
25
+
26
+ # Constructor for the external command write class.
27
+ #
28
+ # @param [String] path Full UNIX path to external command file
29
+ #
30
+ # == Example
31
+ #
32
+ # >> cmd = Nagios::ExternalCommands.new('/var/nagios/rw/nagios.cmd')
33
+ #
34
+ def initialize path
35
+ raise ArgumentError, "External command file name must be provided" unless path
36
+ raise RuntimeError, "External command directory holding file #{path} is not writable by this user." unless File.writable? File.dirname path
37
+
38
+ @path = path
39
+ end
40
+
41
+ attr_reader :path
42
+
43
+ # Action to write: one of the keys listed in
44
+ # ::Nagios::ExternalCommands::ACTIONS hash.
45
+ attr_accessor :action
46
+
47
+ # Time-stamp - usually time when write is performed, but can be
48
+ # overridden by params[:ts] in constructor. If given as argument
49
+ # for constructor it should be String of the format:
50
+ # Time.to_i.to_s (i.e number of seconds since epoch).
51
+ attr_accessor :ts
52
+
53
+ # TODO: make int dynamically later with:
54
+ # >> Nagios::ExternalCommands::ACTIONS.values.flatten.uniq
55
+ # This returns full list of Nagios variables used in external commands
56
+ #
57
+
58
+ # Nagios variable used in external command
59
+ attr_accessor :host_name, :sticky, :notify, :persistent, :author,
60
+ :comment, :service_description, :contact_name,
61
+ :notification_timeperiod, :value, :varname, :varvalue,
62
+ :event_handler_command, :check_command, :timeperiod,
63
+ :check_attempts, :check_interval, :check_timeperiod,
64
+ :notification_time, :comment_id, :downtime_id, :contactgroup_name,
65
+ :hostgroup_name, :servicegroup_name, :file_name, :delete,
66
+ :status_code, :plugin_output, :return_code, :start_time,
67
+ :end_time, :fixed, :trigger_id, :duration, :check_time,
68
+ :service_desription, :start_time, :options, :notification_number
69
+
70
+ # Get private binding to use with ERB bindings.
71
+ def get_binding
72
+ binding()
73
+ end
74
+
75
+ # Send command to Nagios. Prints formatted string to external command file (pipe).
76
+ #
77
+ # @param [Hash or Array] data Data to write to command file pipe. Must
78
+ # include :action and all additional variables
79
+ def write data
80
+ case data
81
+ when Hash then data = [data]
82
+ else
83
+ return { :result => false, :data => "Input data type #{data.class} is not supproted." }
84
+ end
85
+
86
+ result, output = true, []
87
+
88
+ data.each do |params|
89
+
90
+ messages = []
91
+
92
+ if params.has_key? :action
93
+ messages << "ArgumentError: Action name #{params[:action]} is not implemented" unless ACTIONS.keys.include? params[:action]
94
+ else
95
+ messages << "ArgumentError: Action name must be provided"
96
+ end
97
+
98
+ # It makes sense to continue only if checks above did not fail
99
+ if messages.empty?
100
+ #
101
+ # Clear all attributes first - so no old data left
102
+ #
103
+ ACTIONS.values.flatten.uniq.each do |att|
104
+ self.instance_variable_set "@#{att}", nil
105
+ end
106
+ #
107
+ # And set it to param's value
108
+ #
109
+ params.each { |k,v| self.instance_variable_set "@#{k}", v }
110
+ #
111
+ # Check that all variable that are used in the template are
112
+ # actually set, not nil's
113
+ #
114
+ ACTIONS[@action].each do |var|
115
+ messages << "ArgumentError, Parameter :#{var} is required, cannot be nil" if self.instance_variable_get("@#{var}").nil?
116
+ end
117
+
118
+ # Try to write to file only if none of the above failed
119
+ if messages.empty?
120
+ self.ts = params[:ts] || Time.now.to_i.to_s
121
+
122
+ format = "[#{ts}] " << ([self.action.to_s] + ACTIONS[self.action].map {|x| "<%= #{x} %>" }).join(';')
123
+
124
+ begin
125
+ File.open(path, 'a') do |pipe|
126
+ pipe.puts ERB.new(format).result(self.get_binding)
127
+ pipe.close
128
+ end
129
+ rescue e
130
+ messages << e.message
131
+ end
132
+ end
133
+ end
134
+
135
+ output << { data: params, result: messages.empty? , messages: messages }
136
+ end # data.each
137
+
138
+ { result: result, data: output }
139
+ end # def write
140
+ end
141
+ end
142
+