livestatus 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,24 +5,6 @@ require "livestatus/connection"
5
5
  require "livestatus/models"
6
6
 
7
7
  module Livestatus
8
- mattr_accessor :config
9
- self.config = {
10
- :uri => "unix:///var/nagios/rw/live",
11
- }
12
-
13
- def self.connection
14
- @@connection ||= connection!
15
- end
16
-
17
- def self.connection!
18
- Livestatus::Connection.new(config)
19
- end
20
-
21
- def self.get(table_name, options = {})
22
- connection.get(table_name, options)
23
- end
24
-
25
- def self.command(cmd, time = nil)
26
- connection.command(cmd, time)
27
- end
8
+ mattr_accessor :connection
9
+ self.connection = nil
28
10
  end
@@ -9,6 +9,7 @@ module Livestatus
9
9
  Hash[env.select do |k, v|
10
10
  k =~ /^HTTP_X_LIVESTATUS_/
11
11
  end.map do |k, v|
12
+ v = Yajl::Parser.parse(v) if v =~ /^\[/
12
13
  [k[18..-1].downcase.to_sym, v]
13
14
  end]
14
15
  end
@@ -17,7 +18,7 @@ module Livestatus
17
18
  headers = parse_headers(request.env)
18
19
 
19
20
  halt 400, 'no query specified' unless headers.include?(:query)
20
- method, query = headers.delete(:query).split
21
+ method, query = headers.delete(:query).split(' ', 2)
21
22
 
22
23
  halt 400, 'invalid method' unless ['GET', 'COMMAND'].include?(method)
23
24
  method = method.downcase.to_sym
@@ -26,11 +27,14 @@ module Livestatus
26
27
 
27
28
  case method
28
29
  when :get
29
- Yajl::Encoder.encode(c.get(query, headers))
30
+ res = c.get(Livestatus.models[query], headers).map(&:data)
30
31
  when :command
31
- c.command(query)
32
- Yajl::Encoder.encode(c.command(query))
32
+ query =~ /\[([0-9]+)\] (.*)/
33
+ time, command = $1.to_i, $2
34
+ res = c.command(command, time)
33
35
  end
36
+
37
+ Yajl::Encoder.encode(res)
34
38
  end
35
39
  end
36
40
  end
@@ -18,9 +18,9 @@ module Livestatus
18
18
  def handler!
19
19
  case @config[:uri]
20
20
  when /^https?:\/\//
21
- PatronHandler.new(@config)
21
+ PatronHandler.new(self, @config)
22
22
  when /^unix:\/\//
23
- UnixHandler.new(@config)
23
+ UnixHandler.new(self, @config)
24
24
  else
25
25
  raise AttributeError, "unknown uri type: #{@config[:uri]}"
26
26
  end
@@ -1,18 +1,5 @@
1
1
  module Livestatus
2
-
3
2
  class HandlerException < StandardError; end
4
-
5
- class BaseHandler
6
- def get(table_name, options = {})
7
- query(:get, table_name.to_s, options)
8
- end
9
-
10
- def command(cmd, time = nil)
11
- time = Time.now.to_i unless time
12
- query(:command, "[#{time}] #{cmd}")
13
- end
14
- end
15
-
16
3
  end
17
4
 
18
5
  Dir["#{File.dirname(__FILE__)}/handler/*.rb"].each do |path|
@@ -4,10 +4,11 @@ require 'yajl'
4
4
 
5
5
  module Livestatus
6
6
 
7
- class PatronHandler < BaseHandler
7
+ class PatronHandler
8
8
  attr_accessor :session
9
9
 
10
- def initialize(config)
10
+ def initialize(connection, config)
11
+ @connection = connection
11
12
  @session = Patron::Session.new
12
13
  @session.timeout = 10
13
14
  @session.headers["User-Agent"] = "livestatus/#{VERSION} ruby/#{RUBY_VERSION}"
@@ -18,10 +19,23 @@ module Livestatus
18
19
  @uri = config[:uri]
19
20
  end
20
21
 
22
+ def get(model, options = {})
23
+ query(:get, model.table_name, options).map do |data|
24
+ model.new(data, @connection)
25
+ end
26
+ end
27
+
28
+ def command(cmd, time = nil)
29
+ time = Time.now.to_i unless time
30
+ query(:command, "[#{time}] #{cmd}")
31
+ nil
32
+ end
33
+
21
34
  def query(method, query, headers = {})
22
35
  headers = Hash[headers.merge({
23
36
  :query => "#{method.to_s.upcase} #{query}"
24
37
  }).map do |k, v|
38
+ v = Yajl::Encoder.encode(v) if v.is_a?(Array)
25
39
  ["X-Livestatus-#{k.to_s.dasherize}", v]
26
40
  end]
27
41
 
@@ -4,51 +4,59 @@ require 'yajl'
4
4
 
5
5
  module Livestatus
6
6
 
7
- class UnixHandler < BaseHandler
8
- def initialize(config)
7
+ class UnixHandler
8
+ def initialize(connection, config)
9
+ @connection = connection
9
10
  @socket = UNIXSocket.open(config[:uri].sub(/^unix:\/\//, ''))
10
11
  end
11
12
 
12
- def get(table_name, options = {})
13
- data = super
14
-
15
- if options.include?(:columns)
16
- columns = options[:columns].split(" ")
17
- else
18
- columns = data.delete_at(0)
19
- end
20
-
21
- column_zip(columns, data)
22
- end
23
-
24
- def query(method, query, headers = {})
25
- headers.merge!({
13
+ def get(model, options = {})
14
+ options.merge!({
26
15
  :response_header => "fixed16",
27
16
  :output_format => "json",
28
17
  :keep_alive => "on",
29
18
  })
30
19
 
31
- headers = headers.map { |k,v| "#{k.to_s.camelize}: #{v}" }.join("\n")
20
+ headers = options.map do |k,v|
21
+ if v.is_a?(Array)
22
+ v.map do |e|
23
+ "#{k.to_s.camelize}: #{e}"
24
+ end
25
+ else
26
+ "#{k.to_s.camelize}: #{v}"
27
+ end
28
+ end.flatten.join("\n")
29
+
32
30
  headers += "\n" unless headers.empty?
33
31
 
34
- case method
35
- when :get
36
- @socket.write("#{method.to_s.upcase} #{query}\n#{headers}\n")
32
+ @socket.write("GET #{model.table_name}\n#{headers}\n")
37
33
 
38
- res = @socket.read(16)
39
- status, length = res[0..2].to_i, res[4..14].chomp.to_i
34
+ res = @socket.read(16)
35
+ status, length = res[0..2].to_i, res[4..14].chomp.to_i
40
36
 
41
- unless status == 200
42
- raise HandlerException, "livestatus query failed with status #{status}"
43
- end
37
+ unless status == 200
38
+ raise HandlerException, "livestatus query failed with status #{status}"
39
+ end
40
+
41
+ data = Yajl::Parser.new.parse(@socket.read(length))
44
42
 
45
- Yajl::Parser.new.parse(@socket.read(length))
46
- when :command
47
- @socket.write("#{method.to_s.upcase} #{query}\n\n")
48
- nil
43
+ if options.include?(:columns)
44
+ columns = options[:columns].split(" ")
45
+ else
46
+ columns = data.delete_at(0)
47
+ end
48
+
49
+ column_zip(columns, data).map do |d|
50
+ model.new(d, @connection)
49
51
  end
50
52
  end
51
53
 
54
+ def command(cmd, time = nil)
55
+ time = Time.now.to_i unless time
56
+ @socket.write("COMMAND [#{time}] #{cmd}\n\n")
57
+ nil
58
+ end
59
+
52
60
  private
53
61
 
54
62
  def column_zip(columns, data)
@@ -2,13 +2,14 @@ require "active_support/core_ext"
2
2
 
3
3
  module Livestatus
4
4
  mattr_accessor :models
5
- self.models = []
5
+ self.models = {}
6
6
 
7
7
  class Base
8
8
  attr_reader :data
9
9
 
10
- def initialize(data)
10
+ def initialize(data, connection = nil)
11
11
  @data = data.symbolize_keys!
12
+ @connection = connection
12
13
  end
13
14
 
14
15
  def method_missing(name, *args)
@@ -16,12 +17,6 @@ module Livestatus
16
17
  end
17
18
 
18
19
  class << self
19
- def find(options = {})
20
- Livestatus.get(table_name, options).map do |data|
21
- new(data)
22
- end
23
- end
24
-
25
20
  def table_name
26
21
  to_s.demodulize.tableize.downcase.pluralize
27
22
  end
@@ -93,5 +88,6 @@ Dir["#{File.dirname(__FILE__)}/models/*.rb"].map do |path|
93
88
  File.basename(path, '.rb')
94
89
  end.each do |name|
95
90
  require "livestatus/models/#{name}"
96
- Livestatus.models << "Livestatus::#{name.pluralize.classify}".constantize
91
+ model = "Livestatus::#{name.pluralize.classify}".constantize
92
+ Livestatus.models[model.table_name] = model
97
93
  end
@@ -14,6 +14,19 @@ class Livestatus::Host < Livestatus::Base
14
14
  :last_notification, :last_state_change, :last_time_down,
15
15
  :last_time_unreachable, :last_time_up, :next_check, :next_notification
16
16
 
17
+ def services
18
+ if @connection
19
+ @data[:services].map do |service|
20
+ @connection.get(Livestatus::Service, :filter => [
21
+ "host_name = #{name}",
22
+ "display_name = #{service}"
23
+ ]).first
24
+ end
25
+ else
26
+ @data[:services]
27
+ end
28
+ end
29
+
17
30
  def _id
18
31
  display_name
19
32
  end
@@ -1,3 +1,3 @@
1
1
  module Livestatus
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: livestatus
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 2
9
- - 1
10
- version: 0.2.1
8
+ - 3
9
+ - 0
10
+ version: 0.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - "Benedikt B\xC3\xB6hm"