sfn 3.0.30 → 3.0.32

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,151 @@
1
+ require "sfn"
2
+ require "sparkle_formation"
3
+
4
+ module Sfn
5
+ module CommandModule
6
+ # Planning helpers
7
+ module Planning
8
+ # Create a new planner instance
9
+ #
10
+ # @param [Miasma::Models::Orchestration::Stack]
11
+ # @return [Sfn::Planner]
12
+ def build_planner(stack)
13
+ klass_name = stack.api.class.to_s.split("::").last
14
+ if Planner.const_defined?(klass_name)
15
+ Planner.const_get(klass_name).new(ui, config, arguments, stack)
16
+ else
17
+ warn "Failed to build planner for current provider. No provider implemented. (`#{klass_name}`)"
18
+ nil
19
+ end
20
+ end
21
+
22
+ # Display plan result on the UI
23
+ #
24
+ # @param result [Miasma::Models::Orchestration::Stack::Plan]
25
+ def display_plan_information(result)
26
+ ui.info ui.color("Pre-update resource planning report:", :bold)
27
+ unless print_plan_result(result, [result.name])
28
+ ui.info "No resources life cycle changes detected in this update!"
29
+ end
30
+ cmd = self.class.to_s.split("::").last.downcase
31
+ ui.confirm "Apply this stack #{cmd}?" unless config[:plan_only]
32
+ end
33
+
34
+ # Print plan information to the UI
35
+ #
36
+ # @param info [Miasma::Models::Orchestration::Stack::Plan]
37
+ # @param names [Array<String>] nested names
38
+ def print_plan_result(info, names = [])
39
+ said_any_things = false
40
+ unless Array(info.stacks).empty?
41
+ info.stacks.each do |s_name, s_info|
42
+ result = print_plan_result(s_info, [*names, s_name].compact)
43
+ said_any_things ||= result
44
+ end
45
+ end
46
+ if !names.flatten.compact.empty? || info.name
47
+ said_things = false
48
+ output_name = names.empty? ? info.name : names.join(" > ")
49
+ ui.puts
50
+ ui.puts " #{ui.color("Update plan for:", :bold)} #{ui.color(names.join(" > "), :blue)}"
51
+ unless Array(info.unknown).empty?
52
+ ui.puts " #{ui.color("!!! Unknown update effect:", :red, :bold)}"
53
+ print_plan_items(info, :unknown, :red)
54
+ ui.puts
55
+ said_any_things = said_things = true
56
+ end
57
+ unless Array(info.unavailable).empty?
58
+ ui.puts " #{ui.color("Update request not allowed:", :red, :bold)}"
59
+ print_plan_items(info, :unavailable, :red)
60
+ ui.puts
61
+ said_any_things = said_things = true
62
+ end
63
+ unless Array(info.replace).empty?
64
+ ui.puts " #{ui.color("Resources to be replaced:", :red, :bold)}"
65
+ print_plan_items(info, :replace, :red)
66
+ ui.puts
67
+ said_any_things = said_things = true
68
+ end
69
+ unless Array(info.interrupt).empty?
70
+ ui.puts " #{ui.color("Resources to be interrupted:", :yellow, :bold)}"
71
+ print_plan_items(info, :interrupt, :yellow)
72
+ ui.puts
73
+ said_any_things = said_things = true
74
+ end
75
+ unless Array(info.remove).empty?
76
+ ui.puts " #{ui.color("Resources to be removed:", :red, :bold)}"
77
+ print_plan_items(info, :remove, :red)
78
+ ui.puts
79
+ said_any_things = said_things = true
80
+ end
81
+ unless Array(info.add).empty?
82
+ ui.puts " #{ui.color("Resources to be added:", :green, :bold)}"
83
+ print_plan_items(info, :add, :green)
84
+ ui.puts
85
+ said_any_things = said_things = true
86
+ end
87
+ unless said_things
88
+ ui.puts " #{ui.color("No resource lifecycle changes detected!", :green)}"
89
+ ui.puts
90
+ said_any_things = true
91
+ end
92
+ end
93
+ said_any_things
94
+ end
95
+
96
+ # Print planning items
97
+ #
98
+ # @param info [Miasma::Models::Orchestration::Stack::Plan] plan
99
+ # @param key [Symbol] key of items
100
+ # @param color [Symbol] color to flag
101
+ def print_plan_items(info, key, color)
102
+ collection = info.send(key)
103
+ max_name = collection.map(&:name).map(&:size).max
104
+ max_type = collection.map(&:type).map(&:size).max
105
+ max_p = collection.map(&:diffs).flatten(1).map(&:name).map(&:to_s).map(&:size).max
106
+ max_o = collection.map(&:diffs).flatten(1).map(&:current).map(&:to_s).map(&:size).max
107
+ collection.each do |val|
108
+ name = val.name
109
+ ui.print " " * 6
110
+ ui.print ui.color("[#{val.type}]", color)
111
+ ui.print " " * (max_type - val.type.size)
112
+ ui.print " " * 4
113
+ ui.print ui.color(name, :bold)
114
+ properties = Array(val.diffs).map(&:name)
115
+ unless properties.empty?
116
+ ui.print " " * (max_name - name.size)
117
+ ui.print " " * 4
118
+ ui.print "Reason: `#{properties.join("`, `")}`"
119
+ end
120
+ ui.puts
121
+ if config[:diffs]
122
+ unless val.diffs.empty?
123
+ p_name = nil
124
+ val.diffs.each do |diff|
125
+ if !diff.proposed.nil? || !diff.current.nil?
126
+ p_name = diff.name
127
+ ui.print " " * 8
128
+ ui.print "#{p_name}: "
129
+ ui.print " " * (max_p - p_name.size)
130
+ ui.print ui.color("-#{diff.current}", :red) if diff.current
131
+ ui.print " " * (max_o - diff.current.to_s.size)
132
+ ui.print " "
133
+ if diff.proposed == Sfn::Planner::RUNTIME_MODIFIED
134
+ ui.puts ui.color("+#{diff.current} <Dependency Modified>", :green)
135
+ else
136
+ if diff.proposed.nil?
137
+ ui.puts
138
+ else
139
+ ui.puts ui.color("+#{diff.proposed.to_s.gsub("__MODIFIED_REFERENCE_VALUE__", "<Dependency Modified>")}", :green)
140
+ end
141
+ end
142
+ end
143
+ end
144
+ ui.puts if p_name
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
@@ -1,5 +1,5 @@
1
- require 'sfn'
2
- require 'sparkle_formation'
1
+ require "sfn"
2
+ require "sparkle_formation"
3
3
 
