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.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/bin/sfn +16 -14
  4. data/lib/chef/knife/knife_plugin_seed.rb +12 -12
  5. data/lib/sfn.rb +17 -17
  6. data/lib/sfn/api_provider.rb +3 -3
  7. data/lib/sfn/api_provider/google.rb +2 -2
  8. data/lib/sfn/api_provider/terraform.rb +2 -2
  9. data/lib/sfn/cache.rb +9 -9
  10. data/lib/sfn/callback.rb +6 -6
  11. data/lib/sfn/callback/aws_assume_role.rb +5 -5
  12. data/lib/sfn/callback/aws_mfa.rb +8 -6
  13. data/lib/sfn/callback/stack_policy.rb +15 -15
  14. data/lib/sfn/command.rb +37 -36
  15. data/lib/sfn/command/conf.rb +12 -12
  16. data/lib/sfn/command/create.rb +9 -9
  17. data/lib/sfn/command/describe.rb +6 -6
  18. data/lib/sfn/command/destroy.rb +8 -8
  19. data/lib/sfn/command/diff.rb +31 -31
  20. data/lib/sfn/command/events.rb +6 -6
  21. data/lib/sfn/command/export.rb +8 -8
  22. data/lib/sfn/command/graph.rb +21 -21
  23. data/lib/sfn/command/graph/aws.rb +34 -34
  24. data/lib/sfn/command/graph/provider.rb +1 -1
  25. data/lib/sfn/command/graph/terraform.rb +41 -41
  26. data/lib/sfn/command/import.rb +17 -17
  27. data/lib/sfn/command/init.rb +15 -15
  28. data/lib/sfn/command/inspect.rb +16 -16
  29. data/lib/sfn/command/lint.rb +6 -6
  30. data/lib/sfn/command/list.rb +2 -2
  31. data/lib/sfn/command/plan.rb +227 -0
  32. data/lib/sfn/command/print.rb +4 -4
  33. data/lib/sfn/command/promote.rb +2 -2
  34. data/lib/sfn/command/update.rb +19 -144
  35. data/lib/sfn/command/validate.rb +17 -13
  36. data/lib/sfn/command_module.rb +6 -5
  37. data/lib/sfn/command_module/base.rb +8 -8
  38. data/lib/sfn/command_module/callbacks.rb +5 -5
  39. data/lib/sfn/command_module/planning.rb +151 -0
  40. data/lib/sfn/command_module/stack.rb +34 -34
  41. data/lib/sfn/command_module/template.rb +50 -50
  42. data/lib/sfn/config.rb +46 -44
  43. data/lib/sfn/config/conf.rb +3 -3
  44. data/lib/sfn/config/create.rb +9 -9
  45. data/lib/sfn/config/describe.rb +7 -7
  46. data/lib/sfn/config/destroy.rb +1 -1
  47. data/lib/sfn/config/diff.rb +3 -3
  48. data/lib/sfn/config/events.rb +9 -9
  49. data/lib/sfn/config/export.rb +5 -5
  50. data/lib/sfn/config/graph.rb +10 -10
  51. data/lib/sfn/config/import.rb +4 -4
  52. data/lib/sfn/config/init.rb +1 -1
  53. data/lib/sfn/config/inspect.rb +16 -16
  54. data/lib/sfn/config/lint.rb +5 -5
  55. data/lib/sfn/config/list.rb +6 -6
  56. data/lib/sfn/config/plan.rb +28 -0
  57. data/lib/sfn/config/print.rb +5 -5
  58. data/lib/sfn/config/promote.rb +4 -4
  59. data/lib/sfn/config/update.rb +18 -18
  60. data/lib/sfn/config/validate.rb +30 -30
  61. data/lib/sfn/lint.rb +5 -5
  62. data/lib/sfn/lint/definition.rb +3 -3
  63. data/lib/sfn/lint/rule.rb +3 -3
  64. data/lib/sfn/lint/rule_set.rb +2 -2
  65. data/lib/sfn/monkey_patch.rb +2 -2
  66. data/lib/sfn/monkey_patch/stack.rb +27 -27
  67. data/lib/sfn/monkey_patch/stack/azure.rb +1 -1
  68. data/lib/sfn/monkey_patch/stack/google.rb +5 -5
  69. data/lib/sfn/planner.rb +4 -4
  70. data/lib/sfn/planner/aws.rb +114 -70
  71. data/lib/sfn/provider.rb +13 -13
  72. data/lib/sfn/utils.rb +10 -10
  73. data/lib/sfn/utils/debug.rb +2 -2
  74. data/lib/sfn/utils/json.rb +1 -1
  75. data/lib/sfn/utils/object_storage.rb +3 -3
  76. data/lib/sfn/utils/output.rb +4 -4
  77. data/lib/sfn/utils/path_selector.rb +15 -15
  78. data/lib/sfn/utils/ssher.rb +4 -4
  79. data/lib/sfn/utils/stack_exporter.rb +16 -16
  80. data/lib/sfn/utils/stack_parameter_scrubber.rb +6 -6
  81. data/lib/sfn/utils/stack_parameter_validator.rb +22 -22
  82. data/lib/sfn/version.rb +1 -1
  83. data/sfn.gemspec +32 -32
  84. metadata +16 -13
