sparkle_formation 3.0.26 → 3.0.28
Sign up to get free protection for your applications and to get access to all the features.
- 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
|