cfhighlander 0.2.1.alpha.34 → 0.2.1.alpha.43
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/README.md +134 -60
- data/lib/cfhighlander.compiler.rb +22 -14
- data/lib/cfhighlander.dsl.params.rb +31 -36
- data/lib/{cfhighlander.dsl.component.rb → cfhighlander.dsl.subcomponent.rb} +71 -60
- data/lib/{cfhighlander.dsl.rb → cfhighlander.dsl.template.rb} +60 -42
- data/lib/cfhighlander.factory.rb +1 -1
- data/lib/cfhighlander.helper.rb +1 -1
- data/lib/cfhighlander.model.component.rb +29 -5
- data/templates/cfndsl.component.template.erb +4 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b0076c7a6d8d8d5dcfe21a9c57601f659014cc64dadfc78c890b78ac98aaee7e
|
4
|
+
data.tar.gz: d9688f728ef4edd875f8603b8733c153a95270a1650b0555a706cf9d0f7f5a6b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 928880bc75f3bc9665ab84c7bbd8d50fe8e310d520365e065c1c036cbdc8c67195e37059e608e4340dd018943965f322361287a057a3450771905997648960ad
|
7
|
+
data.tar.gz: 7ba9c66b2e655044c62c7b6db12d42451e46e5c5239206b879b1951a69472c1fe883b491efbfdcd26fb38a850663abcf7e673150bdf61ec5e5ed85d383c3c490
|
data/README.md
CHANGED
@@ -5,20 +5,23 @@
|
|
5
5
|
Cfhighlander is DSL processor that enables composition and orchestration of Amazon CloudFormation templates
|
6
6
|
written using [CfnDsl](https://github.com/cfndsl/cfndsl) in an abstract way. It tries to tackle problem of merging multiple templates into master
|
7
7
|
template in an elegant way, so higher degree of template reuse can be achieved. It does so by formalising commonly
|
8
|
-
used patterns via DSL statements. For an example, passing output of one stack into other stack is
|
9
|
-
|
8
|
+
used cfndsl template composition patterns via DSL statements. For an example, passing output of one stack into other stack is done
|
9
|
+
automatically if parameter and output names are the same,
|
10
|
+
rather than wiring them manually in 'master' cfndsl template. For this example to
|
10
11
|
work, parent component will have to pull in both component rendering output values, and component pulling them in
|
11
|
-
as parameters.
|
12
|
-
|
12
|
+
as parameters. Cfhighlander allows for greater reuse of component templates by allowing references to templates
|
13
|
+
via git urls, and s3 urls. [Theonestack](https://github.com/theonestack) has several prebuilt component templates to use,
|
14
|
+
with repositories from this org being one of the default sources for searching component templates.
|
13
15
|
|
14
|
-
Highlander DSL produces CloudFormation templates in
|
16
|
+
Highlander DSL produces CloudFormation templates in 4 phases
|
15
17
|
|
16
18
|
- Processing referenced component's configuration and resolving configuration exports
|
19
|
+
- Wiring parameters from components to their inner components
|
17
20
|
- Producing [CfnDsl](https://github.com/cfndsl/cfndsl) templates for all components and subcomponents as intermediary
|
18
21
|
step
|
19
22
|
- Producing resulting CloudFormation templates using configuration and templates generated in two previous phases.
|
20
23
|
|
21
|
-
Each phase above is executable as stand-alone through CLI, making development of Highlander templates easier by enabling
|
24
|
+
Each phase (aside from parameter wiring) above is executable as stand-alone through CLI, making development of Highlander templates easier by enabling
|
22
25
|
debugging of produced configuration and cfndsl templates.
|
23
26
|
|
24
27
|
|
@@ -169,7 +172,7 @@ This configuration level overrides component's own config file.
|
|
169
172
|
- Outer component explicit configuration. You can pass `config` named parameter to `Component` statement, such as
|
170
173
|
|
171
174
|
```ruby
|
172
|
-
|
175
|
+
CfhighlanderTemplate do
|
173
176
|
|
174
177
|
# ...
|
175
178
|
# some dsl code
|
@@ -257,7 +260,7 @@ Parameters block is used to define CloudFormation template parameters, and metad
|
|
257
260
|
are wired with outer or sibling components.
|
258
261
|
|
259
262
|
```ruby
|
260
|
-
|
263
|
+
CfhighlanderTemplate do
|
261
264
|
Parameters do
|
262
265
|
##
|
263
266
|
## parameter definitions here
|
@@ -270,81 +273,117 @@ Parameter block supports following parameters
|
|
270
273
|
|
271
274
|
#### ComponentParam
|
272
275
|
|
273
|
-
`ComponentParam` - Component parameter
|
274
|
-
|
275
|
-
|
276
|
+
`ComponentParam` - Component parameter exposes parameter to be wired from outer component. Cfhighlander's
|
277
|
+
autowiring mechanism will try and find any stack outputs from other components defined by outer components with name
|
278
|
+
matching. If there is no explicit value provided, or autowired from outputs, parameter will be propagated to outer component.
|
279
|
+
|
280
|
+
Propagated parameter will be prefixed with component name **if it is not defined as global parameter**. Otherwise,
|
281
|
+
parameter name is kept in full.
|
282
|
+
|
283
|
+
Example below demonstrates 3 different ways of providing parameter values from outer to inner component.
|
284
|
+
|
285
|
+
- Provide value explicitly
|
286
|
+
- Provide value explicitly as output of another component
|
287
|
+
- Autowire value from output of another component with the same name
|
288
|
+
- Propagate parameter to outer component
|
276
289
|
|
277
290
|
```ruby
|
278
291
|
|
279
|
-
# Inner Component
|
280
|
-
|
292
|
+
# Inner Component 1
|
293
|
+
CfhighlanderTemplate do
|
281
294
|
Name 's3'
|
282
295
|
Parameters do
|
283
296
|
ComponentParam 'BucketName','highlander.example.com.au'
|
297
|
+
ComponentParam 'BucketName2',''
|
298
|
+
ComponentParam 'BucketName3',''
|
299
|
+
ComponentParam 'BucketName4','', isGlobal: false # default value is false
|
300
|
+
ComponentParam 'BucketName5','', isGlobal: true
|
284
301
|
end
|
302
|
+
|
285
303
|
end
|
304
|
+
|
286
305
|
```
|
287
306
|
|
288
307
|
```ruby
|
289
|
-
#
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
parameters:{'BucketName' => 'outer.example.com.au'}
|
308
|
+
# Inner Component 2
|
309
|
+
CfhighlanderTemplate do
|
310
|
+
Name 'nameproducer'
|
311
|
+
|
312
|
+
# has output 'bucket name defined in cfdnsl
|
295
313
|
end
|
296
|
-
```
|
297
314
|
|
298
|
-
#### StackParam
|
299
315
|
|
300
|
-
|
301
|
-
|
316
|
+
# -- contents of cfndsl
|
317
|
+
CloudFormation do
|
302
318
|
|
319
|
+
Condition 'AlwaysFalse', FnEquals('true','false')
|
320
|
+
S3_Bucket :resourcetovalidateproperly do
|
321
|
+
Condition 'AlwaysFalse'
|
322
|
+
end
|
303
323
|
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
Component template:'s3',name:'s3'
|
324
|
+
Output('BucketName') do
|
325
|
+
Value('highlanderbucketautowired.example.com.au')
|
326
|
+
end
|
308
327
|
end
|
328
|
+
|
329
|
+
|
309
330
|
```
|
310
331
|
|
311
332
|
```ruby
|
312
|
-
#
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
333
|
+
# Outer component
|
334
|
+
CfhighlanderTemplate do
|
335
|
+
Component 'nameproducer'
|
336
|
+
Component 's3' do
|
337
|
+
parameter name: 'BucketName2', value: 'nameproducer.BucketName'
|
338
|
+
parameter name: 'BucketName3', value: 'mybucket.example.cfhighlander.org'
|
339
|
+
end
|
319
340
|
end
|
341
|
+
|
320
342
|
```
|
321
343
|
|
322
344
|
|
323
|
-
Example above translates to following
|
345
|
+
Example above translates to following wiring of parameters in cfndsl template
|
324
346
|
```ruby
|
325
347
|
CloudFormation do
|
326
348
|
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
Parameter('s3BucketName') do
|
333
|
-
Type 'String'
|
334
|
-
Default 'highlander.example.com.au'
|
349
|
+
# Parameter that was propagated
|
350
|
+
Parameter('s3BucketName4') do
|
351
|
+
Type 'String'
|
352
|
+
Default ''
|
353
|
+
NoEcho false
|
335
354
|
end
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
'EnvironmentName' => Ref('EnvironmentName'),
|
342
|
-
|
343
|
-
'BucketName' => Ref('s3BucketName'),
|
344
|
-
|
345
|
-
})
|
355
|
+
|
356
|
+
Parameter('BucketName5') do
|
357
|
+
Type 'String'
|
358
|
+
Default ''
|
359
|
+
NoEcho false
|
346
360
|
end
|
361
|
+
|
362
|
+
CloudFormation_Stack('s3') do
|
363
|
+
TemplateURL './s3.compiled.yaml'
|
364
|
+
Parameters ({
|
365
|
+
|
366
|
+
# Paramater that was auto-wired
|
367
|
+
'BucketName' => {"Fn::GetAtt":["nameproducer","Outputs.BucketName"]},
|
368
|
+
|
369
|
+
# Parameter that was explicitly wired as output param from another component
|
370
|
+
'BucketName2' => {"Fn::GetAtt":["nameproducer","Outputs.BucketName"]},
|
371
|
+
|
372
|
+
# Paramater that was explicitly provided
|
373
|
+
'BucketName3' => 'mybucket.example.cfhighlander.org',
|
374
|
+
|
375
|
+
# Reference to parameter that was propagated. isGlobal: false when defining
|
376
|
+
# parameter, so parameter name is prefixed with component name
|
377
|
+
'BucketName4' => {"Ref":"s3BucketName4"},
|
378
|
+
|
379
|
+
# Reference to parameter that was propagated. isGlobal: true when defining
|
380
|
+
# parameter, so parameter name is not prefixed, but rather propagated as-is
|
381
|
+
'BucketName5' => {"Ref":"BucketName5"},
|
382
|
+
|
383
|
+
})
|
384
|
+
end
|
347
385
|
end
|
386
|
+
|
348
387
|
```
|
349
388
|
|
350
389
|
|
@@ -358,7 +397,7 @@ This DSL statements takes a full body, as Mapping name, Map key, and value key n
|
|
358
397
|
|
359
398
|
```ruby
|
360
399
|
# Inner component
|
361
|
-
|
400
|
+
CfhighlanderTemplate do
|
362
401
|
Name 's3'
|
363
402
|
Parameters do
|
364
403
|
MappingParam 'BucketName' do
|
@@ -370,17 +409,13 @@ end
|
|
370
409
|
```
|
371
410
|
|
372
411
|
|
373
|
-
#### OutputParam
|
374
|
-
|
375
|
-
TBD
|
376
|
-
|
377
412
|
### DependsOn
|
378
413
|
|
379
414
|
`DependsOn` - this will include any globally exported libraries from given
|
380
415
|
template. E.g.
|
381
416
|
|
382
417
|
```ruby
|
383
|
-
|
418
|
+
CfhighlanderTemplate do
|
384
419
|
Name 's3'
|
385
420
|
DependsOn 'vpc@1.0.3'
|
386
421
|
end
|
@@ -398,7 +433,46 @@ so extension methods can be consumed within cfndsl template.
|
|
398
433
|
#### Referencing
|
399
434
|
|
400
435
|
|
401
|
-
## Finding and
|
436
|
+
## Finding templates and creating components
|
437
|
+
|
438
|
+
|
439
|
+
Templates are located by default in following locations
|
440
|
+
|
441
|
+
- `$WD`
|
442
|
+
- `$WD/$componentname`
|
443
|
+
- `$WD/components/$componentname`
|
444
|
+
- `~/.cfhighlander/components/componentname/componentversion`
|
445
|
+
- `https://github.com/cfhighlander/theonestack/hl-component-$componentname` on `master` branch
|
446
|
+
|
447
|
+
Location of component templates can be given as git/github repo:
|
448
|
+
|
449
|
+
```ruby
|
450
|
+
|
451
|
+
CfhighlanderTemplate do
|
452
|
+
|
453
|
+
# pulls directly from master branch of https://github.com/theonestack/hl-component-vpc
|
454
|
+
Component name: 'vpc0', template: 'vpc'
|
455
|
+
|
456
|
+
# specify branch github.com: or github: work. You specify branch with hash
|
457
|
+
Component name: 'vpc1', template: 'github:theonestack/hl-component-vpc#master'
|
458
|
+
|
459
|
+
# you can use git over ssh
|
460
|
+
# Component name: 'vpc2', template: 'git:git@github.com:theonestack/hl-component-vpc.git'
|
461
|
+
|
462
|
+
# use git over https
|
463
|
+
Component name: 'vpc3', template: 'git:https://github.com/theonestack/hl-component-sns.git'
|
464
|
+
|
465
|
+
# specify .snapshot to always clone fresh copy
|
466
|
+
Component name: 'vpc4', template: 'git:https://github.com/theonestack/hl-component-sns.git#master.snapshot'
|
467
|
+
|
468
|
+
# by default, if not found locally, highlander will search for https://github.com/theonestack/component-$componentname
|
469
|
+
# in v${version} branch (or tag for that matter)
|
470
|
+
Component name: 'vpc5', template: 'vpc@1.0.4'
|
471
|
+
|
472
|
+
end
|
473
|
+
|
474
|
+
```
|
475
|
+
|
402
476
|
|
403
477
|
## Rendering CloudFormation templates
|
404
478
|
|
@@ -43,13 +43,15 @@ module Cfhighlander
|
|
43
43
|
@lambdas_processed = false
|
44
44
|
@silent_mode = false
|
45
45
|
@lambda_src_paths = []
|
46
|
+
@config_yaml_path = nil
|
47
|
+
@cfn_model = nil
|
46
48
|
|
47
49
|
if @@global_extensions_paths.empty?
|
48
50
|
global_extensions_folder = "#{File.dirname(__FILE__)}/../cfndsl_ext"
|
49
51
|
Dir["#{global_extensions_folder}/*.rb"].each { |f| @@global_extensions_paths << f }
|
50
52
|
end
|
51
53
|
|
52
|
-
@component.highlander_dsl.
|
54
|
+
@component.highlander_dsl.subcomponents.each do |sub_component|
|
53
55
|
sub_component_compiler = Cfhighlander::Compiler::ComponentCompiler.new(sub_component.component_loaded)
|
54
56
|
sub_component_compiler.component_name = sub_component.name
|
55
57
|
@sub_components << sub_component_compiler
|
@@ -67,7 +69,7 @@ module Cfhighlander
|
|
67
69
|
dsl = @component.highlander_dsl
|
68
70
|
component_cfndsl = @component.cfndsl_content
|
69
71
|
|
70
|
-
@component.highlander_dsl.
|
72
|
+
@component.highlander_dsl.subcomponents.each { |sc|
|
71
73
|
sc.distribution_format = out_format
|
72
74
|
}
|
73
75
|
|
@@ -100,33 +102,38 @@ module Cfhighlander
|
|
100
102
|
|
101
103
|
end
|
102
104
|
|
103
|
-
def
|
104
|
-
|
105
|
-
|
105
|
+
def evaluateCloudFormation(format = 'yaml')
|
106
106
|
#compile cfndsl templates first
|
107
107
|
compileCfnDsl format unless @cfndsl_compiled
|
108
108
|
|
109
|
+
# write config
|
110
|
+
cfndsl_opts = []
|
111
|
+
cfndsl_opts.push([:yaml, @config_yaml_path])
|
112
|
+
|
113
|
+
# grab cfndsl model
|
114
|
+
model = CfnDsl.eval_file_with_extras(@cfndsl_compiled_path, cfndsl_opts, false)
|
115
|
+
@cfn_model = model
|
116
|
+
return model
|
117
|
+
end
|
118
|
+
|
119
|
+
def compileCloudFormation(format = 'yaml')
|
120
|
+
|
109
121
|
dsl = @component.highlander_dsl
|
110
|
-
component_cfndsl = @component.cfndsl_content
|
111
122
|
|
112
123
|
# create out dir if not there
|
113
124
|
@cfn_output_location = "#{@workdir}/out/#{format}"
|
114
125
|
output_dir = @cfn_output_location
|
115
126
|
FileUtils.mkdir_p(output_dir) unless Dir.exist?(output_dir)
|
116
127
|
|
117
|
-
# write config
|
118
|
-
config_yaml_path = writeConfig
|
119
|
-
|
120
128
|
|
121
129
|
# compile templates
|
122
|
-
output_path = "#{output_dir}/#{component_name}.compiled.#{format}"
|
130
|
+
output_path = "#{output_dir}/#{@component_name}.compiled.#{format}"
|
123
131
|
@cfn_template_paths << output_path
|
124
132
|
# configure cfndsl
|
125
|
-
|
126
|
-
cfndsl_opts.push([:yaml, config_yaml_path])
|
133
|
+
|
127
134
|
|
128
135
|
# grab cfndsl model
|
129
|
-
model =
|
136
|
+
model = evaluateCloudFormation
|
130
137
|
|
131
138
|
# write resulting cloud formation template
|
132
139
|
if format == 'json'
|
@@ -165,7 +172,8 @@ module Cfhighlander
|
|
165
172
|
end
|
166
173
|
end
|
167
174
|
@config_written = true
|
168
|
-
config_yaml_path
|
175
|
+
@config_yaml_path = config_yaml_path
|
176
|
+
return @config_yaml_path
|
169
177
|
end
|
170
178
|
|
171
179
|
def processLambdas()
|
@@ -3,6 +3,8 @@ require_relative './cfhighlander.dsl.base'
|
|
3
3
|
module Cfhighlander
|
4
4
|
|
5
5
|
module Dsl
|
6
|
+
|
7
|
+
# dsl statements
|
6
8
|
class Parameters < DslBase
|
7
9
|
|
8
10
|
attr_accessor :param_list
|
@@ -12,7 +14,7 @@ module Cfhighlander
|
|
12
14
|
end
|
13
15
|
|
14
16
|
def addParam(param)
|
15
|
-
existing_param = @param_list.find {
|
17
|
+
existing_param = @param_list.find {|p| p.name == param.name}
|
16
18
|
if not existing_param.nil?
|
17
19
|
puts "Parameter being overwritten. Updating parameter #{param.name} with new definition..."
|
18
20
|
@param_list[@param_list.index(existing_param)] = param
|
@@ -21,62 +23,55 @@ module Cfhighlander
|
|
21
23
|
end
|
22
24
|
end
|
23
25
|
|
24
|
-
def StackParam(name, defaultValue='', isGlobal: false, noEcho: false)
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
def StackParam(name, defaultValue = '', isGlobal: false, noEcho: false, type: 'String')
|
27
|
+
STDERR.puts "DEPRECATED: StackParam #{name} - Use ComponentParam instead"
|
28
|
+
ComponentParam(name, defaultValue, isGlobal: isGlobal, noEcho: noEcho, type: type)
|
29
|
+
end
|
30
|
+
|
31
|
+
def OutputParam(component:, name:, isGlobal: false, noEcho: false, type: 'String')
|
32
|
+
STDERR.puts ("DEPRECATED: OutputParam #{name} - Use ComponentParam instead. Outputut params are " +
|
33
|
+
"autorwired by name only, with component disregarded")
|
34
|
+
param = ComponentParam(name, '', isGlobal: isGlobal, noEcho: noEcho, type: type)
|
35
|
+
param.provided_value = "#{component}.#{name}"
|
30
36
|
end
|
31
37
|
|
32
|
-
def ComponentParam(name, defaultValue='')
|
33
|
-
param =
|
38
|
+
def ComponentParam(name, defaultValue = '', isGlobal: false, noEcho: false, type: 'String', allowedValues: nil)
|
39
|
+
param = Parameter.new(name, type, defaultValue, noEcho, isGlobal, allowedValues)
|
34
40
|
param.config = @config
|
35
41
|
addParam param
|
42
|
+
return param
|
36
43
|
end
|
37
44
|
|
38
|
-
def MappingParam(name, defaultValue='', &block)
|
45
|
+
def MappingParam(name, defaultValue = '', &block)
|
39
46
|
param = MappingParam.new(name, 'String', defaultValue)
|
40
47
|
param.config = @config
|
41
48
|
param.instance_eval(&block)
|
42
49
|
addParam param
|
43
50
|
end
|
44
51
|
|
45
|
-
|
46
|
-
param = OutputParam.new(component, name, default)
|
47
|
-
param.config = @config
|
48
|
-
addParam param
|
49
|
-
end
|
52
|
+
|
50
53
|
end
|
51
54
|
|
55
|
+
# model classes
|
52
56
|
class Parameter < DslBase
|
53
|
-
attr_accessor :name,
|
54
|
-
|
55
|
-
|
57
|
+
attr_accessor :name,
|
58
|
+
:type,
|
59
|
+
:default_value,
|
60
|
+
:no_echo,
|
61
|
+
:is_global,
|
62
|
+
:provided_value,
|
63
|
+
:allowed_values
|
64
|
+
|
65
|
+
def initialize(name, type, defaultValue, noEcho = false, isGlobal = false, allowed_values = nil)
|
56
66
|
@no_echo = noEcho
|
57
67
|
@name = name
|
58
68
|
@type = type
|
59
69
|
@default_value = defaultValue
|
70
|
+
@is_global = isGlobal
|
71
|
+
@allowed_values = allowed_values
|
72
|
+
@provided_value = nil
|
60
73
|
end
|
61
|
-
end
|
62
|
-
|
63
|
-
class StackParam < Parameter
|
64
|
-
attr_accessor :is_global
|
65
|
-
end
|
66
74
|
|
67
|
-
class ComponentParam < Parameter
|
68
|
-
|
69
|
-
end
|
70
|
-
|
71
|
-
class OutputParam < Parameter
|
72
|
-
attr_accessor :component
|
73
|
-
|
74
|
-
def initialize(component, name, default)
|
75
|
-
@component = component
|
76
|
-
@name = name
|
77
|
-
@default_value = default
|
78
|
-
@type = 'String'
|
79
|
-
end
|
80
75
|
end
|
81
76
|
|
82
77
|
class MappingParam < Parameter
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require_relative './cfhighlander.helper'
|
2
2
|
require_relative './cfhighlander.dsl.base'
|
3
3
|
require_relative './cfhighlander.factory'
|
4
|
+
require 'cfndsl'
|
4
5
|
|
5
6
|
module Cfhighlander
|
6
7
|
|
@@ -15,7 +16,6 @@ module Cfhighlander
|
|
15
16
|
|
16
17
|
end
|
17
18
|
|
18
|
-
|
19
19
|
class Subcomponent < DslBase
|
20
20
|
|
21
21
|
attr_accessor :name,
|
@@ -100,9 +100,6 @@ module Cfhighlander
|
|
100
100
|
end
|
101
101
|
|
102
102
|
def load(component_config_override = {})
|
103
|
-
# check for component config on parent
|
104
|
-
parent = @parent
|
105
|
-
|
106
103
|
# Highest priority is DSL defined configuration
|
107
104
|
component_config_override.extend @config
|
108
105
|
|
@@ -111,9 +108,13 @@ module Cfhighlander
|
|
111
108
|
@component_loaded.load @component_config_override
|
112
109
|
end
|
113
110
|
|
111
|
+
def parameter(name:, value:)
|
112
|
+
@param_values[name] = value
|
113
|
+
end
|
114
|
+
|
114
115
|
# Parameters should be lazy loaded, that is late-binding should happen once
|
115
116
|
# all parameters and mappings are known
|
116
|
-
def
|
117
|
+
def resolve_parameter_values(available_outputs)
|
117
118
|
component_dsl = @component_loaded.highlander_dsl
|
118
119
|
component_dsl.parameters.param_list.each do |component_param|
|
119
120
|
param = Cfhighlander::Dsl::SubcomponentParameter.new
|
@@ -121,7 +122,8 @@ module Cfhighlander
|
|
121
122
|
param.cfndsl_value = SubcomponentParamValueResolver.resolveValue(
|
122
123
|
@parent,
|
123
124
|
self,
|
124
|
-
component_param
|
125
|
+
component_param,
|
126
|
+
available_outputs)
|
125
127
|
@parameters << param
|
126
128
|
end
|
127
129
|
end
|
@@ -129,40 +131,77 @@ module Cfhighlander
|
|
129
131
|
end
|
130
132
|
|
131
133
|
class SubcomponentParamValueResolver
|
132
|
-
def self.resolveValue(component, sub_component, param)
|
133
|
-
|
134
|
-
|
134
|
+
def self.resolveValue(component, sub_component, param, available_outputs)
|
135
|
+
|
136
|
+
print("INFO Resolving parameter #{component.name} -> #{sub_component.name}.#{param.name}: ")
|
137
|
+
|
138
|
+
# rule 0: this rule is here for legacy reasons and OutputParam. It should be deprecated
|
139
|
+
# once all hl-components- repos remove any references to OutputParam
|
140
|
+
if not param.provided_value.nil?
|
141
|
+
component_name = param.provided_value.split('.')[0]
|
142
|
+
output_name = param.provided_value.split('.')[1]
|
143
|
+
source_component = component.subcomponents.find {|c| c.name == component_name}
|
144
|
+
if source_component.nil?
|
145
|
+
source_component = component.subcomponents.find {|c| c.component_loaded.template.template_name == component_name}
|
146
|
+
end
|
147
|
+
return CfnDsl::Fn.new('GetAtt', [
|
148
|
+
source_component.name,
|
149
|
+
"Outputs.#{output_name}"
|
150
|
+
]).to_json
|
151
|
+
end
|
135
152
|
|
136
|
-
# check if there are values defined on component itself
|
153
|
+
# rule 1: check if there are values defined on component itself
|
137
154
|
if sub_component.param_values.key?(param.name)
|
138
|
-
|
155
|
+
puts " parameter value provided "
|
156
|
+
|
157
|
+
param_value = sub_component.param_values[param.name]
|
158
|
+
if param_value.is_a? String and param_value.include? '.'
|
159
|
+
source_component_name = param_value.split('.')[0]
|
160
|
+
source_output = param_value.split('.')[1]
|
161
|
+
source_component = component.subcomponents.find {|sc| sc.name == source_component_name}
|
162
|
+
# if source component exists
|
163
|
+
if not source_component.nil?
|
164
|
+
if source_component_name == sub_component.name
|
165
|
+
STDERR.puts "WARNING: Parameter value on component #{source_component_name} references component itself: #{param_value}"
|
166
|
+
else
|
167
|
+
return CfnDsl::Fn.new('GetAtt', [
|
168
|
+
source_component_name,
|
169
|
+
"Outputs.#{source_output}"
|
170
|
+
]).to_json
|
171
|
+
end
|
172
|
+
else
|
173
|
+
return Cfhighlander::Helper.parameter_cfndsl_value(param_value)
|
174
|
+
end
|
175
|
+
else
|
176
|
+
return Cfhighlander::Helper.parameter_cfndsl_value(sub_component.param_values[param.name])
|
177
|
+
end
|
139
178
|
end
|
140
179
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
elsif param.class == Cfhighlander::Dsl::MappingParam
|
180
|
+
# rule 1.1 mapping parameters are handled differently.
|
181
|
+
# TODO wire mapping parameters outside of component
|
182
|
+
if param.class == Cfhighlander::Dsl::MappingParam
|
183
|
+
puts " mapping parameter"
|
146
184
|
return self.resolveMappingParamValue(component, sub_component, param)
|
147
|
-
elsif param.class == Cfhighlander::Dsl::OutputParam
|
148
|
-
return self.resolveOutputParamValue(component, sub_component, param)
|
149
|
-
else
|
150
|
-
raise "#{param.class} not resolvable to parameter value"
|
151
185
|
end
|
152
|
-
end
|
153
186
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
187
|
+
# rule #2: match output values from other components
|
188
|
+
# by parameter name
|
189
|
+
if available_outputs.key? param.name
|
190
|
+
component_name = available_outputs[param.name].component.name
|
191
|
+
puts " resolved as output of #{component_name}"
|
192
|
+
return CfnDsl::Fn.new('GetAtt', [
|
193
|
+
component_name,
|
194
|
+
"Outputs.#{param.name}"
|
195
|
+
]).to_json
|
196
|
+
end
|
197
|
+
|
198
|
+
# by default bubble parameter and resolve as reference on upper level
|
199
|
+
propagated_param = param.clone
|
200
|
+
propagated_param.name = "#{sub_component.name}#{param.name}" unless param.is_global
|
201
|
+
component.parameters.addParam propagated_param
|
202
|
+
puts " no autowiring candidates, propagate parameter to parent"
|
203
|
+
return CfnDsl::RefDefinition.new(propagated_param.name).to_json
|
158
204
|
|
159
|
-
def self.resolveComponentParamValue(component, sub_component, param)
|
160
|
-
# check component config for param value
|
161
|
-
# TODO
|
162
|
-
# check stack config for param value
|
163
|
-
# TODO
|
164
|
-
# return default value
|
165
|
-
return "'#{param.default_value}'"
|
166
205
|
end
|
167
206
|
|
168
207
|
def self.resolveMappingParamValue(component, sub_component, param)
|
@@ -207,37 +246,9 @@ module Cfhighlander
|
|
207
246
|
return "''"
|
208
247
|
end
|
209
248
|
|
210
|
-
return value
|
211
|
-
|
212
|
-
|
213
249
|
return value
|
214
250
|
end
|
215
251
|
|
216
|
-
def self.resolveOutputParamValue(component, sub_component, param)
|
217
|
-
component_name = param.component
|
218
|
-
resource_name = nil
|
219
|
-
if not sub_component.export_config.nil?
|
220
|
-
if sub_component.export_config.key? component_name
|
221
|
-
resource_name = sub_component.export_config[component_name]
|
222
|
-
end
|
223
|
-
end
|
224
|
-
|
225
|
-
if resource_name.nil?
|
226
|
-
# find by component
|
227
|
-
resource = component.components.find {|c| c.name == component_name}
|
228
|
-
resource_name = resource.name unless resource.nil?
|
229
|
-
if resource_name.nil?
|
230
|
-
resource = component.components.find {|c| c.template == component_name}
|
231
|
-
resource_name = resource.name unless resource.nil?
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
if resource_name.nil?
|
236
|
-
raise "#{sub_component.name}.Params.#{param.name}: Failed to resolve OutputParam '#{param.name}' with source '#{component_name}'. Component not found!"
|
237
|
-
end
|
238
|
-
|
239
|
-
return "FnGetAtt('#{resource_name}','Outputs.#{param.name}')"
|
240
|
-
end
|
241
252
|
end
|
242
253
|
|
243
254
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
extensions_folder = "#{File.dirname(__FILE__)}/../hl_ext"
|
4
4
|
|
5
|
-
Dir["#{extensions_folder}/*.rb"].each {
|
5
|
+
Dir["#{extensions_folder}/*.rb"].each {|f|
|
6
6
|
require f
|
7
7
|
}
|
8
8
|
|
@@ -10,7 +10,7 @@ Dir["#{extensions_folder}/*.rb"].each { |f|
|
|
10
10
|
|
11
11
|
require_relative './cfhighlander.dsl.base'
|
12
12
|
require_relative './cfhighlander.dsl.params'
|
13
|
-
require_relative './cfhighlander.dsl.
|
13
|
+
require_relative './cfhighlander.dsl.subcomponent'
|
14
14
|
|
15
15
|
module Cfhighlander
|
16
16
|
|
@@ -21,7 +21,7 @@ module Cfhighlander
|
|
21
21
|
attr_accessor :mappings,
|
22
22
|
:parameters,
|
23
23
|
:name,
|
24
|
-
:
|
24
|
+
:subcomponents,
|
25
25
|
:version,
|
26
26
|
:distribute_url,
|
27
27
|
:distribution_bucket,
|
@@ -32,7 +32,7 @@ module Cfhighlander
|
|
32
32
|
|
33
33
|
def initialize
|
34
34
|
@mappings = []
|
35
|
-
@
|
35
|
+
@subcomponents = []
|
36
36
|
@config = { 'mappings' => {}, 'component_version' => 'latest' }
|
37
37
|
@component_configs = {}
|
38
38
|
@version = 'latest'
|
@@ -74,7 +74,7 @@ module Cfhighlander
|
|
74
74
|
|
75
75
|
def DynamicMappings(providerName)
|
76
76
|
maps = mappings_provider_maps(providerName, self.config)
|
77
|
-
maps.each {
|
77
|
+
maps.each {|name, map| addMapping(name, map)} unless maps.nil?
|
78
78
|
end
|
79
79
|
|
80
80
|
def DependsOn(template)
|
@@ -82,8 +82,20 @@ module Cfhighlander
|
|
82
82
|
end
|
83
83
|
|
84
84
|
|
85
|
-
def Component(
|
85
|
+
def Component(template_arg = nil, template: nil,
|
86
|
+
name: template,
|
87
|
+
param_values: {},
|
88
|
+
config: {},
|
89
|
+
export_config: {}, &block)
|
86
90
|
puts "INFO: Requested subcomponent #{name} with template #{template}"
|
91
|
+
if ((not template_arg.nil?) and template.nil?)
|
92
|
+
template = template_arg
|
93
|
+
elsif (template_arg.nil? and template.nil?)
|
94
|
+
raise 'Component must be defined with template name at minimum,' +
|
95
|
+
' passed as first argument, or template: named arguent'
|
96
|
+
end
|
97
|
+
|
98
|
+
name = template if name.nil?
|
87
99
|
|
88
100
|
# load component
|
89
101
|
component = Cfhighlander::Dsl::Subcomponent.new(self,
|
@@ -94,11 +106,12 @@ module Cfhighlander
|
|
94
106
|
config,
|
95
107
|
export_config
|
96
108
|
)
|
109
|
+
component.instance_eval(&block) unless block.nil?
|
97
110
|
component.distribute_bucket = @distribution_bucket unless @distribution_bucket.nil?
|
98
111
|
component.distribute_prefix = @distribution_prefix unless @distribution_prefix.nil?
|
99
112
|
component.version = @version unless @version.nil?
|
100
113
|
@component_configs[name] = config
|
101
|
-
@
|
114
|
+
@subcomponents << component
|
102
115
|
end
|
103
116
|
|
104
117
|
def ComponentVersion(version)
|
@@ -151,8 +164,8 @@ module Cfhighlander
|
|
151
164
|
def loadComponents()
|
152
165
|
|
153
166
|
# empty config overrides to start with
|
154
|
-
@config_overrides = Hash[@
|
155
|
-
@named_components = Hash[@
|
167
|
+
@config_overrides = Hash[@subcomponents.collect {|c| [c.name, { 'nested_component' => true }]}]
|
168
|
+
@named_components = Hash[@subcomponents.collect {|c| [c.name, c]}]
|
156
169
|
|
157
170
|
# populate overrides with master config defined overrides
|
158
171
|
load_configfile_component_config
|
@@ -174,7 +187,7 @@ module Cfhighlander
|
|
174
187
|
|
175
188
|
|
176
189
|
# load components and extract parent stack parameters and mappings
|
177
|
-
@
|
190
|
+
@subcomponents.each do |component|
|
178
191
|
|
179
192
|
component.load @config_overrides[component.name]
|
180
193
|
# add all of it's stack parameters unless same template has been already processed
|
@@ -184,19 +197,6 @@ module Cfhighlander
|
|
184
197
|
.parameters
|
185
198
|
.param_list.each do |param|
|
186
199
|
|
187
|
-
# add stack parameters
|
188
|
-
if param.class == Cfhighlander::Dsl::StackParam
|
189
|
-
# sub-component stack param becomes top-level component param
|
190
|
-
param_name = param.is_global ? param.name : "#{component.name}#{param.name}"
|
191
|
-
stack_param = Cfhighlander::Dsl::ComponentParam.new(
|
192
|
-
param_name,
|
193
|
-
param.type,
|
194
|
-
param.default_value,
|
195
|
-
param.no_echo
|
196
|
-
)
|
197
|
-
@parameters.addParam stack_param
|
198
|
-
end unless component.param_values.key? param.name
|
199
|
-
|
200
200
|
# for map parameters add maps
|
201
201
|
if param.class == Cfhighlander::Dsl::MappingParam
|
202
202
|
if not param.mapProvider.nil?
|
@@ -215,9 +215,21 @@ module Cfhighlander
|
|
215
215
|
|
216
216
|
end
|
217
217
|
|
218
|
-
|
219
|
-
|
220
|
-
|
218
|
+
component.component_loaded.eval_cfndsl()
|
219
|
+
end
|
220
|
+
|
221
|
+
# in 2nd pass, load parameters
|
222
|
+
# 2nd pass is required as all of cfndsl models need to be populated
|
223
|
+
available_outputs = {}
|
224
|
+
@subcomponents.each do |c|
|
225
|
+
c.component_loaded.outputs.each do |out|
|
226
|
+
available_outputs[out.name] = out
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
@subcomponents.each do |component|
|
231
|
+
component.resolve_parameter_values available_outputs
|
232
|
+
end
|
221
233
|
|
222
234
|
@dependson_components_templates.each do |template|
|
223
235
|
component = Cfhighlander::Dsl::Subcomponent.new(self,
|
@@ -232,7 +244,7 @@ module Cfhighlander
|
|
232
244
|
end
|
233
245
|
|
234
246
|
def load_extension_exports
|
235
|
-
@
|
247
|
+
@subcomponents.each do |c|
|
236
248
|
component = c.component_loaded
|
237
249
|
config = component.config
|
238
250
|
if ((config.key? 'lib_export') and (config['lib_export'].key? 'global'))
|
@@ -241,7 +253,7 @@ module Cfhighlander
|
|
241
253
|
if global_export_config.key? 'cfndsl'
|
242
254
|
global_export_config['cfndsl'].each do |exported_extension|
|
243
255
|
extension_file_path = "#{component.component_dir}/ext/cfndsl/#{exported_extension}.rb"
|
244
|
-
@
|
256
|
+
@subcomponents.each do |cr|
|
245
257
|
cr.component_loaded.cfndsl_ext_files << extension_file_path unless cr == c
|
246
258
|
end
|
247
259
|
end
|
@@ -252,14 +264,14 @@ module Cfhighlander
|
|
252
264
|
end
|
253
265
|
|
254
266
|
def apply_config_overrides
|
255
|
-
@config_overrides.each {
|
267
|
+
@config_overrides.each {|component_name, component_override|
|
256
268
|
@named_components[component_name].component_loaded.config.extend(component_override)
|
257
269
|
}
|
258
270
|
end
|
259
271
|
|
260
272
|
def load_configfile_component_config
|
261
273
|
if (@config.key? 'components')
|
262
|
-
@config['components'].each {
|
274
|
+
@config['components'].each {|component_name, component_config|
|
263
275
|
if component_config.key?('config')
|
264
276
|
if @config_overrides.key? component_name
|
265
277
|
@config_overrides[component_name].extend(component_config['config'])
|
@@ -274,28 +286,28 @@ module Cfhighlander
|
|
274
286
|
def apply_config_exports
|
275
287
|
# first export from master to all children
|
276
288
|
if ((@config.key? 'config_export') and (@config['config_export']['global']))
|
277
|
-
@config['config_export']['global'].each {
|
289
|
+
@config['config_export']['global'].each {|global_export_key|
|
278
290
|
if @config.key? global_export_key
|
279
|
-
@config_overrides.each {
|
291
|
+
@config_overrides.each {|cname, co|
|
280
292
|
co[global_export_key] = @config[global_export_key]
|
281
293
|
}
|
282
294
|
end
|
283
295
|
}
|
284
296
|
end
|
285
297
|
|
286
|
-
@
|
298
|
+
@subcomponents.each {|component|
|
287
299
|
cl = component.component_loaded
|
288
300
|
if ((not cl.config.nil?) and (cl.config.key? 'config_export'))
|
289
301
|
|
290
302
|
# global config
|
291
303
|
if cl.config['config_export'].key? 'global'
|
292
|
-
cl.config['config_export']['global'].each {
|
304
|
+
cl.config['config_export']['global'].each {|global_export_key|
|
293
305
|
|
294
306
|
# global config is exported to parent and every component
|
295
307
|
if cl.config.key? global_export_key
|
296
308
|
|
297
309
|
# cname is for component name, co for component override
|
298
|
-
@config_overrides.each {
|
310
|
+
@config_overrides.each {|cname, co|
|
299
311
|
|
300
312
|
# if templates are different e.g don't export from vpc to vpc
|
301
313
|
config_receiver_component = @named_components[cname]
|
@@ -321,7 +333,7 @@ module Cfhighlander
|
|
321
333
|
end
|
322
334
|
|
323
335
|
if cl.config['config_export'].key? 'component'
|
324
|
-
cl.config['config_export']['component'].each {
|
336
|
+
cl.config['config_export']['component'].each {|component_name, export_keys|
|
325
337
|
# check if there is configuration of export from this component
|
326
338
|
# and if there is export configuration for given component name
|
327
339
|
|
@@ -330,7 +342,7 @@ module Cfhighlander
|
|
330
342
|
if @config_overrides.key? component.export_config[component_name]
|
331
343
|
# override the config
|
332
344
|
real_component_name = component.export_config[component_name]
|
333
|
-
export_keys.each {
|
345
|
+
export_keys.each {|export_component_key|
|
334
346
|
puts("Exporting config for key=#{export_component_key} from #{component.name} to #{real_component_name}")
|
335
347
|
if not @config_overrides[real_component_name].key? export_component_key
|
336
348
|
@config_overrides[real_component_name][export_component_key] = {}
|
@@ -341,7 +353,7 @@ module Cfhighlander
|
|
341
353
|
STDERR.puts("Trying to export configuration for non-existant component #{component.export_config[component_name]}")
|
342
354
|
end
|
343
355
|
elsif @config_overrides.key? component_name
|
344
|
-
export_keys.each {
|
356
|
+
export_keys.each {|export_component_key|
|
345
357
|
puts("Exporting config for key=#{export_component_key} from #{component.name} to #{component_name}")
|
346
358
|
if not @config_overrides[component_name].key? export_component_key
|
347
359
|
@config_overrides[component_name][export_component_key] = {}
|
@@ -361,7 +373,7 @@ module Cfhighlander
|
|
361
373
|
end
|
362
374
|
|
363
375
|
def load_explicit_component_config
|
364
|
-
@component_configs.each {
|
376
|
+
@component_configs.each {|component_name, component_config|
|
365
377
|
@config_overrides[component_name].extend(component_config)
|
366
378
|
}
|
367
379
|
end
|
@@ -384,7 +396,7 @@ module Cfhighlander
|
|
384
396
|
if not (@distribution_bucket.nil? or @distribution_prefix.nil?)
|
385
397
|
@distribute_url = "https://#{@distribution_bucket}.s3.amazonaws.com/#{@distribution_prefix}"
|
386
398
|
@distribute_url = "#{@distribute_url}/#{@version}" unless @version.nil?
|
387
|
-
@
|
399
|
+
@subcomponents.each {|component|
|
388
400
|
component.distribute_bucket = @distribution_bucket unless @distribution_bucket.nil?
|
389
401
|
component.distribute_prefix = @distribution_prefix unless @distribution_prefix.nil?
|
390
402
|
component.version = @version unless @version.nil?
|
@@ -399,7 +411,7 @@ module Cfhighlander
|
|
399
411
|
|
400
412
|
end
|
401
413
|
|
402
|
-
def
|
414
|
+
def CfhighlanderTemplate(&block)
|
403
415
|
instance = Cfhighlander::Dsl::HighlanderTemplate.new
|
404
416
|
|
405
417
|
puts "Processing higlander component #{@name}\n\tLocation:#{@highlander_dsl_path}" +
|
@@ -435,5 +447,11 @@ def HighlanderComponent(&block)
|
|
435
447
|
end
|
436
448
|
|
437
449
|
def CfhighlanderComponent(&block)
|
438
|
-
|
450
|
+
STDERR.puts("DEPRECATED: #{@template.template_name}: use CfhighlanderTemplate instead of CfhighlanderComponent")
|
451
|
+
CfhighlanderTemplate(&block)
|
452
|
+
end
|
453
|
+
|
454
|
+
def HighlanderComponent(&block)
|
455
|
+
STDERR.puts("DEPRECATED: #{@template.template_name}: use CfhighlanderTemplate instead of HighlanderComponent")
|
456
|
+
CfhighlanderTemplate(&block)
|
439
457
|
end
|
data/lib/cfhighlander.factory.rb
CHANGED
data/lib/cfhighlander.helper.rb
CHANGED
@@ -22,6 +22,8 @@ module Cfhighlander
|
|
22
22
|
:cfndsl_ext_files,
|
23
23
|
:lambda_src_files
|
24
24
|
|
25
|
+
attr_reader :cfn_model, :outputs
|
26
|
+
|
25
27
|
def initialize(template_meta, component_name)
|
26
28
|
@template = template_meta
|
27
29
|
@name = component_name
|
@@ -69,7 +71,7 @@ module Cfhighlander
|
|
69
71
|
STDERR.puts "DEPRECATED: #{legacy_cfhighlander_path} - Use *.cfhiglander.rb"
|
70
72
|
@highlander_dsl_path = legacy_cfhighlander_path
|
71
73
|
else
|
72
|
-
@highlander_dsl_path =
|
74
|
+
@highlander_dsl_path = "#{@component_dir}/#{@template.template_name}.cfhighlander.rb"
|
73
75
|
end
|
74
76
|
|
75
77
|
@cfndsl_path = "#{@component_dir}/#{@template.template_name}.cfndsl.rb"
|
@@ -88,10 +90,7 @@ module Cfhighlander
|
|
88
90
|
@config['component_name'] = @name
|
89
91
|
@config['template_name'] = @template.template_name
|
90
92
|
@config['template_version'] = @template.template_version
|
91
|
-
|
92
|
-
# config_override.each do |key, value|
|
93
|
-
# @config[key] = value
|
94
|
-
# end unless config_override.nil?
|
93
|
+
|
95
94
|
|
96
95
|
Dir[candidate_mappings_path].each do |mapping_file|
|
97
96
|
mappings = YAML.load(File.read(mapping_file))
|
@@ -145,6 +144,31 @@ module Cfhighlander
|
|
145
144
|
|
146
145
|
loadDepandantExt()
|
147
146
|
end
|
147
|
+
|
148
|
+
# evaluates cfndsl with current config
|
149
|
+
def eval_cfndsl
|
150
|
+
compiler = Cfhighlander::Compiler::ComponentCompiler.new self
|
151
|
+
@cfn_model = compiler.evaluateCloudFormation().as_json
|
152
|
+
@outputs = (
|
153
|
+
if @cfn_model.key? 'Outputs'
|
154
|
+
then
|
155
|
+
@cfn_model['Outputs'].map {|k, v| ComponentOutput.new self, k, v}
|
156
|
+
else
|
157
|
+
[]
|
158
|
+
end
|
159
|
+
)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
class ComponentOutput
|
164
|
+
|
165
|
+
attr_reader :component, :name, :value
|
166
|
+
|
167
|
+
def initialize(component, name, value)
|
168
|
+
@component = component
|
169
|
+
@name = name
|
170
|
+
@value = value
|
171
|
+
end
|
148
172
|
end
|
149
173
|
|
150
174
|
end
|
@@ -8,7 +8,7 @@ CloudFormation do
|
|
8
8
|
<% end %>
|
9
9
|
|
10
10
|
# render subcomponents
|
11
|
-
<% for @component in dsl.
|
11
|
+
<% for @component in dsl.subcomponents %>
|
12
12
|
CloudFormation_Stack('<%= @component.name.gsub('-','').gsub('_','') %>') do
|
13
13
|
TemplateURL '<%= @component.distribution_url %>'
|
14
14
|
Parameters ({
|
@@ -38,6 +38,9 @@ CloudFormation do
|
|
38
38
|
<% unless @param.no_echo.nil? %>
|
39
39
|
NoEcho <%= @param.no_echo.to_s %>
|
40
40
|
<% end %>
|
41
|
+
<% unless @param.allowed_values.nil? %>
|
42
|
+
AllowedValues <%= @param.allowed_values.to_s %>
|
43
|
+
<% end %>
|
41
44
|
end
|
42
45
|
<% end %>
|
43
46
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cfhighlander
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.1.alpha.
|
4
|
+
version: 0.2.1.alpha.43
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nikola Tosic
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2018-06-
|
12
|
+
date: 2018-06-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: highline
|
@@ -245,9 +245,9 @@ files:
|
|
245
245
|
- hl_ext/vpc.rb
|
246
246
|
- lib/cfhighlander.compiler.rb
|
247
247
|
- lib/cfhighlander.dsl.base.rb
|
248
|
-
- lib/cfhighlander.dsl.component.rb
|
249
248
|
- lib/cfhighlander.dsl.params.rb
|
250
|
-
- lib/cfhighlander.dsl.rb
|
249
|
+
- lib/cfhighlander.dsl.subcomponent.rb
|
250
|
+
- lib/cfhighlander.dsl.template.rb
|
251
251
|
- lib/cfhighlander.factory.rb
|
252
252
|
- lib/cfhighlander.factory.templatefinder.rb
|
253
253
|
- lib/cfhighlander.helper.rb
|