cfn-guardian 0.3.4 → 0.6.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build-gem.yml +25 -0
  3. data/.github/workflows/release-gem.yml +25 -0
  4. data/.github/workflows/release-image.yml +33 -0
  5. data/.rspec +1 -0
  6. data/Gemfile.lock +24 -24
  7. data/README.md +4 -772
  8. data/cfn-guardian.gemspec +1 -3
  9. data/docs/alarm_templates.md +130 -0
  10. data/docs/cli.md +182 -0
  11. data/docs/composite_alarms.md +24 -0
  12. data/docs/custom_checks/azure_file_check.md +28 -0
  13. data/docs/custom_checks/domain_expiry.md +10 -0
  14. data/docs/custom_checks/http.md +59 -0
  15. data/docs/custom_checks/log_group_metric_filters.md +27 -0
  16. data/docs/custom_checks/nrpe.md +29 -0
  17. data/docs/custom_checks/port.md +40 -0
  18. data/docs/custom_checks/sftp.md +73 -0
  19. data/docs/custom_checks/sql.md +44 -0
  20. data/docs/custom_checks/tls.md +25 -0
  21. data/docs/custom_metrics.md +71 -0
  22. data/docs/event_subscriptions.md +67 -0
  23. data/docs/maintenance_mode.md +85 -0
  24. data/docs/notifiers.md +33 -0
  25. data/docs/overview.md +22 -0
  26. data/docs/resources.md +93 -0
  27. data/docs/variables.md +58 -0
  28. data/lib/cfnguardian.rb +76 -62
  29. data/lib/cfnguardian/cloudwatch.rb +43 -32
  30. data/lib/cfnguardian/compile.rb +90 -4
  31. data/lib/cfnguardian/config/defaults.yaml +9 -0
  32. data/lib/cfnguardian/deploy.rb +2 -16
  33. data/lib/cfnguardian/display_formatter.rb +1 -2
  34. data/lib/cfnguardian/error.rb +4 -0
  35. data/lib/cfnguardian/models/alarm.rb +102 -30
  36. data/lib/cfnguardian/models/check.rb +30 -12
  37. data/lib/cfnguardian/models/event.rb +43 -15
  38. data/lib/cfnguardian/models/event_subscription.rb +111 -0
  39. data/lib/cfnguardian/resources/amazonmq_rabbitmq.rb +136 -0
  40. data/lib/cfnguardian/resources/azure_file.rb +20 -0
  41. data/lib/cfnguardian/resources/base.rb +126 -26
  42. data/lib/cfnguardian/resources/batch.rb +14 -0
  43. data/lib/cfnguardian/resources/ec2_instance.rb +11 -0
  44. data/lib/cfnguardian/resources/glue.rb +23 -0
  45. data/lib/cfnguardian/resources/http.rb +1 -0
  46. data/lib/cfnguardian/resources/rds_cluster.rb +14 -0
  47. data/lib/cfnguardian/resources/rds_instance.rb +80 -0
  48. data/lib/cfnguardian/resources/redshift_cluster.rb +2 -2
  49. data/lib/cfnguardian/resources/step_functions.rb +41 -0
  50. data/lib/cfnguardian/stacks/main.rb +9 -8
  51. data/lib/cfnguardian/stacks/resources.rb +35 -6
  52. data/lib/cfnguardian/version.rb +1 -1
  53. metadata +39 -10
@@ -9,50 +9,61 @@ module CfnGuardian
9
9
  alarm_id = alarm.resource_name.nil? ? alarm.resource_id : alarm.resource_name
10
10
  return "guardian-#{alarm.group}-#{alarm_id}-#{alarm.name}"
11
11
  end
12
-
13
- def self.get_alarms(alarms)
14
- alarm_names = alarms.map {|alarm| self.get_alarm_name(alarm)}
15
-
12
+
13
+ def self.get_alarms_by_prefix(prefix:, state: nil, action_prefix: nil)
16
14
  client = Aws::CloudWatch::Client.new()
