class Op5util::Monitor

Foo

Foo

Foo

Foo

Foo

Foo

Foo

Foo

Top level documentation

Foo

Foo

Foo

Foo

Public Class Methods

new(monitor, username, password) click to toggle source

debug_output $stdout

# File lib/op5util/monitor.rb, line 18
def initialize(monitor, username, password)
  @monitor = monitor
  @auth = { username: username, password: password }
  @base_uri = "https://#{@monitor}/api/"
  url = 'status/status?format=json'
  response = self.class.get(@base_uri + url, basic_auth: @auth, verify: false)
  raise AuthenticationError if !response.nil? && !response.code.nil? && response.code == 401
  raise CommunicationError if response.nil? || response.code.nil? || response.code != 200
  self
end

Public Instance Methods

acknowledge_all_alarms(options) click to toggle source
# File lib/op5util/acknowledge_alarm.rb, line 25
def acknowledge_all_alarms(options)
  response = self.class.get(@base_uri + 'config/host?format=json',
                            basic_auth: @auth, verify: false)
  raise ApiError unless response.code == 200
  JSON.parse!(response.body).map { |h| h['name'] }.each do |host|
    acknowledge_host_alarms(host, options)
  end
end
acknowledge_host_alarms(host, options) click to toggle source
# File lib/op5util/acknowledge_alarm.rb, line 6
def acknowledge_host_alarms(host, options)
  host_states = host_status(host)
  if host_states[:host] > 0
    puts 'Acknowledge host alarm for host ' + host
    ack_host_alarm(host, options)
  else
    puts 'No alarm for host ' + host + ', not acking host'
  end
  if host_states[:services].count > 0
    host_states[:services].each do |s|
      ack_host_service(host, s, options)
      puts "Service \"#{s}\" acknowledged" if options[:verbose]
    end
    puts 'All service alarms for host ' + host + ' acknowledged'
  else
    puts "No service alarms to acknowledge for host #{host}"
  end
end
add_host(host, options) click to toggle source
# File lib/op5util/add_host.rb, line 13
def add_host(host, options)
  body = build_add_host_request_body(host, options)
  response = self.class.post(@base_uri + 'config/host',
                             headers: { 'Content-Type' => 'application/json' },
                             body: body, basic_auth: @auth, verify: false)
  raise ApiError, "Response code: #{response.code}, Message: #{response.body}" if response.code != 201
  commit_op5_config unless options['no-commit'.to_sym]
end
add_hostgroups(host, hostgroups, no_commit_config) click to toggle source
# File lib/op5util/add_hostgroups.rb, line 8
def add_hostgroups(host, hostgroups, no_commit_config)
  hostgroups.each do |group|
    members = get_hostgroup_members(group)
    if !members.grep(host).empty?
      puts "Host #{host} is already a member of hostgroup #{group}"
    else
      raise NoSuchHostError, host unless host_exist?(host)
      members << host
      update_hostgroup(group, members)
    end
  end
  commit_op5_config unless no_commit_config
end
autocomplete() click to toggle source
# File lib/op5util/autocomplete.rb, line 6
    def autocomplete
      s = '
# Add this to suitable shell startup file to get tab autocomplete for op5util.
# op5util autocomplete >> ~/.bashrc
# ZSH-users should uncomment the line below
# autoload -U +X bashcompinit && bashcompinit

