zabbirc 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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