15
+ options = {max_records: 100}
16
+ options[:alarm_name_prefix] = prefix
17
+
18
+ unless state.nil?
19
+ options[:state_value] = state
20
+ end
21
+
22
+ unless action_prefix.nil?
23
+ options[:action_prefix] = action_prefix
24
+ end
25
+
26
+ resp = client.describe_alarms(options)
27
+ return resp.metric_alarms
28
+ end
29
+
30
+ def self.get_alarms_by_name(alarm_names:, state: nil, action_prefix: nil)
31
+ client = Aws::CloudWatch::Client.new()
32
+ options = {max_records: 100}
33
+
34
+ unless state.nil?
35
+ options[:state_value] = state
36
+ end
37
+
38
+ unless action_prefix.nil?
39
+ options[:action_prefix] = "arn:aws:sns:#{Aws.config[:region]}:#{aws_account_id()}:#{action_prefix}"
40
+ end
41
+
17
42
  metric_alarms = []
18
43
  alarm_names.each_slice(100) do |batch|
19
- resp = client.describe_alarms({alarm_names: batch, max_records: 100})
44
+ options[:alarm_names] = batch
45
+ resp = client.describe_alarms(options)
20
46
  metric_alarms.push(*resp.metric_alarms)
21
47
  end
22
-
48
+
23
49
  return metric_alarms
24
50
  end
25
-
26
- def self.get_alarm_state(config_alarms: [], alarm_names: [], alarm_prefix: nil, state: nil)
27
- rows = []
28
-
29
- if config_alarms.any?
30
- alarm_names = config_alarms.map {|alarm| self.get_alarm_name(alarm)}
31
- end
32
-
33
- client = Aws::CloudWatch::Client.new()
34
-
35
- options = {max_records: 100}
36
- options[:state_value] = state if !state.nil?
37
-
38
- cw_alarms = []
39
- if !alarm_prefix.nil?
40
- options[:alarm_name_prefix] = alarm_prefix
41
- resp = client.describe_alarms(options)
42
- cw_alarms = resp.metric_alarms
43
- else
44
- alarm_names.each_slice(100) do |batch|
45
- options[:alarm_names] = batch
46
- resp = client.describe_alarms(options)
47
- cw_alarms.push(*resp.metric_alarms)
51
+
52
+ def self.filter_alarms(filters:, alarms:)
53
+ return alarms unless filters.is_a?(Hash)
54
+ filters = filters.slice('group', 'resource', 'alarm', 'stack-id')
55
+
56
+ filtered_alarms = []
57
+ alarms.each do |alarm|
58
+ if filters.values.all? {|filter| alarm.alarm_name.include? (filter)}
59
+ filtered_alarms << alarm
48
60
  end
49
61
  end
50
-
51
- return cw_alarms
62
+
63
+ return filtered_alarms
52
64
  end
53
65
 
54
66
  def self.get_alarm_history(alarm_name,type)
55
- rows = []
56
67
  client = Aws::CloudWatch::Client.new()
57
68
 
58
69
  logger.debug "Searching #{type} history for #{alarm_name}"
@@ -35,6 +35,13 @@ require 'cfnguardian/resources/log_group'
35
35
  require 'cfnguardian/resources/sftp'
36
36
  require 'cfnguardian/resources/internal_sftp'
37
37
  require 'cfnguardian/resources/tls'
38
+ require 'cfnguardian/resources/azure_file'
39
+ require 'cfnguardian/resources/amazonmq_rabbitmq'
40
+ require 'cfnguardian/resources/batch'
41
+ require 'cfnguardian/resources/glue'
42
+ require 'cfnguardian/resources/step_functions'
43
+ require 'cfnguardian/version'
44
+ require 'cfnguardian/error'
38
45
 
39
46
  module CfnGuardian
40
47
  class Compile
@@ -50,7 +57,13 @@ module CfnGuardian
50
57
  @templates = config.fetch('Templates',{})
51
58
  @topics = config.fetch('Topics',{})
52
59
  @maintenance_groups = config.fetch('MaintenaceGroups', {})
60
+ @event_subscriptions = config.fetch('EventSubscriptions', {})
53
61
 
62
+ # Make sure the default topics exist if they aren't supplied in the alarms.yaml
63
+ %w(Critical Warning Task Informational Events).each do |topic|
64
+ @topics[topic] = '' unless @topics.has_key?(topic)
65
+ end
66
+
54
67
  @maintenance_group_list = @maintenance_groups.keys.map {|group| "#{group}MaintenanceGroup"}
55
68
  @resources = []
56
69
  @stacks = []
@@ -81,10 +94,15 @@ module CfnGuardian
81
94
  end
82
95
  end
