class CfnGuardian::Compile
Attributes
cost[R]
resources[R]
topics[R]
Public Class Methods
new(config_file)
click to toggle source
# File lib/cfnguardian/compile.rb, line 57 def initialize(config_file) config = YAML.load_file(config_file) @resource_groups = config.fetch('Resources',{}) @composites = config.fetch('Composites',{}) @templates = config.fetch('Templates',{}) @topics = config.fetch('Topics',{}) @maintenance_groups = config.fetch('MaintenanceGroups', {}) @event_subscriptions = config.fetch('EventSubscriptions', {}) # Make sure the default topics exist if they aren't supplied in the alarms.yaml %w(Critical Warning Task Informational Events).each do |topic| @topics[topic] = '' unless @topics.has_key?(topic) end @resources = [] @stacks = [] @checks = [] @ssm_parameters = [] @cost = 0 end
Public Instance Methods
alarms()
click to toggle source
# File lib/cfnguardian/compile.rb, line 148 def alarms @resources.select {|resource| resource.type == 'Alarm'} end
clean_out_directory()
click to toggle source
# File lib/cfnguardian/compile.rb, line 208 def clean_out_directory Dir["out/*.yaml"].each {|file| File.delete(file)} end
compile_templates(bucket,path)
click to toggle source
# File lib/cfnguardian/compile.rb, line 190 def compile_templates(bucket,path) clean_out_directory() resources = split_resources(bucket,path) main_stack = CfnGuardian::Stacks::Main.new() main_stack.build_template(@stacks,@checks,@topics,@maintenance_groups,@ssm_parameters) valid = main_stack.template.validate FileUtils.mkdir_p 'out' File.write("out/guardian.compiled.yaml", JSON.parse(valid.to_json).to_yaml) resources.each_with_index do |resources,index| stack = CfnGuardian::Stacks::Resources.new(main_stack.parameters,index) stack.build_template(resources) valid = stack.template.validate File.write("out/guardian-stack-#{index}.compiled.yaml", JSON.parse(valid.to_json).to_yaml) end end
genrate_template_config(parameters)
click to toggle source
# File lib/cfnguardian/compile.rb, line 231 def genrate_template_config(parameters) template = { Tags: { 'guardian:version': CfnGuardian::VERSION } } if ENV.has_key?('CODEBUILD_RESOLVED_SOURCE_VERSION') template[:Tags][:'guardian:config:commit'] = ENV['CODEBUILD_RESOLVED_SOURCE_VERSION'] end unless parameters.empty? template[:Parameters] = parameters end File.write("out/template-config.guardian.json", template.to_json) end
get_resources()
click to toggle source
# File lib/cfnguardian/compile.rb, line 80 def get_resources @resource_groups.each do |group,resources| resources.each do |resource| begin resource_class = Kernel.const_get("CfnGuardian::Resource::#{group}").new(resource) rescue NameError => e if @templates.has_key?(group) && @templates[group].has_key?('Inherit') begin resource_class = Kernel.const_get("CfnGuardian::Resource::#{@templates[group]['Inherit']}").new(resource, group) logger.debug "Inheritited resource group #{@templates[group]['Inherit']} for group #{group}" rescue NameError => e logger.warn "'#{@templates[group]['Inherit']}' resource group doesn't exist and is unable to be inherited from" next end else logger.error(e) next end end template_overides = @templates.has_key?(group) ? @templates[group] : {} @resources.concat resource_class.get_alarms(group,template_overides) @resources.concat resource_class.get_metric_filters() @resources.concat resource_class.get_events() event_subscriptions = @event_subscriptions.has_key?(group) ? @event_subscriptions[group] : {} @resources.concat resource_class.get_event_subscriptions(group,event_subscriptions) @checks.concat resource_class.get_checks() @cost += resource_class.get_cost end end @maintenance_groups.each do |maintenance_group,resource_groups| resource_groups.each do |group, alarms| if group == 'Schedules' next end alarms.each do |alarm, resources| resources.each do |resource| res = @resources.find {|r| (r.type == 'Alarm') && (r.group == group && r.name == alarm) && (r.resource_id == resource['Id'] || r.resource_name == resource['Name'])} unless res.nil? res.maintenance_groups.append("#{maintenance_group}MaintenanceGroup") end end end end end @composites.each do |name,params| @resources.push CfnGuardian::Models::Composite.new(name,params) @cost += 0.50 end @ssm_parameters = @resources.select {|resource| resource.type == 'Event'}.map {|event| event.ssm_parameters}.flatten.uniq validate_resources() end
load_parameters(options)
click to toggle source
# File lib/cfnguardian/compile.rb, line 212 def load_parameters(options) parameters = {} # Load sns topic parameters in order of preference @topics.each do |key, value| # if parameter is passed in as a command line option if options.has_key?("sns_#{key.downcase}") parameters[key.to_sym] = options["sns_#{key.downcase}"] # if parameter is in config elsif !value.empty? parameters[key.to_sym] = value # if parameter is set as environment variable elsif ENV.has_key?("GUARDIAN_TOPIC_#{key.upcase}") parameters[key.to_sym] = ENV["GUARDIAN_TOPIC_#{key.upcase}"] end end return parameters end
split_resources(bucket,path)
click to toggle source
# File lib/cfnguardian/compile.rb, line 178 def split_resources(bucket,path) split = @resources.each_slice(200).to_a split.each_with_index do |resources,index| @stacks.push({ 'Name' => "GuardianStack#{index}", 'TemplateURL' => "https://#{bucket}.s3.amazonaws.com/#{path}/guardian-stack-#{index}.compiled.yaml", 'Reference' => index }) end return split end
validate_resources()
click to toggle source
# File lib/cfnguardian/compile.rb, line 152 def validate_resources() errors = [] @resources.each do |resource| case resource.type when 'Alarm' %w(metric_name namespace).each do |property| if resource.send(property).nil? errors << "Alarm #{resource.name} for resource #{resource.resource_id} has nil value for property #{property.to_camelcase}" end end when 'Check' # no validation check yet when 'Event' # no validation check yet when 'Composite' # no validation check yet when 'EventSubscription' # no validation check yet when 'MetricFilter' # no validation check yet end end raise CfnGuardian::ValidationError, "#{errors.size} errors found\n[*] #{errors.join("\n[*] ")}" if errors.any? end