summaryrefslogtreecommitdiff
blob: 38aad87526f80a63b822c901c4b25e200e069ffd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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
require 'singleton'
require 'json'
require 'date'

# Defining state constants
module State
  UP = 1
  DOWN = 2
  WARNING = 3
  NA = 0
end

module HelperMethods
  # Checks if all hosts are up
  def all_hosts_up?(hosts)
    hosts.each do |host|
      return false unless
          status_data['hosts'].key?(host) &&
          status_data['hosts'][host]['current_state'] == 0
    end

    true
  end

  def host_up?(host)
    status_data['hosts'].key?(host) &&
      status_data['hosts'][host]['current_state'] == 0
  end

  def host_flapping?(host)
    status_data['hosts'].key?(host) &&
      status_data['hosts'][host]['is_flapping'] != 0
  end

  # Checks if the service is up
  def service_up?(host, service)
    status_data['services'].key?(host) &&
      status_data['services'][host].key?(service) &&
      status_data['services'][host][service]['current_state'] == 0
  end

  def service_flapping?(host, service)
    status_data['services'].key?(host) &&
      status_data['services'][host].key?(service) &&
      status_data['services'][host][service]['is_flapping'] != 0
  end

  def has_service?(host, service)
    status_data['services'][host].key?(service)
  end

  def default(host, service = nil)
    if service.nil?
      if host_flapping? host
        State::WARNING
      elsif host_up? host
        State::UP
      else
        State::DOWN
      end
    else
      return State::NA unless has_service? host, service

      if service_flapping? host, service
        State::WARNING
      elsif service_up? host, service
        State::UP
      else
        State::DOWN
      end
    end
  end
end

class ServiceRegistry
  CACHE_SECONDS = 600
  StatusSource = File.join(File.dirname(__FILE__), '..', 'data', 'status.json')

  include Singleton
  include HelperMethods
  attr_reader :load_date

  def initialize
    @cache_locked = false
    @next_name = nil
    @current_category = nil
  end

  def name(n)
    @next_name = n
  end

  def service(name, &block)
    @services[name] = {}
    @services[name][:name] = @next_name || name

    begin
      @services[name][:status] = block.call
    rescue Exception => e
      @services[name][:status] = State::NA
      $stderr.puts "Processing #{name}: #{e}"
    end

    @next_name = nil
  end

  def services
    update?
    @services
  end

  def status_data
    update?
    @status_data
  end

  def columns
    update?
    @columns
  end

  def categories
    update?
    @categories
  end

  def category(name, &block)
    @categories[name] = {}
    @current_category = name
    @categories[name][:services] = block.call
    @columns[@categories[name][:column]] << name
  end

  def column(id)
    @categories[@current_category][:column] = id
  end

  def update!
    @cache_locked = true
    @services = {}
    @categories = {}
    @columns = { 1 => [], 2 => [], 3 => [] }
    @status_data = JSON.parse(File.read(StatusSource))
    load(File.join(File.dirname(__FILE__), '..', 'data', 'services.rb'))
    @load_date = DateTime.now
    @cache_locked = false
  rescue Exception => e
    $stderr.puts e
    @services = {}
    @categories = {}
    @columns = {1 => [], 2 => [], 3 => []}
    @load_date = DateTime.new(2000, 1, 1)
    @cache_locked = false
  end

  private

  def update?
    if !@load_date.nil? && !@cache_locked && ((DateTime.now - @load_date) * 60 * 60 * 24).to_i > CACHE_SECONDS
      update!
    end
  end
end

def Services(&block)
  ServiceRegistry.instance.instance_eval(&block)
end