Module: Icinga2::Hosts

Included in:
Client
Defined in:
lib/icinga2/hosts.rb

Overview

namespace for host handling

Instance Method Summary collapse

Instance Method Details

#add_host(params) ⇒ Hash

add host

Examples:

param = {
  name: 'foo',
  address: 'foo.bar.com',
  display_name: 'test node',
  max_check_attempts: 5,
  notes: 'test node',
  vars: {
    description: 'host foo',
    os: 'Linux',
    partitions: {
      '/' => {
        crit: '95%',
        warn: '90%'
      }
    }
  }
}

@icinga.add_host(param)

Parameters:

Options Hash (params):

  • :name (String)
  • :address (String)
  • :display_name (String)
  • :enable_notifications (Bool) — default: false
  • :max_check_attempts (Integer) — default: 3
  • :check_interval (Integer) — default: 60
  • :retry_interval (Integer) — default: 45
  • :notes (String)
  • :notes_url (String)
  • :action_url (String)
  • :vars (Hash) — default: {}

Returns:

Raises:

  • (ArgumentError)


46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/icinga2/hosts.rb', line 46

def add_host( params )

  raise ArgumentError.new(format('wrong type. \'params\' must be an Hash, given \'%s\'', params.class.to_s)) unless( params.is_a?(Hash) )
  raise ArgumentError.new('missing params') if( params.size.zero? )

  action_url = params.dig(:action_url)
  address = params.dig(:address)
  address6 = params.dig(:address6)
  check_command = params.dig(:check_command)
  check_interval = params.dig(:check_interval)
  check_period = params.dig(:check_period)
  check_timeout = params.dig(:check_timeout)
  command_endpoint = params.dig(:command_endpoint)
  display_name = params.dig(:display_name)
  enable_active_checks = params.dig(:enable_active_checks)
  enable_event_handler = params.dig(:enable_event_handler)
  enable_flapping = params.dig(:enable_flapping) || false
  enable_notifications = params.dig(:enable_notifications)
  enable_passive_checks = params.dig(:enable_passive_checks)
  enable_perfdata = params.dig(:enable_perfdata)
  event_command = params.dig(:event_command)
  flapping_threshold = params.dig(:flapping_threshold)
  groups = params.dig(:groups)
  icon_image = params.dig(:icon_image)
  icon_image_alt = params.dig(:icon_image_alt)
  max_check_attempts = params.dig(:max_check_attempts)
  name = params.dig(:name)
  notes = params.dig(:notes)
  notes_url = params.dig(:notes_url)
  retry_interval = params.dig(:retry_interval)
  templates = params.dig(:templates) || [ 'generic-host' ]
  vars = params.dig(:vars) || {}
  volatile = params.dig(:volatile)
  zone = params.dig(:zone)

  raise ArgumentError.new('missing name') if( name.nil? )

  %w[action_url
     address
     address6
     check_command
     check_period
     command_endpoint
     display_name
     event_command
     icon_image
     icon_image_alt
     name
     notes
     notes_url
     zone].each do |attr|
      v = eval(attr)
      raise ArgumentError.new(format('wrong type. \'%s\' must be an String, given \'%s\'', attr, v.class.to_s)) unless( v.is_a?(String) || v.nil? )
  end

  %w[check_interval
     flapping_threshold
     max_check_attempts
     retry_interval].each do |attr|
      v = eval(attr)
      raise ArgumentError.new(format('wrong type. \'%s\' must be an Integer, given \'%s\'', attr, v.class.to_s)) unless( v.is_a?(Integer) || v.nil? )
  end

  %w[enable_active_checks
     enable_event_handler
     enable_flapping
     enable_notifications
     enable_passive_checks
     enable_perfdata
     volatile].each do |attr|
      v = eval(attr)
      raise ArgumentError.new(format('wrong type. \'%s\' must be True or False, given \'%s\'', attr, v.class.to_s)) unless( v.is_a?(TrueClass) || v.is_a?(FalseClass) || v.nil? )
  end

  %w[groups templates].each do |attr|
      v = eval(attr)
      raise ArgumentError.new(format('wrong type. \'%s\' must be an Array, given \'%s\'', attr, v.class.to_s)) unless( v.is_a?(Array) || v.nil? )
  end

  raise ArgumentError.new(format('wrong type. \'vars\' must be an Hash, given \'%s\'', v.class.to_s)) unless( vars.is_a?(Hash) )

  address = Socket.gethostbyname( name ).first if( address.nil? )

  payload = {
    'templates' => templates,
    'attrs'     => {
      'action_url' => action_url,
      'address' => address,
      'address6' => address6,
      'check_period' => check_period,
      'check_command' => check_command,
      'check_interval' => check_interval,
      'check_timeout' => check_timeout,
      'command_endpoint' => command_endpoint,
      'display_name' => display_name,
      'enable_active_checks' => enable_active_checks,
      'enable_event_handler' => enable_event_handler,
      'enable_flapping' => enable_flapping,
      'enable_notifications' => enable_notifications,
      'enable_passive_checks' => enable_passive_checks,
      'enable_perfdata' => enable_perfdata,
      'event_command' => event_command,
      'flapping_threshold' => flapping_threshold,
      'groups' => groups,
      'icon_image' => icon_image,
      'icon_image_alt' => icon_image_alt,
      'max_check_attempts' => max_check_attempts,
      'notes' => notes,
      'notes_url' => notes_url,
      'retry_interval' => retry_interval,
      'volatile' => volatile,
      'zone' => zone
    }
  }

  payload['attrs']['vars'] = vars unless vars.empty?

  # remove all empty attrs
  payload.reject!{ |_k, v| v.nil? }
  payload['attrs'].reject!{ |_k, v| v.nil? }