_op5util()
{
    local cur prev opts base
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    op5command="${COMP_WORDS[1]}"
    opts="acknowledge add add_hostgroups downtime help hostgroups schedule status"

    case "${op5command}" in
        acknowledge)
            COMPREPLY=( $(compgen -W "-c --comment=Work_in_Progress -p --persistent --no-persistent -v --verbose --no-verbose $(op5util hosts)" -- ${cur}) )
            ;;
        add)
            COMPREPLY=( $(compgen -W "-a --alias=\" -c --contactgroups=\" -g --hostgroups=\" -i --ipaddr=\" HOST_TO_ADD  $(op5util hostgroups)" -- ${cur}) )
            ;;
        add_hostgroups)
            COMPREPLY=( $(compgen -W "-g --hostgroup=  $(op5util hosts)" -- ${cur}) )
            ;;
        autocomplete)
            COMPREPLY=( $(compgen -W "ENTER" -- ${cur}) )
            ;;
        downtime)
            COMPREPLY=( $(compgen -W "-t --time=n_hour_duration_of_downtime -w --wait=n_hours_before_downtime_start -c --comment=  $(op5util hosts)" -- ${cur}) )
            ;;
        hostgroups)
            COMPREPLY=( $(compgen -W "-l --long  $(op5util hostgroups)" -- ${cur}) )
            ;;
        schedule)
            COMPREPLY=( $(compgen -W "-v --verbose  $(op5util hosts)" -- ${cur}) )
            ;;
        status)
            COMPREPLY=( $(compgen -W "-l --long -s --short  $(op5util hosts)" -- ${cur}) )
            ;;
        *)
            ;;
    esac
    if [ -z $COMPREPLY ]; then
        COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
    fi
    return 0
}
complete -F _op5util op5util
'
      puts s
    end
commit_op5_config() click to toggle source
# File lib/op5util/commit.rb, line 6
def commit_op5_config
  if pending_changes.empty?
    puts 'No changes to commit'
  else
    do_commit
  end
end
list_hostgroups(hostgroup, options) click to toggle source
# File lib/op5util/list_hostgroups.rb, line 7
def list_hostgroups(hostgroup, options)
  response = self.class.get(@base_uri + 'config/hostgroup?format=json',
                            basic_auth: @auth, verify: false)
  raise ApiError unless response.code == 200
  if hostgroup.nil?
    hostgroups = JSON.parse!(response.body).map { |h| h['name'] }
  else
    hostgroups = JSON.parse!(response.body).map { |h| h['name'] }.select { |hg| hg == hostgroup }
    raise NoSuchHostgroupError if hostgroups.empty?
  end
  if options[:long]
    list_hostgroups_with_services(hostgroups)
  else
    hostgroups.each { |h| puts h }
  end
end
list_hosts(host, options) click to toggle source
# File lib/op5util/list_hosts.rb, line 6
def list_hosts(host, options)
  response = self.class.get(@base_uri + 'config/host?format=json',
                            basic_auth: @auth, verify: false)
  raise ApiError unless response.code == 200
  JSON.parse!(response.body).map { |h| h['name'] }.select { |h| host.nil? ? true : h == host }.each do |h|
    puts h
    print_detailed_host_info(h) if options[:long]
  end
end
method_template() click to toggle source
# File lib/op5util/method_template.rb, line 6
def method_template
  response = self.class.get(@base_uri + 'some/path?format=json',
                            basic_auth: @auth, verify: false)
  raise ApiError unless response.code == 200
  puts 'Do something'
end
schedule_checks(host, options) click to toggle source
# File lib/op5util/schedule_checks.rb, line 6
def schedule_checks(host, options)
  schedule_host_check(host)
  schedule_service_checks_for_host(host, options)
end
schedule_downtime(host_string, options) click to toggle source
# File lib/op5util/schedule_downtime.rb, line 7
def schedule_downtime(host_string, options)
  host_string.split(',').each do |host|
    schedule_downtime_for_host(host, options)
  end
end
status_host(host, options) click to toggle source
# File lib/op5util/status_host.rb, line 8
def status_host(host, options)
  full_status = JSON.parse!(get_host_status(host))
  if options[:short] || (!options[:short] && !options[:long])
    print_short_status(full_status)
  else
    print_full_status(full_status)
  end
end
status_summary(options) click to toggle source
# File lib/op5util/status_summary.rb, line 7
def status_summary(options)
  if options[:long]
    print_hosts_summary
  else
    print_summary
  end
end

Private Instance Methods

