sparkle_formation 2.1.8 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9afdab094c6cd47a509662f18ad290fc743d2ee9
4
- data.tar.gz: 20e9e353dae5fa25db4b3415b33622bac16058f8
3
+ metadata.gz: 1d032f4e99137cc1d2cedff18a9d3cd1d9ed3ffc
4
+ data.tar.gz: ef8783a42ab4ac91f344db64ee884ec3a568d616
5
5
  SHA512:
6
- metadata.gz: fe65169a0f63eca6043542891a2f44b90935cd243d2ec56d7fc5b04ca6ad9f18796aa9d11f2d47d8800e9253126121111b9741b38ec6d8885a1b1653e2914312
7
- data.tar.gz: 3ad051b35500b4f0782f3e5d41a39b9b1c79fa1efaf76b70eaf4776ce1dd3d00d8c9c12b41aed4ebaada43dfa6bc368895e839b5a1bd4bd91f84140d8628d6aa
6
+ metadata.gz: 015d1daa74bb173669757e8e88d41f3e43009d6f046668c0f9a45bea175be16743a9007001136172a1e39b6d7f6ab6ba82b1eacf776f0b286c129ac4babc068b
7
+ data.tar.gz: c43367d2255f83fedc4861303bff7be56349dd636017de2a60e0ccc1c3537e90ac6eb1980ce1f357e6035a072fb4c22de7f2db2d10eef8213caeb16d6ba8cf4e
data/CHANGELOG.md CHANGED
@@ -1,3 +1,20 @@
1
+ # v3.0.0
2
+ _Major release includes breaking changes!_
3
+ * Builtin provider resources updates (#163)
4
+ * New Resource and Propery types
5
+ * Support for conditional logic to determine property modification effect
6
+ * New provider Google (#167)
7
+ * Inject nested stacks using dynamic style insertion (#167)
8
+ * Add sparkle aliases for dumps to allow non-provider formatted template dumps (#167)
9
+ * Allow sparkle pack to load as empty pack (#167)
10
+ * Generate nested stack resource name using key processing style of current context (#167)
11
+ * SparkleFormation#apply_nesting now returns compiled structure not Hash (#167)
12
+ * SparkleFormation#stack_template_extractor now sets compiled structure not Hash (#167)
13
+ * Remove helper method aliasing in Azure module to work on Ruby 2.3 (#170)
14
+ * Implement provider restrictions and naming uniqueness (#169)
15
+
16
+ _NOTE: If using non-AWS provider, files must be updated to include `:provider` flag._
17
+
1
18
  # v2.1.8
2
19
  * Add support for CFN list type with shallow nesting (#150)
3
20
  * Fix deprecation warnings on Ruby 2.3 caused by TimeoutError constant
data/docs/README.md CHANGED
@@ -22,6 +22,7 @@
22
22
  - [Nested Stacks](nested-stacks.md)
23
23
  - [Shallow Nesting](nested-stacks.md#shallow-nesting)
24
24
  - [Deep Nesting](nested-stacks.md#deep-nesting)
25
+ - [Provider Restrictions](provider-restrictions.md)
25
26
  - [Sparkle Packs](sparkle-packs.md)
26
27
  - [Stack Policies](stack-policies.md)
27
28
  - [Translation](translation.md)
@@ -155,5 +155,6 @@ to the library documentation:
155
155
 
156
156
  * [AWS helpers](http://sparkleformation.github.io/sparkle_formation/SparkleFormation/SparkleAttribute/Aws.html)
157
157
  * [Azure helpers](http://sparkleformation.github.io/sparkle_formation/SparkleFormation/SparkleAttribute/Azure.html)
158
+ * [Google helpers](http://sparkleformation.github.io/sparkle_formation/SparkleFormation/SparkleAttribute/Google.html)
158
159
  * [HEAT helpers](http://sparkleformation.github.io/sparkle_formation/SparkleFormation/SparkleAttribute/Heat.html)
159
160
  * [Rackspace helpers](http://sparkleformation.github.io/sparkle_formation/SparkleFormation/SparkleAttribute/Rackspace.html)
@@ -0,0 +1,174 @@
1
+ ---
2
+ title: "Provider Restrictions"
3
+ category: "dsl"
4
+ weight: 9
5
+ anchors:
6
+ - title: "Provider Restrictions"
7
+ url: "#provider-restrictions"
8
+ - title: "Setting Provider Restrictions"
9
+ url: "#setting-provider-restrictions"
10
+ - title: "Building Block Uniqueness"
11
+ url: "#building-block-uniqueness"
12
+ - title: "Sharing Building Blocks"
13
+ url: "#sharing-building-blocks"
14
+ ---
15
+
16
+ ## Provider Restrictions
17
+
18
+ SparkleFormation supports generating templates for multiple
19
+ orchestration APIs. By default all building blocks are assigned
20
+ `:aws` as a provider. As a template is compiled and building
21
+ block items are requested, the provider restriction is enforced
22
+ during lookup. This restriction helps to enforce correctly structured
23
+ template by only allowing building blocks with like providers to
24
+ interact with each other ensuring a properly compiled template.
25
+
26
+ ## Setting Provider Restriction
27
+
28
+ Provider restrictions are set using a common pattern among all
29
+ building blocks:
30
+
31
+ ### Template
32
+
33
+ ~~~ruby
34
+ SparkleFormation.new(:my_template, :provider => :azure) do
35
+ ...
36
+ ~~~
37
+
38
+ ### Component
39
+
40
+ ~~~ruby
41
+ SparkleFormation.component(:my_component, :provider => :azure) do
42
+ ...
43
+ ~~~
44
+
45
+ ### Dynamic
46
+
47
+ ~~~ruby
48
+ SparkleFormation.dynamic(:my_dynamic, :provider => :azure) do
49
+ ...
50
+ ~~~
51
+
52
+ ### Registry
53
+
54
+ ~~~ruby
55
+ SfnRegistry.register(:my_item, :provider => :azure) do
56
+ ...
57
+ ~~~
58
+
59
+ ## Building Block Uniqueness
60
+
61
+ ### Name Collision Failure
62
+
63
+ The uniqueness of a building block is based on the combination of
64
+ the building block's name and defined provider. This allows common
65
+ naming schemes to be applied for multiple providers within the same
66
+ runtime. For example, given a template named `:network` defined
67
+ as:
68
+
69
+ ~~~ruby
70
+ SparkleFormation.new(:network) do
71
+ ...
72
+ ~~~
73
+
74
+ the uniqueness of this template is defined by `:network` within
75
+ the `:aws` provider (because the `:aws` provider is the default). This
76
+ means that defining another template with the provider explicitly defined
77
+ for `:aws` will fail:
78
+
79
+ ~~~ruby
80
+ SparkleFormation.new(:network, :provider => :aws) do
81
+ ...
82
+ ~~~
83
+
84
+ The failure is due to the fact that the names of these two templates is
85
+ effectively equivalent.
86
+
87
+ ### Common Name Unique Provider
88
+
89
+ Using the previous example of a `:network` template, we can define our
90
+ template and explicitly set the provider for clarity:
91
+
92
+ ~~~ruby
93
+ SparkleFormation.new(:network, :provider => :aws) do
94
+ ...
95
+ ~~~
96
+
97
+ Now if we want to provide a template for a different provider (OpenStack
98
+ for instance) we can use the same template name but specify a different
99
+ target provider:
100
+
101
+ ~~~ruby
102
+ SparkleFormation.new(:network, :provider => :heat) do
103
+ ...
104
+ ~~~
105
+
106
+ Two templates with a common name (`:network`) now exist within our runtime
107
+ because while the name is common, the providers are different. This functionality
108
+ applies to all the SparkleFormation building blocks and is important for allowing
109
+ a common interface for user interactions while allowing provider specific implementations.
110
+
111
+ ## Sharing Building Blocks
112
+
113
+ Building blocks may not always need to be restricted to a specific provider. The
114
+ provider value used for building block lookup can be overridden. Using this
115
+ override functionality allows for sharing building blocks between providers. For
116
+ example, lets define a pseudo-template for AWS that sets a value using a registry
117
+ item:
118
+
119
+ ~~~ruby
120
+ SfnRegistry.register(:creator) do
121
+ 'spox'
122
+ end
123
+ ~~~
124
+
125
+ ~~~ruby
126
+ SparkleFormation.new(:template) do
127
+ owner registry!(:creator)
128
+ end
129
+ ~~~
130
+
131
+ Now if the same pseudo-template with a provider set to `:azure` is defined:
132
+
133
+ ~~~ruby
134
+ SparkleFormation.new(:template, :provider => :azure) do
135
+ owner registry!(:creator)
136
+ end
137
+ ~~~
138
+
139
+ it will fail. The failure is due to the implicitly set provider (`:aws`) on the registry
140
+ item. To allow sharing of the registry item, we _can_ override the lookup to use
141
+ `:aws` as the provider:
142
+
143
+ ~~~ruby
144
+ SparkleFormation.new(:template, :provider => :azure) do
145
+ owner registry!(:creator, :provider => :aws)
146
+ end
147
+ ~~~
148
+
149
+ but this doesn't make logical sense within the layout as the registry item itself
150
+ isn't restricted to the AWS provider in any way. A better approach would be defining
151
+ a shared provider and using that value for the override. Refactoring would provide
152
+ a registry item:
153
+
154
+ ~~~ruby
155
+ SfnRegistry.register(:creator, :provider => :shared) do
156
+ 'spox'
157
+ end
158
+ ~~~
159
+
160
+ With the provider set, the two templates can now be updated to use the override:
161
+
162
+ ~~~ruby
163
+ SparkleFormation.new(:template) do
164
+ owner registry!(:creator, :provider => :shared)
165
+ end
166
+ ~~~
167
+
168
+ and:
169
+
170
+ ~~~ruby
171
+ SparkleFormation.new(:template, :provider => :azure) do
172
+ owner registry!(:creator, :provider => :shared)
173
+ end
174
+ ~~~
data/docs/translation.md CHANGED
@@ -9,6 +9,9 @@ anchors:
9
9
  url: "#usage"
10
10
  ---
11
11
 
12
+ _WARNING: Translations of templates between providers is no longer
13
+ being actively developed._
14
+
12
15
  ## Translation
13
16
 
14
17
  SparkleFormation has alpha support for template translation from
@@ -26,6 +26,9 @@ class SparkleFormation
26
26
  autoload :Composition, 'sparkle_formation/composition'
27
27
  autoload :Error, 'sparkle_formation/error'
28
28
  autoload :FunctionStruct, 'sparkle_formation/function_struct'
29
+ autoload :GoogleStruct, 'sparkle_formation/function_struct'
30
+ autoload :JinjaExpressionStruct, 'sparkle_formation/function_struct'
31
+ autoload :JinjaStatementStruct, 'sparkle_formation/function_struct'
29
32
  autoload :Provider, 'sparkle_formation/provider'
30
33
  autoload :Resources, 'sparkle_formation/resources'
31
34
  autoload :Sparkle, 'sparkle_formation/sparkle'
@@ -58,7 +58,11 @@ class SparkleFormation
58
58
  # @param val [Integer, String]
59
59
  # @return [FunctionStruct]
60
60
  def [](val)
61
- _set("[#{val}]")
61
+ if(val.is_a?(::String) && __single_quote_strings)
62
+ _set("['#{val}']")
63
+ else
64
+ _set("[#{val.inspect}]")
65
+ end
62
66
  end
63
67
 
64
68
  # Override of the dump to properly format eval string
@@ -80,14 +84,14 @@ class SparkleFormation
80
84
  arg._dump
81
85
  elsif(arg.is_a?(::Symbol))
82
86
  "'#{::Bogo::Utility.camel(arg.to_s, false)}'"
83
- elsif(arg.is_a?(::String))
87
+ elsif(arg.is_a?(::String) && __single_quote_strings)
84
88
  "'#{arg}'"
85
89
  else
86
90
  arg.inspect
87
91
  end
88
92
  end.join(', ')
89
93
  unless(_fn_name.to_s.empty?)
90
- function_name = args.empty? ? "#{_fn_name}()" : "#{_fn_name}(#{args})"
94
+ function_name = args.empty? ? "#{_fn_name}#{__empty_argument_list}" : "#{_fn_name}(#{args})"
91
95
  end
92
96
  internal = _eval_join(
93
97
  *[
@@ -95,7 +99,7 @@ class SparkleFormation
95
99
  suffix
96
100
  ].compact
97
101
  )
98
- root? ? "[#{internal}]" : internal
102
+ root? ? "#{__anchor_start}#{internal}#{__anchor_stop}" : internal
99
103
  else
100
104
  suffix
101
105
  end
@@ -122,5 +126,129 @@ class SparkleFormation
122
126
  ::SparkleFormation::FunctionStruct
123
127
  end
124
128
 
129
+ # @return [String] start character(s) used to anchor function call
130
+ def __anchor_start
131
+ '['
132
+ end
133
+
134
+ # @return [String] stop character(s) used to anchor function call
135
+ def __anchor_stop
136
+ ']'
137
+ end
138
+
139
+ # @return [String] value to use when argument list is empty
140
+ def __empty_argument_list
141
+ '()'
142
+ end
143
+
144
+ # @return [String] dump from root
145
+ def to_s
146
+ _root._dump
147
+ end
148
+
149
+ # @return [String] dump from root
150
+ def inspect
151
+ _root._dump
152
+ end
153
+
154
+ # @return [TrueClass] enable single quote string generation
155
+ def __single_quote_strings
156
+ true
157
+ end
158
+
159
+ end
160
+
161
+ # FunctionStruct for jinja expressions
162
+ class JinjaExpressionStruct < FunctionStruct
163
+
164
+ SINGLE_QUOTE_STRINGS = false
165
+
166
+ # @return [String] start character(s) used to anchor function call
167
+ def __anchor_start
168
+ '{{ '
169
+ end
170
+
171
+ # @return [String] stop character(s) used to anchor function call
172
+ def __anchor_stop
173
+ ' }}'
174
+ end
175
+
176
+ # @return [String] value to use when argument list is empty
177
+ def __empty_argument_list
178
+ ''
179
+ end
180
+
181
+ # @return [FalseClass] disable single quote string generation
182
+ def __single_quote_strings
183
+ false
184
+ end
185
+
186
+ # @return [Class]
187
+ def _klass
188
+ ::SparkleFormation::JinjaExpressionStruct
189
+ end
190
+
191
+ end
192
+
193
+ # FunctionStruct for jinja statements
194
+ class JinjaStatementStruct < FunctionStruct
195
+
196
+ SINGLE_QUOTE_STRINGS = false
197
+
198
+ # @return [String] start character(s) used to anchor function call
199
+ def __anchor_start
200
+ '{% '
201
+ end
202
+
203
+ # @return [String] stop character(s) used to anchor function call
204
+ def __anchor_stop
205
+ ' %}'
206
+ end
207
+
208
+ # @return [String] value to use when argument list is empty
209
+ def __empty_argument_list
210
+ ''
211
+ end
212
+
213
+ # @return [FalseClass] disable single quote string generation
214
+ def __single_quote_strings
215
+ false
216
+ end
217
+
218
+ # @return [Class]
219
+ def _klass
220
+ ::SparkleFormation::JinjaStatementStruct
221
+ end
222
+
223
+ end
224
+
225
+ # FunctionStruct for customized google functions
226
+ class GoogleStruct < FunctionStruct
227
+
228
+ # @return [String] start character(s) used to anchor function call
229
+ def __anchor_start
230
+ '$('
231
+ end
232
+
233
+ # @return [String] stop character(s) used to anchor function call
234
+ def __anchor_stop
235
+ ')'
236
+ end
237
+
238
+ # @return [String] value to use when argument list is empty
239
+ def __empty_argument_list
240
+ ''
241
+ end
242
+
243
+ # @return [FalseClass] disable single quote string generation
244
+ def __single_quote_strings
245
+ false
246
+ end
247
+
248
+ # @return [Class]
249
+ def _klass
250
+ ::SparkleFormation::GoogleStruct
251
+ end
252
+
125
253
  end
126
254
  end
@@ -6,6 +6,7 @@ class SparkleFormation
6
6
 
7
7
  autoload :Aws, 'sparkle_formation/provider/aws'
8
8
  autoload :Azure, 'sparkle_formation/provider/azure'
9
+ autoload :Google, 'sparkle_formation/provider/google'
9
10
  autoload :Heat, 'sparkle_formation/provider/heat'
10
11
 
11
12
  end
@@ -47,7 +47,7 @@ class SparkleFormation
47
47
  # @yieldparam resource [AttributeStruct] the stack resource
48
48
  # @yieldparam s_name [String] stack resource name
49
49
  # @yieldreturn [Hash] key/values to be merged into resource properties
50
- # @return [Hash] dumped stack
50
+ # @return [SparkleFormation::SparkleStruct] compiled structure
51
51
  def apply_deep_nesting(*args, &block)
52
52
  outputs = collect_outputs
53
53
  nested_stacks(:with_resource).each do |stack, resource|
@@ -65,7 +65,7 @@ class SparkleFormation
65
65
  if(block_given?)
66
66
  extract_templates(&block)
67
67
  end
68
- compile.dump!
68
+ compile
69
69
  end
70
70
 
71
71
  # Apply shallow nesting. This style of nesting will bubble
@@ -76,7 +76,7 @@ class SparkleFormation
76
76
  # @yieldparam resource_name [String] name of stack resource
77
77
  # @yieldparam stack [SparkleFormation] nested stack
78
78
  # @yieldreturn [String] Remote URL storage for template
79
- # @return [Hash]
79
+ # @return [SparkleFormation::SparkleStruct] compiled structure
80
80
  def apply_shallow_nesting(*args, &block)
81
81
  parameters = compile[:parameters] ? compile[:parameters]._dump : {}
82
82
  output_map = {}
@@ -97,7 +97,7 @@ class SparkleFormation
97
97
  compile.outputs output_hash
98
98
  end
99
99
  end
100
- compile.dump!
100
+ compile
101
101
  end
102
102
 
103
103
  # Extract output to make available for stack parameter usage at the