#       puts JSON.pretty_generate  payload

  put(
    url: format( '%s/objects/hosts/%s', @icinga_api_url_base, name ),
    headers: @headers,
    options: @options,
    payload: payload
  )
end

#count_hosts_with_problemsInteger

return count of hosts with problems

Examples:

@icinga.count_hosts_with_problems

Returns:

  • (Integer)


492
493
494
495
496
497
498
499
500
# File 'lib/icinga2/hosts.rb', line 492

def count_hosts_with_problems

  host_data = host_objects
  host_data = JSON.parse(host_data) if  host_data.is_a?(String)

  f = host_data.select { |t| t.dig('attrs','state') != 0 && t.dig('attrs','downtime_depth').zero? && t.dig('attrs','acknowledgement').zero? }

  f.size
end

#delete_host(params) ⇒ Hash

delete a host

Examples:

@icinga.delete_host(name: 'foo')

Parameters:

Options Hash (params):

  • :name (String)

    host to delete

Returns:

Raises:

  • (ArgumentError)


187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/icinga2/hosts.rb', line 187

def delete_host( params )

  raise ArgumentError.new('only Hash are allowed') unless( params.is_a?(Hash) )
  raise ArgumentError.new('missing params') if( params.size.zero? )

  host = params.dig(:name)

  raise ArgumentError.new('Missing name') if( host.nil? )

  delete(
    url: format( '%s/objects/hosts/%s?cascade=1', @icinga_api_url_base, host ),
    headers: @headers,
    options: @options
  )
end

#exists_host?(host_name) ⇒ Bool

returns true if the host exists

Examples:

@icinga.exists_host?('icinga2')

Parameters:

  • host_name (String)

Returns:

  • (Bool)

Raises:

  • (ArgumentError)


370
371
372
373
374
375
376
377
378
379
380
381
382
# File 'lib/icinga2/hosts.rb', line 370

def exists_host?( host_name )

  raise ArgumentError.new('only String are allowed') unless( host_name.is_a?(String) )
  raise ArgumentError.new('Missing host_name') if( host_name.size.zero? )

  result = hosts( name: host_name )
  result = JSON.parse( result ) if( result.is_a?(String) )
  result = result.first if( result.is_a?(Array) )

  return false if( result.is_a?(Hash) && result.dig('code') == 404 )

  true
end

#host_objects(params = {}) ⇒ Hash

returns host objects

Examples:

with default attrs and joins

@icinga.host_objects
@icinga.host_objects(attrs: ['name', 'state'])

