Compare commits
No commits in common. "master" and "v0.1.1" have entirely different histories.
17
README.md
17
README.md
|
@ -8,17 +8,7 @@ This is a ruby-pure implementation.
|
||||||
|
|
||||||
First it was planed to provide a client-API, but now there is also a full server-API.
|
First it was planed to provide a client-API, but now there is also a full server-API.
|
||||||
|
|
||||||
Tested against nsca-2.7, -2.9.
|
Tested against nsca-2.7.
|
||||||
|
|
||||||
Usage
|
|
||||||
=====
|
|
||||||
|
|
||||||
Simple sending
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
NSCA.destinations << NSCA::Client.new('localhost')
|
|
||||||
NSCA.send 'serverA', 'serviceA', 1, 'Ok'
|
|
||||||
```
|
|
||||||
|
|
||||||
TO DO AND DONE
|
TO DO AND DONE
|
||||||
==============
|
==============
|
||||||
|
@ -26,6 +16,7 @@ TO DO AND DONE
|
||||||
TODO
|
TODO
|
||||||
----
|
----
|
||||||
|
|
||||||
|
* build packet with performance data
|
||||||
* server side parsing of performance data
|
* server side parsing of performance data
|
||||||
* more documentations
|
* more documentations
|
||||||
* mcrypt-support
|
* mcrypt-support
|
||||||
|
@ -39,9 +30,9 @@ DONE
|
||||||
* server-API (recv from client)
|
* server-API (recv from client)
|
||||||
* check-API (describe checks and performance data)
|
* check-API (describe checks and performance data)
|
||||||
* fast usable API for sending checks
|
* fast usable API for sending checks
|
||||||
* build packet with performance data
|
|
||||||
|
|
||||||
Copyright
|
Copyright
|
||||||
=========
|
=========
|
||||||
|
|
||||||
Copyright (c) 2013-2015 Denis Knauf. See [LICENSE.txt](LICENSE.txt) for further details.
|
Copyright (c) 2013 Denis Knauf. See LICENSE.txt for
|
||||||
|
further details.
|
||||||
|
|
4
Rakefile
4
Rakefile
|
@ -15,8 +15,8 @@ require 'jeweler'
|
||||||
Jeweler::Tasks.new do |gem|
|
Jeweler::Tasks.new do |gem|
|
||||||
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
||||||
gem.name = "nsca"
|
gem.name = "nsca"
|
||||||
gem.homepage = "http://github.com/DenisKnauf/ruby-nsca"
|
gem.homepage = "http://github.com/DenisKnauf/nsca"
|
||||||
gem.license = "LGPL-3"
|
gem.license = "MIT"
|
||||||
gem.summary = %Q{Nagios passive alerts with friendly API}
|
gem.summary = %Q{Nagios passive alerts with friendly API}
|
||||||
gem.description = %Q{Create your alerts easily and send it to Nagios}
|
gem.description = %Q{Create your alerts easily and send it to Nagios}
|
||||||
gem.email = "Denis.Knauf@gmail.com"
|
gem.email = "Denis.Knauf@gmail.com"
|
||||||
|
|
53
lib/nsca.rb
53
lib/nsca.rb
|
@ -18,35 +18,6 @@ module NSCA
|
||||||
clname[0] = clname[0].upcase
|
clname[0] = clname[0].upcase
|
||||||
clname.to_sym
|
clname.to_sym
|
||||||
end
|
end
|
||||||
|
|
||||||
def xor_stream key
|
|
||||||
key = case key
|
|
||||||
when Array then key
|
|
||||||
when String then key.bytes.to_a
|
|
||||||
when Enumerable then key.to_a
|
|
||||||
end
|
|
||||||
return lambda{|x|x} if [nil, '', []].include? key
|
|
||||||
length = key.length
|
|
||||||
i = 0
|
|
||||||
lambda do |str|
|
|
||||||
r = ''
|
|
||||||
str.bytes.each_with_index do |c, j|
|
|
||||||
r[j] = (c ^ key[i]).chr
|
|
||||||
i = (i + 1) % length
|
|
||||||
end
|
|
||||||
r
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def crc32_stream
|
|
||||||
sum = 0xFFFFFFFF
|
|
||||||
lambda do |str|
|
|
||||||
sum = str.bytes.inject sum do |r, b|
|
|
||||||
8.times.inject( r^b) {|r,_i| (r>>1) ^ (0xEDB88320 * (r&1)) }
|
|
||||||
end if str
|
|
||||||
sum ^ 0xFFFFFFFF
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -57,30 +28,6 @@ module NSCA
|
||||||
NSCA.destinations.each {|server| server.send *results }
|
NSCA.destinations.each {|server| server.send *results }
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
def xor key, msg = nil, key_a = nil
|
|
||||||
NSCA::Helper.xor_stream( key_a || key)[ msg]
|
|
||||||
end
|
|
||||||
|
|
||||||
def crc32 msg
|
|
||||||
NSCA::Helper.crc32_stream[ msg]
|
|
||||||
end
|
|
||||||
|
|
||||||
# Builds a null terminated, null padded string of length maxlen
|
|
||||||
def str2cstr str, maxlen = nil
|
|
||||||
str = str.to_s
|
|
||||||
str = str.to_s[0..(maxlen-2)] if maxlen
|
|
||||||
"#{str}\x00"
|
|
||||||
end
|
|
||||||
def rand_padding( str, maxlen) str + SecureRandom.random_bytes( maxlen - str.length) end
|
|
||||||
def str2cstr_rand_padding( str, maxlen = nil) rand_padding str2cstr( str, maxlen), maxlen end
|
|
||||||
def str2nstr str, maxlen = nil
|
|
||||||
str = str.to_s.gsub ' ', "\x00"
|
|
||||||
"#{str} "
|
|
||||||
end
|
|
||||||
def str2nstr_rand_padding( str, maxlen = nil) rand_padding str2nstr( str, maxlen), maxlen end
|
|
||||||
def cstr2str( str, maxlen = nil) str[ 0, str.index( ?\0) || ((maxlen||str.length+1)-1)] end
|
|
||||||
def nstr2str( str, maxlen = nil) str[ 0, str.index( ' ') || ((maxlen||str.length+1)-1)].gsub( "\x00", ' ') end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,45 +1,29 @@
|
||||||
module NSCA
|
module NSCA
|
||||||
module PerformanceData
|
module PerformanceData
|
||||||
class TimeUnitExpected < Exception
|
|
||||||
end
|
|
||||||
|
|
||||||
class Base
|
class Base
|
||||||
extend Timeout
|
extend Timeout
|
||||||
extend Benchmark
|
extend Benchmark
|
||||||
|
|
||||||
class <<self
|
class <<self
|
||||||
attr_reader :label, :unit, :warn, :crit, :min, :max
|
attr_reader :label, :unit, :warn, :crit, :min, :max
|
||||||
def init *args
|
def init label, unit = nil, warn = nil, crit = nil, min = nil, max = nil
|
||||||
a, o = args, args.last.is_a?( Hash) ? args.pop : {}
|
@label, @unit, @warn, @crit, @min, @max = label.to_s, unit, warn, crit, min, max
|
||||||
@label, @unit = a[0]||o[:label], a[1]||o[:unit]
|
|
||||||
@warn, @crit = a[2]||o[:warn], a[3]||o[:crit]
|
|
||||||
@min, @max = a[4]||o[:min], a[5]||o[:max]
|
|
||||||
raise ArgumentError, "Label expected" unless @label
|
|
||||||
@label = @label.to_s
|
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
def measure &block
|
def measure &block
|
||||||
f = case unit.to_s.to_sym
|
timeout ||= 0
|
||||||
when :s then 1
|
exception = Class.new Timeout::Error
|
||||||
when :ms then 1000
|
pd = perfdatas[perfdata_label.to_sym]
|
||||||
else raise TimeUnitExpected, "Unit must be seconds (s) or miliseconds (ms) not (#{unit})"
|
timeout = pd.max
|
||||||
end
|
|
||||||
exception = ::Class.new Timeout::Error
|
|
||||||
timeout = max
|
|
||||||
m = realtime do
|
m = realtime do
|
||||||
begin
|
begin
|
||||||
timeout timeout, exception, &block
|
timeout timeout, exception, &block
|
||||||
rescue exception
|
rescue exception
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
new f * m
|
new m
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_sym() label.to_sym end
|
|
||||||
def to_h() {label: @label, unit: @unit, warn: @warn, crit: @crit, min: @min, max: @max } end
|
|
||||||
def to_a() [label, unit, warn, crit, min, max] end
|
|
||||||
def clone( opts = nil) ::Class.new( self).init opts ? to_h.merge( opts) : to_h end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_reader :value
|
attr_reader :value
|
||||||
|
@ -50,13 +34,8 @@ module NSCA
|
||||||
def crit() self.class.crit end
|
def crit() self.class.crit end
|
||||||
def min() self.class.min end
|
def min() self.class.min end
|
||||||
def max() self.class.max end
|
def max() self.class.max end
|
||||||
def to_a() [label, value, unit, warn, crit, min, max] end
|
def to_s() "#{label}=#{value}#{unit},#{warn},#{crit},#{min},#{max}" end
|
||||||
def to_s() "'#{label.gsub /[\n'\|]/, ''}'=#{value}#{unit},#{warn},#{crit},#{min},#{max}" end
|
def to_sym() self.class.label.to_sym end
|
||||||
def to_sym() self.class.to_sym end
|
|
||||||
|
|
||||||
def to_h
|
|
||||||
{label: @label, value: @value, unit: @unit, warn: @warn, crit: @crit, min: @min, max: @max}
|
|
||||||
end
|
|
||||||
|
|
||||||
def return_code
|
def return_code
|
||||||
if @value.nil? then 3
|
if @value.nil? then 3
|
||||||
|
@ -68,9 +47,13 @@ module NSCA
|
||||||
end
|
end
|
||||||
|
|
||||||
class <<self
|
class <<self
|
||||||
def new( *args) ::Class.new( Base).init *args end
|
def new label, unit = nil, warn = nil, crit = nil, min = nil, max = nil
|
||||||
def create label, *args
|
cl = Class.new Base
|
||||||
cl = new label, *args
|
cl.init label, unit, warn, crit, min, max
|
||||||
|
end
|
||||||
|
|
||||||
|
def create label, unit = nil, warn = nil, crit = nil, min = nil, max = nil
|
||||||
|
cl = new label, unit, warn, crit, min, max
|
||||||
clname = NSCA::Helper.class_name_gen label
|
clname = NSCA::Helper.class_name_gen label
|
||||||
self.const_set clname, cl if clname
|
self.const_set clname, cl if clname
|
||||||
cl
|
cl
|
||||||
|
@ -80,10 +63,8 @@ module NSCA
|
||||||
|
|
||||||
module Check
|
module Check
|
||||||
class Base
|
class Base
|
||||||
attr_accessor :return_code, :status, :timestamp
|
attr_reader :perfdatas, :return_code, :status, :timestamp
|
||||||
attr_reader :perfdatas
|
def initialize return_code = nil, status = nil, perfdatas = nil
|
||||||
|
|
||||||
def initialize return_code = nil, status = nil, perfdatas = nil, timestamp = nil
|
|
||||||
@perfdatas = {}
|
@perfdatas = {}
|
||||||
init return_code, status, perfdatas, timestamp || Time.now
|
init return_code, status, perfdatas, timestamp || Time.now
|
||||||
end
|
end
|
||||||
|
@ -107,47 +88,59 @@ module NSCA
|
||||||
end
|
end
|
||||||
|
|
||||||
def push *perfdatas
|
def push *perfdatas
|
||||||
perfdatas.each {|perfdata| @perfdatas[perfdata.label.to_sym] = perfdata }
|
perfdatas.each {|perfdata| @perfdatas[perfdata.label] = perfdata }
|
||||||
@perfdatas
|
@perfdatas
|
||||||
end
|
end
|
||||||
|
|
||||||
def perfdata_for label
|
|
||||||
if label.is_a? PerformanceData::Base
|
|
||||||
label
|
|
||||||
else
|
|
||||||
label = label.to_sym
|
|
||||||
self.class.perfdatas[label] || PerformanceData::Base.new( label)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def []= perfdata_label, value
|
def []= perfdata_label, value
|
||||||
return push value if value.is_a? PerformanceData::Base
|
return push value if value.is_a? PerformanceData::Base
|
||||||
perfdata_label = perfdata_label.to_sym
|
perfdata_label = perfdata_label.to_sym
|
||||||
@perfdatas[perfdata_label] = perfdata_for( perfdata_label).new value
|
cl = self.class.perfdatas[perfdata_label]
|
||||||
|
cl ||= PerformanceData::Base.new perfdata_label
|
||||||
|
@perfdatas[perfdata_label] = cl.new value
|
||||||
end
|
end
|
||||||
|
|
||||||
def text
|
def text
|
||||||
r = "#{status || ReturnCode.find(retcode)}"
|
r = "#{status || ReturnCode.find(return_code)}"
|
||||||
r += " | #{perfdatas.each_value.map( &:to_s).join ' '}" unless perfdatas.empty?
|
r += " | #{perfdatas.each_value.map( &:to_s).join ' '}" unless perfdatas.empty?
|
||||||
r
|
r
|
||||||
end
|
end
|
||||||
|
|
||||||
def measure perfdata_label, &block
|
def measure perfdata_label, &block
|
||||||
push perfdata_for( perfdata_label).measure( &block)
|
@perfdatas[perfdata_label.to_sym].measure &block
|
||||||
end
|
end
|
||||||
def send() NSCA::send self end
|
def send() NSCA::send self end
|
||||||
|
|
||||||
def ok( *args) init ReturnCode::OK, *args end
|
def ok status = nil, perfdatas = nil
|
||||||
def warning( *args) init ReturnCode::WARNING, *args end
|
init ReturnCode::OK, status, perfdatas
|
||||||
|
send
|
||||||
|
end
|
||||||
|
|
||||||
|
def warning status = nil, perfdatas = nil
|
||||||
|
init ReturnCode::WARNING, status, perfdatas
|
||||||
|
send
|
||||||
|
end
|
||||||
alias warn warning
|
alias warn warning
|
||||||
def critical( *args) init ReturnCode::CRITICAL, *args end
|
|
||||||
|
def critical status = nil, perfdatas = nil
|
||||||
|
init ReturnCode::CRITICAL, status, perfdatas
|
||||||
|
send
|
||||||
|
end
|
||||||
alias crit critical
|
alias crit critical
|
||||||
def unknown( *args) init ReturnCode::UNKNOWN, *args end
|
|
||||||
|
def unknown status = nil, perfdatas = nil
|
||||||
|
init ReturnCode::UNKNOWN, status, perfdatas
|
||||||
|
send
|
||||||
|
end
|
||||||
|
|
||||||
def determine_return_code
|
def determine_return_code
|
||||||
self.class.perfdatas.map do |label, pdc|
|
self.class.perfdatas.map do |label, pdc|
|
||||||
pd = @perfdatas[label]
|
pd = @perfdatas[label]
|
||||||
pd ? pd.return_code : -1
|
if pd
|
||||||
|
pd.return_code
|
||||||
|
else
|
||||||
|
-1
|
||||||
|
end
|
||||||
end.max
|
end.max
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -158,24 +151,12 @@ module NSCA
|
||||||
|
|
||||||
def service() self.class.service end
|
def service() self.class.service end
|
||||||
def hostname() self.class.hostname end
|
def hostname() self.class.hostname end
|
||||||
def to_a() [timestamp, retcode, hostname, service, text] end
|
|
||||||
def to_h
|
|
||||||
{timestamp: timestamp, return_code: retcode, hostname: hostname, server: service, status: text}
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_packet version = nil
|
|
||||||
version ||= PacketV3
|
|
||||||
version.new timestamp, retcode, hostname, service, text
|
|
||||||
end
|
|
||||||
|
|
||||||
class <<self
|
class <<self
|
||||||
attr_reader :service, :hostname, :perfdatas
|
attr_reader :service, :hostname, :perfdatas
|
||||||
def init *args
|
def init service, hostname = nil, perfdatas = nil
|
||||||
a, o = args, args.last.is_a?( Hash) ? args.pop : {}
|
@service, @hostname, @perfdatas = service, hostname || `hostname -f`, {}
|
||||||
service, hostname = nil, perfdatas = nil
|
perfdatas.each {|pd| @perfdatas[pd.label.to_sym] = pd }
|
||||||
@service, @hostname, @perfdatas = a[0]||o[:service], a[1]||o[:hostname]||`hostname`.chomp, {}
|
|
||||||
perfdatas = a[2]||o[:perfdatas]
|
|
||||||
perfdatas.each {|pd| @perfdatas[pd.to_sym] = pd } if perfdatas
|
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -185,23 +166,18 @@ module NSCA
|
||||||
def critical( status = nil, perfdatas = nil) new.warning status, perfdatas end
|
def critical( status = nil, perfdatas = nil) new.warning status, perfdatas end
|
||||||
alias crit critical
|
alias crit critical
|
||||||
def unknown( status = nil, perfdatas = nil) new.unknown status, perfdatas end
|
def unknown( status = nil, perfdatas = nil) new.unknown status, perfdatas end
|
||||||
|
|
||||||
def to_a() [service, hostname, perfdatas.dup] end
|
|
||||||
def to_h() {service: service, hostname: hostname, perfdatas: perfdatas.values} end
|
|
||||||
def to_sym() "#{hostname}|#{service}".to_sym end
|
|
||||||
def clone( opts = nil) ::Class.new( self).init opts ? to_h.merge( opts) : to_h end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class <<self
|
class <<self
|
||||||
def new service, hostname = nil, perfdatas = nil
|
def create service, hostname = nil, perfdatas = nil
|
||||||
cl = Class.new Base
|
cl = Class.new Base
|
||||||
cl.init service, hostname, perfdatas
|
cl.init service, hostname, perfdatas
|
||||||
cl
|
cl
|
||||||
end
|
end
|
||||||
|
|
||||||
def create service, hostname = nil, perfdatas = nil
|
def new service, hostname = nil, perfdatas = nil
|
||||||
cl = new service, hostname, perfdatas
|
cl = create service, hostname, perfdatas
|
||||||
clname = NSCA::Helper.class_name_gen service.to_s
|
clname = NSCA::Helper.class_name_gen service.to_s
|
||||||
self.const_set clname, cl if clname
|
self.const_set clname, cl if clname
|
||||||
cl
|
cl
|
||||||
|
@ -210,12 +186,12 @@ module NSCA
|
||||||
end
|
end
|
||||||
|
|
||||||
module Checks
|
module Checks
|
||||||
def perfdata( *params) NSCA::PerformanceData.new( *params) end
|
def perfdata( cl, *params) const_set cl, NSCA::PerformanceData.new( *params) end
|
||||||
|
|
||||||
def check service, hostname, perfdatas = nil
|
def check cl, service, hostname, perfdatas = nil
|
||||||
perfdatas ||= []
|
perfdatas ||= []
|
||||||
perfdatas.map! {|cl| cl.is_a?( Symbol) ? const_get( cl) : cl }
|
perfdatas.map! {|cl| cl.is_a?( Symbol) ? const_get( cl) : cl }
|
||||||
NSCA::Check.new service, hostname, perfdatas
|
const_set cl, NSCA::Check.new( service, hostname, perfdatas)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -61,26 +61,19 @@ module NSCA
|
||||||
# @param [String(length<512)] status Status-line inclusive optional Performance Data.
|
# @param [String(length<512)] status Status-line inclusive optional Performance Data.
|
||||||
def build_packet timestamp, return_code, hostname, service, status
|
def build_packet timestamp, return_code, hostname, service, status
|
||||||
packet = @packet_version.new timestamp || @timestamp, return_code, hostname, service, status
|
packet = @packet_version.new timestamp || @timestamp, return_code, hostname, service, status
|
||||||
packet.build
|
packet.build @iv_key, @password
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sends a check-result.
|
# Sends a check-result.
|
||||||
# @see #build_packet
|
# @see #build_packet
|
||||||
def send_packet( *a)
|
def send_packet( *a) @socket.write build_packet( *a) end
|
||||||
packet = case a.first
|
|
||||||
when NSCA::Packet then a.first.build
|
|
||||||
when NSCA::Check::Base then a.first.to_packet( @packet_version).build
|
|
||||||
else build_packet( *a)
|
|
||||||
end
|
|
||||||
packet = NSCA::xor @iv_key, packet
|
|
||||||
packet = NSCA::xor @password, packet
|
|
||||||
@socket.write packet
|
|
||||||
end
|
|
||||||
|
|
||||||
# Sends check-results
|
# Sends check-results
|
||||||
# @param [Array<NSCA::Check::Base>] results
|
# @param [Array<NSCA::Check::Base>] results
|
||||||
def send *results
|
def send *results
|
||||||
results.flatten.each &method(:send_packet)
|
results.flatten.each do |r|
|
||||||
|
send_packet r.timestamp, r.retcode, r.hostname, r.service, r.text
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Closes connection to NSCA.
|
# Closes connection to NSCA.
|
||||||
|
@ -92,7 +85,7 @@ module NSCA
|
||||||
@hostname, @port, @password = hostname, port, password
|
@hostname, @port, @password = hostname, port, password
|
||||||
end
|
end
|
||||||
|
|
||||||
def open( &e) Connection.open hostname: @hostname, port: @port, password: @password, &e end
|
def open( &e) Connection.open @hostname, @port, @password, &e end
|
||||||
def send( *results) open {|conn| conn.send results } end
|
def send( *results) open {|conn| conn.send results } end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,29 @@
|
||||||
module NSCA
|
module NSCA
|
||||||
|
class <<self
|
||||||
|
def xor key, msg, key_a = nil
|
||||||
|
key_a ||= key.unpack 'C*'
|
||||||
|
l = key_a.length
|
||||||
|
return msg if l < 1
|
||||||
|
# Slice the message in parts of length key_a.length.
|
||||||
|
# XOR each char of a part with char at the same index in key_a.
|
||||||
|
msg.unpack( 'C*').each_with_index.map {|c,i| c^key_a[i%l] }.pack 'C*'
|
||||||
|
end
|
||||||
|
|
||||||
|
def crc32 msg
|
||||||
|
(msg.each_byte.inject 0xFFFFFFFF do |r,b|
|
||||||
|
8.times.inject( r^b) {|r,_i| (r>>1) ^ (0xEDB88320 * (r&1)) }
|
||||||
|
end) ^ 0xFFFFFFFF
|
||||||
|
end
|
||||||
|
|
||||||
|
# Builds a null terminated, null padded string of length maxlen
|
||||||
|
def str2cstr( str, maxlen = nil)
|
||||||
|
str = str.to_s
|
||||||
|
str = str.to_s[0..(maxlen-2)] if maxlen
|
||||||
|
"#{str}\x00"
|
||||||
|
end
|
||||||
|
def cstr2str( str, maxlen = nil) str[ 0, x.index( ?\0) || ((maxlen||0)-1)] end
|
||||||
|
end
|
||||||
|
|
||||||
class Packet
|
class Packet
|
||||||
class CSC32CheckFailed <Exception
|
class CSC32CheckFailed <Exception
|
||||||
end
|
end
|
||||||
|
@ -32,7 +57,7 @@ module NSCA
|
||||||
END_OF_TRANSMISSION = ?\x0a
|
END_OF_TRANSMISSION = ?\x0a
|
||||||
HOSTNAME_LENGTH = 64
|
HOSTNAME_LENGTH = 64
|
||||||
SERVICE_LENGTH = 128
|
SERVICE_LENGTH = 128
|
||||||
PLUGIN_OUTPUT_LENGTH = 512
|
STATUS_LENGTH = 512
|
||||||
|
|
||||||
# these line describes the data package:
|
# these line describes the data package:
|
||||||
# typedef struct data_packet_struct{
|
# typedef struct data_packet_struct{
|
||||||
|
@ -46,54 +71,41 @@ module NSCA
|
||||||
# char plugin_output[MAX_PLUGINOUTPUT_LENGTH];
|
# char plugin_output[MAX_PLUGINOUTPUT_LENGTH];
|
||||||
# /* two extra padding-xx, too. */
|
# /* two extra padding-xx, too. */
|
||||||
# }data_packet;
|
# }data_packet;
|
||||||
PACK_STRING = "s> xx L> L> s> A#{HOSTNAME_LENGTH} A#{SERVICE_LENGTH} A#{PLUGIN_OUTPUT_LENGTH} xx"
|
PACK_STRING = "s> xx L> L> s> Z#{HOSTNAME_LENGTH} Z#{SERVICE_LENGTH} Z#{STATUS_LENGTH} xx"
|
||||||
PACK_LENGTH = 2+2+4+4+2+HOSTNAME_LENGTH+SERVICE_LENGTH+PLUGIN_OUTPUT_LENGTH+2
|
PACK_LENGTH = 2+2+4+4+2+HOSTNAME_LENGTH+SERVICE_LENGTH+STATUS_LENGTH+2
|
||||||
register_version PACKET_VERSION, self
|
register_version PACKET_VERSION, self
|
||||||
|
|
||||||
# Builds a check-result-line for NSCA.
|
# Builds a check-result-line for NSCA.
|
||||||
#
|
#
|
||||||
# Will be terminated by end-of-terminate.
|
# Will be terminated by end-of-terminate.
|
||||||
def build slf = nil
|
def build key = nil, password = nil
|
||||||
cl = (slf || self).class
|
|
||||||
entry = [
|
entry = [
|
||||||
cl::PACKET_VERSION,
|
PACKET_VERSION,
|
||||||
0, # crc32 (unknown yet)
|
0, # crc32 (unknown yet)
|
||||||
(timestamp || Time.now).to_i,
|
(timestamp || Time.now).to_i,
|
||||||
return_code.to_i,
|
return_code.to_i,
|
||||||
NSCA::str2cstr_rand_padding( hostname || `hostname -f`, cl::HOSTNAME_LENGTH),
|
NSCA::str2cstr( hostname || `hostname -f`, HOSTNAME_LENGTH),
|
||||||
NSCA::str2cstr_rand_padding( service, cl::SERVICE_LENGTH),
|
NSCA::str2cstr( service, SERVICE_LENGTH),
|
||||||
NSCA::str2cstr_rand_padding( status, cl::PLUGIN_OUTPUT_LENGTH) # incl perfdata
|
NSCA::str2cstr( status, STATUS_LENGTH) # incl perfdata
|
||||||
]
|
]
|
||||||
# generate crc32 and put it at entry[2...6]
|
# generate crc32 and put it at entry[2...6]
|
||||||
entry[1] = NSCA::crc32 entry.pack( cl::PACK_STRING)
|
entry[1] = NSCA::crc32 entry.pack( PACK_STRING)
|
||||||
entry = entry.pack cl::PACK_STRING
|
entry = entry.pack PACK_STRING
|
||||||
|
entry = NSCA::xor key, entry if key
|
||||||
|
entry = NSCA::xor password, entry if password
|
||||||
entry
|
entry
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.parse entry, no_verification_checks = nil
|
def self.parse entry, key = nil, password = nil, no_verification_checks = nil
|
||||||
entry = entry.to_s.dup
|
entry = NSCA::xor key, entry if key
|
||||||
|
entry = NSCA::xor password, entry if password
|
||||||
ver, crc32sum, *x = entry.unpack( PACK_STRING)
|
ver, crc32sum, *x = entry.unpack( PACK_STRING)
|
||||||
x[2] = NSCA::cstr2str x[2]
|
|
||||||
x[3] = NSCA::cstr2str x[3]
|
|
||||||
x[4] = NSCA::cstr2str x[4]
|
|
||||||
raise VersionCheckFailed, "Packet version 3 expected. (recv: #{ver})" \
|
raise VersionCheckFailed, "Packet version 3 expected. (recv: #{ver})" \
|
||||||
unless no_verification_checks or 3 == ver
|
unless no_verification_checks or 3 == ver
|
||||||
entry[4..7] = ?\x00*4
|
entry[4..7] = ?\x00*4
|
||||||
crc32 = NSCA::crc32 entry
|
raise CSC32CheckFailed, "crc32-check failed. packet seems to be broken." \
|
||||||
raise CSC32CheckFailed, "crc32-check failed. packet seems to be broken: #{crc32sum.inspect} != #{crc32.inspect}" \
|
unless no_verification_checks or crc32sum == NSCA::crc32( entry)
|
||||||
unless no_verification_checks or crc32sum == crc32
|
|
||||||
new *x
|
new *x
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class PacketV3__2_9 < PacketV3
|
|
||||||
NAGIOS_VERSION = 2.7
|
|
||||||
PACKET_VERSION = 3
|
|
||||||
END_OF_TRANSMISSION = ?\x0a
|
|
||||||
PLUGIN_OUTPUT_LENGTH = 4096
|
|
||||||
HOSTNAME_LENGTH = 64
|
|
||||||
SERVICE_LENGTH = 128
|
|
||||||
PACK_STRING = "s> xx L> L> s> A#{HOSTNAME_LENGTH} A#{SERVICE_LENGTH} A#{PLUGIN_OUTPUT_LENGTH} xx"
|
|
||||||
PACK_LENGTH = 2+2+4+4+2+HOSTNAME_LENGTH+SERVICE_LENGTH+PLUGIN_OUTPUT_LENGTH+2
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,12 +2,12 @@ module NSCA
|
||||||
class Server
|
class Server
|
||||||
include Enumerable
|
include Enumerable
|
||||||
|
|
||||||
attr_reader :iv_key, :server, :packet_version, :password, :xor_iv_key, :xor_password
|
attr_reader :iv_key, :server, :packet_version, :password
|
||||||
def initialize *args
|
def initialize *args
|
||||||
opts = {}
|
opts = {}
|
||||||
opts = args.pop.dup if args.last.is_a? Hash
|
opts = args.pop.dup if args.last.is_a? Hash
|
||||||
opts[:host] ||= opts[:hostname]
|
opts[:host] ||= opts[:hostname]
|
||||||
opts[:serv] ||= opts[:server]
|
opts[:sock] ||= opts[:socket]
|
||||||
opts[:pass] ||= opts[:password]
|
opts[:pass] ||= opts[:password]
|
||||||
|
|
||||||
case args[0]
|
case args[0]
|
||||||
|
@ -15,7 +15,7 @@ module NSCA
|
||||||
opts[:port] = args[0]
|
opts[:port] = args[0]
|
||||||
opts[:host] ||= args[1]
|
opts[:host] ||= args[1]
|
||||||
when IO
|
when IO
|
||||||
opts[:serv] = args[0]
|
opts[:sock] = args[0]
|
||||||
end
|
end
|
||||||
|
|
||||||
@packet_version = opts[:packet_version] || PacketV3
|
@packet_version = opts[:packet_version] || PacketV3
|
||||||
|
@ -25,7 +25,7 @@ module NSCA
|
||||||
@server = if opts[:serv].is_a?( TCPServer) or opts[:serv].is_a?( UNIXServer)
|
@server = if opts[:serv].is_a?( TCPServer) or opts[:serv].is_a?( UNIXServer)
|
||||||
opts[:serv]
|
opts[:serv]
|
||||||
elsif opts[:port].is_a? Integer
|
elsif opts[:port].is_a? Integer
|
||||||
TCPServer.new *[opts[:host], opts[:port]].compact
|
TCPServer.new *[opts[:port], opts[:host]].compact
|
||||||
else
|
else
|
||||||
raise ArgumentError, "Server or port-number expected"
|
raise ArgumentError, "Server or port-number expected"
|
||||||
end
|
end
|
||||||
|
@ -50,36 +50,22 @@ module NSCA
|
||||||
@packet_version = server.packet_version
|
@packet_version = server.packet_version
|
||||||
@packet_length = @packet_version::PACK_LENGTH
|
@packet_length = @packet_version::PACK_LENGTH
|
||||||
@socket.write [@iv_key, Time.now.to_i].pack( 'a* L>')
|
@socket.write [@iv_key, Time.now.to_i].pack( 'a* L>')
|
||||||
@xor_password = NSCA::Helper.xor_stream @password
|
|
||||||
@xor_iv_key = NSCA::Helper.xor_stream @iv_key
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch
|
def fetch
|
||||||
iv_key = NSCA::Helper.xor_stream @iv_key
|
data = read
|
||||||
password = NSCA::Helper.xor_stream @password
|
@packet_version.parse data, @iv_key, @password if data
|
||||||
packet_version = iv_key[ password[ read PacketV3::PACKET_VERSION]]
|
|
||||||
v = packet_version.unpack( 's>').first
|
|
||||||
case v
|
|
||||||
when 3
|
|
||||||
data = packet_version + iv_key[ password[ read( PacketV3::PACK_LENGTH - PacketV3::PACKET_VERSION)]]
|
|
||||||
begin
|
|
||||||
return PacketV3.parse( data)
|
|
||||||
rescue NSCA::Packet::CSC32CheckFailed
|
|
||||||
x = read( PacketV3__2_9::PACK_LENGTH - data.length)
|
|
||||||
raise if x.nil?
|
|
||||||
return PacketV3__2_9.parse( data + iv_key[ password[ x]])
|
|
||||||
end
|
|
||||||
else raise "Unknown Version #{v.inspect}"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def each &block
|
def each &block
|
||||||
return Enumerator.new( self) unless block_given?
|
return Enumerator.new( self) unless block_given?
|
||||||
yield fetch until eof?
|
while data = fetch
|
||||||
|
yield data
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def eof?() @socket.eof? end
|
def eof?() @socket.eof? end
|
||||||
def read( len = nil) @socket.read( len || @packet_length) end
|
def read() @socket.read @packet_length end
|
||||||
def close() @socket.close end
|
def close() @socket.close end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,11 +5,11 @@
|
||||||
|
|
||||||
Gem::Specification.new do |s|
|
Gem::Specification.new do |s|
|
||||||
s.name = "nsca"
|
s.name = "nsca"
|
||||||
s.version = "0.2.1"
|
s.version = "0.1.1"
|
||||||
|
|
||||||
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
||||||
s.authors = ["Denis Knauf"]
|
s.authors = ["Denis Knauf"]
|
||||||
s.date = "2013-04-24"
|
s.date = "2013-04-09"
|
||||||
s.description = "Create your alerts easily and send it to Nagios"
|
s.description = "Create your alerts easily and send it to Nagios"
|
||||||
s.email = "Denis.Knauf@gmail.com"
|
s.email = "Denis.Knauf@gmail.com"
|
||||||
s.extra_rdoc_files = [
|
s.extra_rdoc_files = [
|
||||||
|
@ -35,7 +35,7 @@ Gem::Specification.new do |s|
|
||||||
"test/test_nsca.rb"
|
"test/test_nsca.rb"
|
||||||
]
|
]
|
||||||
s.homepage = "http://github.com/DenisKnauf/nsca"
|
s.homepage = "http://github.com/DenisKnauf/nsca"
|
||||||
s.licenses = ["LGPL-3"]
|
s.licenses = ["MIT"]
|
||||||
s.require_paths = ["lib"]
|
s.require_paths = ["lib"]
|
||||||
s.rubygems_version = "1.8.23"
|
s.rubygems_version = "1.8.23"
|
||||||
s.summary = "Nagios passive alerts with friendly API"
|
s.summary = "Nagios passive alerts with friendly API"
|
||||||
|
|
|
@ -1,89 +1,35 @@
|
||||||
require 'helper'
|
require 'helper'
|
||||||
require 'dummy_server'
|
|
||||||
require 'securerandom'
|
|
||||||
|
|
||||||
class TestNSCA < Test::Unit::TestCase
|
class TestNSCA < Test::Unit::TestCase
|
||||||
context 'xor' do
|
class TestChecks
|
||||||
should 'return a if a (random) will xored double with random key. (1000 rounds)' do
|
extend NSCA::Checks
|
||||||
1000.times do
|
perfdata :PD1, :pd1_in_sec, :s, 10, 20, 0, 30
|
||||||
key_len = SecureRandom.random_number 1000
|
perfdata :PD2, :pd2_in_1, 1, 0.99, 0.98, 0, 1
|
||||||
a_len = SecureRandom.random_number 1000
|
perfdata :PD3, :pd3_count, :c, 3, 5, 0
|
||||||
key = SecureRandom.random_bytes key_len
|
check :T0, 'TestNSCA0', 'uxnags01-sbe.net.mobilkom.at'
|
||||||
a = SecureRandom.random_bytes a_len
|
check :T1, 'TestNSCA1', 'uxnags01-sbe.net.mobilkom.at', [PD1, PD2]
|
||||||
assert_equal a, NSCA.xor( key, NSCA.xor(key, a))
|
check :T2, :TestNSCA2, 'uxnags01-sbe.net.mobilkom.at', [PD1, PD2, PD3]
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class TestNSCACommunication < Test::Unit::TestCase
|
context 'our test server' do
|
||||||
Port = 5787
|
should 'receive data. NSCA-server should run on localhost 5777. if not, ignore this test. password=abcdefghijkl' do
|
||||||
def dummy_server *args
|
PD1 = TestChecks::PD1
|
||||||
server = Thread.new do
|
PD2 = TestChecks::PD2
|
||||||
begin
|
PD3 = TestChecks::PD3
|
||||||
NSCA.dummy_server *args
|
T0 = TestChecks::T0
|
||||||
rescue Object
|
T1 = TestChecks::T1
|
||||||
#STDERR.puts "#{$!.class}: #{$!}", $!.backtrace.map{|bt|" #{bt}"}
|
T2 = TestChecks::T2
|
||||||
raise
|
|
||||||
ensure
|
|
||||||
#STDERR.puts "Dummy Server Shutdown"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
sleep 1 # server needs time to start...
|
|
||||||
server
|
|
||||||
end
|
|
||||||
|
|
||||||
include NSCA::Checks
|
|
||||||
|
|
||||||
context "our dummy test server on localhost:#{Port} with random password" do
|
|
||||||
should 'receive data' do
|
|
||||||
password = 'password' || SecureRandom.random_bytes
|
|
||||||
timestamp = Time.now
|
|
||||||
|
|
||||||
PD1 = perfdata :pd1_in_sec, :s, 10, 20, 0, 30
|
|
||||||
PD2 = perfdata :pd2_in_1, 1, 0.99, 0.98, 0, 1
|
|
||||||
PD3 = perfdata :pd3_count, :c, 3, 5, 0
|
|
||||||
T0 = check 'TestNSCA0', 'localhost'
|
|
||||||
T1 = check 'TestNSCA1', 'localhost', [PD1, PD2]
|
|
||||||
T2 = check :TestNSCA2, 'localhost', [PD1, PD2, PD3]
|
|
||||||
|
|
||||||
checks = []
|
checks = []
|
||||||
t0 = T0.new( 1, "0123456789"*51+"AB", nil, timestamp) # oversized service name
|
checks << TestChecks::T0.new( 1, "0123456789"*51+"AB")
|
||||||
checks << t0
|
|
||||||
|
|
||||||
pd1 = PD1.new 3
|
pd1 = PD1.new 3
|
||||||
pd2 = PD2.new 0.9996
|
pd2 = PD2.new 0.9996
|
||||||
pd3 = PD3.new 2
|
pd3 = PD3.new 2
|
||||||
t1 = T1.new( nil, "Should be OK", [pd1, pd2, pd3], timestamp)
|
checks << TestChecks::T1.new( nil, "Should be OK", [pd1, pd2, pd3])
|
||||||
checks << t1
|
|
||||||
|
|
||||||
NSCA::destinations.clear
|
NSCA::destinations << NSCA::Client.new( 'localhost', 5667, password: 'abcdefghijkl')
|
||||||
NSCA::destinations << NSCA::Client.new( 'localhost', Port, password)
|
|
||||||
|
|
||||||
server = dummy_server port: Port, password: password
|
|
||||||
NSCA::send *checks
|
NSCA::send *checks
|
||||||
pc0, pc1 = server.value
|
|
||||||
|
|
||||||
[[t0, pc0], [t1, pc1]].each do |(test, packet)|
|
|
||||||
assert_equal test.hostname, packet.hostname
|
|
||||||
assert_equal test.service, packet.service
|
|
||||||
assert_equal timestamp.to_i, packet.timestamp.to_i
|
|
||||||
assert_equal test.retcode, packet.return_code
|
|
||||||
end
|
|
||||||
# original with AB, but B is char 512 and will be replaced by \0
|
|
||||||
assert_equal "0123456789"*51+"A", pc0.status
|
|
||||||
assert_equal "Should be OK | 'pd1_in_sec'=3s,10,20,0,30 'pd2_in_1'=0.99961,0.99,0.98,0,1 'pd3_count'=2c,3,5,0,", pc1.status
|
|
||||||
end
|
|
||||||
|
|
||||||
should 'fail crc32 if wrong password' do
|
|
||||||
password = 'password' || SecureRandom.random_bytes
|
|
||||||
timestamp = Time.now
|
|
||||||
T3 = check 'TestNSCA0', 'localhost'
|
|
||||||
NSCA::destinations.clear
|
|
||||||
NSCA::destinations << NSCA::Client.new( 'localhost', Port, password+'a')
|
|
||||||
server = dummy_server hostname: 'localhost', port: Port, password: password
|
|
||||||
NSCA::send [T3.new( 1, 'status', nil, timestamp)]
|
|
||||||
assert_raise( NSCA::Packet::CSC32CheckFailed) { server.join }
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -123,14 +69,8 @@ class TestNSCA::PerformanceData < Test::Unit::TestCase
|
||||||
|
|
||||||
context 'Created NSCA::PerformanceData-subclasses' do
|
context 'Created NSCA::PerformanceData-subclasses' do
|
||||||
should 'be the same like returned' do
|
should 'be the same like returned' do
|
||||||
PA = NSCA::PerformanceData.create 'returned and subclass the same test'
|
cl = NSCA::PerformanceData.create 'returned and subclass the same test'
|
||||||
assert_equal PA, NSCA::PerformanceData::Returned_and_subclass_the_same_test
|
assert cl == NSCA::PerformanceData::Returned_and_subclass_the_same_test, 'Classes are not the same.'
|
||||||
end
|
|
||||||
should 'not exists, if #new used' do
|
|
||||||
pb = NSCA::PerformanceData.new 'no subclass'
|
|
||||||
assert_raise NameError do
|
|
||||||
NSCA::PerformanceData::No_subclass
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
should 'have a unit if given' do
|
should 'have a unit if given' do
|
||||||
assert :s == perfdata( 'have an unit test', :s).unit, "Not s as unit"
|
assert :s == perfdata( 'have an unit test', :s).unit, "Not s as unit"
|
||||||
|
@ -145,110 +85,11 @@ class TestNSCA::PerformanceData < Test::Unit::TestCase
|
||||||
assert nil == perfdata( 'have not a warn test', nil, nil).warn, "Not nil as warn"
|
assert nil == perfdata( 'have not a warn test', nil, nil).warn, "Not nil as warn"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'Measure' do
|
|
||||||
should 'work with s' do
|
|
||||||
PC = perfdata 'something in seconds', :s
|
|
||||||
assert PC.measure { true }.is_a?( PC), 'can not be created?'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
should 'work with ms' do
|
|
||||||
PD = perfdata 'something in mili seconds', :ms
|
|
||||||
assert PD.measure { true }.is_a?( PD), 'can not be created?'
|
|
||||||
end
|
|
||||||
|
|
||||||
should 'not work with something else' do
|
class TestNSCA::Client < Test::Unit::TestCase
|
||||||
PE = perfdata 'something else than time', :c
|
should '' do
|
||||||
assert_raise NSCA::PerformanceData::TimeUnitExpected do
|
NSCA::Client
|
||||||
PE.measure { true }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
should 'measure something between 1s..3s if i sleep 2 seconds' do
|
|
||||||
PF = perfdata 'wait 2 seconds', :s
|
|
||||||
pf = PF.measure { sleep 2 }
|
|
||||||
assert (1..3).include?( pf.value), "Not in range 1s..3s: #{pf.value}s"
|
|
||||||
end
|
|
||||||
|
|
||||||
should 'measure something between 1000ms..3000ms if i sleep 2 seconds' do
|
|
||||||
PG = perfdata 'wait 2000 mili second', :ms
|
|
||||||
pf = PG.measure { sleep 2 }
|
|
||||||
assert (1000..3000).include?( pf.value), "Not in range 1000ms..3000ms: #{pf.value}ms"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class TestNSCA::Check < Test::Unit::TestCase
|
|
||||||
context 'Data' do
|
|
||||||
should 'also be empty' do
|
|
||||||
CF = NSCA::Check.new 'empty data'
|
|
||||||
cf = CF.new
|
|
||||||
hostname = `hostname`.chomp
|
|
||||||
assert_equal [cf.timestamp, 3, hostname, 'empty data', 'UNKNOWN'], cf.to_a
|
|
||||||
end
|
|
||||||
|
|
||||||
should 'have default a timestamp. ~ -10s..10s' do
|
|
||||||
CG = NSCA::Check.new 'default timestamp'
|
|
||||||
cg = CG.new
|
|
||||||
now = Time.now
|
|
||||||
range = Time.at(now-10) .. Time.at(now+10)
|
|
||||||
assert range.begin <= cg.timestamp && cg.timestamp <= range.end,
|
|
||||||
"Not a valid timestamp ~now: #{cg.timestamp}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'Subclasses' do
|
|
||||||
should 'be created by NSCA::Check.create' do
|
|
||||||
CA = NSCA::Check.create 'a uniq name'
|
|
||||||
assert_same CA, NSCA::Check::A_uniq_name
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'No Subclasses' do
|
|
||||||
should 'be created by NSCA::Check.new' do
|
|
||||||
CB = NSCA::Check.new 'a uniq name, too'
|
|
||||||
assert_raise NameError, 'A class named NSCA::Check::A_uniq_name_too exists' do
|
|
||||||
CB == NSCA::Check::A_uniq_name_too
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'Clones' do
|
|
||||||
should 'have old class as superclass' do
|
|
||||||
CC1 = NSCA::Check.new( 'a check which will be for cloning')
|
|
||||||
CC2 = CC1.clone
|
|
||||||
assert_equal CC2.superclass, CC1
|
|
||||||
end
|
|
||||||
|
|
||||||
should 'have the same data' do
|
|
||||||
CD1 = NSCA::Check.new 'a check for same data after cloning'
|
|
||||||
CD2 = CD1.clone
|
|
||||||
assert_equal CD2.to_a, CD2.to_a
|
|
||||||
end
|
|
||||||
|
|
||||||
should 'have the same data, except specific data' do
|
|
||||||
CE1 = NSCA::Check.new 'a check for same data after cloning again, but...'
|
|
||||||
CE2 = CE1.clone service: '... but the service will be changed.'
|
|
||||||
assert_not_equal CE1.service, CE2.service
|
|
||||||
assert_equal 'a check for same data after cloning again, but...', CE1.service
|
|
||||||
assert_equal '... but the service will be changed.', CE2.service
|
|
||||||
ce1_data, ce2_data = CE1.to_a, CE2.to_a
|
|
||||||
ce1_data[0] = ce2_data[0] = 'dummy'
|
|
||||||
assert_equal ce1_data, ce2_data
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'Perfdatas in Checks' do
|
|
||||||
should 'be saved as symbol-key' do
|
|
||||||
PH = NSCA::PerformanceData.new 'simplename', :ms
|
|
||||||
CH = NSCA::Check.new 'a check with perfdata', 'hostname', [PH]
|
|
||||||
assert_equal PH, CH.perfdatas[:'simplename']
|
|
||||||
ch = CH.new
|
|
||||||
assert_equal nil, ch['simplename']
|
|
||||||
assert_equal nil, ch[:simplename]
|
|
||||||
a = 0
|
|
||||||
ch.measure( 'simplename') { 0.upto( 10000) { a += 1 } }
|
|
||||||
assert_equal ch['simplename'], ch[:simplename]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue