Class: CfnGuardian::Resource::Base

Inherits:
Object
  • Object
show all
Includes:
Logging
Defined in:
lib/cfnguardian/resources/base.rb

Instance Method Summary collapse

Methods included from Logging

colors, included, logger, #logger, logger=

Constructor Details

#initialize(resource, override_group = nil) ⇒ Base

Returns a new instance of Base.



13
14
15
16
17
18
19
20
21
# File 'lib/cfnguardian/resources/base.rb', line 13

def initialize(resource, override_group = nil)
  @resource = resource
  @override_group = override_group
  @alarms = []
  @events = []
  @checks = []
  @metric_filters = []
  @event_subscriptions = []
end

Instance Method Details

#default_alarmsObject

Overidden by inherited classes to define default alarms



24
25
26
# File 'lib/cfnguardian/resources/base.rb', line 24

def default_alarms()
  return @alarms
end

#default_checksObject

Overidden by inherited classes to define default checks



141
142
143
# File 'lib/cfnguardian/resources/base.rb', line 141

def default_checks()
  return @checks
end

#default_event_subscriptionsObject

Overidden by inherited classes to define default checks



161
162
163
# File 'lib/cfnguardian/resources/base.rb', line 161

def default_event_subscriptions()
  return @event_subscriptions
end

#default_eventsObject

Overidden by inherited classes to define default events



131
132
133
# File 'lib/cfnguardian/resources/base.rb', line 131

def default_events()
  return @events
end

#default_metric_filtersObject

Overidden by inherited classes to define default checks



151
152
153
# File 'lib/cfnguardian/resources/base.rb', line 151

def default_metric_filters()
  return @metric_filters
end

#get_alarms(group, overides = {}) ⇒ Object



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
# File 'lib/cfnguardian/resources/base.rb', line 28

def get_alarms(group,overides={})
  # deep copying the overrides to preserve its reference before doing any changes to it
  overides = Marshal.load(Marshal.dump(overides))

  # generate default alarms
  default_alarms()

  # override any group properties
  group_overrides = overides.has_key?('GroupOverrides') ? overides['GroupOverrides'] : {}
  overides.delete('GroupOverrides')
  if group_overrides.any?
    @alarms.each do |alarm|
      logger.debug("overriding #{alarm.name} alarm properties for resource #{alarm.resource_id} in resource group #{group} via group overrides") 
      group_overrides.each {|attr,value| update_object(alarm,attr,value)}
    end
  end

  # loop over each override template for the service
  overides.each do |name,properties|       
    # disable default alarms
    if [false].include?(properties)
      alarms = find_alarms(name)
      
      if !alarms.nil?
        alarms.each do |alarm| 
          alarm.enabled = false
          logger.info "disabling alarm '#{name}' for resource #{alarm.resource_id}"
        end
        next
      end
    end

    # continue if the override is in the incorrect format
    unless properties.is_a?(Hash)
      if name != 'Inherit'
        logger.warn "incorrect format for alarm '#{name}'. Should be of type 'Hash', instead got type '#{properties.group}'"
      end
      next
    end

    properties.merge!(group_overrides)

    # Create a new alarm inheriting the defaults of an existing alarm
    if properties.has_key?('Inherit')
      alarm = find_alarm(properties['Inherit'])
      if !alarm.nil?
        logger.debug("creating new alarm #{name} for alarm group #{self.class.to_s.split('::').last} inheriting properties from alarm #{properties['Inherit']}")
        inherited_alarm = alarm.clone
        alarm.name = name
        properties.each {|attr,value| update_object(inherited_alarm,attr,value)}
        @alarms.push(inherited_alarm)
      else
        logger.warn "alarm '#{properties['Inherit']}' doesn't exist and cannot be inherited"
      end
      next
    end
    
    alarms = find_alarms(name)

    if alarms.empty? && !['LogGroup'].any?(group)
      # if the alarm doesn't exist and it's not being inherited from another alarm create a new alarm
      # and is a supported a resource group.
      # unsupported resource groups
      # - LogGroup: this is not required as alarms are defined in the Metric Filters object in the resource group
      resources = @resource.has_key?('Hosts') ? @resource['Hosts'] : [@resource]
      resources.each do |res|
        alarm = Kernel.const_get("CfnGuardian::Models::#{self.class.to_s.split('::').last}Alarm").new(res)
        properties.each {|attr,value| update_object(alarm,attr,value)}
        alarm.name = name
        logger.debug("created new alarm #{alarm.name} for resource #{alarm.resource_id} in resource group #{group}")
        @alarms.push(alarm)
      end
    else
      # if there is an existing alarm update the properties
      alarms.each do |alarm|
        logger.debug("overriding #{alarm.name} alarm properties for resource #{alarm.resource_id} in resource group #{group} via alarm overrides") 
        properties.each {|attr,value| update_object(alarm,attr,value)}
      end
    end
  end
  
  unless @override_group.nil?
    @alarms.each {|a| a.group = @override_group}
  end
  
  # String interpolation for alarm dimensions
  @alarms.each do |alarm|
    next if alarm.dimensions.nil?
    alarm.dimensions.each do |k,v|
      if v.is_a?(String) && v.match?(/^\${Resource::.*[A-Za-z]}$/)
        resource_key = v.tr('${}', '').split('Resource::').last
        if @resource.has_key?(resource_key)
          logger.debug "overriding alarm #{alarm.name} dimension key '#{k}' with value '#{@resource[resource_key]}'" 
          alarm.dimensions[k] = @resource[resource_key]
        end
      end
    end
  end

  return @alarms.select{|a| a.enabled}
end

#get_checksObject



145
146
147
148
# File 'lib/cfnguardian/resources/base.rb', line 145

def get_checks()
  default_checks()
  return @checks
end

#get_costObject



214
215
216
# File 'lib/cfnguardian/resources/base.rb', line 214

def get_cost()
  return @alarms.length * 0.10
end

#get_event_subscriptions(group, overides) ⇒ Object



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/cfnguardian/resources/base.rb', line 165

def get_event_subscriptions(group, overides)
  # generate default event subscriptions
  default_event_subscriptions()

  # override the defaults
  overides.each do |name, properties|
    event_subscription = find_event_subscriptions(name)

    # disable the event subscription if the value is false
    if [false].include?(properties)
      unless event_subscription.nil?
        event_subscription.enabled = false
        logger.info "Disabling event subscription #{name} for #{group} #{event_subscription.resource_id}"
      end

      next
    end

    # ignore all properties not in a proper format
    next unless properties.is_a?(Hash) 

    # Create a new event subscription by inheriting an existing one
    if properties.has_key?('Inherit')
      inherit_event_subscription = find_event_subscriptions(properties['Inherit'])
      
      if inherit_event_subscription.nil?
        logger.warn "Unable to create #{topic} RDSEventSubscription by inheriting #{properties['Inherit']} as it cannot be found"
        next
      end

      event_subscription = inherit_event_subscription.clone
      event_subscription.enabled = true
      event_subscription.name = name
      @event_subscriptions.push(event_subscription) 
      logger.debug "Inheriting RDSEventSubscription #{properties['Inherit']}"
    end

    if event_subscription.nil?
      event_subscription = Kernel.const_get("CfnGuardian::Models::#{self.class.to_s.split('::').last}EventSubscription").new(@resource)
      event_subscription.name = name
      @event_subscriptions.push(event_subscription) 
    end

    properties.each {|attr,value| update_object(event_subscription,attr,value)}
  end

  return @event_subscriptions.select {|es| es.enabled }
end

#get_eventsObject



135
136
137
138
# File 'lib/cfnguardian/resources/base.rb', line 135

def get_events()
  default_events()
  return @events.select{|e| e.enabled}
end

#get_metric_filtersObject



155
156
157
158
# File 'lib/cfnguardian/resources/base.rb', line 155

def get_metric_filters()
  default_metric_filters()
  return @metric_filters
end

#resource_exists?Boolean

Returns:

  • (Boolean)


218
219
220
# File 'lib/cfnguardian/resources/base.rb', line 218

def resource_exists?
  return true
end