zabbirc 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/zabbirc +32 -0
- data/bin/zabbirc-install +16 -0
- data/config/config.rb +5 -0
- data/lib/zabbirc/configuration.rb +43 -0
- data/lib/zabbirc/irc/plugin.rb +20 -0
- data/lib/zabbirc/irc/plugin_methods.rb +208 -0
- data/lib/zabbirc/logger.rb +45 -0
- data/lib/zabbirc/op.rb +67 -0
- data/lib/zabbirc/op_list.rb +47 -0
- data/lib/zabbirc/priority.rb +38 -0
- data/lib/zabbirc/service.rb +86 -0
- data/lib/zabbirc/services/base.rb +56 -0
- data/lib/zabbirc/services/events.rb +31 -0
- data/lib/zabbirc/services/ops.rb +38 -0
- data/lib/zabbirc/setting.rb +31 -0
- data/lib/zabbirc/stop_error.rb +3 -0
- data/lib/zabbirc/zabbix/connection.rb +26 -0
- data/lib/zabbirc/zabbix/event.rb +94 -0
- data/lib/zabbirc/zabbix/host.rb +6 -0
- data/lib/zabbirc/zabbix/resource/associations.rb +30 -0
- data/lib/zabbirc/zabbix/resource/base.rb +52 -0
- data/lib/zabbirc/zabbix/resource/finders.rb +37 -0
- data/lib/zabbirc/zabbix/trigger.rb +47 -0
- data/lib/zabbirc/zabbix/user.rb +10 -0
- data/lib/zabbirc.rb +24 -0
- data/spec/bot_spec.rb +186 -0
- data/spec/spec_helper.rb +96 -0
- data/spec/support/mock_bot.rb +29 -0
- data/templates/zabbirc_config.rb +14 -0
- data/thread_test.rb +46 -0
- data/tmp/playground.rb +37 -0
- metadata +171 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
module Zabbirc
|
2
|
+
module Services
|
3
|
+
class Events < Base
|
4
|
+
def iterate
|
5
|
+
synchronize do
|
6
|
+
recent_events = Zabbix::Event.recent
|
7
|
+
recent_events = filter_out_repeated_events(recent_events)
|
8
|
+
|
9
|
+
recent_events.each do |event|
|
10
|
+
@service.ops.interested_in(event).notify event
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def filter_out_repeated_events events
|
18
|
+
triggers = events.group_by{|e| e.related_object.id }
|
19
|
+
triggers.collect do |_id, events|
|
20
|
+
events.sort_by{|e| e.created_at }.last
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def send_notifications op, events
|
25
|
+
events.each do |event|
|
26
|
+
op.notify event
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Zabbirc
|
2
|
+
module Services
|
3
|
+
class Ops < Base
|
4
|
+
def iterate
|
5
|
+
synchronize do
|
6
|
+
@cinch_bot.channels.each do |channel|
|
7
|
+
sync_ops channel
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def channel_nicks channel
|
15
|
+
channel.users.keys.collect(&:nick)
|
16
|
+
end
|
17
|
+
|
18
|
+
def channel_find_user channel, nick
|
19
|
+
channel.users.keys.find { |irc_user| irc_user.nick == nick }
|
20
|
+
end
|
21
|
+
|
22
|
+
def sync_ops channel
|
23
|
+
nicks = channel_nicks channel
|
24
|
+
zabbix_users = Zabbix::User.get filter: { alias: nicks }
|
25
|
+
zabbix_users.each do |zabbix_user|
|
26
|
+
irc_user = channel_find_user channel, zabbix_user.alias
|
27
|
+
op = @service.ops.add(Op.new(zabbix_user: zabbix_user, irc_user: irc_user))
|
28
|
+
op.add_channel channel
|
29
|
+
end
|
30
|
+
|
31
|
+
@service.ops.each do |op|
|
32
|
+
op.remove_channel channel unless nicks.include? op.nick
|
33
|
+
end
|
34
|
+
true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Zabbirc
|
2
|
+
class Setting
|
3
|
+
DEFAULTS = {
|
4
|
+
notify: true,
|
5
|
+
primary_channel: nil,
|
6
|
+
events_priority: :information
|
7
|
+
}
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@options = ActiveSupport::HashWithIndifferentAccess.new DEFAULTS.deep_dup
|
11
|
+
end
|
12
|
+
|
13
|
+
def set name, value
|
14
|
+
@options[name] = value
|
15
|
+
end
|
16
|
+
|
17
|
+
def get name
|
18
|
+
@options[name]
|
19
|
+
end
|
20
|
+
|
21
|
+
def fetch name, value
|
22
|
+
@options[name] ||= value
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
@options.collect do |k, v|
|
27
|
+
"#{k}: #{v}"
|
28
|
+
end.join(", ")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'zabbix/client'
|
2
|
+
|
3
|
+
module Zabbirc
|
4
|
+
module Zabbix
|
5
|
+
class Connection
|
6
|
+
attr_reader :client
|
7
|
+
|
8
|
+
def self.get_connection
|
9
|
+
Thread.current[:zabbix_connection] ||= self.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.test_connection
|
13
|
+
self.new
|
14
|
+
true
|
15
|
+
rescue => e
|
16
|
+
Zabbirc.logger.fatal "Could not connect to zabbix: #{e}"
|
17
|
+
false
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
@client = ::Zabbix::Client.new(Zabbirc.config.zabbix_api_url, debug: false)
|
22
|
+
@client.user.login(user: Zabbirc.config.zabbix_login, password: Zabbirc.config.zabbix_password)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Zabbirc
|
2
|
+
module Zabbix
|
3
|
+
class Event < Resource::Base
|
4
|
+
has_many :hosts
|
5
|
+
|
6
|
+
def self.recent options={}
|
7
|
+
params = {
|
8
|
+
acknowledged: false,
|
9
|
+
time_from: Zabbirc.config.notify_about_events_from_last.ago.utc.to_i,
|
10
|
+
priority_from: 0,
|
11
|
+
selectRelatedObject: :extend,
|
12
|
+
selectHosts: :extend
|
13
|
+
}.merge(options)
|
14
|
+
|
15
|
+
priority_from = Priority.new(params.delete(:priority_from))
|
16
|
+
events = get params
|
17
|
+
events = events.find_all{|e| e.priority >= priority_from }
|
18
|
+
events.sort{|x,y| x.priority <=> y.priority }
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_reader :attrs
|
22
|
+
|
23
|
+
delegate :priority, :priority_code, to: :related_object
|
24
|
+
|
25
|
+
def related_object
|
26
|
+
raise AttributeError, "`source` attribute required" if @attrs[:source].blank?
|
27
|
+
raise AttributeError, "`object` attribute required" if @attrs[:object].blank?
|
28
|
+
@related_object ||= determine_related_object
|
29
|
+
end
|
30
|
+
|
31
|
+
def acknowledge message
|
32
|
+
res = api.event.acknowledge(eventids: id, message: message)
|
33
|
+
res["eventids"].collect(&:to_i).include? id.to_i
|
34
|
+
end
|
35
|
+
|
36
|
+
def acknowledged?
|
37
|
+
acknowledged.to_i == 1
|
38
|
+
end
|
39
|
+
|
40
|
+
def created_at
|
41
|
+
Time.at(clock.to_i)
|
42
|
+
end
|
43
|
+
|
44
|
+
def value
|
45
|
+
case @attrs[:source].to_i
|
46
|
+
when 0
|
47
|
+
case @attrs[:value].to_i
|
48
|
+
when 0
|
49
|
+
:ok
|
50
|
+
when 1
|
51
|
+
:problem
|
52
|
+
end
|
53
|
+
else
|
54
|
+
@attrs[:value]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
alias_method :state, :value
|
59
|
+
|
60
|
+
def message
|
61
|
+
desc = related_object.description
|
62
|
+
if desc.include?("{HOST.NAME}")
|
63
|
+
desc.sub("{HOST.NAME}", hosts.collect(&:host).join(', '))
|
64
|
+
else
|
65
|
+
"#{desc} on #{hosts.collect(&:host).join(', ')}"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def label
|
70
|
+
format_label "|%id| %time [%priority-code] %msg - %state"
|
71
|
+
end
|
72
|
+
|
73
|
+
def format_label fmt
|
74
|
+
fmt.gsub("%priority-code", "#{priority.code}").
|
75
|
+
gsub("%priority-num", "#{priority.number}").
|
76
|
+
gsub("%time", "#{created_at.to_formatted_s(:short)}").
|
77
|
+
gsub("%msg", "#{message}").
|
78
|
+
gsub("%id", "#{id}").
|
79
|
+
gsub("%state", "#{state}")
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def determine_related_object
|
85
|
+
case @attrs[:object].to_i
|
86
|
+
when 0
|
87
|
+
@attrs[:relatedObject] ? Trigger.new(@attrs[:relatedObject]) : Trigger.find(@attrs[:objectid])
|
88
|
+
else
|
89
|
+
raise StandardError, "related object #{@attrs[:object].to_i} not implemented yet"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Zabbirc
|
2
|
+
module Zabbix
|
3
|
+
module Resource
|
4
|
+
module Associations
|
5
|
+
def has_many name
|
6
|
+
define_method name do
|
7
|
+
@associations ||= ActiveSupport::HashWithIndifferentAccess.new
|
8
|
+
@associations[name] ||= begin
|
9
|
+
assoc_class = Zabbix.const_get(name.to_s.singularize.camelize)
|
10
|
+
hash_data = @attrs[name]
|
11
|
+
if hash_data.blank?
|
12
|
+
this = self.class.find id, :"select#{name.to_s.camelize}" => :extend
|
13
|
+
raise StandardError, "zabbix response does not contain #{name}" if this[name].blank?
|
14
|
+
hash_data = this[name]
|
15
|
+
end
|
16
|
+
|
17
|
+
hash_data.collect do |obj|
|
18
|
+
assoc_class.new obj
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def has_one name
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require_relative 'finders'
|
2
|
+
require_relative 'associations'
|
3
|
+
|
4
|
+
module Zabbirc
|
5
|
+
module Zabbix
|
6
|
+
|
7
|
+
IDNotUniqueError = Class.new(StandardError)
|
8
|
+
|
9
|
+
module Resource
|
10
|
+
class Base
|
11
|
+
extend Finders, Associations
|
12
|
+
|
13
|
+
def self.set_model_name model_name
|
14
|
+
@model_name = model_name
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.model_name
|
18
|
+
@model_name ||= name.split(/::/).last.underscore
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.api
|
22
|
+
Connection.get_connection.client
|
23
|
+
end
|
24
|
+
|
25
|
+
def api
|
26
|
+
Connection.get_connection.client
|
27
|
+
end
|
28
|
+
|
29
|
+
def initialize attrs
|
30
|
+
@attrs = ActiveSupport::HashWithIndifferentAccess.new attrs
|
31
|
+
raise ArgumentError, "attribute `#{self.class.model_name}id` not found, probably not an Event" unless @attrs.key? :"#{self.class.model_name}id"
|
32
|
+
end
|
33
|
+
|
34
|
+
def id
|
35
|
+
@attrs["#{self.class.model_name}id"]
|
36
|
+
end
|
37
|
+
|
38
|
+
def [] attr
|
39
|
+
@attrs[attr]
|
40
|
+
end
|
41
|
+
|
42
|
+
def method_missing method, *args, &block
|
43
|
+
if args.length == 0 and not block_given? and @attrs.key? method
|
44
|
+
@attrs[method]
|
45
|
+
else
|
46
|
+
super
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Zabbirc
|
2
|
+
module Zabbix
|
3
|
+
module Resource
|
4
|
+
module Finders
|
5
|
+
def find id, *options
|
6
|
+
options = options.extract_options!
|
7
|
+
options = options.reverse_merge({
|
8
|
+
:"#{model_name}ids" => id
|
9
|
+
})
|
10
|
+
res = api.send(model_name).get options
|
11
|
+
if res.size == 0
|
12
|
+
nil
|
13
|
+
elsif res.size > 1
|
14
|
+
raise IDNotUniqueError, "#{model_name.camelize} ID `#{id}` is not unique"
|
15
|
+
else
|
16
|
+
self.new res.first
|
17
|
+
end
|
18
|
+
rescue Errno::ETIMEDOUT => e
|
19
|
+
Zabbirc.logger.error "Zabbix::Resource#find: #{e}"
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
|
23
|
+
def get *options
|
24
|
+
options = options.extract_options!
|
25
|
+
res = api.send(model_name).get options
|
26
|
+
res.collect do |obj|
|
27
|
+
self.new obj
|
28
|
+
end
|
29
|
+
rescue Errno::ETIMEDOUT => e
|
30
|
+
Zabbirc.logger.error "Zabbix::Resource#get: #{e}"
|
31
|
+
[]
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Zabbirc
|
2
|
+
module Zabbix
|
3
|
+
class Trigger < Resource::Base
|
4
|
+
has_many :hosts
|
5
|
+
|
6
|
+
def priority
|
7
|
+
Priority.new(super.to_i)
|
8
|
+
end
|
9
|
+
|
10
|
+
def value
|
11
|
+
case @attrs[:value].to_i
|
12
|
+
when 0
|
13
|
+
:ok
|
14
|
+
when 1
|
15
|
+
:problem
|
16
|
+
else
|
17
|
+
@attrs[:value]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def message
|
22
|
+
if description.include?("{HOST.NAME}")
|
23
|
+
description.sub("{HOST.NAME}", hosts.collect(&:host).join(', '))
|
24
|
+
else
|
25
|
+
"#{description} on #{hosts.collect(&:host).join(', ')}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def label
|
30
|
+
format_label "%time [%priority-code] %msg - %value"
|
31
|
+
end
|
32
|
+
|
33
|
+
def changed_at
|
34
|
+
Time.at(lastchange.to_i)
|
35
|
+
end
|
36
|
+
|
37
|
+
def format_label fmt
|
38
|
+
fmt.gsub("%priority-code", "#{priority.code}").
|
39
|
+
gsub("%priority-num", "#{priority.number}").
|
40
|
+
gsub("%time", "#{changed_at.to_formatted_s(:short)}").
|
41
|
+
gsub("%msg", "#{message}").
|
42
|
+
gsub("%id", "#{id}").
|
43
|
+
gsub("%value", "#{value}")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/zabbirc.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'active_support/all'
|
2
|
+
require 'singleton'
|
3
|
+
require 'dotenv'
|
4
|
+
Dotenv.load
|
5
|
+
|
6
|
+
def require_dir dir
|
7
|
+
base_dir = Pathname.new(File.expand_path(File.dirname(__FILE__)))
|
8
|
+
Dir.glob(base_dir.join(dir)).each do |f|
|
9
|
+
require f
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module Zabbirc
|
14
|
+
def self.synchronize &block
|
15
|
+
@mutex ||= Mutex.new
|
16
|
+
@mutex.synchronize &block
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
require_dir "zabbirc/*.rb"
|
21
|
+
require_dir "zabbirc/irc/*.rb"
|
22
|
+
require 'zabbirc/zabbix/resource/base'
|
23
|
+
require_dir "zabbirc/zabbix/*.rb"
|
24
|
+
require_dir "zabbirc/services/*.rb"
|
data/spec/bot_spec.rb
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
describe Zabbirc::Irc::PluginMethods do
|
2
|
+
# let(:service) { Zabbirc::ServiceMock.new }
|
3
|
+
let(:mock_message) { double("Cinch::Message", user: mock_user) }
|
4
|
+
let(:mock_user) { double("Cinch::User", nick: mock_nick) }
|
5
|
+
let(:bot) { Zabbirc::MockBot.new }
|
6
|
+
let(:mock_nick) { "op1" }
|
7
|
+
let(:mock_user_settings) { nil }
|
8
|
+
|
9
|
+
before do
|
10
|
+
bot.setup_op mock_nick, mock_user_settings
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#acknowledge_event" do
|
14
|
+
let(:event) { double "Event", id: 1, label: "Event 1 label" }
|
15
|
+
let(:message) { "ack message" }
|
16
|
+
before do
|
17
|
+
allow(event).to receive(:acknowledge).and_return(true)
|
18
|
+
allow(Zabbirc::Zabbix::Event).to receive(:find).and_return(event)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should acknowledge event" do
|
22
|
+
expect(mock_message).to receive(:reply).with("#{mock_nick}: Event `#{event.label}` acknowledged with message: #{message}")
|
23
|
+
bot.acknowledge_event mock_message, event.id, message
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#host_status" do
|
28
|
+
before do
|
29
|
+
allow(Zabbirc::Zabbix::Host).to receive(:get).and_return(hosts)
|
30
|
+
end
|
31
|
+
|
32
|
+
context "reporting" do
|
33
|
+
before do
|
34
|
+
allow(Zabbirc::Zabbix::Trigger).to receive(:get).and_return(problem_triggers)
|
35
|
+
end
|
36
|
+
let(:host) { double "Host", id: 1, name: "Host-1" }
|
37
|
+
let(:hosts) { [host] }
|
38
|
+
let(:problem_trigger) { double "Trigger", priority: Zabbirc::Priority.new(1), label: "problem_trigger", value: 1 }
|
39
|
+
context "problem trigger" do
|
40
|
+
let(:problem_triggers) { [problem_trigger] }
|
41
|
+
let(:expected_msg) do
|
42
|
+
msg = ["#{mock_nick}: Host: #{host.name} - status: #{problem_triggers.size} problems"]
|
43
|
+
problem_triggers.each do |trigger|
|
44
|
+
msg << "#{mock_nick}: status: #{trigger.label}"
|
45
|
+
end
|
46
|
+
msg.join("\n")
|
47
|
+
end
|
48
|
+
it "should report problem" do
|
49
|
+
expect(mock_message).to receive(:reply).with(expected_msg)
|
50
|
+
bot.host_status mock_message, host.name
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "ok trigger" do
|
55
|
+
let(:problem_triggers) { [] }
|
56
|
+
let(:expected_msg) { "#{mock_nick}: Host: #{host.name} - status: OK" }
|
57
|
+
it "should report problem" do
|
58
|
+
expect(mock_message).to receive(:reply).with(expected_msg)
|
59
|
+
bot.host_status mock_message, host.name
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end # context reporting
|
63
|
+
|
64
|
+
context "host identification" do
|
65
|
+
context "no hosts" do
|
66
|
+
let(:hosts) { [] }
|
67
|
+
let(:host_name) { "undefined_host_name" }
|
68
|
+
it "should not found host" do
|
69
|
+
expect(mock_message).to receive(:reply).with("#{mock_nick}: Host not found `#{host_name}`")
|
70
|
+
bot.host_status mock_message, host_name
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "2 - 10 hosts" do
|
75
|
+
let(:host1) { double "Host1", id: 1, name: "host-1" }
|
76
|
+
let(:host2) { double "Host2", id: 2, name: "host-2" }
|
77
|
+
let(:hosts) { [host1, host2] }
|
78
|
+
let(:expected_msg) { "#{mock_nick}: Found #{hosts.size} hosts: #{hosts.collect(&:name).join(', ')}. Be more specific" }
|
79
|
+
it "should print host names" do
|
80
|
+
expect(mock_message).to receive(:reply).with(expected_msg)
|
81
|
+
bot.host_status mock_message, "host"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context "more than 10 hosts" do
|
86
|
+
let(:hosts) { double "HostsArray", size: 11 }
|
87
|
+
let(:expected_msg) { "#{mock_nick}: Found #{hosts.size} Be more specific" }
|
88
|
+
it "should print host names" do
|
89
|
+
expect(mock_message).to receive(:reply).with(expected_msg)
|
90
|
+
bot.host_status mock_message, "host"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end # context host identification
|
94
|
+
end # context #host_status
|
95
|
+
|
96
|
+
context "#host_latest" do
|
97
|
+
let(:host) { double "Host", id: 1, name: "Host1" }
|
98
|
+
let(:hosts) { [host] }
|
99
|
+
let(:event1) { double "Event", label: "Event 1 label" }
|
100
|
+
let(:events) { [event1] }
|
101
|
+
let(:expected_msg) do
|
102
|
+
msg = ["#{mock_nick}: Host: #{host.name} - showing last #{events.size} events"]
|
103
|
+
events.each do |event|
|
104
|
+
msg << "#{mock_nick}: !latest: #{event.label}"
|
105
|
+
end
|
106
|
+
msg.join("\n")
|
107
|
+
end
|
108
|
+
before do
|
109
|
+
allow(Zabbirc::Zabbix::Host).to receive(:get).and_return(hosts)
|
110
|
+
allow(Zabbirc::Zabbix::Event).to receive(:get).and_return(events)
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should print latest events" do
|
114
|
+
expect(mock_message).to receive(:reply).with(expected_msg)
|
115
|
+
bot.host_latest mock_message, "Host1", nil, nil
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe "#list_events" do
|
120
|
+
before do
|
121
|
+
allow(Zabbirc::Zabbix::Event).to receive(:recent).and_return(recent_events)
|
122
|
+
end
|
123
|
+
context "no last events" do
|
124
|
+
let(:recent_events) { [] }
|
125
|
+
|
126
|
+
it "should report no last events" do
|
127
|
+
expect(mock_message).to receive(:reply).with("#{mock_nick}: No last events")
|
128
|
+
bot.list_events mock_message
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context "no last events" do
|
133
|
+
let(:event1) { double "Event1", label: "Event 1 label" }
|
134
|
+
let(:event2) { double "Event2", label: "Event 2 label" }
|
135
|
+
let(:recent_events) { [event1, event2] }
|
136
|
+
let(:expected_msg) { recent_events.collect{|e| "#{mock_nick}: #{e.label}"}.join("\n") }
|
137
|
+
|
138
|
+
it "should report no last events" do
|
139
|
+
expect(mock_message).to receive(:reply).with(expected_msg)
|
140
|
+
bot.list_events mock_message
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe "#show_settings" do
|
146
|
+
let(:mock_user_settings) { {primary_channel: "#channel-1", events_priority: "high", notify: false } }
|
147
|
+
let(:expected_msg) { "#{mock_nick}: notify: false, primary_channel: #channel-1, events_priority: high" }
|
148
|
+
it "should show settings" do
|
149
|
+
expect(mock_message).to receive(:reply).with(expected_msg)
|
150
|
+
bot.show_settings mock_message
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe "#set_setting" do
|
155
|
+
shared_examples "set_setting" do |key, value, expected_setting_value|
|
156
|
+
let(:expected_msg) { "#{mock_nick}: setting `#{key}` was set to `#{expected_setting_value}`" }
|
157
|
+
let(:op) { bot.get_op mock_nick }
|
158
|
+
it "should set #{key} setting to #{value}" do
|
159
|
+
expect(mock_message).to receive(:reply).with(expected_msg)
|
160
|
+
bot.set_setting mock_message, key, nil, value
|
161
|
+
expect(op.setting.get(key)).to eq expected_setting_value
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
|
166
|
+
context "notify" do
|
167
|
+
it_should_behave_like "set_setting", "notify", "false", false
|
168
|
+
it_should_behave_like "set_setting", "notify", "true", true
|
169
|
+
end
|
170
|
+
|
171
|
+
context "events_priority" do
|
172
|
+
it_should_behave_like "set_setting", "events_priority", "high", :high
|
173
|
+
it_should_behave_like "set_setting", "events_priority", "5", :disaster
|
174
|
+
end
|
175
|
+
|
176
|
+
context "primary_channel" do
|
177
|
+
before do
|
178
|
+
op.add_channel double("#channel1", name: "#channel1")
|
179
|
+
op.add_channel double("#channel2double", name: "#channel2")
|
180
|
+
end
|
181
|
+
it_should_behave_like "set_setting", "primary_channel", "#channel1", "#channel1"
|
182
|
+
it_should_behave_like "set_setting", "primary_channel", "#channel2", "#channel2"
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
186
|
+
end
|