Class: Icinga2::Client

Inherits:
Object show all
Includes:
Converts, Downtimes, Hostgroups, Hosts, Network, Notifications, Servicegroups, Services, Statistics, Tools, Usergroups, Users, Logging
Defined in:
lib/icinga2/client.rb

Overview

Abstract base class for the API calls. Provides some helper methods

Author:

  • Bodo Schulz

Instance Method Summary collapse

Methods included from Usergroups

#add_usergroup, #delete_usergroup, #exists_usergroup?, #usergroups

Methods included from Users

#add_user, #delete_user, #exists_user?, #users

Methods included from Servicegroups

#add_servicegroup, #delete_servicegroup, #exists_servicegroup?, #servicegroups

Methods included from Services

#add_service, #count_services_with_problems, #delete_service, #exists_service?, #list_services_with_problems, #modify_service, #service_objects, #service_problems, #service_problems_handled, #services, #services_adjusted, #services_all, #unhandled_services

Methods included from Hostgroups

#add_hostgroup, #delete_hostgroup, #exists_hostgroup?, #hostgroups

Methods included from Hosts

#add_host, #count_hosts_with_problems, #delete_host, #exists_host?, #host_objects, #host_problems, #hosts, #hosts_adjusted, #hosts_all, #list_hosts_with_problems, #modify_host

Methods included from Notifications

#disable_host_notification, #disable_hostgroup_notification, #disable_service_notification, #enable_host_notification, #enable_hostgroup_notification, #enable_service_notification, #notifications

Methods included from Downtimes

#add_downtime, #downtimes

Methods included from Tools

#count_problems, #object_has_been_checked?, #parse_version

Methods included from Converts

format_service, state_to_color, state_to_string

Methods included from Statistics

#average_statistics, #host_statistics, #interval_statistics, #service_statistics, #work_queue_statistics

Methods included from Network

#api_data, #delete, #icinga_application_data, #post, #put

Methods included from Logging

configure_logger_for, #logger, logger_for

Constructor Details

#initialize(settings) ⇒ instance, #read

Returns a new instance of Client

Examples:

to create an new Instance

config = {
  icinga: {
    host: '192.168.33.5',
    api: {
      port: 5665,
      user: 'root',
      password: 'icinga',
      version: 1
    },
    cluster: false,
    satellite: true
  }
}

@icinga = Icinga2::Client.new(config)