83
96
 
84
- overides = @templates.has_key?(group) ? @templates[group] : {}
85
- @resources.concat resource_class.get_alarms(overides,resource)
97
+ template_overides = @templates.has_key?(group) ? @templates[group] : {}
98
+ @resources.concat resource_class.get_alarms(group,template_overides)
99
+
86
100
  @resources.concat resource_class.get_metric_filters()
87
101
  @resources.concat resource_class.get_events()
102
+
103
+ event_subscriptions = @event_subscriptions.has_key?(group) ? @event_subscriptions[group] : {}
104
+ @resources.concat resource_class.get_event_subscriptions(group,event_subscriptions)
105
+
88
106
  @checks.concat resource_class.get_checks()
89
107
 
90
108
  @cost += resource_class.get_cost
@@ -95,13 +113,16 @@ module CfnGuardian
95
113
  resource_groups.each do |group, alarms|
96
114
  alarms.each do |alarm, resources|
97
115
  resources.each do |resource|
116
+
98
117
  res = @resources.find {|r|
99
118
  (r.type == 'Alarm') &&
100
- (r.class == group && r.name == alarm) &&
119
+ (r.group == group && r.name == alarm) &&
101
120
  (r.resource_id == resource['Id'] || r.resource_name == resource['Name'])}
121
+
102
122
  unless res.nil?
103
123
  res.maintenance_groups.append("#{maintenance_group}MaintenanceGroup")
104
124
  end
125
+
105
126
  end
106
127
  end
107
128
  end
@@ -113,11 +134,39 @@ module CfnGuardian
113
134
  end
114
135
 
115
136
  @ssm_parameters = @resources.select {|resource| resource.type == 'Event'}.map {|event| event.ssm_parameters}.flatten.uniq
137
+
138
+ validate_resources()
116
139
  end
117
140
 
118
141
  def alarms
119
142
  @resources.select {|resource| resource.type == 'Alarm'}
120
143
  end
144
+
145
+ def validate_resources()
146
+ errors = []
147
+ @resources.each do |resource|
148
+ case resource.type
149
+ when 'Alarm'
150
+ %w(metric_name namespace).each do |property|
151
+ if resource.send(property).nil?
152
+ errors << "Alarm #{resource.name} for resource #{resource.resource_id} has nil value for property #{property.to_camelcase}"
153
+ end
154
+ end
155
+ when 'Check'
156
+ # no validation check yet
157
+ when 'Event'
158
+ # no validation check yet
159
+ when 'Composite'
160
+ # no validation check yet
161
+ when 'EventSubscription'
162
+ # no validation check yet
163
+ when 'MetricFilter'
164
+ # no validation check yet
165
+ end
166
+ end
167
+
168
+ raise CfnGuardian::ValidationError, "#{errors.size} errors found\n[*] #{errors.join("\n[*] ")}" if errors.any?
169
+ end
121
170
 
122
171
  def split_resources(bucket,path)
123
172
  split = @resources.each_slice(200).to_a
@@ -142,7 +191,7 @@ module CfnGuardian
142
191
  File.write("out/guardian.compiled.yaml", JSON.parse(valid.to_json).to_yaml)
143
192
 
144
193
  resources.each_with_index do |resources,index|
145
- stack = CfnGuardian::Stacks::Resources.new(main_stack.parameters)
194
+ stack = CfnGuardian::Stacks::Resources.new(main_stack.parameters,index)
146
195
  stack.build_template(resources)
147
196
  valid = stack.template.validate
148
197
  File.write("out/guardian-stack-#{index}.compiled.yaml", JSON.parse(valid.to_json).to_yaml)
@@ -152,6 +201,43 @@ module CfnGuardian
152
201
  def clean_out_directory
153
202
  Dir["out/*.yaml"].each {|file| File.delete(file)}
154
203
  end
