zabbirc 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1d4081d968390062febd6847ba0792fd884837ef
4
- data.tar.gz: a06fc08a9ce62d8732a7452d881446abf71b3452
3
+ metadata.gz: d19487ed3b008b96ed9834da9be4dcc1739397d2
4
+ data.tar.gz: 6b4d2299af4229cc7991ffc6b268c522128bec97
5
5
  SHA512:
6
- metadata.gz: 7f4874d643b926dcb8e6fd7fb82fd10d4d3e087bd5ac14d2f232b93f9b02fb0eaa9e3a1662246cefdb0a144e68a6ad32f84b1f80a1982f7398a9ef910045665d
7
- data.tar.gz: 88c8c869678986755f6738a1efe8a8fb75b5792146a7efc5de2d16fb1228eb9ae4893a0809f06bf4b6ba05e7f17fc20b0ef00d37e8b125861cab0a18f2eddb87
6
+ metadata.gz: dbdf9dcbd24433c9b539d2805facd668bbf241dab7294d759bc108707f5dec617987ad46555b8a8f44f7fdc7545ff71b6f575d468cddc31e13b27656c001ef38
7
+ data.tar.gz: 54e596bd981be3078251ebb6b4fa57c0035b3046a5189c578ce4cea6e4dca908ef74f6ea37831217b31912478220794cc5a673fab04050794408d5afdbe50c2d
@@ -3,10 +3,11 @@ Zabbirc.configure do |config|
3
3
  config.zabbix_login = ENV['ZABBIX_LOGIN']
4
4
  config.zabbix_password = ENV['ZABBIX_PASSWORD']
5
5
 
6
- # config.irc_server = "irc.devel.redhat.com"
6
+ config.irc_server = "irc.devel.redhat.com"
7
7
  # config.irc_channels = ["#libra-zabbix"]
8
- config.irc_server = "irc.freenode.org"
9
- config.irc_channels = ["#zabbirc-test", "#zabbirc-test-2"]
8
+ # config.irc_server = "irc.freenode.org"
9
+ config.irc_channels = ["#zabbirc-test"] #, "#zabbirc-test-2"]
10
10
 
11
11
  config.notify_about_events_from_last = 25.minutes
12
+ config.colors = true
12
13
  end
@@ -26,6 +26,13 @@ module Zabbirc
26
26
  def self.maintenances_id_shortener
27
27
  @maintenances_id_shortener ||= IdShortener.new
28
28
  end
29
+
30
+ def self.rich_text_formatter
31
+ @rich_text_formatter ||= begin
32
+ palette = (config.colors ? Palettes::Default : Palettes::Clean)
33
+ RichTextFormatter.new palette
34
+ end
35
+ end
29
36
  end
30
37
 
31
38
  require 'zabbirc/configuration'
@@ -36,3 +43,4 @@ require 'zabbirc/zabbix/resource/base'
36
43
  require_dir "zabbirc/zabbix/*.rb"
37
44
  require 'zabbirc/services/base'
38
45
  require_dir "zabbirc/services/*.rb"
46
+
@@ -20,11 +20,16 @@ module Zabbirc
20
20
  config_accessor :zabbix_password
21
21
 
22
22
  config_accessor :irc_server
23
+ config_accessor :irc_port
24
+ config_accessor :irc_ssl
25
+ config_accessor :irc_ssl_verify
23
26
  config_accessor :irc_channels
24
27
 
25
28
  config_accessor :events_check_interval
26
29
  config_accessor :notify_about_events_from_last
27
30
 
31
+ config_accessor :colors
32
+
28
33
  def param_name
29
34
  config.param_name.respond_to?(:call) ? config.param_name.call : config.param_name
30
35
  end
@@ -54,6 +59,10 @@ module Zabbirc
54
59
  config.default_events_priority = :high
55
60
 
56
61
  config.irc_server = "irc.freenode.org"
62
+ config.irc_port = 6667
63
+ config.irc_ssl = false
64
+ config.irc_ssl_verify = false
57
65
  config.irc_channels = ["#zabbirc-test", "#zabbirc-test-2"]
66
+ config.colors = true
58
67
  end
