livestatus 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rvmrc +1 -1
- data/Gemfile +4 -0
- data/README.rst +2 -3
- data/config.ru +2 -0
- data/{contrib/example.rb → examples/http.rb} +1 -1
- data/examples/simple.rb +5 -0
- data/examples/unix.rb +8 -0
- data/lib/livestatus.rb +4 -2
- data/lib/livestatus/api.rb +29 -0
- data/lib/livestatus/connection.rb +2 -0
- data/lib/livestatus/handler.rb +16 -1
- data/lib/livestatus/handler/patron.rb +9 -14
- data/lib/livestatus/handler/unix.rb +55 -0
- data/lib/livestatus/{model/base.rb → models.rb} +13 -0
- data/lib/livestatus/{model → models}/command.rb +0 -0
- data/lib/livestatus/{model → models}/comment.rb +0 -0
- data/lib/livestatus/{model → models}/contact.rb +0 -0
- data/lib/livestatus/{model → models}/contactgroup.rb +0 -0
- data/lib/livestatus/{model → models}/downtime.rb +0 -0
- data/lib/livestatus/{model → models}/host.rb +0 -0
- data/lib/livestatus/{model → models}/hostgroup.rb +0 -0
- data/lib/livestatus/{model → models}/service.rb +0 -0
- data/lib/livestatus/{model → models}/servicegroup.rb +0 -0
- data/lib/livestatus/{model → models}/timeperiod.rb +0 -0
- data/lib/livestatus/version.rb +1 -1
- data/livestatus.gemspec +3 -3
- metadata +83 -71
- data/contrib/live.php +0 -252
- data/lib/livestatus/handler/base.rb +0 -32
- data/lib/livestatus/model.rb +0 -5
data/.rvmrc
CHANGED
@@ -1 +1 @@
|
|
1
|
-
rvm use --create ruby-1.
|
1
|
+
rvm use --create ruby-1.8.7-p352@livestatus
|
data/Gemfile
CHANGED
data/README.rst
CHANGED
@@ -3,11 +3,10 @@ livestatus
|
|
3
3
|
==========
|
4
4
|
|
5
5
|
:Author: `Benedikt Böhm <bb@xnull.de>`_
|
6
|
-
:Web:
|
6
|
+
:Web: https://github.com/zenops/livestatus
|
7
7
|
:Git: ``git clone https://github.com/zenops/livestatus``
|
8
8
|
|
9
|
-
Livestatus is a simple Ruby library to
|
10
|
-
LivestatusSlave.
|
9
|
+
Livestatus is a simple Ruby library to control Nagios via MK Livestatus.
|
11
10
|
|
12
11
|
Contributing to livestatus
|
13
12
|
==========================
|
data/config.ru
ADDED
data/examples/simple.rb
ADDED
data/examples/unix.rb
ADDED
data/lib/livestatus.rb
CHANGED
@@ -2,11 +2,13 @@ require "active_support/core_ext"
|
|
2
2
|
|
3
3
|
require "livestatus/version"
|
4
4
|
require "livestatus/connection"
|
5
|
-
require "livestatus/
|
5
|
+
require "livestatus/models"
|
6
6
|
|
7
7
|
module Livestatus
|
8
8
|
mattr_accessor :config
|
9
|
-
self.config = {
|
9
|
+
self.config = {
|
10
|
+
:uri => "unix:///var/nagios/rw/live",
|
11
|
+
}
|
10
12
|
|
11
13
|
def self.connection
|
12
14
|
@@connection ||= connection!
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'livestatus/connection'
|
2
|
+
require 'livestatus/models'
|
3
|
+
require 'sinatra/base'
|
4
|
+
require 'yajl'
|
5
|
+
|
6
|
+
module Livestatus
|
7
|
+
class API < Sinatra::Base
|
8
|
+
def parse_headers(env)
|
9
|
+
Hash[env.select do |k, v|
|
10
|
+
k =~ /^HTTP_X_LIVESTATUS_/
|
11
|
+
end.map do |k, v|
|
12
|
+
[k[18..-1].downcase.to_sym, v]
|
13
|
+
end]
|
14
|
+
end
|
15
|
+
|
16
|
+
get '/' do
|
17
|
+
headers = parse_headers(request.env)
|
18
|
+
|
19
|
+
halt 400, 'no query specified' unless headers.include?(:query)
|
20
|
+
method, model = headers.delete(:query).split
|
21
|
+
|
22
|
+
halt 400, 'invalid method' unless ['GET', 'COMMAND'].include?(method)
|
23
|
+
method = method.downcase.to_sym
|
24
|
+
|
25
|
+
c = Livestatus::Connection.new(:uri => 'unix:///var/nagios/rw/live')
|
26
|
+
Yajl::Encoder.encode(c.handler.send(method, model, headers))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/livestatus/handler.rb
CHANGED
@@ -1,4 +1,19 @@
|
|
1
|
-
|
1
|
+
module Livestatus
|
2
|
+
|
3
|
+
class HandlerException < StandardError; end
|
4
|
+
|
5
|
+
class BaseHandler
|
6
|
+
def get(table_name, options = {})
|
7
|
+
query(:get, table_name.to_s, options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def command(cmd, time = nil)
|
11
|
+
time = Time.now.to_i unless time
|
12
|
+
query(:command, "[#{time}] #{cmd}")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
2
17
|
|
3
18
|
Dir["#{File.dirname(__FILE__)}/handler/*.rb"].each do |path|
|
4
19
|
require "livestatus/handler/#{File.basename(path, '.rb')}"
|
@@ -1,6 +1,6 @@
|
|
1
|
+
require 'livestatus/handler'
|
1
2
|
require 'patron'
|
2
3
|
require 'yajl'
|
3
|
-
require 'cgi'
|
4
4
|
|
5
5
|
module Livestatus
|
6
6
|
|
@@ -12,31 +12,26 @@ module Livestatus
|
|
12
12
|
@session.timeout = 10
|
13
13
|
@session.headers["User-Agent"] = "livestatus/#{VERSION} ruby/#{RUBY_VERSION}"
|
14
14
|
@session.insecure = config[:insecure]
|
15
|
-
@session.auth_type = config
|
15
|
+
@session.auth_type = config.fetch(:auth_type, :basic).to_sym
|
16
16
|
@session.username = config[:username]
|
17
17
|
@session.password = config[:password]
|
18
18
|
@uri = config[:uri]
|
19
19
|
end
|
20
20
|
|
21
21
|
def query(method, query, headers = {})
|
22
|
-
headers = headers.
|
23
|
-
|
22
|
+
headers = Hash[headers.merge({
|
23
|
+
:query => "#{method.to_s.upcase} #{query}"
|
24
|
+
}).map do |k, v|
|
25
|
+
["X-Livestatus-#{k.to_s.dasherize}", v]
|
26
|
+
end]
|
24
27
|
|
25
|
-
|
26
|
-
result = session.get("#{@uri}?q=#{query}")
|
28
|
+
result = session.get(@uri, headers)
|
27
29
|
|
28
30
|
unless result.status == 200
|
29
31
|
raise HandlerException, "livestatus query failed with status #{result.status}"
|
30
32
|
end
|
31
33
|
|
32
|
-
|
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]
|
34
|
+
Yajl::Parser.parse(result.body)
|
40
35
|
end
|
41
36
|
end
|
42
37
|
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'livestatus/handler'
|
2
|
+
require 'socket'
|
3
|
+
require 'yajl'
|
4
|
+
|
5
|
+
module Livestatus
|
6
|
+
|
7
|
+
class UnixHandler < BaseHandler
|
8
|
+
def initialize(config)
|
9
|
+
@socket = UNIXSocket.open(config[:uri].sub(/^unix:\/\//, ''))
|
10
|
+
end
|
11
|
+
|
12
|
+
def get(table_name, options = {})
|
13
|
+
data = super
|
14
|
+
|
15
|
+
if options.include?(:columns)
|
16
|
+
columns = options[:columns].split(" ")
|
17
|
+
else
|
18
|
+
columns = data.delete_at(0)
|
19
|
+
end
|
20
|
+
|
21
|
+
column_zip(columns, data)
|
22
|
+
end
|
23
|
+
|
24
|
+
def query(method, query, headers = {})
|
25
|
+
headers.merge!({
|
26
|
+
:response_header => "fixed16",
|
27
|
+
:output_format => "json",
|
28
|
+
:keep_alive => "on",
|
29
|
+
})
|
30
|
+
|
31
|
+
headers = headers.map { |k,v| "#{k.to_s.camelize}: #{v}" }.join("\n")
|
32
|
+
headers += "\n" unless headers.empty?
|
33
|
+
|
34
|
+
@socket.write("#{method.to_s.upcase} #{query}\n#{headers}\n")
|
35
|
+
|
36
|
+
res = @socket.read(16)
|
37
|
+
status, length = res[0..2].to_i, res[4..14].chomp.to_i
|
38
|
+
|
39
|
+
unless status == 200
|
40
|
+
raise HandlerException, "livestatus query failed with status #{status}"
|
41
|
+
end
|
42
|
+
|
43
|
+
Yajl::Parser.new.parse(@socket.read(length))
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def column_zip(columns, data)
|
49
|
+
data.map do |d|
|
50
|
+
Hash[columns.zip(d)]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -1,4 +1,9 @@
|
|
1
|
+
require "active_support/core_ext"
|
2
|
+
|
1
3
|
module Livestatus
|
4
|
+
mattr_accessor :models
|
5
|
+
self.models = []
|
6
|
+
|
2
7
|
class Base
|
3
8
|
attr_reader :data
|
4
9
|
|
@@ -82,3 +87,11 @@ module Livestatus
|
|
82
87
|
end
|
83
88
|
end
|
84
89
|
end
|
90
|
+
|
91
|
+
# load all models and register in Livestatus.models
|
92
|
+
Dir["#{File.dirname(__FILE__)}/models/*.rb"].map do |path|
|
93
|
+
File.basename(path, '.rb')
|
94
|
+
end.each do |name|
|
95
|
+
require "livestatus/models/#{name}"
|
96
|
+
Livestatus.models << "Livestatus::#{name.pluralize.classify}".constantize
|
97
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/lib/livestatus/version.rb
CHANGED
data/livestatus.gemspec
CHANGED
@@ -7,9 +7,9 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.version = Livestatus::VERSION
|
8
8
|
s.authors = ["Benedikt Böhm"]
|
9
9
|
s.email = ["bb@xnull.de"]
|
10
|
-
s.homepage = ""
|
11
|
-
s.summary = %q{
|
12
|
-
s.description = %q{
|
10
|
+
s.homepage = "https://github.com/zenops/livestatus"
|
11
|
+
s.summary = %q{Livestatus is a simple Ruby library to control Nagios via MK Livestatus.}
|
12
|
+
s.description = %q{Livestatus is a simple Ruby library to control Nagios via MK Livestatus.}
|
13
13
|
|
14
14
|
s.files = `git ls-files`.split("\n")
|
15
15
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
metadata
CHANGED
@@ -1,116 +1,128 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: livestatus
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.0
|
3
|
+
version: !ruby/object:Gem::Version
|
5
4
|
prerelease:
|
5
|
+
version: 0.2.0
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
8
|
-
- Benedikt
|
7
|
+
authors:
|
8
|
+
- "Benedikt B\xC3\xB6hm"
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
|
13
|
+
date: 2011-11-23 00:00:00 +01:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
15
17
|
name: activesupport
|
16
|
-
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
17
20
|
none: false
|
18
|
-
requirements:
|
19
|
-
- -
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version:
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: "0"
|
22
25
|
type: :runtime
|
23
|
-
|
24
|
-
|
25
|
-
- !ruby/object:Gem::Dependency
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
26
28
|
name: i18n
|
27
|
-
|
29
|
+
prerelease: false
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
28
31
|
none: false
|
29
|
-
requirements:
|
30
|
-
- -
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version:
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: "0"
|
33
36
|
type: :runtime
|
34
|
-
|
35
|
-
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
37
39
|
name: patron
|
38
|
-
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
39
42
|
none: false
|
40
|
-
requirements:
|
41
|
-
- -
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
version:
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
44
47
|
type: :runtime
|
45
|
-
|
46
|
-
|
47
|
-
- !ruby/object:Gem::Dependency
|
48
|
+
version_requirements: *id003
|
49
|
+
- !ruby/object:Gem::Dependency
|
48
50
|
name: yajl-ruby
|
49
|
-
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
50
53
|
none: false
|
51
|
-
requirements:
|
52
|
-
- -
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
55
58
|
type: :runtime
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
email:
|
59
|
+
version_requirements: *id004
|
60
|
+
description: Livestatus is a simple Ruby library to control Nagios via MK Livestatus.
|
61
|
+
email:
|
60
62
|
- bb@xnull.de
|
61
63
|
executables: []
|
64
|
+
|
62
65
|
extensions: []
|
66
|
+
|
63
67
|
extra_rdoc_files: []
|
64
|
-
|
68
|
+
|
69
|
+
files:
|
65
70
|
- .gitignore
|
66
71
|
- .rvmrc
|
67
72
|
- Gemfile
|
68
73
|
- LICENSE
|
69
74
|
- README.rst
|
70
75
|
- Rakefile
|
71
|
-
-
|
72
|
-
-
|
76
|
+
- config.ru
|
77
|
+
- examples/http.rb
|
78
|
+
- examples/simple.rb
|
79
|
+
- examples/unix.rb
|
73
80
|
- lib/livestatus.rb
|
81
|
+
- lib/livestatus/api.rb
|
74
82
|
- lib/livestatus/connection.rb
|
75
83
|
- lib/livestatus/handler.rb
|
76
|
-
- lib/livestatus/handler/base.rb
|
77
84
|
- lib/livestatus/handler/patron.rb
|
78
|
-
- lib/livestatus/
|
79
|
-
- lib/livestatus/
|
80
|
-
- lib/livestatus/
|
81
|
-
- lib/livestatus/
|
82
|
-
- lib/livestatus/
|
83
|
-
- lib/livestatus/
|
84
|
-
- lib/livestatus/
|
85
|
-
- lib/livestatus/
|
86
|
-
- lib/livestatus/
|
87
|
-
- lib/livestatus/
|
88
|
-
- lib/livestatus/
|
89
|
-
- lib/livestatus/
|
85
|
+
- lib/livestatus/handler/unix.rb
|
86
|
+
- lib/livestatus/models.rb
|
87
|
+
- lib/livestatus/models/command.rb
|
88
|
+
- lib/livestatus/models/comment.rb
|
89
|
+
- lib/livestatus/models/contact.rb
|
90
|
+
- lib/livestatus/models/contactgroup.rb
|
91
|
+
- lib/livestatus/models/downtime.rb
|
92
|
+
- lib/livestatus/models/host.rb
|
93
|
+
- lib/livestatus/models/hostgroup.rb
|
94
|
+
- lib/livestatus/models/service.rb
|
95
|
+
- lib/livestatus/models/servicegroup.rb
|
96
|
+
- lib/livestatus/models/timeperiod.rb
|
90
97
|
- lib/livestatus/version.rb
|
91
98
|
- livestatus.gemspec
|
92
|
-
|
99
|
+
has_rdoc: true
|
100
|
+
homepage: https://github.com/zenops/livestatus
|
93
101
|
licenses: []
|
102
|
+
|
94
103
|
post_install_message:
|
95
104
|
rdoc_options: []
|
96
|
-
|
105
|
+
|
106
|
+
require_paths:
|
97
107
|
- lib
|
98
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
108
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
99
109
|
none: false
|
100
|
-
requirements:
|
101
|
-
- -
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version:
|
104
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: "0"
|
114
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
115
|
none: false
|
106
|
-
requirements:
|
107
|
-
- -
|
108
|
-
- !ruby/object:Gem::Version
|
109
|
-
version:
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: "0"
|
110
120
|
requirements: []
|
121
|
+
|
111
122
|
rubyforge_project:
|
112
|
-
rubygems_version: 1.
|
123
|
+
rubygems_version: 1.6.2
|
113
124
|
signing_key:
|
114
125
|
specification_version: 3
|
115
|
-
summary:
|
126
|
+
summary: Livestatus is a simple Ruby library to control Nagios via MK Livestatus.
|
116
127
|
test_files: []
|
128
|
+
|
data/contrib/live.php
DELETED
@@ -1,252 +0,0 @@
|
|
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
|
-
}
|
@@ -1,32 +0,0 @@
|
|
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
|