Parameters:

  • params (Hash) (defaults to: {})

Options Hash (params):

  • :attrs (Array) — default: ['name', 'state', 'acknowledgement', 'downtime_depth', 'last_check']
  • :filter (Array) — default: []
  • :joins (Array) — default: []

Returns:



399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
# File 'lib/icinga2/hosts.rb', line 399

def host_objects( params = {} )

  attrs   = params.dig(:attrs)
  filter  = params.dig(:filter)
  joins   = params.dig(:joins)

#       raise ArgumentError.new('only Array for attrs are allowed') unless( attrs.is_a?(Hash) )
#       raise ArgumentError.new('only Array for filter are allowed') unless( filter.is_a?(Hash) )
#       raise ArgumentError.new('only Array for joins are allowed') unless( joins.is_a?(Hash) )

  payload = {}

  if( attrs.nil? )
    attrs = %w[name state acknowledgement downtime_depth last_check]
  end

  payload['attrs']  = attrs  unless attrs.nil?
  payload['filter'] = filter unless filter.nil?
  payload['joins']  = joins  unless joins.nil?

  data = api_data(
    url: format( '%s/objects/hosts', @icinga_api_url_base ),
    headers: @headers,
    options: @options,
    payload: payload
  )

  @last_host_objects_called = Time.now.to_i

  if( !data.nil? && data.is_a?(Array) )

    all_hosts = data.clone

    unless( all_hosts.nil? )
      # global var for count of all hosts
      @hosts_all           = all_hosts.size
      # global var for count of all host with a problem
      @hosts_problems      = count_problems(all_hosts)
      # global var for count of all gost with state HOSTS_DOWN
      @hosts_problems_down     = count_problems(all_hosts, Icinga2::HOSTS_DOWN)
      @hosts_problems_critical = count_problems(all_hosts, Icinga2::HOSTS_CRITICAL)
      @hosts_problems_unknown  = count_problems(all_hosts, Icinga2::HOSTS_UNKNOWN)

    end
  end

  data
end

#host_problemsHash

returns data with host problems

Examples:

@icinga.host_objects
all, down, critical, unknown, handled, adjusted = @icinga.host_problems.values

p = @icinga.host_problems
down = h.dig(:down)

Returns:

  • (Hash)
    • all

    • down

    • critical

    • unknown

Raises:

  • (ArgumentError)


571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
# File 'lib/icinga2/hosts.rb', line 571

def host_problems

  cib_data if((Time.now.to_i - @last_cib_data_called).to_i > @last_call_timeout)
  host_objects if((Time.now.to_i - @last_host_objects_called).to_i > @last_call_timeout)

  raise ArgumentError.new('Integer for @hosts_problems_down needed') unless( @hosts_problems_down.is_a?(Integer) )
  raise ArgumentError.new('Integer for @hosts_problems_critical needed') unless( @hosts_problems_critical.is_a?(Integer) )
  raise ArgumentError.new('Integer for @hosts_problems_unknown needed') unless( @hosts_problems_unknown.is_a?(Integer) )
  raise ArgumentError.new('Integer for @hosts_down needed') unless( @hosts_down.is_a?(Integer) )

  problems_all      = @hosts_problems.nil?           ? 0 : @hosts_problems
  problems_down     = @hosts_problems_down.nil?      ? 0 : @hosts_problems_down
  problems_critical = @hosts_problems_critical.nil?  ? 0 : @hosts_problems_critical
  problems_unknown  = @hosts_problems_unknown.nil?   ? 0 : @hosts_problems_unknown

  # calculate host problems adjusted by handled problems
  # count togther handled host problems
  problems_handled  = @hosts_problems_down + @hosts_problems_critical + @hosts_problems_unknown
  problems_adjusted = @hosts_down - problems_handled

  {
    all: problems_all.to_i,
    down: problems_down.to_i,
    critical: problems_critical.to_i,
    unknown: problems_unknown.to_i,
    handled: problems_handled.to_i,
    adjusted: problems_adjusted.to_i
  }
end

#hosts(params = {}) ⇒ Array

return hosts

Examples:

