-
Notifications
You must be signed in to change notification settings - Fork 0
/
alarm-resource.rb
150 lines (124 loc) · 3.8 KB
/
alarm-resource.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
require 'json'
require 'set'
class ResourceValidationException < Exception
end
class AlarmResource
attr_reader :name
def self.parse(name, resource_value)
AlarmResource.new(name, resource_value)
end
def initialize(name, resource_value)
@name = name
@resource_value = resource_value
validate
end
def to_s
"AWS::CloudWatch::Alarm:
name: #{@name},
namespace: #{namespace},
statistic: #{statistic},
period: #{period},
evaluation_periods: #{evaluation_periods},
threshold: #{threshold},
comparison_operator: #{comparison_operator}"
end
def properties
@resource_value["Properties"]
end
def metric
properties && properties["MetricName"]
end
def namespace
properties && properties["Namespace"]
end
def statistic
properties && properties["Statistic"]
end
def period
properties && properties["Period"] && properties["Period"].to_i
end
def evaluation_periods
properties && properties["EvaluationPeriods"] && properties["EvaluationPeriods"].to_i
end
def threshold
properties && properties["Threshold"] && properties["Threshold"].to_i
end
def comparison_operator
properties && properties["ComparisonOperator"]
end
def alarm_cpu?(cpu_usage)
if metric == "CPUUtilization" then
compare(cpu_usage, threshold, comparison_operator)
else
false
end
end
def alarm_memory?(memory_usage)
if metric == "MemoryUtilization" then
compare(memory_usage, threshold, comparison_operator)
else
false
end
end
private
def compare(actual_value, threshold, operator)
if operator == "GreaterThanOrEqualToThreshold" then
actual_value >= threshold
elsif operator == "GreaterThanThreshold" then
actual_value > threshold
elsif operator == "LessThanThreshold" then
actual_value < threshold
elsif operator == "LessThanOrEqualToThreshold" then
actual_value <= threshold
else
validation_error("Unsupported comparison operator: " + operator)
end
end
def validate
warning("Unsupported period: " + period.to_s + ". Only 60 seconds is supported.") unless period == 60
warning("Unsupported evaluation_periods: " + evaluation_periods.to_s + ". Only 1 period is supported.") unless evaluation_periods == 1
validation_error("Unsupported metric: " + metric) unless ["MemoryUtilization", "CPUUtilization"].member?(metric)
validation_error("Unsupported statistic: " + statistic ) unless statistic == "Average"
validation_error("Unsupported comparison operator: " + comparison_operator) unless [ "GreaterThanOrEqualToThreshold", "GreaterThanThreshold", "LessThanThreshold", "LessThanOrEqualToThreshold"].member?(comparison_operator)
end
def validation_error(message)
raise ResourceValidationException.new(@name + message)
end
def warning(message)
puts message
end
end
class TemplateUtils
def self.template_as_json(file_path)
JSON.parse(File.read(file_path))
end
def self.get_resource_type(resource_value)
resource_value["Type"]
end
def self.alarm_resource?(resource_value)
self.get_resource_type(resource_value) == "AWS::CloudWatch::Alarm"
end
end
class AlarmUtils
def self.collect_alarms_from_template(file_path)
template_content = TemplateUtils.template_as_json(file_path)
template_resources = template_content["Resources"]
alarms = []
if template_resources then
template_resources.each do |k, v|
alarms << AlarmResource.parse(k, v) if TemplateUtils.alarm_resource?(v)
end
else
puts "Error: Could not find resources in the template file"
exit 1
end
alarms
end
def self.collect_metrics(alarm_resources)
result = Set.new
alarm_resources.each do |resource|
result.add(resource.metric)
end
result.to_a
end
end