watch_list 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.travis.yml +12 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +99 -0
- data/Rakefile +5 -0
- data/bin/watch_list +122 -0
- data/lib/watch_list.rb +27 -0
- data/lib/watch_list/client.rb +156 -0
- data/lib/watch_list/constants.rb +16 -0
- data/lib/watch_list/driver.rb +146 -0
- data/lib/watch_list/dsl.rb +11 -0
- data/lib/watch_list/dsl/context.rb +40 -0
- data/lib/watch_list/dsl/context/alert_contact.rb +33 -0
- data/lib/watch_list/dsl/context/monitor.rb +82 -0
- data/lib/watch_list/dsl/context/monitor/http.rb +13 -0
- data/lib/watch_list/dsl/context/monitor/keyword.rb +30 -0
- data/lib/watch_list/dsl/context/monitor/ping.rb +4 -0
- data/lib/watch_list/dsl/context/monitor/port.rb +30 -0
- data/lib/watch_list/dsl/context/monitor/type.rb +24 -0
- data/lib/watch_list/dsl/converter.rb +107 -0
- data/lib/watch_list/exporter.rb +145 -0
- data/lib/watch_list/ext/string_ext.rb +25 -0
- data/lib/watch_list/logger.rb +30 -0
- data/lib/watch_list/utils.rb +14 -0
- data/lib/watch_list/version.rb +3 -0
- data/spec/alert_contact_spec.rb +153 -0
- data/spec/monitor_spec.rb +303 -0
- data/spec/paused_spec.rb +69 -0
- data/spec/spec_helper.rb +149 -0
- data/spec/status_spec.rb +31 -0
- data/watch_list.gemspec +27 -0
- metadata +154 -0
@@ -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,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
|