to get all hosts

@icinga.hosts

to get one host

@icinga.hosts( name: 'icinga2')

Parameters:

  • params (Hash) (defaults to: {})

Options Hash (params):

  • :name (String)
  • :attrs (String)
  • :filter (String)
  • :joins (String)

Returns:



341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
# File 'lib/icinga2/hosts.rb', line 341

def hosts( params = {} )

  name   = params.dig(:name)
#       attrs  = params.dig(:attrs)
#       filter = params.dig(:filter)
#       joins  = params.dig(:joins)

#       payload = {}
#
#       payload['attrs']  = attrs  unless attrs.nil?
#       payload['filter'] = filter unless filter.nil?
#       payload['joins']  = joins  unless joins.nil?

  api_data(
    url: format( '%s/objects/hosts/%s', @icinga_api_url_base, name ),
    headers: @headers,
    options: @options
  )
end

#hosts_adjustedHash

returns adjusted hosts state OBSOLETE

Examples:

handled, down = @icinga.hosts_adjusted.values

h = @icinga.hosts_adjusted
down = h.dig(:down_adjusted)

Returns:

  • (Hash)
    • handled_problems

    • down_adjusted

Raises:

  • (ArgumentError)


461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
# File 'lib/icinga2/hosts.rb', line 461

def hosts_adjusted

  puts 'function hosts_adjusted() is obsolete'
  puts 'Please use host_problems()'

  cib_data if((Time.now.to_i - @last_cib_data_called).to_i > @last_call_timeout)
  host_objects if((Time.now.to_i - @last_host_objects_called).to_i > @last_call_timeout)

  raise ArgumentError.new('Integer for @hosts_problems_down needed') unless( @hosts_problems_down.is_a?(Integer) )
  raise ArgumentError.new('Integer for @hosts_problems_critical needed') unless( @hosts_problems_critical.is_a?(Integer) )
  raise ArgumentError.new('Integer for @hosts_problems_unknown needed') unless( @hosts_problems_unknown.is_a?(Integer) )
  raise ArgumentError.new('Integer for @hosts_down needed') unless( @hosts_down.is_a?(Integer) )

  # calculate host problems adjusted by handled problems
  # count togther handled host problems
  handled_problems = @hosts_problems_down + @hosts_problems_critical + @hosts_problems_unknown
  down_adjusted    = @hosts_down - handled_problems

  {
    handled_problems: handled_problems.to_i,
    down_adjusted: down_adjusted.to_i
  }
end

#hosts_allInteger

returns a counter of all hosts

Examples:

@icinga.hosts_all

Returns:

  • (Integer)


551
552
553
554
# File 'lib/icinga2/hosts.rb', line 551

def hosts_all
  host_objects if( @hosts_all.nil? || @hosts_all.zero? )
  @hosts_all
end

#list_hosts_with_problems(max_items = 5) ⇒ Hash

return a list of hosts with problems

Examples:

@icinga.list_hosts_with_problems

Parameters:

  • max_items (Integer) (defaults to: 5)

    numbers of list entries

Returns:

Raises:

  • (ArgumentError)


511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
# File 'lib/icinga2/hosts.rb', line 511

def list_hosts_with_problems( max_items = 5 )

  raise ArgumentError.new('only Integer for max_items are allowed') unless( max_items.is_a?(Integer) )

  host_problems = {}
  host_problems_severity = {}

  host_data = host_objects
  host_data = JSON.parse( host_data ) if host_data.is_a?(String)

# logger.debug(host_data)

  unless( host_data.nil? )

    host_data.each do |h,_v|
      name  = h.dig('name')
      state = h.dig('attrs','state')

      next if state.to_i.zero?

      host_problems[name] = host_severity(h)
    end
  end

  # get the count of problems
  #
  if( host_problems.count != 0 )
    host_problems.keys[1..max_items].each { |k| host_problems_severity[k] = host_problems[k] }
  end

  host_problems_severity
end

#modify_host(params) ⇒ Hash

modify a host

Examples:

param = {
  name: 'foo',
  address: 'foo.bar.com',
  display_name: 'Host for an example Problem',
  max_check_attempts: 10,
}

