icinga2 0.5.2 → 0.6.1
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 +63 -38
- data/doc/downtimes.md +4 -3
- data/doc/hostgroups.md +10 -7
- data/doc/hosts.md +19 -7
- data/doc/notifications.md +24 -7
- data/doc/servicegroups.md +11 -8
- data/doc/services.md +29 -6
- data/doc/usergroups.md +8 -4
- data/doc/users.md +12 -11
- data/examples/test.rb +117 -113
- data/lib/icinga2.rb +71 -61
- data/lib/icinga2/converts.rb +68 -53
- data/lib/icinga2/downtimes.rb +73 -90
- data/lib/icinga2/hostgroups.rb +50 -73
- data/lib/icinga2/hosts.rb +133 -170
- data/lib/icinga2/network.rb +182 -117
- data/lib/icinga2/notifications.rb +82 -79
- data/lib/icinga2/servicegroups.rb +50 -71
- data/lib/icinga2/services.rb +144 -162
- data/lib/icinga2/status.rb +32 -32
- data/lib/icinga2/tools.rb +10 -4
- data/lib/icinga2/usergroups.rb +49 -67
- data/lib/icinga2/users.rb +65 -70
- data/lib/icinga2/version.rb +7 -3
- data/lib/logging.rb +10 -6
- metadata +2 -2
data/lib/icinga2/hostgroups.rb
CHANGED
@@ -1,98 +1,75 @@
|
|
1
1
|
|
2
|
+
# frozen_string_literal: false
|
3
|
+
|
2
4
|
module Icinga2
|
3
5
|
|
6
|
+
#
|
7
|
+
#
|
8
|
+
#
|
4
9
|
module Hostgroups
|
5
10
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
11
|
+
#
|
12
|
+
#
|
13
|
+
#
|
14
|
+
def add_hostgroup(params = {})
|
15
|
+
name = params.dig(:name)
|
16
|
+
display_name = params.dig(:display_name)
|
17
|
+
if name.nil?
|
13
18
|
return {
|
14
|
-
:
|
15
|
-
:
|
19
|
+
status: 404,
|
20
|
+
message: 'no name for the hostgroup'
|
16
21
|
}
|
17
22
|
end
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
}
|
24
|
-
|
25
|
-
result = Network.put( {
|
26
|
-
:url => sprintf( '%s/v1/objects/hostgroups/%s', @icingaApiUrlBase, name ),
|
27
|
-
:headers => @headers,
|
28
|
-
:options => @options,
|
29
|
-
:payload => payload
|
30
|
-
} )
|
31
|
-
|
32
|
-
return JSON.pretty_generate( result )
|
33
|
-
|
23
|
+
result = Network.put(url: format('%s/v1/objects/hostgroups/%s', @icinga_api_url_base, name),
|
24
|
+
headers: @headers,
|
25
|
+
options: @options,
|
26
|
+
payload: { 'attrs' => { 'display_name' => display_name } })
|
27
|
+
JSON.pretty_generate(result)
|
34
28
|
end
|
35
29
|
|
36
|
-
|
37
|
-
|
38
|
-
|
30
|
+
#
|
31
|
+
#
|
32
|
+
#
|
33
|
+
def delete_hostgroup(params = {})
|
39
34
|
name = params.dig(:name)
|
40
|
-
|
41
|
-
if( name == nil )
|
42
|
-
|
35
|
+
if name.nil?
|
43
36
|
return {
|
44
|
-
:
|
45
|
-
:
|
37
|
+
status: 404,
|
38
|
+
message: 'no name for the hostgroup'
|
46
39
|
}
|
47
40
|
end
|
48
|
-
|
49
|
-
|
50
|
-
:
|
51
|
-
:
|
52
|
-
|
53
|
-
:options => @options
|
54
|
-
} )
|
55
|
-
|
56
|
-
return JSON.pretty_generate( result )
|
57
|
-
|
41
|
+
result = Network.delete(host: name,
|
42
|
+
url: format('%s/v1/objects/hostgroups/%s?cascade=1', @icinga_api_url_base, name),
|
43
|
+
headers: @headers,
|
44
|
+
options: @options)
|
45
|
+
JSON.pretty_generate(result)
|
58
46
|
end
|
59
47
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
result = Network.get(
|
66
|
-
:
|
67
|
-
:
|
68
|
-
:
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
return JSON.pretty_generate( result )
|
73
|
-
|
48
|
+
#
|
49
|
+
#
|
50
|
+
#
|
51
|
+
def hostgroups(params = {})
|
52
|
+
name = params.dig(:name) || ''
|
53
|
+
result = Network.get(host: name,
|
54
|
+
url: format('%s/v1/objects/hostgroups/%s', @icinga_api_url_base, name),
|
55
|
+
headers: @headers,
|
56
|
+
options: @options)
|
57
|
+
result = JSON.pretty_generate(result) unless result.nil?
|
58
|
+
result
|
74
59
|
end
|
75
60
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
result = JSON.parse( result )
|
83
|
-
end
|
84
|
-
|
61
|
+
#
|
62
|
+
#
|
63
|
+
#
|
64
|
+
def exists_hostgroup?(name)
|
65
|
+
result = hostgroups(name: name)
|
66
|
+
result = JSON.parse(result) if result.is_a?(String)
|
85
67
|
status = result.dig('status')
|
86
68
|
|
87
|
-
if
|
88
|
-
return true
|
89
|
-
end
|
90
|
-
|
91
|
-
return false
|
69
|
+
return true if !status.nil? && status == 200
|
92
70
|
|
71
|
+
false
|
93
72
|
end
|
94
73
|
|
95
|
-
|
96
74
|
end
|
97
|
-
|
98
75
|
end
|
data/lib/icinga2/hosts.rb
CHANGED
@@ -1,191 +1,178 @@
|
|
1
1
|
|
2
|
+
# frozen_string_literal: true
|
2
3
|
module Icinga2
|
3
4
|
|
5
|
+
#
|
6
|
+
#
|
7
|
+
#
|
4
8
|
module Hosts
|
5
9
|
|
6
|
-
|
10
|
+
#
|
11
|
+
#
|
12
|
+
#
|
13
|
+
def add_host( params = {} )
|
7
14
|
|
8
15
|
name = params.dig(:name)
|
9
16
|
fqdn = params.dig(:fqdn)
|
10
|
-
|
17
|
+
display_name = params.dig(:display_name) || name
|
11
18
|
notifications = params.dig(:enable_notifications) || false
|
12
|
-
|
13
|
-
|
14
|
-
|
19
|
+
max_check_attempts = params.dig(:max_check_attempts) || 3
|
20
|
+
check_interval = params.dig(:check_interval) || 60
|
21
|
+
retry_interval = params.dig(:retry_interval) || 45
|
15
22
|
notes = params.dig(:notes)
|
16
|
-
|
17
|
-
|
23
|
+
notes_url = params.dig(:notes_url)
|
24
|
+
action_url = params.dig(:action_url)
|
18
25
|
vars = params.dig(:vars) || {}
|
19
26
|
|
20
|
-
if( name
|
27
|
+
if( name.nil? )
|
21
28
|
|
22
29
|
return {
|
23
|
-
:
|
24
|
-
:
|
30
|
+
status: 404,
|
31
|
+
message: 'missing host name'
|
25
32
|
}
|
26
33
|
end
|
27
34
|
|
28
|
-
if( fqdn
|
35
|
+
if( fqdn.nil? )
|
29
36
|
# build FQDN
|
30
37
|
fqdn = Socket.gethostbyname( name ).first
|
31
38
|
end
|
32
39
|
|
33
40
|
payload = {
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
41
|
+
'templates' => [ 'generic-host' ],
|
42
|
+
'attrs' => {
|
43
|
+
'address' => fqdn,
|
44
|
+
'display_name' => display_name,
|
45
|
+
'max_check_attempts' => max_check_attempts.to_i,
|
46
|
+
'check_interval' => check_interval.to_i,
|
47
|
+
'retry_interval' => retry_interval.to_i,
|
48
|
+
'enable_notifications' => notifications,
|
49
|
+
'action_url' => action_url,
|
50
|
+
'notes' => notes,
|
51
|
+
'notes_url' => notes_url
|
45
52
|
}
|
46
53
|
}
|
47
54
|
|
48
|
-
|
49
|
-
payload['attrs']['vars'] = vars
|
50
|
-
end
|
55
|
+
payload['attrs']['vars'] = vars unless vars.empty?
|
51
56
|
|
52
|
-
if( @
|
53
|
-
payload['attrs']['zone'] = @
|
57
|
+
if( @icinga_cluster == true && !@icinga_satellite.nil? )
|
58
|
+
payload['attrs']['zone'] = @icinga_satellite
|
54
59
|
end
|
55
60
|
|
56
61
|
logger.debug( JSON.pretty_generate( payload ) )
|
57
62
|
|
58
|
-
result = Network.put(
|
59
|
-
:
|
60
|
-
:
|
61
|
-
:
|
62
|
-
:
|
63
|
-
:payload => payload
|
64
|
-
} )
|
63
|
+
result = Network.put( host: name,
|
64
|
+
url: format( '%s/v1/objects/hosts/%s', @icinga_api_url_base, name ),
|
65
|
+
headers: @headers,
|
66
|
+
options: @options,
|
67
|
+
payload: payload )
|
65
68
|
|
66
|
-
|
69
|
+
JSON.pretty_generate( result )
|
67
70
|
|
68
71
|
end
|
69
72
|
|
70
|
-
|
71
|
-
|
73
|
+
#
|
74
|
+
#
|
75
|
+
#
|
76
|
+
def delete_host( params = {} )
|
72
77
|
|
73
78
|
name = params.dig(:name)
|
74
79
|
|
75
|
-
if( name
|
80
|
+
if( name.nil? )
|
76
81
|
|
77
82
|
return {
|
78
|
-
:
|
79
|
-
:
|
83
|
+
status: 404,
|
84
|
+
message: 'missing host name'
|
80
85
|
}
|
81
86
|
end
|
82
87
|
|
83
|
-
result = Network.delete(
|
84
|
-
:
|
85
|
-
:
|
86
|
-
:
|
87
|
-
:options => @options
|
88
|
-
} )
|
88
|
+
result = Network.delete( host: name,
|
89
|
+
url: format( '%s/v1/objects/hosts/%s?cascade=1', @icinga_api_url_base, name ),
|
90
|
+
headers: @headers,
|
91
|
+
options: @options )
|
89
92
|
|
90
|
-
|
93
|
+
JSON.pretty_generate( result )
|
91
94
|
|
92
95
|
end
|
93
96
|
|
94
|
-
|
95
|
-
|
97
|
+
#
|
98
|
+
#
|
99
|
+
#
|
100
|
+
def hosts( params = {} )
|
96
101
|
|
97
102
|
name = params.dig(:name)
|
98
103
|
attrs = params.dig(:attrs)
|
99
104
|
filter = params.dig(:filter)
|
100
105
|
joins = params.dig(:joins)
|
101
106
|
|
102
|
-
|
103
|
-
|
104
|
-
|
107
|
+
payload['attrs'] = attrs unless attrs.nil?
|
108
|
+
payload['filter'] = filter unless filter.nil?
|
109
|
+
payload['joins'] = joins unless joins.nil?
|
105
110
|
|
106
|
-
|
107
|
-
|
108
|
-
|
111
|
+
result = Network.get( host: name,
|
112
|
+
url: format( '%s/v1/objects/hosts/%s', @icinga_api_url_base, name ),
|
113
|
+
headers: @headers,
|
114
|
+
options: @options )
|
109
115
|
|
110
|
-
|
111
|
-
payload['joins'] = joins
|
112
|
-
end
|
113
|
-
|
114
|
-
result = Network.get( {
|
115
|
-
:host => name,
|
116
|
-
:url => sprintf( '%s/v1/objects/hosts/%s', @icingaApiUrlBase, name ),
|
117
|
-
:headers => @headers,
|
118
|
-
:options => @options
|
119
|
-
} )
|
120
|
-
|
121
|
-
return JSON.pretty_generate( result )
|
116
|
+
JSON.pretty_generate( result )
|
122
117
|
|
123
118
|
end
|
124
119
|
|
120
|
+
#
|
121
|
+
#
|
122
|
+
#
|
123
|
+
def exists_host?( name )
|
125
124
|
|
126
|
-
|
125
|
+
result = hosts( name: name )
|
127
126
|
|
128
|
-
result =
|
129
|
-
|
130
|
-
if( result.is_a?( String ) )
|
131
|
-
result = JSON.parse( result )
|
132
|
-
end
|
127
|
+
result = JSON.parse( result ) if result.is_a?( String )
|
133
128
|
|
134
129
|
status = result.dig('status')
|
135
130
|
|
136
|
-
if
|
137
|
-
return true
|
138
|
-
end
|
131
|
+
return true if !status.nil? && status == 200
|
139
132
|
|
140
|
-
|
133
|
+
false
|
141
134
|
|
142
135
|
end
|
143
136
|
|
144
|
-
|
145
|
-
|
137
|
+
#
|
138
|
+
#
|
139
|
+
#
|
140
|
+
def host_objects( params = {} )
|
146
141
|
|
147
142
|
attrs = params.dig(:attrs)
|
148
143
|
filter = params.dig(:filter)
|
149
144
|
joins = params.dig(:joins)
|
150
145
|
payload = {}
|
151
146
|
|
152
|
-
if( attrs
|
153
|
-
attrs = [
|
147
|
+
if( attrs.nil? )
|
148
|
+
attrs = %w[name state acknowledgement downtime_depth last_check]
|
154
149
|
end
|
155
150
|
|
156
|
-
|
157
|
-
payload['attrs'] = attrs
|
158
|
-
end
|
151
|
+
payload['attrs'] = attrs unless attrs.nil?
|
159
152
|
|
160
|
-
|
161
|
-
payload['filter'] = filter
|
162
|
-
end
|
153
|
+
payload['filter'] = filter unless filter.nil?
|
163
154
|
|
164
|
-
|
165
|
-
payload['joins'] = joins
|
166
|
-
end
|
155
|
+
payload['joins'] = joins unless joins.nil?
|
167
156
|
|
168
|
-
result = Network.get(
|
169
|
-
:
|
170
|
-
:
|
171
|
-
:
|
172
|
-
:
|
173
|
-
:payload => payload
|
174
|
-
} )
|
157
|
+
result = Network.get( host: nil,
|
158
|
+
url: format( '%s/v1/objects/hosts', @icinga_api_url_base ),
|
159
|
+
headers: @headers,
|
160
|
+
options: @options,
|
161
|
+
payload: payload )
|
175
162
|
|
176
|
-
|
163
|
+
JSON.pretty_generate( result )
|
177
164
|
|
178
165
|
end
|
179
166
|
|
167
|
+
#
|
168
|
+
#
|
169
|
+
#
|
170
|
+
def host_problems
|
180
171
|
|
181
|
-
|
182
|
-
|
183
|
-
data = self.hostObjects()
|
172
|
+
data = host_objects
|
184
173
|
problems = 0
|
185
174
|
|
186
|
-
|
187
|
-
data = JSON.parse(data)
|
188
|
-
end
|
175
|
+
data = JSON.parse(data) if data.is_a?(String)
|
189
176
|
|
190
177
|
nodes = data.dig('nodes')
|
191
178
|
|
@@ -194,114 +181,90 @@ module Icinga2
|
|
194
181
|
attrs = n.last.dig('attrs')
|
195
182
|
|
196
183
|
state = attrs.dig('state') || 0
|
197
|
-
|
184
|
+
downtime_depth = attrs.dig('downtime_depth') || 0
|
198
185
|
acknowledgement = attrs.dig('acknowledgement') || 0
|
199
186
|
|
200
|
-
if( state != 0 &&
|
187
|
+
if( state != 0 && downtime_depth.zero? && acknowledgement.zero? )
|
201
188
|
problems += 1
|
202
189
|
end
|
203
190
|
|
204
191
|
end
|
205
192
|
|
206
|
-
|
193
|
+
problems
|
207
194
|
|
208
195
|
end
|
209
196
|
|
197
|
+
#
|
198
|
+
#
|
199
|
+
#
|
200
|
+
def problem_hosts( max_items = 5 )
|
210
201
|
|
211
|
-
|
212
|
-
|
213
|
-
count = 0
|
214
|
-
@hostProblems = {}
|
215
|
-
@hostProblemsSeverity = {}
|
216
|
-
|
217
|
-
hostData = self.hostObjects()
|
202
|
+
@host_problems = {}
|
203
|
+
@host_problems_severity = {}
|
218
204
|
|
219
|
-
|
205
|
+
host_data = host_objects
|
220
206
|
|
221
|
-
|
222
|
-
end
|
207
|
+
host_data = JSON.parse( host_data ) if host_data.is_a?(String)
|
223
208
|
|
224
|
-
# logger.debug(
|
209
|
+
# logger.debug( host_data )
|
225
210
|
|
226
|
-
|
211
|
+
host_data = host_data.dig('nodes')
|
227
212
|
|
228
|
-
|
213
|
+
host_data.each do |_host,v|
|
229
214
|
|
230
215
|
name = v.dig('name')
|
231
216
|
state = v.dig('attrs','state')
|
232
217
|
|
233
|
-
if
|
234
|
-
next
|
235
|
-
end
|
218
|
+
next if state.zero?
|
236
219
|
|
237
|
-
@
|
220
|
+
@host_problems[name] = host_severity(v)
|
238
221
|
end
|
239
222
|
|
240
223
|
# get the count of problems
|
241
224
|
#
|
242
|
-
@
|
243
|
-
|
244
|
-
# @hostProblems.each do |k,v|
|
245
|
-
#
|
246
|
-
# if( count >= max_items )
|
247
|
-
# break
|
248
|
-
# end
|
249
|
-
#
|
250
|
-
# @hostProblemsSeverity[k] = v
|
251
|
-
#
|
252
|
-
# count += 1
|
253
|
-
# end
|
225
|
+
@host_problems.keys[1..max_items].each { |k,_v| @host_problems_severity[k] = @host_problems[k] }
|
254
226
|
|
255
|
-
|
227
|
+
@host_problems_severity
|
256
228
|
|
257
229
|
end
|
258
230
|
|
259
231
|
# stolen from Icinga Web 2
|
260
232
|
# ./modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicestatusQuery.php
|
261
233
|
#
|
262
|
-
def
|
234
|
+
def host_severity( host )
|
263
235
|
|
264
|
-
attrs
|
236
|
+
attrs = host.dig('attrs')
|
237
|
+
state = attrs.dig('state')
|
238
|
+
acknowledgement = attrs.dig('acknowledgement') || 0
|
239
|
+
downtime_depth = attrs.dig('downtime_depth') || 0
|
265
240
|
|
266
241
|
severity = 0
|
267
242
|
|
268
|
-
|
269
|
-
if
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
if (attrs["acknowledgement"] != 0)
|
274
|
-
severity += 2
|
275
|
-
elsif (attrs["downtime_depth"] > 0)
|
276
|
-
severity += 1
|
243
|
+
severity +=
|
244
|
+
if acknowledgement != 0
|
245
|
+
2
|
246
|
+
elsif downtime_depth > 0
|
247
|
+
1
|
277
248
|
else
|
278
|
-
|
279
|
-
end
|
280
|
-
else
|
281
|
-
if (getObjectHasBeenChecked(host))
|
282
|
-
severity += 16
|
283
|
-
elsif (attrs["state"] == 1)
|
284
|
-
severity += 32
|
285
|
-
elsif (attrs["state"] == 2)
|
286
|
-
severity += 64
|
287
|
-
else
|
288
|
-
severity += 256
|
249
|
+
4
|
289
250
|
end
|
290
251
|
|
291
|
-
|
292
|
-
severity += 2
|
293
|
-
elsif (attrs["downtime_depth"] > 0)
|
294
|
-
severity += 1
|
295
|
-
else
|
296
|
-
severity += 4
|
297
|
-
end
|
298
|
-
end
|
252
|
+
severity += 16 if object_has_been_checked?(host)
|
299
253
|
|
300
|
-
|
254
|
+
unless state.zero?
|
301
255
|
|
302
|
-
|
256
|
+
severity +=
|
257
|
+
if state == 1
|
258
|
+
32
|
259
|
+
elsif state == 2
|
260
|
+
64
|
261
|
+
else
|
262
|
+
256
|
263
|
+
end
|
264
|
+
end
|
303
265
|
|
266
|
+
severity
|
267
|
+
end
|
304
268
|
|
305
269
|
end
|
306
|
-
|
307
270
|
end
|