@@ -1,53 +1,54 @@
1
- require 'sfn'
2
- require 'bogo-cli'
1
+ require "sfn"
2
+ require "bogo-cli"
3
3
 
4
4
  module Sfn
5
5
  class Command < Bogo::Cli::Command
6
6
  include CommandModule::Callbacks
7
7
 
8
- autoload :Conf, 'sfn/command/conf'
9
- autoload :Create, 'sfn/command/create'
10
- autoload :Describe, 'sfn/command/describe'
11
- autoload :Destroy, 'sfn/command/destroy'
12
- autoload :Diff, 'sfn/command/diff'
13
- autoload :Events, 'sfn/command/events'
14
- autoload :Export, 'sfn/command/export'
15
- autoload :Graph, 'sfn/command/graph'
16
- autoload :Import, 'sfn/command/import'
17
- autoload :Init, 'sfn/command/init'
18
- autoload :Inspect, 'sfn/command/inspect'
19
- autoload :Lint, 'sfn/command/lint'
20
- autoload :List, 'sfn/command/list'
21
- autoload :Print, 'sfn/command/print'
22
- autoload :Promote, 'sfn/command/promote'
23
- autoload :Update, 'sfn/command/update'
24
- autoload :Validate, 'sfn/command/validate'
8
+ autoload :Conf, "sfn/command/conf"
9
+ autoload :Create, "sfn/command/create"
10
+ autoload :Describe, "sfn/command/describe"
11
+ autoload :Destroy, "sfn/command/destroy"
12
+ autoload :Diff, "sfn/command/diff"
13
+ autoload :Events, "sfn/command/events"
14
+ autoload :Export, "sfn/command/export"
15
+ autoload :Graph, "sfn/command/graph"
16
+ autoload :Import, "sfn/command/import"
17
+ autoload :Init, "sfn/command/init"
18
+ autoload :Inspect, "sfn/command/inspect"
19
+ autoload :Lint, "sfn/command/lint"
20
+ autoload :List, "sfn/command/list"
21
+ autoload :Plan, "sfn/command/plan"
22
+ autoload :Print, "sfn/command/print"
23
+ autoload :Promote, "sfn/command/promote"
24
+ autoload :Update, "sfn/command/update"
25
+ autoload :Validate, "sfn/command/validate"
25
26
 
26
27
  # Base name of configuration file
27
- CONFIG_BASE_NAME = '.sfn'
28
+ CONFIG_BASE_NAME = ".sfn"
28
29
 
29
30
  # Supported configuration file extensions