4
4
  module Sfn
5
5
  module CommandModule
@@ -10,13 +10,13 @@ module Sfn
10
10
  # maximum number of attempts to get valid parameter value
11
11
  MAX_PARAMETER_ATTEMPTS = 5
12
12
  # Template parameter locations
13
- TEMPLATE_PARAMETER_LOCATIONS = ['Parameters', 'parameters']
13
+ TEMPLATE_PARAMETER_LOCATIONS = ["Parameters", "parameters"]
14
14
  # Template parameter default value locations
15
- TEMPLATE_PARAMETER_DEFAULTS = ['Default', 'defaultValue', 'default']
15
+ TEMPLATE_PARAMETER_DEFAULTS = ["Default", "defaultValue", "default"]
16
16
  # Template parameter no echo locations
17
- TEMPLATE_PARAMETER_NOECHO = ['NoEcho']
17
+ TEMPLATE_PARAMETER_NOECHO = ["NoEcho"]
18
18
  # Template parameter no echo custom
19
- TEMPLATE_PARAMETER_SFN_NOECHO = ['Quiet', 'quiet']
19
+ TEMPLATE_PARAMETER_SFN_NOECHO = ["Quiet", "quiet"]
20
20
 
21
21
  # Apply any defined remote stacks
22
22
  #