ack_host_alarm(host, options) click to toggle source
# File lib/op5util/acknowledge_alarm.rb, line 46
def ack_host_alarm(host, options)
  body = ack_host_alarm_body(host, options)
  response = self.class.post(@base_uri + 'command/ACKNOWLEDGE_HOST_PROBLEM?format=json',
                             headers: { 'Content-Type' => 'application/json' },
                             body: body, basic_auth: @auth, verify: false)
  raise ApiError unless response.code == 200
  puts 'Host alarm acknowledged'
end
ack_host_alarm_body(host, options) click to toggle source
# File lib/op5util/acknowledge_alarm.rb, line 36
def ack_host_alarm_body(host, options)
  {
    host_name:   host,
    sticky:      true,
    notify:      true,
    persistent:  options[:persistent],
    comment:     options[:comment]
  }.to_json
end
ack_host_service(host, service, options) click to toggle source
# File lib/op5util/acknowledge_alarm.rb, line 66
def ack_host_service(host, service, options)
  body = ack_host_service_alarm_body(host, service, options)
  response = self.class.post(@base_uri + 'command/ACKNOWLEDGE_SVC_PROBLEM?format=json',
                             headers: { 'Content-Type' => 'application/json' },
                             body: body, basic_auth: @auth, verify: false)
  raise ApiError unless response.code == 200
  puts "Alarm for service \"#{service}\" acknowledged" if options[:verbose]
end
ack_host_service_alarm_body(host, service, options) click to toggle source
# File lib/op5util/acknowledge_alarm.rb, line 55
def ack_host_service_alarm_body(host, service, options)
  {
    host_name:           host,
    service_description: service,
    sticky:              true,
    notify:              true,
    persistent:          options[:persistent],
    comment:             options[:comment]
  }.to_json
end
add_host_request_body_as_json(host, host_ipaddr, host_alias, contactgroups, hostgroups) click to toggle source
# File lib/op5util/add_host.rb, line 32
def add_host_request_body_as_json(host, host_ipaddr, host_alias, contactgroups, hostgroups)
  { file_id:                   'etc/hosts.cfg',
    host_name:                 host.to_s,
    address:                   host_ipaddr.to_s,
    alias:                     host_alias.to_s,
    max_check_attempts:        3,
    notification_interval:     0,
    notification_options:      %w[d u r],
    notification_period:       '24x7',
    notifications_enabled:     true,
    template:                  'default-host-template',
    contact_groups:            contactgroups,
    hostgroups:                hostgroups }.to_json
end
build_add_host_request_body(host, options) click to toggle source
# File lib/op5util/add_host.rb, line 24
def build_add_host_request_body(host, options)
  host_ipaddr   = options[:ipaddr].nil? ? Resolv.getaddress(host) : options[:ipaddr]
  host_alias    = options[:alias].nil? ? short_name(host) : options[:alias]
  contactgroups = options[:contactgroups].nil? ? ['support-group'] : options[:contactgroups]
  hostgroups    = options[:hostgroups].nil? ? [] : options[:hostgroups]
  add_host_request_body_as_json(host, host_ipaddr, host_alias, contactgroups, hostgroups)
end
build_host_check_body(host) click to toggle source
# File lib/op5util/schedule_checks.rb, line 13
def build_host_check_body(host)
  time = Time.now.to_i
  { host_name:  host,
    check_time: time }.to_json
end
build_schedule_downtime_request_body(host, options) click to toggle source
# File lib/op5util/schedule_downtime.rb, line 24
def build_schedule_downtime_request_body(host, options)
  start_time = Time.now.to_i + options[:wait].to_i
  end_time   = start_time + + options[:time].to_i * 3600 + 10
  {
    host_name:      host.to_s,
    start_time:     start_time,
    end_time:       end_time,
    fixed:          1,
    trigger_id:     0,
    duration:       options[:time].to_i * 3600 + 10,
    comment:        options[:comment]
  }.to_json
end
build_service_check_body(host, service_description) click to toggle source
# File lib/op5util/schedule_checks.rb, line 53
def build_service_check_body(host, service_description)
  time = Time.now.to_i
  { host_name:           host,
    check_time:          time,
    service_description: service_description }.to_json
