watch_list 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.
@@ -0,0 +1,107 @@
1
+ class WatchList::DSL::Converter
2
+ TYPE_ATTRS = [
3
+ :SubType,
4
+ :Port,
5
+ :KeywordType,
6
+ :KeywordValue,
7
+ :HTTPUsername,
8
+ :HTTPPassword,
9
+ ]
10
+
11
+ class << self
12
+ def convert(exported, opts = {})
13
+ self.new(exported, opts).convert
14
+ end
15
+ end # of class methods
16
+
17
+ def initialize(exported, options = {})
18
+ @exported = exported
19
+ @options = options
20
+ end
21
+
22
+ def convert
23
+ [
24
+ output_monitors(@exported[:monitors]),
25
+ output_alert_contacts(@exported[:alert_contacts]),
26
+ ].join("\n\n")
27
+ end
28
+
29
+ private
30
+
31
+ def output_monitors(monitors)
32
+ (monitors || []).map {|friendlyname, monitor|
33
+ output_monitor(monitor)
34
+ }.join("\n\n")
35
+ end
36
+
37
+ def output_monitor(monitor)
38
+ alert_contacts = monitor[:AlertContacts]
39
+ has_type_attr = TYPE_ATTRS.any? {|i| monitor[i] }
40
+ monitor_type = WatchList::Monitor::Type.key(monitor[:Type]).to_sym
41
+ paused = (monitor[:Status] == UptimeRobot::Monitor::Status::Paused)
42
+
43
+ output {|buf|
44
+ buf << "monitor #{monitor[:FriendlyName].inspect} do"
45
+ buf << " target #{monitor[:URL].inspect}"
46
+ buf << " interval #{monitor[:Interval].inspect}"
47
+ buf << " paused #{paused.inspect}"
48
+
49
+ unless alert_contacts.empty?
50
+ output_monitor_alert_contacts(alert_contacts, buf)
51
+ end
52
+
53
+ buf << ""
54
+ buf << " type #{monitor_type.inspect}" + (has_type_attr ? " do" : "")
55
+
56
+ if has_type_attr
57
+ output_monitor_type_attrs(monitor, buf)
58
+ buf << " end"
59
+ end
60
+
61
+ buf << "end"
62
+ }.join("\n")
63
+ end
64
+
65
+ def output_monitor_alert_contacts(alert_contacts, buf)
66
+ alert_contacts.each do |alert_contact|
67
+ type = WatchList::AlertContact::Type.key(alert_contact[:Type]).to_sym
68
+ buf << " alert_contact #{type.inspect}, #{alert_contact[:Value].inspect}"
69
+ end
70
+ end
71
+
72
+ def output_monitor_type_attrs(monitor, buf)
73
+ TYPE_ATTRS.each do |key|
74
+ value = monitor[key]
75
+ next unless value
76
+
77
+ if WatchList::Monitor.const_defined?(key)
78
+ const = WatchList::Monitor.const_get(key)
79
+ buf << " #{key.to_s.downcase} " + const.key(value).to_sym.inspect
80
+ else
81
+ buf << " #{key.to_s.downcase} #{value.inspect}"
82
+ end
83
+ end
84
+ end
85
+
86
+ def output_alert_contacts(alert_contacts)
87
+ (alert_contacts || []).map {|alert_contact|
88
+ output_alert_contact(alert_contact)
89
+ }.join("\n\n")
90
+ end
91
+
92
+ def output_alert_contact(alert_contact)
93
+ alert_contact_type = WatchList::AlertContact::Type.key(alert_contact[:Type]).to_sym
94
+
95
+ output {|buf|
96
+ buf << "alert_contact do"
97
+ buf << " type #{alert_contact_type.inspect}"
98
+ buf << " value #{alert_contact[:Value].inspect}"
99
+ buf << "end"
100
+ }.join("\n")
101
+ end
102
+
103
+ def output(buf = [])
104
+ yield(buf)
105
+ buf
106
+ end
107
+ end
@@ -0,0 +1,145 @@
1
+ class WatchList::Exporter
2
+ class << self
3
+ def export(uptimerobot, opts = {})
4
+ self.new(uptimerobot, opts).export
5
+ end
6
+
7
+ def export_status(uptimerobot, opts = {})
8
+ self.new(uptimerobot, opts).export_status
9
+ end
10
+ end # of class methods
11
+
12
+ def initialize(uptimerobot, options = {})
13
+ @uptimerobot = uptimerobot
14
+ @options = options
15
+ end
16
+
17
+ def export
18
+ monitors = @uptimerobot.getMonitors(showMonitorAlertContacts: 1)
19
+ alert_contacts = @uptimerobot.getAlertContacts
20
+
21
+ {
22
+ :monitors => normalize_monitors(monitors),
23
+ :alert_contacts => normalize_alert_contacts(alert_contacts),
24
+ }
25
+ end
26
+
27
+ def export_status
28
+ monitors = @uptimerobot.getMonitors(
29
+ :logs => 1,
30
+ :responseTimes => 1,
31
+ :showTimezone => 1,
32
+ )
33
+
34
+ {
35
+ :timezone => monitors['timezone'],
36
+ :monitors => normalize_monitors_status(monitors),
37
+ }
38
+ end
39
+
40
+ private
41
+
42
+ def normalize_monitors(monitors)
43
+ monitors = monitors.fetch('monitors', {}).fetch('monitor', [])
44
+ monitor_hash = {}
45
+
46
+ monitors.each do |monitor|
47
+ friendlyname = monitor['friendlyname']
48
+ type = monitor['type'].to_i
49
+
50
+ monitor_hash[friendlyname] = {
51
+ :ID => monitor['id'],
52
+ :FriendlyName => friendlyname,
53
+ :URL => monitor['url'],
54
+ :Type => type,
55
+ :AlertContacts => monitor.fetch('alertcontact', []).map {|alert_contact|
56
+ {
57
+ :Type => alert_contact['type'].to_i,
58
+ :Value => alert_contact['value'],
59
+ }
60
+ },
61
+ :Interval => nil_if_blank(monitor['interval'], :to_i) / 60,
62
+ :Status => monitor['status'].to_i,
63
+ }
64
+
65
+ case WatchList::Monitor::Type.key(type)
66
+ when 'http'
67
+ monitor_hash[friendlyname].update(
68
+ :HTTPUsername => nil_if_blank(monitor['httpusername']),
69
+ :HTTPPassword => nil_if_blank(monitor['httppassword']),
70
+ )
71
+ when 'keyword'
72
+ monitor_hash[friendlyname].update(
73
+ :KeywordType => nil_if_blank(monitor['keywordtype'], :to_i),
74
+ :KeywordValue => nil_if_blank(monitor['keywordvalue']),
75
+ :HTTPUsername => nil_if_blank(monitor['httpusername']),
76
+ :HTTPPassword => nil_if_blank(monitor['httppassword']),
77
+ )
78
+ when 'ping'
79
+ when 'port'
80
+ monitor_hash[friendlyname].update(
81
+ :SubType => nil_if_blank(monitor['subtype'], :to_i),
82
+ :Port => nil_if_blank(monitor['port'], :to_i),
83
+ )
84
+ end
85
+ end
86
+
87
+ monitor_hash
88
+ end
89
+
90
+ def normalize_alert_contacts(alert_contacts)
91
+ alert_contacts = alert_contacts.fetch('alertcontacts', {}).fetch('alertcontact', [])
92
+
93
+ alert_contacts.map do |alert_contact|
94
+ {
95
+ :ID => alert_contact['id'],
96
+ :Type => alert_contact['type'].to_i,
97
+ :Value => alert_contact['value'],
98
+ }
99
+ end
100
+ end
101
+
102
+ def normalize_monitors_status(monitors)
103
+ monitors = monitors.fetch('monitors', {}).fetch('monitor', [])
104
+ monitor_hash = {}
105
+
106
+ monitors.each do |monitor|
107
+ friendlyname = monitor['friendlyname']
108
+
109
+ monitor_hash[friendlyname] = {
110
+ :status => WatchList::Monitor::Status.key(monitor['status'].to_i),
111
+ :alltimeuptimeratio => monitor['alltimeuptimeratio'].to_i,
112
+ :log => normalize_monitor_log(monitor),
113
+ :responsetime => normalize_monitor_responsetime(monitor),
114
+ }
115
+ end
116
+
117
+ monitor_hash
118
+ end
119
+
120
+ def normalize_monitor_log(monitor)
121
+ monitor.fetch('log', []).map do |log|
122
+ {
123
+ :datetime => log['datetime'],
124
+ :type => WatchList::Log::Type.key(log['type'].to_i),
125
+ }
126
+ end
127
+ end
128
+
129
+ def normalize_monitor_responsetime(monitor)
130
+ monitor.fetch('responsetime', []).map do |responsetime|
131
+ {
132
+ :datetime => responsetime['datetime'],
133
+ :value => responsetime['value'].to_i,
134
+ }
135
+ end
136
+ end
137
+
138
+ def nil_if_blank(str, conv = nil)
139
+ if str.empty?
140
+ nil
141
+ else
142
+ conv ? str.send(conv) : str
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,25 @@
1
+ class String
2
+ @@colorize = false
3
+
4
+ class << self
5
+ def colorize=(value)
6
+ @@colorize = value
7
+ end
8
+
9
+ def colorize
10
+ @@colorize
11
+ end
12
+ end # of class methods
13
+
14
+ Term::ANSIColor::Attribute.named_attributes.map do |attribute|
15
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
16
+ def #{attribute.name}
17
+ if @@colorize
18
+ Term::ANSIColor.send(#{attribute.name.inspect}, self)
19
+ else
20
+ self
21
+ end
22
+ end
23
+ EOS
24
+ end
25
+ end
@@ -0,0 +1,30 @@
1
+ class WatchList::Logger < ::Logger
2
+ include Singleton
3
+
4
+ def initialize
5
+ super($stdout)
6
+
7
+ self.formatter = proc do |severity, datetime, progname, msg|
8
+ "#{msg}\n"
9
+ end
10
+
11
+ self.level = INFO
12
+ end
13
+
14
+ def set_debug(value)
15
+ self.level = value ? DEBUG : INFO
16
+ end
17
+
18
+ module Helper
19
+ def log(level, message, opts = {})
20
+ opts = (@options || {}).merge(opts)
21
+
22
+ message = "[#{level.to_s.upcase}] #{message}" unless level == :info
23
+ message << ' (dry-run)' if opts[:dry_run]
24
+ message = message.send(opts[:color]) if opts[:color]
25
+
26
+ logger = opts[:logger] || WatchList::Logger.instance
27
+ logger.send(level, message)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,14 @@
1
+ class WatchList::Utils
2
+ class << self
3
+ def const_to_hash(const)
4
+ hash = {}
5
+
6
+ const.constants.map do |c|
7
+ key = c.to_s.gsub(/[A-Z]+/, '_\0').sub(/\A_/, '').downcase
8
+ hash[key] = const.const_get(c)
9
+ end
10
+
11
+ hash
12
+ end
13
+ end # of class methods
14
+ end
@@ -0,0 +1,3 @@
1
+ module WatchList
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,153 @@
1
+ describe 'alert contact' do
2
+ it do
3
+ watch_list do
4
+ <<-RUBY
5
+ alert_contact do
6
+ type :email
7
+ value "#{WATCH_LIST_TEST_EMAIL}"
8
+ end
9
+
10
+ alert_contact do
11
+ type :email
12
+ value "#{WATCH_LIST_TEST_EMAIL2}"
13
+ end
14
+ RUBY
15
+ end
16
+
17
+ expect(watch_list_export {|h| h[:alert_contacts].length > 1 }).to eq(
18
+ {:monitors=>{},
19
+ :alert_contacts=>
20
+ [{:Type=>2, :Value=>WATCH_LIST_TEST_EMAIL},
21
+ {:Type=>2, :Value=>WATCH_LIST_TEST_EMAIL2}]}
22
+ )
23
+
24
+ watch_list do
25
+ <<-RUBY
26
+ monitor "http monitor" do
27
+ target "http://example.com"
28
+ interval 5
29
+ paused false
30
+ alert_contact :email, "#{WATCH_LIST_TEST_EMAIL}"
31
+ alert_contact :email, "#{WATCH_LIST_TEST_EMAIL2}"
32
+ type :http
33
+ end
34
+
35
+ alert_contact do
36
+ type :email
37
+ value "#{WATCH_LIST_TEST_EMAIL}"
38
+ end
39
+
40
+ alert_contact do
41
+ type :email
42
+ value "#{WATCH_LIST_TEST_EMAIL2}"
43
+ end
44
+ RUBY
45
+ end
46
+
47
+ expect(watch_list_export {|h| h[:monitors].length > 0 }).to eq(
48
+ {:monitors=>
49
+ {"http monitor"=>
50
+ {:FriendlyName=>"http monitor",
51
+ :URL=>"http://example.com",
52
+ :Type=>1,
53
+ :HTTPUsername=>nil,
54
+ :HTTPPassword=>nil,
55
+ :AlertContacts=>
56
+ [{:Type=>2, :Value=>WATCH_LIST_TEST_EMAIL},
57
+ {:Type=>2, :Value=>WATCH_LIST_TEST_EMAIL2}],
58
+ :Interval=>5}},
59
+ :alert_contacts=>
60
+ [{:Type=>2, :Value=>WATCH_LIST_TEST_EMAIL},
61
+ {:Type=>2, :Value=>WATCH_LIST_TEST_EMAIL2}]}
62
+ )
63
+
64
+ watch_list do
65
+ <<-RUBY
66
+ monitor "http monitor" do
67
+ target "http://example.com"
68
+ interval 5
69
+ paused false
70
+ alert_contact :email, "#{WATCH_LIST_TEST_EMAIL}"
71
+ type :http
72
+ end
73
+
74
+ alert_contact do
75
+ type :email
76
+ value "#{WATCH_LIST_TEST_EMAIL}"
77
+ end
78
+
79
+ alert_contact do
80
+ type :email
81
+ value "#{WATCH_LIST_TEST_EMAIL2}"
82
+ end
83
+ RUBY
84
+ end
85
+
86
+ expect(watch_list_export {|h| h[:monitors]['http monitor'][:AlertContacts].length < 2 }).to eq(
87
+ {:monitors=>
88
+ {"http monitor"=>
89
+ {:FriendlyName=>"http monitor",
90
+ :URL=>"http://example.com",
91
+ :Type=>1,
92
+ :HTTPUsername=>nil,
93
+ :HTTPPassword=>nil,
94
+ :AlertContacts=>
95
+ [{:Type=>2, :Value=>WATCH_LIST_TEST_EMAIL}],
96
+ :Interval=>5}},
97
+ :alert_contacts=>
98
+ [{:Type=>2, :Value=>WATCH_LIST_TEST_EMAIL},
99
+ {:Type=>2, :Value=>WATCH_LIST_TEST_EMAIL2}]}
100
+ )
101
+
102
+ watch_list do
103
+ <<-RUBY
104
+ monitor "http monitor" do
105
+ target "http://example.com"
106
+ interval 5
107
+ paused false
108
+ alert_contact :email, "#{WATCH_LIST_TEST_EMAIL2}"
109
+ type :http
110
+ end
111
+
112
+ alert_contact do
113
+ type :email
114
+ value "#{WATCH_LIST_TEST_EMAIL}"
115
+ end
116
+
117
+ alert_contact do
118
+ type :email
119
+ value "#{WATCH_LIST_TEST_EMAIL2}"
120
+ end
121
+ RUBY
122
+ end
123
+
124
+ expect(watch_list_export {|h| h[:monitors]['http monitor'][:AlertContacts][0][:Value] != WATCH_LIST_TEST_EMAIL }).to eq(
125
+ {:monitors=>
126
+ {"http monitor"=>
127
+ {:FriendlyName=>"http monitor",
128
+ :URL=>"http://example.com",
129
+ :Type=>1,
130
+ :HTTPUsername=>nil,
131
+ :HTTPPassword=>nil,
132
+ :AlertContacts=>
133
+ [{:Type=>2, :Value=>WATCH_LIST_TEST_EMAIL2}],
134
+ :Interval=>5}},
135
+ :alert_contacts=>
136
+ [{:Type=>2, :Value=>WATCH_LIST_TEST_EMAIL},
137
+ {:Type=>2, :Value=>WATCH_LIST_TEST_EMAIL2}]}
138
+ )
139
+
140
+ watch_list do
141
+ <<-RUBY
142
+ alert_contact do
143
+ type :email
144
+ value "#{WATCH_LIST_TEST_EMAIL}"
145
+ end
146
+ RUBY
147
+ end
148
+
149
+ expect(watch_list_export {|h| h[:monitors].length < 1 }).to eq(
150
+ {:monitors=>{}, :alert_contacts=>[{:Type=>2, :Value=>WATCH_LIST_TEST_EMAIL}]}
151
+ )
152
+ end
153
+ end