59
- end
68
+ end
@@ -70,6 +70,7 @@ module Zabbirc
70
70
  "#{@op.nick}: #{options[:prefix]}#{m}"
71
71
  end.join("\n")
72
72
 
73
+ msg = Zabbirc.rich_text_formatter.format msg
73
74
  @message.reply msg
74
75
  end
75
76
 
@@ -30,13 +30,13 @@ module Zabbirc
30
30
 
31
31
  triggers = Zabbix::Trigger.get(hostids: host.id, filter: {value: 1}, selectHosts: :extend)
32
32
  triggers = triggers.sort{|x,y| x.priority <=> y.priority }
33
- msg = ["Host: #{host.name}"]
33
+ msg = ["$C,GREY$Host:$C,RST$ #{host.name}"]
34
34
  if triggers.empty?
35
- msg[0] << " - status: OK"
35
+ msg[0] << " - $C,GREY$status:$C,GREEN$ OK$C,RST$"
36
36
  else
37
- msg[0] << " - status: #{triggers.size} problems"
37
+ msg[0] << " - $C,GREY$status:$C,RED$ #{triggers.size} problems$C,RST$"
38
38
  triggers.each do |trigger|
39
- msg << "status: #{trigger.label}"
39
+ msg << "$C,GREY$status:$C,RST$ #{trigger.label}"
40
40
  end
41
41
  end
42
42
  reply msg
@@ -47,14 +47,14 @@ module Zabbirc
47
47
  limit = @args.shift
48
48
  limit ||= 8
49
49
 
50
- msg = ["Host: #{host.name}"]
50
+ msg = ["$C,GREY$Host:$C,RST$ $U$#{host.name}$U,RST$"]
51
51
  events = Zabbix::Event.get(hostids: host.id, limit: limit, selectHosts: :extend, selectRelatedObject: :extend, sortfield: :clock, sortorder: "DESC")
52
52
  if events.empty?
53
53
  msg[0] << " - no events found"
54
54
  else
55
- msg[0] << " - showing last #{events.size} events"
55
+ msg[0] << " - showing last $C,RED$#{events.size}$C,RST$ events"
56
56
  events.each do |event|
57
- msg << "!latest: #{event.label}"
57
+ msg << "$C,GREY$!latest:$C,RST$ #{event.label}"
58
58
  end
59
59
  end
60
60
  reply msg
@@ -25,22 +25,22 @@ module Zabbirc
25
25
  def show
26
26
  inline = @op.setting.collect do |key, value|
27
27
  next if key == "host_groups"
28
- "#{key}: #{value}"
28
+ "$C,BLUE_CYAN$#{key}:$C,RST$ #{value}"
29
29
  end.compact.join(", ")
30
30
 
31
- reply "Default settings: #{inline}"
31
+ reply "$C,GREY$Default settings: $C,RST$#{inline}"
32
32
 
33
33
  host_group_options = []
34
34
  @op.setting.get(:host_groups).each do |group_id, options|
35
35
  if options.any?
36
36
  group = Zabbix::HostGroup.find(group_id)
37
- group_options = options.collect{|k,v| "#{k}: #{v}" }.sort.join(", ")
38
- host_group_options << " - #{group.name}: #{group_options}"
37
+ group_options = options.collect{|k,v| "$C,BLUE_CYAN$#{k}:$C,RST$ #{v}" }.sort.join(", ")
38
+ host_group_options << " - $C,ORANGE$#{group.name}: $C,RST$ #{group_options}"
39
39
  end
40
40
  end
41
41
 
42
42
  if host_group_options.any?
43
- reply "Host group settings:"
43
+ reply "$C,GREY$Host group settings: $C,RST$"
44
44
  reply host_group_options
45
45
  end
46
46
  end
@@ -94,21 +94,22 @@ module Zabbirc
94
94
  end
95
95
 
96
96
  def set_value key, value, host_groups_flag, host_groups
97
+ key_label = "$C,BLUE_CYAN$#{key}$C,RST$"
97
98
  case host_groups_flag
98
99
  when :none
99
100
  @op.setting.set key, value
