livestatus 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +5 -0
- data/.rvmrc +1 -0
- data/Gemfile +2 -0
- data/LICENSE +20 -0
- data/README.rst +30 -0
- data/Rakefile +1 -0
- data/contrib/example.rb +13 -0
- data/contrib/live.php +252 -0
- data/lib/livestatus.rb +26 -0
- data/lib/livestatus/connection.rb +28 -0
- data/lib/livestatus/handler.rb +5 -0
- data/lib/livestatus/handler/base.rb +32 -0
- data/lib/livestatus/handler/patron.rb +43 -0
- data/lib/livestatus/model.rb +5 -0
- data/lib/livestatus/model/base.rb +84 -0
- data/lib/livestatus/model/command.rb +2 -0
- data/lib/livestatus/model/comment.rb +2 -0
- data/lib/livestatus/model/contact.rb +2 -0
- data/lib/livestatus/model/contactgroup.rb +2 -0
- data/lib/livestatus/model/downtime.rb +2 -0
- data/lib/livestatus/model/host.rb +20 -0
- data/lib/livestatus/model/hostgroup.rb +2 -0
- data/lib/livestatus/model/service.rb +29 -0
- data/lib/livestatus/model/servicegroup.rb +2 -0
- data/lib/livestatus/model/timeperiod.rb +2 -0
- data/lib/livestatus/version.rb +3 -0
- data/livestatus.gemspec +23 -0
- metadata +116 -0
data/.rvmrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
rvm use --create ruby-1.9.2-p290@livestatus
|
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2011 Benedikt Böhm
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rst
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
==========
|
|
2
|
+
livestatus
|
|
3
|
+
==========
|
|
4
|
+
|
|
5
|
+
:Author: `Benedikt Böhm <bb@xnull.de>`_
|
|
6
|
+
:Web: http://github.com/zenops/livestatus
|
|
7
|
+
:Git: ``git clone https://github.com/zenops/livestatus``
|
|
8
|
+
|
|
9
|
+
Livestatus is a simple Ruby library to get Nagios data via MK Livestatus or
|
|
10
|
+
LivestatusSlave.
|
|
11
|
+
|
|
12
|
+
Contributing to livestatus
|
|
13
|
+
==========================
|
|
14
|
+
|
|
15
|
+
- Check out the latest master to make sure the feature hasn't been implemented
|
|
16
|
+
or the bug hasn't been fixed yet
|
|
17
|
+
|
|
18
|
+
- Check out the issue tracker to make sure someone already hasn't requested it
|
|
19
|
+
and/or contributed it
|
|
20
|
+
|
|
21
|
+
- Fork the project
|
|
22
|
+
|
|
23
|
+
- Start a feature/bugfix branch
|
|
24
|
+
|
|
25
|
+
- Commit and push until you are happy with your contribution
|
|
26
|
+
|
|
27
|
+
Copyright
|
|
28
|
+
=========
|
|
29
|
+
|
|
30
|
+
Copyright (c) 2011 Benedikt Böhm. See LICENSE for further details.
|
data/Rakefile
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require "bundler/gem_tasks"
|
data/contrib/example.rb
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'livestatus'
|
|
4
|
+
|
|
5
|
+
c = Livestatus::Connection.new("https://nagios.example.com/nagios/live.php")
|
|
6
|
+
|
|
7
|
+
c.handler.session.insecure = true
|
|
8
|
+
c.handler.session.auth_type = :basic
|
|
9
|
+
c.handler.session.username = 'admin'
|
|
10
|
+
c.handler.session.password = 'password'
|
|
11
|
+
|
|
12
|
+
c.command("DISABLE_NOTIFICATIONS")
|
|
13
|
+
puts c.get("status").inspect
|
data/contrib/live.php
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
/*****************************************************************************
|
|
3
|
+
*
|
|
4
|
+
* live.php - Standalone PHP script to serve the unix socket of the
|
|
5
|
+
* MKLivestatus NEB module as webservice.
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2010,2011 Lars Michelsen <lm@larsmichelsen.com>
|
|
8
|
+
* Copyright (c) 2011 Benedikt Böhm <bb@xnull.de>
|
|
9
|
+
*
|
|
10
|
+
* License:
|
|
11
|
+
*
|
|
12
|
+
* This program is free software; you can redistribute it and/or modify
|
|
13
|
+
* it under the terms of the GNU General Public License version 2 as
|
|
14
|
+
* published by the Free Software Foundation.
|
|
15
|
+
*
|
|
16
|
+
* This program is distributed in the hope that it will be useful,
|
|
17
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
18
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
19
|
+
* GNU General Public License for more details.
|
|
20
|
+
*
|
|
21
|
+
* You should have received a copy of the GNU General Public License
|
|
22
|
+
* along with this program; if not, write to the Free Software
|
|
23
|
+
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
24
|
+
*
|
|
25
|
+
* @AUTHOR Lars Michelsen <lm@larsmichelsen.com>
|
|
26
|
+
* @HOME http://nagios.larsmichelsen.com/livestatusslave/
|
|
27
|
+
* @VERSION 1.1
|
|
28
|
+
*****************************************************************************/
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Script configuration.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
$conf = Array(
|
|
35
|
+
// The socket type can be 'unix' for connecting with the unix socket or 'tcp'
|
|
36
|
+
// to connect to a tcp socket.
|
|
37
|
+
'socketType' => 'unix',
|
|
38
|
+
// When using a unix socket the path to the socket needs to be set
|
|
39
|
+
'socketPath' => '/var/nagios/rw/live',
|
|
40
|
+
// When using a tcp socket the address and port needs to be set
|
|
41
|
+
'socketAddress' => '',
|
|
42
|
+
'socketPort' => '',
|
|
43
|
+
// Modify the default allowed query type match regex
|
|
44
|
+
'queryTypes' => '(GET|COMMAND)',
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
###############################################################################
|
|
49
|
+
# Don't modify the code below when you're not aware of what you are doing...
|
|
50
|
+
###############################################################################
|
|
51
|
+
|
|
52
|
+
class LiveException extends Exception {}
|
|
53
|
+
|
|
54
|
+
$LIVE = null;
|
|
55
|
+
|
|
56
|
+
// Start the main function
|
|
57
|
+
livestatusSlave();
|
|
58
|
+
|
|
59
|
+
function livestatusSlave() {
|
|
60
|
+
global $conf;
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
verifyConfig();
|
|
64
|
+
connectSocket();
|
|
65
|
+
|
|
66
|
+
$query = getQuery();
|
|
67
|
+
response(Array(0, 'OK'), queryLivestatus($query));
|
|
68
|
+
|
|
69
|
+
closeSocket();
|
|
70
|
+
exit(0);
|
|
71
|
+
} catch(LiveException $e) {
|
|
72
|
+
response(Array(1, $e->getMessage()), Array());
|
|
73
|
+
closeSocket();
|
|
74
|
+
exit(1);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function readQuery() {
|
|
79
|
+
global $argv;
|
|
80
|
+
|
|
81
|
+
if (isset($_REQUEST['q']) && $_REQUEST['q'] !== '') {
|
|
82
|
+
return str_replace('\\\\n', "\n", $_REQUEST['q']);
|
|
83
|
+
} elseif (isset($argv[1]) && $argv[1] !== '') {
|
|
84
|
+
return str_replace('\\n', "\n", $argv[1]);
|
|
85
|
+
} else {
|
|
86
|
+
throw new LiveException('No query given in "q" Attribute nor argv[0].');
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function getQuery() {
|
|
91
|
+
global $conf;
|
|
92
|
+
$query = readQuery();
|
|
93
|
+
|
|
94
|
+
if (!preg_match("/^".$conf['queryTypes']."\s/", $query))
|
|
95
|
+
throw new LiveException('Invalid livestatus query: ' . $query);
|
|
96
|
+
|
|
97
|
+
return $query;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function response($head, $body) {
|
|
101
|
+
header('Content-type: application/json');
|
|
102
|
+
$json_result = json_encode(Array($head, $body));
|
|
103
|
+
|
|
104
|
+
// Support jsonp when requested by client (see http://en.wikipedia.org/wiki/JSONP).
|
|
105
|
+
if (isset($_REQUEST['callback']) && $_REQUEST['callback'] != '')
|
|
106
|
+
$json_result = $_REQUEST['callback']."(".$json_result.")";
|
|
107
|
+
|
|
108
|
+
echo $json_result;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function verifyConfig() {
|
|
112
|
+
global $conf;
|
|
113
|
+
|
|
114
|
+
if (!function_exists('socket_create')) {
|
|
115
|
+
throw new LiveException('The PHP function socket_create is not available. Maybe the sockets module is missing in your PHP installation.');
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if ($conf['socketType'] != 'tcp' && $conf['socketType'] != 'unix') {
|
|
119
|
+
throw new LiveException('Socket Type is invalid. Need to be "unix" or "tcp".');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if ($conf['socketType'] == 'unix') {
|
|
123
|
+
if ($conf['socketPath'] == '') {
|
|
124
|
+
throw new LiveException('The option socketPath is empty.');
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (!file_exists($conf['socketPath'])) {
|
|
128
|
+
throw new LiveException('The configured livestatus socket does not exists');
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
elseif ($conf['socketType'] == 'tcp') {
|
|
133
|
+
if ($conf['socketAddress'] == '') {
|
|
134
|
+
throw new LiveException('The option socketAddress is empty.');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if ($conf['socketPort'] == '') {
|
|
138
|
+
throw new LiveException('The option socketPort is empty.');
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function readSocket($len) {
|
|
144
|
+
global $LIVE;
|
|
145
|
+
$offset = 0;
|
|
146
|
+
$socketData = '';
|
|
147
|
+
|
|
148
|
+
while($offset < $len) {
|
|
149
|
+
if (($data = @socket_read($LIVE, $len - $offset)) === false)
|
|
150
|
+
return false;
|
|
151
|
+
|
|
152
|
+
$dataLen = strlen ($data);
|
|
153
|
+
$offset += $dataLen;
|
|
154
|
+
$socketData .= $data;
|
|
155
|
+
|
|
156
|
+
if ($dataLen == 0)
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return $socketData;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function queryLivestatus($query) {
|
|
164
|
+
global $LIVE;
|
|
165
|
+
|
|
166
|
+
// Query to get a json formated array back
|
|
167
|
+
// Use fixed16 header
|
|
168
|
+
socket_write($LIVE, $query . "OutputFormat: json\nResponseHeader: fixed16\n\n");
|
|
169
|
+
socket_shutdown($LIVE, 1);
|
|
170
|
+
|
|
171
|
+
if (substr($query, 0, 7) == "COMMAND") {
|
|
172
|
+
return Array();
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Read 16 bytes to get the status code and body size
|
|
176
|
+
$read = readSocket(16);
|
|
177
|
+
|
|
178
|
+
if ($read === false)
|
|
179
|
+
throw new LiveException('Problem while reading from socket: '.socket_strerror(socket_last_error($LIVE)));
|
|
180
|
+
|
|
181
|
+
// Extract status code
|
|
182
|
+
$status = substr($read, 0, 3);
|
|
183
|
+
|
|
184
|
+
// Extract content length
|
|
185
|
+
$len = intval(trim(substr($read, 4, 11)));
|
|
186
|
+
|
|
187
|
+
// Read socket until end of data
|
|
188
|
+
$read = readSocket($len);
|
|
189
|
+
|
|
190
|
+
if ($read === false)
|
|
191
|
+
throw new LiveException('Problem while reading from socket: '.socket_strerror(socket_last_error($LIVE)));
|
|
192
|
+
|
|
193
|
+
// Catch errors (Like HTTP 200 is OK)
|
|
194
|
+
if ($status != "200")
|
|
195
|
+
throw new LiveException('Problem while reading from socket: '.$read);
|
|
196
|
+
|
|
197
|
+
// Catch problems occured while reading? 104: Connection reset by peer
|
|
198
|
+
if (socket_last_error($LIVE) == 104)
|
|
199
|
+
throw new LiveException('Problem while reading from socket: '.socket_strerror(socket_last_error($LIVE)));
|
|
200
|
+
|
|
201
|
+
// Decode the json response
|
|
202
|
+
$obj = json_decode(utf8_encode($read));
|
|
203
|
+
|
|
204
|
+
// json_decode returns null on syntax problems
|
|
205
|
+
if ($obj === null)
|
|
206
|
+
throw new LiveException('The response has an invalid format');
|
|
207
|
+
else
|
|
208
|
+
return $obj;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function connectSocket() {
|
|
212
|
+
global $conf, $LIVE;
|
|
213
|
+
|
|
214
|
+
// Create socket connection
|
|
215
|
+
if ($conf['socketType'] === 'unix') {
|
|
216
|
+
$LIVE = socket_create(AF_UNIX, SOCK_STREAM, 0);
|
|
217
|
+
} elseif ($conf['socketType'] === 'tcp') {
|
|
218
|
+
$LIVE = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if ($LIVE == false) {
|
|
222
|
+
throw new LiveException('Could not create livestatus socket connection.');
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Connect to the socket
|
|
226
|
+
if ($conf['socketType'] === 'unix') {
|
|
227
|
+
$result = socket_connect($LIVE, $conf['socketPath']);
|
|
228
|
+
} elseif ($conf['socketType'] === 'tcp') {
|
|
229
|
+
$result = socket_connect($LIVE, $conf['socketAddress'], $conf['socketPort']);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if ($result == false) {
|
|
233
|
+
throw new LiveException('Unable to connect to livestatus socket.');
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Maybe set some socket options
|
|
237
|
+
if ($conf['socketType'] === 'tcp') {
|
|
238
|
+
// Disable Nagle's Algorithm - Nagle's Algorithm is bad for brief protocols
|
|
239
|
+
if (defined('TCP_NODELAY')) {
|
|
240
|
+
socket_set_option($LIVE, SOL_TCP, TCP_NODELAY, 1);
|
|
241
|
+
} else {
|
|
242
|
+
// See http://bugs.php.net/bug.php?id=46360
|
|
243
|
+
socket_set_option($LIVE, SOL_TCP, 1, 1);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function closeSocket() {
|
|
249
|
+
global $LIVE;
|
|
250
|
+
@socket_close($LIVE);
|
|
251
|
+
$LIVE = null;
|
|
252
|
+
}
|
data/lib/livestatus.rb
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require "active_support/core_ext"
|
|
2
|
+
|
|
3
|
+
require "livestatus/version"
|
|
4
|
+
require "livestatus/connection"
|
|
5
|
+
require "livestatus/model"
|
|
6
|
+
|
|
7
|
+
module Livestatus
|
|
8
|
+
mattr_accessor :config
|
|
9
|
+
self.config = {}
|
|
10
|
+
|
|
11
|
+
def self.connection
|
|
12
|
+
@@connection ||= connection!
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.connection!
|
|
16
|
+
Livestatus::Connection.new(config)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.get(table_name, options = {})
|
|
20
|
+
connection.get(table_name, options)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.command(cmd, time = nil)
|
|
24
|
+
connection.command(cmd, time)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require "livestatus/handler"
|
|
2
|
+
|
|
3
|
+
module Livestatus
|
|
4
|
+
|
|
5
|
+
class Connection
|
|
6
|
+
extend Forwardable
|
|
7
|
+
|
|
8
|
+
def_delegators :handler, :get, :command
|
|
9
|
+
|
|
10
|
+
def initialize(config)
|
|
11
|
+
@config = config.symbolize_keys!
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def handler
|
|
15
|
+
@handler ||= handler!
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def handler!
|
|
19
|
+
case @config[:uri]
|
|
20
|
+
when /^https?:\/\//
|
|
21
|
+
PatronHandler.new(@config)
|
|
22
|
+
else
|
|
23
|
+
raise AttributeError, "unknown uri type: #{@config[:uri]}"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Livestatus
|
|
2
|
+
|
|
3
|
+
class HandlerException < StandardError; end
|
|
4
|
+
|
|
5
|
+
class BaseHandler
|
|
6
|
+
def get(table_name, options = {})
|
|
7
|
+
data = query(:get, table_name.to_s, options)
|
|
8
|
+
|
|
9
|
+
if options.include?(:columns)
|
|
10
|
+
columns = options[:columns].split(" ")
|
|
11
|
+
else
|
|
12
|
+
columns = data.delete_at(0)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
column_zip(columns, data)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def command(cmd, time = nil)
|
|
19
|
+
time = Time.now.to_i unless time
|
|
20
|
+
query(:command, "[#{time}] #{cmd}")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def column_zip(columns, data)
|
|
26
|
+
data.map do |d|
|
|
27
|
+
Hash[columns.zip(d)]
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require 'patron'
|
|
2
|
+
require 'yajl'
|
|
3
|
+
require 'cgi'
|
|
4
|
+
|
|
5
|
+
module Livestatus
|
|
6
|
+
|
|
7
|
+
class PatronHandler < BaseHandler
|
|
8
|
+
attr_accessor :session
|
|
9
|
+
|
|
10
|
+
def initialize(config)
|
|
11
|
+
@session = Patron::Session.new
|
|
12
|
+
@session.timeout = 10
|
|
13
|
+
@session.headers["User-Agent"] = "livestatus/#{VERSION} ruby/#{RUBY_VERSION}"
|
|
14
|
+
@session.insecure = config[:insecure]
|
|
15
|
+
@session.auth_type = config[:auth_type].to_sym
|
|
16
|
+
@session.username = config[:username]
|
|
17
|
+
@session.password = config[:password]
|
|
18
|
+
@uri = config[:uri]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def query(method, query, headers = {})
|
|
22
|
+
headers = headers.map { |k,v| "#{k.to_s.capitalize}: #{v}" }.join("\n")
|
|
23
|
+
headers += "\n" unless headers.empty?
|
|
24
|
+
|
|
25
|
+
query = CGI::escape("#{method.to_s.upcase} #{query}\n#{headers}")
|
|
26
|
+
result = session.get("#{@uri}?q=#{query}")
|
|
27
|
+
|
|
28
|
+
unless result.status == 200
|
|
29
|
+
raise HandlerException, "livestatus query failed with status #{result.status}"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
parser = Yajl::Parser.new
|
|
33
|
+
data = parser.parse(result.body)
|
|
34
|
+
|
|
35
|
+
if data[0][0] > 0
|
|
36
|
+
raise HandlerException, "livestatus returned error: #{data[0][1]}"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
return data[1]
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
module Livestatus
|
|
2
|
+
class Base
|
|
3
|
+
attr_reader :data
|
|
4
|
+
|
|
5
|
+
def initialize(data)
|
|
6
|
+
@data = data.symbolize_keys!
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def method_missing(name, *args)
|
|
10
|
+
data[name.to_sym]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class << self
|
|
14
|
+
def find(options = {})
|
|
15
|
+
Livestatus.get(table_name, options).map do |data|
|
|
16
|
+
new(data)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def table_name
|
|
21
|
+
to_s.demodulize.tableize.downcase.pluralize
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def boolean_attributes(*accessors)
|
|
25
|
+
accessors.each do |m|
|
|
26
|
+
define_method(m) do
|
|
27
|
+
data[m] == 1
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def time_attributes(*accessors)
|
|
33
|
+
accessors.each do |m|
|
|
34
|
+
define_method(m) do
|
|
35
|
+
Time.at(data[m].to_i)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
module ID
|
|
43
|
+
def id
|
|
44
|
+
Digest::SHA1.hexdigest(_id)[0..7]
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
module State
|
|
49
|
+
def state
|
|
50
|
+
{
|
|
51
|
+
0 => :ok,
|
|
52
|
+
1 => :warning,
|
|
53
|
+
2 => :critical,
|
|
54
|
+
3 => :unknown,
|
|
55
|
+
}[data[:state]]
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def state_class
|
|
59
|
+
{
|
|
60
|
+
:ok => :green,
|
|
61
|
+
:warning => :yellow,
|
|
62
|
+
:critical => :red,
|
|
63
|
+
:unknown => :orange,
|
|
64
|
+
:pending => :gray,
|
|
65
|
+
}[state]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def state_type
|
|
69
|
+
{
|
|
70
|
+
0 => :soft,
|
|
71
|
+
1 => :hard,
|
|
72
|
+
}[data[:state_type]]
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
module CheckType
|
|
77
|
+
def check_type
|
|
78
|
+
{
|
|
79
|
+
0 => :active,
|
|
80
|
+
1 => :passive,
|
|
81
|
+
}[data[:check_type]]
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
class Livestatus::Host < Livestatus::Base
|
|
2
|
+
include Livestatus::ID
|
|
3
|
+
include Livestatus::CheckType
|
|
4
|
+
include Livestatus::State
|
|
5
|
+
|
|
6
|
+
boolean_attributes :accept_passive_checks, :acknowledged,
|
|
7
|
+
:active_checks_enabled, :checks_enabled, :event_handler_enabled,
|
|
8
|
+
:flap_detection_enabled, :has_been_checked, :in_check_period,
|
|
9
|
+
:in_notification_period, :is_executing, :is_flapping,
|
|
10
|
+
:notifications_enabled, :obsess_over_host, :pending_flex_downtime,
|
|
11
|
+
:process_performance_data
|
|
12
|
+
|
|
13
|
+
time_attributes :last_check, :last_hard_state, :last_hard_state_change,
|
|
14
|
+
:last_notification, :last_state_change, :last_time_down,
|
|
15
|
+
:last_time_unreachable, :last_time_up, :next_check, :next_notification
|
|
16
|
+
|
|
17
|
+
def _id
|
|
18
|
+
display_name
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
class Livestatus::Service < Livestatus::Base
|
|
2
|
+
include Livestatus::ID
|
|
3
|
+
include Livestatus::CheckType
|
|
4
|
+
include Livestatus::State
|
|
5
|
+
|
|
6
|
+
boolean_attributes :accept_passive_checks, :acknowledged,
|
|
7
|
+
:active_checks_enabled, :checks_enabled, :event_handler_enabled,
|
|
8
|
+
:flap_detection_enabled, :has_been_checked, :host_accept_passive_checks,
|
|
9
|
+
:host_acknowledged, :host_active_checks_enabled, :host_checks_enabled,
|
|
10
|
+
:host_event_handler_enabled, :host_flap_detection_enabled,
|
|
11
|
+
:host_has_been_checked, :host_in_check_period,
|
|
12
|
+
:host_in_notification_period, :host_is_executing, :host_is_flapping,
|
|
13
|
+
:host_notifications_enabled, :host_obsess_over_host,
|
|
14
|
+
:host_pending_flex_downtime, :host_process_performance_data,
|
|
15
|
+
:in_check_period, :in_notification_period, :is_executing, :is_flapping,
|
|
16
|
+
:notifications_enabled, :obsess_over_service, :process_performance_data
|
|
17
|
+
|
|
18
|
+
time_attributes :host_last_check, :host_last_hard_state,
|
|
19
|
+
:host_last_hard_state_change, :host_last_notification,
|
|
20
|
+
:host_last_state_change, :host_last_time_down, :host_last_time_unreachable,
|
|
21
|
+
:host_last_time_up, :host_next_check, :last_check, :last_hard_state,
|
|
22
|
+
:last_hard_state_change, :last_notification, :last_state_change,
|
|
23
|
+
:last_time_critical, :last_time_ok, :last_time_unknown, :last_time_warning,
|
|
24
|
+
:next_check, :next_notification
|
|
25
|
+
|
|
26
|
+
def _id
|
|
27
|
+
host_display_name + display_name
|
|
28
|
+
end
|
|
29
|
+
end
|
data/livestatus.gemspec
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
|
3
|
+
require "livestatus/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |s|
|
|
6
|
+
s.name = "livestatus"
|
|
7
|
+
s.version = Livestatus::VERSION
|
|
8
|
+
s.authors = ["Benedikt Böhm"]
|
|
9
|
+
s.email = ["bb@xnull.de"]
|
|
10
|
+
s.homepage = ""
|
|
11
|
+
s.summary = %q{Simple API wrapper for MK Livestatus and LivestatusSlave}
|
|
12
|
+
s.description = %q{Simple API wrapper for MK Livestatus and LivestatusSlave}
|
|
13
|
+
|
|
14
|
+
s.files = `git ls-files`.split("\n")
|
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
17
|
+
s.require_paths = ["lib"]
|
|
18
|
+
|
|
19
|
+
s.add_runtime_dependency "activesupport"
|
|
20
|
+
s.add_runtime_dependency "i18n"
|
|
21
|
+
s.add_runtime_dependency "patron"
|
|
22
|
+
s.add_runtime_dependency "yajl-ruby"
|
|
23
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: livestatus
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
prerelease:
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- Benedikt Böhm
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2011-11-19 00:00:00.000000000Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: activesupport
|
|
16
|
+
requirement: &24410080 !ruby/object:Gem::Requirement
|
|
17
|
+
none: false
|
|
18
|
+
requirements:
|
|
19
|
+
- - ! '>='
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '0'
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: *24410080
|
|
25
|
+
- !ruby/object:Gem::Dependency
|
|
26
|
+
name: i18n
|
|
27
|
+
requirement: &24409660 !ruby/object:Gem::Requirement
|
|
28
|
+
none: false
|
|
29
|
+
requirements:
|
|
30
|
+
- - ! '>='
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: *24409660
|
|
36
|
+
- !ruby/object:Gem::Dependency
|
|
37
|
+
name: patron
|
|
38
|
+
requirement: &24409240 !ruby/object:Gem::Requirement
|
|
39
|
+
none: false
|
|
40
|
+
requirements:
|
|
41
|
+
- - ! '>='
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
version: '0'
|
|
44
|
+
type: :runtime
|
|
45
|
+
prerelease: false
|
|
46
|
+
version_requirements: *24409240
|
|
47
|
+
- !ruby/object:Gem::Dependency
|
|
48
|
+
name: yajl-ruby
|
|
49
|
+
requirement: &24408820 !ruby/object:Gem::Requirement
|
|
50
|
+
none: false
|
|
51
|
+
requirements:
|
|
52
|
+
- - ! '>='
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
type: :runtime
|
|
56
|
+
prerelease: false
|
|
57
|
+
version_requirements: *24408820
|
|
58
|
+
description: Simple API wrapper for MK Livestatus and LivestatusSlave
|
|
59
|
+
email:
|
|
60
|
+
- bb@xnull.de
|
|
61
|
+
executables: []
|
|
62
|
+
extensions: []
|
|
63
|
+
extra_rdoc_files: []
|
|
64
|
+
files:
|
|
65
|
+
- .gitignore
|
|
66
|
+
- .rvmrc
|
|
67
|
+
- Gemfile
|
|
68
|
+
- LICENSE
|
|
69
|
+
- README.rst
|
|
70
|
+
- Rakefile
|
|
71
|
+
- contrib/example.rb
|
|
72
|
+
- contrib/live.php
|
|
73
|
+
- lib/livestatus.rb
|
|
74
|
+
- lib/livestatus/connection.rb
|
|
75
|
+
- lib/livestatus/handler.rb
|
|
76
|
+
- lib/livestatus/handler/base.rb
|
|
77
|
+
- lib/livestatus/handler/patron.rb
|
|
78
|
+
- lib/livestatus/model.rb
|
|
79
|
+
- lib/livestatus/model/base.rb
|
|
80
|
+
- lib/livestatus/model/command.rb
|
|
81
|
+
- lib/livestatus/model/comment.rb
|
|
82
|
+
- lib/livestatus/model/contact.rb
|
|
83
|
+
- lib/livestatus/model/contactgroup.rb
|
|
84
|
+
- lib/livestatus/model/downtime.rb
|
|
85
|
+
- lib/livestatus/model/host.rb
|
|
86
|
+
- lib/livestatus/model/hostgroup.rb
|
|
87
|
+
- lib/livestatus/model/service.rb
|
|
88
|
+
- lib/livestatus/model/servicegroup.rb
|
|
89
|
+
- lib/livestatus/model/timeperiod.rb
|
|
90
|
+
- lib/livestatus/version.rb
|
|
91
|
+
- livestatus.gemspec
|
|
92
|
+
homepage: ''
|
|
93
|
+
licenses: []
|
|
94
|
+
post_install_message:
|
|
95
|
+
rdoc_options: []
|
|
96
|
+
require_paths:
|
|
97
|
+
- lib
|
|
98
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
99
|
+
none: false
|
|
100
|
+
requirements:
|
|
101
|
+
- - ! '>='
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '0'
|
|
104
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
105
|
+
none: false
|
|
106
|
+
requirements:
|
|
107
|
+
- - ! '>='
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '0'
|
|
110
|
+
requirements: []
|
|
111
|
+
rubyforge_project:
|
|
112
|
+
rubygems_version: 1.8.10
|
|
113
|
+
signing_key:
|
|
114
|
+
specification_version: 3
|
|
115
|
+
summary: Simple API wrapper for MK Livestatus and LivestatusSlave
|
|
116
|
+
test_files: []
|