@@ -25,7 +25,7 @@ module Sfn
25
25
  def apply_stacks!(stack)
26
26
  remote_stacks = [config[:apply_stack]].flatten.compact
27
27
  remote_stacks.each do |stack_name|
28
- stack_info = stack_name.split('__')
28
+ stack_info = stack_name.split("__")
29
29
  stack_info.unshift(nil) if stack_info.size == 1
30
30
  stack_location, stack_name = stack_info
31
31
  remote_stack = provider_for(stack_location).stack(stack_name)
@@ -66,7 +66,7 @@ module Sfn
66
66
  if config[:apply_mapping]
67
67
  valid_keys = config[:apply_mapping].keys.find_all do |a_key|
68
68
  a_key = a_key.to_s
69
- key_parts = a_key.split('__')
69
+ key_parts = a_key.split("__")
70
70
  case key_parts.size
71
71
  when 3
72
72
  provider_stack.api.data[:location] == key_parts[0] &&
@@ -85,7 +85,7 @@ module Sfn
85
85
  valid_keys -= to_remove
86
86
  Hash[
87
87
  valid_keys.map do |a_key|
88
- cut_key = a_key.split('__').last
88
+ cut_key = a_key.split("__").last
89
89
  [cut_key, config[:apply_mapping][a_key]]
90
90
  end
91
91
  ]
@@ -148,16 +148,16 @@ module Sfn
148
148
  # @param parameter_name [String] parameter name
149
149
  # @return [Array<String>] [expected_template_key, configuration_used_key]
150
150
  def locate_config_parameter_key(parameter_prefix, parameter_name, root_name)
151
- check_name = parameter_name.downcase.tr('-_', '')
152
- check_prefix = parameter_prefix.map { |i| i.downcase.tr('-_', '') }
151
+ check_name = parameter_name.downcase.tr("-_", "")
152
+ check_prefix = parameter_prefix.map { |i| i.downcase.tr("-_", "") }
153
153
  key_match = config[:parameters].keys.detect do |cp_key|
154
- cp_key = cp_key.to_s.downcase.split('__').map { |i| i.tr('-_', '') }.join('__')
155
- non_root_matcher = (check_prefix + [check_name]).join('__')
156
- root_matcher = ([root_name] + check_prefix + [check_name]).join('__')
154
+ cp_key = cp_key.to_s.downcase.split("__").map { |i| i.tr("-_", "") }.join("__")
155
+ non_root_matcher = (check_prefix + [check_name]).join("__")
156
+ root_matcher = ([root_name] + check_prefix + [check_name]).join("__")
157
157
  cp_key == non_root_matcher ||
158
158
  cp_key == root_matcher
159
159
  end
160
- actual_key = (parameter_prefix + [parameter_name]).compact.join('__')
160
+ actual_key = (parameter_prefix + [parameter_name]).compact.join("__")
161
161
  if key_match
162
162
  ui.debug "Remapping configuration runtime parameter `#{key_match}` -> `#{actual_key}`"
163
163
  config[:parameters][actual_key] = config[:parameters].delete(key_match)
@@ -179,9 +179,9 @@ module Sfn
179
179
  attempt = 0
180
180
  if !valid && !param_banner
181
181
  if sparkle.is_a?(SparkleFormation)
182
- ui.info "#{ui.color('Stack runtime parameters:', :bold)} - template: #{ui.color(sparkle.root_path.map(&:name).map(&:to_s).join(' > '), :green, :bold)}"
182
+ ui.info "#{ui.color("Stack runtime parameters:", :bold)} - template: #{ui.color(sparkle.root_path.map(&:name).map(&:to_s).join(" > "), :green, :bold)}"
183
183
  else
184
- ui.info ui.color('Stack runtime parameters:', :bold)
184
+ ui.info ui.color("Stack runtime parameters:", :bold)
185
185
  end