Parameters:

  • settings (Hash, #read)

    the settings for Icinga2

Options Hash (settings):

  • :host (String) — default: 'localhost'

    the Icinga2 Hostname

  • :port (Integer) — default: 5665

    the Icinga2 API Port

  • :user (String)

    the Icinga2 API User

  • :password (String)

    the Icinga2 API Password

  • :version (Integer) — default: 1

    the Icinga2 API Version

  • :cluster (Bool)

    Icinga2 Cluster Mode

  • :notifications (Bool) — default: false

    enable Icinga2 Host Notifications

Raises:

  • (ArgumentError)


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
# File 'lib/icinga2/client.rb', line 91

def initialize( settings )

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

  icinga_host           = settings.dig(:icinga, :host)           || 'localhost'
  icinga_api_port       = settings.dig(:icinga, :api, :port)     || 5665
  icinga_api_user       = settings.dig(:icinga, :api, :user)
  icinga_api_pass       = settings.dig(:icinga, :api, :password)
  icinga_api_version    = settings.dig(:icinga, :api, :version)  || 1
  icinga_api_pki_path   = settings.dig(:icinga, :api, :pki_path)
  icinga_api_node_name  = settings.dig(:icinga, :api, :node_name)
  @icinga_cluster       = settings.dig(:icinga, :cluster)        || false
  @icinga_satellite     = settings.dig(:icinga, :satellite)
  @icinga_notifications = settings.dig(:icinga, :notifications)  || false

  @last_call_timeout    = 320
  @last_cib_data_called = 0
  @last_status_data_called = 0
  @last_application_data_called = 0
  @last_service_objects_called = 0
  @last_host_objects_called = 0

  @icinga_api_url_base  = format( 'https://%s:%d/v%s', icinga_host, icinga_api_port, icinga_api_version )

  _has_cert, @options = cert?(
    pki_path: icinga_api_pki_path,
    node_name: icinga_api_node_name,
    user: icinga_api_user,
    password: icinga_api_pass
  )

  @headers    = { 'Content-Type' => 'application/json', 'Accept' => 'application/json' }

  self
end

Instance Method Details

#api_listenerHash

return Icinga2 API Listener

Examples:

@icinga.api_listener

Returns:



329
330
331
332
333
334
335
336
337
338
# File 'lib/icinga2/client.rb', line 329

def api_listener

  @last_application_data_called = Time.now.to_i

  icinga_application_data(
    url: format( '%s/status/ApiListener', @icinga_api_url_base ),
    headers: @headers,
    options: @options
  )
end

#application_dataHash

return Icinga2 Application data

Examples:

@icinga.application_data

Returns:



209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/icinga2/client.rb', line 209

def application_data

  data = icinga_application_data(
    url: format( '%s/status/IcingaApplication', @icinga_api_url_base ),
    headers: @headers,
    options: @options
  )

  #puts '---'
  #puts data
  #puts data.class.to_s
  #puts '---'

  return nil if( data.nil? )
#      return data if( data.is_a?(Hash) && data.dig('code').to_i != 200 )
#puts '.'

  app_data = data.dig('icingaapplication','app')

  #puts '---'
  #puts app_data
  #puts app_data.class.to_s
  #puts '---'

  # version and revision
  @version, @revision = parse_version(app_data.dig('version'))

  #   - node_name
  @node_name = app_data.dig('node_name')

  #   - start_time
  @start_time = Time.at(app_data.dig('program_start').to_f)

  data
end

#available?Bool

check the availability of a Icinga network connect

Examples:

@icinga.available?

Returns:

  • (Bool)


347
348
349
350
351
352
353
354
# File 'lib/icinga2/client.rb', line 347

def available?

  data = application_data

  return true unless( data.nil? )

  false
end

#cert?(params) ⇒ Bool, #read

create a HTTP Header based on a Icinga2 Certificate or an User API Login

Examples:

with Certificate

@icinga.cert?(pki_path: '/etc/icinga2', node_name: 'icinga2-dashing')

with User

@icinga.cert?(user: 'root', password: 'icinga')

Parameters:

  • params (Hash, #read)

Options Hash (params):

  • :pki_path (String)

    the location of the Certificate Files

  • :node_name (String)

    the Icinga2 Hostname

  • :user (String)

    the Icinga2 API User

  • :password (String)

    the Icinga2 API Password

Returns:

  • (Bool, #read)

Raises:

  • (ArgumentError)


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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/icinga2/client.rb', line 144

def cert?( 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? )

  pki_path     = params.dig(:pki_path)
  node_name    = params.dig(:node_name)
  user         = params.dig(:user)
  password     = params.dig(:password)

  if( node_name.nil? )
    begin
      node_name = Socket.gethostbyname(Socket.gethostname).first
      logger.debug(format('node name: %s', node_name))
    rescue SocketError => e

      raise format("can't resolve hostname (%s)", e)
    end
  end

  ssl_cert_file = format( '%s/%s.crt', pki_path, node_name )
  ssl_key_file  = format( '%s/%s.key', pki_path, node_name )
  ssl_ca_file   = format( '%s/ca.crt', pki_path )

  if( File.file?( ssl_cert_file ) && File.file?( ssl_key_file ) && File.file?( ssl_ca_file ) )

    logger.debug( 'PKI found, using client certificates for connection to Icinga 2 API' )

    ssl_cert_file = File.read( ssl_cert_file )
    ssl_key_file  = File.read( ssl_key_file )
    ssl_ca_file   = File.read( ssl_ca_file )

    cert          = OpenSSL::X509::Certificate.new( ssl_cert_file )
    key           = OpenSSL::PKey::RSA.new( ssl_key_file )

    [true, {
      ssl_client_cert: cert,
      ssl_client_key: key,
      ssl_ca_file: ssl_ca_file,
      verify_ssl: OpenSSL::SSL::VERIFY_NONE
    } ]

  else

    logger.debug( 'PKI not found, using basic auth for connection to Icinga 2 API' )

    raise ArgumentError.new('Missing user_name') if( user.nil? )
    raise ArgumentError.new('Missing password')  if( password.nil? )

    [false, {
      user: user,
      password: password,
      verify_ssl: OpenSSL::SSL::VERIFY_NONE
    } ]
  end

end

#cib_dataHash

return Icinga2 CIB

Examples:

@icinga.cib_data

Returns:



252
253
254
255
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
# File 'lib/icinga2/client.rb', line 252

def cib_data

  data = icinga_application_data(
    url: format( '%s/status/CIB', @icinga_api_url_base ),
    headers: @headers,
    options: @options
  )

  return nil if( data.nil? )

  @last_cib_data_called = 0 #Time.now.to_i

  if( data.is_a?(Hash))

    cib_data = data.clone

    # extract
    #   - uptime
    uptime   = cib_data.dig('uptime').round(2)
    @uptime  = Time.at(uptime).utc.strftime('%H:%M:%S')
    #   - avg_latency / avg_execution_time
    @avg_latency        = cib_data.dig('avg_latency').round(2)
    @avg_execution_time = cib_data.dig('avg_execution_time').round(2)

    #   - hosts
    @hosts_up           = cib_data.dig('num_hosts_up').to_i
    @hosts_down         = cib_data.dig('num_hosts_down').to_i
    @hosts_pending      = cib_data.dig('num_hosts_pending').to_i
    @hosts_unreachable  = cib_data.dig('num_hosts_unreachable').to_i
    @hosts_in_downtime  = cib_data.dig('num_hosts_in_downtime').to_i
    @hosts_acknowledged = cib_data.dig('num_hosts_acknowledged').to_i

    #   - services
    @services_ok           = cib_data.dig('num_services_ok').to_i
    @services_warning      = cib_data.dig('num_services_warning').to_i
    @services_critical     = cib_data.dig('num_services_critical').to_i
    @services_unknown      = cib_data.dig('num_services_unknown').to_i
    @services_pending      = cib_data.dig('num_services_pending').to_i
    @services_in_downtime  = cib_data.dig('num_services_in_downtime').to_i
    @services_acknowledged = cib_data.dig('num_services_acknowledged').to_i

    #   - check stats
    @hosts_active_checks_1min     = cib_data.dig('active_host_checks_1min')
    @hosts_passive_checks_1min    = cib_data.dig('passive_host_checks_1min')
    @services_active_checks_1min  = cib_data.dig('active_service_checks_1min')
    @services_passive_checks_1min = cib_data.dig('passive_service_checks_1min')

  end

  data
end

#node_nameString

return Icinga2 node_name

Examples:

@icinga.node_name

Returns:

  • (String)


388
389
390
391
392
393
394
395
# File 'lib/icinga2/client.rb', line 388

def node_name

  application_data if((Time.now.to_i - @last_application_data_called).to_i > @last_call_timeout)

  return @node_name if( @node_name )

  nil
end

#start_timeString

return Icinga2 start time

Examples:

@icinga.start_time

Returns:

  • (String)


404
405
406
407
408
409
410
411
# File 'lib/icinga2/client.rb', line 404

def start_time

  application_data if((Time.now.to_i - @last_application_data_called).to_i > @last_call_timeout)

  return @start_time if( @start_time )

  nil
end

#status_dataHash

return Icinga2 Status Data

Examples:

@icinga.status_data

Returns:



311
312
313
314
315
316
317
318
319
320
# File 'lib/icinga2/client.rb', line 311

def status_data

  @last_status_data_called = Time.now.to_i

  icinga_application_data(
    url: format( '%s/status', @icinga_api_url_base ),
    headers: @headers,
    options: @options
  )
end

#uptimeString

return Icinga2 uptime

Examples:

@icinga.cib_data
@icinga.uptime

Returns:

  • (String)


421
422
423
424
425
426
427
428
# File 'lib/icinga2/client.rb', line 421

def uptime

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

  return @uptime if( @uptime )

  nil
end

#versionHash

return Icinga2 version and revision

Examples:

@icinga.version.values

v = @icinga.version
version = v.dig(:version)

Returns:

  • (Hash)
    • version

    • revision



368
369
370
371
372
373
374
375
376
377
378
379
# File 'lib/icinga2/client.rb', line 368

def version

  application_data if((Time.now.to_i - @last_application_data_called).to_i > @last_call_timeout)

  version  = @version.nil?  ? 0 : @version
  revision = @revision.nil? ? 0 : @revision

  {
    version: version.to_s,
    revision: revision.to_s
  }
end