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
@@ -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