sfn 2.2.0 → 3.0.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/CHANGELOG.md +20 -0
- data/bin/command-config-generator +44 -0
- data/bin/sfn +1 -5
- data/docs/README.md +2 -1
- data/docs/callbacks.md +18 -0
- data/docs/command-config.md +1276 -0
- data/docs/configuration.md +0 -105
- data/docs/overview.md +1 -0
- data/lib/sfn.rb +1 -0
- data/lib/sfn/api_provider.rb +9 -0
- data/lib/sfn/api_provider/google.rb +84 -0
- data/lib/sfn/command.rb +22 -0
- data/lib/sfn/command/create.rb +33 -45
- data/lib/sfn/command/describe.rb +1 -1
- data/lib/sfn/command/destroy.rb +7 -1
- data/lib/sfn/command/diff.rb +4 -5
- data/lib/sfn/command/graph.rb +1 -3
- data/lib/sfn/command/print.rb +3 -4
- data/lib/sfn/command/update.rb +89 -87
- data/lib/sfn/command/validate.rb +24 -11
- data/lib/sfn/command_module/base.rb +1 -12
- data/lib/sfn/command_module/stack.rb +45 -56
- data/lib/sfn/command_module/template.rb +74 -33
- data/lib/sfn/config/print.rb +5 -0
- data/lib/sfn/config/update.rb +4 -0
- data/lib/sfn/config/validate.rb +4 -0
- data/lib/sfn/monkey_patch/stack.rb +153 -83
- data/lib/sfn/monkey_patch/stack/azure.rb +23 -0
- data/lib/sfn/monkey_patch/stack/google.rb +129 -0
- data/lib/sfn/planner/aws.rb +111 -72
- data/lib/sfn/utils/json.rb +3 -0
- data/lib/sfn/utils/stack_parameter_scrubber.rb +20 -23
- data/lib/sfn/utils/stack_parameter_validator.rb +162 -157
- data/lib/sfn/version.rb +1 -1
- data/sfn.gemspec +3 -2
- metadata +34 -8
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'sfn'
|
2
|
+
|
3
|
+
module Sfn
|
4
|
+
module MonkeyPatch
|
5
|
+
module Stack
|
6
|
+
# Azure specific monkey patch implementations
|
7
|
+
module Azure
|
8
|
+
|
9
|
+
# @return [Hash] restructured azure template
|
10
|
+
# @note Will return #template if name collision encountered within resources
|
11
|
+
def sparkleish_template_azure
|
12
|
+
new_template = template.to_smash
|
13
|
+
resources = new_template.delete(:resources)
|
14
|
+
resources.each do |resource|
|
15
|
+
new_template.set(:resources, resource.delete(:name), resource)
|
16
|
+
end
|
17
|
+
resources.size == new_template[:resources].size ? new_template : template
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'sfn'
|
2
|
+
|
3
|
+
module Sfn
|
4
|
+
module MonkeyPatch
|
5
|
+
module Stack
|
6
|
+
# Google specific monkey patch implementations
|
7
|
+
module Google
|
8
|
+
|
9
|
+
# Helper module to allow nested stack behavior to function as expected
|
10
|
+
# internally within sfn
|
11
|
+
module PretendStack
|
12
|
+
|
13
|
+
# disable reload
|
14
|
+
def reload
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
# disable template load
|
19
|
+
def perform_template_load
|
20
|
+
Smash.new
|
21
|
+
end
|
22
|
+
|
23
|
+
# only show resources associated to this stack
|
24
|
+
def resources
|
25
|
+
collection = Miasma::Models::Orchestration::Stack::Resources.new(self)
|
26
|
+
collection.define_singleton_method(:perform_population) do
|
27
|
+
valid = stack.sparkleish_template.fetch(:resources, {}).keys
|
28
|
+
stack.custom[:resources].find_all{|r| valid.include?(r[:name])}.map do |attrs|
|
29
|
+
Miasma::Models::Orchestration::Stack::Resource.new(stack, attrs).valid_state
|
30
|
+
end
|
31
|
+
end
|
32
|
+
collection
|
33
|
+
end
|
34
|
+
|
35
|
+
# Sub-stacks never provide events
|
36
|
+
def events
|
37
|
+
collection = Miasma::Models::Orchestration::Stack::Events.new(self)
|
38
|
+
collection.define_singleton_method(:perform_population){ [] }
|
39
|
+
collection
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Return all stacks contained within this stack
|
44
|
+
#
|
45
|
+
# @param recurse [TrueClass, FalseClass] recurse to fetch _all_ stacks
|
46
|
+
# @return [Array<Miasma::Models::Orchestration::Stack>]
|
47
|
+
def nested_stacks_google(recurse=true)
|
48
|
+
my_template = sparkleish_template
|
49
|
+
if(my_template[:resources][name])
|
50
|
+
my_template = my_template.get(:resources, name, :properties, :stack)
|
51
|
+
end
|
52
|
+
n_stacks = my_template[:resources].map do |s_name, content|
|
53
|
+
if(content[:type] == 'sparkleformation.stack')
|
54
|
+
n_stack = self.class.new(api)
|
55
|
+
n_stack.extend PretendStack
|
56
|
+
n_layout = custom.fetch(:layout, {}).fetch(:resources, []).detect{|r| r[:name] == name}
|
57
|
+
n_layout = (n_layout || custom.fetch(:layout, {})).fetch(:resources, []).detect{|r| r[:name] == s_name} || Smash.new
|
58
|
+
n_stack.load_data(
|
59
|
+
:name => s_name,
|
60
|
+
:id => s_name,
|
61
|
+
:template => content.get(:properties, :stack),
|
62
|
+
:outputs => n_layout.fetch('outputs', []).map{|o_val| Smash.new(:key => o_val[:name], :value => o_val['finalValue'])},
|
63
|
+
:custom => {
|
64
|
+
:resources => resources.all.map(&:attributes),
|
65
|
+
:layout => n_layout
|
66
|
+
}
|
67
|
+
).valid_state
|
68
|
+
n_stack.data[:logical_id] = s_name
|
69
|
+
n_stack.data[:parent_stack] = self
|
70
|
+
n_stack
|
71
|
+
end
|
72
|
+
end.compact
|
73
|
+
if(recurse)
|
74
|
+
(n_stacks + n_stacks.map(&:nested_stacks)).flatten.compact
|
75
|
+
else
|
76
|
+
n_stacks
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# @return [Hash] restructured google template
|
81
|
+
def sparkleish_template_google(*args)
|
82
|
+
copy_template = template.to_smash
|
83
|
+
deref = lambda do |template|
|
84
|
+
result = template.to_smash
|
85
|
+
(result.delete(:resources) || []).each do |t_resource|
|
86
|
+
t_name = t_resource.delete(:name)
|
87
|
+
if(t_resource[:type].to_s.end_with?('.jinja'))
|
88
|
+
schema = copy_template.fetch(:config, :content, :imports, []).delete("#{t_resource[:type]}.schema")
|
89
|
+
schema_content = copy_template.fetch(:imports, []).detect do |s_item|
|
90
|
+
s_item[:name] == schema
|
91
|
+
end
|
92
|
+
if(schema_content)
|
93
|
+
t_resource.set(:parameters, schema_content.get(:content, :properties))
|
94
|
+
end
|
95
|
+
n_template = copy_template.fetch(:imports, []).detect do |s_item|
|
96
|
+
s_item[:name] == t_resource[:type]
|
97
|
+
end
|
98
|
+
if(n_template)
|
99
|
+
t_resource[:type] = 'sparkleformation.stack'
|
100
|
+
current_properties = t_resource.delete(:properties)
|
101
|
+
t_resource.set(:properties, :parameters, current_properties) if current_properties
|
102
|
+
t_resource.set(:properties, :stack, deref.call(n_template[:content]))
|
103
|
+
end
|
104
|
+
end
|
105
|
+
result.set(:resources, t_name, t_resource)
|
106
|
+
end
|
107
|
+
result
|
108
|
+
end
|
109
|
+
s_template = deref.call(Smash.new(:resources => copy_template.get(:config, :content, :resources)))
|
110
|
+
if(s_template.empty?)
|
111
|
+
template.to_smash
|
112
|
+
else
|
113
|
+
layout = custom.fetch(:layout, {}).to_smash
|
114
|
+
(layout.delete(:resources) || []).each do |l_resource|
|
115
|
+
layout.set(:resources, l_resource.delete(:name), l_resource)
|
116
|
+
end
|
117
|
+
args.include?(:remove_wrapper) ? s_template.get(:resources, name, :properties, :stack) : s_template
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# @return [Hash]
|
122
|
+
def root_parameters_google
|
123
|
+
sparkleish_template.fetch(:resources, name, :properties, :parameters, Smash.new)
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
data/lib/sfn/planner/aws.rb
CHANGED
@@ -108,7 +108,8 @@ module Sfn
|
|
108
108
|
|
109
109
|
# Resources that will be replaced on metadata init updates
|
110
110
|
REPLACE_ON_CFN_INIT_UPDATE = [
|
111
|
-
'AWS::AutoScaling::LaunchConfiguration'
|
111
|
+
'AWS::AutoScaling::LaunchConfiguration',
|
112
|
+
'AWS::EC2::Instance'
|
112
113
|
]
|
113
114
|
|
114
115
|
# @return [Smash] initialized translators
|
@@ -145,7 +146,6 @@ module Sfn
|
|
145
146
|
:unavailable => Smash.new,
|
146
147
|
:unknown => Smash.new
|
147
148
|
)
|
148
|
-
# scrub_stack_properties(template)
|
149
149
|
result
|
150
150
|
end
|
151
151
|
|
@@ -203,17 +203,21 @@ module Sfn
|
|
203
203
|
origin_template = dereference_template(
|
204
204
|
"#{stack.data.checksum}_origin",
|
205
205
|
stack.template,
|
206
|
-
Smash[
|
206
|
+
Smash[
|
207
|
+
stack.parameters.map do |k,v|
|
208
|
+
[k, v.to_s]
|
209
|
+
end
|
210
|
+
].merge(get_global_parameters(stack))
|
207
211
|
)
|
208
212
|
|
209
|
-
|
210
|
-
run_stack_diff(stack,
|
213
|
+
translator_key = "#{stack.data.checksum}_#{stack.data.fetch(:logical_id, stack.name)}"
|
214
|
+
run_stack_diff(stack, translator_key, plan_results, origin_template, new_template, new_parameters)
|
211
215
|
|
212
216
|
new_checksum = nil
|
213
217
|
current_checksum = false
|
214
218
|
until(new_checksum == current_checksum)
|
215
219
|
current_checksum = plan_results.checksum
|
216
|
-
run_stack_diff(stack,
|
220
|
+
run_stack_diff(stack, translator_key, plan_results, origin_template, new_template, new_parameters)
|
217
221
|
new_checksum = plan_results.checksum
|
218
222
|
end
|
219
223
|
scrub_plan(plan_results)
|
@@ -249,6 +253,7 @@ module Sfn
|
|
249
253
|
# Run the stack diff and populate the result set
|
250
254
|
#
|
251
255
|
# @param stack [Miasma::Models::Orchestration::Stack] existing stack
|
256
|
+
# @param t_key [String] translator key
|
252
257
|
# @param plan_result [Smash] plan data to populate
|
253
258
|
# @param origin_template [Smash] template of existing stack
|
254
259
|
# @param new_template [Smash] template to replace existing
|
@@ -256,7 +261,6 @@ module Sfn
|
|
256
261
|
# @return [NilClass]
|
257
262
|
def run_stack_diff(stack, t_key, plan_results, origin_template, new_template, new_parameters)
|
258
263
|
translator = translator_for(t_key)
|
259
|
-
|
260
264
|
new_parameters = new_parameters.dup
|
261
265
|
if(stack.parameters)
|
262
266
|
stack.parameters.each do |k,v|
|
@@ -266,50 +270,12 @@ module Sfn
|
|
266
270
|
end
|
267
271
|
end
|
268
272
|
end
|
269
|
-
|
270
273
|
new_parameters.merge!(get_global_parameters(stack))
|
271
|
-
|
272
274
|
new_template_hash = new_template.to_smash
|
273
|
-
|
274
|
-
o_nested_stacks = origin_template.fetch('Resources', {}).find_all do |s_name, s_val|
|
275
|
-
is_stack?(s_val['Type'])
|
276
|
-
end.map(&:first)
|
277
|
-
n_nested_stacks = (new_template_hash['Resources'] || {}).find_all do |s_name, s_val|
|
278
|
-
is_stack?(s_val['Type'])
|
279
|
-
end.map(&:first)
|
280
|
-
[o_nested_stacks + n_nested_stacks].flatten.compact.uniq.each do |n_name|
|
281
|
-
o_stack = stack.nested_stacks(false).detect{|s| s.data[:logical_id] == n_name}
|
282
|
-
n_exists = is_stack?(new_template_hash.get('Resources', n_name, 'Type'))
|
283
|
-
n_template = new_template_hash.get('Resources', n_name, 'Properties', 'Stack')
|
284
|
-
n_parameters = new_template_hash.fetch('Resources', n_name, 'Properties', 'Parameters', Smash.new)
|
285
|
-
n_type = new_template_hash.fetch('Resources', n_name, 'Type',
|
286
|
-
origin_template.get('Resources', n_name, 'Type')
|
287
|
-
)
|
288
|
-
resource = Smash.new(
|
289
|
-
:name => n_name,
|
290
|
-
:type => n_type,
|
291
|
-
:properties => []
|
292
|
-
)
|
293
|
-
if(o_stack && n_template)
|
294
|
-
n_parameters.keys.each do |n_key|
|
295
|
-
n_parameters[n_key] = translator.dereference(n_parameters[n_key])
|
296
|
-
end
|
297
|
-
n_results = plan_stack(o_stack, n_template, n_parameters)
|
298
|
-
unless(n_results[:outputs].empty?)
|
299
|
-
n_results[:outputs].keys.each do |n_output|
|
300
|
-
translator.flag_ref("#{n_name}_Outputs.#{n_output}")
|
301
|
-
end
|
302
|
-
end
|
303
|
-
plan_results[:stacks][n_name] = n_results
|
304
|
-
elsif(o_stack && (!n_template && !n_exists))
|
305
|
-
plan_results[:removed][n_name] = resource
|
306
|
-
elsif(n_template && !o_stack)
|
307
|
-
plan_results[:added][n_name] = resource
|
308
|
-
end
|
309
|
-
end
|
310
|
-
|
311
275
|
scrub_stack_properties(new_template_hash)
|
312
276
|
|
277
|
+
plan_nested_stacks(stack, translator, origin_template, new_template_hash, plan_results)
|
278
|
+
|
313
279
|
update_template = dereference_template(
|
314
280
|
t_key, new_template_hash, new_parameters,
|
315
281
|
plan_results[:replace].keys + plan_results[:unavailable].keys
|
@@ -320,23 +286,72 @@ module Sfn
|
|
320
286
|
end.each do |a_path, diff_items|
|
321
287
|
register_diff(
|
322
288
|
plan_results, a_path, diff_items, translator_for(t_key),
|
323
|
-
|
324
|
-
|
289
|
+
Smash.new(
|
290
|
+
:origin => origin_template,
|
291
|
+
:update => update_template
|
292
|
+
)
|
325
293
|
)
|
326
294
|
end
|
327
295
|
nil
|
328
296
|
end
|
329
297
|
|
330
|
-
#
|
298
|
+
# Extract nested stacks and generate plans
|
331
299
|
#
|
332
|
-
# @param
|
333
|
-
# @param
|
334
|
-
# @param
|
335
|
-
# @param
|
336
|
-
# @
|
337
|
-
# @
|
338
|
-
def
|
339
|
-
|
300
|
+
# @param stack [Miasma::Orchestration::Models::Stack]
|
301
|
+
# @param translator [Translator]
|
302
|
+
# @param origin_template [Smash]
|
303
|
+
# @param new_template_hash [Smash]
|
304
|
+
# @param plan_results [Smash]
|
305
|
+
# @return [NilClass]
|
306
|
+
def plan_nested_stacks(stack, translator, origin_template, new_template_hash, plan_results)
|
307
|
+
origin_stacks = origin_template.fetch('Resources', {}).find_all do |s_name, s_val|
|
308
|
+
is_stack?(s_val['Type'])
|
309
|
+
end.map(&:first)
|
310
|
+
new_stacks = (new_template_hash['Resources'] || {}).find_all do |s_name, s_val|
|
311
|
+
is_stack?(s_val['Type'])
|
312
|
+
end.map(&:first)
|
313
|
+
[origin_stacks + new_stacks].flatten.compact.uniq.each do |stack_name|
|
314
|
+
original_stack = stack.nested_stacks(false).detect do |stk|
|
315
|
+
stk.data[:logical_id] == stack_name
|
316
|
+
end
|
317
|
+
new_stack_exists = is_stack?(new_template_hash.get('Resources', stack_name, 'Type'))
|
318
|
+
new_stack_template = new_template_hash.get('Resources', stack_name, 'Properties', 'Stack')
|
319
|
+
new_stack_parameters = new_stack_template.fetch('Parameters', Smash.new)
|
320
|
+
new_stack_type = new_template_hash.fetch('Resources', stack_name, 'Type',
|
321
|
+
origin_template.get('Resources', stack_name, 'Type')
|
322
|
+
)
|
323
|
+
resource = Smash.new(
|
324
|
+
:name => stack_name,
|
325
|
+
:type => new_stack_type,
|
326
|
+
:properties => []
|
327
|
+
)
|
328
|
+
if(original_stack && new_stack_template)
|
329
|
+
new_stack_parameters = Smash[
|
330
|
+
new_stack_parameters.map do |new_param_key, new_param_value|
|
331
|
+
[new_param_key, translator.dereference(new_param_value)]
|
332
|
+
end
|
333
|
+
]
|
334
|
+
result = plan_stack(original_stack, new_stack_template, new_stack_parameters)
|
335
|
+
result[:outputs].keys.each do |modified_output|
|
336
|
+
translator.flag_ref("#{stack_name}_Outputs.#{modified_output}")
|
337
|
+
end
|
338
|
+
plan_results[:stacks][stack_name] = result
|
339
|
+
elsif(original_stack && (!new_stack_template && !new_stack_exists))
|
340
|
+
plan_results[:removed][stack_name] = resource
|
341
|
+
elsif(new_stack_template && !original_stack)
|
342
|
+
plan_results[:added][stack_name] = resource
|
343
|
+
end
|
344
|
+
end
|
345
|
+
nil
|
346
|
+
end
|
347
|
+
|
348
|
+
# Initialize the diff result hash
|
349
|
+
#
|
350
|
+
# @param diff [Array] Hashdiff result entry
|
351
|
+
# @param path [String] modification path within structure
|
352
|
+
# @return [Smash]
|
353
|
+
def diff_init(diff, path)
|
354
|
+
Smash.new.tap do |di|
|
340
355
|
if(diff.size > 1)
|
341
356
|
updated = diff.detect{|x| x.first == '+'}
|
342
357
|
original = diff.detect{|x| x.first == '-'}
|
@@ -353,12 +368,24 @@ module Sfn
|
|
353
368
|
end
|
354
369
|
end
|
355
370
|
end
|
371
|
+
end
|
372
|
+
|
373
|
+
# Register a diff item into the results set
|
374
|
+
#
|
375
|
+
# @param results [Hash]
|
376
|
+
# @param path [String]
|
377
|
+
# @param diff [Array]
|
378
|
+
# @param templates [Smash]
|
379
|
+
# @option :templates [Smash] :origin
|
380
|
+
# @option :templates [Smash] :update
|
381
|
+
def register_diff(results, path, diff, translator, templates)
|
382
|
+
diff_info = diff_init(diff, path)
|
356
383
|
if(path.start_with?('Resources'))
|
357
384
|
p_path = path.split('.')
|
358
385
|
if(p_path.size == 2)
|
359
386
|
diff = diff.first
|
360
387
|
key = diff.first == '+' ? :added : :removed
|
361
|
-
type = (key == :added ? templates[:update] : templates[:origin])
|
388
|
+
type = (key == :added ? templates[:update] : templates[:origin]).get('Resources', p_path.last, 'Type')
|
362
389
|
results[key][p_path.last] = Smash.new(
|
363
390
|
:name => p_path.last,
|
364
391
|
:type => type,
|
@@ -375,9 +402,7 @@ module Sfn
|
|
375
402
|
else
|
376
403
|
property_name = p_path[3].to_s.sub(/\[\d+\]$/, '')
|
377
404
|
end
|
378
|
-
type = templates
|
379
|
-
info = SfnAws.registry.fetch(type, {}).to_smash
|
380
|
-
effect = info.fetch(:full_properties, property_name, :update_causes, :unknown).to_sym
|
405
|
+
type = templates.get(:origin, 'Resources', resource_name, 'Type')
|
381
406
|
resource = Smash.new(
|
382
407
|
:name => resource_name,
|
383
408
|
:type => type,
|
@@ -386,16 +411,30 @@ module Sfn
|
|
386
411
|
diff_info.merge(:property_name => property_name)
|
387
412
|
]
|
388
413
|
)
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
414
|
+
begin
|
415
|
+
r_info = SparkleFormation::Resources::Aws.resource_lookup(type)
|
416
|
+
r_property = r_info.property(property_name)
|
417
|
+
if(r_property)
|
418
|
+
effect = r_property.update_causes(
|
419
|
+
templates.get(:update, 'Resources', resource_name),
|
420
|
+
templates.get(:origin, 'Resources', resource_name)
|
421
|
+
)
|
422
|
+
else
|
423
|
+
raise KeyError.new 'Unknown property'
|
424
|
+
end
|
425
|
+
case effect.to_sym
|
426
|
+
when :replacement
|
427
|
+
set_resource(:replace, results, resource_name, resource)
|
428
|
+
when :interrupt
|
429
|
+
set_resource(:interrupt, results, resource_name, resource)
|
430
|
+
when :unavailable
|
431
|
+
set_resource(:unavailable, results, resource_name, resource)
|
432
|
+
when :none
|
433
|
+
# \o/
|
434
|
+
else
|
435
|
+
set_resource(:unknown, results, resource_name, resource)
|
436
|
+
end
|
437
|
+
rescue KeyError
|
399
438
|
set_resource(:unknown, results, resource_name, resource)
|
400
439
|
end
|
401
440
|
elsif(p_path.include?('AWS::CloudFormation::Init'))
|
data/lib/sfn/utils/json.rb
CHANGED
@@ -13,6 +13,7 @@ module Sfn
|
|
13
13
|
def _to_json(thing)
|
14
14
|
MultiJson.dump(thing)
|
15
15
|
end
|
16
|
+
alias_method :dump_json, :_to_json
|
16
17
|
|
17
18
|
# Load JSON data
|
18
19
|
#
|
@@ -21,6 +22,7 @@ module Sfn
|
|
21
22
|
def _from_json(thing)
|
22
23
|
MultiJson.load(thing)
|
23
24
|
end
|
25
|
+
alias_method :load_json, :_from_json
|
24
26
|
|
25
27
|
# Format object into pretty JSON
|
26
28
|
#
|
@@ -30,6 +32,7 @@ module Sfn
|
|
30
32
|
thing = _from_json(thing) if thing.is_a?(String)
|
31
33
|
MultiJson.dump(thing, :pretty => true)
|
32
34
|
end
|
35
|
+
alias_method :format_json, :_format_json
|
33
36
|
|
34
37
|
end
|
35
38
|
|
@@ -3,35 +3,32 @@ require 'sfn'
|
|
3
3
|
module Sfn
|
4
4
|
module Utils
|
5
5
|
# Helper for scrubbing stack parameters
|
6
|
-
|
6
|
+
module StackParameterScrubber
|
7
7
|
|
8
|
-
|
8
|
+
# Validate attributes within Parameter blocks
|
9
|
+
ALLOWED_PARAMETER_ATTRIBUTES = %w(
|
10
|
+
Type Default NoEcho AllowedValues AllowedPattern
|
11
|
+
MaxLength MinLength MaxValue MinValue Description
|
12
|
+
ConstraintDescription
|
13
|
+
)
|
9
14
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
# @return [Hash] template
|
21
|
-
def scrub!(template)
|
22
|
-
parameters = template['Parameters']
|
23
|
-
if(parameters)
|
24
|
-
parameters.each do |name, options|
|
25
|
-
options.delete_if do |attribute, value|
|
26
|
-
!ALLOWED_PARAMETER_ATTRIBUTES.include?(attribute)
|
27
|
-
end
|
15
|
+
# Clean the parameters of the template
|
16
|
+
#
|
17
|
+
# @param template [Hash]
|
18
|
+
# @return [Hash] template
|
19
|
+
def parameter_scrub!(template)
|
20
|
+
parameters = template['Parameters']
|
21
|
+
if(parameters)
|
22
|
+
parameters.each do |name, options|
|
23
|
+
options.delete_if do |attribute, value|
|
24
|
+
!ALLOWED_PARAMETER_ATTRIBUTES.include?(attribute)
|
28
25
|
end
|
29
|
-
template['Parameters'] = parameters
|
30
26
|
end
|
31
|
-
template
|
27
|
+
template['Parameters'] = parameters
|
32
28
|
end
|
33
|
-
|
29
|
+
template
|
34
30
|
end
|
31
|
+
|
35
32
|
end
|
36
33
|
end
|
37
34
|
end
|