Class: MkStack::Template

Inherits:
Object
  • Object
show all
Defined in:
lib/mkstack/template.rb

Overview

A CloudFormation template

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(format = "json") ⇒ Template

Returns a new instance of Template.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/mkstack/template.rb', line 13

def initialize(format = "json")
  @format = format

  @sections = {
    "AWSTemplateFormatVersion" => Section.new("AWSTemplateFormatVersion", String, nil),
    "Description" => Section.new("Description", String, 1024),

    "Conditions"  => Section.new("Conditions",  Hash, nil),
    "Mappings"    => Section.new("Mappings",    Hash, 100),
    "Metadata"    => Section.new("Metadata",    Hash, nil),
    "Outputs"     => Section.new("Outputs",     Hash, 60),
    "Parameters"  => Section.new("Parameters",  Hash, 60),
    "Resources"   => Section.new("Resources",   Hash, nil),
    "Transforms"  => Section.new("Transforms",  Hash, nil),
  }
  @limit = 51200

  # Keep track of parsed files to avoid loops
  @parsed = {}

  # Save a binding so ERB can reuse it instead of creating a new one
  # every time we load a file.  This allows ERB code in one file to
  # be referenced in another.
  @binding = binding

  # See add_domain_types
  @yaml_domain = "mlfs.org,2019"
  @global_tag = "tag:#{@yaml_domain}:"
end

Instance Attribute Details

#formatObject (readonly)

Returns the value of attribute format.



11
12
13
# File 'lib/mkstack/template.rb', line 11

def format
  @format
end

#limitObject (readonly)

Returns the value of attribute limit.



11
12
13
# File 'lib/mkstack/template.rb', line 11

def limit
  @limit
end

#sectionsObject (readonly)

Returns the value of attribute sections.



11
12
13
# File 'lib/mkstack/template.rb', line 11

def sections
  @sections
end

Instance Method Details

#[](section) ⇒ Object

Shorthand accessor for template sections



44
# File 'lib/mkstack/template.rb', line 44

def [](section); @sections[section]; end

#exceeds_limit?Boolean

Check if the template exceeds the AWS limit

Returns:

  • (Boolean)


50
# File 'lib/mkstack/template.rb', line 50

def exceeds_limit?; limit && length > limit; end

#lengthObject

Return the length of the entire template



47
# File 'lib/mkstack/template.rb', line 47

def length; to_json.to_s.length; end

#merge(file, erb) ⇒ Object

Merge contents of a file



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/mkstack/template.rb', line 55

def merge(file, erb)
  contents = load(file, erb)

  begin
    # Try JSON
    cfn = JSON.load(contents)
  rescue Exception => e
    # Try YAML
    add_domain_types
    cfn = YAML.load(contents)
  end

  # Merge sections that are present in the file
  @sections.each { |name, section| section.merge(cfn[name]) if cfn[name] }

  # Look for Includes and merge them
  # Files are Included relative to the file with the Include directive
  cfn["Include"].each do |file|
    Dir.chdir(File.dirname(file)) { self.merge(File.basename(file), erb) }
  end if cfn["Include"]
end

#ppObject

Format contents



88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/mkstack/template.rb', line 88

def pp
  case @format
  when "json"
    to_hash.to_json
  when "yaml"
    # Strip enclosing quotes around tags and revert tags to their short form
    # And keep Psych from splitting "long" lines
    to_hash.to_yaml({ line_width: -1 }).gsub(/"(#{@global_tag}[^"]+?)"/, '\1').gsub("#{@global_tag}", "!")
  else
    to_hash
  end
end

#validateObject



80
81
82
83
# File 'lib/mkstack/template.rb', line 80

def validate
  require "aws-sdk-cloudformation"
  Aws::CloudFormation::Client.new.validate_template({ template_body: pp })
end