cfhighlander 0.2.0.alpha.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +411 -0
- data/bin/cfhighlander +3 -0
- data/bin/highlander.rb +158 -0
- data/cfndsl_ext/config/managed_policies.yaml +172 -0
- data/cfndsl_ext/iam_helper.rb +55 -0
- data/cfndsl_ext/lambda_helper.rb +86 -0
- data/cfndsl_ext/sg.rb +26 -0
- data/hl_ext/aws_helper.rb +13 -0
- data/hl_ext/common_helper.rb +21 -0
- data/hl_ext/mapping_helper.rb +99 -0
- data/hl_ext/vpc.rb +12 -0
- data/lib/highlander.compiler.rb +306 -0
- data/lib/highlander.dsl.base.rb +25 -0
- data/lib/highlander.dsl.component.rb +243 -0
- data/lib/highlander.dsl.params.rb +113 -0
- data/lib/highlander.dsl.rb +428 -0
- data/lib/highlander.factory.rb +359 -0
- data/lib/highlander.helper.rb +23 -0
- data/lib/highlander.mapproviders.rb +31 -0
- data/lib/highlander.publisher.rb +71 -0
- data/lib/highlander.validator.rb +72 -0
- data/lib/util/zip.util.rb +57 -0
- data/templates/cfndsl.component.template.erb +45 -0
- metadata +248 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e3e89ca96189f61bf33bee53483c80d21bc8b019046d0f88f53546187ffb8a3f
|
4
|
+
data.tar.gz: 570a0ecaf7861401432572603be85d3d2627309aeeeca96369b080540e79556b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f2dd509569d44185bdfabafe04e20fa11efb4556f4e9bd33f5415bf8dee5faf3abcc35f53e155438af3f41595387e6719662ae21a0ed8a700fa08c04a88624ce
|
7
|
+
data.tar.gz: ddbff792cf60a90b573e281cc4671cd0ef94e842a01440710a960ef08bdcf3831da5be5ad9e3b7832213762ff2af1fa985a952f260449fb70921d97f3fa6388f
|
data/README.md
ADDED
@@ -0,0 +1,411 @@
|
|
1
|
+
[![Build Status](https://travis-ci.com/theonestack/cfhighlander.svg?branch=develop)](https://travis-ci.com/theonestack/cfhighlander)
|
2
|
+
|
3
|
+
# Highlander
|
4
|
+
|
5
|
+
Highlander is DSL processor that enables composition and orchestration of Amazon CloudFormation templates
|
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
|
+
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 achieved using
|
9
|
+
`OutputParam` highlander DSL statement, rather than wiring this parameters manually in cfndsl templates. For this example to
|
10
|
+
work, parent component will have to pull in both component rendering output values, and component pulling them in
|
11
|
+
as parameters. It also enables it's user to build component library, where components can be distributed to s3, and
|
12
|
+
consequentially references to them resolved.
|
13
|
+
|
14
|
+
Highlander DSL produces CloudFormation templates in 3 phases
|
15
|
+
|
16
|
+
- Processing referenced component's configuration and resolving configuration exports
|
17
|
+
- Producing [CfnDsl](https://github.com/cfndsl/cfndsl) templates for all components and subcomponents as intermediary
|
18
|
+
step
|
19
|
+
- Producing resulting CloudFormation templates using configuration and templates generated in two previous phases.
|
20
|
+
|
21
|
+
Each phase above is executable as stand-alone through CLI, making development of Highlander templates easier by enabling
|
22
|
+
debugging of produced configuration and cfndsl templates.
|
23
|
+
|
24
|
+
|
25
|
+
## Highlander components
|
26
|
+
|
27
|
+
Highlander component is located on local file system or S3 location with following
|
28
|
+
files defining them
|
29
|
+
|
30
|
+
- Highlander DSL file (`$componentname.highlander.rb`)
|
31
|
+
- *(Optional)* Configuration files (`*.config.yaml`)
|
32
|
+
- *(Optional)* CfnDSL file (`componentname.cfnds.rb`)
|
33
|
+
- *(Optional)* Mappings YAML files `*.mappings.yaml` -
|
34
|
+
this file defines map used within component itself
|
35
|
+
- *(Optional)* Mappings extension file `componentname.mappings.rb` - see more under Mappings section
|
36
|
+
- *(Optional)* Ruby extensions consumed by cfndsl templates - placed in `ext/cfndsl/*.rb` - see more under
|
37
|
+
Extensions section
|
38
|
+
|
39
|
+
## Terminology
|
40
|
+
|
41
|
+
**Component** is basic building block of highlander systems. Components have following roles
|
42
|
+
|
43
|
+
- Define (include) other components
|
44
|
+
- Define how their parameters are wired with other components (sibling and outer components)
|
45
|
+
- Define how their configuration affects other components
|
46
|
+
- Define sources of their inner components
|
47
|
+
- Define publish location for both component source code and compiled CloudFormation templates
|
48
|
+
- Define cfndsl template used for building CloudFormation resources
|
49
|
+
|
50
|
+
|
51
|
+
**Outer component** is component that defines other component via higlander dsl `Component` statement. Defined component
|
52
|
+
is called **inner component**. Components defined under same outer component are **sibling components**
|
53
|
+
|
54
|
+
## Usage
|
55
|
+
|
56
|
+
You can either pull highlander classes in your own code, or more commonly use it via command line interface (cli).
|
57
|
+
For both ways, highlander is distributed as ruby gem
|
58
|
+
|
59
|
+
|
60
|
+
```bash
|
61
|
+
$ gem install highlander
|
62
|
+
$ highlander help
|
63
|
+
highlander commands:
|
64
|
+
highlander cfcompile component[@version] -f, --format=FORMAT # Compile Highlander component to CloudFormation templates
|
65
|
+
highlander cfpublish component[@version] -f, --format=FORMAT # Publish CloudFormation template for component, and it' referenced subcomponents
|
66
|
+
highlander configcompile component[@version] # Compile Highlander components configuration
|
67
|
+
highlander dslcompile component[@version] -f, --format=FORMAT # Compile Highlander component configuration and create cfndsl templates
|
68
|
+
highlander help [COMMAND] # Describe available commands or one specific command
|
69
|
+
highlander publish component[@version] [-v published_version] # Publish CloudFormation template for component, and it' referenced subcomponents
|
70
|
+
|
71
|
+
```
|
72
|
+
### Working directory
|
73
|
+
|
74
|
+
All templates and configuration generated are placed in `$WORKDIR/out` directory. Optionally, you can alter working directory
|
75
|
+
via `HIGHLANDER_WORKDIR` environment variable.
|
76
|
+
|
77
|
+
### Commands
|
78
|
+
|
79
|
+
To get full list of options for any of cli commands use `highlander help command_name` syntax
|
80
|
+
|
81
|
+
```bash
|
82
|
+
$ highlander help publish
|
83
|
+
Usage:
|
84
|
+
highlander publish component[@version] [-v published_version]
|
85
|
+
|
86
|
+
Options:
|
87
|
+
[--dstbucket=DSTBUCKET] # Distribution S3 bucket
|
88
|
+
[--dstprefix=DSTPREFIX] # Distribution S3 prefix
|
89
|
+
-v, [--version=VERSION] # Distribution component version, defaults to latest
|
90
|
+
|
91
|
+
Publish CloudFormation template for component,
|
92
|
+
and it' referenced subcomponents
|
93
|
+
|
94
|
+
```
|
95
|
+
|
96
|
+
#### Silent mode
|
97
|
+
|
98
|
+
Highlander DSL processor has built-in support for packaging and deploying AWS Lambda functions. Some of these lambda
|
99
|
+
functions may require shell command to be executed (e.g. pulling library dependencies) prior their packaging in ZIP archive format.
|
100
|
+
Such commands are potential security risk, as they allow execution of arbitrary code, so for this reason user agreement is required
|
101
|
+
e.g:
|
102
|
+
|
103
|
+
```bash
|
104
|
+
Packaging AWS Lambda function logMessage...
|
105
|
+
Following code will be executed to generate lambda function logMessage:
|
106
|
+
|
107
|
+
pip install requests -t lib
|
108
|
+
|
109
|
+
Proceed (y/n)?
|
110
|
+
```
|
111
|
+
|
112
|
+
In order to avoid user prompt pass `-q` or `--quiet` switch to CLI for commands that require Lambda packaging
|
113
|
+
(`dslcompile`, `cfcompile`, `cfpublish`)
|
114
|
+
|
115
|
+
|
116
|
+
#### cfcompile
|
117
|
+
|
118
|
+
*cfcompile* will produce cloudformation templates in specified format (defaults to yaml). You can optionally validate
|
119
|
+
produced template via `--validate` switch. Resulting templates will be placed in `$WORKDIR/out/$format`
|
120
|
+
|
121
|
+
|
122
|
+
#### cfpublish
|
123
|
+
|
124
|
+
*cfcompile* will produce cloudformation templates in specified format (defaults to yaml), and publish them to S3 location.
|
125
|
+
You can optionally validate produced template via `--validate` switch. Resulting templates will be placed in `$WORKDIR/out/$format`, and
|
126
|
+
published to `s3://$distributionBucket/$distributionPrefix/$distributionVersion`. All S3 path components can be controlled
|
127
|
+
via CLI (`--dstbucket`, `--dstprefix`, `-v`). Default distribution bucket and prefix can be also be controlled via DSL using
|
128
|
+
`DistributionBucket`, `DistributionBucket`, `DistributionPrefix` or `ComponentDistribution` statements. Check DSL specification
|
129
|
+
for more details on this statements. Version defaults to `latest` if not explicitly given using `-v` switch
|
130
|
+
|
131
|
+
|
132
|
+
#### configcompile
|
133
|
+
|
134
|
+
*configcompile* produces configuration yamls that are passed as external configuration when processing
|
135
|
+
cfndsl templates. Check component configuration section for more details.
|
136
|
+
|
137
|
+
#### dslcompile
|
138
|
+
|
139
|
+
*dslcompile* will produce intermediary cfndsl templates. This is useful for debugging highlander components
|
140
|
+
|
141
|
+
#### publish
|
142
|
+
|
143
|
+
*publish* command publishes highlander components source code to s3 location (compared to *cfpublish* which is publishing
|
144
|
+
compiled cloudformation templates). Same CLI / DSL options apply as for *cfpublish* command. Version defaults to `latest`
|
145
|
+
|
146
|
+
|
147
|
+
|
148
|
+
## Component configuration
|
149
|
+
|
150
|
+
There are 4 levels of component configuration
|
151
|
+
|
152
|
+
- Component local config file `component.config.yaml` (lowest priority)
|
153
|
+
- Outer component configuration file, under `components` key, like
|
154
|
+
|
155
|
+
|
156
|
+
```yaml
|
157
|
+
|
158
|
+
# some configuration values
|
159
|
+
|
160
|
+
components:
|
161
|
+
vpc:
|
162
|
+
config:
|
163
|
+
maximum_availibility_zones: 2
|
164
|
+
|
165
|
+
```
|
166
|
+
This configuration level overrides component's own config file.
|
167
|
+
|
168
|
+
|
169
|
+
- Outer component explicit configuration. You can pass `config` named parameter to `Component` statement, such as
|
170
|
+
|
171
|
+
```ruby
|
172
|
+
HighlanderComponent do
|
173
|
+
|
174
|
+
# ...
|
175
|
+
# some dsl code
|
176
|
+
# ...
|
177
|
+
|
178
|
+
Component template:'vpc@latest',config: {'maximum_availibility_zones' => 2}
|
179
|
+
|
180
|
+
end
|
181
|
+
```
|
182
|
+
Configuration done this way will override any outer component config coming from configuration file
|
183
|
+
|
184
|
+
|
185
|
+
- Exported configuration from other components. If any component exports configuration using `config_export` configuration
|
186
|
+
key, it may alter configuration of other components. Globally exported configuration is defined under `global`, while
|
187
|
+
component-oriented configuration is exported under `component` key. E.g. following configuration will export global
|
188
|
+
configuration defining name of ecs cluster, and targeted to vpc component configuration, defining subnets
|
189
|
+
|
190
|
+
```yaml
|
191
|
+
ecs_cluster_name: ApplicationCluster
|
192
|
+
|
193
|
+
subnets:
|
194
|
+
ecs_cluster:
|
195
|
+
name: ECSCluster
|
196
|
+
type: private
|
197
|
+
allocation: 20
|
198
|
+
|
199
|
+
config_export:
|
200
|
+
global:
|
201
|
+
- ecs_cluster_name
|
202
|
+
|
203
|
+
component:
|
204
|
+
vpc:
|
205
|
+
- subnets
|
206
|
+
```
|
207
|
+
|
208
|
+
Configuration is exported **AFTER** component local config, and outer component configurations are loaded.
|
209
|
+
Outer component configuration takes priority over exported configuration, as this configuration is loaded once
|
210
|
+
more once component exported conifgurations are applied to appropriate components.
|
211
|
+
|
212
|
+
To change *NAME* of targeted component (e.g. from `vpc` to `vpc1`), you can use `export_config` named parameter on `Component` dsl method
|
213
|
+
In addition to configuration in inner component above, wiring of targeted component for export would be done like
|
214
|
+
|
215
|
+
```ruby
|
216
|
+
Component name: 'vpc1', template: 'vpc'
|
217
|
+
Component name: 'ecs_cluster', template: 'ecs_cluster@latest', export_config: {'vpc' => 'vpc1'}
|
218
|
+
```
|
219
|
+
## CloudFormation mappings
|
220
|
+
|
221
|
+
[CloudFormation Mappings](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/mappings-section-structure.html)
|
222
|
+
section matches a key to a corresponding set of named values. Highlander allows you to define this mappings in two ways
|
223
|
+
|
224
|
+
1. By using static maps defined through YAML files. Place `*.mappings.yaml` file alongside with highlander
|
225
|
+
template to define mappings this way. Mappings defined in a static way are automatically rendered withing CloudFormation
|
226
|
+
template E.g.
|
227
|
+
|
228
|
+
```yaml
|
229
|
+
# Master component mappings
|
230
|
+
# envtype.mappings.yaml
|
231
|
+
EnvironmentType:
|
232
|
+
dev:
|
233
|
+
InstanceType: t2.medium
|
234
|
+
prod:
|
235
|
+
InstanceType: m4.medium
|
236
|
+
```
|
237
|
+
|
238
|
+
2. By defining mappings dynamically through Ruby code. Alongside with mappings, you can define default map name, and default
|
239
|
+
map key to be used when looking up value within this map. This mappings are usually rendered in outer component when inner
|
240
|
+
components pulls mapping value as parameter via `MappingParam` statement. Optionally, this mappings can be rendered within
|
241
|
+
component that defines them using `DynamicMappings` DSL statement.
|
242
|
+
|
243
|
+
## Extensions
|
244
|
+
|
245
|
+
### Cfndsl extensions
|
246
|
+
|
247
|
+
In order to make template more DRY, template developer may reuse ruby functions. It is possible to place
|
248
|
+
such functions in separate files. Any ruby files placed within `ext/cfndsl` directory will get automatically
|
249
|
+
included via Ruby `require` function in compiled Cfndsl template.
|
250
|
+
|
251
|
+
## Component DSL
|
252
|
+
|
253
|
+
|
254
|
+
### Parameters
|
255
|
+
|
256
|
+
Parameters block is used to define CloudFormation template parameters, and metadata on how they
|
257
|
+
are wired with outer or sibling components.
|
258
|
+
|
259
|
+
```ruby
|
260
|
+
HighlanderComponent do
|
261
|
+
Parameters do
|
262
|
+
##
|
263
|
+
## parameter definitions here
|
264
|
+
##
|
265
|
+
end
|
266
|
+
end
|
267
|
+
```
|
268
|
+
|
269
|
+
Parameter block supports following parameters
|
270
|
+
|
271
|
+
#### ComponentParam
|
272
|
+
|
273
|
+
`ComponentParam` - Component parameter takes name and default value. It defines component parameter
|
274
|
+
that is not auto-wired in any way with outer component. This parameter will either use default value, or value
|
275
|
+
explicitly passed from outer component.
|
276
|
+
|
277
|
+
```ruby
|
278
|
+
|
279
|
+
# Inner Component
|
280
|
+
HighlanderComponent do
|
281
|
+
Name 's3'
|
282
|
+
Parameters do
|
283
|
+
ComponentParam 'BucketName','highlander.example.com.au'
|
284
|
+
end
|
285
|
+
end
|
286
|
+
```
|
287
|
+
|
288
|
+
```ruby
|
289
|
+
# Outer component
|
290
|
+
HighlanderComponent do
|
291
|
+
# instantiate inner component with name and template
|
292
|
+
Component template:'s3',
|
293
|
+
name:'s3',
|
294
|
+
parameters:{'BucketName' => 'outer.example.com.au'}
|
295
|
+
end
|
296
|
+
```
|
297
|
+
|
298
|
+
#### StackParam
|
299
|
+
|
300
|
+
`StackParam` - Stack parameter bubbles up to it's outer component. Outer component will either define top level parameter
|
301
|
+
with same name as inner component parameter (if parameter is defined as global), or it will be prefixed with inner component name.
|
302
|
+
|
303
|
+
|
304
|
+
```ruby
|
305
|
+
# Outer component
|
306
|
+
HighlanderComponent do
|
307
|
+
Component template:'s3',name:'s3'
|
308
|
+
end
|
309
|
+
```
|
310
|
+
|
311
|
+
```ruby
|
312
|
+
# Inner component
|
313
|
+
HighlanderComponent do
|
314
|
+
Name 's3'
|
315
|
+
Parameters do
|
316
|
+
StackParam 'EnvironmentName','dev', isGlobal:true
|
317
|
+
StackParam 'BucketName','highlander.example.com.au', isGlobal:false
|
318
|
+
end
|
319
|
+
end
|
320
|
+
```
|
321
|
+
|
322
|
+
|
323
|
+
Example above translates to following cfndsl template in outer component
|
324
|
+
```ruby
|
325
|
+
CloudFormation do
|
326
|
+
|
327
|
+
Parameter('EnvironmentName') do
|
328
|
+
Type 'String'
|
329
|
+
Default ''
|
330
|
+
end
|
331
|
+
|
332
|
+
Parameter('s3BucketName') do
|
333
|
+
Type 'String'
|
334
|
+
Default 'highlander.example.com.au'
|
335
|
+
end
|
336
|
+
|
337
|
+
CloudFormation_Stack('s3') do
|
338
|
+
TemplateURL 'https://distributionbucket/dist/latest/s3.yaml'
|
339
|
+
Parameters ({
|
340
|
+
|
341
|
+
'EnvironmentName' => Ref('EnvironmentName'),
|
342
|
+
|
343
|
+
'BucketName' => Ref('s3BucketName'),
|
344
|
+
|
345
|
+
})
|
346
|
+
end
|
347
|
+
end
|
348
|
+
```
|
349
|
+
|
350
|
+
|
351
|
+
#### MappingParam
|
352
|
+
|
353
|
+
`MappingParam` - Mapping parameters value is passed as CloudFormation mapping lookup from outer component.
|
354
|
+
This DSL statements takes a full body, as Mapping name, Map key, and value key need to be specified. `key`,
|
355
|
+
`attribute` and `map` methods are used to specify these properties. Mapping parameters involve ruby code execution
|
356
|
+
|
357
|
+
|
358
|
+
|
359
|
+
```ruby
|
360
|
+
# Inner component
|
361
|
+
HighlanderComponent do
|
362
|
+
Name 's3'
|
363
|
+
Parameters do
|
364
|
+
MappingParam 'BucketName' do
|
365
|
+
map 'AccountId'
|
366
|
+
attribute 'DnsDomain'
|
367
|
+
end
|
368
|
+
end
|
369
|
+
end
|
370
|
+
```
|
371
|
+
|
372
|
+
|
373
|
+
#### OutputParam
|
374
|
+
|
375
|
+
TBD
|
376
|
+
|
377
|
+
### DependsOn
|
378
|
+
|
379
|
+
`DependsOn` - this will include any globally exported libraries from given
|
380
|
+
template. E.g.
|
381
|
+
|
382
|
+
```ruby
|
383
|
+
HighlanderComponent do
|
384
|
+
Name 's3'
|
385
|
+
DependsOn 'vpc@1.0.3'
|
386
|
+
end
|
387
|
+
```
|
388
|
+
|
389
|
+
Will include any cfndsl libraries present and exported in vpc template
|
390
|
+
so extension methods can be consumed within cfndsl template.
|
391
|
+
|
392
|
+
### LambdaFunctions
|
393
|
+
|
394
|
+
#### Packaging and publishing
|
395
|
+
|
396
|
+
#### Rendering
|
397
|
+
|
398
|
+
#### Referencing
|
399
|
+
|
400
|
+
|
401
|
+
## Finding and loading components
|
402
|
+
|
403
|
+
## Rendering CloudFormation templates
|
404
|
+
|
405
|
+
|
406
|
+
|
407
|
+
## Global Extensions
|
408
|
+
|
409
|
+
Any extensions placed within `cfndsl_ext` folder will be
|
410
|
+
available in cfndsl templates of all components. Any extensions placed within `hl_ext` folder are
|
411
|
+
available in highlander templates of all components.
|
data/bin/cfhighlander
ADDED
data/bin/highlander.rb
ADDED
@@ -0,0 +1,158 @@
|
|
1
|
+
####
|
2
|
+
#### highlander publish [component_dir:-$PWD] (defaults to current dir) - (publishes highlander component)
|
3
|
+
#### highlander compile [component_dir:-$PWD] [--format json] - compile component to cloudformation template
|
4
|
+
#### highlander env create --name [stack_name] [component_name@version:-$PWD] create environment out of component (compile, deploy to s3, update)
|
5
|
+
#### highlander env update --name [stack_name] [component_name@version] update environment to component version (compile,deploy to s3, update)
|
6
|
+
#### highlander env delete --name [stack_name]
|
7
|
+
####
|
8
|
+
|
9
|
+
|
10
|
+
require 'thor'
|
11
|
+
require 'rubygems'
|
12
|
+
require_relative '../lib//highlander.compiler'
|
13
|
+
require_relative '../lib/highlander.factory'
|
14
|
+
require_relative '../lib/highlander.publisher'
|
15
|
+
require_relative '../lib/highlander.validator'
|
16
|
+
|
17
|
+
class HighlanderCli < Thor
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
package_name "highlander"
|
22
|
+
|
23
|
+
desc 'configcompile component[@version]', 'Compile Highlander components configuration'
|
24
|
+
|
25
|
+
def configcompile(component_name)
|
26
|
+
|
27
|
+
# find and load component
|
28
|
+
component_loader = Highlander::Factory::ComponentFactory.new
|
29
|
+
component = component_loader.findComponent(component_name)
|
30
|
+
component.load
|
31
|
+
|
32
|
+
# compile cfndsl template
|
33
|
+
component_compiler = Highlander::Compiler::ComponentCompiler.new(component)
|
34
|
+
component_compiler.writeConfig(true)
|
35
|
+
end
|
36
|
+
|
37
|
+
desc 'dslcompile component[@version]', 'Compile Highlander component configuration and create cfndsl templates'
|
38
|
+
method_option :version, :type => :string, :required => false, :default => nil, :aliases => '-v',
|
39
|
+
:desc => 'Version to compile by which subcomponents are referenced'
|
40
|
+
method_option :dstbucket, :type => :string, :required => false, :default => nil,
|
41
|
+
:desc => 'Distribution S3 bucket'
|
42
|
+
method_option :dstprefix, :type => :string, :required => false, :default => nil,
|
43
|
+
:desc => 'Distribution S3 prefix'
|
44
|
+
method_option :format, :type => :string, :required => true, :default => 'yaml', :aliases => "-f",
|
45
|
+
:enum => %w(yaml json), :desc => 'CloudFormation templates output format'
|
46
|
+
method_option :quiet, :type => :boolean, :default => false, :aliases => '-q',
|
47
|
+
:desc => 'Silently agree on user prompts (e.g. Package lambda command)'
|
48
|
+
|
49
|
+
def dslcompile(component_name)
|
50
|
+
component = build_component(options, component_name)
|
51
|
+
|
52
|
+
# compile cfndsl template
|
53
|
+
component_compiler = Highlander::Compiler::ComponentCompiler.new(component)
|
54
|
+
component_compiler.silent_mode = options[:quiet]
|
55
|
+
out_format = options[:format]
|
56
|
+
component_compiler.compileCfnDsl out_format
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
desc 'cfcompile component[@version]', 'Compile Highlander component to CloudFormation templates'
|
61
|
+
method_option :version, :type => :string, :required => false, :default => nil, :aliases => '-v',
|
62
|
+
:desc => 'Version to compile by which subcomponents are referenced'
|
63
|
+
method_option :dstbucket, :type => :string, :required => false, :default => nil,
|
64
|
+
:desc => 'Distribution S3 bucket'
|
65
|
+
method_option :dstprefix, :type => :string, :required => false, :default => nil,
|
66
|
+
:desc => 'Distribution S3 prefix'
|
67
|
+
method_option :format, :type => :string, :required => true, :default => 'yaml', :aliases => "-f",
|
68
|
+
:enum => %w(yaml json), :desc => 'CloudFormation templates output format'
|
69
|
+
method_option :validate, :type => :boolean, :default => false,
|
70
|
+
:desc => 'Optionally validate template'
|
71
|
+
method_option :quiet, :type => :boolean, :default => false, :aliases => '-q',
|
72
|
+
:desc => 'Silently agree on user prompts (e.g. Package lambda command)'
|
73
|
+
|
74
|
+
def cfcompile(component_name)
|
75
|
+
component = build_component(options, component_name)
|
76
|
+
|
77
|
+
# compile cloud formation
|
78
|
+
component_compiler = Highlander::Compiler::ComponentCompiler.new(component)
|
79
|
+
component_compiler.silent_mode = options[:quiet]
|
80
|
+
out_format = options[:format]
|
81
|
+
component_compiler.compileCloudFormation out_format
|
82
|
+
if options[:validate]
|
83
|
+
component_validator = Highlander::Cloudformation::Validator.new(component)
|
84
|
+
component_validator.validate(component_compiler.cfn_template_paths, out_format)
|
85
|
+
end
|
86
|
+
component_compiler
|
87
|
+
end
|
88
|
+
|
89
|
+
desc 'cfpublish component[@version]', 'Publish CloudFormation template for component,
|
90
|
+
and it\' referenced subcomponents'
|
91
|
+
method_option :version, :type => :string, :required => false, :default => nil, :aliases => '-v',
|
92
|
+
:desc => 'Version to compile by which subcomponents are referenced'
|
93
|
+
method_option :dstbucket, :type => :string, :required => false, :default => nil,
|
94
|
+
:desc => 'Distribution S3 bucket'
|
95
|
+
method_option :dstprefix, :type => :string, :required => false, :default => nil,
|
96
|
+
:desc => 'Distribution S3 prefix'
|
97
|
+
method_option :format, :type => :string, :required => true, :default => 'yaml', :aliases => "-f",
|
98
|
+
:enum => %w(yaml json), :desc => 'CloudFormation templates output format'
|
99
|
+
method_option :validate, :type => :boolean, :default => false,
|
100
|
+
:desc => 'Optionally validate template'
|
101
|
+
method_option :quiet, :type => :boolean, :default => false, :aliases => '-q',
|
102
|
+
:desc => 'Silently agree on user prompts (e.g. Package lambda command)'
|
103
|
+
|
104
|
+
def cfpublish(component_name)
|
105
|
+
compiler = cfcompile(component_name)
|
106
|
+
publisher = Highlander::Publisher::Component.new(compiler.component, false)
|
107
|
+
publisher.publishFiles(compiler.cfn_template_paths + compiler.lambda_src_paths)
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
desc 'publish component[@version] [-v published_version]', 'Publish CloudFormation template for component,
|
112
|
+
and it\'s referenced subcomponents'
|
113
|
+
method_option :dstbucket, :type => :string, :required => false, :default => nil,
|
114
|
+
:desc => 'Distribution S3 bucket'
|
115
|
+
method_option :dstprefix, :type => :string, :required => false, :default => nil,
|
116
|
+
:desc => 'Distribution S3 prefix'
|
117
|
+
method_option :version, :type => :string, :required => false, :default => nil, :aliases => '-v',
|
118
|
+
:desc => 'Distribution component version, defaults to latest'
|
119
|
+
|
120
|
+
def publish(component_name)
|
121
|
+
component_version = options[:version]
|
122
|
+
distribution_bucket = options[:dstbucket]
|
123
|
+
distribution_prefix = options[:dstprefix]
|
124
|
+
|
125
|
+
# find and load component
|
126
|
+
component_loader = Highlander::Factory::ComponentFactory.new
|
127
|
+
component = component_loader.findComponent(component_name)
|
128
|
+
component.version = component_version
|
129
|
+
component.distribution_bucket = distribution_bucket unless distribution_bucket.nil?
|
130
|
+
component.distribution_prefix = distribution_prefix unless distribution_prefix.nil?
|
131
|
+
component.load
|
132
|
+
|
133
|
+
publisher = Highlander::Publisher::Component.new(component, true)
|
134
|
+
publisher.publishComponent
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
# build component from passed cli options
|
140
|
+
def build_component(options, component_name)
|
141
|
+
if ENV['HIGHLANDER_WORKDIR'].nil?
|
142
|
+
ENV['HIGHLANDER_WORKDIR'] = Dir.pwd
|
143
|
+
end
|
144
|
+
component_version = options[:version]
|
145
|
+
distribution_bucket = options[:dstbucket]
|
146
|
+
distribution_prefix = options[:dstprefix]
|
147
|
+
|
148
|
+
# find and load component
|
149
|
+
component_loader = Highlander::Factory::ComponentFactory.new
|
150
|
+
component = component_loader.findComponent(component_name)
|
151
|
+
component.version = component_version unless component_version.nil?
|
152
|
+
component.distribution_bucket = distribution_bucket unless distribution_bucket.nil?
|
153
|
+
component.distribution_prefix = distribution_prefix unless distribution_prefix.nil?
|
154
|
+
component.load
|
155
|
+
component
|
156
|
+
end
|
157
|
+
|
158
|
+
HighlanderCli.start
|