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