icinga_api 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +36 -12
- data/lib/icinga_api.rb +24 -0
- data/lib/icinga_api/filter.rb +38 -0
- data/lib/icinga_api/host.rb +10 -3
- data/lib/icinga_api/host_group.rb +68 -0
- data/lib/icinga_api/request.rb +43 -28
- data/lib/icinga_api/service.rb +2 -2
- data/lib/icinga_api/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0153d5f474c808802e38b9c00130ccec7292bdfd
|
4
|
+
data.tar.gz: 8a3c89757f2fa0a0edca40427109437aa8b1baa2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9684ab8be64d04cc6588bbabf95f8214a0fee92ba4372faa49376b75ba3e95081d0a32757d3e70f207f0d642fb2af6919aa1656831dc5cadd7bb06a56ef26683
|
7
|
+
data.tar.gz: 8dd51da1d9fc0de0d2f5ee7aaa9fdbc2a2aff7fc11eb0f246764043ca6bc8def942473fbacbbc8faf4282b8be0600f8b36f4e894723cd3fab8db04774f25b586
|
data/README.md
CHANGED
@@ -20,7 +20,9 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
## Usage
|
22
22
|
|
23
|
-
###
|
23
|
+
### simple expamples
|
24
|
+
|
25
|
+
#### create connection
|
24
26
|
```ruby
|
25
27
|
require 'icinga_api'
|
26
28
|
|
@@ -30,24 +32,24 @@ icinga = IcingaApi.new(
|
|
30
32
|
)
|
31
33
|
```
|
32
34
|
|
33
|
-
|
35
|
+
#### host API
|
34
36
|
```ruby
|
35
37
|
host = icinga.host("my-monitored-host")
|
36
38
|
|
37
39
|
# is the host up?
|
38
|
-
host.up?
|
40
|
+
up = host.up?
|
39
41
|
|
40
42
|
# what is the state of the host?
|
41
|
-
host.current_state
|
43
|
+
state = host.current_state
|
42
44
|
|
43
45
|
# when was the last check of the host
|
44
|
-
host.last_check
|
46
|
+
t = host.last_check
|
45
47
|
|
46
48
|
# has the host problem been acknowledged?
|
47
|
-
host.problem_has_been_acknowledged
|
49
|
+
ack = host.problem_has_been_acknowledged
|
48
50
|
|
49
51
|
# get a list of services of the host
|
50
|
-
host.services
|
52
|
+
services = host.services
|
51
53
|
|
52
54
|
# get a specific service by name on a host
|
53
55
|
service = host.service("Time")
|
@@ -55,23 +57,45 @@ service = host.service("Time")
|
|
55
57
|
etc.
|
56
58
|
```
|
57
59
|
|
58
|
-
###
|
60
|
+
### service API
|
59
61
|
```ruby
|
60
62
|
# is the service ok?
|
61
|
-
service.ok?
|
63
|
+
is_ok = service.ok?
|
62
64
|
|
63
65
|
# since when is the service in the current state?
|
64
|
-
service.last_state_change
|
66
|
+
t = service.last_state_change
|
65
67
|
|
66
68
|
# what is the display name of the service?
|
67
|
-
service.display_name
|
69
|
+
str = service.display_name
|
68
70
|
|
69
71
|
# when will the service be checked the next time?
|
70
|
-
service.next_check
|
72
|
+
t = service.next_check
|
71
73
|
|
72
74
|
etc.
|
73
75
|
```
|
74
76
|
|
77
|
+
## more advanced examples
|
78
|
+
|
79
|
+
IcingaApi understands predefined or manual filters, which make it possible to
|
80
|
+
query any parameters
|
81
|
+
|
82
|
+
### host api
|
83
|
+
```ruby
|
84
|
+
# find all hosts which are down
|
85
|
+
hosts = icinga.hosts(IcingaApi::Host::F_DOWN)
|
86
|
+
|
87
|
+
# find all hosts which are down and not acknowledged the easy_way
|
88
|
+
hosts = icinga.hosts_down
|
89
|
+
|
90
|
+
# or with filters:
|
91
|
+
hosts = icinga.hosts(IcingaApi::Host::F_DOWN & IcingaApi::Host::F_NACK)
|
92
|
+
|
93
|
+
# or with manually defined filters:
|
94
|
+
filter_host_down = IcingaApi::Filter.new('HOST_CURRENT_STATE', '=', 1)
|
95
|
+
filter_host_not_ack = IcingaApi::Filter.new('HOST_PROBLEM_HAS_BEEN_ACKNOWLEDGET', '=', 0)
|
96
|
+
hosts = icinga.hosts(filter_host_down & filter_host_not_ack)
|
97
|
+
```
|
98
|
+
|
75
99
|
|
76
100
|
## Contributing
|
77
101
|
|
data/lib/icinga_api.rb
CHANGED
@@ -5,7 +5,9 @@ require 'time'
|
|
5
5
|
require 'ipaddress'
|
6
6
|
|
7
7
|
require "icinga_api/version"
|
8
|
+
require "icinga_api/filter"
|
8
9
|
require "icinga_api/request"
|
10
|
+
require "icinga_api/host_group"
|
9
11
|
require "icinga_api/host"
|
10
12
|
require "icinga_api/service"
|
11
13
|
|
@@ -21,4 +23,26 @@ class IcingaApi
|
|
21
23
|
Host.new(self, name)
|
22
24
|
end
|
23
25
|
|
26
|
+
|
27
|
+
def hosts(filter=nil)
|
28
|
+
rc = Request::request(self, Host::TARGET, filter, [:HOST_NAME])
|
29
|
+
rc[:result].map do |host_hash|
|
30
|
+
Host.new(self, host_hash[:HOST_NAME])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
def hosts_up(filter=nil)
|
36
|
+
hosts(filter ? (Host::F_UP & filter) : Host::F_UP)
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def host_group(name)
|
41
|
+
HostGroup.new(self, name)
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
def host_groups(filter)
|
46
|
+
# TODO
|
47
|
+
end
|
24
48
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class IcingaApi
|
2
|
+
class Filter
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
attr_reader :data
|
6
|
+
|
7
|
+
def initialize(field=nil, operator=nil, value=nil)
|
8
|
+
@multi = false
|
9
|
+
if field.class == Hash
|
10
|
+
# only for internal use
|
11
|
+
@data = field
|
12
|
+
@multi = true
|
13
|
+
else
|
14
|
+
# normal use
|
15
|
+
@data = { type: "atom", field: [ field ], method: [ operator ], value: [ value ] }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
def &(other)
|
21
|
+
other = Marshal.load(Marshal.dump(other))
|
22
|
+
self.class.new ({ type: 'AND', field: [@data, other.data] })
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
def |(other)
|
27
|
+
other = Marshal.load(Marshal.dump(other))
|
28
|
+
self.class.new ({ type: 'OR', field: [@data, other.data] })
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
def to_json
|
33
|
+
# icinga always wants a AND or OR construct, the hell knows why
|
34
|
+
return (self & self).to_json unless @multi
|
35
|
+
@data.to_json
|
36
|
+
end
|
37
|
+
end # of class Filter
|
38
|
+
end # of class IcingaApi
|
data/lib/icinga_api/host.rb
CHANGED
@@ -3,6 +3,14 @@ class IcingaApi
|
|
3
3
|
TARGET="host"
|
4
4
|
attr_reader :name, :host_filter
|
5
5
|
|
6
|
+
# some popular filter definitions
|
7
|
+
F_UP = Filter.new("HOST_CURRENT_STATE", "=", 0)
|
8
|
+
F_DOWN = Filter.new("HOST_CURRENT_STATE", "=", 1)
|
9
|
+
F_ACK = Filter.new("HOST_PROBLEM_HAS_BEEN_ACKNOWLEDGED", "=", 1)
|
10
|
+
F_NACK = Filter.new("HOST_PROBLEM_HAS_BEEN_ACKNOWLEDGED", "=", 0)
|
11
|
+
F_DOWN_ACK = F_DOWN & F_ACK
|
12
|
+
F_DOWN_NACK = F_DOWN & F_NACK
|
13
|
+
|
6
14
|
CHECKS = {
|
7
15
|
integer: %i(
|
8
16
|
HOST_ID
|
@@ -37,8 +45,8 @@ class IcingaApi
|
|
37
45
|
HOST_SHOULD_BE_SCHEDULED
|
38
46
|
HOST_PROCESS_PERFORMANCE_DATA
|
39
47
|
),
|
48
|
+
#HOST_NAME
|
40
49
|
string: %i(
|
41
|
-
HOST_NAME
|
42
50
|
HOST_ALIAS
|
43
51
|
HOST_DISPLAY_NAME
|
44
52
|
HOST_NOTES
|
@@ -75,7 +83,7 @@ class IcingaApi
|
|
75
83
|
def initialize(connection, name)
|
76
84
|
@connection = connection
|
77
85
|
@name = name
|
78
|
-
@host_filter =
|
86
|
+
@host_filter = Filter.new("HOST_NAME", "=", name)
|
79
87
|
end
|
80
88
|
|
81
89
|
|
@@ -124,7 +132,6 @@ class IcingaApi
|
|
124
132
|
|
125
133
|
def services
|
126
134
|
rc = request(Service::TARGET, @host_filter, [:SERVICE_NAME])
|
127
|
-
# TODO: langsam, und keine Ahnung, warum
|
128
135
|
rc[:result].map do |service_hash|
|
129
136
|
Service.new(@connection, self, service_hash[:SERVICE_NAME])
|
130
137
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
class IcingaApi
|
2
|
+
class HostGroup < Request
|
3
|
+
TARGET="hostgroup"
|
4
|
+
attr_reader :name, :host_group_filter
|
5
|
+
|
6
|
+
CHECKS = {
|
7
|
+
integer: %i(
|
8
|
+
HOSTGROUP_ID
|
9
|
+
HOSTGROUP_OBJECT_ID
|
10
|
+
HOSTGROUP_INSTANCE_ID
|
11
|
+
),
|
12
|
+
#float: %i(
|
13
|
+
#),
|
14
|
+
#boolean: %i(
|
15
|
+
#),
|
16
|
+
string: %i(
|
17
|
+
HOSTGROUP_NAME
|
18
|
+
HOSTGROUP_ALIAS
|
19
|
+
),
|
20
|
+
#time: %i(
|
21
|
+
#)
|
22
|
+
}
|
23
|
+
|
24
|
+
CHECKS.each do |check_type, arr|
|
25
|
+
request_name = "#{check_type.to_s}_request"
|
26
|
+
arr.each do |method_symbol|
|
27
|
+
method_name = method_symbol.to_s.gsub(/^\w+?_/, "").downcase
|
28
|
+
define_method(method_name) do
|
29
|
+
send(request_name, TARGET, @host_group_filter, method_symbol)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
def initialize(connection, name)
|
36
|
+
@connection = connection
|
37
|
+
@name = name
|
38
|
+
@host_group_filter = Filter.new("HOSTGROUP_NAME", "=", name)
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
def fetch(method)
|
43
|
+
string_request(TARGET, @host_group_filter, method)
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
def hosts(filter=nil)
|
48
|
+
filter = filter ? (@host_group_filter & filter) : @host_group_filter
|
49
|
+
rc = request(Host::TARGET, filter, [:HOST_NAME])
|
50
|
+
rc[:result].map do |host_hash|
|
51
|
+
Host.new(@connection, host_hash[:HOST_NAME])
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
def hosts_down
|
57
|
+
hosts(Host::F_DOWN)
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
def hosts_up
|
62
|
+
hosts(Host::F_UP)
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
# TODO: implement further
|
67
|
+
end # of class HostGroup
|
68
|
+
end
|
data/lib/icinga_api/request.rb
CHANGED
@@ -2,36 +2,18 @@ class IcingaApi
|
|
2
2
|
class Request
|
3
3
|
attr_accessor :connection
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
def and_filters(a, b)
|
8
|
-
{ type: "AND", field: [a, b] }
|
9
|
-
end
|
10
|
-
|
11
|
-
|
12
|
-
def or_filters(a, b)
|
13
|
-
{ type: "OR", field: [a, b] }
|
14
|
-
end
|
15
|
-
|
16
|
-
|
17
|
-
def filter(field, operator, value)
|
18
|
-
{ type: "atom", field: [ field ], method: [ operator ], value: [ value ] }
|
19
|
-
end
|
20
|
-
|
21
|
-
|
22
|
-
def request(target, filters, columns)
|
5
|
+
def self.request(connection, target, filter, columns)
|
23
6
|
# prepare post data
|
24
7
|
data = Hash.new
|
25
|
-
data[:authkey] =
|
8
|
+
data[:authkey] = connection.data[:authkey]
|
26
9
|
data[:target] = target
|
27
|
-
|
28
|
-
data[:filters_json] = filters.to_json if filters
|
10
|
+
data[:filters_json] = filter.to_json if filter
|
29
11
|
columns.each_with_index do |col, i|
|
30
12
|
data["columns[#{i}]".to_sym] = col
|
31
13
|
end
|
32
14
|
|
33
15
|
# post data
|
34
|
-
url =
|
16
|
+
url = connection.data[:url]
|
35
17
|
uri = URI("#{url}/web/api/authkey=#{data[:authkey]}/json")
|
36
18
|
res = Net::HTTP.post_form(uri, data)
|
37
19
|
raise "error on API query" unless res.code.to_i == 200
|
@@ -39,29 +21,62 @@ class IcingaApi
|
|
39
21
|
end
|
40
22
|
|
41
23
|
|
42
|
-
def string_request(target, filter, field)
|
43
|
-
rc = request(target, filter, [ field ])
|
24
|
+
def self.string_request(connection, target, filter, field)
|
25
|
+
rc = request(connection, target, filter, [ field ])
|
44
26
|
rc[:result][0][field]
|
45
27
|
end
|
46
28
|
|
47
29
|
|
30
|
+
def self.integer_request(connection, target, filter, field)
|
31
|
+
string_request(connection, target, filter, field).to_i
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
def self.float_request(connection, target, filter, field)
|
36
|
+
string_request(connection, target, filter, field).to_f
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def self.boolean_request(connection, target, filter, field)
|
41
|
+
integer_request(connection, target, filter, field) == 1
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
def self.time_request(connection, target, filter, field)
|
46
|
+
Time.parse(string_request(connection, target, filter, field))
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
protected
|
51
|
+
|
52
|
+
|
53
|
+
def request(target, filters, columns)
|
54
|
+
self.class.request(@connection, target, filters, columns)
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
def string_request(target, filter, field)
|
59
|
+
self.class.string_request(@connection, target, filter, field)
|
60
|
+
end
|
61
|
+
|
62
|
+
|
48
63
|
def integer_request(target, filter, field)
|
49
|
-
|
64
|
+
self.class.integer_request(@connection, target, filter, field)
|
50
65
|
end
|
51
66
|
|
52
67
|
|
53
68
|
def float_request(target, filter, field)
|
54
|
-
|
69
|
+
self.class.float_request(@connection, target, filter, field)
|
55
70
|
end
|
56
71
|
|
57
72
|
|
58
73
|
def boolean_request(target, filter, field)
|
59
|
-
|
74
|
+
self.class.boolean_request(@connection, target, filter, field)
|
60
75
|
end
|
61
76
|
|
62
77
|
|
63
78
|
def time_request(target, filter, field)
|
64
|
-
|
79
|
+
self.class.time_request(@connection, target, filter, field)
|
65
80
|
end
|
66
81
|
end # of class Request
|
67
82
|
end
|
data/lib/icinga_api/service.rb
CHANGED
@@ -72,7 +72,7 @@ class IcingaApi
|
|
72
72
|
@connection = connection
|
73
73
|
@host = host
|
74
74
|
@name = name
|
75
|
-
@service_filter =
|
75
|
+
@service_filter = (@host.host_filter & Filter.new("SERVICE_NAME", "=", name))
|
76
76
|
end
|
77
77
|
|
78
78
|
|
@@ -83,7 +83,7 @@ class IcingaApi
|
|
83
83
|
|
84
84
|
def perfdata
|
85
85
|
rc = request(TARGET, @service_filter, [:SERVICE_PERFDATA])
|
86
|
-
# TODO:
|
86
|
+
# TODO: parsing
|
87
87
|
end
|
88
88
|
|
89
89
|
|
data/lib/icinga_api/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: icinga_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lothar Handl
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-07
|
11
|
+
date: 2014-08-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ipaddress
|
@@ -66,7 +66,9 @@ files:
|
|
66
66
|
- Rakefile
|
67
67
|
- icinga_api.gemspec
|
68
68
|
- lib/icinga_api.rb
|
69
|
+
- lib/icinga_api/filter.rb
|
69
70
|
- lib/icinga_api/host.rb
|
71
|
+
- lib/icinga_api/host_group.rb
|
70
72
|
- lib/icinga_api/request.rb
|
71
73
|
- lib/icinga_api/service.rb
|
72
74
|
- lib/icinga_api/version.rb
|