30
31
  VALID_CONFIG_EXTENSIONS = [
31
- '',
32
- '.rb',
33
- '.json',
34
- '.yaml',
35
- '.yml',
36
- '.xml',
32
+ "",
33
+ ".rb",
34
+ ".json",
35
+ ".yaml",
36
+ ".yml",
37
+ ".xml",
37
38
  ]
38
39
 
39
40
  # Override to provide config file searching
40
41
  def initialize(cli_opts, args)
41
- unless cli_opts['config']
42
+ unless cli_opts["config"]
42
43
  discover_config(cli_opts)
43
44
  end
44
- unless ENV['DEBUG']
45
- ENV['DEBUG'] = 'true' if cli_opts[:debug]
45
+ unless ENV["DEBUG"]
46
+ ENV["DEBUG"] = "true" if cli_opts[:debug]
46
47
  end
47
48
  super(cli_opts, args)
48
49
  load_api_provider_extensions!
49
50
  run_callbacks_for(:after_config)
50
- run_callbacks_for("after_config_#{Bogo::Utility.snake(self.class.name.split('::').last)}")
51
+ run_callbacks_for("after_config_#{Bogo::Utility.snake(self.class.name.split("::").last)}")
51
52
  end
52
53
 
53
54
  # @return [Smash]
@@ -65,7 +66,7 @@ module Sfn
65
66
  def load_api_provider_extensions!
66
67
  if config.get(:credentials, :provider)
67
68
  base_ext = Bogo::Utility.camel(config.get(:credentials, :provider)).to_sym
68
- targ_ext = self.class.name.split('::').last
69
+ targ_ext = self.class.name.split("::").last
69
70
  if ApiProvider.constants.include?(base_ext)
70
71
  base_module = ApiProvider.const_get(base_ext)
71
72
  ui.debug "Loading core provider extensions via `#{base_module}`"
@@ -87,26 +88,26 @@ module Sfn
87
88
  # @return [Slop]
88
89
  def discover_config(opts)
89
90
  cwd = Dir.pwd.split(File::SEPARATOR)
90
- detected_path = ''
91
+ detected_path = ""
91
92
  until cwd.empty? || File.exists?(detected_path.to_s)