186
186
  param_banner = true
187
187
  end
@@ -194,17 +194,17 @@ module Sfn
194
194
  )
195
195
  if config[:interactive_parameters]
196
196
  no_echo = !!TEMPLATE_PARAMETER_NOECHO.detect { |loc_key|
197
- param_value[loc_key].to_s.downcase == 'true'
197
+ param_value[loc_key].to_s.downcase == "true"
198
198
  }
199
199
  sfn_no_echo = TEMPLATE_PARAMETER_SFN_NOECHO.map do |loc_key|
200
200
  res = param_value.delete(loc_key).to_s.downcase
201
- res if !res.empty? && res != 'false'
201
+ res if !res.empty? && res != "false"
202
202
  end.compact.first
203
203
  no_echo = sfn_no_echo if sfn_no_echo
204
204
  answer = ui.ask_question(
205
- "#{param_name.split(/([A-Z]+[^A-Z]*)/).find_all { |s| !s.empty? }.join(' ')}",
205
+ "#{param_name.split(/([A-Z]+[^A-Z]*)/).find_all { |s| !s.empty? }.join(" ")}",
206
206
  :default => default,
207
- :hide_default => sfn_no_echo == 'all',
207
+ :hide_default => sfn_no_echo == "all",
208
208
  :no_echo => !!no_echo,
209
209
  )
210
210
  else
@@ -216,11 +216,11 @@ module Sfn
216
216
  valid = true
217
217
  else
218
218
  validation.each do |validation_error|
219
- ui.error validation_error.last
219
+ ui.error "#{param_name}: #{validation_error.last}"
220
220
  end
221
221
  end
222
222
  if attempt > MAX_PARAMETER_ATTEMPTS
223
- ui.fatal 'Failed to receive allowed parameter!'
223
+ ui.fatal "Failed to receive allowed parameter!"
224
224
  exit 1
225
225
  end
226
226
  end
@@ -279,8 +279,8 @@ module Sfn
279
279
  end
