cfndsl 0.17.5 → 1.0.0.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +4 -4
- data/.travis.yml +6 -1
- data/CHANGELOG.md +32 -34
- data/README.md +68 -21
- data/Rakefile +25 -3
- data/TODO.md +18 -0
- data/UPGRADING.md +22 -0
- data/cfndsl.gemspec +3 -3
- data/exe/cfndsl +5 -0
- data/lib/cfndsl.rb +2 -116
- data/lib/cfndsl/aws/cloud_formation_template.rb +8 -1
- data/lib/cfndsl/aws/patches/000_sam.spec.json +574 -0
- data/lib/cfndsl/aws/patches/100_sam.spec_DeploymentPreference_patch.json +64 -0
- data/lib/cfndsl/aws/patches/500_Cognito_IdentityPoolRoleAttachment_patches.json +25 -0
- data/lib/cfndsl/aws/patches/500_IoT1Click_patch_PlacementTemplate_DeviceTemplates.json +20 -0
- data/lib/cfndsl/aws/patches/500_SAM_Serverless_Function_S3Event_Events_patch.json +16 -0
- data/lib/cfndsl/aws/patches/500_SAM_Serverless_Function_S3Location_Version_patch.json +16 -0
- data/lib/cfndsl/aws/patches/500_SSM_AssociationName_patch.json +16 -0
- data/lib/cfndsl/aws/patches/500_VPCEndpoint_patch.json +17 -0
- data/lib/cfndsl/aws/patches/510_ElasticSearch_Domain_patches.json +15 -0
- data/lib/cfndsl/aws/patches/600_RefKinds_patch.json +3654 -0
- data/lib/cfndsl/aws/patches/700_SAM_Serverless_Function_InlineCode_patch.json +20 -0
- data/lib/cfndsl/aws/patches/800_List_types_patch.json +115 -0
- data/lib/cfndsl/aws/resource_specification.json +35809 -11627
- data/lib/cfndsl/aws/types.rb +3 -3
- data/lib/cfndsl/cfnlego.rb +34 -0
- data/lib/{cfnlego → cfndsl/cfnlego}/cloudformation.erb +0 -0
- data/lib/{cfnlego → cfndsl/cfnlego}/cloudformation.rb +0 -0
- data/lib/{cfnlego → cfndsl/cfnlego}/resource.rb +3 -8
- data/lib/cfndsl/cloudformation.rb +107 -0
- data/lib/cfndsl/conditions.rb +11 -1
- data/lib/cfndsl/creation_policy.rb +1 -1
- data/lib/cfndsl/deep_merge.rb +4 -0
- data/lib/cfndsl/external_parameters.rb +4 -13
- data/lib/cfndsl/globals.rb +48 -9
- data/lib/cfndsl/jsonable.rb +22 -60
- data/lib/cfndsl/mappings.rb +1 -1
- data/lib/cfndsl/module.rb +16 -5
- data/lib/cfndsl/orchestration_template.rb +185 -83
- data/lib/cfndsl/outputs.rb +5 -1
- data/lib/cfndsl/parameters.rb +1 -1
- data/lib/cfndsl/plurals.rb +12 -1
- data/lib/cfndsl/properties.rb +1 -1
- data/lib/cfndsl/rake_task.rb +206 -12
- data/lib/cfndsl/ref_check.rb +19 -11
- data/lib/cfndsl/resources.rb +6 -19
- data/lib/cfndsl/rules.rb +1 -1
- data/lib/cfndsl/runner.rb +143 -0
- data/lib/cfndsl/specification.rb +80 -95
- data/lib/cfndsl/types.rb +205 -91
- data/lib/cfndsl/update_policy.rb +1 -1
- data/lib/cfndsl/version.rb +1 -1
- data/sample/autoscale.rb +0 -1
- data/sample/autoscale2.rb +0 -1
- data/sample/config_service.rb +2 -2
- data/sample/t1.rb +1 -1
- data/sample/vpc_example.rb +1 -1
- data/sample/vpc_with_vpn_example.rb +1 -1
- data/spec/aws/list_type_patches_spec.rb +35 -0
- data/spec/aws/nested_arrays_spec.rb +155 -3
- data/spec/aws/serverless_spec.rb +0 -2
- data/spec/cfndsl_spec.rb +94 -78
- data/spec/cli_spec.rb +16 -54
- data/spec/cloud_formation_template_spec.rb +233 -0
- data/spec/condition_spec.rb +24 -0
- data/spec/direct_ruby_spec.rb +19 -0
- data/spec/external_parameters_spec.rb +2 -15
- data/spec/fixtures/condition-assertion.json +1 -0
- data/spec/fixtures/test.rb +2 -1
- data/spec/generate_spec.rb +4 -2
- data/spec/resources_spec.rb +0 -7
- data/spec/spec_helper.rb +2 -7
- data/spec/support/shared_examples/orchestration_template.rb +15 -2
- data/spec/types_definition_spec.rb +3 -6
- metadata +52 -23
- data/bin/cfndsl +0 -160
- data/lib/cfndsl/errors.rb +0 -31
- data/lib/cfndsl/os/heat_template.rb +0 -18
- data/lib/cfndsl/os/types.rb +0 -14
- data/lib/cfndsl/os/types.yaml +0 -2423
- data/lib/cfndsl/patches.rb +0 -226
- data/lib/cfnlego.rb +0 -44
- data/spec/fixtures/heattest.rb +0 -24
- data/spec/heat_template_spec.rb +0 -7
data/lib/cfndsl/aws/types.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative '../jsonable'
|
4
|
+
require_relative '../types'
|
4
5
|
|
5
6
|
module CfnDsl
|
6
7
|
module AWS
|
7
8
|
# Cloud Formation Types
|
8
9
|
module Types
|
9
|
-
TYPE_PREFIX = 'aws'
|
10
10
|
class Type < JSONable; end
|
11
|
-
include CfnDsl::Types
|
11
|
+
include CfnDsl::Types # This include triggers loading and patching of the global specification
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'erb'
|
5
|
+
require 'net/http'
|
6
|
+
require 'uri'
|
7
|
+
require_relative 'cfnlego/cloudformation'
|
8
|
+
require_relative 'cfnlego/resource'
|
9
|
+
require_relative 'specification'
|
10
|
+
|
11
|
+
# Cfnlego
|
12
|
+
module Cfnlego
|
13
|
+
def self.resources
|
14
|
+
@resources ||= CfnDsl::Specification.load_file.resources
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.run(options)
|
18
|
+
resources =
|
19
|
+
options[:resources].each_with_object([]) do |r, list|
|
20
|
+
/(.*),(.*)/.match(r) do |m|
|
21
|
+
type = m[1]
|
22
|
+
name = m[2]
|
23
|
+
list << Cfnlego::Resource.new(type, name)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
begin
|
28
|
+
return Cfnlego::CloudFormation.new(resources).render
|
29
|
+
rescue RuntimeError => e
|
30
|
+
warn "Error: #{e.message}"
|
31
|
+
end
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
end
|
File without changes
|
File without changes
|
@@ -26,14 +26,9 @@ module Cfnlego
|
|
26
26
|
private
|
27
27
|
|
28
28
|
def definition
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
begin
|
33
|
-
@definition ||= data[@type]
|
34
|
-
rescue RuntimeError
|
35
|
-
raise "unknown #{@type}, no matching definition found"
|
36
|
-
end
|
29
|
+
@definition ||= Cfnlego.resources[@type]
|
30
|
+
rescue StandardError
|
31
|
+
raise "unknown #{@type}, no matching definition found"
|
37
32
|
end
|
38
33
|
end
|
39
34
|
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'globals'
|
4
|
+
require_relative 'external_parameters'
|
5
|
+
require_relative 'aws/cloud_formation_template'
|
6
|
+
|
7
|
+
# CfnDsl
|
8
|
+
module CfnDsl
|
9
|
+
# This function handles the eval of the template file and returns the
|
10
|
+
# results. It does this with a ruby "eval", but it builds up a customized
|
11
|
+
# binding environment before it calls eval. The environment can be
|
12
|
+
# customized by passing a list of customizations in the extras parameter.
|
13
|
+
#
|
14
|
+
# These customizations are expressed as an array of pairs of
|
15
|
+
# (type,filename). They are evaluated in the order they appear in the
|
16
|
+
# extras array. The types are as follows
|
17
|
+
#
|
18
|
+
# :yaml - the second element is treated as a file name, which is loaded
|
19
|
+
# as a yaml file. The yaml file should contain a top level
|
20
|
+
# dictionary. Each of the keys of the top level dictionary is
|
21
|
+
# used as a local variable in the evalation context.
|
22
|
+
#
|
23
|
+
# :json - the second element is treated as a file name, which is loaded
|
24
|
+
# as a json file. The yaml file should contain a top level
|
25
|
+
# dictionary. Each of the keys of the top level dictionary is
|
26
|
+
# used as a local variable in the evalation context.
|
27
|
+
#
|
28
|
+
# :raw - the second element is treated as a ruby statement and is
|
29
|
+
# evaluated in the binding context, similar to the contents of
|
30
|
+
# a ruby file.
|
31
|
+
#
|
32
|
+
# Note that the order is important, as later extra sections can overwrite
|
33
|
+
# or even undo things that were done by earlier sections.
|
34
|
+
|
35
|
+
def self.eval_file_with_extras(filename, extras = [], logstream = nil)
|
36
|
+
b = binding
|
37
|
+
params = CfnDsl::ExternalParameters.refresh!
|
38
|
+
extras.each do |type, file|
|
39
|
+
case type
|
40
|
+
when :yaml, :json
|
41
|
+
klass_name = type.to_s.upcase
|
42
|
+
logstream.puts("Loading #{klass_name} file #{file}") if logstream
|
43
|
+
params.load_file file
|
44
|
+
when :raw
|
45
|
+
params.set_param(*file.split('='))
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
logstream.puts("Loading template file #{filename}") if logstream
|
50
|
+
b.eval(File.read(filename), filename)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Syntactic Sugar for embedded ruby usage
|
54
|
+
# @example
|
55
|
+
# require `cfndsl`
|
56
|
+
#
|
57
|
+
# class Builder
|
58
|
+
# include CfnDsl::CloudFormation
|
59
|
+
#
|
60
|
+
# def build_template()
|
61
|
+
# template = CloudFormation('ANewTemplate')
|
62
|
+
# a_param = template.Parameter('AParam')
|
63
|
+
# a_param.Type('String')
|
64
|
+
# return template
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# def map_instance_type(instance_type)
|
68
|
+
# # logic to auto convert instance types to latest available etc..
|
69
|
+
# FnFindInMap("InstanceTypeConversion",Ref('AWS::Region'),instance_type)
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
# # templates can be passed around to other methods/classes
|
73
|
+
# def add_instance(template, instance_type)
|
74
|
+
# ec2 = template.EC2_Instance(:myInstance)
|
75
|
+
# ec2.InstanceType(map_instance_type(instance_type))
|
76
|
+
# # Alteratively with DSL block syntax
|
77
|
+
# this = self # declare block is eval for the model instance so need to keep a reference
|
78
|
+
# template.declare do
|
79
|
+
# EC2_Instance(:myInstance) do
|
80
|
+
# InstanceType this.map_instance_type(instance_type)
|
81
|
+
# end
|
82
|
+
# end
|
83
|
+
# end
|
84
|
+
#
|
85
|
+
# def generate(template,pretty: false)
|
86
|
+
# valid = template.validate
|
87
|
+
# pretty ? valid.to_json : JSON.pretty_generate(valid)
|
88
|
+
# end
|
89
|
+
# end
|
90
|
+
#
|
91
|
+
module CloudFormation
|
92
|
+
# Include all the fun JSONABLE stuff and Fn* functions so you can use them
|
93
|
+
# in local methods
|
94
|
+
include Functions
|
95
|
+
|
96
|
+
def CloudFormation(description = nil, &block)
|
97
|
+
CloudFormationTemplate.new(description, &block)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Main function to build and validate
|
103
|
+
# @return [CfnDsl::CloudFormationTemplate]
|
104
|
+
# @raise [CfnDsl::Error] if the block does not generate a valid template
|
105
|
+
def CloudFormation(description = nil, &block)
|
106
|
+
CfnDsl::CloudFormationTemplate.new(description).declare(&block).validate
|
107
|
+
end
|
data/lib/cfndsl/conditions.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative 'jsonable'
|
4
4
|
|
5
5
|
module CfnDsl
|
6
6
|
# Handles condition objects
|
@@ -13,5 +13,15 @@ module CfnDsl
|
|
13
13
|
def initialize(value)
|
14
14
|
@value = value
|
15
15
|
end
|
16
|
+
|
17
|
+
# For when Condition is used inside Fn::And, Fn::Or, Fn::Not
|
18
|
+
def condition_refs
|
19
|
+
case @value
|
20
|
+
when String, Symbol
|
21
|
+
[@value.to_s]
|
22
|
+
else
|
23
|
+
[]
|
24
|
+
end
|
25
|
+
end
|
16
26
|
end
|
17
27
|
end
|
@@ -1,5 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'forwardable'
|
4
|
+
require 'json'
|
5
|
+
require_relative 'deep_merge'
|
6
|
+
|
3
7
|
module CfnDsl
|
4
8
|
# Handles all external parameters
|
5
9
|
class ExternalParameters
|
@@ -46,19 +50,6 @@ module CfnDsl
|
|
46
50
|
parameters
|
47
51
|
end
|
48
52
|
|
49
|
-
def add_to_binding(bind, logstream)
|
50
|
-
parameters.each_pair do |key, val|
|
51
|
-
# rubocop:disable Style/SafeNavigation
|
52
|
-
logstream.puts("Setting local variable #{key} to #{val}") if logstream
|
53
|
-
# rubocop:enable Style/SafeNavigation
|
54
|
-
if defined?(key) && val.is_a?(Hash)
|
55
|
-
bind.eval "#{key}.merge(#{val.inspect})"
|
56
|
-
else
|
57
|
-
bind.eval "#{key} = #{val.inspect}"
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
53
|
def load_file(fname)
|
63
54
|
format = File.extname fname
|
64
55
|
case format
|
data/lib/cfndsl/globals.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'version'
|
4
|
+
|
3
5
|
# Global variables to adjust CfnDsl behavior
|
4
6
|
module CfnDsl
|
5
|
-
|
6
|
-
|
7
|
-
def disable_binding
|
8
|
-
@disable_binding = true
|
7
|
+
class Error < StandardError
|
9
8
|
end
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
module_function
|
11
|
+
|
12
|
+
AWS_SPECIFICATION_URL = 'https://d1uauaxba7bl26.cloudfront.net/%<version>s/gzip/CloudFormationResourceSpecification.json'
|
13
|
+
LOCAL_SPEC_FILE = File.expand_path('aws/resource_specification.json', __dir__)
|
14
14
|
|
15
15
|
def disable_deep_merge
|
16
16
|
@disable_deep_merge = true
|
@@ -20,12 +20,51 @@ module CfnDsl
|
|
20
20
|
@disable_deep_merge
|
21
21
|
end
|
22
22
|
|
23
|
+
def specification_file=(file)
|
24
|
+
raise Error, "Specification #{file} does not exist" unless File.exist?(file)
|
25
|
+
|
26
|
+
@specification_file = file
|
27
|
+
end
|
28
|
+
|
29
|
+
# @overload specification_file()
|
30
|
+
# @return [String] the specification file name
|
31
|
+
# @overload specification_file(file)
|
32
|
+
# @deprecated Use specification_file= to override the specification file
|
23
33
|
def specification_file(file = nil)
|
24
|
-
|
25
|
-
@specification_file ||=
|
34
|
+
self.specification_file = file if file
|
35
|
+
@specification_file ||= user_specification_file
|
36
|
+
@specification_file = LOCAL_SPEC_FILE unless File.exist?(@specification_file)
|
26
37
|
@specification_file
|
27
38
|
end
|
28
39
|
|
40
|
+
def user_specification_file
|
41
|
+
File.join(ENV['HOME'], '.cfndsl/resource_specification.json')
|
42
|
+
end
|
43
|
+
|
44
|
+
def update_specification_file(file: user_specification_file, version: nil)
|
45
|
+
require 'open-uri'
|
46
|
+
version ||= 'latest'
|
47
|
+
FileUtils.mkdir_p File.dirname(file)
|
48
|
+
url = format(AWS_SPECIFICATION_URL, version: version)
|
49
|
+
content = URI.parse(url).open.read
|
50
|
+
version = JSON.parse(content)['ResourceSpecificationVersion'] if version == 'latest'
|
51
|
+
File.open(file, 'w') { |f| f.puts content }
|
52
|
+
{ file: file, version: version, url: url }
|
53
|
+
rescue StandardError
|
54
|
+
raise "Failed updating specification file #{file} from #{url}"
|
55
|
+
end
|
56
|
+
|
57
|
+
def additional_specs(*specs)
|
58
|
+
@additional_specs ||= Dir[File.expand_path('aws/patches/*.spec.json', __dir__)]
|
59
|
+
@additional_specs.concat(specs.flatten)
|
60
|
+
end
|
61
|
+
|
62
|
+
def specification_patches(*patches)
|
63
|
+
# TODO: This is not capturing all the files in patches dir!
|
64
|
+
@patches ||= Dir[File.expand_path('aws/patches/*patch.json', __dir__)]
|
65
|
+
@patches.concat(patches.flatten)
|
66
|
+
end
|
67
|
+
|
29
68
|
def reserved_items
|
30
69
|
%w[Resource Rule Parameter Output].freeze
|
31
70
|
end
|
data/lib/cfndsl/jsonable.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
require_relative 'ref_check'
|
4
|
+
require_relative 'json_serialisable_object'
|
5
|
+
require_relative 'external_parameters'
|
6
6
|
|
7
7
|
module CfnDsl
|
8
8
|
# These functions are available anywhere inside
|
@@ -25,7 +25,7 @@ module CfnDsl
|
|
25
25
|
|
26
26
|
# Equivalent to the CloudFormation template built in function Fn::GetAtt
|
27
27
|
def FnGetAtt(logical_resource, attribute)
|
28
|
-
Fn.new('GetAtt', [logical_resource, attribute])
|
28
|
+
Fn.new('GetAtt', [logical_resource, attribute], [logical_resource])
|
29
29
|
end
|
30
30
|
|
31
31
|
# Equivalent to the CloudFormation template built in function Fn::GetAZs
|
@@ -57,7 +57,7 @@ module CfnDsl
|
|
57
57
|
|
58
58
|
# Equivalent to the Cloudformation template built in function Fn::If
|
59
59
|
def FnIf(condition_name, true_value, false_value)
|
60
|
-
Fn.new('If', [condition_name, true_value, false_value])
|
60
|
+
Fn.new('If', [condition_name, true_value, false_value], [], [condition_name])
|
61
61
|
end
|
62
62
|
|
63
63
|
# Equivalent to the Cloudformation template built in function Fn::Not
|
@@ -82,15 +82,20 @@ module CfnDsl
|
|
82
82
|
end
|
83
83
|
|
84
84
|
# Equivalent to the CloudFormation template built in function Fn::Sub
|
85
|
+
FN_SUB_SCANNER = /\$\{([^!}]*)\}/.freeze
|
86
|
+
|
85
87
|
def FnSub(string, substitutions = nil)
|
86
88
|
raise ArgumentError, 'The first argument passed to Fn::Sub must be a string' unless string.is_a? String
|
87
89
|
|
90
|
+
refs = string.scan(FN_SUB_SCANNER).map(&:first)
|
91
|
+
|
88
92
|
if substitutions
|
89
93
|
raise ArgumentError, 'The second argument passed to Fn::Sub must be a Hash' unless substitutions.is_a? Hash
|
90
94
|
|
91
|
-
|
95
|
+
refs -= substitutions.keys.map(&:to_s)
|
96
|
+
Fn.new('Sub', [string, substitutions], refs)
|
92
97
|
else
|
93
|
-
Fn.new('Sub', string)
|
98
|
+
Fn.new('Sub', string, refs)
|
94
99
|
end
|
95
100
|
end
|
96
101
|
|
@@ -99,60 +104,11 @@ module CfnDsl
|
|
99
104
|
Fn.new('ImportValue', value)
|
100
105
|
end
|
101
106
|
|
102
|
-
# DEPRECATED
|
103
|
-
# Usage
|
104
|
-
# FnFormat('This is a %0. It is 100%% %1', 'test', 'effective')
|
105
|
-
# or
|
106
|
-
# FnFormat('This is a %{test}. It is 100%% %{effective}',
|
107
|
-
# :test => 'test",
|
108
|
-
# :effective => 'effective')
|
109
|
-
#
|
110
|
-
# These will each generate a call to Fn::Join that when
|
111
|
-
# evaluated will produce the string "This is a test. It is 100%
|
112
|
-
# effective."
|
113
|
-
#
|
114
|
-
# Think of this as %0, %1, etc in the format string being replaced by the
|
115
|
-
# corresponding arguments given after the format string. '%%' is replaced
|
116
|
-
# by the '%' character.
|
117
|
-
#
|
118
|
-
# The actual Fn::Join call corresponding to the above FnFormat call would be
|
119
|
-
# {"Fn::Join": ["",["This is a ","test",". It is 100","%"," ","effective"]]}
|
120
|
-
#
|
121
|
-
# If no arguments are given, or if a hash is given and the format
|
122
|
-
# variable name does not exist in the hash, it is used as a Ref
|
123
|
-
# to an existing resource or parameter.
|
124
|
-
#
|
125
|
-
# rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
126
|
-
def FnFormat(string, *arguments)
|
127
|
-
warn '`FnFormat` is deprecated and will be removed a future release. Use `FnSub` instead'
|
128
|
-
array = []
|
129
|
-
|
130
|
-
if arguments.empty? || (arguments.length == 1 && arguments[0].instance_of?(Hash))
|
131
|
-
hash = arguments[0] || {}
|
132
|
-
string.scan(/(.*?)(?:%(%|\{([\w:]+)\})|\z)/m) do |x, y, z|
|
133
|
-
array.push x if x && !x.empty?
|
134
|
-
|
135
|
-
next unless y
|
136
|
-
|
137
|
-
array.push(y == '%' ? '%' : (hash[z] || hash[z.to_sym] || Ref(z)))
|
138
|
-
end
|
139
|
-
else
|
140
|
-
string.scan(/(.*?)(?:%(%|\d+)|\z)/m) do |x, y|
|
141
|
-
array.push x if x && !x.empty?
|
142
|
-
|
143
|
-
next unless y
|
144
|
-
|
145
|
-
array.push(y == '%' ? '%' : arguments[y.to_i])
|
146
|
-
end
|
147
|
-
end
|
148
|
-
Fn.new('Join', ['', array])
|
149
|
-
end
|
150
|
-
|
151
107
|
# Equivalent to the CloudFormation template built in function Fn::Cidr
|
152
108
|
def FnCidr(ipblock, count, sizemask)
|
153
109
|
Fn.new('Cidr', [ipblock, count, sizemask])
|
154
110
|
end
|
155
|
-
# rubocop:enable
|
111
|
+
# rubocop:enable
|
156
112
|
end
|
157
113
|
|
158
114
|
# This is the base class for just about everything useful in the
|
@@ -204,15 +160,17 @@ module CfnDsl
|
|
204
160
|
|
205
161
|
def declare(&block)
|
206
162
|
instance_eval(&block) if block_given?
|
163
|
+
self
|
207
164
|
end
|
208
165
|
end
|
209
166
|
|
210
167
|
# Handles all of the Fn:: objects
|
211
168
|
class Fn < JSONable
|
212
|
-
def initialize(function, argument, refs = [])
|
169
|
+
def initialize(function, argument, refs = [], condition_refs = [])
|
213
170
|
@function = function
|
214
171
|
@argument = argument
|
215
172
|
@_refs = refs
|
173
|
+
@_condition_refs = condition_refs
|
216
174
|
end
|
217
175
|
|
218
176
|
def as_json(_options = {})
|
@@ -225,12 +183,16 @@ module CfnDsl
|
|
225
183
|
as_json.to_json(*args)
|
226
184
|
end
|
227
185
|
|
228
|
-
def
|
186
|
+
def all_refs
|
229
187
|
@_refs
|
230
188
|
end
|
231
189
|
|
190
|
+
def condition_refs
|
191
|
+
@_condition_refs
|
192
|
+
end
|
193
|
+
|
232
194
|
def ref_children
|
233
|
-
[@argument]
|
195
|
+
[@argument].flatten
|
234
196
|
end
|
235
197
|
end
|
236
198
|
|