class Lono::Configset::Combiner
Public Class Methods
new(cfn, options={})
click to toggle source
# File lib/lono/configset/combiner.rb, line 5 def initialize(cfn, options={}) @cfn, @options = cfn, options @sets = [] @map = {} # stores resource logical id => metadata cfn-init end
Public Instance Methods
add(registry, metadata)
click to toggle source
# File lib/lono/configset/combiner.rb, line 41 def add(registry, metadata) @sets << [registry, metadata.dup] end
additional_configsets?()
click to toggle source
# File lib/lono/configset/combiner.rb, line 45 def additional_configsets? !Register::Blueprint.configsets.empty? || !Register::Project.configsets.empty? end
combine()
click to toggle source
# File lib/lono/configset/combiner.rb, line 66 def combine # Remove duplicate configsets. Can happen if same configset is in blueprint and project. # Ugly because of the sets structure. @sets.uniq! do |array| registry, _ = array registry.name end metadata_map = {} configsets_map = {} @sets.each_with_index do |array, i| padded_i = "%03d" % i registry, metadata = array # metadata example (full structure): # # {"Metadata"=> # {"AWS::CloudFormation::Init"=> # {"configSets"=>{"default"=>["aaa1", "aaa2"]}, # "aaa1"=>{"commands"=>{"test"=>{"command"=>"echo from-aaa1 > test1.txt"}}}, # "aaa2"=> # {"commands"=>{"test"=>{"command"=>"echo from-aaa2 > test1.txt"}}}}}} name, resource = registry.name, registry.resource configsets = configsets_map[resource] ||= {} validate_structure!(name, metadata) new_metadata = metadata["Metadata"].dup init = new_metadata["AWS::CloudFormation::Init"] # important: adjust data by reference if init.key?("configSets") validate_simple!(registry, new_metadata["AWS::CloudFormation::Init"]["configSets"]) # validate original configset for only simple elements # 1. expand each config as its own config, flattening to top-level cs = init.delete("configSets") # Only support configSets with simple Array of Strings new_config_set = {} new_config_set[name] = cs["default"].map {|c| "#{padded_i}_#{c}" } init.transform_keys! { |c| "#{padded_i}_#{c}" } # Rebuild default configSet, append the new complex ConfigSet structure with each iteration configsets["default"] ||= [] configsets["default"] << {"ConfigSet" => name} configsets.merge!(new_config_set) # add each config from #1 to the top-level init["configSets"] = configsets # replace new configset else # simple config init["configSets"] = configsets # adjust data by reference configsets["default"] ||= [] configsets["default"] << {"ConfigSet" => name} # build new config config_key = "#{padded_i}_single_generated" configsets[name] = [config_key] new_config = {config_key => init["config"]} # replace old config with new one init.delete("config") # delete original simple config init.merge!(new_config) end metadata_map[resource] ||= {"Metadata" => {}} metadata_map[resource]["Metadata"].deep_merge!(new_metadata) @map[resource] = metadata_map[resource] end @map end
existing_configsets()
click to toggle source
Normalized/convert cfn template to mimic the registry format
# File lib/lono/configset/combiner.rb, line 50 def existing_configsets configsets = [] @cfn["Resources"].each do |logical_id, attributes| init = attributes.dig("Metadata", "AWS::CloudFormation::Init") next unless init data = { registry: Lono::Jade::Registry.new(["#{logical_id}OriginalConfigset"], resource: logical_id), metdata_configset: {"Metadata" => attributes["Metadata"]} # # wrap metadata to create right structure } configsets << data end configsets end
generator_options(registry, options={})
click to toggle source
# File lib/lono/configset/combiner.rb, line 12 def generator_options(registry, options={}) o = @options.merge(configset: registry.name, resource: registry.resource) o.merge(options) end
metadata_map()
click to toggle source
# File lib/lono/configset/combiner.rb, line 17 def metadata_map return {} unless additional_configsets? existing_configsets.each do |data| add(data[:registry], data[:metdata_configset]) end Register::Blueprint.configsets.each do |registry| generator = Lono::Configset::Generator.new(generator_options(registry, type: "blueprint")) cloudformation_init = generator.build add(registry, cloudformation_init) end Register::Project.configsets.each do |registry| generator = Lono::Configset::Generator.new(generator_options(registry, type: "project")) cloudformation_init = generator.build add(registry, cloudformation_init) end combine Register::Blueprint.clear! # in case of lono generate for all templates Register::Project.clear! # in case of lono generate for all templates @map end
validate_simple!(registry, cs)
click to toggle source
# File lib/lono/configset/combiner.rb, line 142 def validate_simple!(registry, cs) has_complex_type = cs["default"].detect { |s| !s.is_a?(String) } if has_complex_type message =<<~EOL ERROR: The configset #{registry.name} has a configSets property with a complex type. configSets: #{cs} lono configsets only supports combining configSets with an Array of Strings. EOL if ENV['LONO_TEST'] raise message else puts message.color(:red) exit 1 end end end
validate_structure!(name, metadata)
click to toggle source
# File lib/lono/configset/combiner.rb, line 134 def validate_structure!(name, metadata) return if metadata.is_a?(Hash) && metadata.dig("Metadata", "AWS::CloudFormation::Init") puts "ERROR: The #{name} configset does not appear to have a AWS::CloudFormation::Init key".color(:red) puts "Please double check the #{name} configset.yml structure" exit 1 end