icinga2 0.9.2.8 → 1.0.0
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 +1 -9
- data/doc/downtimes.md +39 -0
- data/lib/icinga2/actions.rb +152 -0
- data/lib/icinga2/client.rb +29 -22
- data/lib/icinga2/configuration_management.rb +312 -0
- data/lib/icinga2/downtimes.rb +72 -4
- data/lib/icinga2/hostgroups.rb +6 -6
- data/lib/icinga2/hosts.rb +23 -23
- data/lib/icinga2/network.rb +115 -10
- data/lib/icinga2/notifications.rb +17 -9
- data/lib/icinga2/servicegroups.rb +5 -5
- data/lib/icinga2/services.rb +32 -30
- data/lib/icinga2/statistics.rb +17 -14
- data/lib/icinga2/tools.rb +31 -10
- data/lib/icinga2/usergroups.rb +5 -5
- data/lib/icinga2/users.rb +5 -5
- data/lib/icinga2/validator.rb +40 -34
- data/lib/icinga2/version.rb +1 -3
- data/lib/monkey_patches.rb +67 -14
- data/spec/icinga2_spec.rb +1013 -0
- data/spec/spec_helper.rb +13 -0
- metadata +9 -22
- data/doc/Array.html +0 -200
- data/doc/Boolean.html +0 -122
- data/doc/FalseClass.html +0 -132
- data/doc/Hash.html +0 -332
- data/doc/Icinga2.html +0 -247
- data/doc/Logging.html +0 -328
- data/doc/Object.html +0 -286
- data/doc/Time.html +0 -200
- data/doc/TrueClass.html +0 -132
- data/doc/_index.html +0 -352
- data/doc/class_list.html +0 -51
- data/doc/examples +0 -122
- data/doc/file.README.html +0 -349
- data/doc/file_list.html +0 -56
- data/doc/frames.html +0 -17
- data/doc/index.html +0 -349
- data/doc/method_list.html +0 -755
- data/doc/top-level-namespace.html +0 -112
data/lib/icinga2/downtimes.rb
CHANGED
@@ -22,7 +22,7 @@ module Icinga2
|
|
22
22
|
# @option params [String] config_owner
|
23
23
|
# @option params [Integer] duration Duration of the downtime in seconds if fixed is set to false. (Required for flexible downtimes.)
|
24
24
|
# @option params [Integer] entry_time
|
25
|
-
# @option params [
|
25
|
+
# @option params [Bool] fixed (true) Defaults to true. If true, the downtime is fixed otherwise flexible. See downtimes for more information.
|
26
26
|
# @option params [String] scheduled_by
|
27
27
|
# @option params [String] service_name
|
28
28
|
# @option params [String] triggered_by Sets the trigger for a triggered downtime. See downtimes for more information on triggered downtimes.
|
@@ -37,7 +37,7 @@ module Icinga2
|
|
37
37
|
# start_time: Time.now.to_i,
|
38
38
|
# end_time: Time.now.to_i + 20
|
39
39
|
# }
|
40
|
-
#
|
40
|
+
# add_downtime(param)
|
41
41
|
#
|
42
42
|
# @return [Hash]
|
43
43
|
#
|
@@ -65,7 +65,7 @@ module Icinga2
|
|
65
65
|
|
66
66
|
# sanitychecks
|
67
67
|
#
|
68
|
-
raise ArgumentError.new(format('wrong downtype type. only \'host\'
|
68
|
+
raise ArgumentError.new(format('wrong downtype type. only \'host\' or \'service\' allowed, given \%s\'', type)) if( %w[host service].include?(type.downcase) == false )
|
69
69
|
raise ArgumentError.new('choose \'host_name\' or \'host_group\', not both') unless( host_group.nil? || host_name.nil? )
|
70
70
|
raise ArgumentError.new(format('these \'author\' are not exists: \'%s\'', author)) unless( exists_user?( author ) )
|
71
71
|
raise ArgumentError.new('Missing downtime \'end_time\'') if( end_time.nil? )
|
@@ -113,10 +113,78 @@ module Icinga2
|
|
113
113
|
)
|
114
114
|
end
|
115
115
|
|
116
|
+
# remove downtime
|
117
|
+
#
|
118
|
+
# @param [Hash] params
|
119
|
+
# @option params [String] host_name
|
120
|
+
# @option params [String] host_group
|
121
|
+
# @option params [String] author Name of the author. (required)
|
122
|
+
# @option params [String] comment Comment text. (required)
|
123
|
+
# @option params [String] service_name
|
124
|
+
# @option params [String] filter
|
125
|
+
# @option params [Hash] filter_vars
|
126
|
+
#
|
127
|
+
#
|
128
|
+
# @example
|
129
|
+
# param = {
|
130
|
+
# comment: 'test downtime',
|
131
|
+
# author: 'icingaadmin'
|
132
|
+
# }
|
133
|
+
# remove_downtime(param)
|
134
|
+
#
|
135
|
+
# param = {
|
136
|
+
# filter: '"host.name == filterHost && !service && downtime.author == filterAuthor"',
|
137
|
+
# filter_vars: { filterHost: 'c1-mysql-1', filterAuthor: 'icingaadmin' }
|
138
|
+
# )
|
139
|
+
# remove_downtime(param)
|
140
|
+
#
|
141
|
+
# param = {
|
142
|
+
# host_name: 'c1-mysql-1',
|
143
|
+
# service_name: 'ping4'
|
144
|
+
# }
|
145
|
+
# remove_downtime(param)
|
146
|
+
#
|
147
|
+
# @return [Hash]
|
148
|
+
#
|
149
|
+
def remove_downtime( params )
|
150
|
+
|
151
|
+
raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
|
152
|
+
raise ArgumentError.new('missing \'params\'') if( params.size.zero? )
|
153
|
+
|
154
|
+
host_name = validate( params, required: false, var: 'host_name', type: String )
|
155
|
+
host_group = validate( params, required: false, var: 'host_group', type: String )
|
156
|
+
author = validate( params, required: false, var: 'author', type: String )
|
157
|
+
comment = validate( params, required: false, var: 'comment', type: String )
|
158
|
+
service_name = validate( params, required: false, var: 'service_name', type: String )
|
159
|
+
filter = validate( params, required: false, var: 'filter', type: String )
|
160
|
+
filter_vars = validate( params, required: false, var: 'filter_vars', type: Hash )
|
161
|
+
|
162
|
+
payload = {
|
163
|
+
type: 'Downtime',
|
164
|
+
host_name: host_name,
|
165
|
+
service_name: service_name,
|
166
|
+
host_group: host_group,
|
167
|
+
comment: comment,
|
168
|
+
author: author,
|
169
|
+
filter: filter,
|
170
|
+
filter_vars: filter_vars
|
171
|
+
}
|
172
|
+
|
173
|
+
# remove all empty attrs
|
174
|
+
payload.reject!{ |_k, v| v.nil? }
|
175
|
+
|
176
|
+
post(
|
177
|
+
url: format( '%s/actions/remove-downtime', @icinga_api_url_base ),
|
178
|
+
headers: @headers,
|
179
|
+
options: @options,
|
180
|
+
payload: payload
|
181
|
+
)
|
182
|
+
end
|
183
|
+
|
116
184
|
# return downtimes
|
117
185
|
#
|
118
186
|
# @example
|
119
|
-
#
|
187
|
+
# downtimes
|
120
188
|
#
|
121
189
|
# @return [Array]
|
122
190
|
#
|
data/lib/icinga2/hostgroups.rb
CHANGED
@@ -17,7 +17,7 @@ module Icinga2
|
|
17
17
|
# @option params [Hash] vars ({})
|
18
18
|
#
|
19
19
|
# @example
|
20
|
-
#
|
20
|
+
# add_hostgroup(host_group: 'foo', display_name: 'FOO')
|
21
21
|
#
|
22
22
|
# @return [Hash] result
|
23
23
|
#
|
@@ -62,8 +62,8 @@ module Icinga2
|
|
62
62
|
# @option params [Bool] cascade (false) delete hostgroup also when other objects depend on it
|
63
63
|
#
|
64
64
|
# @example
|
65
|
-
#
|
66
|
-
#
|
65
|
+
# delete_hostgroup(name: 'foo')
|
66
|
+
# delete_hostgroup(name: 'foo', cascade: true)
|
67
67
|
#
|
68
68
|
# @return [Hash] result
|
69
69
|
#
|
@@ -91,10 +91,10 @@ module Icinga2
|
|
91
91
|
# @param [String] host_group (nil) optional for a single hostgroup
|
92
92
|
#
|
93
93
|
# @example to get all users
|
94
|
-
#
|
94
|
+
# hostgroups
|
95
95
|
#
|
96
96
|
# @example to get one user
|
97
|
-
#
|
97
|
+
# hostgroups(host_group: 'linux-servers')
|
98
98
|
#
|
99
99
|
# @return [Hash] returns a hash with all hostgroups
|
100
100
|
#
|
@@ -117,7 +117,7 @@ module Icinga2
|
|
117
117
|
# @param [String] host_group the name of the hostgroup
|
118
118
|
#
|
119
119
|
# @example
|
120
|
-
#
|
120
|
+
# exists_hostgroup?('linux-servers')
|
121
121
|
#
|
122
122
|
# @return [Bool] returns true if the hostgroup exists
|
123
123
|
#
|
data/lib/icinga2/hosts.rb
CHANGED
@@ -57,7 +57,7 @@ module Icinga2
|
|
57
57
|
# }
|
58
58
|
# }
|
59
59
|
# }
|
60
|
-
#
|
60
|
+
# add_host(param)
|
61
61
|
#
|
62
62
|
# @return [Hash]
|
63
63
|
#
|
@@ -152,8 +152,8 @@ module Icinga2
|
|
152
152
|
# @option params [Bool] cascade (false) delete host also when other objects depend on it
|
153
153
|
#
|
154
154
|
# @example
|
155
|
-
#
|
156
|
-
#
|
155
|
+
# delete_host(name: 'foo')
|
156
|
+
# delete_host(name: 'foo', cascade: true)
|
157
157
|
#
|
158
158
|
#
|
159
159
|
# @return [Hash] result
|
@@ -244,7 +244,7 @@ module Icinga2
|
|
244
244
|
# }
|
245
245
|
# }
|
246
246
|
#
|
247
|
-
#
|
247
|
+
# add_host(param)
|
248
248
|
#
|
249
249
|
# @return [Hash]
|
250
250
|
#
|
@@ -352,10 +352,10 @@ module Icinga2
|
|
352
352
|
# @option params [Array] joins
|
353
353
|
#
|
354
354
|
# @example to get all hosts
|
355
|
-
#
|
355
|
+
# hosts
|
356
356
|
#
|
357
357
|
# @example to get one host
|
358
|
-
#
|
358
|
+
# hosts( name: 'icinga2')
|
359
359
|
#
|
360
360
|
# @return [Array]
|
361
361
|
#
|
@@ -388,7 +388,7 @@ module Icinga2
|
|
388
388
|
# @param [String] host_name
|
389
389
|
#
|
390
390
|
# @example
|
391
|
-
#
|
391
|
+
# exists_host?('icinga2')
|
392
392
|
#
|
393
393
|
# @return [Bool]
|
394
394
|
#
|
@@ -414,10 +414,10 @@ module Icinga2
|
|
414
414
|
# @option params [Array] joins ([])
|
415
415
|
#
|
416
416
|
# @example with default attrs and joins
|
417
|
-
#
|
417
|
+
# host_objects
|
418
418
|
#
|
419
419
|
# @example
|
420
|
-
#
|
420
|
+
# host_objects(attrs: ['name', 'state'])
|
421
421
|
#
|
422
422
|
# @return [Hash]
|
423
423
|
#
|
@@ -447,9 +447,9 @@ module Icinga2
|
|
447
447
|
all_hosts = data.clone
|
448
448
|
unless( all_hosts.nil? )
|
449
449
|
# global var for count of all hosts
|
450
|
-
@hosts_all
|
450
|
+
@hosts_all = all_hosts.size
|
451
451
|
# global var for count of all host with a problem
|
452
|
-
@hosts_problems
|
452
|
+
@hosts_problems = count_problems(all_hosts)
|
453
453
|
# global var for count of all gost with state HOSTS_DOWN
|
454
454
|
@hosts_problems_down = count_problems(all_hosts, Icinga2::HOSTS_DOWN)
|
455
455
|
@hosts_problems_critical = count_problems(all_hosts, Icinga2::HOSTS_CRITICAL)
|
@@ -464,9 +464,9 @@ module Icinga2
|
|
464
464
|
# OBSOLETE
|
465
465
|
#
|
466
466
|
# @example
|
467
|
-
# handled, down =
|
467
|
+
# handled, down = hosts_adjusted.values
|
468
468
|
#
|
469
|
-
# h =
|
469
|
+
# h = hosts_adjusted
|
470
470
|
# down = h.dig(:down_adjusted)
|
471
471
|
#
|
472
472
|
# @return [Hash]
|
@@ -500,7 +500,7 @@ module Icinga2
|
|
500
500
|
# return count of hosts with problems
|
501
501
|
#
|
502
502
|
# @example
|
503
|
-
#
|
503
|
+
# count_hosts_with_problems
|
504
504
|
#
|
505
505
|
# @return [Integer]
|
506
506
|
#
|
@@ -519,7 +519,7 @@ module Icinga2
|
|
519
519
|
# @param [Integer] max_items numbers of list entries
|
520
520
|
#
|
521
521
|
# @example
|
522
|
-
#
|
522
|
+
# list_hosts_with_problems
|
523
523
|
#
|
524
524
|
# @return [Hash]
|
525
525
|
#
|
@@ -554,7 +554,7 @@ module Icinga2
|
|
554
554
|
# returns a counter of all hosts
|
555
555
|
#
|
556
556
|
# @example
|
557
|
-
#
|
557
|
+
# hosts_all
|
558
558
|
#
|
559
559
|
# @return [Integer]
|
560
560
|
#
|
@@ -566,10 +566,10 @@ module Icinga2
|
|
566
566
|
# returns data with host problems
|
567
567
|
#
|
568
568
|
# @example
|
569
|
-
#
|
570
|
-
# all, down, critical, unknown, handled, adjusted =
|
569
|
+
# host_objects
|
570
|
+
# all, down, critical, unknown, handled, adjusted = host_problems.values
|
571
571
|
#
|
572
|
-
# p =
|
572
|
+
# p = host_problems
|
573
573
|
# down = h.dig(:down)
|
574
574
|
#
|
575
575
|
# @return [Hash]
|
@@ -583,10 +583,10 @@ module Icinga2
|
|
583
583
|
cib_data if((Time.now.to_i - @last_cib_data_called).to_i > @last_call_timeout)
|
584
584
|
host_objects if((Time.now.to_i - @last_host_objects_called).to_i > @last_call_timeout)
|
585
585
|
|
586
|
-
raise ArgumentError.new(format('wrong type. \'@hosts_problems_down\' must be an Integer, given \'%s\'', @hosts_problems_down.class.to_s)) unless( @hosts_problems_down.is_a?(Integer)
|
587
|
-
raise ArgumentError.new(format('wrong type. \'@hosts_problems_critical\' must be an Integer, given \'%s\'', @hosts_problems_critical.class.to_s)) unless( @hosts_problems_critical.is_a?(Integer)
|
588
|
-
raise ArgumentError.new(format('wrong type. \'@hosts_problems_critical\' must be an Integer, given \'%s\'', @hosts_problems_critical.class.to_s)) unless( @hosts_problems_critical.is_a?(Integer)
|
589
|
-
raise ArgumentError.new(format('wrong type. \'@hosts_down\' must be an Integer, given \'%s\'', @hosts_down.class.to_s)) unless( @hosts_down.is_a?(Integer)
|
586
|
+
raise ArgumentError.new(format('wrong type. \'@hosts_problems_down\' must be an Integer, given \'%s\'', @hosts_problems_down.class.to_s)) unless( @hosts_problems_down.is_a?(Integer))
|
587
|
+
raise ArgumentError.new(format('wrong type. \'@hosts_problems_critical\' must be an Integer, given \'%s\'', @hosts_problems_critical.class.to_s)) unless( @hosts_problems_critical.is_a?(Integer))
|
588
|
+
raise ArgumentError.new(format('wrong type. \'@hosts_problems_critical\' must be an Integer, given \'%s\'', @hosts_problems_critical.class.to_s)) unless( @hosts_problems_critical.is_a?(Integer))
|
589
|
+
raise ArgumentError.new(format('wrong type. \'@hosts_down\' must be an Integer, given \'%s\'', @hosts_down.class.to_s)) unless( @hosts_down.is_a?(Integer))
|
590
590
|
|
591
591
|
problems_all = @hosts_problems.nil? ? 0 : @hosts_problems
|
592
592
|
problems_down = @hosts_problems_down.nil? ? 0 : @hosts_problems_down
|
data/lib/icinga2/network.rb
CHANGED
@@ -111,16 +111,34 @@ module Icinga2
|
|
111
111
|
|
112
112
|
begin
|
113
113
|
data = request( rest_client, 'POST', headers, payload )
|
114
|
-
|
115
114
|
data = JSON.parse( data ) if( data.is_a?(String) )
|
116
115
|
data = data.deep_string_keys
|
117
|
-
data = data.dig('results')
|
116
|
+
data = data.dig('results') if( data.is_a?(Hash) )
|
118
117
|
|
119
|
-
|
118
|
+
if( data.count.zero? )
|
119
|
+
code = 404
|
120
|
+
name = nil
|
121
|
+
status = 'Object not found.'
|
122
|
+
elsif( data.count == 1 )
|
123
|
+
data = data.first
|
124
|
+
code = data.dig('code').to_i
|
125
|
+
name = data.dig('name')
|
126
|
+
status = data.dig('status')
|
127
|
+
else
|
128
|
+
code = data.max_by{|k| k['code'] }.dig('code')
|
129
|
+
status = data.map do |hash|
|
130
|
+
hash['status']
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
return { 'code' => code, 'name' => name, 'status' => status }
|
120
135
|
rescue => e
|
121
136
|
logger.error(e)
|
122
137
|
logger.error(e.backtrace.join("\n"))
|
123
138
|
|
139
|
+
puts e
|
140
|
+
puts e.backtrace.join("\n")
|
141
|
+
|
124
142
|
return nil
|
125
143
|
end
|
126
144
|
end
|
@@ -217,13 +235,56 @@ module Icinga2
|
|
217
235
|
end
|
218
236
|
end
|
219
237
|
|
238
|
+
# static function for GET Requests
|
239
|
+
#
|
240
|
+
# @param [Hash] params
|
241
|
+
# @option params [String] url
|
242
|
+
# @option params [String] headers
|
243
|
+
# @option params [String] options
|
244
|
+
#
|
245
|
+
#
|
246
|
+
# @return [Hash]
|
247
|
+
#
|
248
|
+
def get(params)
|
249
|
+
|
250
|
+
raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
|
251
|
+
raise ArgumentError.new('missing params') if( params.size.zero? )
|
252
|
+
|
253
|
+
url = validate( params, required: true, var: 'url', type: String )
|
254
|
+
headers = validate( params, required: true, var: 'headers', type: Hash )
|
255
|
+
options = validate( params, required: true, var: 'options', type: Hash ).deep_symbolize_keys
|
256
|
+
|
257
|
+
rest_client = RestClient::Resource.new( URI.encode( url ), options )
|
258
|
+
|
259
|
+
begin
|
260
|
+
data = request( rest_client, 'GET', headers )
|
261
|
+
|
262
|
+
# puts "data: #{data}"
|
263
|
+
|
264
|
+
begin
|
265
|
+
data = JSON.parse( data ) if( data.is_a?(String) )
|
266
|
+
data = data.deep_string_keys
|
267
|
+
data['code'] = 200
|
268
|
+
rescue
|
269
|
+
data
|
270
|
+
end
|
271
|
+
|
272
|
+
return data
|
273
|
+
rescue => e
|
274
|
+
logger.error(e)
|
275
|
+
logger.error(e.backtrace.join("\n"))
|
276
|
+
|
277
|
+
return nil
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
220
281
|
private
|
221
282
|
#
|
222
283
|
# internal functionfor the Rest-Client Request
|
223
284
|
#
|
224
285
|
def request( client, method, headers, data = {} )
|
225
286
|
|
226
|
-
# logger.debug( "request( #{client.to_s}, #{method}, #{headers}, #{
|
287
|
+
# logger.debug( "request( #{client.to_s}, #{method}, #{headers}, #{data} )" )
|
227
288
|
|
228
289
|
raise ArgumentError.new('client must be an RestClient::Resource') unless( client.is_a?(RestClient::Resource) )
|
229
290
|
raise ArgumentError.new('method must be an \'GET\', \'POST\', \'PUT\' or \'DELETE\'') unless( %w[GET POST PUT DELETE].include?(method) )
|
@@ -270,10 +331,13 @@ module Icinga2
|
|
270
331
|
end
|
271
332
|
|
272
333
|
response_body = response.body
|
273
|
-
response_headers = response.headers
|
274
|
-
response_body = JSON.parse( response_body )
|
334
|
+
# response_headers = response.headers
|
275
335
|
|
276
|
-
|
336
|
+
begin
|
337
|
+
return JSON.parse( response_body ) if( response_body.is_a?(String) )
|
338
|
+
rescue
|
339
|
+
return response_body
|
340
|
+
end
|
277
341
|
|
278
342
|
rescue RestClient::BadRequest
|
279
343
|
|
@@ -289,10 +353,25 @@ module Icinga2
|
|
289
353
|
|
290
354
|
return { 'results' => [{ 'code' => 404, 'status' => 'Object not Found' }] }
|
291
355
|
|
292
|
-
rescue RestClient::InternalServerError
|
356
|
+
rescue RestClient::InternalServerError => error
|
293
357
|
|
294
358
|
response_body = JSON.parse(@response_body) if @response_body.is_a?(String)
|
295
359
|
|
360
|
+
# begin
|
361
|
+
# puts '-------------------------------------'
|
362
|
+
# puts response
|
363
|
+
# puts response.class.to_s
|
364
|
+
#
|
365
|
+
# puts response.code.to_i
|
366
|
+
# puts response_body
|
367
|
+
# puts response_body.class.to_s
|
368
|
+
# puts '-------------------------------------'
|
369
|
+
# rescue
|
370
|
+
#
|
371
|
+
# end
|
372
|
+
|
373
|
+
return { 'results' => [{ 'code' => 500, 'status' => error }] } if( response_body.nil? )
|
374
|
+
|
296
375
|
results = response_body.dig('results')
|
297
376
|
results = results.first if( results.is_a?(Array) )
|
298
377
|
status = results.dig('status')
|
@@ -313,12 +392,38 @@ module Icinga2
|
|
313
392
|
sleep(3)
|
314
393
|
retry
|
315
394
|
|
395
|
+
rescue RestClient::ExceptionWithResponse => e
|
396
|
+
|
397
|
+
response = e.response
|
398
|
+
response_body = response.body
|
399
|
+
# response_code = response.code
|
400
|
+
|
401
|
+
if( response_body =~ /{(.*)}{(.*)}/ )
|
402
|
+
parts = response_body.match( /^{(?<regular>(.+))}{(.*)}/ )
|
403
|
+
response_body = parts['regular'].to_s.strip
|
404
|
+
response_body = format('{%s}', response_body )
|
405
|
+
end
|
406
|
+
|
407
|
+
begin
|
408
|
+
response_body = JSON.parse(response_body) if response_body.is_a?(String)
|
409
|
+
code = response.code.to_i
|
410
|
+
status = response_body.dig('status')
|
411
|
+
|
412
|
+
return { 'results' => [{ 'code' => code, 'status' => status }] }
|
413
|
+
|
414
|
+
rescue => error
|
415
|
+
puts(error)
|
416
|
+
puts(error.backtrace.join("\n"))
|
417
|
+
|
418
|
+
return { 'results' => [{ 'code' => 500, 'status' => error }] }
|
419
|
+
end
|
420
|
+
|
316
421
|
rescue RestClient::ExceptionWithResponse => e
|
317
422
|
|
318
423
|
@logger.error( "Error: #{__method__} #{method_type.upcase} on #{endpoint} error: '#{e}'" )
|
319
424
|
@logger.error( data )
|
320
|
-
|
321
|
-
|
425
|
+
# @logger.error( @headers )
|
426
|
+
# @logger.error( JSON.pretty_generate( response_headers ) )
|
322
427
|
|
323
428
|
return { 'results' => [{ 'code' => 500, 'status' => e }] }
|
324
429
|
end
|