end
count_ok(a) click to toggle source
# File lib/op5util/status_summary.rb, line 70
def count_ok(a)
  a[0] - a[1] - a[2]
end
do_commit() click to toggle source
# File lib/op5util/commit.rb, line 23
def do_commit
  url = @base_uri + 'config/change'
  response = self.class.post(url, body: {}, basic_auth: @auth, verify: false)
  raise ApiError, "Response code: #{response.code}, Message: #{response.body}" if response.code != 200
  puts 'Op5-config commited'
end
fold_string(s, width) click to toggle source
# File lib/op5util/status_host.rb, line 76
def fold_string(s, width)
  return nil if s.nil?
  start_pos = 0
  result = ''
  while start_pos < s.length
    cut_chars = [width, (s.length - start_pos)].min
    cut_pos = start_pos + cut_chars - 1
    result += s[start_pos..cut_pos]
    start_pos += cut_chars
    result += "\n" if start_pos < s.length
  end
  result
end
get_host_status(host) click to toggle source
# File lib/op5util/status_host.rb, line 144
def get_host_status(host)
  response = self.class.get(@base_uri + "status/host/#{host}?format=json",
                            basic_auth: @auth, verify: false)
  raise ApiError unless response.code == 200
  response.body
end
get_host_statuses() click to toggle source
# File lib/op5util/status_summary.rb, line 74
def get_host_statuses
  host_urls = ['=%5Bhosts%5D%20all',
               '=%5Bhosts%5D%20acknowledged%20%3D%201',
               '=%5Bhosts%5D%20state%20!%3D%200%20and%20acknowledged%20%3D%200%20and%20scheduled_downtime_depth%20%3D%200']
  host_statuses = []
  host_urls.each do |url|
    response = self.class.get(@base_uri + 'filter/count?query' + url,
                              basic_auth: @auth, verify: false)
    raise ApiError unless response.code == 200
    host_statuses << JSON.parse!(response.body)['count'].to_i
  end
  host_statuses
end
get_hostgroup_members(group) click to toggle source
# File lib/op5util/add_hostgroups.rb, line 24
def get_hostgroup_members(group)
  response = self.class.get(@base_uri + "config/hostgroup/#{group}?format=json",
                            basic_auth: @auth, verify: false)
  raise NoSuchHostgroupError if response.code == 404
  JSON.parse!(response.body)['members']
end
get_service_statuses() click to toggle source
# File lib/op5util/status_summary.rb, line 56
def get_service_statuses
  service_urls = ['=%5Bservices%5D%20all',
                  '=%5Bservices%5D%20acknowledged%20%3D%201',
                  '=[services] state !%3D 0 and acknowledged %3D 0 and scheduled_downtime_depth %3D 0 and host.scheduled_downtime_depth %3D 0']
  service_statuses = []
  service_urls.each do |url|
    response = self.class.get(@base_uri + 'filter/count?query' + url,
                              basic_auth: @auth, verify: false)
    raise ApiError unless response.code == 200
    service_statuses << JSON.parse!(response.body)['count'].to_i
  end
  service_statuses
end
host_exist?(host) click to toggle source
# File lib/op5util/add_hostgroups.rb, line 31
def host_exist?(host)
  response = self.class.get(@base_uri + "config/host/#{host}?format=json",
                            basic_auth: @auth, verify: false)
  raise NoSuchHostError if response.code == 404
  raise ApiError if response.code != 200
  true
end
host_state_to_s(state) click to toggle source
# File lib/op5util/status_host.rb, line 120
def host_state_to_s(state)
  case state
  when 0
    'UP'.green
  when 1
    'DOWN'.red.bold
  else
    'UNKNOWN'.white.bold
  end
end
host_status(host) click to toggle source
# File lib/op5util/acknowledge_alarm.rb, line 75
def host_status(host)
  response = self.class.get(@base_uri + "status/host/#{host}?format=json",
                            basic_auth: @auth, verify: false)
  raise ApiError unless response.code == 200
  state = JSON.parse!(response.body)
  {
    host:     state['hard_state'],
    services: state['services_with_state'].select { |s| s[1] > 0 }.map { |s| s[0] }
  }
