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,16 @@
1
+ module WatchList
2
+ module Monitor
3
+ Type = WatchList::Utils.const_to_hash(UptimeRobot::Monitor::Type)
4
+ SubType = WatchList::Utils.const_to_hash(UptimeRobot::Monitor::SubType)
5
+ KeywordType = WatchList::Utils.const_to_hash(UptimeRobot::Monitor::KeywordType)
6
+ Status = WatchList::Utils.const_to_hash(UptimeRobot::Monitor::Status)
7
+ end
8
+
9
+ module Log
10
+ Type = WatchList::Utils.const_to_hash(UptimeRobot::Log::Type)
11
+ end
12
+
13
+ module AlertContact
14
+ Type = WatchList::Utils.const_to_hash(UptimeRobot::AlertContact::Type)
15
+ end
16
+ end
@@ -0,0 +1,146 @@
1
+ class WatchList::Driver
2
+ include WatchList::Logger::Helper
3
+
4
+ def initialize(uptimerobot, opts = {})
5
+ @uptimerobot = uptimerobot
6
+ @options = opts
7
+ end
8
+
9
+ def new_alert_contact(attrs)
10
+ updated = false
11
+ log(:info, "Create AlertContact: #{describe_alert_contacts(attrs)}", :color => :cyan)
12
+
13
+ unless @options[:dry_run]
14
+ response = @uptimerobot.newAlertContact(
15
+ :alertContactType => attrs[:Type],
16
+ :alertContactValue => attrs[:Value],
17
+ )
18
+
19
+ attrs[:ID] = response['alertcontact']['id']
20
+ updated = true
21
+ end
22
+
23
+ updated
24
+ end
25
+
26
+ def delete_alert_contact(attrs)
27
+ updated = false
28
+ log(:info, "Delete AlertContact: #{describe_alert_contacts(attrs)}", :color => :red)
29
+
30
+ unless @options[:dry_run]
31
+ @uptimerobot.deleteAlertContact(
32
+ :alertContactID => attrs[:ID],
33
+ )
34
+
35
+ updated = true
36
+ end
37
+
38
+ updated
39
+ end
40
+
41
+ def new_monitor(attrs, exist_alert_contacts)
42
+ updated = false
43
+ log(:info, "Create Monitor: #{attrs[:FriendlyName]}", :color => :cyan)
44
+
45
+ unless @options[:dry_run]
46
+ normalize_edit_attrs!(attrs)
47
+ params = monitor_to_params(attrs, exist_alert_contacts)
48
+ response = @uptimerobot.newMonitor(params)
49
+ attrs[:ID] = response['monitor']['id']
50
+ updated = true
51
+ end
52
+
53
+ updated
54
+ end
55
+
56
+ def delete_monitor(attrs)
57
+ updated = false
58
+ log(:info, "Delete Monitor: #{attrs[:FriendlyName]}", :color => :red)
59
+
60
+ unless @options[:dry_run]
61
+ @uptimerobot.deleteMonitor(
62
+ :monitorID => attrs[:ID],
63
+ )
64
+
65
+ updated = true
66
+ end
67
+
68
+ updated
69
+ end
70
+
71
+ def edit_monitor(monitor_id, monitor_name, attrs, exist_alert_contacts)
72
+ updated = false
73
+ log(:info, "Update Monitor: #{monitor_name}", :color => :green)
74
+
75
+ attrs.each do |key, value|
76
+ log(:info, " set #{key}=#{value}", :color => :green)
77
+ end
78
+
79
+ unless @options[:dry_run]
80
+ params = monitor_to_params(attrs, exist_alert_contacts)
81
+ params[:monitorID] = monitor_id
82
+ @uptimerobot.editMonitor(params)
83
+ updated = true
84
+ end
85
+
86
+ updated
87
+ end
88
+
89
+ def pause_monitor(monitor_id, monitor_name, paused)
90
+ updated = false
91
+ log(:info, (paused ? 'Pause' : 'Unpause') + " Monitor: #{monitor_name}", :color => :green)
92
+
93
+ unless @options[:dry_run]
94
+ @uptimerobot.editMonitor(
95
+ :monitorID => monitor_id,
96
+ :monitorStatus => (paused ? 0 : 1),
97
+ )
98
+
99
+ updated = true
100
+ end
101
+
102
+ updated
103
+ end
104
+
105
+ private
106
+
107
+ def describe_alert_contacts(attrs)
108
+ type = WatchList::AlertContact::Type.key(attrs[:Type])
109
+ "#{type}, #{attrs[:Value]}"
110
+ end
111
+
112
+ def monitor_to_params(attrs, exist_alert_contacts)
113
+ params = {}
114
+ attrs = attrs.dup
115
+ attrs.delete(:Paused)
116
+ alert_contacts = attrs.delete(:AlertContacts) || []
117
+
118
+ attrs.each do |key, value|
119
+ params["monitor#{key}"] = value unless value.nil?
120
+ end
121
+
122
+ unless alert_contacts.empty?
123
+ params[:monitorAlertContacts] = alert_contacts.map {|alert_contact|
124
+ exist_alert_contact = exist_alert_contacts.find {|i|
125
+ i.values_at(:Type, :Value) == alert_contact.values_at(:Type, :Value)
126
+ }
127
+
128
+ raise "AlertContact does not exist: #{alert_contact.inspect}" unless exist_alert_contact
129
+
130
+ exist_alert_contact[:ID]
131
+ }.join(',')
132
+ end
133
+
134
+ params
135
+ end
136
+
137
+ def normalize_edit_attrs!(attrs)
138
+ # XXX: Other parameter is required in order to update the "HTTPUsername" and "HTTPPassword"
139
+ attrs[:Interval] ||= expected[:Interval]
140
+
141
+ # Remove by an empty parameter
142
+ attrs.keys.each do |key|
143
+ attrs[key] ||= ''
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,11 @@
1
+ class WatchList::DSL
2
+ class << self
3
+ def convert(exported, opts = {})
4
+ WatchList::DSL::Converter.convert(exported, opts)
5
+ end
6
+
7
+ def parse(dsl, path, opts = {})
8
+ WatchList::DSL::Context.eval(dsl, path, opts).result
9
+ end
10
+ end # of class methods
11
+ end
@@ -0,0 +1,40 @@
1
+ class WatchList::DSL::Context
2
+ class << self
3
+ def eval(dsl, path, opts = {})
4
+ self.new(path, opts) {
5
+ Kernel.eval(dsl, binding, path)
6
+ }
7
+ end
8
+ end # of class methods
9
+
10
+ attr_reader :result
11
+
12
+ def initialize(path, options = {}, &block)
13
+ @path = path
14
+ @options = options
15
+ @result = {:monitors => {}, :alert_contacts => []}
16
+ instance_eval(&block)
17
+ end
18
+
19
+ def require(file)
20
+ robotfile = File.expand_path(File.join(File.dirname(@path), file))
21
+
22
+ if File.exist?(robotfile)
23
+ instance_eval(File.read(robotfile), robotfile)
24
+ elsif File.exist?(robotfile + '.rb')
25
+ instance_eval(File.read(robotfile + '.rb'), robotfile + '.rb')
26
+ else
27
+ Kernel.require(file)
28
+ end
29
+ end
30
+
31
+ def monitor(name, &block)
32
+ raise 'Monitor: "friendlyname" is required' unless name
33
+ raise "Monitor `#{name}` is already defined" if @result[:monitors][name]
34
+ @result[:monitors][name] = WatchList::DSL::Context::Monitor.new(name, &block).result
35
+ end
36
+
37
+ def alert_contact(&block)
38
+ @result[:alert_contacts] << WatchList::DSL::Context::AlertContact.new(&block).result
39
+ end
40
+ end
@@ -0,0 +1,33 @@
1
+ class WatchList::DSL::Context::AlertContact
2
+ def initialize(&block)
3
+ @result = {}
4
+ instance_eval(&block)
5
+ end
6
+
7
+ def result
8
+ [:Type, :Value].each do |key|
9
+ raise %!AlertContact: "#{key.to_s.downcase}" is required! unless @result[key]
10
+ end
11
+
12
+ @result
13
+ end
14
+
15
+ def type(value, &block)
16
+ if value.kind_of?(Integer)
17
+ alert_contact_type = value
18
+ else
19
+ alert_contact_type = WatchList::AlertContact::Type[value.to_s]
20
+ end
21
+
22
+ unless WatchList::AlertContact::Type.values.include?(alert_contact_type)
23
+ raise %!AlertContact: "type" is invalid: #{value.inspect}!
24
+ end
25
+
26
+ @result[:Type] = alert_contact_type
27
+ end
28
+
29
+ def value(value)
30
+ raise %!AlertContact: "value" is invalid: #{value.inspect}! if value.nil?
31
+ @result[:Value] = value.to_s
32
+ end
33
+ end
@@ -0,0 +1,82 @@
1
+ class WatchList::DSL::Context::Monitor
2
+ def initialize(name, &block)
3
+ @name = name
4
+
5
+ @result = {
6
+ :FriendlyName => name,
7
+ :Paused => false,
8
+ :AlertContacts => [],
9
+ }
10
+
11
+ instance_eval(&block)
12
+ end
13
+
14
+ def result
15
+ raise %!Monitor `#{@name}`: "target" is required! unless @result[:URL]
16
+
17
+ [:Interval, :Type].each do |key|
18
+ raise %!Monitor `#{@name}`: "#{key.to_s.downcase}" is required! unless @result[key]
19
+ end
20
+
21
+ @result
22
+ end
23
+
24
+ def target(value)
25
+ raise %!Monitor `#{@name}`: "target" is invalid: #{value.inspect}! if value.nil?
26
+ @result[:URL] = value.to_s
27
+ end
28
+
29
+ def interval(value)
30
+ raise %!Monitor `#{@name}`: "interval" is invalid: #{value.inspect}! unless value.kind_of?(Integer)
31
+ @result[:Interval] = value
32
+ end
33
+
34
+ def paused(value)
35
+ unless [TrueClass, FalseClass].any? {|i| value.kind_of?(i) }
36
+ raise %!Monitor `#{@name}`: "paused" is invalid: #{value.inspect}!
37
+ end
38
+
39
+ @result[:Paused] = value
40
+ end
41
+
42
+ def alert_contact(type, value)
43
+ if type.kind_of?(Integer)
44
+ alert_contact_type = type
45
+ else
46
+ alert_contact_type = WatchList::AlertContact::Type[type.to_s]
47
+ end
48
+
49
+ unless WatchList::AlertContact::Type.values.include?(alert_contact_type)
50
+ raise %!Monitor `#{@name}`: "alert_contact" type is invalid: #{type.inspect}!
51
+ end
52
+
53
+ raise %!Monitor `#{@name}`: "alert_contact" value is invalid: #{value.inspect}! if value.nil?
54
+
55
+ hash = {:Type => alert_contact_type, :Value => value.to_s}
56
+
57
+ if @result[:AlertContacts].include?(hash)
58
+ raise %!Monitor `#{@name}`: "alert_contact"(#{type}, #{value}) is already defined!
59
+ end
60
+
61
+ @result[:AlertContacts] << hash
62
+ end
63
+
64
+ def type(value, &block)
65
+ if value.kind_of?(Integer)
66
+ monitor_type = value
67
+ else
68
+ monitor_type = WatchList::Monitor::Type[value.to_s]
69
+ end
70
+
71
+ unless WatchList::Monitor::Type.values.include?(monitor_type)
72
+ raise %!Monitor `#{@name}`: "type" is invalid: #{value.inspect}!
73
+ end
74
+
75
+ @result[:Type] = monitor_type
76
+
77
+ type_class = WatchList::DSL::Context::Monitor::Type[value.to_s]
78
+ raise "Monitor `#{@name}`: #{value.inspect} is unimplemented type" unless type_class
79
+
80
+ @result.update(type_class.new(@name, &block).result)
81
+ end
82
+ end
@@ -0,0 +1,13 @@
1
+ class WatchList::DSL::Context::Monitor
2
+ class HTTP < Type
3
+ def httpusername(value)
4
+ raise %!Monitor `#{@monitor_name}`: "httpusername" is invalid: #{value.inspect}! if value.nil?
5
+ @result[:HTTPUsername] = value.to_s
6
+ end
7
+
8
+ def httppassword(value)
9
+ raise %!Monitor `#{@monitor_name}`: "httppassword" is invalid: #{value.inspect}! if value.nil?
10
+ @result[:HTTPPassword] = value.to_s
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,30 @@
1
+ class WatchList::DSL::Context::Monitor
2
+ class Keyword < HTTP
3
+ def result
4
+ [:KeywordType, :KeywordValue].each do |key|
5
+ raise %!Monitor `#{@monitor_name}`: "#{key.to_s.downcase}" is required! unless @result[key]
6
+ end
7
+
8
+ super
9
+ end
10
+
11
+ def keywordtype(value)
12
+ if value.kind_of?(Integer)
13
+ type = value
14
+ else
15
+ type = WatchList::Monitor::KeywordType[value.to_s]
16
+ end
17
+
18
+ unless WatchList::Monitor::KeywordType.values.include?(type)
19
+ raise %!Monitor `#{@monitor_name}`: "keywordtype" is invalid: #{value.inspect}!
20
+ end
21
+
22
+ @result[:KeywordType] = type
23
+ end
24
+
25
+ def keywordvalue(value)
26
+ raise %!Monitor `#{@monitor_name}`: "keywordvalue" is invalid: #{value.inspect}! if value.nil?
27
+ @result[:KeywordValue] = value.to_s
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,4 @@
1
+ class WatchList::DSL::Context::Monitor
2
+ class Ping < Type
3
+ end
4
+ end
@@ -0,0 +1,30 @@
1
+ class WatchList::DSL::Context::Monitor
2
+ class Port < Type
3
+ def result
4
+ [:SubType, :Port].each do |key|
5
+ raise %!Monitor `#{@monitor_name}`: "#{key.to_s.downcase}" is required! unless @result[key]
6
+ end
7
+
8
+ super
9
+ end
10
+
11
+ def subtype(value)
12
+ if value.kind_of?(Integer)
13
+ type = value
14
+ else
15
+ type = WatchList::Monitor::SubType[value.to_s]
16
+ end
17
+
18
+ unless WatchList::Monitor::SubType.values.include?(type)
19
+ raise %!Monitor `#{@monitor_name}`: "subtype" is invalid: #{value.inspect}!
20
+ end
21
+
22
+ @result[:SubType] = type
23
+ end
24
+
25
+ def port(value)
26
+ raise %!Monitor `#{@monitor_name}`: "port" is invalid: #{value.inspect}! unless value.kind_of?(Integer)
27
+ @result[:Port] = value
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,24 @@
1
+ class WatchList::DSL::Context::Monitor::Type
2
+ CHILDREN = {}
3
+
4
+ class << self
5
+ def inherited(child)
6
+ name = child.to_s.split('::').last.downcase
7
+ CHILDREN[name] = child
8
+ end
9
+
10
+ def [](name)
11
+ CHILDREN[name]
12
+ end
13
+ end # of class methods
14
+
15
+ def initialize(monitor_name, &block)
16
+ @monitor_name = monitor_name
17
+ @result = {}
18
+ instance_eval(&block) if block
19
+ end
20
+
21
+ def result
22
+ @result
23
+ end
24
+ end