Class: Icinga2::Client

Overview

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

Author:

  • Bodo Schulz

Constant Summary

Constants included from Converts

Icinga2::Converts::HOST_STATE_COLOR, Icinga2::Converts::HOST_STATE_STRING, Icinga2::Converts::SERVICE_STATE_COLOR, Icinga2::Converts::SERVICE_STATE_STRING

Instance Method Summary collapse

Methods included from Actions

#restart_process, #shutdown_process

Methods included from ConfigurationManagement

#create_config_package, #fetch_config_stages, #list_config_packages, #list_config_stages, #package_exists?, #package_stage_errors, #remove_config_package, #remove_config_stage, #upload_config_package

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, #remove_downtime

Methods included from Tools

#count_problems, #object_has_been_checked?, #parse_version, #valid_json?

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, #get, #icinga_application_data, #post, #put

Methods included from Validator

#validate

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: {
      username: 'root',
      password: 'icinga',
      version: 1
    }
  }
}
@icinga = Icinga2::Client.new(config)

Parameters:

  • settings (Hash, #read)

    the settings for Icinga2

Options Hash (settings):

  • host (String)

    the Icinga2 Hostname

  • port (Integer) — default: 5665

    the Icinga2 API Port

  • username (String)

    the Icinga2 API User

  • password (String)

    the Icinga2 API Password

  • version (Integer) — default: 1

    the Icinga2 API Version

  • pki_path (String)

    the location of the Certificate Files

  • node_name (String)

    overwrite the Icnag2 hostname for the PKI. if the node_name no set, we try to resolve with gethostbyname()

Raises:

  • (ArgumentError)


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

def initialize( settings )

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

  icinga_host           = settings.dig(:icinga, :host)
  icinga_api_port       = settings.dig(:icinga, :api, :port)     || 5665
  icinga_api_user       = settings.dig(:icinga, :api, :username)
  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)

  @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,
    username: icinga_api_user,
    password: icinga_api_pass
  )

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

Instance Method Details

#api_listenerHash

return Icinga2 API Listener

Examples:

api_listener

Returns:



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

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:

application_data

Returns:



203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/icinga2/client.rb', line 203

def application_data

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

  return nil if( data.nil? )
  return nil unless(data.is_a?(Hash))

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

  # 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:

available?

Returns:

  • (Bool)


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

def available?

  data = application_data

  return true unless( data.nil? )

  false
end

#cert?(params) ⇒ Array

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

Examples:

with Certificate

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

with User

cert?(username: '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:

Raises:

  • (ArgumentError)


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

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)
  username     = params.dig(:username)
  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 \'username\'') if( username.nil? )
    raise ArgumentError.new('Missing \'password\'') if( password.nil? )

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

#cib_dataHash

return Icinga2 CIB

Examples:

cib_data

Returns:



233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
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
# File 'lib/icinga2/client.rb', line 233

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:

node_name

Returns:



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

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:

start_time

Returns:



385
386
387
388
389
390
391
392
# File 'lib/icinga2/client.rb', line 385

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:

status_data

Returns:



292
293
294
295
296
297
298
299
300
301
# File 'lib/icinga2/client.rb', line 292

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:

cib_data
uptime

Returns:



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

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:

version.values

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

Returns:

  • (Hash)
    • version

    • revision



349
350
351
352
353
354
355
356
357
358
359
360
# File 'lib/icinga2/client.rb', line 349

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