100
- reply "setting `#{key}` has been set to `#{@op.setting.get key}`"
101
+ reply "setting `#{key_label}` has been set to `$C,BLUE_CYAN$#{@op.setting.get key}$C,RST$`"
101
102
  when :all
102
103
  @op.setting.set key, value
103
104
  host_groups.each do |host_group|
104
105
  @op.setting.set key, value, host_group_id: host_group.id
105
106
  end
106
- reply "setting `#{key}` has been set to `#{@op.setting.get key}` for all host groups"
107
+ reply "setting `#{key_label}` has been set to `$C,BLUE_CYAN$#{@op.setting.get key}$C,RST$` for all host groups"
107
108
  when :some
108
109
  host_groups.each do |host_group|
109
110
  @op.setting.set key, value, host_group_id: host_group.id
110
111
  end
111
- reply "setting `#{key}` has been set to `#{value}` for host groups: #{host_groups.collect(&:name).join(", ")}"
112
+ reply "setting `#{key_label}` has been set to `$C,BLUE_CYAN$#{value}$C,RST$` for host groups: $C,ORANGE$#{host_groups.collect(&:name).join(", ")}$C,ORANGE$"
112
113
  end
113
114
  end
114
115
 
@@ -59,6 +59,7 @@ module Zabbirc
59
59
  when Zabbix::Event
60
60
  object.label
61
61
  end
62
+ message = Zabbirc.rich_text_formatter.format message
62
63
  group_by(&:primary_channel).each do |channel, ops|
63
64
  next if channel.nil?
64
65
  op_targets = ops.collect{|op| "#{op.nick}:" }.join(" ")
