sparkle_formation 1.0.4 → 1.1.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 +5 -0
- data/docs/README.md +28 -0
- data/docs/anatomy.md +205 -0
- data/docs/building-blocks.md +360 -0
- data/docs/compile-time-parameters.md +182 -0
- data/docs/helper-methods.md +157 -0
- data/docs/nested-stacks.md +425 -0
- data/docs/overview.md +54 -0
- data/docs/sparkle-packs.md +211 -0
- data/docs/sparkleformation-dsl.md +303 -0
- data/docs/stack-policies.md +90 -0
- data/docs/translation.md +64 -0
- data/docs/v/0.3.2/marked.js +1272 -0
- data/docs/v/bootstrap.min.css +7 -0
- data/docs/v/finalizer.css +6 -0
- data/docs/v/highlight.min.css +1 -0
- data/docs/v/highlight.min.js +2 -0
- data/docs/v/jquery-2.1.3.min.js +4 -0
- data/docs/v/loader.js +34 -0
- data/lib/sparkle_formation/sparkle.rb +4 -0
- data/lib/sparkle_formation/sparkle_formation.rb +75 -14
- data/lib/sparkle_formation/sparkle_struct.rb +17 -0
- data/lib/sparkle_formation/version.rb +1 -1
- data/sparkle_formation.gemspec +1 -1
- metadata +21 -4
@@ -0,0 +1,303 @@
|
|
1
|
+
---
|
2
|
+
title: "SparkleFormation DSL"
|
3
|
+
category: "dsl"
|
4
|
+
weight: 2
|
5
|
+
anchors:
|
6
|
+
- title: "Behavior"
|
7
|
+
url: "#behavior"
|
8
|
+
- title: "Key Alteration"
|
9
|
+
url: "#key-alteration"
|
10
|
+
- title: "Data Access"
|
11
|
+
url: "#data-access"
|
12
|
+
---
|
13
|
+
|
14
|
+
## SparkleFormation DSL
|
15
|
+
|
16
|
+
The SparkleFormation DSL (domain specific language) is based
|
17
|
+
on (and built on top of) the [AttributeStruct](https://github.com/chrisroberts/attribute_struct)
|
18
|
+
library. This provides SparkleFormation with its free-form behavior
|
19
|
+
and allows immediate support of any template style or API
|
20
|
+
updates requiring modifications to existing templates.
|
21
|
+
|
22
|
+
For a closer look at the underlying features provided by
|
23
|
+
the AttributeStruct library, please refer to the
|
24
|
+
[AttributeStruct documentation](https://chrisroberts.github.io/attribute_struct).
|
25
|
+
|
26
|
+
### Behavior
|
27
|
+
|
28
|
+
The behavior of the SparkleFormation DSL is largely dictated by the
|
29
|
+
AttributeStruct library, and as such are not specific to SparkleFormation
|
30
|
+
alone. Some optional features of the AttributeStruct library are automatically
|
31
|
+
enabled when using SparkleFormation, most notably the automatic camel casing
|
32
|
+
of key values.
|
33
|
+
|
34
|
+
#### Key Alteration
|
35
|
+
|
36
|
+
The default behavior of SparkleFormation is to camel case all Hash keys.
|
37
|
+
This is done via:
|
38
|
+
|
39
|
+
~~~ruby
|
40
|
+
AttributeStruct.camel_keys = true
|
41
|
+
~~~
|
42
|
+
|
43
|
+
And results in all Hash keys in the resultant compile Hash being converted
|
44
|
+
to a camel cased format:
|
45
|
+
|
46
|
+
~~~ruby
|
47
|
+
SparkleFormation.new(:test) do
|
48
|
+
parameters.creator.default 'spox'
|
49
|
+
end
|
50
|
+
~~~
|
51
|
+
|
52
|
+
The resultant data structure after compiling:
|
53
|
+
|
54
|
+
~~~ruby
|
55
|
+
{
|
56
|
+
"Parameters": {
|
57
|
+
"Creator": {
|
58
|
+
"Default": "spox"
|
59
|
+
}
|
60
|
+
}
|
61
|
+
}
|
62
|
+
~~~
|
63
|
+
|
64
|
+
In some cases it may be desired to have a key _not_
|
65
|
+
be automatically camel cased. Camel casing can be
|
66
|
+
disabled via a helper method that is attached to the
|
67
|
+
Symbol and String instances:
|
68
|
+
|
69
|
+
~~~ruby
|
70
|
+
SparkleFormation.new(:test) do
|
71
|
+
parameters.set!(:creator.disable_camel!).default 'spox'
|
72
|
+
end
|
73
|
+
~~~
|
74
|
+
|
75
|
+
The resultant data structure after compiling:
|
76
|
+
|
77
|
+
~~~ruby
|
78
|
+
{
|
79
|
+
"Parameters": {
|
80
|
+
"creator": {
|
81
|
+
"Default": "spox"
|
82
|
+
}
|
83
|
+
}
|
84
|
+
}
|
85
|
+
~~~
|
86
|
+
|
87
|
+
Depending on the formatting of the target template there
|
88
|
+
may be lack of consistency within certain locations. A
|
89
|
+
classic example of this inconsistency can be seen in the
|
90
|
+
`AWS::CloudFormation::Init` metadata section on compute
|
91
|
+
type resources. Within the context of this `Init` section
|
92
|
+
the format of the keys change from the standard camel casing
|
93
|
+
to a snake cased format. It is possible to handle this by using
|
94
|
+
the `disable_camel!` method for all defined keys, but it is
|
95
|
+
clunky and reduces the readability of the code.
|
96
|
+
|
97
|
+
As the data structure is built when compiling the SparkleFormation
|
98
|
+
template state is tracked at each "level" of the data structure.
|
99
|
+
When the camel casing is enabled on AttributeStruct, this is merely
|
100
|
+
the default behavior and can be overridden, even from within
|
101
|
+
the DSL. For example:
|
102
|
+
|
103
|
+
~~~ruby
|
104
|
+
SparkleFormation.new(:test) do
|
105
|
+
parameters do
|
106
|
+
camel_keys_set!(:auto_disable)
|
107
|
+
creator.default 'spox'
|
108
|
+
end
|
109
|
+
outputs.creator.value ref!(:creator.disable_camel!)
|
110
|
+
end
|
111
|
+
~~~
|
112
|
+
|
113
|
+
The resultant data structure after compiling:
|
114
|
+
|
115
|
+
~~~ruby
|
116
|
+
{
|
117
|
+
"Parameters": {
|
118
|
+
"creator": {
|
119
|
+
"default": "spox"
|
120
|
+
}
|
121
|
+
},
|
122
|
+
"Outputs": {
|
123
|
+
"Value": {
|
124
|
+
"Ref": "creator"
|
125
|
+
}
|
126
|
+
}
|
127
|
+
}
|
128
|
+
~~~
|
129
|
+
|
130
|
+
This example shows how the behavior of the Hash key modification
|
131
|
+
can be altered at a specific context within the data structure.
|
132
|
+
New values added (as well as nested) will not the camel casing
|
133
|
+
modification applied. The behavior can be adjusted at multiple
|
134
|
+
depth locations, and that behavior will persist on re-entry:
|
135
|
+
|
136
|
+
~~~ruby
|
137
|
+
SparkleFormation.new(:test) do
|
138
|
+
parameters do
|
139
|
+
camel_keys_set!(:auto_disable)
|
140
|
+
creator do
|
141
|
+
camel_keys_set!(:auto_enable)
|
142
|
+
default 'spox'
|
143
|
+
end
|
144
|
+
end
|
145
|
+
outputs.creator.value ref!(:creator.disable_camel!)
|
146
|
+
parameters.creator.type 'String'
|
147
|
+
parameters.author.default 'John Doe'
|
148
|
+
end
|
149
|
+
~~~
|
150
|
+
|
151
|
+
The resultant data structure after compiling:
|
152
|
+
|
153
|
+
~~~ruby
|
154
|
+
{
|
155
|
+
"Parameters": {
|
156
|
+
"creator": {
|
157
|
+
"Default": "spox",
|
158
|
+
"Type": "String"
|
159
|
+
},
|
160
|
+
"author": {
|
161
|
+
"default": "John Doe"
|
162
|
+
}
|
163
|
+
},
|
164
|
+
"Outputs": {
|
165
|
+
"Value": {
|
166
|
+
"Ref": "creator"
|
167
|
+
}
|
168
|
+
}
|
169
|
+
}
|
170
|
+
~~~
|
171
|
+
|
172
|
+
### Features
|
173
|
+
|
174
|
+
#### Data Access
|
175
|
+
|
176
|
+
As a SparkleFormation template is compiled it is dynamically
|
177
|
+
building the data structure defined by the template. Because
|
178
|
+
this data structure is being generated during compilation, the
|
179
|
+
template itself has access to this data and can inspect the
|
180
|
+
state of the data structure as it exists _at that specific
|
181
|
+
time_. This allows for inspecting previously defined data
|
182
|
+
and using that data for decision making, or to copy/modify into
|
183
|
+
other locations.
|
184
|
+
|
185
|
+
##### Local Context Data
|
186
|
+
|
187
|
+
When using block style syntax in the DSL an optional parameter
|
188
|
+
can be defined for the block. If provided, AttributeStruct will
|
189
|
+
pass the local AttributeStruct instance to the block when it
|
190
|
+
is executed:
|
191
|
+
|
192
|
+
~~~ruby
|
193
|
+
SparkleFormation.new(:test) do
|
194
|
+
parameters.creator.default 'spox'
|
195
|
+
parameters do |params|
|
196
|
+
author.default params.creator.default
|
197
|
+
end
|
198
|
+
end
|
199
|
+
~~~
|
200
|
+
|
201
|
+
The resultant data structure after compiling:
|
202
|
+
|
203
|
+
~~~ruby
|
204
|
+
{
|
205
|
+
"Parameters": {
|
206
|
+
"Creator": {
|
207
|
+
"Default": "spox"
|
208
|
+
},
|
209
|
+
"Author": {
|
210
|
+
"Default": "spox"
|
211
|
+
}
|
212
|
+
}
|
213
|
+
}
|
214
|
+
~~~
|
215
|
+
|
216
|
+
##### Parent Context Data
|
217
|
+
|
218
|
+
It is possible to access the parent context data from the current
|
219
|
+
context:
|
220
|
+
|
221
|
+
~~~ruby
|
222
|
+
SparkleFormation.new(:test) do
|
223
|
+
parameters.creator.default 'spox'
|
224
|
+
parameters.author do
|
225
|
+
default parent!.creator.default
|
226
|
+
end
|
227
|
+
end
|
228
|
+
~~~
|
229
|
+
|
230
|
+
The resultant data structure after compiling:
|
231
|
+
|
232
|
+
~~~ruby
|
233
|
+
{
|
234
|
+
"Parameters": {
|
235
|
+
"Creator": {
|
236
|
+
"Default": "spox"
|
237
|
+
},
|
238
|
+
"Author": {
|
239
|
+
"Default": "spox"
|
240
|
+
}
|
241
|
+
}
|
242
|
+
}
|
243
|
+
~~~
|
244
|
+
|
245
|
+
|
246
|
+
##### Root Context Data
|
247
|
+
|
248
|
+
It is possible to access the root context data from the current
|
249
|
+
context:
|
250
|
+
|
251
|
+
~~~ruby
|
252
|
+
SparkleFormation.new(:test) do
|
253
|
+
parameters.creator.default 'spox'
|
254
|
+
parameters.author.default root!.parameters.creator.default
|
255
|
+
end
|
256
|
+
~~~
|
257
|
+
|
258
|
+
The resultant data structure after compiling:
|
259
|
+
|
260
|
+
~~~ruby
|
261
|
+
{
|
262
|
+
"Parameters": {
|
263
|
+
"Creator": {
|
264
|
+
"Default": "spox"
|
265
|
+
},
|
266
|
+
"Author": {
|
267
|
+
"Default": "spox"
|
268
|
+
}
|
269
|
+
}
|
270
|
+
}
|
271
|
+
~~~
|
272
|
+
|
273
|
+
##### Raw Access
|
274
|
+
|
275
|
+
The raw Hash instance holding the data of the current context
|
276
|
+
can be reached using the `data!` method:
|
277
|
+
|
278
|
+
~~~ruby
|
279
|
+
SparkleFormation.new(:test) do
|
280
|
+
parameters.creator.default 'spox'
|
281
|
+
if(data!['Creator'].default == 'spox')
|
282
|
+
parameters.author.default 'xops'
|
283
|
+
end
|
284
|
+
end
|
285
|
+
~~~
|
286
|
+
|
287
|
+
The resultant data structure after compiling:
|
288
|
+
|
289
|
+
~~~ruby
|
290
|
+
{
|
291
|
+
"Parameters": {
|
292
|
+
"Creator": {
|
293
|
+
"Default": "spox"
|
294
|
+
},
|
295
|
+
"Author": {
|
296
|
+
"Default": "xops"
|
297
|
+
}
|
298
|
+
}
|
299
|
+
}
|
300
|
+
~~~
|
301
|
+
|
302
|
+
> NOTE: Because `data!` returns a Hash instance, no automatic formatting
|
303
|
+
> (camel case conversions) will be applied to keys when accessing values.
|
@@ -0,0 +1,90 @@
|
|
1
|
+
---
|
2
|
+
title: "Stack Policies"
|
3
|
+
category: "dsl"
|
4
|
+
weight: 8
|
5
|
+
anchors:
|
6
|
+
- title: "Template Usage"
|
7
|
+
url: "#template-usage"
|
8
|
+
- title: "Library Usage"
|
9
|
+
url: "#library-usage"
|
10
|
+
---
|
11
|
+
|
12
|
+
## Stack Policies
|
13
|
+
|
14
|
+
AWS CloudFormation includes support for stack policies. These
|
15
|
+
policies add an extra layer of control that restricts or allows
|
16
|
+
actions to be taken on specific resources within a stack.
|
17
|
+
SparkleFormation includes support for extracting inline stack
|
18
|
+
policy information from SparkleFormation templates which can
|
19
|
+
then be applied to stacks.
|
20
|
+
|
21
|
+
* [AWS CFN Stack Policies](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/protect-stack-resources.html)
|
22
|
+
|
23
|
+
### Template Usage
|
24
|
+
|
25
|
+
Resource policies can be defined within a SparkleFormation
|
26
|
+
template. This allows for policies to be programatically generated
|
27
|
+
in the same manner as the stack template itself.
|
28
|
+
|
29
|
+
~~~ruby
|
30
|
+
template = SparkleFormation.new(:test) do
|
31
|
+
resources.my_resource do
|
32
|
+
policy do
|
33
|
+
allow 'Modify'
|
34
|
+
deny 'Replace'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
~~~
|
39
|
+
|
40
|
+
### Library Usage
|
41
|
+
|
42
|
+
SparkleFormation can extract stack policies from a template after
|
43
|
+
it has been compiled. Once extracted, the policy can be applied
|
44
|
+
to the stack as dictated by the API.
|
45
|
+
|
46
|
+
~~~ruby
|
47
|
+
template = SparkleFormation.new(:test) do
|
48
|
+
resources.my_resource do
|
49
|
+
policy do
|
50
|
+
allow 'Modify'
|
51
|
+
deny 'Replace'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
policy = template.generate_policy
|
57
|
+
~~~
|
58
|
+
|
59
|
+
This generates a policy data structure:
|
60
|
+
|
61
|
+
~~~ruby
|
62
|
+
{
|
63
|
+
"Statement" => [
|
64
|
+
{
|
65
|
+
"Effect" => "Allow",
|
66
|
+
"Action" => [
|
67
|
+
"Update:*"
|
68
|
+
],
|
69
|
+
"Resource" => "*",
|
70
|
+
"Principal" => "*"
|
71
|
+
},
|
72
|
+
{
|
73
|
+
"Effect" => "Allow",
|
74
|
+
"Action" => [
|
75
|
+
"Update:Modify"
|
76
|
+
],
|
77
|
+
"Resource" => "LogicalResourceId/MyResource",
|
78
|
+
"Principal" => "*"
|
79
|
+
},
|
80
|
+
{
|
81
|
+
"Effect" => "Deny",
|
82
|
+
"Action" => [
|
83
|
+
"Update:Replace"
|
84
|
+
],
|
85
|
+
"Resource" => "LogicalResourceId/MyResource",
|
86
|
+
"Principal" => "*"
|
87
|
+
}
|
88
|
+
]
|
89
|
+
}
|
90
|
+
~~~
|
data/docs/translation.md
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
---
|
2
|
+
title: "Translation"
|
3
|
+
category: "dsl"
|
4
|
+
weight: 9
|
5
|
+
anchors:
|
6
|
+
- title: "Supported Translations"
|
7
|
+
url: "#supported-translations"
|
8
|
+
- title: "Usage"
|
9
|
+
url: "#usage"
|
10
|
+
---
|
11
|
+
|
12
|
+
## Translation
|
13
|
+
|
14
|
+
SparkleFormation has alpha support for template translation from
|
15
|
+
AWS CFN to target orchestration API template formats.
|
16
|
+
|
17
|
+
> NOTE: Translations do not currently support stack nesting functionality
|
18
|
+
|
19
|
+
### Supported Translations
|
20
|
+
|
21
|
+
Basic support implementations:
|
22
|
+
|
23
|
+
* OpenStack
|
24
|
+
* Rackspace
|
25
|
+
|
26
|
+
### Usage
|
27
|
+
|
28
|
+
Translations are based around AWS CFN and then target some
|
29
|
+
remote orchestration API (currently Heat and Rackspace). First
|
30
|
+
the template must be compiled, then it is passed to the translator
|
31
|
+
which converts the CFN specific template to the expected format
|
32
|
+
of the target API:
|
33
|
+
|
34
|
+
~~~ruby
|
35
|
+
sfn = SparkleFormation.new(:my_stack) do
|
36
|
+
...
|
37
|
+
end
|
38
|
+
|
39
|
+
cfn_template = sfn.compile.dump!
|
40
|
+
translator = SparkleFormation::Translation::Heat.new(cfn_template)
|
41
|
+
|
42
|
+
heat_template = translator.translate!
|
43
|
+
~~~
|
44
|
+
|
45
|
+
In general applications of translators, the implementation will
|
46
|
+
first collect optional template parameters prior to translation
|
47
|
+
allowing the translator access to parameters that may be required
|
48
|
+
in places where the resultant template may not have support for
|
49
|
+
dynamic references. These can then be passed to the translator:
|
50
|
+
|
51
|
+
~~~ruby
|
52
|
+
sfn = SparkleFormation.new(:my_stack) do
|
53
|
+
...
|
54
|
+
end
|
55
|
+
|
56
|
+
cfn_template = sfn.compile.dump!
|
57
|
+
custom_params = collect_parameters(cfn_template)
|
58
|
+
translator = SparkleFormation::Translation::Heat.new(
|
59
|
+
cfn_template,
|
60
|
+
:parameters => custom_params
|
61
|
+
)
|
62
|
+
|
63
|
+
heat_template = translator.translate!
|
64
|
+
~~~
|