Class: Nagira
- Inherits:
-
Sinatra::Base
- Object
- Sinatra::Base
- Nagira
- Includes:
- OutputTypeable
- Defined in:
- app/app.rb,
app/routes/get.rb,
app/filters/after.rb,
app/filters/before.rb,
app/parsers/parser.rb,
app/routes/put/host.rb,
app/filters/configure.rb,
app/routes/get/config.rb,
app/routes/get/status.rb,
app/routes/put/status.rb,
app/routes/get/objects.rb,
lib/nagira/hostservice.rb,
app/helpers/put_helpers.rb,
app/loggers/simple_logger.rb,
app/parsers/background_parse.rb,
app/routes/get/status/hostgroups.rb,
app/controllers/api_help_controller.rb,
app/routes/get/status/servicegroups.rb,
app/writers/external_command_writer.rb,
app/controllers/hostgroup_controller.rb,
app/controllers/host_status_controller.rb,
app/controllers/service_status_controler.rb,
app/controllers/servicegroups_controller.rb,
app/controllers/resource_status_controler.rb
Overview
PUT method routes for services status.
Defined Under Namespace
Classes: ApiHelpController, BackgroundParser, HostService, HostStatusController, HostgroupController, Logger, Parser, ResourceStatusController, ServiceStatusController, ServicegroupController, Writer
Instance Method Summary collapse
-
#after("ArgumentError") ⇒ Object
Return 400 if result of PUT operation is not success.
-
#before("clear data") ⇒ Object
Clear values onf instance variables before start.
- #after("Return Array for ActiveResouce routes") ⇒ Object
-
#before('detect ActiveResource mode') ⇒ Object
Detect if this a request for ActiveResource PATH.
-
#before('find callback name') ⇒ Object
Detects if request is using jQuery JSON-P and sets @callback variable.
-
#get_1_object ⇒ Object
Get single Nagios object.
-
#get(/_api)) ⇒ Object
Provide information about API routes.
-
#get("/_config") ⇒ Object
Get Nagios configuration hash form parsing main Nagios configuration file nagios.cfg.
-
#get_object_type ⇒ Object
Get all objects of type :type.
-
#get_objects ⇒ Object
Objects routes ============================================================.
-
#get(/_runtime)) ⇒ Object
Print out nagira runtime configuration.
-
#get(/)) ⇒ Object
Returns application information: name, version, github repository.
-
#get_status ⇒ Object
Return all hosts status.
-
#get_status_hostgroup ⇒ Object
Return full status of the hostgroup: including host status and service status.
-
#get("/_status/_hostgroup/: hostgroup/_host") ⇒ Object
Endpoint: - GET /_status/_hostgroup/:host.
-
#get_status_hostgroup_service ⇒ Object
Endpoint: - GET /_status/_hostgroup/:hostgroup/_service.
-
#get_status_hostname ⇒ Object
Hoststatus for single host or all services.
-
#get_status_hostname_services ⇒ Object
Endpoints: - GET /_status/:hostname/_services - GET /_status/:hostname/_hostcomments - GET /_status/:hostname/_servicecomments.
-
#get("/_status/: hostname/_services/:service_name") ⇒ Object
Full or short status information for single service on single host.
-
#get_status_servicegroup ⇒ Object
Endpoint: - GET /_status/_servicegroup/:servicegroup.
-
#after("Object not found or bad request") ⇒ Object
If result-set of object/status search is empty return HTTP 404 .
-
#before("Parse PUT request body") ⇒ Array
Process the data before on each HTTP request.
-
#before("Parse Nagios files") ⇒ Object
Parse nagios files.
-
#put("/_host_status/: host_name") ⇒ Object
Same as /_status/:host_name (Not implemented).
-
#put("/_status") ⇒ Object
Submit JSON Hash for multiple services, on multiple hosts.
-
#put(/_status/: host_name/_services/:service_description/_return_code/:return_code/_plugin_output/:plugin_output) ⇒ Object
Update single service status on a single host.
-
#put("/_status/: host_name") ⇒ Object
Update hoststatus information only for the given host.
-
#put("/_status/: host_name/_services") ⇒ Object
Update multiple services on the same host.
-
#after("Return formatted data") ⇒ Object
If it’s a JSON-P request, return its data with prepended @callback function name.
-
#before("Initial Config") ⇒ Object
Do some necessary tasks at start and then run Sinatra app.
-
#before("detect format") ⇒ Object
Detect and strip output format extension.
-
#before('detect output mode') ⇒ Object
Detect output mode modifier.
-
#update_service_status(params) ⇒ Object
Small helper to submit data to ::Nagios::ExternalCommands object.
Methods included from OutputTypeable
#body_with_list, #full?, #list?, #state?
Instance Method Details
#after("ArgumentError") ⇒ Object
Return 400 if result of PUT operation is not success.
37 38 39 40 41 |
# File 'app/filters/after.rb', line 37 after do if request.put? && ! response.body[:result] halt [400, response.body.send("to_#{@format}") ] end end |
#before("clear data") ⇒ Object
Clear values onf instance variables before start.
45 46 47 48 |
# File 'app/filters/before.rb', line 45 before do @data = [] @format = @output = nil end |
#after("Return Array for ActiveResouce routes") ⇒ Object
48 49 50 |
# File 'app/filters/after.rb', line 48 after do response.body = response.body.values if @active_resource && response.body.is_a?(Hash) end |
#before('detect ActiveResource mode') ⇒ Object
Detect if this a request for ActiveResource PATH
81 82 83 |
# File 'app/filters/before.rb', line 81 before do @active_resource = request.path_info =~ %r{^#{Nagira::AR_PREFIX}/} end |
#before('find callback name') ⇒ Object
Detects if request is using jQuery JSON-P and sets @callback variable. @callback variable is used if after method and prepends JSON data with callback function name.
Example
GET /_api?callback=jQuery12313123123 # @callback == jQuery12313123123
JSONP support is based on the code from sinatra/jsonp
Gem github.com/shtirlic/sinatra-jsonp.
127 128 129 130 131 132 133 |
# File 'app/filters/before.rb', line 127 before do if @format == :json ['callback','jscallback','jsonp','jsoncallback'].each do |x| @callback = params.delete(x) unless @callback end end end |
#get_1_object ⇒ Object
Get single Nagios object.
Accepted output type modifiers:
-
none
45 46 47 |
# File 'app/routes/get/objects.rb', line 45 get "/_objects/:type/:name" do |type,name| @objects[type.to_sym][name] end |
#get(/_api)) ⇒ Object
Provide information about API routes
9 10 11 |
# File 'app/routes/get.rb', line 9 get "/_api" do ApiHelpController.get end |
#get("/_config") ⇒ Object
Get Nagios configuration hash form parsing main Nagios configuration file nagios.cfg
8 9 10 |
# File 'app/routes/get/config.rb', line 8 get "/_config" do Parser.config.configuration end |
#get_object_type ⇒ Object
Get all objects of type :type
Accepted output type modifiers:
-
/_list
: Short list of available objects, depending on the current request context: hosts, services, etc.
30 31 32 |
# File 'app/routes/get/objects.rb', line 30 get "/_objects/:type" do |type| body_with_list @objects[type.to_sym] end |
#get_objects ⇒ Object
Objects routes
Get full list of Nagios objects. Returns hash containing all configured objects in Nagios: hosts, hostgroups, services, contacts. etc.
Accepted output type modifiers:
-
/_list
: Short list of available objects, depending on the current request context: hosts, services, etc.
16 17 18 |
# File 'app/routes/get/objects.rb', line 16 get "/_objects" do body_with_list @objects end |
#get(/_runtime)) ⇒ Object
Print out nagira runtime configuration
18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'app/routes/get.rb', line 18 get "/_runtime" do { application: self.class, version: VERSION, runtime: { environment: Nagira.settings.environment, home: ENV['HOME'], user: ENV['LOGNAME'], nagiosFiles: Parser.state.to_h.keys.map { |x| { x: Parser.state.to_h[x].path }}, commandFile: Writer.commands.path } } end |
#get(/)) ⇒ Object
Returns application information: name, version, github repository.
36 37 38 39 40 41 42 43 |
# File 'app/routes/get.rb', line 36 get "/" do { :application => self.class, :version => VERSION, :source => GITHUB, :apiUrl => request.url.sub(/\/$/,'') + "/_api", } end |
#get_status ⇒ Object
Return all hosts status.
If no output modifier provided, outputs full hosttatus information for each host. Not including services information. When _full
modifier is provided data include hoststatus, servicestatus and all comments (servicecomments and hostcomments) for hosts.
Alias: get /_status is the same thing as get /_status/_hosts with ActiveResource compatibility, i.e. for */_hosts request Nagira returns array instead of hash.
Accepted output type modifiers:
-
/_state
- Instead of full status information send only current state. For hosts up/down, for services OK, Warn, Critical, Unknown (0,1,2-1) -
/_list
: Short list of available objects, depending on the current request context: hosts, services, etc. -
/_full
- Show full status information. When used in /_status/_full call will display full hoststaus and servicestatus information for each host.
Support for (see API):
-
plural resources: N/A
-
object access by ID: N/A
73 74 75 |
# File 'app/routes/get/status.rb', line 73 get %r{^/_status(/_hosts)?$} do HostStatusController.new(@status, output: @output).get end |
#get_status_hostgroup ⇒ Object
Return full status of the hostgroup: including host status and service status.
9 10 11 |
# File 'app/routes/get/status/hostgroups.rb', line 9 get "/_status/_hostgroup/:hostgroup" do |hostgroup| HostgroupController.new(hostgroup).full end |
#get("/_status/_hostgroup/: hostgroup/_host") ⇒ Object
Endpoint:
-
GET /_status/_hostgroup/:host
29 30 31 |
# File 'app/routes/get/status/hostgroups.rb', line 29 get "/_status/_hostgroup/:hostgroup/_host" do |hostgroup| HostgroupController.new(hostgroup).host_status end |
#get_status_hostgroup_service ⇒ Object
Endpoint:
-
GET /_status/_hostgroup/:hostgroup/_service
19 20 21 |
# File 'app/routes/get/status/hostgroups.rb', line 19 get "/_status/_hostgroup/:hostgroup/_service" do |hostgroup| HostgroupController.new(hostgroup).service_status end |
#get_status_hostname ⇒ Object
Hoststatus for single host or all services.
Endpoint
-
get “/_status/:hostname”
Accepted output type modifiers:
-
/_state
- Instead of full status information send only current state. For hosts up/down, for services OK, Warn, Critical, Unknown (0,1,2-1)
Support for:
-
plural resources: N/A
-
object access by ID: NO (TODO)
94 95 96 |
# File 'app/routes/get/status.rb', line 94 get %r{^/_status/(?<hostname>#{hostname_regex})$} do |hostname| HostStatusController.new(@status, output: @output, hostname: hostname).get end |
#get_status_hostname_services ⇒ Object
Endpoints:
-
GET /_status/:hostname/_services
-
GET /_status/:hostname/_hostcomments
-
GET /_status/:hostname/_servicecomments
Read services
, hostcomments
or servicecomments
for single host.
Accepted output type modifiers:
-
/_state
- Instead of full status information send only current state. For hosts up/down, for services OK, Warn, Critical, Unknown (0,1,2-1) -
/_list
: Short list of available objects, depending on the current request context: hosts, services, etc. -
/_full
- Show full status information. When used in /_status/_full call will display full hoststaus and servicestatus information for each host.
41 42 43 44 45 46 47 48 |
# File 'app/routes/get/status.rb', line 41 get %r{^/_status/(?<hostname>#{hostname_regex})/_(?<resource>(services|hostcomments|servicecomments))$} do |hostname,resource| # hostname = hostname.to_i if hostname =~ /^\d+$/ ResourceStatusController.new( @status, hostname: hostname, output: @output, resource: resource ).get end |
#get("/_status/: hostname/_services/:service_name") ⇒ Object
Full or short status information for single service on single host.
Accepted output type modifiers:
-
/_state
- Instead of full status information send only current state. For hosts up/down, for services OK, Warn, Critical, Unknown (0,1,2-1)
19 20 21 22 23 |
# File 'app/routes/get/status.rb', line 19 get "/_status/:hostname/_services/:service_name" do |hostname,service| ServiceStatusController.new( @status, hostname: hostname, service_name: service, output: @output ).get end |
#get_status_servicegroup ⇒ Object
Endpoint:
-
GET /_status/_servicegroup/:servicegroup
Supported extensions: _state, _list
12 13 14 |
# File 'app/routes/get/status/servicegroups.rb', line 12 get "/_status/_servicegroup/:servicegroup" do |group_name| ServicegroupController.new(group_name).send(@output) end |
#after("Object not found or bad request") ⇒ Object
If result-set of object/status search is empty return HTTP 404 . This can happen when you are requesting status for not existing host and/or service.
21 22 23 24 25 26 27 28 29 |
# File 'app/filters/after.rb', line 21 after do if response.body.empty? halt [404, { :message => "Object not found or bad request", :error => "HTTP::Notfound" }.send("to_#{@format}") ] end end |
#before("Parse PUT request body") ⇒ Array
Process the data before on each HTTP request.
142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'app/filters/before.rb', line 142 before do if request.put? data = request.body.read @input = case @format when :json then JSON.parse data when :xml then Hash.from_xml data when :yaml then YAML.load data end # Make sure we always return an Array @input = [@input] if @input.is_a? Hash @input end end |
#before("Parse Nagios files") ⇒ Object
Parse nagios files.
Note: *.parse methods are monkey-patched here (if you have required ‘lib/nagira’ above) to set min parsing interval to avoid file paring on each HTTP request. File is parsed only if it was changed and if it was parsed more then 60 (default) seconds ago. See lib/nagira/timed_parse.rb
for mor more info.
In development mode use files located under ./test/data
directory. This allows to do development on the host where Nagios is notinstalled. If you want to change this edit configuration in config/environment.rb file.
See also comments in config/default.rb file regarding nagios_cfg, status_cfg, objects_cfg.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'app/filters/before.rb', line 22 before do Logger.log("BackgroundParser is not running", :warning) if BackgroundParser.configured? && BackgroundParser.dead? Parser.parse @status = Parser.status['hosts'] @objects = Parser.objects # # Add plural keys to use ActiveResource with Nagira # @objects.keys.each do |singular| @objects[singular.to_s.pluralize.to_sym] = @objects[singular] end end |
#put("/_host_status/: host_name") ⇒ Object
Same as /_status/:host_name (Not implemented)
44 45 46 |
# File 'app/routes/put/host.rb', line 44 put "/_host_status/:host_name" do "Not implemented: TODO" end |
#put("/_status") ⇒ Object
Submit JSON Hash for multiple services, on multiple hosts.
10 11 12 |
# File 'app/routes/put/host.rb', line 10 put "/_status" do "TODO: Not implemented" end |
#put(/_status/: host_name/_services/:service_description/_return_code/:return_code/_plugin_output/:plugin_output) ⇒ Object
Update single service status on a single host. Use data provided in RESTful path as parameters.
Example
curl -d "test data" \
-X PUT http://localhost:4567/_status/viy/_services/PING/_return_code/0/_plugin_output/OK
# => ok
87 88 89 |
# File 'app/routes/put/status.rb', line 87 put "/_status/:host_name/_services/:service_description/_return_code/:return_code/_plugin_output/:plugin_output" do update_service_status params end |
#put("/_status/: host_name") ⇒ Object
Update hoststatus information only for the given host. URL hostname always override hostname given in the JSON file.
Example
$ curl -i -H "Accept: application/json" -d @host.json -X
PUT http://localhost:4567/_status/svaroh
=> {"result": true, "object": [{"data": {"host_name":"svaroh",
"status_code": "0", "plugin_output": "ping OK", "action":
"PROCESS_HOST_CHECK_RESULT"}, "result":true, "messages": []}]}
Example JSON
{
"status_code":"0",
"plugin_output" : "ping OK"
}
35 36 37 |
# File 'app/routes/put/host.rb', line 35 put "/_status/:host_name" do HostStatusController.new({}, hostname: params['host_name']).put(@input.first) end |
#put("/_status/: host_name/_services") ⇒ Object
Update multiple services on the same host.
Hostname from URL always overrides host_name if it’s is provided in the JSON data.
Example return JSON data
$ curl -i -H "Accept: application/json" -d @dat_m.json -X PUT
http://localhost:4567/_status/svaroh/_services
{"result"=>true,
"object"=>
[{"data"=>
{"return_code"=>0,
"plugin_output"=>"All OK",
"service_description"=>"PING",
"host_name"=>"archive",
"action"=>"PROCESS_SERVICE_CHECK_RESULT"},
"result"=>true,
"messages"=>[]}]}
Example JSON for submit
All attributes provided in the example below are requried for host service status information:
-
host_name
-
service_description
-
return_code
-
plugin_output
[{ "host_name":"viy", "service_description":"PING", "return_code":"0", "plugin_output":"64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.046 ms " }, {"host_name":"svaroh", "service_description":"Apache", "return_code":"2", "plugin_output":"HTTP GEt failed" } ]
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'app/routes/put/status.rb', line 54 put "/_status/:host_name/_services" do |hostname| data, result = [], true @input.each do |datum| # FIXME - this calls update for each service. Should be batching them together update = update_service_status( datum.merge({ 'host_name' => hostname }) ) data << update[:object].first result &&= update[:result] end { result: result, object: data } end |
#after("Return formatted data") ⇒ Object
If it’s a JSON-P request, return its data with prepended @callback function name. JSONP request is detected by before
method.
If no callback paramete given, then simply return formatted data as XML, JSON, or YAML in response body.
Example
$ curl 'http://localhost:4567/?callback=test'
test(["{\"application\":\"Nagira\",\"version\":\"0.1.3\",\"url\":\"http://dmytro.github.com/nagira/\"}"])
67 68 69 70 71 72 73 74 75 |
# File 'app/filters/after.rb', line 67 after do body( if @callback "#{@callback.to_s} (#{response.body.to_json})" else response.body.send "to_#{@format}" end ) end |
#before("Initial Config") ⇒ Object
Do some necessary tasks at start and then run Sinatra app.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'app/filters/configure.rb', line 11 configure do Parser.config = settings.nagios_cfg Parser.status = settings.status_cfg || Parser.config.status_file Parser.objects = settings.objects_cfg || Parser.config.object_cache_file Writer.commands = settings.command_file || Parser.config.command_file BackgroundParser.ttl = ::DEFAULT[:ttl].to_i BackgroundParser.start = ::DEFAULT[:start_background_parser] Logger.log "Starting Nagira application" Logger.log "Version #{Nagira::VERSION}" Logger.log "Running in #{Nagira.settings.environment} environment" Parser.state.to_h.keys.each do |x| Logger.log "Using nagios #{x} file: #{Parser.state[x].path}" end Logger.log "Using nagios command file: #{Writer.commands.path}" BackgroundParser.run if BackgroundParser.configured? end |
#before("detect format") ⇒ Object
Detect and strip output format extension
Strip extension (@format) from HTTP route and set it as instance variable @format. Valid formats are .xml, .json, .yaml. If format is not specified, it is set to default format (Nagira.settings.format).
@format can be assigned one of the symbols: :xml, :json, :yaml.
Examples
GET /_objects # => default format
GET /_objects.json # => :json
GET /_status/_list.yaml # => :yaml
69 70 71 72 73 |
# File 'app/filters/before.rb', line 69 before do request.path_info.sub!(/#{settings.format_extensions}/, '') @format = ($1 || settings.format).to_sym content_type "application/#{@format.to_s}" end |
#before('detect output mode') ⇒ Object
Detect output mode modifier
Detect and strip output type from HTTP route. Full list of output types is :list
, :state
or :full
, corresponding to (+/list, /state
, /full
routes).
Output type defined by route modifier appended to the end of HTTP route. If no output type specfied it is set to :full
. Output mode can be followed by format extension (.json
, .xml
or .yaml
).
Examples
GET /_objects/_list # => :list
GET /_status/_state # => :state
GET /_status/:hostname # => :full
GET /_status # => :normal
107 108 109 110 |
# File 'app/filters/before.rb', line 107 before do request.path_info.sub!(/\/_(list|state|full)$/, '') @output = ($1 || :normal).to_sym end |
#update_service_status(params) ⇒ Object
Small helper to submit data to ::Nagios::ExternalCommands object. For status updates sends external coond via ::Nagios::ExternalCommands.send method.
7 8 9 |
# File 'app/helpers/put_helpers.rb', line 7 def update_service_status params Writer.new(:PROCESS_SERVICE_CHECK_RESULT).put params end |