92
93
  detected_path = Dir.glob(
93
- (cwd + ["#{CONFIG_BASE_NAME}{#{VALID_CONFIG_EXTENSIONS.join(',')}}"]).join(
94
+ (cwd + ["#{CONFIG_BASE_NAME}{#{VALID_CONFIG_EXTENSIONS.join(",")}}"]).join(
94
95
  File::SEPARATOR
95
96
  )
96
97
  ).first
97
98
  cwd.pop
98
99
  end
99
100
  if opts.respond_to?(:fetch_option)
100
- opts.fetch_option('config').value = detected_path if detected_path
101
+ opts.fetch_option("config").value = detected_path if detected_path
101
102
  else
102
- opts['config'] = detected_path if detected_path
103
+ opts["config"] = detected_path if detected_path
103
104
  end
104
105
  opts
105
106
  end
106
107
 
107
108
  # @return [Class] attempt to return customized configuration class
108
109
  def config_class
109
- klass_name = self.class.name.split('::').last
110
+ klass_name = self.class.name.split("::").last
110
111
  if Sfn::Config.const_defined?(klass_name)
111
112
  Sfn::Config.const_get(klass_name)
112
113
  else
@@ -1,4 +1,4 @@
1
- require 'sfn'
1
+ require "sfn"
2
2
 
3
3
  module Sfn
4
4
  class Command
@@ -12,42 +12,42 @@ module Sfn
12
12
  Config::Conf.attributes.sort_by(&:first).each do |k, val|
13
13
  if config.has_key?(k)
14
14
  ui.print " #{ui.color(k, :bold, :green)}: "
15
- format_value(config[k], ' ')
15
+ format_value(config[k], " ")
16
16
  end
17
17
  end
18
18
  if config[:generate]
19
19
  ui.puts
20
- ui.info 'Generating .sfn configuration file..'
20
+ ui.info "Generating .sfn configuration file.."
21
21
  generate_config!
22
- ui.info "Generation of .sfn configuration file #{ui.color('complete!', :green, :bold)}"
22
+ ui.info "Generation of .sfn configuration file #{ui.color("complete!", :green, :bold)}"
23
23
  end
24
24
  end
25
25
 
26
26
  def generate_config!
27
- if File.exists?('.sfn')
28
- ui.warn 'Existing .sfn configuration file detected!'
29
- ui.confirm 'Overwrite current .sfn configuration file?'
27
+ if File.exists?(".sfn")
28
+ ui.warn "Existing .sfn configuration file detected!"
29
+ ui.confirm "Overwrite current .sfn configuration file?"
30
30
  end
31
- run_action 'Writing .sfn file' do
32
- File.open('.sfn', 'w') do |file|
31
+ run_action "Writing .sfn file" do
32
+ File.open(".sfn", "w") do |file|
33
33
  file.write SFN_CONFIG_CONTENTS
34
34
  end
35
35
  nil
36
36
  end
37
37
  end
38
38
 
39
- def format_value(value, indent = '')
39
+ def format_value(value, indent = "")
40
40
  if value.is_a?(Hash)
41
41
  ui.puts
42
42
  value.sort_by(&:first).each do |k, v|
43
43
  ui.print "#{indent} #{ui.color(k, :bold)}: "
44
- format_value(v, indent + ' ')
44
+ format_value(v, indent + " ")
45
45
  end
46
46
  elsif value.is_a?(Array)
47
47
  ui.puts
48
48
  value.map(&:to_s).sort.each do |v|
49
49
  ui.print "#{indent} "
50
- format_value(v, indent + ' ')
50
+ format_value(v, indent + " ")
51
51
  end
52
52
  else
53
53
  ui.puts value.to_s
@@ -1,5 +1,5 @@
1
- require 'sparkle_formation'
2
- require 'sfn'
1
+ require "sparkle_formation"
2
+ require "sfn"
3
3
 
4
4
  module Sfn
5
5
  class Command
@@ -24,12 +24,12 @@ module Sfn
24
24
  end
25
25
 
26
26
  unless config[:print_only]
27
- ui.info "#{ui.color('SparkleFormation:', :bold)} #{ui.color('create', :green)}"
27
+ ui.info "#{ui.color("SparkleFormation:", :bold)} #{ui.color("create", :green)}"
28
28
  end
29
29
 
30
- stack_info = "#{ui.color('Name:', :bold)} #{name}"
30
+ stack_info = "#{ui.color("Name:", :bold)} #{name}"
31
31
  if config[:path]
32
- stack_info << " #{ui.color('Path:', :bold)} #{config[:file]}"
32
+ stack_info << " #{ui.color("Path:", :bold)} #{config[:file]}"
33
33
  end
34
34
 
35
35
  if config[:print_only]
@@ -66,14 +66,14 @@ module Sfn
66
66
  stack = provider.stack(name)
67
67
 
68
68
  if stack.reload.state == :create_complete
69
- ui.info "Stack create complete: #{ui.color('SUCCESS', :green)}"
69
+ ui.info "Stack create complete: #{ui.color("SUCCESS", :green)}"
70
70
  namespace.const_get(:Describe).new({:outputs => true}, [name]).execute!
71
71
  else
72
- ui.fatal "Create of new stack #{ui.color(name, :bold)}: #{ui.color('FAILED', :red, :bold)}"
73
- raise 'Stack did not reach a successful completion state.'
72
+ ui.fatal "Create of new stack #{ui.color(name, :bold)}: #{ui.color("FAILED", :red, :bold)}"
73
+ raise "Stack did not reach a successful completion state."
74
74
  end
75
75
  else
76
- ui.warn 'Stack state polling has been disabled.'
76
+ ui.warn "Stack state polling has been disabled."
77
77
  ui.info "Stack creation initialized for #{ui.color(name, :green)}"
78
78
  end
79
79
  end
@@ -1,4 +1,4 @@
1
- require 'sfn'
1
+ require "sfn"
2
2
 
3
3
  module Sfn
4
4
  class Command
@@ -75,11 +75,11 @@ module Sfn
75
75
  unless stack.outputs.nil? || stack.outputs.empty?
76
76
  stack.outputs.each do |output|
77
77
  key, value = output.key, output.value
78
- key = snake(key).to_s.split('_').map(&:capitalize).join(' ')
79
- ui.info [' ', ui.color("#{key}:", :bold), value].join(' ')
78
+ key = snake(key).to_s.split("_").map(&:capitalize).join(" ")
79
+ ui.info [" ", ui.color("#{key}:", :bold), value].join(" ")
80
80
  end
81
81
  else
82
- ui.info " #{ui.color('No outputs found')}"
82
+ ui.info " #{ui.color("No outputs found")}"
83
83
  end
84
84
  end
85
85
 
@@ -90,10 +90,10 @@ module Sfn
90
90
  ui.info "Tags for stack: #{ui.color(stack.name, :bold)}"
91
91
  if stack.tags && !stack.tags.empty?
92
92
  stack.tags.each do |key, value|
93
- ui.info [' ', ui.color("#{key}:", :bold), value].join(' ')
93
+ ui.info [" ", ui.color("#{key}:", :bold), value].join(" ")
94
94
  end
95
95
  else
96
- ui.info " #{ui.color('No tags found')}"
96
+ ui.info " #{ui.color("No tags found")}"
97
97
  end
98
98
  end
99
99
 
@@ -1,4 +1,4 @@
1
- require 'sfn'
1
+ require "sfn"
2
2
 
3
3
  module Sfn
4
4
  class Command
@@ -9,7 +9,7 @@ module Sfn
9
9
  def execute!
10
10
  name_required!
11
11
  stacks = name_args.sort
12
- plural = 's' if stacks.size > 1
12
+ plural = "s" if stacks.size > 1
13
13
  globs = stacks.find_all do |s|
14
14
  s !~ /^[a-zA-Z0-9-]+$/
15
15
  end
@@ -23,7 +23,7 @@ module Sfn
23
23
  stacks -= globs
24
24
  stacks.sort!
25
25
  end
26
- ui.warn "Destroying Stack#{plural}: #{ui.color(stacks.join(', '), :bold)}"
26
+ ui.warn "Destroying Stack#{plural}: #{ui.color(stacks.join(", "), :bold)}"
27
27
  ui.confirm "Destroy listed stack#{plural}?"
28
28
  stacks.each do |stack_name|
29
29
  stack = provider.connection.stacks.get(stack_name)
@@ -56,7 +56,7 @@ module Sfn
56
56
  ui.error "Stack polling is not available when multiple stack deletion is requested!"
57
57
  end
58
58
  end
59
- ui.info " -> Destroyed SparkleFormation#{plural}: #{ui.color(stacks.join(', '), :bold, :red)}"
59
+ ui.info " -> Destroyed SparkleFormation#{plural}: #{ui.color(stacks.join(", "), :bold, :red)}"
60
60
  end
61
61
 
62
62
  # Cleanup persisted templates if nested stack resources are included
@@ -64,12 +64,12 @@ module Sfn
64
64
  stack.nested_stacks.each do |n_stack|
65
65
  nested_stack_cleanup!(n_stack)
66
66
  end
67
- nest_stacks = stack.template.fetch('Resources', {}).values.find_all do |resource|
68
- provider.connection.data[:stack_types].include?(resource['Type'])
67
+ nest_stacks = stack.template.fetch("Resources", {}).values.find_all do |resource|
68
+ provider.connection.data[:stack_types].include?(resource["Type"])
69
69
  end.each do |resource|
70
- url = resource['Properties']['TemplateURL']
70
+ url = resource["Properties"]["TemplateURL"]
71
71
  if url && url.is_a?(String)
72
- _, bucket_name, path = URI.parse(url).path.split('/', 3)
72
+ _, bucket_name, path = URI.parse(url).path.split("/", 3)
73
73
  bucket = provider.connection.api_for(:storage).buckets.get(bucket_name)
74
74
  if bucket
75
75
  file = bucket.files.get(path)
@@ -1,6 +1,6 @@
1
- require 'sparkle_formation'
2
- require 'sfn'
3
- require 'hashdiff'
1
+ require "sparkle_formation"
2
+ require "sfn"
3
+ require "hashdiff"
4
4
 
5
5
  module Sfn
6
6
  class Command
@@ -26,7 +26,7 @@ module Sfn
26
26
  file = load_template_file
27
27
  file = parameter_scrub!(file.dump)
28
28
 
29
- ui.info "#{ui.color('SparkleFormation:', :bold)} #{ui.color('diff', :blue)} - #{name}"
29
+ ui.info "#{ui.color("SparkleFormation:", :bold)} #{ui.color("diff", :blue)} - #{name}"
30
30
  ui.puts
31
31
 
32
32
  diff_stack(stack, MultiJson.load(MultiJson.dump(file)).to_smash)
@@ -40,8 +40,8 @@ module Sfn
40
40
  def diff_stack(stack, file, parent_names = [])
41
41
  stack_template = stack.template
42
42
  nested_stacks = Hash[
43
- file.fetch('Resources', file.fetch('resources', {})).find_all do |name, value|
44
- value.fetch('Properties', {})['Stack']
43
+ file.fetch("Resources", file.fetch("resources", {})).find_all do |name, value|
44
+ value.fetch("Properties", {})["Stack"]
45
45
  end
46
46
  ]
47
47
  nested_stacks.each do |name, value|
@@ -49,58 +49,58 @@ module Sfn
49
49
  ns.data[:logical_id] == name
50
50
  end
51
51
  if n_stack
52
- diff_stack(n_stack, value['Properties']['Stack'], [*parent_names, stack.data.fetch(:logical_id, stack.name)].compact)
52
+ diff_stack(n_stack, value["Properties"]["Stack"], [*parent_names, stack.data.fetch(:logical_id, stack.name)].compact)
53
53
  end
54
- file['Resources'][name]['Properties'].delete('Stack')
54
+ file["Resources"][name]["Properties"].delete("Stack")
55
55
  end
56
56
 
57
- ui.info "#{ui.color('Stack diff:', :bold)} #{ui.color((parent_names + [stack.data.fetch(:logical_id, stack.name)]).compact.join(' > '), :blue)}"
57
+ ui.info "#{ui.color("Stack diff:", :bold)} #{ui.color((parent_names + [stack.data.fetch(:logical_id, stack.name)]).compact.join(" > "), :blue)}"
58
58
 
59
59
  stack_diff = HashDiff.diff(stack.template, file)
60
60
 
61
61
  if config[:raw_diff]
62
62
  ui.info "Dumping raw template diff:"
63
- require 'pp'
63
+ require "pp"
64
64
  pp stack_diff
65
65
  else
66
66
  added_resources = stack_diff.find_all do |item|
67
- item.first == '+' && item[1].match(/Resources\.[^.]+$/)
67
+ item.first == "+" && item[1].match(/Resources\.[^.]+$/)
68
68
  end
69
69
  removed_resources = stack_diff.find_all do |item|
70
- item.first == '-' && item[1].match(/Resources\.[^.]+$/)
70
+ item.first == "-" && item[1].match(/Resources\.[^.]+$/)
71
71
  end
72
72
  modified_resources = stack_diff.find_all do |item|
73
- item[1].start_with?('Resources.') &&
74
- !item[1].end_with?('TemplateURL') &&
75
- !item[1].include?('Properties.Parameters')
73
+ item[1].start_with?("Resources.") &&
74
+ !item[1].end_with?("TemplateURL") &&
75
+ !item[1].include?("Properties.Parameters")
76
76
  end - added_resources - removed_resources
77
77
 
78
78
  if added_resources.empty? && removed_resources.empty? && modified_resources.empty?
79
- ui.info 'No changes detected'
79
+ ui.info "No changes detected"
80
80
  ui.puts
81
81
  else
82
82
  unless added_resources.empty?
83
- ui.info ui.color('Added Resources:', :green, :bold)
83
+ ui.info ui.color("Added Resources:", :green, :bold)
84
84
  added_resources.each do |item|
85
- ui.print ui.color(" -> #{item[1].split('.').last}", :green)
86
- ui.puts " [#{item[2]['Type']}]"
85
+ ui.print ui.color(" -> #{item[1].split(".").last}", :green)
86
+ ui.puts " [#{item[2]["Type"]}]"
87
87
  end
88
88
  ui.puts
89
89
  end
90
90
 
91
91
  unless modified_resources.empty?
92
- ui.info ui.color('Modified Resources:', :yellow, :bold)
92
+ ui.info ui.color("Modified Resources:", :yellow, :bold)
93
93
  m_resources = Hash.new.tap do |hash|
94
94
  modified_resources.each do |item|
95
- _, key, path = item[1].split('.', 3)
95
+ _, key, path = item[1].split(".", 3)
96
96
  hash[key] ||= {}
97
- prefix, a_key = path.split('.', 2)
97
+ prefix, a_key = path.split(".", 2)
98
98
  hash[key][prefix] ||= []
99
99
  matched = hash[key][prefix].detect do |i|
100
100
  i[:path] == a_key
101
101
  end
102
102
  if matched
103
- if item.first == '-'
103
+ if item.first == "-"
104
104
  matched[:original] = item[2]
105
105
  else
106
106
  matched[:new] = item[2]
@@ -109,10 +109,10 @@ module Sfn
109
109
  hash[key][prefix] << Hash.new.tap do |info|
110
110
  info[:path] = a_key
111
111
  case item.first
112
- when '~'
112
+ when "~"
113
113
  info[:original] = item[2]
114
114
  info[:new] = item[3]
115
- when '+'
115
+ when "+"
116
116
  info[:new] = item[2]
117
117
  else
118
118
  info[:original] = item[2]
@@ -121,12 +121,12 @@ module Sfn
121
121
  end
122
122
  end
123
123
  end.to_smash(:sorted).each do |key, value|
124
- ui.puts ui.color(" - #{key}", :yellow) + " [#{stack.template['Resources'][key]['Type']}]"
124
+ ui.puts ui.color(" - #{key}", :yellow) + " [#{stack.template["Resources"][key]["Type"]}]"
125
125
  value.each do |prefix, items|
126
126
  ui.puts ui.color(" #{prefix}:", :bold)
127
127
  items.each do |item|
128
- original = item[:original].nil? ? ui.color('(none)', :yellow) : ui.color(item[:original].inspect, :red)
129
- new_val = item[:new].nil? ? ui.color('(deleted)', :red) : ui.color(item[:new].inspect, :green)
128
+ original = item[:original].nil? ? ui.color("(none)", :yellow) : ui.color(item[:original].inspect, :red)
129
+ new_val = item[:new].nil? ? ui.color("(deleted)", :red) : ui.color(item[:new].inspect, :green)
130
130
  ui.puts " #{item[:path]}: #{original} -> #{new_val}"
131
131
  end
132
132
  end
@@ -135,10 +135,10 @@ module Sfn
135
135
  end
136
136
 
137
137
  unless removed_resources.empty?
138
- ui.info ui.color('Removed Resources:', :red, :bold)
138
+ ui.info ui.color("Removed Resources:", :red, :bold)
139
139
  removed_resources.each do |item|
140
- ui.print ui.color(" <- #{item[1].split('.').last}", :red)
141
- ui.puts " [#{item[2]['Type']}]"
140
+ ui.print ui.color(" <- #{item[1].split(".").last}", :red)
141
+ ui.puts " [#{item[2]["Type"]}]"
142
142
  end
143
143
  ui.puts
144
144
  end