This repository has been archived by the owner on Sep 26, 2023. It is now read-only.
/
app.rb
executable file
·274 lines (244 loc) · 7.59 KB
/
app.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
#!/usr/bin/env ruby
# @!macro [attach] sinatra.get
#
# @overload get "$1"
#
# @return HTTP response. Hash formatted in the format defined by
# requested output type(XML, YAML or JSON).
#
#
#
# @!macro [new] type
# @param [String] :type Type is one of Nagios objects like hosts, hostgroupsroups, etc.
#
# @!macro [new] name
# @param [String] :name
#
# @!macro [new] hostname
# @param [String] :hostname Configured Nagios hostname
#
# @!macro [new] service_name
# @param [String] :service_name Configured Nagios service for the host
#
# @!macro [new] accepted
#
# <b>Accepted output type modifiers:</b>
#
# @!macro [new] list
#
# - +/_list+ : Short list of available objects, depending on the
# current request context: hosts, services, etc.
#
# @!macro [new] state
#
# - +/_state+ - Instead of full status information send only
# current state. For hosts up/down, for services OK, Warn,
# Critical, Unknown (0,1,2-1)
#
# @!macro [new] full
#
# - +/_full+ - Show full status information. When used in
# /_status/_full call will display full hoststaus and
# servicestatus information for each host.
#
#
$: << File.dirname(__FILE__)
require 'lib/nagira'
##
# Main class of Nagira application implementing RESTful API for
# Nagios.
#
class Nagira < Sinatra::Base
set :app_file, __FILE__
##
# 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.
#
# @method parse_nagios_files
# @overload before("Parse Nagios files")
before do
$nagios ||= { :config => nil, :status => nil, :objects => nil }
$nagios[:config] ||= Nagios::Config.new Nagira.settings.nagios_cfg
$nagios[:config].parse
$nagios[:status] ||= Nagios::Status.new( Nagira.settings.status_cfg ||
$nagios[:config].status_file
)
$nagios[:objects] ||= Nagios::Objects.new( Nagira.settings.objects_cfg ||
$nagios[:config].object_cache_file
)
$nagios[:commands] ||= Nagios::ExternalCommands.new( Nagira.settings.command_file ||
$nagios[:config].command_file
)
$nagios[:status].parse
$nagios[:objects].parse
@status = $nagios[:status].status['hosts']
@objects = $nagios[:objects].objects
end
##
# @method clear_instance_data
# @overload before("clear data")
#
# Clear values onf instance variables before start.
#
before do
@data = []
@format = @output = nil
end
##
# @method strip_extensions
# @overload before("detect format")
#
# 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
#
before do
request.path_info.sub!(/#{settings.format_extensions}/, '')
@format = ($1 || settings.format).to_sym
content_type "application/#{@format.to_s}"
end
##
# @method strip_output_type
# @overload before('detect output mode')
#
# 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
#
before do
request.path_info.sub!(/\/_(list|state|full)$/, '')
@output = ($1 || :normal).to_sym
end
##
# @method find_jsonp_callback
# @overload before('find callback name')
#
# 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
# https://github.com/shtirlic/sinatra-jsonp.
#
before do
if @format == :json
['callback','jscallback','jsonp','jsoncallback'].each do |x|
@callback = params.delete(x) unless @callback
end
end
end
##
# @method object_not_found
# @overload after("Object not found or bad request")
#
# 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.
#
#
after do
# return unless request["REQUEST_METHOD"] == 'PUT'
if ! @data || @data.empty?
halt [404, {
:message => "Object not found or bad request",
:error => "HTTP::Notfound"
}.send("to_#{@format}")
]
end
end
##
# @method return_jsonp_data
# @overload after("Return formatted data")
#
# 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/\"}"])
#
after do
body( @callback ? "#{@callback.to_s} (#{@data.to_json})" : @data.send("to_#{@format}") )
end
require_relative "app/routes/get/config"
require_relative "app/routes/get/objects"
require_relative "app/routes/get/status"
require_relative "app/routes/put"
require_relative "app/routes/put/status"
##
# @method get_api
# @overload get(/_api)
#
# Provide information about API routes
#
get "/_api" do
@data = self.api
nil
end
# @method get_slash
# @overload get(/)
#
# Returns application information: name, version, github repository.
get "/" do
@data = {
:application => self.class,
:version => VERSION,
:source => GITHUB,
:apiUrl => request.url.sub(/\/$/,'') + "/_api"
}
nil
end
# Other resources in parsed status file. Supported are => ["hosts",
# "info", "process", "contacts"]
# get "/:resource" do |resource|
# respond_with $nagios.status[resource], @format
# end
# Start Sinatra application when not running from rack
run! if app_file == $0
end