@@ -0,0 +1,11 @@
1
+ module Zabbirc
2
+ module Palettes
3
+ class Clean
4
+ def format tokens
5
+ tokens.reject do |token|
6
+ token.is_a? Array
7
+ end.join.gsub(/ +/," ").strip
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,101 @@
1
+ module Zabbirc
2
+ module Palettes
3
+ class Default
4
+ COLORS = {
5
+ "white" => 0,
6
+ "black" => 1,
7
+ "blue" => 2,
8
+ "green" => 3,
9
+ "red" => 4,
10
+ "brown" => 5,
11
+ "purple" => 6,
12
+ "orange" => 7,
13
+ "yellow" => 8,
14
+ "light_green" => 9,
15
+ "blue_cyan" => 10,
16
+ "light_cyan" => 11,
17
+ "light_blue" => 12,
18
+ "pink" => 13,
19
+ "grey" => 14,
20
+ "light_grey" => 15
21
+ }
22
+ COMMANDS = {
23
+ bold: "\x02",
24
+ color: "\x03",
25
+ underlined: "\x1F",
26
+ reset: "\x0F"
27
+ }
28
+ RESET_ARG = "RST"
29
+
30
+ def format tokens
31
+ @flags = Hash.new(false)
32
+ tokens.collect do |token|
33
+ process_token token
34
+ end.join
35
+ end
36
+
37
+ private
38
+ def process_token token
39
+ case token
40
+ when Array
41
+ cmd = token.shift
42
+ case cmd
43
+ when :C then process_color token
44
+ when :B then process_bold token
45
+ when :U then process_underline token
46
+ when :RST then process_reset token
47
+ else
48
+ raise ArgumentError, "unknown irc richtext command `#{cmd.inspect}`"
49
+ end
50
+ when String then token
51
+ else
52
+ raise ArgumentError, "unknown token `#{token.inspect}`"
53
+ end
54
+ end
55
+
56
+ def process_color args
57
+ raise ArgumentError, "too many arguments for C command" if args.size > 2
58
+ fg, bg = args.compact
59
+ return COMMANDS[:color] if fg == RESET_ARG
60
+ fg = "%02d" % COLORS[fg.downcase] if fg.present?
61
+ bg = "%02d" % COLORS[bg.downcase] if bg.present?
62
+ colors = [fg,bg].compact.join(",")
63
+ "#{COMMANDS[:color]}#{colors}"
64
+ end
65
+
66
+ def process_bold args
67
+ raise ArgumentError, "too many arguments for B command" if args.size > 1
68
+ case args.first
69
+ when RESET_ARG
70
+ return unless @flags[:bold]
71
+ @flags[:bold] = false
72
+ COMMANDS[:bold]
73
+ else
74
+ return if @flags[:bold]
75
+ @flags[:bold] = true
76
+ COMMANDS[:bold]
77
+ end
78
+ end
79
+
80
+ def process_underline args
81
+ raise ArgumentError, "too many arguments for U command" if args.size > 1
82
+ case args.first
83
+ when RESET_ARG
84
+ return unless @flags[:underlined]
85
+ @flags[:underlined] = false
86
+ COMMANDS[:underlined]
87
+ else
88
+ return if @flags[:underlined]
89
+ @flags[:underlined] = true
90
+ COMMANDS[:underlined]
91
+ end
92
+ end
93
+
94
+ def process_reset args
95
+ raise ArgumentError, "too many arguments for RST command" unless args.size.zero?
96
+ @flags = Hash.new(false)
97
+ COMMANDS[:reset]
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,32 @@
1
+ require_dir 'zabbirc/palettes/*'
2
+
3
+ module Zabbirc
4
+ class RichTextFormatter
5
+ DEFAULT_PALETTE = Zabbirc::Palettes::Default
6
+ COMMANDS = %w[C B U RST] # C - color, B - bold, U - underlined, RST - reset all formatting
7
+ COMMANDS_REGEXP = Regexp.union(COMMANDS)
8
+ delegate :paint, to: :pallete
9
+ def initialize palette=DEFAULT_PALETTE
10
+ @palette = palette.new
11
+ end
12
+
13
+ def format msg
14
+ tokens = tokenize msg
15
+ @palette.format tokens
16
+ end
17
+
18
+ private
19
+ def tokenize msg
20
+ r = /\$(?<cmd>#{COMMANDS_REGEXP})(?<args>(,[a-zA-Z0-9_]+)*)\$(?<rest>(?:[\n\r]|.)*)/
21
+ match_data = msg.match(r)
22
+ return [msg] if match_data.nil?
23
+ args = match_data[:args].split(/,/).reject(&:blank?)
24
+ cmd = [
25
+ match_data[:cmd].to_sym,
26
+ args
27
+ ].flatten
28
+ ([match_data.pre_match, cmd] + tokenize(match_data[:rest])).reject(&:nil?)
29
+ end
30
+
31
+ end
32
+ end
@@ -22,8 +22,11 @@ module Zabbirc
22
22
  @cinch_bot = Cinch::Bot.new do
23
23
  configure do |c|
24
24
  c.server = Zabbirc.config.irc_server
25
+ c.port = Zabbirc.config.irc_port
25
26
  c.channels = Zabbirc.config.irc_channels
26
27
  c.nick = "zabbirc"
28
+ c.ssl.use = Zabbirc.config.irc_ssl
29
+ c.ssl.verify = Zabbirc.config.irc_ssl_verify
27
30
  c.plugins.plugins = [Irc::Plugin]
28
31
  end
29
32
  end
@@ -100,4 +103,4 @@ module Zabbirc
100
103
  @cinch_bot_thread.join
101
104
  end
102
105
  end
103
- end
106
+ end
@@ -1,3 +1,3 @@
1
1
  module Zabbirc
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.2"
3
3
  end
@@ -35,7 +35,7 @@ module Zabbirc
35
35
  attr_reader :attrs
36
36
  attr_writer :host_groups
37
37
 
38
- delegate :priority, :priority_code, to: :related_object
38
+ delegate :priority, :priority_code, :severity_label, to: :related_object
39
39
 
40
40
  def related_object
41
41
  raise AttributeError, "`source` attribute required" if @attrs[:source].blank?
@@ -72,7 +72,7 @@ module Zabbirc
72
72
  end
73
73
 
74
74
  def maintenance_label
75
- " [MAINT]" if maintenance?
75
+ " $C,PURPLE$[MAINT]$C,RST$" if maintenance?
76
76
  end
77
77
 
78
78
  def created_at
@@ -97,24 +97,34 @@ module Zabbirc
97
97
  @shorten_id ||= Zabbirc.events_id_shortener.get_shorten_id id
98
98
  end
99
99
 
100
- alias_method :state, :value
100
+ def state
101
+ case value
102
+ when :ok then "$C,GREEN$ok$C,RST$"
103
+ when :problem then "$C,RED$problem$C,RST$"
104
+ else
105
+ value
106
+ end
107
+ end
101
108
 
102
109
  def message
103
110
  desc = related_object.description
104
- if desc.include?("{HOST.NAME}")
105
- desc.sub("{HOST.NAME}", hosts.collect(&:host).join(', '))
111
+ host_label_regexp = Regexp.union("{HOSTNAME}", "{HOST.NAME}")
112
+ host_names = "$U$#{hosts.collect(&:host).join(', ')}$U,RST$"
113
+ if desc =~ host_label_regexp
114
+ desc.sub(host_label_regexp, host_names)
106
115
  else
107
- "#{desc} on #{hosts.collect(&:host).join(', ')}"
116
+ "#{desc} on #{host_names}"
108
117
  end
109
118
  end
110
119
 
111
120
  def label
112
- format_label "|%sid| %time%maint [%priority-code] %msg - %state"
121
+ format_label "$C,PURPLE$|%sid|$C,RST$ %time %severity%maint %msg - %state"
113
122
  end
114
123
 
115
124
  def format_label fmt
116
125
  fmt.gsub("%priority-code", "#{priority.code}").
117
126
  gsub("%priority-num", "#{priority.number}").
127
+ gsub("%severity", "#{severity_label}").
118
128
  gsub("%time", "#{created_at.to_formatted_s(:short)}").
119
129
  gsub("%msg", "#{message}").
120
130
  gsub("%id", "#{id}").
@@ -84,11 +84,11 @@ module Zabbirc
84
84
  end
85
85
 
86
86
  def data_collection_label
87
- " [NO-DATA-COL]" if maintenance_type.to_i == 1
87
+ " $C,ORANGE$[NO-DATA-COL]$C,RST$" if maintenance_type.to_i == 1
88
88
  end
89
89
 
90
90
  def label
91
- format_label "|%sid|%data-collection-label %start -> %end >> %name %targets"
91
+ format_label "$C,PURPLE$|%sid|$C,RST$%data-collection-label %start $C,RED$->$C,RST$ %end $C,RED$>>$C,RST$ %name $C,ORANGE$%targets$C,RST$"
92
92
  end
93
93
 
94
94
  def format_label fmt
@@ -18,16 +18,41 @@ module Zabbirc
18
18
  end
19
19
  end
20
20
 
21
+ def state
22
+ case value
23
+ when :ok then "$C,GREEN$ok$C,RST$"
24
+ when :problem then "$C,RED$problem$C,RST$"
25
+ else
26
+ value
27
+ end
28
+ end
29
+
21
30
  def message
22
- if description.include?("{HOST.NAME}")
23
- description.sub("{HOST.NAME}", hosts.collect(&:host).join(', '))
31
+ host_label_regexp = Regexp.union("{HOSTNAME}", "{HOST.NAME}")
32
+ host_names = "$U$#{hosts.collect(&:host).join(', ')}$U,RST$"
33
+ if description =~ host_label_regexp
34
+ description.sub(host_label_regexp, host_names)
24
35
  else
25
- "#{description} on #{hosts.collect(&:host).join(', ')}"
36
+ "#{description} on #{host_names}"
37
+ end
38
+ end
39
+
40
+
41
+
42
+ def severity_label
43
+ code = priority.code
44
+ case code
45
+ when :not_classified then "$C,GREY$[#{code}]$C,RST$"
46
+ when :information then "$C,LIGHT_GREEN$[#{code}]$C,RST$"
47
+ when :warning then "$C,YELLOW$[#{code}]$C,RST$"
48
+ when :average then "$C,ORANGE$[#{code}]$C,RST$"
49
+ when :high then "$C,RED$[#{code}]$C,RST$"
50
+ when :disaster then "$C,BROWN$[#{code}]$C,RST$"
26
51
  end
27
52
  end
28
53
 
29
54
  def label
30
- format_label "%time [%priority-code] %msg - %value"
55
+ format_label "%time %severity %msg - %value"
31
56
  end
32
57
 
33
58
  def changed_at
@@ -37,10 +62,11 @@ module Zabbirc
37
62
  def format_label fmt
38
63
  fmt.gsub("%priority-code", "#{priority.code}").
39
64
  gsub("%priority-num", "#{priority.number}").
65
+ gsub("%severity", "#{severity_label}").
40
66
  gsub("%time", "#{changed_at.to_formatted_s(:short)}").
41
67
  gsub("%msg", "#{message}").
42
68
  gsub("%id", "#{id}").
43
- gsub("%value", "#{value}")
69
+ gsub("%value", "#{state}")
44
70
  end
45
71
  end
46
72
  end
@@ -0,0 +1,3 @@
1
+ def Zabbirc.rich_text_formatter
2
+ @rich_text_formatter ||= Zabbirc::RichTextFormatter.new(Zabbirc::Palettes::Clean)
3
+ end
@@ -7,9 +7,13 @@ Zabbirc.configure do |config|
7
7
  ### IRC configurations
8
8
  # config.irc_server = "irc.freenode.org"
9
9
  # config.irc_channels = ["#zabbirc-test", "#zabbirc-test-2"]
10
+ # config.irc_port = 6667
11
+ # config.irc_ssl = false
12
+ # config.irc_ssl_verify = false
10
13
 
11
14
  ### Zabbirc configurations
12
15
  # config.events_check_interval = 10.seconds
13
16
  # config.notify_about_events_from_last = 5.minutes
14
17
  # config.default_events_priority = :high
15
- end
18
+ # config.colors = true
19
+ end
@@ -34,4 +34,43 @@ end
34
34
 
35
35
  include Zabbirc::Zabbix
36
36
  es = Event.get(selectHosts: :extend, sortfield: :clock);
37
- Event.preload_host_groups es;
37
+ Event.preload_host_groups es;
38
+
39
+
40
+ c = s.ops.get('fzachar').primary_channel
41
+ (0..15).each do |i|
42
+ msg = "\x03%02d %s - %02d" % [i, "The message", i]
43
+ c.send(msg)
44
+ sleep 1
45
+ end
46
+
47
+
48
+
49
+
50
+ ####################################################
51
+
52
+ $nopry = false
53
+ priorities = (0..5).collect{|i| Zabbirc::Priority.new i }
54
+ e = Zabbirc::Zabbix::Event.get.last
55
+ def e.priority
56
+ @the_priority
57
+ end
58
+
59
+ def e.the_priority= p
60
+ @the_priority = p
61
+ end
62
+ channel = s.ops.get('tulak').primary_channel
63
+ priorities.each do |p|
64
+ def e.maintenance?
65
+ false
66
+ end
67
+ e.the_priority = p
68
+ channel.send("tulak: #{Zabbirc.rich_text_formatter.format e.label}")
69
+
70
+ def e.maintenance?
71
+ true
72
+ end
73
+
74
+ channel.send("tulak: #{Zabbirc.rich_text_formatter.format e.label}")
75
+ sleep 1
76
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zabbirc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Filip Zachar
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-16 00:00:00.000000000 Z
11
+ date: 2015-11-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -130,7 +130,10 @@ files:
130
130
  - lib/zabbirc/logger.rb
131
131
  - lib/zabbirc/op.rb
132
132
  - lib/zabbirc/op_list.rb
133
+ - lib/zabbirc/palettes/clean.rb
134
+ - lib/zabbirc/palettes/default.rb
133
135
  - lib/zabbirc/priority.rb
136
+ - lib/zabbirc/rich_text_formatter.rb
134
137
  - lib/zabbirc/service.rb
135
138
  - lib/zabbirc/services/base.rb
136
139
  - lib/zabbirc/services/events.rb
@@ -154,6 +157,7 @@ files:
154
157
  - spec/maintenance_command_spec.rb
155
158
  - spec/settings_command_spec.rb
156
159
  - spec/spec_helper.rb
160
+ - spec/support/clean_palette.rb
157
161
  - spec/support/mock_bot.rb
158
162
  - spec/support/ops_builder.rb
159
163
  - templates/zabbirc_config.rb