end
hostgroup_info(h) click to toggle source
# File lib/op5util/list_hostgroups.rb, line 26
def hostgroup_info(h)
  response = self.class.get(@base_uri + "config/hostgroup/#{URI.escape(h)}?format=json",
                            basic_auth: @auth, verify: false)
  raise ApiError unless response.code == 200
  hostgroup = JSON.parse!(response.body)
  hostgroup['members'].nil? ? '' : members = hostgroup['members'].join(',')
  max = max_cell_width
  if hostgroup['services'].nil?
    services = ''
  else
    services = hostgroup['services'].map { |s| fold_string('"' + s['service_description'] + '"', max) }.join("\n")
  end
  [members, services]
end
hostgroup_services(hg) click to toggle source
# File lib/op5util/schedule_checks.rb, line 28
def hostgroup_services(hg)
  response = self.class.get(@base_uri + "config/hostgroup/#{URI.escape(hg)}?format=json",
                            basic_auth: @auth, verify: false)
  raise ApiError unless response.code == 200
  hg_info = JSON.parse!(response.body)
  hg_info['services'].nil? ? [] : hg_info['services'].map { |s| s['service_description'] }
end
list_hostgroups_with_services(hostgroups) click to toggle source
# File lib/op5util/list_hostgroups.rb, line 50
def list_hostgroups_with_services(hostgroups)
  max = max_cell_width
  table = Terminal::Table.new do |t|
    t.add_row ['Hostgroup'.blue, 'Member hosts'.blue, 'Service checks'.blue]
    t.add_separator
    hostgroups.each do |h|
      (members, services) = hostgroup_info(h)
      t.add_row [h, fold_string(members, max), services ]
    end
  end
  puts table
end
max_cell_width() click to toggle source
# File lib/op5util/list_hostgroups.rb, line 41
def max_cell_width
  # The magic number 15 is the size of tables cells padding + the heading 'State'
  # and a an extra characters for safe layout on narrow terminals, down to
  # 80 characters width tested.
  require 'io/console'
  (_terminal_height, terminal_width) = IO.console.winsize
  ((terminal_width - 15) / 2).floor
end
pending_changes() click to toggle source
# File lib/op5util/commit.rb, line 16
def pending_changes
  url = @base_uri + 'config/change'
  response = self.class.get(url, basic_auth: @auth, verify: false)
  raise ApiError, "Response code: #{response.code}, Message: #{response.body}" if response.code != 200
  JSON.parse!(response.body)
end
pp_n_services(n, total = 0) click to toggle source
# File lib/op5util/status_host.rb, line 112
def pp_n_services(n, total = 0)
  if n == total || ( total == 0 && n > 0 )
    n.to_s.green
  else
    n.to_s.red.bold
  end
end
pp_seconds(seconds) click to toggle source
# File lib/op5util/status_host.rb, line 90
def pp_seconds(seconds)
  retval = ''
  s = seconds
  if s > 86_400
    retval = (s / 8600).to_s + ' days, '
    s = s % 86_400
  end
  if s > 3600
    retval += (s / 3660).to_s + ' hours, '
    s = s % 3600
  end
  if s > 60
    retval += (s / 60).to_s + ' minutes, '
    s = s % 60
  end
  retval += (s % 60).to_s + ' seconds '
end
pp_unixtime_ago(t) click to toggle source
# File lib/op5util/status_host.rb, line 108
def pp_unixtime_ago(t)
  pp_seconds(Time.now.to_i - t)
end
print_detailed_host_info(host) click to toggle source
print_full_status(full_status) click to toggle source
print_hosts_summary() click to toggle source
print_short_status(full_status) click to toggle source
print_summary() click to toggle source
row_for_host(host) click to toggle source
# File lib/op5util/status_summary.rb, line 32
def row_for_host(host)
  full_status = JSON.parse!(get_host_status(host))
  row = []
  row << host
  row << host_state_to_s(full_status['state'].to_i)
  row << full_status['num_services'].to_s.green
  row << full_status['num_services_hard_ok'].to_s.green
  row << full_status['num_services_hard_warn'].to_s.yellow
  row << full_status['num_services_hard_crit'].to_s.red
  row
