class Convection::Model::Template
Template
container class
Constants
- DEFAULT_VERSION
Attributes
attribute_mappings[R]
conditions[R]
mappings[R]
outputs[R]
parameters[R]
resource_collections[R]
resources[R]
stack[R]
Public Class Methods
new(stack = nil, &block)
click to toggle source
# File lib/convection/model/template.rb, line 239 def initialize(stack = nil, &block) @definition = block @stack = stack @attribute_mappings = {} @version = DEFAULT_VERSION @description = '' @parameters = Collection.new @mappings = Collection.new @conditions = Collection.new @resources = Collection.new @resource_collections = Collection.new @outputs = Collection.new @metadata = Collection.new end
Public Instance Methods
all_resources()
click to toggle source
# File lib/convection/model/template.rb, line 293 def all_resources resource_collections.reduce(resources) do |result, (_name, resource_collection)| result.merge(resource_collection.resources) end end
clone(stack_)
click to toggle source
# File lib/convection/model/template.rb, line 257 def clone(stack_) Template.new(stack_, &@definition) end
diff(other, stack_ = nil, retain: false)
click to toggle source
# File lib/convection/model/template.rb, line 299 def diff(other, stack_ = nil, retain: false) # We want to accurately show when the DeletionPolicy is getting deleted and also when resources are going to be retained. # Sample DeletionPolicy Removal output # us-east-1 compare Compare local state of stack test-logs-deletion with remote template # us-east-1 delete Resources.sgtestConvectionDeletion.DeletionPolicy # # Sample Mixed Retain/Delete Resources # us-east-1 retain Resources.ELBLoggingPolicy.DependsOn.AWS::S3::BucketPolicy.0 # us-east-1 retain Resources.ELBLoggingPolicy.DeletionPolicy # us-east-1 delete Resources.sgtestConvectionDeletion.Type # us-east-1 delete Resources.sgtestConvectionDeletion.Properties.AWS::EC2::SecurityGroup.GroupDescription # us-east-1 delete Resources.sgtestConvectionDeletion.Properties.AWS::EC2::SecurityGroup.VpcId # events = render(stack_, retain: retain).diff(other).map { |diff| Diff.new(diff[0], *diff[1]) } # Top level events (changes to the resource directly) have keys with a format "Resources.{NAME}.{KEY}". # So we can count the number of separators to find them. top_level_events = events.select { |event| event.key.count('.') <= 2 } # We know something's a deleted resource when it has a top level "Type" attribute. type_suffix = '.Type'.freeze deleted_resources = top_level_events.select do |event| event.action == :delete && event.key.end_with?(type_suffix) end deleted_resources.map! { |event| event.key[0...-type_suffix.length] } # We know something's a retainable resource when it has a top level "DeletionPolicy" attribute. delete_policy_suffix = '.DeletionPolicy'.freeze retainable_resources = top_level_events.select do |event| event.action == :delete && event.key.end_with?(delete_policy_suffix) && event.theirs == 'Retain' end retainable_resources.map! { |event| event.key[0...-delete_policy_suffix.length] } retainable_resources.keep_if { |name| deleted_resources.include?(name) } events.each do |event| retained = retainable_resources.any? { |name| event.action == :delete && event.key.start_with?(name) } event.action = :retain if retained end events end
execute()
click to toggle source
# File lib/convection/model/template.rb, line 261 def execute instance_exec(&@definition) resource_collections.each do |_, group| group.run_definition group.execute end end
render(stack_ = nil, retain: false)
click to toggle source
# File lib/convection/model/template.rb, line 270 def render(stack_ = nil, retain: false) ## Instantiate a new template with the definition block and an other stack return clone(stack_).render unless stack_.nil? execute ## Process the template document { 'AWSTemplateFormatVersion' => version, 'Description' => description, 'Parameters' => parameters.map(&:render), 'Mappings' => mappings.map(&:render), 'Conditions' => conditions.map(&:render), 'Resources' => all_resources.map do |resource| if retain && resource.deletion_policy.nil? resource.deletion_policy('Retain') end resource.render end, 'Outputs' => outputs.map(&:render), 'Metadata' => metadata.map(&:render) } end
template()
click to toggle source
# File lib/convection/model/template.rb, line 235 def template self end
to_json(stack_ = nil, pretty = false, retain: false)
click to toggle source
# File lib/convection/model/template.rb, line 341 def to_json(stack_ = nil, pretty = false, retain: false) rendered_stack = render(stack_, retain: retain) validate(rendered_stack) return JSON.generate(rendered_stack) unless pretty JSON.pretty_generate(rendered_stack) end
validate(rendered_stack = nil)
click to toggle source
# File lib/convection/model/template.rb, line 348 def validate(rendered_stack = nil) %w(resources mappings parameters outputs description bytesize).map do |method| send("validate_#{method}", rendered_stack) end end
validate_bytesize(rendered_stack)
click to toggle source
# File lib/convection/model/template.rb, line 437 def validate_bytesize(rendered_stack) json = JSON.generate(rendered_stack) validate_compare(json.bytesize, CF_MAX_BYTESIZE, ExcessiveTemplateSizeError) end
validate_compare(value, cf_max, error)
click to toggle source
# File lib/convection/model/template.rb, line 354 def validate_compare(value, cf_max, error) limit_exceeded_error(value, cf_max, error) if value > cf_max end
validate_description(rendered_stack)
click to toggle source
# File lib/convection/model/template.rb, line 431 def validate_description(rendered_stack) validate_compare(rendered_stack['Description'].bytesize, CF_MAX_DESCRIPTION_BYTESIZE, ExcessiveDescriptionError) end
validate_mappings(rendered_stack)
click to toggle source
# File lib/convection/model/template.rb, line 369 def validate_mappings(rendered_stack) mappings = rendered_stack ['Mappings'] validate_compare(mappings.count, CF_MAX_MAPPINGS, ExcessiveMappingsError) mappings.each do |_, value| validate_compare( value.count, CF_MAX_MAPPING_ATTRIBUTES, ExcessiveMappingAttributesError ) end mappings.keys.each do |key| validate_compare(key.length, CF_MAX_MAPPING_NAME, ExcessiveMappingNameError) end ## XXX What are we trying to do here @aburke mapping_attributes = mappings.values.flat_map do |inner_hash| inner_hash.keys.select do |key| value = inner_hash[key] end end mapping_attributes.each do |attribute| validate_compare(attribute.length, CF_MAX_MAPPING_ATTRIBUTE_NAME, ExcessiveMappingAttributeNameError) end end
validate_outputs(rendered_stack)
click to toggle source
# File lib/convection/model/template.rb, line 419 def validate_outputs(rendered_stack) outputs = rendered_stack['Outputs'] validate_compare(outputs.count, CF_MAX_OUTPUTS, ExcessiveOutputsError) largest_output_name = outputs.keys.max largest_output_name ||= '' validate_compare(largest_output_name.length, CF_MAX_OUTPUT_NAME_CHARACTERS, ExcessiveOutputNameError) end
validate_parameters(rendered_stack)
click to toggle source
# File lib/convection/model/template.rb, line 402 def validate_parameters(rendered_stack) parameters = rendered_stack['Parameters'] validate_compare(parameters.count, CF_MAX_PARAMETERS, ExcessiveParametersError) largest_parameter_name = parameters.keys.max largest_parameter_name ||= '' validate_compare(largest_parameter_name.length, CF_MAX_PARAMETER_NAME_CHARACTERS, ExcessiveParameterNameError) parameters.values.each do |value| validate_compare(JSON.generate(value).bytesize, CF_MAX_PARAMETER_VALUE_BYTESIZE, ExcessiveParameterBytesizeError) end end
validate_resources(rendered_stack)
click to toggle source
# File lib/convection/model/template.rb, line 358 def validate_resources(rendered_stack) validate_compare(rendered_stack['Resources'].count, CF_MAX_RESOURCES, ExcessiveResourcesError) largest_resource_name = resources.keys.max || '' validate_compare(largest_resource_name.length, CF_MAX_RESOURCE_NAME, ExcessiveResourceNameError) end