sparkle_formation 3.0.26 → 3.0.28
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 +5 -5
- data/CHANGELOG.md +6 -0
- data/lib/sparkle_formation/composition.rb +17 -17
- data/lib/sparkle_formation/error.rb +2 -5
- data/lib/sparkle_formation/function_struct.rb +27 -31
- data/lib/sparkle_formation/provider/aws.rb +32 -31
- data/lib/sparkle_formation/provider/azure.rb +18 -19
- data/lib/sparkle_formation/provider/google.rb +20 -22
- data/lib/sparkle_formation/provider/heat.rb +17 -17
- data/lib/sparkle_formation/provider/terraform.rb +14 -15
- data/lib/sparkle_formation/provider.rb +0 -2
- data/lib/sparkle_formation/resources/aws.rb +129 -149
- data/lib/sparkle_formation/resources/aws_resources.json +9208 -5542
- data/lib/sparkle_formation/resources/azure.rb +2 -5
- data/lib/sparkle_formation/resources/azure_resources.json +12367 -2901
- data/lib/sparkle_formation/resources/google.rb +1 -4
- data/lib/sparkle_formation/resources/heat.rb +0 -4
- data/lib/sparkle_formation/resources/heat_resources.json +2616 -2062
- data/lib/sparkle_formation/resources/rackspace.rb +0 -4
- data/lib/sparkle_formation/resources/terraform.rb +2 -6
- data/lib/sparkle_formation/resources.rb +20 -24
- data/lib/sparkle_formation/sparkle.rb +56 -66
- data/lib/sparkle_formation/sparkle_attribute/aws.rb +61 -34
- data/lib/sparkle_formation/sparkle_attribute/azure.rb +12 -8
- data/lib/sparkle_formation/sparkle_attribute/google.rb +18 -15
- data/lib/sparkle_formation/sparkle_attribute/heat.rb +22 -7
- data/lib/sparkle_formation/sparkle_attribute/rackspace.rb +0 -2
- data/lib/sparkle_formation/sparkle_attribute/terraform.rb +11 -5
- data/lib/sparkle_formation/sparkle_attribute.rb +13 -7
- data/lib/sparkle_formation/sparkle_collection/rainbow.rb +5 -7
- data/lib/sparkle_formation/sparkle_collection.rb +13 -15
- data/lib/sparkle_formation/sparkle_formation.rb +116 -112
- data/lib/sparkle_formation/sparkle_struct.rb +30 -24
- data/lib/sparkle_formation/translation/heat.rb +57 -58
- data/lib/sparkle_formation/translation/rackspace.rb +48 -49
- data/lib/sparkle_formation/translation.rb +34 -37
- data/lib/sparkle_formation/utils.rb +6 -13
- data/lib/sparkle_formation/version.rb +1 -1
- data/sparkle_formation.gemspec +1 -1
- metadata +9 -9
@@ -11,21 +11,25 @@ class SparkleFormation
|
|
11
11
|
include SparkleAttribute
|
12
12
|
include SparkleAttribute::Aws
|
13
13
|
end
|
14
|
+
|
14
15
|
# Azure specific struct
|
15
16
|
class Azure < SparkleStruct
|
16
17
|
include SparkleAttribute
|
17
18
|
include SparkleAttribute::Azure
|
18
19
|
end
|
20
|
+
|
19
21
|
# Google specific struct
|
20
22
|
class Google < SparkleStruct
|
21
23
|
include SparkleAttribute
|
22
24
|
include SparkleAttribute::Google
|
23
25
|
end
|
26
|
+
|
24
27
|
# Heat specific struct
|
25
28
|
class Heat < SparkleStruct
|
26
29
|
include SparkleAttribute
|
27
30
|
include SparkleAttribute::Heat
|
28
31
|
end
|
32
|
+
|
29
33
|
OpenStack = Heat
|
30
34
|
Rackspace = Heat
|
31
35
|
# Rackspace specific struct
|
@@ -33,6 +37,7 @@ class SparkleFormation
|
|
33
37
|
include SparkleAttribute
|
34
38
|
include SparkleAttribute::Rackspace
|
35
39
|
end
|
40
|
+
|
36
41
|
# Terraform specific struct
|
37
42
|
class Terraform < SparkleStruct
|
38
43
|
include SparkleAttribute
|
@@ -59,7 +64,7 @@ class SparkleFormation
|
|
59
64
|
# @param inst [SparkleFormation]
|
60
65
|
# @return [SparkleFormation]
|
61
66
|
def _set_self(inst)
|
62
|
-
unless
|
67
|
+
unless inst.is_a?(::SparkleFormation)
|
63
68
|
::Kernel.raise ::TypeError.new "Expecting type of `SparkleFormation` but got `#{inst.class}`"
|
64
69
|
end
|
65
70
|
@self = inst
|
@@ -67,8 +72,8 @@ class SparkleFormation
|
|
67
72
|
|
68
73
|
# @return [SparkleFormation]
|
69
74
|
def _self(*_)
|
70
|
-
unless
|
71
|
-
if
|
75
|
+
unless @self
|
76
|
+
if _parent.nil?
|
72
77
|
::Kernel.raise ::ArgumentError.new 'Creator did not provide return reference!'
|
73
78
|
else
|
74
79
|
_parent._self
|
@@ -84,8 +89,8 @@ class SparkleFormation
|
|
84
89
|
# @param item [Object]
|
85
90
|
# @return [Object]
|
86
91
|
def function_bubbler(item)
|
87
|
-
if
|
88
|
-
if
|
92
|
+
if item.is_a?(::Enumerable)
|
93
|
+
if item.respond_to?(:keys)
|
89
94
|
item.class[
|
90
95
|
*item.map do |entry|
|
91
96
|
function_bubbler(entry)
|
@@ -98,7 +103,7 @@ class SparkleFormation
|
|
98
103
|
end
|
99
104
|
]
|
100
105
|
end
|
101
|
-
elsif
|
106
|
+
elsif item.is_a?(::SparkleFormation::FunctionStruct)
|
102
107
|
item._root
|
103
108
|
else
|
104
109
|
item
|
@@ -108,14 +113,14 @@ class SparkleFormation
|
|
108
113
|
# Override to inspect result value and fetch root if value is a
|
109
114
|
# FunctionStruct
|
110
115
|
def method_missing(sym, *args, &block)
|
111
|
-
if
|
112
|
-
if
|
116
|
+
if sym.is_a?(::String) || sym.is_a?(::Symbol)
|
117
|
+
if sym.to_s.start_with?('_') || sym.to_s.end_with?('!')
|
113
118
|
::Kernel.raise ::NoMethodError.new "Undefined method `#{sym}` for #{_klass.name}"
|
114
119
|
end
|
115
120
|
end
|
116
121
|
super(*[sym, *args], &block)
|
117
|
-
if
|
118
|
-
if(
|
122
|
+
if sym.is_a?(::String) || sym.is_a?(::Symbol)
|
123
|
+
if (s = sym.to_s).end_with?('=')
|
119
124
|
s.slice!(-1, s.length)
|
120
125
|
sym = s
|
121
126
|
end
|
@@ -125,13 +130,13 @@ class SparkleFormation
|
|
125
130
|
end
|
126
131
|
# When setting an AttributeStruct type instance check parent or context if
|
127
132
|
# available and reset if it has been moved.
|
128
|
-
if
|
129
|
-
if
|
130
|
-
if
|
133
|
+
if @table[sym].is_a?(::AttributeStruct)
|
134
|
+
if @table[sym].is_a?(::SparkleFormation::FunctionStruct)
|
135
|
+
if @table[sym].respond_to?(:_fn_context) && @table[sym]._fn_context != self
|
131
136
|
@table[sym] = @table[sym]._clone
|
132
137
|
@table[sym]._fn_context = self
|
133
138
|
end
|
134
|
-
elsif
|
139
|
+
elsif @table[sym]._parent != self
|
135
140
|
@table[sym]._parent(self)
|
136
141
|
end
|
137
142
|
end
|
@@ -151,10 +156,10 @@ class SparkleFormation
|
|
151
156
|
inst = super()
|
152
157
|
inst._set_self(_self)
|
153
158
|
inst._struct_class = _struct_class
|
154
|
-
if
|
159
|
+
if args.first.is_a?(::Hash)
|
155
160
|
inst._load(args.first)
|
156
161
|
end
|
157
|
-
if
|
162
|
+
if block
|
158
163
|
inst.build!(&block)
|
159
164
|
end
|
160
165
|
inst
|
@@ -168,9 +173,9 @@ class SparkleFormation
|
|
168
173
|
# @raises [ArgumentError]
|
169
174
|
def _state(arg)
|
170
175
|
result = super
|
171
|
-
if
|
172
|
-
if
|
173
|
-
unless
|
176
|
+
if @self && result.nil?
|
177
|
+
if _self.parameters.keys.map(&:to_s).include?(arg.to_s)
|
178
|
+
unless _self.parameters[arg.to_sym].key?(:default)
|
174
179
|
::Kernel.raise ::ArgumentError.new "No value provided for compile time parameter: `#{arg}`!"
|
175
180
|
else
|
176
181
|
result = _self.parameters[arg.to_sym][:default]
|
@@ -179,6 +184,7 @@ class SparkleFormation
|
|
179
184
|
end
|
180
185
|
result
|
181
186
|
end
|
187
|
+
|
182
188
|
alias_method :state!, :_state
|
183
189
|
|
184
190
|
# TODO: Need to refactor attribute_struct dumping to allow hooking
|
@@ -190,8 +196,8 @@ class SparkleFormation
|
|
190
196
|
# @param item [Object]
|
191
197
|
# @return [Object]
|
192
198
|
def _sparkle_dump_unpacker(item)
|
193
|
-
if
|
194
|
-
if
|
199
|
+
if item.is_a?(::Enumerable)
|
200
|
+
if item.respond_to?(:keys)
|
195
201
|
item.class[
|
196
202
|
*item.map do |entry|
|
197
203
|
_sparkle_dump_unpacker(entry)
|
@@ -204,9 +210,9 @@ class SparkleFormation
|
|
204
210
|
end
|
205
211
|
]
|
206
212
|
end
|
207
|
-
elsif
|
213
|
+
elsif item.is_a?(::AttributeStruct)
|
208
214
|
item.nil? ? UNSET_VALUE : item._sparkle_dump
|
209
|
-
elsif
|
215
|
+
elsif item.is_a?(::SparkleFormation)
|
210
216
|
item.sparkle_dump
|
211
217
|
else
|
212
218
|
item
|
@@ -222,7 +228,7 @@ class SparkleFormation
|
|
222
228
|
end.compact
|
223
229
|
__hashish[*processed.flatten(1)]
|
224
230
|
end
|
225
|
-
alias_method :sparkle_dump!, :_sparkle_dump
|
226
231
|
|
232
|
+
alias_method :sparkle_dump!, :_sparkle_dump
|
227
233
|
end
|
228
234
|
end
|
@@ -20,9 +20,9 @@ class SparkleFormation
|
|
20
20
|
cache.fetch('Parameters', {}).each do |k, v|
|
21
21
|
translated['parameters'][k] = Hash[
|
22
22
|
v.map do |key, value|
|
23
|
-
if
|
23
|
+
if key == 'Type'
|
24
24
|
[snake(key).to_s, value.downcase]
|
25
|
-
elsif
|
25
|
+
elsif key == 'AllowedValues'
|
26
26
|
# @todo fix this up to properly build constraints
|
27
27
|
['constraints', [{'allowed_values' => value}]]
|
28
28
|
else
|
@@ -51,11 +51,11 @@ class SparkleFormation
|
|
51
51
|
translated['heat_template_version'] = '2013-05-23'
|
52
52
|
# no HOT support for mappings, so remove and clean pseudo
|
53
53
|
# params in refs
|
54
|
-
if
|
54
|
+
if translated['resources']
|
55
55
|
translated['resources'] = dereference_processor(translated['resources'], ['Fn::FindInMap', 'Ref'])
|
56
56
|
translated['resources'] = rename_processor(translated['resources'])
|
57
57
|
end
|
58
|
-
if
|
58
|
+
if translated['outputs']
|
59
59
|
translated['outputs'] = dereference_processor(translated['outputs'], ['Fn::FindInMap', 'Ref'])
|
60
60
|
translated['outputs'] = rename_processor(translated['outputs'])
|
61
61
|
end
|
@@ -82,24 +82,24 @@ class SparkleFormation
|
|
82
82
|
|
83
83
|
# if health check is provided, create resource and apply to
|
84
84
|
# all pools generated
|
85
|
-
if
|
85
|
+
if healthcheck
|
86
86
|
healthcheck_name = "#{resource_name}HealthCheck"
|
87
87
|
check = {
|
88
88
|
healthcheck_name => {
|
89
89
|
'Type' => 'OS::Neutron::HealthMonitor',
|
90
|
-
'Properties' => {}.tap{ |properties|
|
90
|
+
'Properties' => {}.tap { |properties|
|
91
91
|
{'Timeout' => 'timeout', 'Interval' => 'delay', 'HealthyThreshold' => 'max_retries'}.each do |aws, hot|
|
92
|
-
if
|
92
|
+
if healthcheck[aws]
|
93
93
|
properties[hot] = healthcheck[aws]
|
94
94
|
end
|
95
95
|
end
|
96
|
-
type, port, path = healthcheck['Target'].split(%r{(:|/.*)}).find_all{|x| x != ':'}
|
96
|
+
type, port, path = healthcheck['Target'].split(%r{(:|/.*)}).find_all { |x| x != ':' }
|
97
97
|
properties['type'] = type
|
98
|
-
if
|
98
|
+
if path
|
99
99
|
properties['url_path'] = path
|
100
100
|
end
|
101
|
-
}
|
102
|
-
}
|
101
|
+
},
|
102
|
+
},
|
103
103
|
}
|
104
104
|
translated['Resources'].merge!(check)
|
105
105
|
end
|
@@ -112,21 +112,21 @@ class SparkleFormation
|
|
112
112
|
'Properties' => {
|
113
113
|
'lb_method' => 'ROUND_ROBIN',
|
114
114
|
'monitors' => [
|
115
|
-
{'get_resource' => healthcheck_name}
|
115
|
+
{'get_resource' => healthcheck_name},
|
116
116
|
],
|
117
117
|
'protocol' => base_listener['Protocol'],
|
118
118
|
'vip' => {
|
119
|
-
'protocol_port' => base_listener['LoadBalancerPort']
|
119
|
+
'protocol_port' => base_listener['LoadBalancerPort'],
|
120
120
|
},
|
121
|
-
'subnet' => subnet
|
122
|
-
}
|
123
|
-
}
|
121
|
+
'subnet' => subnet,
|
122
|
+
},
|
123
|
+
},
|
124
124
|
}
|
125
|
-
if
|
125
|
+
if healthcheck
|
126
126
|
base_pool[base_pool_name]['Properties'].merge(
|
127
127
|
'monitors' => [
|
128
|
-
{'get_resource' => healthcheck_name}
|
129
|
-
]
|
128
|
+
{'get_resource' => healthcheck_name},
|
129
|
+
],
|
130
130
|
)
|
131
131
|
end
|
132
132
|
|
@@ -144,16 +144,16 @@ class SparkleFormation
|
|
144
144
|
'protocol' => listener['Protocol'],
|
145
145
|
'subnet' => subnet,
|
146
146
|
'vip' => {
|
147
|
-
'protocol_port' => listener['LoadBalancerPort']
|
148
|
-
}
|
149
|
-
}
|
150
|
-
}
|
147
|
+
'protocol_port' => listener['LoadBalancerPort'],
|
148
|
+
},
|
149
|
+
},
|
150
|
+
},
|
151
151
|
}
|
152
|
-
if
|
152
|
+
if healthcheck
|
153
153
|
pool[pool_name]['Properties'].merge(
|
154
154
|
'monitors' => [
|
155
|
-
{'get_resource' => healthcheck_name}
|
156
|
-
]
|
155
|
+
{'get_resource' => healthcheck_name},
|
156
|
+
],
|
157
157
|
)
|
158
158
|
end
|
159
159
|
|
@@ -174,7 +174,7 @@ class SparkleFormation
|
|
174
174
|
translated['resources'].find_all do |resource_name, resource|
|
175
175
|
resource['type'] == 'OS::Heat::AutoScalingGroup'
|
176
176
|
end.each do |name, value|
|
177
|
-
if
|
177
|
+
if lbs = value['properties'].delete('load_balancers')
|
178
178
|
lbs.each do |lb_ref|
|
179
179
|
lb_name = resource_name(lb_ref)
|
180
180
|
lb_resource = translated['resources'][lb_name]
|
@@ -199,7 +199,7 @@ class SparkleFormation
|
|
199
199
|
# @option args [Hash] :original_resource
|
200
200
|
# @return [Array<String, Object>] name and new value
|
201
201
|
# @todo implement
|
202
|
-
def nova_server_block_device_mapping(value, args={})
|
202
|
+
def nova_server_block_device_mapping(value, args = {})
|
203
203
|
['block_device_mapping', value]
|
204
204
|
end
|
205
205
|
|
@@ -211,7 +211,7 @@ class SparkleFormation
|
|
211
211
|
# @option args [Hash] :new_properties
|
212
212
|
# @option args [Hash] :original_resource
|
213
213
|
# @return [Array<String, Object>] name and new value
|
214
|
-
def nova_server_user_data(value, args={})
|
214
|
+
def nova_server_user_data(value, args = {})
|
215
215
|
args[:new_properties][:user_data_format] = 'RAW'
|
216
216
|
args[:new_properties][:config_drive] = 'true'
|
217
217
|
[:user_data, Hash[value.values.first]]
|
@@ -225,18 +225,18 @@ class SparkleFormation
|
|
225
225
|
# @param old_resource [Hash]
|
226
226
|
# @return [Object]
|
227
227
|
def nova_server_finalizer(resource_name, new_resource, old_resource)
|
228
|
-
if
|
228
|
+
if old_resource['Metadata']
|
229
229
|
new_resource['Metadata'] = old_resource['Metadata']
|
230
230
|
proceed = new_resource['Metadata'] &&
|
231
|
-
|
232
|
-
|
233
|
-
if
|
231
|
+
new_resource['Metadata']['AWS::CloudFormation::Init'] &&
|
232
|
+
config = new_resource['Metadata']['AWS::CloudFormation::Init']['config']
|
233
|
+
if proceed
|
234
234
|
# NOTE: This is a stupid hack since HOT gives the URL to
|
235
235
|
# wget directly and if special characters exist, it fails
|
236
|
-
if
|
236
|
+
if files = config['files']
|
237
237
|
files.each do |key, args|
|
238
|
-
if
|
239
|
-
if
|
238
|
+
if args['source']
|
239
|
+
if args['source'].is_a?(String)
|
240
240
|
args['source'].replace("\"#{args['source']}\"")
|
241
241
|
else
|
242
242
|
args['source'] = {
|
@@ -244,9 +244,9 @@ class SparkleFormation
|
|
244
244
|
'', [
|
245
245
|
"\"",
|
246
246
|
args['source'],
|
247
|
-
"\""
|
248
|
-
]
|
249
|
-
]
|
247
|
+
"\"",
|
248
|
+
],
|
249
|
+
],
|
250
250
|
}
|
251
251
|
end
|
252
252
|
end
|
@@ -266,10 +266,10 @@ class SparkleFormation
|
|
266
266
|
# @return [TrueClass]
|
267
267
|
def neutron_subnet_finalizer(resource_name, new_resource, old_resource)
|
268
268
|
azs = new_resource['Properties'].delete('availability_zone')
|
269
|
-
if
|
269
|
+
if azs
|
270
270
|
network_name = "NetworkFor#{resource_name}"
|
271
271
|
translated['Resources'][network_name] = {
|
272
|
-
'type' => 'OS::Neutron::Network'
|
272
|
+
'type' => 'OS::Neutron::Network',
|
273
273
|
}
|
274
274
|
new_resource['Properties']['network'] = {'get_resource' => network_name}
|
275
275
|
end
|
@@ -295,7 +295,7 @@ class SparkleFormation
|
|
295
295
|
# @return [TrueClass]
|
296
296
|
def resource_finalizer(resource_name, new_resource, old_resource)
|
297
297
|
%w(DependsOn Metadata).each do |key|
|
298
|
-
if
|
298
|
+
if old_resource[key] && !new_resource[key]
|
299
299
|
new_resource[key] = old_resource[key]
|
300
300
|
end
|
301
301
|
end
|
@@ -311,7 +311,7 @@ class SparkleFormation
|
|
311
311
|
# @option args [Hash] :original_resource
|
312
312
|
# @return [Array<String, Object>] name and new value
|
313
313
|
# @todo implement
|
314
|
-
def autoscaling_group_launchconfig(value, args={})
|
314
|
+
def autoscaling_group_launchconfig(value, args = {})
|
315
315
|
['resource', value]
|
316
316
|
end
|
317
317
|
|
@@ -339,8 +339,8 @@ class SparkleFormation
|
|
339
339
|
'SecurityGroups' => 'security_groups',
|
340
340
|
'SecurityGroupIds' => 'security_groups',
|
341
341
|
'Tags' => 'metadata',
|
342
|
-
'UserData' => :nova_server_user_data
|
343
|
-
}
|
342
|
+
'UserData' => :nova_server_user_data,
|
343
|
+
},
|
344
344
|
},
|
345
345
|
'AWS::AutoScaling::AutoScalingGroup' => {
|
346
346
|
:name => 'OS::Heat::AutoScalingGroup',
|
@@ -349,8 +349,8 @@ class SparkleFormation
|
|
349
349
|
'DesiredCapacity' => 'desired_capacity',
|
350
350
|
'MaxSize' => 'max_size',
|
351
351
|
'MinSize' => 'min_size',
|
352
|
-
'LaunchConfigurationName' => :autoscaling_group_launchconfig
|
353
|
-
}
|
352
|
+
'LaunchConfigurationName' => :autoscaling_group_launchconfig,
|
353
|
+
},
|
354
354
|
},
|
355
355
|
'AWS::AutoScaling::LaunchConfiguration' => :delete,
|
356
356
|
'AWS::ElasticLoadBalancing::LoadBalancer' => {
|
@@ -360,15 +360,15 @@ class SparkleFormation
|
|
360
360
|
'Instances' => 'members',
|
361
361
|
'Listeners' => 'listeners',
|
362
362
|
'HealthCheck' => 'health_check',
|
363
|
-
'Subnets' => 'subnets'
|
364
|
-
}
|
363
|
+
'Subnets' => 'subnets',
|
364
|
+
},
|
365
365
|
},
|
366
366
|
'AWS::EC2::VPC' => {
|
367
367
|
:name => 'OS::Neutron::Net',
|
368
368
|
:finalizer => :neutron_net_finalizer,
|
369
369
|
:properties => {
|
370
|
-
'CidrBlock' => 'cidr'
|
371
|
-
}
|
370
|
+
'CidrBlock' => 'cidr',
|
371
|
+
},
|
372
372
|
},
|
373
373
|
'AWS::EC2::Subnet' => {
|
374
374
|
:name => 'OS::Neutron::Subnet',
|
@@ -376,23 +376,22 @@ class SparkleFormation
|
|
376
376
|
:properties => {
|
377
377
|
'CidrBlock' => 'cidr',
|
378
378
|
'VpcId' => 'network',
|
379
|
-
'AvailabilityZone' => 'availability_zone'
|
380
|
-
}
|
381
|
-
}
|
382
|
-
}
|
379
|
+
'AvailabilityZone' => 'availability_zone',
|
380
|
+
},
|
381
|
+
},
|
382
|
+
},
|
383
383
|
}
|
384
384
|
|
385
385
|
REF_MAPPING = {
|
386
386
|
'AWS::StackName' => 'OS::stack_name',
|
387
387
|
'AWS::StackId' => 'OS::stack_id',
|
388
|
-
'AWS::Region' => 'OS::stack_id' # @todo i see it set in source, but no function. wat
|
388
|
+
'AWS::Region' => 'OS::stack_id', # @todo i see it set in source, but no function. wat
|
389
389
|
}
|
390
390
|
|
391
391
|
FN_MAPPING = {
|
392
392
|
'Fn::GetAtt' => 'get_attr',
|
393
|
-
'Fn::Join' => 'list_join'
|
393
|
+
'Fn::Join' => 'list_join',
|
394
394
|
}
|
395
|
-
|
396
395
|
end
|
397
396
|
end
|
398
397
|
end
|