icinga_api 0.0.3 → 0.0.4
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.
- 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
|