204
+
205
+ def load_parameters(options)
206
+ parameters = {}
207
+ # Load sns topic parameters in order of preference
208
+ @topics.each do |key, value|
209
+ # if parameter is passed in as a command line option
210
+ if options.has_key?("sns_#{key.downcase}")
211
+ parameters[key.to_sym] = options["sns_#{key.downcase}"]
212
+ # if parameter is in config
213
+ elsif !value.empty?
214
+ parameters[key.to_sym] = value
215
+ # if parameter is set as environment variable
216
+ elsif ENV.has_key?("GUARDIAN_TOPIC_#{key.upcase}")
217
+ parameters[key.to_sym] = ENV["GUARDIAN_TOPIC_#{key.upcase}"]
218
+ end
219
+ end
220
+
221
+ return parameters
222
+ end
223
+
224
+ def genrate_template_config(parameters)
225
+ template = {
226
+ Tags: {
227
+ 'guardian:version': CfnGuardian::VERSION
228
+ }
229
+ }
230
+
231
+ if ENV.has_key?('CODEBUILD_RESOLVED_SOURCE_VERSION')
232
+ template[:Tags][:'guardian:config:commit'] = ENV['CODEBUILD_RESOLVED_SOURCE_VERSION']
233
+ end
234
+
235
+ unless parameters.empty?
236
+ template[:Parameters] = parameters
237
+ end
238
+
239
+ File.write("out/template-config.guardian.json", template.to_json)
240
+ end
155
241
 
156
242
  end
157
243
  end
@@ -1,6 +1,15 @@
1
1
  Resources:
2
2
  AmazonMQBroker:
3
3
  - Id: Default
4
+ AmazonMQRabbitMQBroker:
5
+ - Id: Default
6
+ AmazonMQRabbitMQNode:
7
+ - Id: Default
8
+ Node: Default
9
+ AmazonMQRabbitMQQueue:
10
+ - Id: Default
11
+ Queue: Default
12
+ Vhost: Default
4
13
  ApiGateway:
5
14
  - Id: Default
6
15
  ApplicationTargetGroup:
@@ -7,27 +7,13 @@ module CfnGuardian
7
7
  class Deploy
8
8
  include Logging
9
9
 
10
- def initialize(opts,bucket)
10
+ def initialize(opts,bucket,parameters)
11
11
  @stack_name = opts.fetch(:stack_name,'guardian')
12
12
  @bucket = bucket
13
13
  @prefix = @stack_name
14
14
  @template_path = "out/guardian.compiled.yaml"
15
15
  @template_url = "https://#{@bucket}.s3.amazonaws.com/#{@prefix}/guardian.compiled.yaml"
16
- @parameters = {}
17
-
18
- config = YAML.load_file(opts[:config])
19
- if config.has_key?('Topics')
20
- @parameters['Critical'] = config['Topics'].fetch('Critical','')
21
- @parameters['Warning'] = config['Topics'].fetch('Warning','')
22
- @parameters['Task'] = config['Topics'].fetch('Task','')
23
- @parameters['Informational'] = config['Topics'].fetch('Informational','')
24
- end
25
-
26
- @parameters['Critical'] = opts.fetch(:sns_critical,@parameters['Critical'])
27
- @parameters['Warning'] = opts.fetch(:sns_warning,@parameters['Warning'])
28
- @parameters['Task'] = opts.fetch(:sns_task,@parameters['Task'])
29
- @parameters['Informational'] = opts.fetch(:sns_informational,@parameters['Informational'])
30
-
16
+ @parameters = parameters
31
17
  @client = Aws::CloudFormation::Client.new()
32
18
  end
33
19
 
@@ -14,7 +14,6 @@ module CfnGuardian
14
14
 
15
15
  @alarms.each do |alarm|
16
16
  alarm_name = CfnGuardian::CloudWatch.get_alarm_name(alarm)
