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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: db65239b18017d516c94d9557964cd7d05deb9fc
4
- data.tar.gz: 83566207d187452e28f7b0fa2a675a71cbd31b70
3
+ metadata.gz: 0153d5f474c808802e38b9c00130ccec7292bdfd
4
+ data.tar.gz: 8a3c89757f2fa0a0edca40427109437aa8b1baa2
5
5
  SHA512:
6
- metadata.gz: c52d9d352a987f591fadc951ddc638608b7d9a4b1888f3b3903c485781b1415b547f1ad193da305673353578f497be4deab472d7a24c0b29d738fc8397973473
7
- data.tar.gz: 0f66f89e8c1254abb2e3d8ea0ae645d6531c6121af820ff0889c6fad8db485bb901eafc0f217a2df7ac0fcbc01ee015a992781f65d006a375d0a21bea58eaca1
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
- ### create connection
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
- ### some sample host API calls
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
- ### some sample service API calls
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
 
@@ -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
@@ -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 = filter("HOST_NAME", "=", name)
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
@@ -2,36 +2,18 @@ class IcingaApi
2
2
  class Request
3
3
  attr_accessor :connection
4
4
 
5
- protected
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] = @connection.data[:authkey]
8
+ data[:authkey] = connection.data[:authkey]
26
9
  data[:target] = target
27
- filters = and_filters(filters, filters) # the hell knows why, but the api always wants an AND- or OR-construct on the top level
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 = @connection.data[: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
- rc = string_request(target, filter, field).to_i
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
- rc = string_request(target, filter, field).to_f
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
- integer_request(target, filter, field) == 1
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
- Time.parse(string_request(target, filter, field))
79
+ self.class.time_request(@connection, target, filter, field)
65
80
  end
66
81
  end # of class Request
67
82
  end
@@ -72,7 +72,7 @@ class IcingaApi
72
72
  @connection = connection
73
73
  @host = host
74
74
  @name = name
75
- @service_filter = and_filters(@host.host_filter, filter("SERVICE_NAME", "=", name))
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: parsen
86
+ # TODO: parsing
87
87
  end
88
88
 
89
89
 
@@ -1,3 +1,3 @@
1
1
  class IcingaApi
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
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.3
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-30 00:00:00.000000000 Z
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