cfn-model 0.4.31 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/cfn-model/model/references.rb +120 -1
- data/lib/cfn-model/parser/parameter_substitution.rb +2 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e4980780e48883af420ef019bce841105f1c4c33f96e090c491296a2b9f74199
|
4
|
+
data.tar.gz: 21a4292366a0363bec0a92113033f4f759399ca6e0c29063c0d6b5e17525ab90
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bc7e5193fd227a66df09aa86e8810fb019313e32e48834cee1a22931493887b4f8351370017a410058ffb2c149c91adafdc167757eff59904bd957846da2ebf9
|
7
|
+
data.tar.gz: 312c9e00357b034832815b4d0b8148a00a33293de6b4055548b877305e0b9319e41a15a3f928470d02a48eb3c9c7af499f7984d834bf7ba4058779a7aedcab41
|
@@ -9,6 +9,10 @@ require 'cfn-model/parser/parser_error'
|
|
9
9
|
# references yet... in the meantime pile things up here and hope a pattern becomes
|
10
10
|
# clear
|
11
11
|
module References
|
12
|
+
def self.unsupported_passthru?(value)
|
13
|
+
value.has_key?('Fn::GetAtt') || value.has_key?('Fn::ImportValue') || value.has_key?('Fn::Transform') || value.has_key?('Fn::Cidr')
|
14
|
+
end
|
15
|
+
|
12
16
|
def self.resolve_value(cfn_model, value)
|
13
17
|
if value.is_a? Hash
|
14
18
|
if value.has_key?('Ref')
|
@@ -17,7 +21,21 @@ module References
|
|
17
21
|
resolve_map(cfn_model, value)
|
18
22
|
elsif value.has_key?('Fn::If')
|
19
23
|
resolve_if(cfn_model, value)
|
20
|
-
|
24
|
+
elsif value.has_key?('Fn::Sub')
|
25
|
+
resolve_sub(cfn_model, value)
|
26
|
+
elsif value.has_key?('Fn::GetAZs')
|
27
|
+
resolve_getazs(cfn_model, value)
|
28
|
+
elsif value.has_key?('Fn::Split')
|
29
|
+
resolve_split(cfn_model, value)
|
30
|
+
elsif value.has_key?('Fn::Join')
|
31
|
+
resolve_join(cfn_model, value)
|
32
|
+
elsif value.has_key?('Fn::Base64')
|
33
|
+
resolve_base64(cfn_model, value)
|
34
|
+
elsif value.has_key?('Fn::Select')
|
35
|
+
resolve_select(cfn_model, value)
|
36
|
+
elsif unsupported_passthru?(value)
|
37
|
+
value
|
38
|
+
else # another mapping
|
21
39
|
value.map do |k,v|
|
22
40
|
[k, resolve_value(cfn_model, v)]
|
23
41
|
end.to_h
|
@@ -101,6 +119,107 @@ module References
|
|
101
119
|
|
102
120
|
private
|
103
121
|
|
122
|
+
def self.resolve_sub(cfn_model, expression)
|
123
|
+
if expression['Fn::Sub'].is_a? String
|
124
|
+
resolve_shorthand_sub(cfn_model, expression)
|
125
|
+
elsif expression['Fn::Sub'].is_a? Array
|
126
|
+
resolve_longform_sub(cfn_model, expression)
|
127
|
+
else
|
128
|
+
expression
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def self.resolve_select(cfn_model, reference)
|
133
|
+
index = reference['Fn::Select'][0]
|
134
|
+
collection = References.resolve_value(cfn_model, reference['Fn::Select'][1])
|
135
|
+
if collection.is_a? Array
|
136
|
+
collection[index]
|
137
|
+
else
|
138
|
+
reference
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def self.resolve_base64(cfn_model, reference)
|
143
|
+
References.resolve_value(cfn_model, reference['Fn::Base64'])
|
144
|
+
end
|
145
|
+
|
146
|
+
def self.resolve_join(cfn_model, reference)
|
147
|
+
delimiter = reference['Fn::Join'][0]
|
148
|
+
items = References.resolve_value(cfn_model, reference['Fn::Join'][1])
|
149
|
+
return reference unless items.is_a?(Array)
|
150
|
+
items.join(delimiter)
|
151
|
+
end
|
152
|
+
|
153
|
+
def self.resolve_split(cfn_model, reference)
|
154
|
+
delimiter = reference['Fn::Split'][0]
|
155
|
+
target_string = References.resolve_value(cfn_model, reference['Fn::Split'][1])
|
156
|
+
return reference unless target_string.is_a?(String)
|
157
|
+
target_string.split(delimiter)
|
158
|
+
end
|
159
|
+
|
160
|
+
def self.resolve_getazs(cfn_model, reference)
|
161
|
+
number_azs = References.resolve_value(cfn_model, { 'Ref' => 'AWS::NumberAZs' })
|
162
|
+
region = reference['Fn::GetAZs']
|
163
|
+
if region == '' || region == { 'Ref' => 'AWS::Region' }
|
164
|
+
region = References.resolve_value(cfn_model, { 'Ref' => 'AWS::Region' })
|
165
|
+
end
|
166
|
+
(('a'.ord)..('a'.ord+number_azs)).map do |az_number|
|
167
|
+
"#{region}#{az_number.chr}"
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def self.strip_cfn_interpolation(reference)
|
172
|
+
reference[2..-2]
|
173
|
+
end
|
174
|
+
|
175
|
+
def self.references_in_sub(string_value)
|
176
|
+
# ignore ${!foo} as cfn interprets that as the literal ${foo}
|
177
|
+
references = string_value.scan /\${[^!].*?}/
|
178
|
+
references.map { |reference| strip_cfn_interpolation(reference) }
|
179
|
+
end
|
180
|
+
|
181
|
+
def self.resolvable_reference?(cfn_model, reference)
|
182
|
+
resolved_value = References.resolve_value(cfn_model, {'Ref'=>reference})
|
183
|
+
resolved_value != {'Ref'=>reference}
|
184
|
+
end
|
185
|
+
|
186
|
+
def self.resolve_shorthand_sub(cfn_model, expression)
|
187
|
+
string_value = expression['Fn::Sub']
|
188
|
+
subbed_string_value = string_value
|
189
|
+
has_unresolved_references = false
|
190
|
+
references_in_sub(string_value).each do |reference|
|
191
|
+
if resolvable_reference?(cfn_model, reference)
|
192
|
+
subbed_string_value = subbed_string_value.gsub(
|
193
|
+
"${#{reference}}",
|
194
|
+
References.resolve_value(cfn_model, {'Ref'=>reference})
|
195
|
+
)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
subbed_string_value
|
199
|
+
end
|
200
|
+
|
201
|
+
def self.resolve_longform_sub(cfn_model, expression)
|
202
|
+
array_value = expression['Fn::Sub']
|
203
|
+
subbed_string_value = array_value[0]
|
204
|
+
substitution_mapping = array_value[1]
|
205
|
+
references_in_sub(subbed_string_value).each do |reference|
|
206
|
+
if substitution_mapping.has_key? reference
|
207
|
+
if References.resolve_value(cfn_model, substitution_mapping[reference]).is_a?(String)
|
208
|
+
subbed_string_value = subbed_string_value.gsub(
|
209
|
+
"${#{reference}}",
|
210
|
+
References.resolve_value(cfn_model, substitution_mapping[reference])
|
211
|
+
)
|
212
|
+
end
|
213
|
+
elsif resolvable_reference?(cfn_model, reference)
|
214
|
+
subbed_string_value = subbed_string_value.gsub(
|
215
|
+
"${#{reference}}",
|
216
|
+
References.resolve_value(cfn_model, {'Ref'=>reference})
|
217
|
+
)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
subbed_string_value
|
221
|
+
end
|
222
|
+
|
104
223
|
def self.resolve_if(cfn_model, expression)
|
105
224
|
if_expression = expression['Fn::If']
|
106
225
|
condition_name = if_expression[0]
|
@@ -43,7 +43,8 @@ class ParameterSubstitution
|
|
43
43
|
'AWS::AccountId' => '111111111111',
|
44
44
|
'AWS::Region' => 'us-east-1',
|
45
45
|
'AWS::StackId' => 'arn:aws:cloudformation:us-east-1:111111111111:stack/stackname/51af3dc0-da77-11e4-872e-1234567db123',
|
46
|
-
'AWS::StackName' => 'stackname'
|
46
|
+
'AWS::StackName' => 'stackname',
|
47
|
+
'AWS::NumberAZs' => 2
|
47
48
|
}
|
48
49
|
pseudo_function_defaults.each do |function_name, default_value|
|
49
50
|
parameter = Parameter.new
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cfn-model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Kascic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-05-
|
11
|
+
date: 2020-05-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop
|