280
280
  Smash[
281
281
  config.fetch(:parameters, {}).map do |k, v|
282
- strip_key = parameter_prefix ? k.sub(/#{parameter_prefix.join('__')}_{2}?/, '') : k
283
- unless strip_key.include?('__')
282
+ strip_key = parameter_prefix ? k.sub(/#{parameter_prefix.join("__")}_{2}?/, "") : k
283
+ unless strip_key.include?("__")
284
284
  [strip_key, v]
285
285
  end
286
286
  end.compact
@@ -299,7 +299,7 @@ module Sfn
299
299
  def config_root_parameters
300
300
  Hash[
301
301
  config.fetch(:parameters, {}).find_all do |k, v|
302
- !k.include?('__')
302
+ !k.include?("__")
303
303
  end
304
304
  ]
305
305
  end
@@ -318,13 +318,13 @@ module Sfn
318
318
  def validate_stack_parameter(c_stack, p_key, p_ns_key, c_value)
319
319
  stack_value = c_stack.parameters[p_key]
320
320
  p_stack = c_stack.data[:parent_stack]
321
- unless config[:parameter_validation] == 'none'
321
+ unless config[:parameter_validation] == "none"
322
322
  if c_value.is_a?(Hash)
323
323
  case c_value.keys.first
324
- when 'Ref'
324
+ when "Ref"
325
325
  current_value = p_stack.parameters[c_value.values.first]
326
- when 'Fn::Att'
327
- resource_name, output_name = c_value.values.first.split('.', 2)
326
+ when "Fn::Att"
327
+ resource_name, output_name = c_value.values.first.split(".", 2)
328
328
  ref_stack = p_stack.nested_stacks.detect { |i| i.data[:logical_id] == resource_name }
329
329
  if ref_stack
330
330
  output = ref_stack.outputs.detect do |o|
@@ -339,14 +339,14 @@ module Sfn
339
339
  current_value = c_value
340
340
  end
341
341
  if current_value && current_value.to_s != stack_value.to_s
342
- if config[:parameter_validation] == 'default'
343
- ui.warn 'Nested stack has been altered directly! This update may cause unexpected modifications!'
342
+ if config[:parameter_validation] == "default"
343
+ ui.warn "Nested stack has been altered directly! This update may cause unexpected modifications!"
344
344
  ui.warn "Stack name: #{c_stack.name}. Parameter: #{p_key}. Current value: #{stack_value}. Expected value: #{current_value} (via: #{c_value.inspect})"
345
- answer = ui.ask_question("Use current value or expected value for #{p_key} [current/expected]?", :valid => ['current', 'expected'])
345
+ answer = ui.ask_question("Use current value or expected value for #{p_key} [current/expected]?", :valid => ["current", "expected"])
346
346
  else
347
347
  answer = config[:parameter_validation]
348
348
  end
349
- answer == 'expected'
349
+ answer == "expected"
350
350
  else
351
351
  true
352
352
  end
@@ -1,7 +1,7 @@
1
- require 'sfn'
2
- require 'sparkle_formation'
1
+ require "sfn"
2
+ require "sparkle_formation"
3
3
 
4
- require 'pathname'
4
+ require "pathname"
5
5
 
6
6
  module Sfn
7
7
  module CommandModule
@@ -48,7 +48,7 @@ module Sfn
48
48
  def request_compile_parameter(p_name, p_config, cur_val, nested = false)
49
49
  result = nil
50
50
  attempts = 0
51
- parameter_type = p_config.fetch(:type, 'string').to_s.downcase.to_sym
51
+ parameter_type = p_config.fetch(:type, "string").to_s.downcase.to_sym
52
52
  if parameter_type == :complex
53
53
  ui.debug "Compile time parameter `#{p_name}` is a complex type. Not requesting value from user."
54
54
  if cur_val.nil?
@@ -61,13 +61,13 @@ module Sfn
61
61
  cur_val = p_config[:default]
62
62
  end
63
63
  if cur_val.is_a?(Array)
64
- cur_val = cur_val.map(&:to_s).join(',')
64
+ cur_val = cur_val.map(&:to_s).join(",")
65
65
  end
66
66
  until result && (!result.respond_to?(:empty?) || !result.empty?)
67
67
  attempts += 1
68
68
  if config[:interactive_parameters] && (!nested || !p_config.key?(:prompt_when_nested) || p_config[:prompt_when_nested] == true)
69
69
  result = ui.ask_question(
70
- p_name.to_s.split('_').map(&:capitalize).join,
70
+ p_name.to_s.split("_").map(&:capitalize).join,
71
71
  :default => cur_val.to_s.empty? ? nil : cur_val.to_s,
72
72
  )
73
73
  else
@@ -76,11 +76,11 @@ module Sfn
76
76
  case parameter_type
77
77
  when :string
78
78
  if p_config[:multiple]
79
- result = result.split(',').map(&:strip)
79
+ result = result.split(",").map(&:strip)
80
80
  end
81
81
  when :number
82
82
  if p_config[:multiple]
83
- result = result.split(',').map(&:strip)
83
+ result = result.split(",").map(&:strip)
84
84
  new_result = result.map do |item|
85
85
  new_item = item.to_i
86
86
  new_item if new_item.to_s == item
@@ -97,7 +97,7 @@ module Sfn
97
97
  unless valid == true
98
98
  result = nil
99
99
  valid.each do |invalid_msg|
100
- ui.error invalid_msg.last
100
+ ui.error "#{p_name}: #{invalid_msg.last}"
101
101
  end
102
102
  end
103
103
  if result.nil? || (result.respond_to?(:empty?) && result.empty?)
@@ -150,7 +150,7 @@ module Sfn
150
150
  end
151
151
  collection.set_root(root_pack)
152
152
  rescue Errno::ENOENT
153
- ui.warn 'No local SparkleFormation files detected'
153
+ ui.warn "No local SparkleFormation files detected"
154
154
  end
155
155
  sparkle_packs.each do |pack|
156
156
  collection.add_sparkle(pack)
@@ -185,8 +185,8 @@ module Sfn
185
185
  end
186
186
  sf.compile_time_parameter_setter do |formation|
187
187
  f_name = formation.root_path.map(&:name).map(&:to_s)
188
- pathed_name = f_name.join(' > ')
189
- f_name = f_name.join('__')
188
+ pathed_name = f_name.join(" > ")
189
+ f_name = f_name.join("__")
190
190
  if formation.root? && compile_state[f_name].nil?
191
191
  current_state = compile_state
192
192
  else
@@ -200,7 +200,7 @@ module Sfn
200
200
  current_state = current_state.merge(formation.compile_state)
201
201
  end
202
202
  unless formation.parameters.empty?
203
- ui.info "#{ui.color('Compile time parameters:', :bold)} - template: #{ui.color(pathed_name, :green, :bold)}" unless config[:print_only]
203
+ ui.info "#{ui.color("Compile time parameters:", :bold)} - template: #{ui.color(pathed_name, :green, :bold)}" unless config[:print_only]
204
204
  formation.parameters.each do |k, v|
205
205
  valid_keys = [
206
206
  "#{f_name}__#{k}",
@@ -251,7 +251,7 @@ module Sfn
251
251
  template
252
252
  end
253
253
  else
254
- raise ArgumentError.new 'Failed to locate template for processing!'
254
+ raise ArgumentError.new "Failed to locate template for processing!"
255
255
  end
256
256
  end
257
257
 
@@ -262,7 +262,7 @@ module Sfn
262
262
  ui.debug "Initial compile parameters - #{compile_state}"
263
263
  compile_state.keys.each do |cs_key|
264
264
  unless cs_key.to_s.start_with?("#{arguments.first}__")
265
- named_cs_key = [arguments.first, cs_key].compact.join('__')
265
+ named_cs_key = [arguments.first, cs_key].compact.join("__")
266
266
  non_named = compile_state.delete(cs_key)
267
267
  if non_named && !compile_state.key?(named_cs_key)
268
268
  ui.debug "Setting non-named compile parameter `#{cs_key}` into `#{named_cs_key}`"
@@ -282,8 +282,8 @@ module Sfn
282
282
  # Force user friendly error if nesting bucket is not set within configuration
283
283
  def validate_nesting_bucket!
284
284
  if config[:nesting_bucket].to_s.empty?
285
- ui.error 'Missing required configuration value for `nesting_bucket`. Cannot generated nested templates!'
286
- raise ArgumentError.new 'Required configuration value for `nesting_bucket` not provided.'
285
+ ui.error "Missing required configuration value for `nesting_bucket`. Cannot generated nested templates!"
286
+ raise ArgumentError.new "Required configuration value for `nesting_bucket` not provided."
287
287
  end
288
288
  end
289
289
 
@@ -307,13 +307,13 @@ module Sfn
307
307
  end
308
308
  file = bucket.files.build
309
309
  file.name = "#{name_args.first}_#{stack_name}.json"
310
- file.content_type = 'text/json'
310
+ file.content_type = "text/json"
311
311
  file.body = MultiJson.dump(parameter_scrub!(stack_definition))
312
312
  file.save
313
313
  url = URI.parse(file.url)
314
314
  template_url = "#{url.scheme}://#{url.host}#{url.path}"
315
315
  end
316
- resource.properties.set!('TemplateURL', template_url)
316
+ resource.properties.set!("TemplateURL", template_url)
317
317
  end
318
318
  end
319
319
 
@@ -331,16 +331,16 @@ module Sfn
331
331
  if current_stack && current_stack.data[:parent_stack]
332
332
  current_parameters.merge!(
333
333
  current_stack.data[:parent_stack].template.fetch(
334
- 'Resources', stack_name, 'Properties', 'Parameters', current_stack.data[:parent_stack].template.fetch(
335
- 'resources', stack_name, 'properties', 'parameters', Smash.new
334
+ "Resources", stack_name, "Properties", "Parameters", current_stack.data[:parent_stack].template.fetch(
335
+ "resources", stack_name, "properties", "parameters", Smash.new
336
336
  )
337
337
  )
338
338
  )
339
339
  end
340
340
  full_stack_name = [
341
341
  config[:nesting_prefix],
342
- stack.root_path.map(&:name).map(&:to_s).join('_'),
343
- ].compact.join('/')
342
+ stack.root_path.map(&:name).map(&:to_s).join("_"),
343
+ ].compact.join("/")
344
344
  unless config[:print_only]
345
345
  result = Smash.new(
346
346
  :parameters => populate_parameters!(stack,
@@ -390,7 +390,7 @@ module Sfn
390
390
  end
391
391
  file = bucket.files.build
392
392
  file.name = "#{full_stack_name}.json"
393
- file.content_type = 'text/json'
393
+ file.content_type = "text/json"
394
394
  file.body = MultiJson.dump(parameter_scrub!(stack_definition))
395
395
  file.save
396
396
  result.merge!(
@@ -422,9 +422,9 @@ module Sfn
422
422
  # @return [Hash]
423
423
  def scrub_template(template)
424
424
  template = parameter_scrub!(template)
425
- (template['Resources'] || {}).each do |r_name, r_content|
426
- if valid_stack_types.include?(r_content['Type'])
427
- result = (r_content['Properties'] || {}).delete('Stack')
425
+ (template["Resources"] || {}).each do |r_name, r_content|
426
+ if valid_stack_types.include?(r_content["Type"])
427
+ result = (r_content["Properties"] || {}).delete("Stack")
428
428
  end
429
429
  end
430
430
  template
@@ -439,11 +439,11 @@ module Sfn
439
439
  case provider
440
440
  when :aws
441
441
  if results[:parameters]
442
- results['Parameters'] = results.delete(:parameters)
442
+ results["Parameters"] = results.delete(:parameters)
443
443
  end
444
444
  if results[:url]
445
445
  url = URI.parse(results.delete(:url))
446
- results['TemplateURL'] = "#{url.scheme}://#{url.host}#{url.path}"
446
+ results["TemplateURL"] = "#{url.scheme}://#{url.host}#{url.path}"
447
447
  end
448
448
  results
449
449
  when :heat, :rackspace
@@ -461,10 +461,10 @@ module Sfn
461
461
  if results[:url]
462
462
  results[:templateLink] = Smash.new(
463
463
  :uri => results.delete(:url),
464
- :contentVersion => '1.0.0.0',
464
+ :contentVersion => "1.0.0.0",
465
465
  )
466
466
  end
467
- results[:mode] = 'Incremental'
467
+ results[:mode] = "Incremental"
468
468
  results
469
469
  else
470
470
  raise "Unknown stack provider value given! `#{provider}`"
@@ -491,7 +491,7 @@ module Sfn
491
491
  translator = klass.new(template, args)
492
492
  translator.translate!
493
493
  template = translator.translated
494
- ui.info "#{ui.color('Translation applied:', :bold)} #{ui.color(klass_name, :yellow)}"
494
+ ui.info "#{ui.color("Translation applied:", :bold)} #{ui.color(klass_name, :yellow)}"
495
495
  end
496
496
  template
497
497
  end
@@ -530,9 +530,9 @@ module Sfn
530
530
  # @return [String] path to template
531
531
  def prompt_for_template(prefix = nil)
532
532
  if prefix
533
- collection_name = prefix.split('__').map do |c_name|
534
- c_name.split('_').map(&:capitalize).join(' ')
535
- end.join(' / ')
533
+ collection_name = prefix.split("__").map do |c_name|
534
+ c_name.split("_").map(&:capitalize).join(" ")
535
+ end.join(" / ")
536
536
  ui.info "Viewing collection: #{ui.color(collection_name, :bold)}"
537
537
  template_names = sparkle_collection.templates.fetch(provider.connection.provider, {}).keys.find_all do |t_name|
538
538
  t_name.to_s.start_with?(prefix.to_s)
@@ -541,46 +541,46 @@ module Sfn
541
541
  template_names = sparkle_collection.templates.fetch(provider.connection.provider, {}).keys
542
542
  end
543
543
  collections = template_names.map do |t_name|
544
- t_name = t_name.to_s.sub(/^#{Regexp.escape(prefix.to_s)}/, '')
545
- if t_name.include?('__')
546
- c_name = t_name.split('__').first
547
- [[prefix, c_name].compact.join('') + '__', c_name]
544
+ t_name = t_name.to_s.sub(/^#{Regexp.escape(prefix.to_s)}/, "")
545
+ if t_name.include?("__")
546
+ c_name = t_name.split("__").first
547
+ [[prefix, c_name].compact.join("") + "__", c_name]
548
548
  end
549
549
  end.compact.uniq(&:first)
550
550
  templates = template_names.map do |t_name|
551
- t_name = t_name.to_s.sub(/^#{Regexp.escape(prefix.to_s)}/, '')
552
- unless t_name.include?('__')
553
- [[prefix, t_name].compact.join(''), t_name]
551
+ t_name = t_name.to_s.sub(/^#{Regexp.escape(prefix.to_s)}/, "")
552
+ unless t_name.include?("__")
553
+ [[prefix, t_name].compact.join(""), t_name]
554
554
  end
555
555
  end.compact
556
556
  if collections.empty? && templates.empty?
557
- ui.error 'Failed to locate any templates!'
557
+ ui.error "Failed to locate any templates!"
558
558
  return nil
559
559
  end
560
- ui.info "Please select an entry#{'(or collection to list)' unless collections.empty?}:"
560
+ ui.info "Please select an entry#{"(or collection to list)" unless collections.empty?}:"
561
561
  output = []
562
562
  idx = 1
563
563
  valid = {}
564
564
  unless collections.empty?
565
- output << ui.color('Collections:', :bold)
565
+ output << ui.color("Collections:", :bold)
566
566
  collections.each do |full_name, part_name|
567
567
  valid[idx] = {:name => full_name, :type => :collection}
568
- output << [idx, part_name.split('_').map(&:capitalize).join(' ')]
568
+ output << [idx, part_name.split("_").map(&:capitalize).join(" ")]
569
569
  idx += 1
570
570
  end
571
571
  end
572
572
  unless templates.empty?
573
- output << ui.color('Templates:', :bold)
573
+ output << ui.color("Templates:", :bold)
574
574
  templates.each do |full_name, part_name|
575
575
  valid[idx] = {:name => full_name, :type => :template}
576
- output << [idx, part_name.split('_').map(&:capitalize).join(' ')]
576
+ output << [idx, part_name.split("_").map(&:capitalize).join(" ")]
577
577
  idx += 1
578
578
  end
579
579
  end
580
580
  max = idx.to_s.length
581
581
  output.map! do |line|
582
582
  if line.is_a?(Array)
583
- " #{line.first}.#{' ' * (max - line.first.to_s.length)} #{line.last}"
583
+ " #{line.first}.#{" " * (max - line.first.to_s.length)} #{line.last}"
584
584
  else
585
585
  line
586
586
  end
@@ -588,7 +588,7 @@ module Sfn
588
588
  ui.puts "#{output.join("\n")}\n"
589
589
  response = nil
590
590
  until valid[response]
591
- response = ui.ask_question('Enter selection').to_i
591
+ response = ui.ask_question("Enter selection").to_i
592
592
  end
593
593
  entry = valid[response]
594
594
  if entry[:type] == :collection