lbrt 0.1.0
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 +7 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +180 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/exe/lbrt +15 -0
- data/lbrt.gemspec +31 -0
- data/lib/lbrt.rb +46 -0
- data/lib/lbrt/alert.rb +91 -0
- data/lib/lbrt/alert/dsl.rb +9 -0
- data/lib/lbrt/alert/dsl/context.rb +32 -0
- data/lib/lbrt/alert/dsl/context/alert.rb +75 -0
- data/lib/lbrt/alert/dsl/context/alert/condition.rb +61 -0
- data/lib/lbrt/alert/dsl/converter.rb +113 -0
- data/lib/lbrt/alert/exporter.rb +38 -0
- data/lib/lbrt/cli.rb +2 -0
- data/lib/lbrt/cli/alert.rb +26 -0
- data/lib/lbrt/cli/app.rb +15 -0
- data/lib/lbrt/cli/service.rb +26 -0
- data/lib/lbrt/cli/space.rb +27 -0
- data/lib/lbrt/driver.rb +240 -0
- data/lib/lbrt/ext/string_ext.rb +25 -0
- data/lib/lbrt/logger.rb +32 -0
- data/lib/lbrt/service.rb +73 -0
- data/lib/lbrt/service/dsl.rb +9 -0
- data/lib/lbrt/service/dsl/context.rb +33 -0
- data/lib/lbrt/service/dsl/context/service.rb +32 -0
- data/lib/lbrt/service/dsl/converter.rb +38 -0
- data/lib/lbrt/service/exporter.rb +37 -0
- data/lib/lbrt/space.rb +126 -0
- data/lib/lbrt/space/dsl.rb +9 -0
- data/lib/lbrt/space/dsl/context.rb +29 -0
- data/lib/lbrt/space/dsl/context/space.rb +19 -0
- data/lib/lbrt/space/dsl/context/space/chart.rb +44 -0
- data/lib/lbrt/space/dsl/context/space/chart/stream.rb +48 -0
- data/lib/lbrt/space/dsl/converter.rb +107 -0
- data/lib/lbrt/space/exporter.rb +56 -0
- data/lib/lbrt/utils.rb +64 -0
- data/lib/lbrt/version.rb +3 -0
- metadata +202 -0
@@ -0,0 +1,32 @@
|
|
1
|
+
class Lbrt::Alert::DSL::Context
|
2
|
+
include Lbrt::Utils::ContextHelper
|
3
|
+
|
4
|
+
def self.eval(client, dsl, path, options = {})
|
5
|
+
self.new(client, path, options) {
|
6
|
+
eval(dsl, binding, path)
|
7
|
+
}
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :result
|
11
|
+
|
12
|
+
def initialize(client, path, options = {}, &block)
|
13
|
+
@path = path
|
14
|
+
@options = options
|
15
|
+
@result = {}
|
16
|
+
@services = Lbrt::Service::Exporter.export(client, options)
|
17
|
+
instance_eval(&block)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def alert(name, &block)
|
23
|
+
name = name.to_s
|
24
|
+
|
25
|
+
if @result[name]
|
26
|
+
raise "Alert `#{name}` is already defined"
|
27
|
+
end
|
28
|
+
|
29
|
+
alrt = Lbrt::Alert::DSL::Context::Alert.new(name, @services, &block).result
|
30
|
+
@result[name] = alrt
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
class Lbrt::Alert::DSL::Context::Alert
|
2
|
+
REQUIRED_ATTRIBUTES = %w(
|
3
|
+
description
|
4
|
+
attributes
|
5
|
+
active
|
6
|
+
rearm_seconds
|
7
|
+
rearm_per_signal
|
8
|
+
)
|
9
|
+
|
10
|
+
def initialize(name, services, &block)
|
11
|
+
@name = name
|
12
|
+
@services = services
|
13
|
+
|
14
|
+
@result = {
|
15
|
+
'attributes' => {},
|
16
|
+
'conditions' => [],
|
17
|
+
'services' => [],
|
18
|
+
}
|
19
|
+
|
20
|
+
instance_eval(&block)
|
21
|
+
end
|
22
|
+
|
23
|
+
def result
|
24
|
+
REQUIRED_ATTRIBUTES.each do |name|
|
25
|
+
unless @result.has_key?(name)
|
26
|
+
raise "Alert `#{@name}`: #{name} is not defined"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
@result
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def description(value)
|
36
|
+
@result['description'] = value.to_s
|
37
|
+
end
|
38
|
+
|
39
|
+
def attributes(value)
|
40
|
+
unless value.is_a?(Hash)
|
41
|
+
raise TypeError, "wrong argument type #{value.class}: #{value.inspect} (expected Hash)"
|
42
|
+
end
|
43
|
+
|
44
|
+
@result['attributes'] = value
|
45
|
+
end
|
46
|
+
|
47
|
+
def active(value)
|
48
|
+
@result['active'] = !!value
|
49
|
+
end
|
50
|
+
|
51
|
+
def rearm_seconds(value)
|
52
|
+
@result['rearm_seconds'] = value.to_i
|
53
|
+
end
|
54
|
+
|
55
|
+
def rearm_per_signal(value)
|
56
|
+
@result['rearm_per_signal'] = !!value
|
57
|
+
end
|
58
|
+
|
59
|
+
def condition(&block)
|
60
|
+
@result['conditions'] << Lbrt::Alert::DSL::Context::Alert::Condition.new(@name, &block).result
|
61
|
+
end
|
62
|
+
|
63
|
+
def service(type, title)
|
64
|
+
service_key = [type, title]
|
65
|
+
service = @services[service_key]
|
66
|
+
|
67
|
+
unless service
|
68
|
+
raise "Service `#{type}/#{title}` is not found"
|
69
|
+
end
|
70
|
+
|
71
|
+
service['title'] = title
|
72
|
+
service['type'] = type
|
73
|
+
@result['services'] << service
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
class Lbrt::Alert::DSL::Context::Alert::Condition
|
2
|
+
REQUIRED_ATTRIBUTES = %w(
|
3
|
+
type
|
4
|
+
metric_name
|
5
|
+
source
|
6
|
+
)
|
7
|
+
|
8
|
+
REQUIRED_ATTRIBUTES_BY_TYPE = {
|
9
|
+
'above' => %W(threshold summary_function),
|
10
|
+
'below' => %W(threshold summary_function),
|
11
|
+
'active' => %W(duration),
|
12
|
+
}
|
13
|
+
|
14
|
+
def initialize(alert_name, &block)
|
15
|
+
@alert_name = alert_name
|
16
|
+
@result = {}
|
17
|
+
instance_eval(&block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def result
|
21
|
+
REQUIRED_ATTRIBUTES.each do |name|
|
22
|
+
unless @result.has_key?(name)
|
23
|
+
raise "Alert `#{@alert_name}` > Condition > `#{name}` is not defined"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
REQUIRED_ATTRIBUTES_BY_TYPE.fetch(@result['type'], {}).each do |name|
|
28
|
+
unless @result.has_key?(name)
|
29
|
+
raise "Alert `#{@alert_name}` > Condition > `#{name}` is not defined"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
@result
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def type(value)
|
39
|
+
@result['type'] = value.to_s
|
40
|
+
end
|
41
|
+
|
42
|
+
def metric_name(value)
|
43
|
+
@result['metric_name'] = value.to_s
|
44
|
+
end
|
45
|
+
|
46
|
+
def source(value)
|
47
|
+
@result['source'] = value.nil? ? nil : value.to_s
|
48
|
+
end
|
49
|
+
|
50
|
+
def threshold(value)
|
51
|
+
@result['threshold'] = value.to_f
|
52
|
+
end
|
53
|
+
|
54
|
+
def summary_function(value)
|
55
|
+
@result['summary_function'] = value.to_s
|
56
|
+
end
|
57
|
+
|
58
|
+
def duration(value)
|
59
|
+
@result['duration'] = value.to_i
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
class Lbrt::Alert::DSL::Converter
|
2
|
+
def self.convert(exported, options = {})
|
3
|
+
self.new(exported, options).convert
|
4
|
+
end
|
5
|
+
|
6
|
+
def initialize(exported, options = {})
|
7
|
+
@exported = exported
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def convert
|
12
|
+
output_alerts(@exported)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def output_alerts(alert_by_name)
|
18
|
+
alerts = []
|
19
|
+
|
20
|
+
alert_by_name.sort_by(&:first).map do |name, attrs|
|
21
|
+
next unless Lbrt::Utils.matched?(name, @options[:target])
|
22
|
+
alerts << output_alert(name, attrs)
|
23
|
+
end
|
24
|
+
|
25
|
+
alerts.join("\n")
|
26
|
+
end
|
27
|
+
|
28
|
+
def output_alert(name, attrs)
|
29
|
+
description = attrs.fetch('description')
|
30
|
+
attributes = attrs.fetch('attributes')
|
31
|
+
active = attrs.fetch('active')
|
32
|
+
rearm_seconds = attrs.fetch('rearm_seconds')
|
33
|
+
rearm_per_signal = attrs.fetch('rearm_per_signal')
|
34
|
+
|
35
|
+
conditions = attrs.fetch('conditions')
|
36
|
+
services = attrs.fetch('services')
|
37
|
+
|
38
|
+
if attributes.empty?
|
39
|
+
attributes = "\n" + <<-EOS.chomp
|
40
|
+
#attributes "runbook_url"=>"http://example.com"
|
41
|
+
EOS
|
42
|
+
else
|
43
|
+
attributes = "\n" + <<-EOS.chomp
|
44
|
+
attributes #{Lbrt::Utils.unbrace(attributes.inspect)}
|
45
|
+
EOS
|
46
|
+
end
|
47
|
+
|
48
|
+
<<-EOS
|
49
|
+
alert #{name.inspect} do
|
50
|
+
description #{description.inspect}#{
|
51
|
+
attributes}
|
52
|
+
active #{active.inspect}
|
53
|
+
rearm_seconds #{rearm_seconds.inspect}
|
54
|
+
rearm_per_signal #{rearm_per_signal.inspect}
|
55
|
+
|
56
|
+
#{output_conditions(conditions)}
|
57
|
+
|
58
|
+
#{output_services(services)}
|
59
|
+
end
|
60
|
+
EOS
|
61
|
+
end
|
62
|
+
|
63
|
+
def output_conditions(conditions)
|
64
|
+
if conditions.empty?
|
65
|
+
'# no condition'
|
66
|
+
else
|
67
|
+
conditions.map {|i| output_condition(i) }.join("\n").strip
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def output_condition(condition)
|
72
|
+
type = condition.fetch('type')
|
73
|
+
metric_name = condition.fetch('metric_name')
|
74
|
+
source = condition.fetch('source')
|
75
|
+
|
76
|
+
out = <<-EOS
|
77
|
+
condition do
|
78
|
+
type #{type.inspect}
|
79
|
+
metric_name #{metric_name.inspect}
|
80
|
+
source #{source.inspect}
|
81
|
+
EOS
|
82
|
+
|
83
|
+
%w(threshold summary_function duration).each do |key|
|
84
|
+
next unless condition.has_key?(key)
|
85
|
+
value = condition[key]
|
86
|
+
|
87
|
+
out << <<-EOS
|
88
|
+
#{key} #{value.inspect}
|
89
|
+
EOS
|
90
|
+
end
|
91
|
+
|
92
|
+
out << <<-EOS
|
93
|
+
end
|
94
|
+
EOS
|
95
|
+
end
|
96
|
+
|
97
|
+
def output_services(services)
|
98
|
+
if services.empty?
|
99
|
+
'# no service'
|
100
|
+
else
|
101
|
+
services.map {|i| output_service(i) }.join.strip
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def output_service(service)
|
106
|
+
type = service.fetch('type')
|
107
|
+
title = service.fetch('title')
|
108
|
+
|
109
|
+
<<-EOS
|
110
|
+
service #{type.inspect}, #{title.inspect}
|
111
|
+
EOS
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class Lbrt::Alert::Exporter
|
2
|
+
class << self
|
3
|
+
def export(client, options = {})
|
4
|
+
self.new(client, options).export
|
5
|
+
end
|
6
|
+
end # of class methods
|
7
|
+
|
8
|
+
def initialize(client, options = {})
|
9
|
+
@client = client
|
10
|
+
@options = options
|
11
|
+
end
|
12
|
+
|
13
|
+
def export
|
14
|
+
alerts = @client.alerts.get
|
15
|
+
normalize(alerts)
|
16
|
+
end
|
17
|
+
|
18
|
+
def normalize(alerts)
|
19
|
+
alert_by_name = {}
|
20
|
+
|
21
|
+
alerts.each do |alrt|
|
22
|
+
name = alrt.delete('name')
|
23
|
+
|
24
|
+
if alert_by_name[name]
|
25
|
+
raise "Duplicate alert name exists: #{name}"
|
26
|
+
end
|
27
|
+
|
28
|
+
%w(created_at updated_at version).each do |key|
|
29
|
+
alrt.delete(key)
|
30
|
+
end
|
31
|
+
|
32
|
+
alrt['attributes'] ||= {}
|
33
|
+
alert_by_name[name] = alrt
|
34
|
+
end
|
35
|
+
|
36
|
+
alert_by_name
|
37
|
+
end
|
38
|
+
end
|
data/lib/lbrt/cli.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
class Lbrt::CLI::Alert < Thor
|
2
|
+
include Lbrt::Utils::CLIHelper
|
3
|
+
|
4
|
+
class_option :target
|
5
|
+
|
6
|
+
desc 'apply FILE', 'Apply alerts'
|
7
|
+
option :'dry-run', :type => :boolean, :default => false
|
8
|
+
def apply(file)
|
9
|
+
updated = client(Lbrt::Alert).apply(file)
|
10
|
+
|
11
|
+
unless updated
|
12
|
+
Lbrt::Logger.instance.info('No change'.intense_blue)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'export [FILE]', 'Export alerts'
|
17
|
+
def export(file = nil)
|
18
|
+
dsl = client(Lbrt::Alert).export
|
19
|
+
|
20
|
+
if file.nil? or file == '-'
|
21
|
+
puts dsl
|
22
|
+
else
|
23
|
+
open(file, 'wb') {|f| f.puts dsl }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/lbrt/cli/app.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
class Lbrt::CLI::App < Thor
|
2
|
+
class_option :user, :default => ENV['LIBRATO_USER']
|
3
|
+
class_option :token, :default => ENV['LIBRATO_TOKEN']
|
4
|
+
class_option :color, :type => :boolean, :default => true
|
5
|
+
class_option :debug, :type => :boolean, :default => false
|
6
|
+
|
7
|
+
desc 'alert SUBCOMMAND', 'Manage alerts'
|
8
|
+
subcommand :alert, Lbrt::CLI::Alert
|
9
|
+
|
10
|
+
desc 'service SUBCOMMAND', 'Manage services'
|
11
|
+
subcommand :service, Lbrt::CLI::Service
|
12
|
+
|
13
|
+
desc 'space SUBCOMMAND', 'Manage spaces'
|
14
|
+
subcommand :space, Lbrt::CLI::Space
|
15
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class Lbrt::CLI::Service < Thor
|
2
|
+
include Lbrt::Utils::CLIHelper
|
3
|
+
|
4
|
+
class_option :target
|
5
|
+
|
6
|
+
desc 'apply FILE', 'Apply services'
|
7
|
+
option :'dry-run', :type => :boolean, :default => false
|
8
|
+
def apply(file)
|
9
|
+
updated = client(Lbrt::Service).apply(file)
|
10
|
+
|
11
|
+
unless updated
|
12
|
+
Lbrt::Logger.instance.info('No change'.intense_blue)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'export [FILE]', 'Export services'
|
17
|
+
def export(file = nil)
|
18
|
+
dsl = client(Lbrt::Service).export
|
19
|
+
|
20
|
+
if file.nil? or file == '-'
|
21
|
+
puts dsl
|
22
|
+
else
|
23
|
+
open(file, 'wb') {|f| f.puts dsl }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class Lbrt::CLI::Space < Thor
|
2
|
+
include Lbrt::Utils::CLIHelper
|
3
|
+
|
4
|
+
class_option :target
|
5
|
+
class_option :'export-concurrency', :type => :numeric, :default => 32
|
6
|
+
|
7
|
+
desc 'apply FILE', 'Apply spaces'
|
8
|
+
option :'dry-run', :type => :boolean, :default => false
|
9
|
+
def apply(file)
|
10
|
+
updated = client(Lbrt::Space).apply(file)
|
11
|
+
|
12
|
+
unless updated
|
13
|
+
Lbrt::Logger.instance.info('No change'.intense_blue)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
desc 'export [FILE]', 'Export spaces'
|
18
|
+
def export(file = nil)
|
19
|
+
dsl = client(Lbrt::Space).export
|
20
|
+
|
21
|
+
if file.nil? or file == '-'
|
22
|
+
puts dsl
|
23
|
+
else
|
24
|
+
open(file, 'wb') {|f| f.puts dsl }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/lbrt/driver.rb
ADDED
@@ -0,0 +1,240 @@
|
|
1
|
+
class Lbrt::Driver
|
2
|
+
include Lbrt::Logger::Helper
|
3
|
+
|
4
|
+
def initialize(client, options = {})
|
5
|
+
@client = client
|
6
|
+
@options = options
|
7
|
+
end
|
8
|
+
|
9
|
+
# Space
|
10
|
+
|
11
|
+
def create_space(name, expected)
|
12
|
+
updated = false
|
13
|
+
|
14
|
+
log(:info, "Create Space `#{name}`", :color => :cyan)
|
15
|
+
|
16
|
+
unless name.is_a?(String)
|
17
|
+
raise TypeError, "wrong argument type #{name.class}: #{name.inspect} (expected String)"
|
18
|
+
end
|
19
|
+
|
20
|
+
unless @options[:dry_run]
|
21
|
+
response = @client.spaces.post('name' => name)
|
22
|
+
expected['id'] = response.fetch('id')
|
23
|
+
updated = true
|
24
|
+
end
|
25
|
+
|
26
|
+
updated
|
27
|
+
end
|
28
|
+
|
29
|
+
def delete_space(name_or_id, actual)
|
30
|
+
updated = false
|
31
|
+
|
32
|
+
log(:info, "Delete Space `#{name_or_id}`", :color => :red)
|
33
|
+
|
34
|
+
space_id = actual.fetch('id')
|
35
|
+
|
36
|
+
unless @options[:dry_run]
|
37
|
+
@client.spaces(space_id).delete
|
38
|
+
updated = true
|
39
|
+
end
|
40
|
+
|
41
|
+
updated
|
42
|
+
end
|
43
|
+
|
44
|
+
# Chart
|
45
|
+
|
46
|
+
def create_chart(space_name_or_id, space_id, name, expected)
|
47
|
+
updated = false
|
48
|
+
|
49
|
+
log(:info, "Create Space `#{space_name_or_id}` > Chart `#{name}`", :color => :cyan)
|
50
|
+
|
51
|
+
unless name.is_a?(String)
|
52
|
+
raise TypeError, "wrong argument type #{name.class}: #{name.inspect} (expected String)"
|
53
|
+
end
|
54
|
+
|
55
|
+
unless @options[:dry_run]
|
56
|
+
response = @client.spaces(space_id).charts.post(expected.merge('name' => name))
|
57
|
+
expected['id'] = response.fetch('id')
|
58
|
+
updated = true
|
59
|
+
end
|
60
|
+
|
61
|
+
updated
|
62
|
+
end
|
63
|
+
|
64
|
+
def delete_chart(space_name_or_id, space_id, name_or_id, actual)
|
65
|
+
updated = false
|
66
|
+
|
67
|
+
log(:info, "Delete Space `#{space_name_or_id}` > `#{name_or_id}`", :color => :red)
|
68
|
+
|
69
|
+
chart_id = actual.fetch('id')
|
70
|
+
|
71
|
+
unless @options[:dry_run]
|
72
|
+
@client.spaces(space_id).charts(chart_id).delete
|
73
|
+
updated = true
|
74
|
+
end
|
75
|
+
|
76
|
+
updated
|
77
|
+
end
|
78
|
+
|
79
|
+
def update_chart(space_name_or_id, space_id, name_or_id, expected, actual)
|
80
|
+
updated = false
|
81
|
+
|
82
|
+
log(:info, "Update Space `#{space_name_or_id}` > Chart: #{name_or_id}", :color => :green)
|
83
|
+
|
84
|
+
delta = diff(Lbrt::Space::DSL::Converter,
|
85
|
+
{space_name_or_id => {'charts' => {name_or_id => actual}}},
|
86
|
+
{space_name_or_id => {'charts' => {name_or_id => expected}}}
|
87
|
+
)
|
88
|
+
|
89
|
+
log(:info, delta)
|
90
|
+
|
91
|
+
chart_id = actual.fetch('id')
|
92
|
+
|
93
|
+
unless @options[:dry_run]
|
94
|
+
params = chart_to_update_params(expected)
|
95
|
+
@client.spaces(space_id).charts(chart_id).put(params)
|
96
|
+
updated = true
|
97
|
+
end
|
98
|
+
|
99
|
+
updated
|
100
|
+
end
|
101
|
+
|
102
|
+
# Alert
|
103
|
+
|
104
|
+
def create_alert(name, expected)
|
105
|
+
updated = false
|
106
|
+
|
107
|
+
log(:info, "Create Alert `#{name}`", :color => :cyan)
|
108
|
+
|
109
|
+
unless @options[:dry_run]
|
110
|
+
params = alert_to_params(name, expected)
|
111
|
+
response = @client.alerts.post(params)
|
112
|
+
expected['id'] = response.fetch('id')
|
113
|
+
updated = true
|
114
|
+
end
|
115
|
+
|
116
|
+
updated
|
117
|
+
end
|
118
|
+
|
119
|
+
def delete_alert(name, actual)
|
120
|
+
updated = false
|
121
|
+
|
122
|
+
log(:info, "Delete Alert `#{name}`", :color => :red)
|
123
|
+
|
124
|
+
alert_id = actual.fetch('id')
|
125
|
+
|
126
|
+
unless @options[:dry_run]
|
127
|
+
@client.alerts(alert_id).delete
|
128
|
+
updated = true
|
129
|
+
end
|
130
|
+
|
131
|
+
updated
|
132
|
+
end
|
133
|
+
|
134
|
+
def update_alert(name, expected, actual)
|
135
|
+
updated = false
|
136
|
+
|
137
|
+
log(:info, "Update Alert `#{name}`", :color => :green)
|
138
|
+
log(:info, diff(Lbrt::Alert::DSL::Converter, {name => actual}, {name => expected}))
|
139
|
+
|
140
|
+
alert_id = actual.fetch('id')
|
141
|
+
|
142
|
+
unless @options[:dry_run]
|
143
|
+
params = alert_to_params(name, expected)
|
144
|
+
@client.alerts(alert_id).put(params)
|
145
|
+
updated = true
|
146
|
+
end
|
147
|
+
|
148
|
+
updated
|
149
|
+
end
|
150
|
+
|
151
|
+
# Service
|
152
|
+
|
153
|
+
def create_service(key, expected)
|
154
|
+
updated = false
|
155
|
+
type, title = key
|
156
|
+
|
157
|
+
log(:info, "Create Service `#{type}/#{title}`", :color => :cyan)
|
158
|
+
|
159
|
+
settings = expected.fetch('settings')
|
160
|
+
|
161
|
+
unless @options[:dry_run]
|
162
|
+
response = @client.services.post(
|
163
|
+
'title' => title,
|
164
|
+
'type' => type,
|
165
|
+
'settings' => settings
|
166
|
+
)
|
167
|
+
|
168
|
+
expected['id'] = response.fetch('id')
|
169
|
+
updated = true
|
170
|
+
end
|
171
|
+
|
172
|
+
updated
|
173
|
+
end
|
174
|
+
|
175
|
+
def delete_service(key, actual)
|
176
|
+
updated = false
|
177
|
+
type, title = key
|
178
|
+
|
179
|
+
log(:info, "Delete Service `#{type}/#{title}`", :color => :red)
|
180
|
+
|
181
|
+
service_id = actual.fetch('id')
|
182
|
+
|
183
|
+
unless @options[:dry_run]
|
184
|
+
@client.services(service_id).delete
|
185
|
+
updated = true
|
186
|
+
end
|
187
|
+
|
188
|
+
updated
|
189
|
+
end
|
190
|
+
|
191
|
+
def update_service(key, expected, actual)
|
192
|
+
updated = false
|
193
|
+
type, title = key
|
194
|
+
|
195
|
+
log(:info, "Update Service `#{type}/#{title}`", :color => :green)
|
196
|
+
log(:info, diff(Lbrt::Service::DSL::Converter, {key => actual}, {key => expected}))
|
197
|
+
|
198
|
+
service_id = actual.fetch('id')
|
199
|
+
settings = expected.fetch('settings')
|
200
|
+
|
201
|
+
unless @options[:dry_run]
|
202
|
+
@client.services(service_id).put(
|
203
|
+
'settings' => settings
|
204
|
+
)
|
205
|
+
|
206
|
+
updated = true
|
207
|
+
end
|
208
|
+
|
209
|
+
updated
|
210
|
+
end
|
211
|
+
|
212
|
+
private
|
213
|
+
|
214
|
+
def diff(converter, obj1, obj2)
|
215
|
+
diffy = Diffy::Diff.new(
|
216
|
+
converter.convert(obj1),
|
217
|
+
converter.convert(obj2),
|
218
|
+
:diff => '-u'
|
219
|
+
)
|
220
|
+
|
221
|
+
diffy.to_s(@options[:color] ? :color : :text).gsub(/\s+\z/m, '')
|
222
|
+
end
|
223
|
+
|
224
|
+
def alert_to_params(name, alert)
|
225
|
+
params = alert.dup
|
226
|
+
params['name'] = name
|
227
|
+
params['services'] = params.fetch('services').map {|i| i.fetch('id') }
|
228
|
+
params
|
229
|
+
end
|
230
|
+
|
231
|
+
def chart_to_update_params(chat)
|
232
|
+
params = chat.dup
|
233
|
+
# XXX: Correct?
|
234
|
+
params['chart_type'] = params.delete('type')
|
235
|
+
params['max'] ||= nil
|
236
|
+
params['min'] ||= nil
|
237
|
+
params['label'] ||= nil
|
238
|
+
params
|
239
|
+
end
|
240
|
+
end
|