sfn 3.0.30 → 3.0.32
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 +6 -0
- data/bin/sfn +16 -14
- data/lib/chef/knife/knife_plugin_seed.rb +12 -12
- data/lib/sfn.rb +17 -17
- data/lib/sfn/api_provider.rb +3 -3
- data/lib/sfn/api_provider/google.rb +2 -2
- data/lib/sfn/api_provider/terraform.rb +2 -2
- data/lib/sfn/cache.rb +9 -9
- data/lib/sfn/callback.rb +6 -6
- data/lib/sfn/callback/aws_assume_role.rb +5 -5
- data/lib/sfn/callback/aws_mfa.rb +8 -6
- data/lib/sfn/callback/stack_policy.rb +15 -15
- data/lib/sfn/command.rb +37 -36
- data/lib/sfn/command/conf.rb +12 -12
- data/lib/sfn/command/create.rb +9 -9
- data/lib/sfn/command/describe.rb +6 -6
- data/lib/sfn/command/destroy.rb +8 -8
- data/lib/sfn/command/diff.rb +31 -31
- data/lib/sfn/command/events.rb +6 -6
- data/lib/sfn/command/export.rb +8 -8
- data/lib/sfn/command/graph.rb +21 -21
- data/lib/sfn/command/graph/aws.rb +34 -34
- data/lib/sfn/command/graph/provider.rb +1 -1
- data/lib/sfn/command/graph/terraform.rb +41 -41
- data/lib/sfn/command/import.rb +17 -17
- data/lib/sfn/command/init.rb +15 -15
- data/lib/sfn/command/inspect.rb +16 -16
- data/lib/sfn/command/lint.rb +6 -6
- data/lib/sfn/command/list.rb +2 -2
- data/lib/sfn/command/plan.rb +227 -0
- data/lib/sfn/command/print.rb +4 -4
- data/lib/sfn/command/promote.rb +2 -2
- data/lib/sfn/command/update.rb +19 -144
- data/lib/sfn/command/validate.rb +17 -13
- data/lib/sfn/command_module.rb +6 -5
- data/lib/sfn/command_module/base.rb +8 -8
- data/lib/sfn/command_module/callbacks.rb +5 -5
- data/lib/sfn/command_module/planning.rb +151 -0
- data/lib/sfn/command_module/stack.rb +34 -34
- data/lib/sfn/command_module/template.rb +50 -50
- data/lib/sfn/config.rb +46 -44
- data/lib/sfn/config/conf.rb +3 -3
- data/lib/sfn/config/create.rb +9 -9
- data/lib/sfn/config/describe.rb +7 -7
- data/lib/sfn/config/destroy.rb +1 -1
- data/lib/sfn/config/diff.rb +3 -3
- data/lib/sfn/config/events.rb +9 -9
- data/lib/sfn/config/export.rb +5 -5
- data/lib/sfn/config/graph.rb +10 -10
- data/lib/sfn/config/import.rb +4 -4
- data/lib/sfn/config/init.rb +1 -1
- data/lib/sfn/config/inspect.rb +16 -16
- data/lib/sfn/config/lint.rb +5 -5
- data/lib/sfn/config/list.rb +6 -6
- data/lib/sfn/config/plan.rb +28 -0
- data/lib/sfn/config/print.rb +5 -5
- data/lib/sfn/config/promote.rb +4 -4
- data/lib/sfn/config/update.rb +18 -18
- data/lib/sfn/config/validate.rb +30 -30
- data/lib/sfn/lint.rb +5 -5
- data/lib/sfn/lint/definition.rb +3 -3
- data/lib/sfn/lint/rule.rb +3 -3
- data/lib/sfn/lint/rule_set.rb +2 -2
- data/lib/sfn/monkey_patch.rb +2 -2
- data/lib/sfn/monkey_patch/stack.rb +27 -27
- data/lib/sfn/monkey_patch/stack/azure.rb +1 -1
- data/lib/sfn/monkey_patch/stack/google.rb +5 -5
- data/lib/sfn/planner.rb +4 -4
- data/lib/sfn/planner/aws.rb +114 -70
- data/lib/sfn/provider.rb +13 -13
- data/lib/sfn/utils.rb +10 -10
- data/lib/sfn/utils/debug.rb +2 -2
- data/lib/sfn/utils/json.rb +1 -1
- data/lib/sfn/utils/object_storage.rb +3 -3
- data/lib/sfn/utils/output.rb +4 -4
- data/lib/sfn/utils/path_selector.rb +15 -15
- data/lib/sfn/utils/ssher.rb +4 -4
- data/lib/sfn/utils/stack_exporter.rb +16 -16
- data/lib/sfn/utils/stack_parameter_scrubber.rb +6 -6
- data/lib/sfn/utils/stack_parameter_validator.rb +22 -22
- data/lib/sfn/version.rb +1 -1
- data/sfn.gemspec +32 -32
- metadata +16 -13
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "sfn"
|
|
2
2
|
|
|
3
3
|
module Sfn
|
|
4
4
|
module MonkeyPatch
|
|
@@ -50,7 +50,7 @@ module Sfn
|
|
|
50
50
|
my_template = my_template.get(:resources, name, :properties, :stack)
|
|
51
51
|
end
|
|
52
52
|
n_stacks = my_template[:resources].map do |s_name, content|
|
|
53
|
-
if content[:type] ==
|
|
53
|
+
if content[:type] == "sparkleformation.stack"
|
|
54
54
|
n_stack = self.class.new(api)
|
|
55
55
|
n_stack.extend PretendStack
|
|
56
56
|
n_layout = custom.fetch(:layout, {}).fetch(:resources, []).detect { |r| r[:name] == name }
|
|
@@ -59,7 +59,7 @@ module Sfn
|
|
|
59
59
|
:name => s_name,
|
|
60
60
|
:id => s_name,
|
|
61
61
|
:template => content.get(:properties, :stack),
|
|
62
|
-
:outputs => n_layout.fetch(
|
|
62
|
+
:outputs => n_layout.fetch("outputs", []).map { |o_val| Smash.new(:key => o_val[:name], :value => o_val["finalValue"]) },
|
|
63
63
|
:custom => {
|
|
64
64
|
:resources => resources.all.map(&:attributes),
|
|
65
65
|
:layout => n_layout,
|
|
@@ -84,7 +84,7 @@ module Sfn
|
|
|
84
84
|
result = template.to_smash
|
|
85
85
|
(result.delete(:resources) || []).each do |t_resource|
|
|
86
86
|
t_name = t_resource.delete(:name)
|
|
87
|
-
if t_resource[:type].to_s.end_with?(
|
|
87
|
+
if t_resource[:type].to_s.end_with?(".jinja")
|
|
88
88
|
schema = copy_template.fetch(:config, :content, :imports, []).delete("#{t_resource[:type]}.schema")
|
|
89
89
|
schema_content = copy_template.fetch(:imports, []).detect do |s_item|
|
|
90
90
|
s_item[:name] == schema
|
|
@@ -96,7 +96,7 @@ module Sfn
|
|
|
96
96
|
s_item[:name] == t_resource[:type]
|
|
97
97
|
end
|
|
98
98
|
if n_template
|
|
99
|
-
t_resource[:type] =
|
|
99
|
+
t_resource[:type] = "sparkleformation.stack"
|
|
100
100
|
current_properties = t_resource.delete(:properties)
|
|
101
101
|
t_resource.set(:properties, :parameters, current_properties) if current_properties
|
|
102
102
|
t_resource.set(:properties, :stack, deref.call(n_template[:content]))
|
data/lib/sfn/planner.rb
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "sfn"
|
|
2
2
|
|
|
3
3
|
module Sfn
|
|
4
4
|
# Interface for generating plan report
|
|
5
5
|
class Planner
|
|
6
|
-
autoload :Aws,
|
|
6
|
+
autoload :Aws, "sfn/planner/aws"
|
|
7
7
|
|
|
8
8
|
# Value to flag runtime modification
|
|
9
|
-
RUNTIME_MODIFIED =
|
|
9
|
+
RUNTIME_MODIFIED = "__MODIFIED_REFERENCE_VALUE__"
|
|
10
10
|
|
|
11
11
|
# @return [Bogo::Ui]
|
|
12
12
|
attr_reader :ui
|
|
@@ -41,7 +41,7 @@ module Sfn
|
|
|
41
41
|
# @param template [Hash] updated template
|
|
42
42
|
# @param parameters [Hash] runtime parameters for update
|
|
43
43
|
#
|
|
44
|
-
# @return [
|
|
44
|
+
# @return [Miasma::Models::Orchestration::Stack::Plan] report
|
|
45
45
|
def generate_plan(template, parameters)
|
|
46
46
|
raise NotImplementedError
|
|
47
47
|
end
|
data/lib/sfn/planner/aws.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
3
|
-
require
|
|
1
|
+
require "sfn"
|
|
2
|
+
require "sparkle_formation/aws"
|
|
3
|
+
require "hashdiff"
|
|
4
4
|
|
|
5
5
|
module Sfn
|
|
6
6
|
class Planner
|
|
@@ -13,7 +13,7 @@ module Sfn
|
|
|
13
13
|
REF_MAPPING = {}
|
|
14
14
|
FN_MAPPING = {}
|
|
15
15
|
|
|
16
|
-
UNKNOWN_RUNTIME_RESULT =
|
|
16
|
+
UNKNOWN_RUNTIME_RESULT = "__UNKNOWN_RUNTIME_RESULT__"
|
|
17
17
|
|
|
18
18
|
# @return [Array<String>] flagged items for value replacement
|
|
19
19
|
attr_reader :flagged
|
|
@@ -26,7 +26,7 @@ module Sfn
|
|
|
26
26
|
|
|
27
27
|
# @return [Hash] defined conditions
|
|
28
28
|
def conditions
|
|
29
|
-
@original.fetch(
|
|
29
|
+
@original.fetch("Conditions", {})
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
# Flag a reference as modified
|
|
@@ -56,19 +56,19 @@ module Sfn
|
|
|
56
56
|
def apply_function(hash, funcs = [])
|
|
57
57
|
if hash.is_a?(Hash)
|
|
58
58
|
k, v = hash.first
|
|
59
|
-
if hash.size == 1 && (k.start_with?(
|
|
60
|
-
method_name = Bogo::Utility.snake(k.gsub(
|
|
59
|
+
if hash.size == 1 && (k.start_with?("Fn") || k == "Ref") && (funcs.include?(:all) || funcs.empty? || funcs.include?(k) || funcs == ["DEREF"])
|
|
60
|
+
method_name = Bogo::Utility.snake(k.gsub("::", ""))
|
|
61
61
|
if (funcs.include?(k) || funcs.include?(:all)) && respond_to?(method_name)
|
|
62
62
|
apply_function(send(method_name, v), funcs)
|
|
63
63
|
else
|
|
64
64
|
case k
|
|
65
|
-
when
|
|
66
|
-
funcs.include?(
|
|
67
|
-
when
|
|
68
|
-
if funcs.include?(
|
|
65
|
+
when "Fn::GetAtt"
|
|
66
|
+
funcs.include?("DEREF") ? dereference(hash) : hash
|
|
67
|
+
when "Ref"
|
|
68
|
+
if funcs.include?("DEREF")
|
|
69
69
|
dereference(hash)
|
|
70
70
|
else
|
|
71
|
-
{
|
|
71
|
+
{"Ref" => self.class.const_get(:REF_MAPPING).fetch(v, v)}
|
|
72
72
|
end
|
|
73
73
|
else
|
|
74
74
|
hash
|
|
@@ -89,7 +89,7 @@ module Sfn
|
|
|
89
89
|
def apply_condition(name)
|
|
90
90
|
condition = conditions[name]
|
|
91
91
|
if condition
|
|
92
|
-
apply_function(condition, [:all,
|
|
92
|
+
apply_function(condition, [:all, "DEREF"])
|
|
93
93
|
else
|
|
94
94
|
raise "Failed to locate condition with name `#{name}`!"
|
|
95
95
|
end
|
|
@@ -169,7 +169,7 @@ module Sfn
|
|
|
169
169
|
# @return [String]
|
|
170
170
|
def fn_join(value)
|
|
171
171
|
unless value.last.is_a?(Array)
|
|
172
|
-
val = value.last.to_s.split(
|
|
172
|
+
val = value.last.to_s.split(",")
|
|
173
173
|
else
|
|
174
174
|
val = value.last
|
|
175
175
|
end
|
|
@@ -202,11 +202,11 @@ module Sfn
|
|
|
202
202
|
def dereference(hash)
|
|
203
203
|
result = nil
|
|
204
204
|
if hash.is_a?(Hash)
|
|
205
|
-
if hash.keys.first ==
|
|
205
|
+
if hash.keys.first == "Ref" && flagged?(hash.values.first)
|
|
206
206
|
result = RUNTIME_MODIFIED
|
|
207
|
-
elsif hash.keys.first ==
|
|
208
|
-
if hash.values.last.last.start_with?(
|
|
209
|
-
if flagged?(hash.values.join(
|
|
207
|
+
elsif hash.keys.first == "Fn::GetAtt"
|
|
208
|
+
if hash.values.last.last.start_with?("Outputs.")
|
|
209
|
+
if flagged?(hash.values.join("_"))
|
|
210
210
|
result = RUNTIME_MODIFIED
|
|
211
211
|
end
|
|
212
212
|
elsif flagged?(hash.values.first)
|
|
@@ -224,8 +224,8 @@ module Sfn
|
|
|
224
224
|
|
|
225
225
|
# Resources that will be replaced on metadata init updates
|
|
226
226
|
REPLACE_ON_CFN_INIT_UPDATE = [
|
|
227
|
-
|
|
228
|
-
|
|
227
|
+
"AWS::AutoScaling::LaunchConfiguration",
|
|
228
|
+
"AWS::EC2::Instance",
|
|
229
229
|
]
|
|
230
230
|
|
|
231
231
|
# @return [Smash] initialized translators
|
|
@@ -262,20 +262,64 @@ module Sfn
|
|
|
262
262
|
:unavailable => Smash.new,
|
|
263
263
|
:unknown => Smash.new,
|
|
264
264
|
)
|
|
265
|
-
result
|
|
265
|
+
convert_to_plan(result)
|
|
266
266
|
end
|
|
267
267
|
|
|
268
268
|
protected
|
|
269
269
|
|
|
270
|
+
PLAN_CLASS = Miasma::Models::Orchestration::Stack::Plan
|
|
271
|
+
PLAN_MAP = {
|
|
272
|
+
:added => :add,
|
|
273
|
+
:removed => :remove,
|
|
274
|
+
:replace => :replace,
|
|
275
|
+
:interrupt => :interrupt,
|
|
276
|
+
:unavailable => :unavailable,
|
|
277
|
+
:unknown => :unknown,
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
# Convert result hash into plan object
|
|
281
|
+
#
|
|
282
|
+
# @param [Hash] plan hash data
|
|
283
|
+
# @return [Miasma::Models::Orchestration::Stack::Plan]
|
|
284
|
+
def convert_to_plan(result)
|
|
285
|
+
plan = PLAN_CLASS.new(origin_stack)
|
|
286
|
+
PLAN_MAP.each do |src, dst|
|
|
287
|
+
collection = result[src].map do |name, info|
|
|
288
|
+
item = PLAN_CLASS::Item.new(
|
|
289
|
+
:name => name,
|
|
290
|
+
:type => info[:type],
|
|
291
|
+
)
|
|
292
|
+
unless info[:diffs].empty?
|
|
293
|
+
item.diffs = info[:diffs].map do |d_info|
|
|
294
|
+
diff = PLAN_CLASS::Diff.new(
|
|
295
|
+
:name => d_info.fetch(:property_name, d_info[:path]),
|
|
296
|
+
:current => d_info[:original].to_json,
|
|
297
|
+
:proposed => d_info[:updated].to_json,
|
|
298
|
+
)
|
|
299
|
+
diff.valid_state
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
item.valid_state
|
|
303
|
+
end
|
|
304
|
+
plan.send("#{dst}=", collection)
|
|
305
|
+
end
|
|
306
|
+
plan.stacks = Smash[
|
|
307
|
+
result.fetch(:stacks, {}).map { |name, info|
|
|
308
|
+
[name, convert_to_plan(info)]
|
|
309
|
+
}
|
|
310
|
+
]
|
|
311
|
+
plan.valid_state
|
|
312
|
+
end
|
|
313
|
+
|
|
270
314
|
# Remote custom Stack property from Stack resources within template
|
|
271
315
|
#
|
|
272
316
|
# @param template [Hash]
|
|
273
317
|
# @return [TrueClass]
|
|
274
318
|
def scrub_stack_properties(template)
|
|
275
|
-
if template[
|
|
276
|
-
template[
|
|
277
|
-
if is_stack?(info[
|
|
278
|
-
info[
|
|
319
|
+
if template["Resources"]
|
|
320
|
+
template["Resources"].each do |name, info|
|
|
321
|
+
if is_stack?(info["Type"]) && info["Properties"].is_a?(Hash)
|
|
322
|
+
info["Properties"].delete("Stack")
|
|
279
323
|
end
|
|
280
324
|
end
|
|
281
325
|
end
|
|
@@ -289,11 +333,11 @@ module Sfn
|
|
|
289
333
|
# @return [Hash]
|
|
290
334
|
def get_global_parameters(stack)
|
|
291
335
|
Smash.new(
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
336
|
+
"AWS::Region" => stack.api.aws_region,
|
|
337
|
+
"AWS::AccountId" => stack.id.split(":")[4],
|
|
338
|
+
"AWS::NotificationARNs" => stack.notification_topics,
|
|
339
|
+
"AWS::StackId" => stack.id,
|
|
340
|
+
"AWS::StackName" => stack.name,
|
|
297
341
|
).merge(config.fetch(:planner, :global_parameters, {}))
|
|
298
342
|
end
|
|
299
343
|
|
|
@@ -345,7 +389,7 @@ module Sfn
|
|
|
345
389
|
# @param type [String]
|
|
346
390
|
# @return [TrueClass, FalseClass]
|
|
347
391
|
def is_stack?(type)
|
|
348
|
-
origin_stack.api.data.fetch(:stack_types, [
|
|
392
|
+
origin_stack.api.data.fetch(:stack_types, ["AWS::CloudFormation::Stack"]).include?(type)
|
|
349
393
|
end
|
|
350
394
|
|
|
351
395
|
# Scrub the plan results to only provide highest precedence diff
|
|
@@ -420,21 +464,21 @@ module Sfn
|
|
|
420
464
|
# @param plan_results [Smash]
|
|
421
465
|
# @return [NilClass]
|
|
422
466
|
def plan_nested_stacks(stack, translator, origin_template, new_template_hash, plan_results)
|
|
423
|
-
origin_stacks = origin_template.fetch(
|
|
424
|
-
is_stack?(s_val[
|
|
467
|
+
origin_stacks = origin_template.fetch("Resources", {}).find_all do |s_name, s_val|
|
|
468
|
+
is_stack?(s_val["Type"])
|
|
425
469
|
end.map(&:first)
|
|
426
|
-
new_stacks = (new_template_hash[
|
|
427
|
-
is_stack?(s_val[
|
|
470
|
+
new_stacks = (new_template_hash["Resources"] || {}).find_all do |s_name, s_val|
|
|
471
|
+
is_stack?(s_val["Type"])
|
|
428
472
|
end.map(&:first)
|
|
429
473
|
[origin_stacks + new_stacks].flatten.compact.uniq.each do |stack_name|
|
|
430
474
|
original_stack = stack.nested_stacks(false).detect do |stk|
|
|
431
475
|
stk.data[:logical_id] == stack_name
|
|
432
476
|
end
|
|
433
|
-
new_stack_exists = is_stack?(new_template_hash.get(
|
|
434
|
-
new_stack_template = new_template_hash.fetch(
|
|
435
|
-
new_stack_parameters = new_template_hash.fetch(
|
|
436
|
-
new_stack_type = new_template_hash.fetch(
|
|
437
|
-
origin_template.get(
|
|
477
|
+
new_stack_exists = is_stack?(new_template_hash.get("Resources", stack_name, "Type"))
|
|
478
|
+
new_stack_template = new_template_hash.fetch("Resources", stack_name, "Properties", "Stack", Smash.new)
|
|
479
|
+
new_stack_parameters = new_template_hash.fetch("Resources", stack_name, "Properties", "Parameters", Smash.new)
|
|
480
|
+
new_stack_type = new_template_hash.fetch("Resources", stack_name, "Type",
|
|
481
|
+
origin_template.get("Resources", stack_name, "Type"))
|
|
438
482
|
resource = Smash.new(
|
|
439
483
|
:name => stack_name,
|
|
440
484
|
:type => new_stack_type,
|
|
@@ -468,15 +512,15 @@ module Sfn
|
|
|
468
512
|
def diff_init(diff, path)
|
|
469
513
|
Smash.new.tap do |di|
|
|
470
514
|
if diff.size > 1
|
|
471
|
-
updated = diff.detect { |x| x.first ==
|
|
472
|
-
original = diff.detect { |x| x.first ==
|
|
515
|
+
updated = diff.detect { |x| x.first == "+" }
|
|
516
|
+
original = diff.detect { |x| x.first == "-" }
|
|
473
517
|
di[:original] = original.last.to_s
|
|
474
518
|
di[:updated] = updated.last.to_s
|
|
475
519
|
else
|
|
476
520
|
diff_data = diff.first
|
|
477
521
|
di[:path] = path
|
|
478
522
|
if diff_data.size == 3
|
|
479
|
-
di[diff_data.first ==
|
|
523
|
+
di[diff_data.first == "+" ? :updated : :original] = diff_data.last
|
|
480
524
|
else
|
|
481
525
|
di[:original] = diff_data[diff_data.size - 2].to_s
|
|
482
526
|
di[:updated] = diff_data.last.to_s
|
|
@@ -495,12 +539,12 @@ module Sfn
|
|
|
495
539
|
# @option :templates [Smash] :update
|
|
496
540
|
def register_diff(results, path, diff, translator, templates)
|
|
497
541
|
diff_info = diff_init(diff, path)
|
|
498
|
-
if path.start_with?(
|
|
499
|
-
p_path = path.split(
|
|
542
|
+
if path.start_with?("Resources")
|
|
543
|
+
p_path = path.split(".")
|
|
500
544
|
if p_path.size == 2
|
|
501
545
|
diff = diff.first
|
|
502
|
-
key = diff.first ==
|
|
503
|
-
type = (key == :added ? templates[:update] : templates[:origin]).get(
|
|
546
|
+
key = diff.first == "+" ? :added : :removed
|
|
547
|
+
type = (key == :added ? templates[:update] : templates[:origin]).get("Resources", p_path.last, "Type")
|
|
504
548
|
results[key][p_path.last] = Smash.new(
|
|
505
549
|
:name => p_path.last,
|
|
506
550
|
:type => type,
|
|
@@ -510,14 +554,14 @@ module Sfn
|
|
|
510
554
|
],
|
|
511
555
|
)
|
|
512
556
|
else
|
|
513
|
-
if p_path.include?(
|
|
557
|
+
if p_path.include?("Properties")
|
|
514
558
|
resource_name = p_path[1]
|
|
515
|
-
if p_path.size < 4 && p_path.last ==
|
|
559
|
+
if p_path.size < 4 && p_path.last == "Properties"
|
|
516
560
|
property_name = diff.flatten.compact.last.keys.first
|
|
517
561
|
else
|
|
518
|
-
property_name = p_path[3].to_s.sub(/\[\d+\]$/,
|
|
562
|
+
property_name = p_path[3].to_s.sub(/\[\d+\]$/, "")
|
|
519
563
|
end
|
|
520
|
-
type = templates.get(:origin,
|
|
564
|
+
type = templates.get(:origin, "Resources", resource_name, "Type")
|
|
521
565
|
resource = Smash.new(
|
|
522
566
|
:name => resource_name,
|
|
523
567
|
:type => type,
|
|
@@ -527,18 +571,18 @@ module Sfn
|
|
|
527
571
|
],
|
|
528
572
|
)
|
|
529
573
|
begin
|
|
530
|
-
if templates.get(:update,
|
|
574
|
+
if templates.get(:update, "Resources", resource_name, "Properties", property_name) == Translator::UNKNOWN_RUNTIME_RESULT
|
|
531
575
|
effect = :unknown
|
|
532
576
|
else
|
|
533
577
|
r_info = SparkleFormation::Resources::Aws.resource_lookup(type)
|
|
534
578
|
r_property = r_info.property(property_name)
|
|
535
579
|
if r_property
|
|
536
580
|
effect = r_property.update_causes(
|
|
537
|
-
templates.get(:update,
|
|
538
|
-
templates.get(:origin,
|
|
581
|
+
templates.get(:update, "Resources", resource_name),
|
|
582
|
+
templates.get(:origin, "Resources", resource_name)
|
|
539
583
|
)
|
|
540
584
|
else
|
|
541
|
-
raise KeyError.new
|
|
585
|
+
raise KeyError.new "Unknown property"
|
|
542
586
|
end
|
|
543
587
|
end
|
|
544
588
|
case effect.to_sym
|
|
@@ -556,15 +600,15 @@ module Sfn
|
|
|
556
600
|
rescue KeyError
|
|
557
601
|
set_resource(:unknown, results, resource_name, resource)
|
|
558
602
|
end
|
|
559
|
-
elsif p_path.include?(
|
|
603
|
+
elsif p_path.include?("AWS::CloudFormation::Init")
|
|
560
604
|
resource_name = p_path[1]
|
|
561
|
-
type = templates[:origin][
|
|
605
|
+
type = templates[:origin]["Resources"][resource_name]["Type"]
|
|
562
606
|
if REPLACE_ON_CFN_INIT_UPDATE.include?(type)
|
|
563
607
|
set_resource(:replace, results, resource_name,
|
|
564
608
|
Smash.new(
|
|
565
609
|
:name => resource_name,
|
|
566
610
|
:type => type,
|
|
567
|
-
:properties => [
|
|
611
|
+
:properties => ["AWS::CloudFormation::Init"],
|
|
568
612
|
:diffs => [
|
|
569
613
|
diff_info,
|
|
570
614
|
],
|
|
@@ -572,8 +616,8 @@ module Sfn
|
|
|
572
616
|
end
|
|
573
617
|
end
|
|
574
618
|
end
|
|
575
|
-
elsif path.start_with?(
|
|
576
|
-
o_resource_name = path.split(
|
|
619
|
+
elsif path.start_with?("Outputs")
|
|
620
|
+
o_resource_name = path.split(".")[1]
|
|
577
621
|
if o_resource_name
|
|
578
622
|
set_resource(
|
|
579
623
|
:outputs, results, o_resource_name,
|
|
@@ -619,31 +663,31 @@ module Sfn
|
|
|
619
663
|
translator.flag_ref(item)
|
|
620
664
|
end
|
|
621
665
|
template.keys.each do |t_key|
|
|
622
|
-
next if [
|
|
666
|
+
next if ["Outputs", "Resources"].include?(t_key)
|
|
623
667
|
template[t_key] = translator.dereference_processor(
|
|
624
|
-
template[t_key], [
|
|
668
|
+
template[t_key], ["DEREF"]
|
|
625
669
|
)
|
|
626
670
|
end
|
|
627
671
|
translator.original.replace(template)
|
|
628
|
-
[
|
|
672
|
+
["Outputs", "Resources"].each do |t_key|
|
|
629
673
|
if template[t_key]
|
|
630
674
|
template[t_key] = translator.dereference_processor(
|
|
631
|
-
template[t_key], [
|
|
675
|
+
template[t_key], ["DEREF", :all]
|
|
632
676
|
)
|
|
633
677
|
end
|
|
634
678
|
end
|
|
635
|
-
if template[
|
|
636
|
-
valid_resources = template[
|
|
637
|
-
if resource_value[
|
|
638
|
-
if translator.apply_condition(resource_value[
|
|
679
|
+
if template["Resources"]
|
|
680
|
+
valid_resources = template["Resources"].map do |resource_name, resource_value|
|
|
681
|
+
if resource_value["OnCondition"]
|
|
682
|
+
if translator.apply_condition(resource_value["OnCondition"])
|
|
639
683
|
resource_name
|
|
640
684
|
end
|
|
641
685
|
else
|
|
642
686
|
resource_name
|
|
643
687
|
end
|
|
644
688
|
end.compact
|
|
645
|
-
(template[
|
|
646
|
-
template[
|
|
689
|
+
(template["Resources"].keys - valid_resources).each do |resource_to_remove|
|
|
690
|
+
template["Resources"].delete(resource_to_remove)
|
|
647
691
|
end
|
|
648
692
|
end
|
|
649
693
|
translator.original.replace({})
|
data/lib/sfn/provider.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
1
|
+
require "logger"
|
|
2
|
+
require "sfn"
|
|
3
3
|
|
|
4
4
|
module Sfn
|
|
5
5
|
# Remote provider interface
|
|
@@ -41,14 +41,14 @@ module Sfn
|
|
|
41
41
|
args = args.to_smash
|
|
42
42
|
unless args.get(:miasma, :provider)
|
|
43
43
|
best_guess = (args[:miasma] || {}).keys.group_by do |key|
|
|
44
|
-
key.to_s.split(
|
|
44
|
+
key.to_s.split("_").first
|
|
45
45
|
end.sort do |x, y|
|
|
46
46
|
y.size <=> x.size
|
|
47
47
|
end.first
|
|
48
48
|
if best_guess
|
|
49
49
|
provider = best_guess.first.to_sym
|
|
50
50
|
else
|
|
51
|
-
raise ArgumentError.new
|
|
51
|
+
raise ArgumentError.new "Cannot auto determine :provider value for credentials"
|
|
52
52
|
end
|
|
53
53
|
else
|
|
54
54
|
provider = args[:miasma].delete(:provider).to_sym
|
|
@@ -58,13 +58,13 @@ module Sfn
|
|
|
58
58
|
args[:miasma][:aws_region] = args[:miasma].delete(:region)
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
|
-
if ENV[
|
|
61
|
+
if ENV["DEBUG"].to_s.downcase == "true"
|
|
62
62
|
log_to = STDOUT
|
|
63
63
|
else
|
|
64
64
|
if Gem.win_platform?
|
|
65
|
-
log_to =
|
|
65
|
+
log_to = "NUL"
|
|
66
66
|
else
|
|
67
|
-
log_to =
|
|
67
|
+
log_to = "/dev/null"
|
|
68
68
|
end
|
|
69
69
|
end
|
|
70
70
|
@logger = args.fetch(:logger, Logger.new(log_to))
|
|
@@ -101,7 +101,7 @@ module Sfn
|
|
|
101
101
|
fetch_stacks(stack_id) if recache
|
|
102
102
|
end
|
|
103
103
|
value = cache[:stacks].value
|
|
104
|
-
value ? MultiJson.dump(MultiJson.load(value).values) :
|
|
104
|
+
value ? MultiJson.dump(MultiJson.load(value).values) : "[]"
|
|
105
105
|
end
|
|
106
106
|
|
|
107
107
|
# @return [Miasma::Orchestration::Stack, NilClass]
|
|
@@ -118,7 +118,7 @@ module Sfn
|
|
|
118
118
|
current_stacks = MultiJson.load(cached_stacks)
|
|
119
119
|
cache.locked_action(:stacks_lock) do
|
|
120
120
|
logger.info "Saving expanded stack attributes in cache (#{stack_id})"
|
|
121
|
-
current_stacks[stack_id] = stack_attributes.merge(
|
|
121
|
+
current_stacks[stack_id] = stack_attributes.merge("Cached" => Time.now.to_i)
|
|
122
122
|
cache[:stacks].value = MultiJson.dump(current_stacks)
|
|
123
123
|
end
|
|
124
124
|
true
|
|
@@ -144,14 +144,14 @@ module Sfn
|
|
|
144
144
|
# @param stack [Miasma::Models::Orchestration::Stack]
|
|
145
145
|
def expand_stack(stack)
|
|
146
146
|
logger.info "Stack expansion requested (#{stack.id})"
|
|
147
|
-
if ((stack.in_progress? && Time.now.to_i - stack.attributes[
|
|
148
|
-
!stack.attributes[
|
|
147
|
+
if ((stack.in_progress? && Time.now.to_i - stack.attributes["Cached"].to_i > stack_expansion_interval) ||
|
|
148
|
+
!stack.attributes["Cached"])
|
|
149
149
|
begin
|
|
150
150
|
expanded = false
|
|
151
151
|
cache.locked_action(:stack_expansion_lock) do
|
|
152
152
|
expanded = true
|
|
153
153
|
stack.reload
|
|
154
|
-
stack.data[
|
|
154
|
+
stack.data["Cached"] = Time.now.to_i
|
|
155
155
|
end
|
|
156
156
|
if expanded
|
|
157
157
|
save_expanded_stack(stack.id, stack.to_json)
|
|
@@ -196,7 +196,7 @@ module Sfn
|
|
|
196
196
|
end
|
|
197
197
|
end
|
|
198
198
|
cache[:stacks].value = stacks.to_json
|
|
199
|
-
logger.info
|
|
199
|
+
logger.info "Stack list has been updated from upstream and cached locally"
|
|
200
200
|
end
|
|
201
201
|
@initial_fetch_complete = true
|
|
202
202
|
end
|