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,7 +11,7 @@ class SparkleFormation
|
|
11
11
|
# @option args [Hash] :new_properties
|
12
12
|
# @option args [Hash] :original_resource
|
13
13
|
# @return [Array<String, Object>] name and new value
|
14
|
-
def rackspace_server_network_interfaces_mapping(value, args={})
|
14
|
+
def rackspace_server_network_interfaces_mapping(value, args = {})
|
15
15
|
networks = [value].flatten.map do |item|
|
16
16
|
{:uuid => item['NetworkInterfaceId']}
|
17
17
|
end
|
@@ -35,7 +35,7 @@ class SparkleFormation
|
|
35
35
|
translated['resources'].find_all do |resource_name, resource|
|
36
36
|
resource['type'] == 'Rackspace::AutoScale::Group'
|
37
37
|
end.each do |name, value|
|
38
|
-
if
|
38
|
+
if lbs = value['properties'].delete('load_balancers')
|
39
39
|
lbs.each do |lb_ref|
|
40
40
|
lb_name = resource_name(lb_ref)
|
41
41
|
lb_resource = translated['resources'][lb_name]
|
@@ -44,25 +44,25 @@ class SparkleFormation
|
|
44
44
|
end
|
45
45
|
value['properties']['launchConfiguration']['args'].tap do |lnch_config|
|
46
46
|
lb_instance = {
|
47
|
-
'loadBalancerId' => lb_ref
|
47
|
+
'loadBalancerId' => lb_ref,
|
48
48
|
}
|
49
49
|
# @note search for a port defined within parameters
|
50
50
|
# that matches naming of LB ID for when they are
|
51
51
|
# passed in rather than defined within the template.
|
52
52
|
# Be sure to document this in user docs since it's
|
53
53
|
# weird but needed
|
54
|
-
if
|
54
|
+
if lb_resource
|
55
55
|
lb_instance['port'] = lb_resource['cache_instance_port']
|
56
56
|
else
|
57
57
|
key = parameters.keys.find_all do |k|
|
58
|
-
if
|
58
|
+
if k.end_with?('Port')
|
59
59
|
lb_ref.values.first.start_with?(k.sub('Instance', '').sub(/Port$/, ''))
|
60
60
|
end
|
61
61
|
end
|
62
62
|
key = key.detect do |k|
|
63
63
|
k.downcase.include?('instance')
|
64
64
|
end || key.first
|
65
|
-
if
|
65
|
+
if key
|
66
66
|
lb_instance['port'] = {'get_param' => key}
|
67
67
|
else
|
68
68
|
raise "Failed to translate load balancer configuartion. No port found! (#{lb_ref})"
|
@@ -72,9 +72,9 @@ class SparkleFormation
|
|
72
72
|
vip_resources.each do |vip_name, vip_resource|
|
73
73
|
lnch_config['loadBalancers'].push(
|
74
74
|
'loadBalancerId' => {
|
75
|
-
'Ref' => vip_name
|
75
|
+
'Ref' => vip_name,
|
76
76
|
},
|
77
|
-
'port' => vip_resource['cache_instance_port']
|
77
|
+
'port' => vip_resource['cache_instance_port'],
|
78
78
|
)
|
79
79
|
end
|
80
80
|
end
|
@@ -91,12 +91,12 @@ class SparkleFormation
|
|
91
91
|
{
|
92
92
|
'get_attr' => [
|
93
93
|
resource_name(node_ref),
|
94
|
-
'accessIPv4'
|
95
|
-
]
|
96
|
-
}
|
94
|
+
'accessIPv4',
|
95
|
+
],
|
96
|
+
},
|
97
97
|
],
|
98
98
|
'port' => resource['cache_instance_port'],
|
99
|
-
'condition' => 'ENABLED'
|
99
|
+
'condition' => 'ENABLED',
|
100
100
|
}
|
101
101
|
end
|
102
102
|
end
|
@@ -126,7 +126,7 @@ class SparkleFormation
|
|
126
126
|
subnet[:name] = 'Rackspace::Cloud::Network'
|
127
127
|
subnet[:finalizer] = :rackspace_subnet_finalizer
|
128
128
|
subnet[:properties] = {
|
129
|
-
'CidrBlock' => 'cidr'
|
129
|
+
'CidrBlock' => 'cidr',
|
130
130
|
}
|
131
131
|
end
|
132
132
|
MAP[:resources]['AWS::ElasticLoadBalancing::LoadBalancer'] = {
|
@@ -136,15 +136,15 @@ class SparkleFormation
|
|
136
136
|
'LoadBalancerName' => 'name',
|
137
137
|
'Instances' => 'nodes',
|
138
138
|
'Listeners' => 'listeners',
|
139
|
-
'HealthCheck' => 'health_check'
|
140
|
-
}
|
139
|
+
'HealthCheck' => 'health_check',
|
140
|
+
},
|
141
141
|
}
|
142
142
|
|
143
143
|
# Attribute map for autoscaling group server properties
|
144
144
|
RACKSPACE_ASG_SRV_MAP = {
|
145
145
|
'imageRef' => 'image',
|
146
146
|
'flavorRef' => 'flavor',
|
147
|
-
'networks' => 'networks'
|
147
|
+
'networks' => 'networks',
|
148
148
|
}
|
149
149
|
|
150
150
|
# Finalizer for the rackspace load balancer resource. This
|
@@ -162,9 +162,9 @@ class SparkleFormation
|
|
162
162
|
def rackspace_lb_finalizer(resource_name, new_resource, old_resource)
|
163
163
|
listeners = new_resource['Properties'].delete('listeners') || []
|
164
164
|
source_listener = listeners.shift
|
165
|
-
if
|
165
|
+
if source_listener
|
166
166
|
new_resource['Properties']['port'] = source_listener['LoadBalancerPort']
|
167
|
-
if
|
167
|
+
if ['HTTP', 'HTTPS'].include?(source_listener['Protocol'])
|
168
168
|
new_resource['Properties']['protocol'] = source_listener['Protocol']
|
169
169
|
else
|
170
170
|
new_resource['Properties']['protocol'] = 'TCP_CLIENT_FIRST'
|
@@ -175,7 +175,7 @@ class SparkleFormation
|
|
175
175
|
new_resource['Properties']['nodes'] = [] unless new_resource['Properties']['nodes']
|
176
176
|
health_check = new_resource['Properties'].delete('health_check')
|
177
177
|
health_check = nil
|
178
|
-
if
|
178
|
+
if health_check
|
179
179
|
new_resource['Properties']['healthCheck'] = {}.tap do |check|
|
180
180
|
check['timeout'] = health_check['Timeout']
|
181
181
|
check['attemptsBeforeDeactivation'] = health_check['UnhealthyThreshold']
|
@@ -183,7 +183,7 @@ class SparkleFormation
|
|
183
183
|
check_target = dereference_processor(health_check['Target'])
|
184
184
|
check_args = check_target.split(':')
|
185
185
|
check_type = check_args.shift
|
186
|
-
if
|
186
|
+
if check_type == 'HTTP' || check_type == 'HTTPS'
|
187
187
|
check['type'] = check_type
|
188
188
|
check['path'] = check_args.last
|
189
189
|
else
|
@@ -191,7 +191,7 @@ class SparkleFormation
|
|
191
191
|
end
|
192
192
|
end
|
193
193
|
end
|
194
|
-
unless
|
194
|
+
unless listeners.empty?
|
195
195
|
listeners.each_with_index do |listener, idx|
|
196
196
|
port = listener['LoadBalancerPort']
|
197
197
|
proto = ['HTTP', 'HTTPS'].include?(listener['Protocol']) ? listener['Protocol'] : 'TCP_CLIENT_FIRST'
|
@@ -206,9 +206,9 @@ class SparkleFormation
|
|
206
206
|
resource_name,
|
207
207
|
'virtualIps',
|
208
208
|
0,
|
209
|
-
'id'
|
210
|
-
]
|
211
|
-
}
|
209
|
+
'id',
|
210
|
+
],
|
211
|
+
},
|
212
212
|
]
|
213
213
|
vip_resource['cache_instance_port'] = listener['InstancePort']
|
214
214
|
translated['Resources'][vip_name] = vip_resource
|
@@ -226,7 +226,7 @@ class SparkleFormation
|
|
226
226
|
# @return [Object]
|
227
227
|
def rackspace_asg_finalizer(resource_name, new_resource, old_resource)
|
228
228
|
new_resource['Properties'] = {}.tap do |properties|
|
229
|
-
if
|
229
|
+
if lbs = new_resource['Properties'].delete('load_balancers')
|
230
230
|
properties['load_balancers'] = lbs
|
231
231
|
end
|
232
232
|
properties['groupConfiguration'] = new_resource['Properties'].merge('name' => resource_name)
|
@@ -269,7 +269,7 @@ class SparkleFormation
|
|
269
269
|
# @option args [Hash] :new_properties
|
270
270
|
# @option args [Hash] :original_resource
|
271
271
|
# @return [Array<String, Object>] name and new value
|
272
|
-
def nova_server_user_data(value, args={})
|
272
|
+
def nova_server_user_data(value, args = {})
|
273
273
|
result = super
|
274
274
|
args[:new_properties].delete(:user_data_format)
|
275
275
|
args[:new_properties].delete(:config_drive)
|
@@ -303,14 +303,14 @@ class SparkleFormation
|
|
303
303
|
# execution (template functions, refs, and the like)
|
304
304
|
raw_result = content.scan(/(?=(\{\s*"(Ref|Fn::[A-Za-z]+)"((?:[^{}]++|\{\g<3>\})++)\}))/).map(&:first)
|
305
305
|
result = [].tap do |filtered|
|
306
|
-
until
|
306
|
+
until raw_result.empty?
|
307
307
|
item = raw_result.shift
|
308
308
|
filtered.push(item)
|
309
309
|
check_item = nil
|
310
|
-
until
|
310
|
+
until raw_result.empty? || !item.include?(check_item = raw_result.shift)
|
311
311
|
check_item = nil
|
312
312
|
end
|
313
|
-
if
|
313
|
+
if check_item && !item.include?(check_item)
|
314
314
|
raw_result.unshift(check_item)
|
315
315
|
end
|
316
316
|
end
|
@@ -323,7 +323,7 @@ class SparkleFormation
|
|
323
323
|
/\n(?=(?:[^"]*"[^"]*")*[^"]*\Z)/
|
324
324
|
).join.gsub('\n', '\\\\\n')
|
325
325
|
# Check for nested join and fix quotes
|
326
|
-
if
|
326
|
+
if string.match(/^[^A-Za-z]+Fn::Join/)
|
327
327
|
string.gsub!("\\\"", "\\\\\\\\\\\"") # HAHAHA ohai thar hairy yak!
|
328
328
|
end
|
329
329
|
MultiJson.load(string)
|
@@ -334,7 +334,7 @@ class SparkleFormation
|
|
334
334
|
result_set = []
|
335
335
|
result.each_with_index do |str, i|
|
336
336
|
cut_index = new_content.index(str)
|
337
|
-
if
|
337
|
+
if cut_index
|
338
338
|
result_set << new_content.slice!(0, cut_index)
|
339
339
|
result_set << objects[i]
|
340
340
|
new_content.slice!(0, str.size)
|
@@ -350,7 +350,7 @@ class SparkleFormation
|
|
350
350
|
|
351
351
|
# Determine optimal chuck sizing and check if viable
|
352
352
|
calculated_chunk_size = (content.size.to_f / num_personality_files).ceil
|
353
|
-
if
|
353
|
+
if calculated_chunk_size > max_chunk_size
|
354
354
|
logger.error 'ERROR: Unable to split personality files within defined bounds!'
|
355
355
|
logger.error " Maximum chunk size: #{max_chunk_size.inspect}"
|
356
356
|
logger.error " Maximum personality files: #{num_personality_files.inspect}"
|
@@ -363,16 +363,16 @@ class SparkleFormation
|
|
363
363
|
chunk_size = calculated_chunk_size
|
364
364
|
file_index = 0
|
365
365
|
parts = {}.tap do |files|
|
366
|
-
until
|
366
|
+
until leftovers.empty? && result_set.empty?
|
367
367
|
file_content = []
|
368
|
-
unless
|
368
|
+
unless leftovers.empty?
|
369
369
|
result_set.unshift leftovers
|
370
370
|
leftovers = ''
|
371
371
|
end
|
372
372
|
item = nil
|
373
373
|
# @todo need better way to determine length of objects since
|
374
374
|
# function structures can severely bloat actual length
|
375
|
-
until(
|
375
|
+
until (cur_len = file_content.map(&:to_s).map(&:size).inject(&:+).to_i) >= chunk_size || result_set.empty?
|
376
376
|
to_cut = chunk_size - cur_len
|
377
377
|
item = result_set.shift
|
378
378
|
case item
|
@@ -383,12 +383,12 @@ class SparkleFormation
|
|
383
383
|
end
|
384
384
|
end
|
385
385
|
leftovers = item if item.is_a?(String) && !item.empty?
|
386
|
-
unless
|
387
|
-
if
|
386
|
+
unless file_content.empty?
|
387
|
+
if file_content.all? { |o| o.is_a?(String) }
|
388
388
|
files["/etc/sprkl/#{file_index}.cfg"] = file_content.join
|
389
389
|
else
|
390
390
|
file_content.map! do |cont|
|
391
|
-
if
|
391
|
+
if cont.is_a?(Hash)
|
392
392
|
["\"", cont, "\""]
|
393
393
|
else
|
394
394
|
cont
|
@@ -397,17 +397,17 @@ class SparkleFormation
|
|
397
397
|
files["/etc/sprkl/#{file_index}.cfg"] = {
|
398
398
|
'Fn::Join' => [
|
399
399
|
'',
|
400
|
-
file_content.flatten
|
401
|
-
]
|
400
|
+
file_content.flatten,
|
401
|
+
],
|
402
402
|
}
|
403
403
|
end
|
404
404
|
end
|
405
405
|
file_index += 1
|
406
406
|
end
|
407
407
|
end
|
408
|
-
if
|
408
|
+
if parts.size > num_personality_files
|
409
409
|
logger.warn "Failed to split files within defined range! (Max files: #{num_personality_files} " \
|
410
|
-
|
410
|
+
"Actual files: #{parts.size})"
|
411
411
|
logger.warn 'Appending to last file and hoping for the best!'
|
412
412
|
parts = parts.to_a
|
413
413
|
extras = parts.slice!(4, parts.length)
|
@@ -416,8 +416,8 @@ class SparkleFormation
|
|
416
416
|
parts[tail_name] = {
|
417
417
|
'Fn::Join' => [
|
418
418
|
'',
|
419
|
-
extras.map(&:last).unshift(tail_contents)
|
420
|
-
]
|
419
|
+
extras.map(&:last).unshift(tail_contents),
|
420
|
+
],
|
421
421
|
}
|
422
422
|
end
|
423
423
|
parts['/etc/cloud/cloud.cfg.d/99_s.cfg'] = RUNNER
|
@@ -426,7 +426,7 @@ class SparkleFormation
|
|
426
426
|
|
427
427
|
FN_MAPPING = {
|
428
428
|
'Fn::GetAtt' => 'get_attr',
|
429
|
-
|
429
|
+
# 'Fn::Join' => 'list_join' # TODO: why is this not working?
|
430
430
|
}
|
431
431
|
|
432
432
|
FN_ATT_MAPPING = {
|
@@ -434,11 +434,11 @@ class SparkleFormation
|
|
434
434
|
'PrivateDnsName' => 'accessIPv4', # @todo - need srv net name for access via nets
|
435
435
|
'PublicDnsName' => 'accessIPv4',
|
436
436
|
'PrivateIp' => 'accessIPv4', # @todo - need srv net name for access via nets
|
437
|
-
'PublicIp' => 'accessIPv4'
|
437
|
+
'PublicIp' => 'accessIPv4',
|
438
438
|
},
|
439
439
|
'AWS::ElasticLoadBalancing::LoadBalancer' => {
|
440
|
-
'DNSName' => 'PublicIp'
|
441
|
-
}
|
440
|
+
'DNSName' => 'PublicIp',
|
441
|
+
},
|
442
442
|
}
|
443
443
|
|
444
444
|
# Metadata init runner
|
@@ -449,7 +449,6 @@ runcmd:
|
|
449
449
|
- chmod 755 /tmp/.z
|
450
450
|
- /tmp/.z -meta-directory /etc/sprkl
|
451
451
|
EOR
|
452
|
-
|
453
452
|
end
|
454
453
|
end
|
455
454
|
end
|
@@ -5,7 +5,6 @@ require 'logger'
|
|
5
5
|
class SparkleFormation
|
6
6
|
# Translator
|
7
7
|
class Translation
|
8
|
-
|
9
8
|
autoload :Heat, 'sparkle_formation/translation/heat'
|
10
9
|
autoload :Rackspace, 'sparkle_formation/translation/rackspace'
|
11
10
|
|
@@ -30,7 +29,7 @@ class SparkleFormation
|
|
30
29
|
# @option args [Logger] :logger custom logger
|
31
30
|
# @option args [Hash] :parameters parameters for stack creation
|
32
31
|
# @option args [Hash] :options options for translation
|
33
|
-
def initialize(template_hash, args={})
|
32
|
+
def initialize(template_hash, args = {})
|
34
33
|
@original = template_hash.dup
|
35
34
|
@template = template_hash.to_smash
|
36
35
|
@translated = {}
|
@@ -74,7 +73,7 @@ class SparkleFormation
|
|
74
73
|
def translate!
|
75
74
|
template.each do |key, value|
|
76
75
|
translate_method = "translate_#{snake(key.to_s)}".to_sym
|
77
|
-
if
|
76
|
+
if respond_to?(translate_method)
|
78
77
|
send(translate_method, value)
|
79
78
|
else
|
80
79
|
translate_default(key, value)
|
@@ -98,23 +97,23 @@ class SparkleFormation
|
|
98
97
|
def resource_translation(resource_name, resource_args)
|
99
98
|
new_resource = {}
|
100
99
|
lookup = map[:resources][resource_args['Type']]
|
101
|
-
if
|
100
|
+
if lookup.nil?
|
102
101
|
logger.warn "Failed to locate resource type: #{resource_args['Type']}"
|
103
102
|
nil
|
104
|
-
elsif
|
103
|
+
elsif lookup == :delete
|
105
104
|
logger.warn "Deleting resource #{resource_name} due to configuration"
|
106
105
|
nil
|
107
106
|
else
|
108
107
|
new_resource['Type'] = lookup[:name]
|
109
|
-
if
|
108
|
+
if resource_args['Properties']
|
110
109
|
new_resource['Properties'] = format_properties(
|
111
110
|
:original_properties => resource_args['Properties'],
|
112
111
|
:property_map => lookup[:properties],
|
113
112
|
:new_resource => new_resource,
|
114
|
-
:original_resource => resource_args
|
113
|
+
:original_resource => resource_args,
|
115
114
|
)
|
116
115
|
end
|
117
|
-
if
|
116
|
+
if lookup[:finalizer]
|
118
117
|
send(lookup[:finalizer], resource_name, new_resource, resource_args)
|
119
118
|
end
|
120
119
|
resource_finalizer(resource_name, new_resource, resource_args)
|
@@ -134,22 +133,21 @@ class SparkleFormation
|
|
134
133
|
args[:new_resource]['Properties'] = {}.tap do |new_properties|
|
135
134
|
args[:original_properties].each do |property_name, property_value|
|
136
135
|
new_key = args[:property_map][property_name]
|
137
|
-
if
|
138
|
-
if
|
139
|
-
unless
|
136
|
+
if new_key
|
137
|
+
if new_key.is_a?(Symbol)
|
138
|
+
unless new_key == :delete
|
140
139
|
new_key, new_value = send(new_key, property_value,
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
)
|
140
|
+
:new_resource => args[:new_resource],
|
141
|
+
:new_properties => new_properties,
|
142
|
+
:original_resource => args[:original_resource])
|
145
143
|
new_properties[new_key] = new_value
|
146
144
|
end
|
147
145
|
else
|
148
146
|
new_properties[new_key] = property_value
|
149
147
|
end
|
150
148
|
else
|
151
|
-
logger.warn "Failed to locate property conversion for `#{property_name}` on "\
|
152
|
-
|
149
|
+
logger.warn "Failed to locate property conversion for `#{property_name}` on " \
|
150
|
+
"resource type `#{args[:new_resource]['Type']}`. Passing directly."
|
153
151
|
new_properties[default_key_format(property_name)] = property_value
|
154
152
|
end
|
155
153
|
end
|
@@ -165,7 +163,7 @@ class SparkleFormation
|
|
165
163
|
translated['Resources'].tap do |modified_resources|
|
166
164
|
value.each do |resource_name, resource_args|
|
167
165
|
new_resource = resource_translation(resource_name, resource_args)
|
168
|
-
if
|
166
|
+
if new_resource
|
169
167
|
modified_resources[resource_name] = new_resource
|
170
168
|
end
|
171
169
|
end
|
@@ -186,11 +184,11 @@ class SparkleFormation
|
|
186
184
|
# @return [Object]
|
187
185
|
def dereference(obj)
|
188
186
|
result = obj
|
189
|
-
if
|
187
|
+
if obj.is_a?(Hash)
|
190
188
|
name = obj['Ref'] || obj['get_param']
|
191
|
-
if
|
189
|
+
if name
|
192
190
|
p_val = parameters[name.to_s]
|
193
|
-
if
|
191
|
+
if p_val
|
194
192
|
result = p_val
|
195
193
|
end
|
196
194
|
end
|
@@ -216,10 +214,10 @@ class SparkleFormation
|
|
216
214
|
#
|
217
215
|
# @param obj [Object]
|
218
216
|
# @return [Object]
|
219
|
-
def dereference_processor(obj, funcs=[])
|
217
|
+
def dereference_processor(obj, funcs = [])
|
220
218
|
case obj
|
221
219
|
when Array
|
222
|
-
obj = obj.map{|v| dereference_processor(v, funcs)}
|
220
|
+
obj = obj.map { |v| dereference_processor(v, funcs) }
|
223
221
|
when Hash
|
224
222
|
new_hash = {}
|
225
223
|
obj.each do |k, v|
|
@@ -235,10 +233,10 @@ class SparkleFormation
|
|
235
233
|
# @param obj [Object]
|
236
234
|
# @param names [Array<Symbol>] enable renaming (:ref, :fn)
|
237
235
|
# @return [Object]
|
238
|
-
def rename_processor(obj, names=[])
|
236
|
+
def rename_processor(obj, names = [])
|
239
237
|
case obj
|
240
238
|
when Array
|
241
|
-
obj = obj.map{|v| rename_processor(v, names)}
|
239
|
+
obj = obj.map { |v| rename_processor(v, names) }
|
242
240
|
when Hash
|
243
241
|
new_hash = {}
|
244
242
|
obj.each do |k, v|
|
@@ -257,13 +255,13 @@ class SparkleFormation
|
|
257
255
|
# @note remapping references to constants:
|
258
256
|
# REF_MAPPING for Ref maps
|
259
257
|
# FN_MAPPING for Fn maps
|
260
|
-
def apply_rename(hash, names=[])
|
258
|
+
def apply_rename(hash, names = [])
|
261
259
|
k, v = hash.first
|
262
|
-
if
|
263
|
-
if
|
260
|
+
if hash.size == 1
|
261
|
+
if k.start_with?('Fn::')
|
264
262
|
{self.class.const_get(:FN_MAPPING).fetch(k, k) => attr_mapping(*v)}
|
265
|
-
elsif
|
266
|
-
if
|
263
|
+
elsif k == 'Ref'
|
264
|
+
if resources.key?(v)
|
267
265
|
{'get_resource' => v}
|
268
266
|
else
|
269
267
|
{'get_param' => self.class.const_get(:REF_MAPPING).fetch(v, v)}
|
@@ -283,9 +281,9 @@ class SparkleFormation
|
|
283
281
|
# @return [Array]
|
284
282
|
def attr_mapping(resource_name, value)
|
285
283
|
result = [resource_name, value]
|
286
|
-
if
|
284
|
+
if r = resources[resource_name]
|
287
285
|
attr_map = self.class.const_get(:FN_ATT_MAPPING)
|
288
|
-
if
|
286
|
+
if attr_map[r['Type']] && replacement = attr_map[r['Type']][value]
|
289
287
|
result = [resource_name, *[replacement].flatten.compact]
|
290
288
|
end
|
291
289
|
end
|
@@ -299,17 +297,17 @@ class SparkleFormation
|
|
299
297
|
# @return [Hash]
|
300
298
|
# @note also allows 'Ref' within funcs to provide mapping
|
301
299
|
# replacements using the REF_MAPPING constant
|
302
|
-
def apply_function(hash, funcs=[])
|
300
|
+
def apply_function(hash, funcs = [])
|
303
301
|
k, v = hash.first
|
304
|
-
if
|
302
|
+
if hash.size == 1 && (k.start_with?('Fn') || k == 'Ref') && (funcs.empty? || funcs.include?(k))
|
305
303
|
case k
|
306
304
|
when 'Fn::Join'
|
307
305
|
v.last.join(v.first)
|
308
306
|
when 'Fn::FindInMap'
|
309
307
|
map_holder = mappings[v[0]]
|
310
|
-
if
|
308
|
+
if map_holder
|
311
309
|
map_item = map_holder[dereference(v[1])]
|
312
|
-
if
|
310
|
+
if map_item
|
313
311
|
map_item[v[2]]
|
314
312
|
else
|
315
313
|
raise "Failed to find mapping item! (#{v[0]} -> #{v[1]})"
|
@@ -332,6 +330,5 @@ class SparkleFormation
|
|
332
330
|
|
333
331
|
# @return [Hash] mapping for intrinsic functions
|
334
332
|
FN_MAPPING = {}
|
335
|
-
|
336
333
|
end
|
337
334
|
end
|
@@ -14,14 +14,14 @@ class SparkleFormation
|
|
14
14
|
# @raises [TypeError]
|
15
15
|
def __t_check(val, types)
|
16
16
|
types = [types] unless types.is_a?(Array)
|
17
|
-
if
|
17
|
+
if types.none? { |t| val.is_a?(t) }
|
18
18
|
ignore_paths = Gem::Specification.find_by_name('sparkle_formation').full_require_paths
|
19
19
|
file_name, line_no = ::Kernel.caller.detect do |l|
|
20
|
-
ignore_paths.none?{|i_path| l.include?(i_path) }
|
20
|
+
ignore_paths.none? { |i_path| l.include?(i_path) }
|
21
21
|
end.split(':')[0, 2]
|
22
22
|
file_name = file_name.to_s.sub(::Dir.pwd, '.')
|
23
23
|
::Kernel.raise TypeError.new "Received invalid value type `#{val.class}`! " \
|
24
|
-
|
24
|
+
"(Allowed types: `#{types.join('`, `')}`) -> #{file_name} @ line #{line_no}"
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
@@ -40,7 +40,6 @@ class SparkleFormation
|
|
40
40
|
def __t_hashish(val)
|
41
41
|
__t_check(val, Hash)
|
42
42
|
end
|
43
|
-
|
44
43
|
end
|
45
44
|
|
46
45
|
# Animal stylings on strins
|
@@ -50,7 +49,7 @@ class SparkleFormation
|
|
50
49
|
# @param string [String]
|
51
50
|
# @return [String]
|
52
51
|
def camel(string)
|
53
|
-
string.to_s.split('_').map{|k| "#{k.slice(0, 1).upcase}#{k.slice(1, k.length)}"}.join
|
52
|
+
string.to_s.split('_').map { |k| "#{k.slice(0, 1).upcase}#{k.slice(1, k.length)}" }.join
|
54
53
|
end
|
55
54
|
|
56
55
|
# Snake case (underscore) string
|
@@ -60,14 +59,11 @@ class SparkleFormation
|
|
60
59
|
def snake(string)
|
61
60
|
string.to_s.gsub(/([a-z])([A-Z])/, '\1_\2').downcase.to_sym
|
62
61
|
end
|
63
|
-
|
64
62
|
end
|
65
|
-
|
66
63
|
end
|
67
64
|
|
68
65
|
# Registry helper
|
69
66
|
class Registry
|
70
|
-
|
71
67
|
class << self
|
72
68
|
|
73
69
|
# Initialize registry
|
@@ -92,15 +88,13 @@ class SparkleFormation
|
|
92
88
|
# @param location [AttributeStruct] context to apply block
|
93
89
|
# @param args [Object] argument list for block
|
94
90
|
def insert(name, location, *args)
|
95
|
-
if
|
91
|
+
if block = @register[name]
|
96
92
|
location.instance_exec(*args, &block)
|
97
93
|
else
|
98
94
|
raise KeyError.new("Requested item not found in registry (#{name})")
|
99
95
|
end
|
100
96
|
end
|
101
|
-
|
102
97
|
end
|
103
|
-
|
104
98
|
end
|
105
99
|
|
106
100
|
# Cache helper
|
@@ -130,12 +124,11 @@ class SparkleFormation
|
|
130
124
|
#
|
131
125
|
# @return [self]
|
132
126
|
def init!
|
133
|
-
unless
|
127
|
+
unless Thread.current[:sparkle_cache]
|
134
128
|
Thread.current[:sparkle_cache] = {}
|
135
129
|
end
|
136
130
|
self
|
137
131
|
end
|
138
|
-
|
139
132
|
end
|
140
133
|
end
|
141
134
|
end
|
data/sparkle_formation.gemspec
CHANGED
@@ -17,8 +17,8 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.add_development_dependency 'minitest'
|
18
18
|
s.add_development_dependency 'rspec', '~> 3.5'
|
19
19
|
s.add_development_dependency 'rake', '~> 10'
|
20
|
-
s.add_development_dependency 'rubocop', '0.38.0'
|
21
20
|
s.add_development_dependency 'yard'
|
21
|
+
s.add_development_dependency 'rufo'
|
22
22
|
s.add_development_dependency 'redcarpet', '~> 2.0'
|
23
23
|
s.add_development_dependency 'github-markup'
|
24
24
|
s.executables << 'generate_sparkle_docs'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sparkle_formation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.28
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Roberts
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-01-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: attribute_struct
|
@@ -101,21 +101,21 @@ dependencies:
|
|
101
101
|
- !ruby/object:Gem::Version
|
102
102
|
version: '10'
|
103
103
|
- !ruby/object:Gem::Dependency
|
104
|
-
name:
|
104
|
+
name: yard
|
105
105
|
requirement: !ruby/object:Gem::Requirement
|
106
106
|
requirements:
|
107
|
-
- -
|
107
|
+
- - ">="
|
108
108
|
- !ruby/object:Gem::Version
|
109
|
-
version: 0
|
109
|
+
version: '0'
|
110
110
|
type: :development
|
111
111
|
prerelease: false
|
112
112
|
version_requirements: !ruby/object:Gem::Requirement
|
113
113
|
requirements:
|
114
|
-
- -
|
114
|
+
- - ">="
|
115
115
|
- !ruby/object:Gem::Version
|
116
|
-
version: 0
|
116
|
+
version: '0'
|
117
117
|
- !ruby/object:Gem::Dependency
|
118
|
-
name:
|
118
|
+
name: rufo
|
119
119
|
requirement: !ruby/object:Gem::Requirement
|
120
120
|
requirements:
|
121
121
|
- - ">="
|
@@ -249,7 +249,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
249
249
|
version: '0'
|
250
250
|
requirements: []
|
251
251
|
rubyforge_project:
|
252
|
-
rubygems_version: 2.
|
252
|
+
rubygems_version: 2.7.3
|
253
253
|
signing_key:
|
254
254
|
specification_version: 4
|
255
255
|
summary: Orchestration Template Generator
|