end
schedule_downtime_for_host(host, options) click to toggle source
# File lib/op5util/schedule_downtime.rb, line 15
def schedule_downtime_for_host(host, options)
  body = build_schedule_downtime_request_body(host, options)
  response = self.class.post(@base_uri + 'command/SCHEDULE_HOST_DOWNTIME',
                             headers: { 'Content-Type' => 'application/json' },
                             body: body, basic_auth: @auth, verify: false)
  raise ApiError unless response.code == 200
  puts "Downtime Scheduled for host #{host}"
end
schedule_host_check(host) click to toggle source
# File lib/op5util/schedule_checks.rb, line 19
def schedule_host_check(host)
  body = build_host_check_body(host)
  response = self.class.post(@base_uri + 'command/SCHEDULE_HOST_CHECK?format=json',
                             headers: { 'Content-Type' => 'application/json' },
                             body: body, basic_auth: @auth, verify: false)
  raise ApiError unless response.code == 200
  puts 'Host check scheduled'
end
schedule_service_checks_for_host(host, options) click to toggle source
# File lib/op5util/schedule_checks.rb, line 60
def schedule_service_checks_for_host(host, options)
  service_description_for_host(host).each do |s|
    body = build_service_check_body(host, s)
    response = self.class.post(@base_uri + 'command/SCHEDULE_SVC_CHECK?format=json',
                               headers: { 'Content-Type' => 'application/json' },
                               body: body, basic_auth: @auth, verify: false)
    raise ApiError unless response.code == 200
    puts "Service check for service \"#{s}\" scheduled" if options[:verbose]
  end
  puts "All services for host #{host} scheduled for check"
end
service_description_for_host(host) click to toggle source

TODO: split hostgroup_info into better re-usable code

# File lib/op5util/schedule_checks.rb, line 37
def service_description_for_host(host)
  response = self.class.get(@base_uri + "config/host/#{host}?format=json",
                            basic_auth: @auth, verify: false)
  raise ApiError unless response.code == 200
  host_config = JSON.parse!(response.body)
  if host_config['services'].nil?
    services = []
  else
    services = host_config['services'].map { |s| s['service_description'] }
  end
  host_config['hostgroups'].each do |hg|
    services += hostgroup_services(hg)
  end
  services.nil? ? [] : services
end
service_info(service, full_status) click to toggle source
# File lib/op5util/status_host.rb, line 50
def service_info(service, full_status)
  full_status['services_with_info'].each do |s|
    return s[3] if s[0] == service
  end
  ''
end
service_state(service, full_status) click to toggle source
# File lib/op5util/status_host.rb, line 43
def service_state(service, full_status)
  full_status['services_with_state'].each do |s|
    return s[1] if s[0] == service
  end
  ''
end
service_state_to_s(state) click to toggle source
# File lib/op5util/status_host.rb, line 131
def service_state_to_s(state)
  case state
  when 0
    'OK'.green
  when 1
    'WARN'.yellow.bold
  when 2
    'CRITICAL'.red.bold
  else
    'UNKNOWN'.white.bold
  end
end
short_name(h) click to toggle source
# File lib/op5util/add_host.rb, line 47
def short_name(h)
  split_host = h.split('.')
  if split_host.count > 1
    split_host[0]
  else
    ''
  end
end
update_hostgroup(hostgroup, members) click to toggle source
# File lib/op5util/add_hostgroups.rb, line 39
def update_hostgroup(hostgroup, members)
  body = { file_id:         'etc/hostgroups.cfg',
           hostgroup_name:  hostgroup.to_s,
           members:         members }.to_json
  response = self.class.patch(@base_uri + "config/hostgroup/#{hostgroup}",
                              headers: { 'Content-Type' => 'application/json' },
                              body: body, basic_auth: @auth, verify: false)
  raise ApiError unless response.code == 200
end