param = {
  name: 'foo',
  address: 'foo.bar.com',
  notes: 'an demonstration object',
  vars: {
    description: 'schould be delete ASAP',
    os: 'Linux',
    partitions: {
      '/' => {
        crit: '98%',
        warn: '95%'
      }
    }
  },
  merge_vars: true
}

param = {
  name: 'foo',
  address: 'foo.bar.com',
  vars: {
    description: 'removed all other custom vars',
  }
}

@icinga.add_host(param)

Parameters:

Options Hash (params):

  • :name (String)
  • :address (String)
  • :display_name (String)
  • :enable_notifications (Bool) — default: false
  • :max_check_attempts (Integer) — default: 3
  • :check_interval (Integer) — default: 60
  • :retry_interval (Integer) — default: 45
  • :notes (String)
  • :notes_url (String)
  • :action_url (String)
  • :vars (Hash) — default: {}
  • :merge_vars (Bool) — default: false

Returns:

Raises:

  • (ArgumentError)


256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
# File 'lib/icinga2/hosts.rb', line 256

def modify_host( params )

  raise ArgumentError.new('only Hash are allowed') unless( params.is_a?(Hash) )
  raise ArgumentError.new('missing params') if( params.size.zero? )

  name               = params.dig(:name)
  address            = params.dig(:address)
  display_name       = params.dig(:display_name) || host
  notifications      = params.dig(:enable_notifications) || false
  max_check_attempts = params.dig(:max_check_attempts) || 3
  check_interval     = params.dig(:check_interval) || 60
  retry_interval     = params.dig(:retry_interval) || 45
  notes              = params.dig(:notes)
  notes_url          = params.dig(:notes_url)
  action_url         = params.dig(:action_url)
  vars               = params.dig(:vars) || {}
  merge_vars         = params.dig(:merge_vars) || false

  raise ArgumentError.new('Missing host name') if( name.nil? )
  raise ArgumentError.new('only true or false for notifications are allowed') unless( notifications.is_a?(TrueClass) || notifications.is_a?(FalseClass) )
  raise ArgumentError.new('only Integer for max_check_attempts are allowed') unless( max_check_attempts.is_a?(Integer) )
  raise ArgumentError.new('only Integer for check_interval are allowed') unless( check_interval.is_a?(Integer) )
  raise ArgumentError.new('only Integer for retry_interval are allowed') unless( retry_interval.is_a?(Integer) )
  raise ArgumentError.new('only String for notes are allowed') unless( notes.is_a?(String) || notes.nil? )
  raise ArgumentError.new('only String for notes_url are allowed') unless( notes_url.is_a?(String) || notes_url.nil? )
  raise ArgumentError.new('only Hash for vars are allowed') unless( vars.is_a?(Hash) )
  raise ArgumentError.new('wrong type. merge_vars must be an Boolean') unless( merge_vars.is_a?(TrueClass) || merge_vars.is_a?(FalseClass) )

  # check if host exists
  exists = exists_host?( name )
  raise ArgumentError.new( format( 'host %s do not exists', name ) ) if( exists == false )

  # merge the new with the old vars
  if( merge_vars == true )
    current_host = hosts( name: name )
    current_host_vars = current_host.first
    current_host_vars = current_host_vars.dig('attrs','vars')
    current_host_vars = current_host_vars.deep_string_keys

    vars = vars.deep_string_keys unless( vars.empty? )
    vars = current_host_vars.merge( vars )
  end

  # POST request
  payload = {
    'attrs'     => {
      'address'              => address,
      'display_name'         => display_name,
      'max_check_attempts'   => max_check_attempts.to_i,
      'check_interval'       => check_interval.to_i,
      'retry_interval'       => retry_interval.to_i,
      'enable_notifications' => notifications,
      'action_url'           => action_url,
      'notes'                => notes,
      'notes_url'            => notes_url
    }
  }

  payload['attrs']['vars'] = vars unless  vars.empty?

  post(
    url: format( '%s/objects/hosts/%s', @icinga_api_url_base, name ),
    headers: @headers,
    options: @options,
    payload: payload
  )
end