17
- puts alarm_name
18
17
  rows = [
19
18
  ['ResourceId', alarm.resource_id],
20
19
  ['ResourceHash', alarm.resource_hash],
@@ -52,7 +51,7 @@ module CfnGuardian
52
51
 
53
52
  @alarms.each do |alarm|
54
53
  alarm_name = CfnGuardian::CloudWatch.get_alarm_name(alarm)
55
- metric_alarm = metric_alarms.find {|ma| ma.alarm_name == alarm_name}
54
+ metric_alarm = metric_alarms.find {|ma| ma.alarm_name.include? alarm_name}
56
55
  dimensions = metric_alarm.dimensions.map {|dim| {dim.name.to_sym => dim.value}}.inject(:merge)
57
56
 
58
57
  rows = [
@@ -0,0 +1,4 @@
1
+ module CfnGuardian
2
+ class ValidationError < StandardError
3
+ end
4
+ end
@@ -3,7 +3,7 @@ require 'digest/md5'
3
3
 
4
4
  module CfnGuardian
5
5
  module Models
6
- class Alarm
6
+ class BaseAlarm
7
7
 
8
8
  attr_reader :type,
9
9
  :resource_hash
@@ -28,7 +28,8 @@ module CfnGuardian
28
28
  :extended_statistic,
29
29
  :evaluate_low_sample_count_percentile,
30
30
  :unit,
31
- :maintenance_groups
31
+ :maintenance_groups,
32
+ :additional_notifiers
32
33
 
33
34
  def initialize(resource)
34
35
  @type = 'Alarm'
@@ -54,6 +55,7 @@ module CfnGuardian
54
55
  @alarm_action = 'Critical'
55
56
  @treat_missing_data = nil
56
57
  @maintenance_groups = []
58
+ @additional_notifiers = []
57
59
  end
58
60
 
59
61
  def metric_name=(metric_name)
@@ -63,7 +65,7 @@ module CfnGuardian
63
65
  end
64
66
 
65
67
 
66
- class ApiGatewayAlarm < Alarm
68
+ class ApiGatewayAlarm < BaseAlarm
67
69
  def initialize(resource)
68
70
  super(resource)
69
71
  @group = 'ApiGateway'
@@ -72,7 +74,7 @@ module CfnGuardian
72
74
  end
73
75
  end
74
76
 
75
- class ApplicationTargetGroupAlarm < Alarm
77
+ class ApplicationTargetGroupAlarm < BaseAlarm
76
78
  def initialize(resource)
77
79
  super(resource)
78
80
  @group = 'ApplicationTargetGroup'
@@ -84,7 +86,7 @@ module CfnGuardian
84
86
  end
85
87
  end
86
88
 
87
- class AmazonMQBrokerAlarm < Alarm
89
+ class AmazonMQBrokerAlarm < BaseAlarm
88
90
  def initialize(resource)
89
91
  super(resource)
90
92
  @group = 'AmazonMQBroker'
@@ -92,8 +94,42 @@ module CfnGuardian
92
94
  @dimensions = { Broker: resource['Id'] }
93
95
  end
94
96
  end
97
+
98
+ class AmazonMQRabbitMQBrokerAlarm < BaseAlarm
99
+ def initialize(resource)
100
+ super(resource)
101
+ @group = 'AmazonMQRabbitMQBroker'
102
+ @namespace = 'AWS/AmazonMQ'
103
+ @dimensions = { Broker: resource['Id'] }
104
+ end
105
+ end
106
+
107
+ class AmazonMQRabbitMQNodeAlarm < BaseAlarm
108
+ def initialize(resource)
109
+ super(resource)
110
+ @group = 'AmazonMQRabbitMQNode'
111
+ @namespace = 'AWS/AmazonMQ'
112
+ @dimensions = {
113
+ Broker: resource['Id'],
114
+ Node: resource['Node']
115
+ }
116
+ end
117
+ end
118
+
119
+ class AmazonMQRabbitMQQueueAlarm < BaseAlarm
120
+ def initialize(resource)
121
+ super(resource)
122
+ @group = 'AmazonMQRabbitMQQueue'
123
+ @namespace = 'AWS/AmazonMQ'
124
+ @dimensions = {
125
+ Broker: resource['Id'],
126
+ Queue: resource['Queue'],
127
+ VirtualHost: resource['Vhost']
128
+ }
129
+ end
130
+ end
95
131
 
96
- class CloudFrontDistributionAlarm < Alarm
132
+ class CloudFrontDistributionAlarm < BaseAlarm
97
133
  def initialize(resource)
98
134
  super(resource)
99
135
  @group = 'CloudFrontDistribution'
@@ -107,7 +143,7 @@ module CfnGuardian
107
143
  end
108
144
  end
109
145
 
110
- class AutoScalingGroupAlarm < Alarm
146
+ class AutoScalingGroupAlarm < BaseAlarm
111
147
  def initialize(resource)
112
148
  super(resource)
113
149
  @group = 'AutoScalingGroup'
@@ -116,7 +152,7 @@ module CfnGuardian
116
152
  end
117
153
  end
118
154
 
119
- class DomainExpiryAlarm < Alarm
155
+ class DomainExpiryAlarm < BaseAlarm
120
156
  def initialize(resource)
121
157
  super(resource)
122
158
  @group = 'DomainExpiry'
@@ -126,7 +162,7 @@ module CfnGuardian
126
162
  end
127
163
  end
128
164
 
129
- class DynamoDBTableAlarm < Alarm
165
+ class DynamoDBTableAlarm < BaseAlarm
130
166
  def initialize(resource)
131
167
  super(resource)
132
168
  @group = 'DynamoDBTable'
@@ -135,7 +171,7 @@ module CfnGuardian
135
171
  end
136
172
  end
137
173
 
138
- class Ec2InstanceAlarm < Alarm
174
+ class Ec2InstanceAlarm < BaseAlarm
139
175
  def initialize(resource)
140
176
  super(resource)
141
177
  @group = 'Ec2Instance'
@@ -144,7 +180,7 @@ module CfnGuardian
144
180
  end
145
181
  end
146
182
 
147
- class ECSClusterAlarm < Alarm
183
+ class ECSClusterAlarm < BaseAlarm
148
184
  def initialize(resource)
149
185
  super(resource)
150
186
  @group = 'ECSCluster'
@@ -156,7 +192,7 @@ module CfnGuardian
156
192
  end
157
193
  end
158
194
 
159
- class ECSServiceAlarm < Alarm
195
+ class ECSServiceAlarm < BaseAlarm
160
196
  def initialize(resource)
161
197
  super(resource)
162
198
  @group = 'ECSService'
@@ -168,7 +204,7 @@ module CfnGuardian
168
204
  end
169
205
  end
170
206
 
171
- class ElastiCacheReplicationGroupAlarm < Alarm
207
+ class ElastiCacheReplicationGroupAlarm < BaseAlarm
172
208
  def initialize(resource)
173
209
  super(resource)
174
210
  @group = 'ElastiCacheReplicationGroup'
@@ -177,7 +213,7 @@ module CfnGuardian
177
213
  end
178
214
  end
179
215
 
180
- class ElasticLoadBalancerAlarm < Alarm
216
+ class ElasticLoadBalancerAlarm < BaseAlarm
181
217
  def initialize(resource)
182
218
  super(resource)
183
219
  @group = 'ElasticLoadBalancer'
@@ -186,7 +222,7 @@ module CfnGuardian
186
222
  end
187
223
  end
188
224
 
189
- class ElasticFileSystemAlarm < Alarm
225
+ class ElasticFileSystemAlarm < BaseAlarm
190
226
  def initialize(resource)
191
227
  super(resource)
192
228
  @group = 'ElasticFileSystem'
@@ -195,7 +231,7 @@ module CfnGuardian
195
231
  end
196
232
  end
197
233
 
198
- class HttpAlarm < Alarm
234
+ class HttpAlarm < BaseAlarm
199
235
  def initialize(resource)
200
236
  super(resource)
201
237
  @group = 'Http'
@@ -213,7 +249,7 @@ module CfnGuardian
213
249
  end
214
250
  end
215
251
 
216
- class PortAlarm < Alarm
252
+ class PortAlarm < BaseAlarm
217
253
  def initialize(resource)
218
254
  super(resource)
219
255
  @group = 'Port'
@@ -231,7 +267,7 @@ module CfnGuardian
231
267
  end
232
268
  end
233
269
 
234
- class SslAlarm < Alarm
270
+ class SslAlarm < BaseAlarm
235
271
  def initialize(resource)
236
272
  super(resource)
237
273
  @group = 'Ssl'
@@ -247,7 +283,7 @@ module CfnGuardian
247
283
  end
248
284
  end
249
285
 
250
- class NrpeAlarm < Alarm
286
+ class NrpeAlarm < BaseAlarm
251
287
  def initialize(resource,environment)
252
288
  super(resource)
253
289
  @group = 'Nrpe'
@@ -258,7 +294,7 @@ module CfnGuardian
258
294
  end
259
295
  end
260
296
 
261
- class LambdaAlarm < Alarm
297
+ class LambdaAlarm < BaseAlarm
262
298
  def initialize(resource)
263
299
  super(resource)
264
300
  @group = 'Lambda'
@@ -269,7 +305,7 @@ module CfnGuardian
269
305
  end
270
306
  end
271
307
 
272
- class NetworkTargetGroupAlarm < Alarm
308
+ class NetworkTargetGroupAlarm < BaseAlarm
273
309
  def initialize(resource)
274
310
  super(resource)
275
311
  @group = 'NetworkTargetGroup'
@@ -281,7 +317,7 @@ module CfnGuardian
281
317
  end
282
318
  end
283
319
 
284
- class RedshiftClusterAlarm < Alarm
320
+ class RedshiftClusterAlarm < BaseAlarm
285
321
  def initialize(resource)
286
322
  super(resource)
287
323
  @group = 'RedshiftCluster'
@@ -290,7 +326,7 @@ module CfnGuardian
290
326
  end
291
327
  end
292
328
 
293
- class RDSClusterInstanceAlarm < Alarm
329
+ class RDSClusterInstanceAlarm < BaseAlarm
294
330
  def initialize(resource)
295
331
  super(resource)
296
332
  @group = 'RDSClusterInstance'
@@ -299,7 +335,7 @@ module CfnGuardian
299
335
  end
300
336
  end
301
337
 
302
- class RDSInstanceAlarm < Alarm
338
+ class RDSInstanceAlarm < BaseAlarm
303
339
  def initialize(resource)
304
340
  super(resource)
305
341
  @group = 'RDSInstance'
@@ -307,8 +343,32 @@ module CfnGuardian
307
343
  @dimensions = { DBInstanceIdentifier: resource['Id'] }
308
344
  end
309
345
  end
310
-
311
- class SqlAlarm < Alarm
346
+
347
+ class StepFunctionsAlarm < BaseAlarm
348
+ def initialize(resource)
349
+ super(resource)
350
+ @group = 'StepFunctions'
351
+ @namespace = 'AWS/States'
352
+ @dimensions = { StateMachineArn: { "Fn::Sub" => "arn:aws:states:${AWS::Region}:${AWS::AccountId}:stateMachine:#{resource['Id']}"} }
353
+ end
354
+ end
355
+
356
+ class BatchAlarm < BaseAlarm
357
+ def initialize(resource)
358
+ super(resource)
359
+ @group = 'Batch'
360
+ end
361
+ end
362
+
363
+ class GlueAlarm < BaseAlarm
364
+ def initialize(resource)
365
+ super(resource)
366
+ @group = 'Batch'
367
+ @namespace = 'Glue'
368
+ end
369
+ end
370
+
371
+ class SqlAlarm < BaseAlarm
312
372
  def initialize(resource)
313
373
  super(resource)
314
374
  @group = 'Sql'
@@ -319,7 +379,7 @@ module CfnGuardian
319
379
  end
320
380
  end
321
381
 
322
- class SQSQueueAlarm < Alarm
382
+ class SQSQueueAlarm < BaseAlarm
323
383
  def initialize(resource)
324
384
  super(resource)
325
385
  @group = 'SQSQueue'
@@ -330,7 +390,7 @@ module CfnGuardian
330
390
  end
331
391
  end
332
392
 
333
- class LogGroupAlarm < Alarm
393
+ class LogGroupAlarm < BaseAlarm
334
394
  def initialize(resource)
335
395
  super(resource)
336
396
  @group = 'LogGroup'
@@ -342,7 +402,7 @@ module CfnGuardian
342
402
  end
343
403
  end
344
404
 
345
- class SFTPAlarm < Alarm
405
+ class SFTPAlarm < BaseAlarm
346
406
  def initialize(resource)
347
407
  super(resource)
348
408
  @group = 'SFTP'
@@ -360,7 +420,7 @@ module CfnGuardian
360
420
  end
361
421
  end
362
422
 
363
- class TLSAlarm < Alarm
423
+ class TLSAlarm < BaseAlarm
364
424
  def initialize(resource)
365
425
  super(resource)
366
426
  @group = 'TLS'
@@ -373,6 +433,18 @@ module CfnGuardian
373
433
  @evaluation_periods = 1
374
434
  end
375
435
  end
436
+
437
+ class AzureFileAlarm < BaseAlarm
438
+ def initialize(resource)
439
+ super(resource)
440
+ @group = 'AzureFile'
441
+ @namespace = 'FileAgeCheck'
442
+ @period = 300
443
+ @comparison_operator = 'GreaterThanThreshold'
444
+ @threshold = 0
445
+ @dimensions = { StorageAccount: resource['Id'], StorageContainer: resource['Container'] }
446
+ end
447
+ end
376
448
 
377
449
  end
378
450
  end