sfn 2.1.2 → 2.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ef688f38c0f0be5810c525cd37e77d5a4216756a
4
- data.tar.gz: 1f3e4f9a893e376b9c7e77fda5f1e495e27df905
3
+ metadata.gz: 16cbb5ea90df094029c2f7cdbc83087652dc5807
4
+ data.tar.gz: a2646f89707aa719a18c5a3907501f4043dce02a
5
5
  SHA512:
6
- metadata.gz: be3015b69f844371bff9588753a0cec1b9ca1dfb05cb957106583e62ed8a5a9b4284b052938ddb53ace50c8f85f0a73a4884b0131c2948a5d49693f41d3a88d7
7
- data.tar.gz: ae268210135a9b5bbc406a1c7684a5e560f16548b21f2b29bd3c8164c66ffe0668c189f995a4c27f86797047f997c3ef3be12d809135b229f86cf3ac049b9225
6
+ metadata.gz: 4796f389bf2333281966e9ba04b03de4ffe47c76db4fbc552e6835379eec230ae89945c11057eb063dc4b2dd5d6ea947c5e073468bc5b3d195466fb88ab3f3f2
7
+ data.tar.gz: 1abc4ab0b61f2a24a32051f1cbb90573a43d8c7e865456b5eda19aa8d603ba7bc91cd304fe6e3bac44c7a1bd3ac36f9f089fdc1a33d9657fc243248ef8596527
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # v2.1.4
2
+ * [fix] Update environment variable name used for azure credentials (#135)
3
+ * [fix] Cast all parameters to String types within planner (#137)
4
+ * [fix] Properly support compile time parameters via CLI (#141)
5
+ * [enhancement] Add diff output support to planner (#142)
6
+ * [enhancement] Support writing template to file via `print` command (#139)
7
+
1
8
  # v2.1.2
2
9
  * [enhancement] Include parameter name on error output when failed to receive (#116)
3
10
  * [enhancement] Rescue planner errors and notify user. Allow update to proceed (#124)
@@ -6,6 +13,7 @@
6
13
  * [fix] Remove policy modification on stack delete within AWS (#127)
7
14
  * [feature] Support optional stack policy removal prior to update (#127)
8
15
  * [feature] Add built-in callback for AWS Assume Role credential caching (#128)
16
+ * [feature] Add load balancer specific inspection (#129)
9
17
 
10
18
  # v2.1.0
11
19
  * [fix] Use SparkleFormation::Collection helper to ensure proper pack ordering (#115)
data/docs/usage.md CHANGED
@@ -92,7 +92,7 @@ end
92
92
 
93
93
  The default nesting functionality is `"deep"`. To learn more about
94
94
  the nesting functionality please refer to the [SparkleFormation nested
95
- stacks][nested-stacks] documentation.
95
+ stacks][nested_stacks] documentation.
96
96
 
97
97
  When using nested stacks, a bucket is required for storage of the
98
98
  nested stack templates. `sfn` will automatically store nested templates
@@ -132,5 +132,6 @@ $ sfn inspect my-stack --attribute 'resources.all.at(0).expand.addresses'
132
132
 
133
133
  [knife]: https://docs.chef.io/knife.html
134
134
  [sparkle_formation]: https://github.com/sparkleformation/sparkle_formation
135
+ [nested_stacks]: http://www.sparkleformation.io/docs/sparkle_formation/nested-stacks.html
135
136
  [sparkle_packs]: https://sparkleformation.github.io/sparkle_formation/UserDocs/sparkle-packs.html
136
137
  [miasma]: https://github.com/miasma-rb/miasma
@@ -97,7 +97,7 @@ Configuration.new do
97
97
  azure_tenant_id ENV['AZURE_TENANT_ID']
98
98
  azure_client_id ENV['AZURE_CLIENT_ID']
99
99
  azure_subscription_id ENV['AZURE_SUBSCRIPTION_ID']
100
- azure_client_secret ENV['AZURE_CLIENT_ID']
100
+ azure_client_secret ENV['AZURE_CLIENT_SECRET']
101
101
  azure_region ENV['AZURE_REGION']
102
102
  azure_blob_account_name ENV['AZURE_BLOB_ACCOUNT_NAME']
103
103
  azure_blob_secret_key ENV['AZURE_BLOB_SECRET_KEY']
@@ -17,7 +17,21 @@ module Sfn
17
17
  file = Sfn::Utils::StackParameterScrubber.scrub!(file)
18
18
  file = translate_template(file)
19
19
 
20
- ui.puts _format_json(file)
20
+ json_content = _format_json(file)
21
+ if(config[:write_to_file])
22
+ unless(File.directory?(File.dirname(config[:write_to_file])))
23
+ run_action 'Creating parent directory' do
24
+ FileUtils.mkdir_p(File.dirname(config[:write_to_file]))
25
+ nil
26
+ end
27
+ end
28
+ run_action "Writing template to file - #{config[:write_to_file]}" do
29
+ File.write(config[:write_to_file], json_content)
30
+ nil
31
+ end
32
+ else
33
+ ui.puts json_content
34
+ end
21
35
  end
22
36
 
23
37
  end
@@ -96,9 +96,13 @@ module Sfn
96
96
  display_plan_information(result)
97
97
  end
98
98
  rescue => e
99
- ui.error "Unexpected error when generating plan information: #{e.class} - #{e}"
100
- ui.debug "#{e.class}: #{e}\n#{e.backtrace.join("\n")}"
101
- ui.confirm 'Continue with stack update?'
99
+ unless(e.message.include?('Confirmation declined'))
100
+ ui.error "Unexpected error when generating plan information: #{e.class} - #{e}"
101
+ ui.debug "#{e.class}: #{e}\n#{e.backtrace.join("\n")}"
102
+ ui.confirm 'Continue with stack update?'
103
+ else
104
+ raise
105
+ end
102
106
  end
103
107
  end
104
108
 
@@ -234,6 +238,8 @@ module Sfn
234
238
  def print_plan_items(info, key, color)
235
239
  max_name = info[key].keys.map(&:size).max
236
240
  max_type = info[key].values.map{|i|i[:type]}.map(&:size).max
241
+ max_p = info[key].values.map{|i| i.fetch(:diffs, [])}.flatten(1).map{|d| d.fetch(:property_name, :path).to_s.size}.max
242
+ max_o = info[key].values.map{|i| i.fetch(:diffs, [])}.flatten(1).map{|d| d[:original].to_s.size}.max
237
243
  info[key].each do |name, val|
238
244
  ui.print ' ' * 6
239
245
  ui.print ui.color("[#{val[:type]}]", color)
@@ -246,6 +252,27 @@ module Sfn
246
252
  ui.print "Reason: Updated properties: `#{val[:properties].join('`, `')}`"
247
253
  end
248
254
  ui.puts
255
+ if(config[:diffs])
256
+ unless(val[:diffs].empty?)
257
+ val[:diffs].each do |diff|
258
+ if(diff[:updated] && diff[:original])
259
+ p_name = diff.fetch(:property_name, :path)
260
+ ui.print ' ' * 8
261
+ ui.print "#{p_name}: "
262
+ ui.print ' ' * (max_p - p_name.size)
263
+ ui.print ui.color("-#{diff[:original]}", :red)
264
+ ui.print ' ' * (max_o - diff[:original].size)
265
+ ui.print ' '
266
+ if(diff[:updated] == Sfn::Planner::RUNTIME_MODIFIED)
267
+ ui.puts ui.color("+#{diff[:original]} <Dependency Modified>", :green)
268
+ else
269
+ ui.puts ui.color("+#{diff[:updated]}", :green)
270
+ end
271
+ end
272
+ end
273
+ ui.puts
274
+ end
275
+ end
249
276
  end
250
277
  end
251
278
 
@@ -145,8 +145,19 @@ module Sfn
145
145
  sf.compile_time_parameter_setter do |formation|
146
146
  f_name = formation.root_path.map(&:name).map(&:to_s)
147
147
  pathed_name = f_name.join(' > ')
148
- f_name = f_name.join('_')
149
- current_state = compile_state.fetch(f_name, Smash.new)
148
+ f_name = f_name.join('__')
149
+ current_state = compile_state[f_name]
150
+ unless(current_state)
151
+ f_name = f_name.split('__')
152
+ f_name.shift
153
+ f_name = f_name.join('__')
154
+ current_state = f_name.empty? ? compile_state : compile_state[f_name]
155
+ end
156
+ if(formation.root? && compile_state[f_name].nil?)
157
+ current_state = compile_state
158
+ else
159
+ current_state = compile_state.fetch(f_name, Smash.new)
160
+ end
150
161
  if(formation.compile_state)
151
162
  current_state = current_state.merge(formation.compile_state)
152
163
  end
@@ -5,6 +5,12 @@ module Sfn
5
5
  # Print command configurationUpdate command configuration
6
6
  class Print < Validate
7
7
 
8
+ attribute(
9
+ :write_to_file, String,
10
+ :description => 'Write compiled SparkleFormation template to path provided',
11
+ :short_flag => 'w'
12
+ )
13
+
8
14
  end
9
15
  end
10
16
  end
@@ -41,9 +41,9 @@ module Sfn
41
41
  :short_flag => 'l'
42
42
  )
43
43
  attribute(
44
- :compile_parameters, Smash,
45
- :description => 'Pass template compile time parameters directly',
46
- :short_flag => 'o'
44
+ :diffs, [TrueClass, FalseClass],
45
+ :description => 'Show planner content diff',
46
+ :short_flag => 'D'
47
47
  )
48
48
 
49
49
  end
@@ -72,6 +72,28 @@ module Sfn
72
72
  :coerce => lambda{|s| s.to_s},
73
73
  :short_flag => 's'
74
74
  )
75
+ attribute(
76
+ :compile_parameters, Smash,
77
+ :description => 'Pass template compile time parameters directly',
78
+ :short_flag => 'o',
79
+ :coerce => lambda{|v|
80
+ case v
81
+ when String
82
+ result = Smash.new
83
+ v.split(',').each do |item_pair|
84
+ key, value = item_pair.split(/[=:]/, 2)
85
+ key = key.split('__')
86
+ key = [key.pop, key.map{|x| Bogo::Utility.camel(x)}.join('__')].reverse
87
+ result.set(*key, value)
88
+ end
89
+ result
90
+ when Hash
91
+ v.to_smash
92
+ else
93
+ v
94
+ end
95
+ }
96
+ )
75
97
 
76
98
  end
77
99
  end
data/lib/sfn/planner.rb CHANGED
@@ -6,6 +6,9 @@ module Sfn
6
6
 
7
7
  autoload :Aws, 'sfn/planner/aws'
8
8
 
9
+ # Value to flag runtime modification
10
+ RUNTIME_MODIFIED = '__MODIFIED_REFERENCE_VALUE__'
11
+
9
12
  # @return [Bogo::Ui]
10
13
  attr_reader :ui
11
14
  # @return [Smash]
@@ -90,14 +90,14 @@ module Sfn
90
90
  result = nil
91
91
  if(hash.is_a?(Hash))
92
92
  if(hash.keys.first == 'Ref' && flagged?(hash.values.first))
93
- result = '__MODIFIED_REFERENCE_VALUE__'
93
+ result = RUNTIME_MODIFIED
94
94
  elsif(hash.keys.first == 'Fn::GetAtt')
95
95
  if(hash.values.last.last.start_with?('Outputs.'))
96
96
  if(flagged?(hash.values.join('_')))
97
- result = '__MODIFIED_REFERENCE_VALUE__'
97
+ result = RUNTIME_MODIFIED
98
98
  end
99
99
  elsif(flagged?(hash.values.first))
100
- result = '__MODIFIED_REFERENCE_VALUE__'
100
+ result = RUNTIME_MODIFIED
101
101
  end
102
102
  end
103
103
  end
@@ -129,6 +129,7 @@ module Sfn
129
129
  #
130
130
  # @return [Hash] report
131
131
  def generate_plan(template, parameters)
132
+ parameters = Smash[parameters.map{|k,v| [k, v.to_s]}]
132
133
  Smash.new(
133
134
  :stacks => Smash.new(
134
135
  origin_stack.name => plan_stack(
@@ -185,7 +186,7 @@ module Sfn
185
186
  origin_template = dereference_template(
186
187
  "#{stack.data.checksum}_origin",
187
188
  stack.template,
188
- stack.parameters.merge(get_global_parameters(stack))
189
+ Smash[stack.parameters.map{|k,v| [k, v.to_s]}].merge(get_global_parameters(stack))
189
190
  )
190
191
 
191
192
  t_key = "#{stack.data.checksum}_#{stack.data.fetch(:logical_id, stack.name)}"
@@ -319,6 +320,23 @@ module Sfn
319
320
  # @option :templates [Hash] :origin
320
321
  # @option :templates [Hash] :update
321
322
  def register_diff(results, path, diff, translator, templates)
323
+ diff_info = Smash.new.tap do |di|
324
+ if(diff.size > 1)
325
+ updated = diff.detect{|x| x.first == '+'}
326
+ original = diff.detect{|x| x.first == '-'}
327
+ di[:original] = original.last.to_s
328
+ di[:updated] = updated.last.to_s
329
+ else
330
+ diff_data = diff.first
331
+ di[:path] = path
332
+ if(diff_data.size == 3)
333
+ di[diff_data.first == '+' ? :updated : :original] = diff_data.last
334
+ else
335
+ di[:original] = diff_data[diff_data.size - 2].to_s
336
+ di[:updated] = diff_data.last.to_s
337
+ end
338
+ end
339
+ end
322
340
  if(path.start_with?('Resources'))
323
341
  p_path = path.split('.')
324
342
  if(p_path.size == 2)
@@ -328,7 +346,10 @@ module Sfn
328
346
  results[key][p_path.last] = Smash.new(
329
347
  :name => p_path.last,
330
348
  :type => type,
331
- :properties => []
349
+ :properties => [],
350
+ :diffs => [
351
+ diff_info
352
+ ]
332
353
  )
333
354
  else
334
355
  if(p_path.include?('Properties'))
@@ -340,7 +361,10 @@ module Sfn
340
361
  resource = Smash.new(
341
362
  :name => resource_name,
342
363
  :type => type,
343
- :properties => [property_name]
364
+ :properties => [property_name],
365
+ :diffs => [
366
+ diff_info.merge(:property_name => property_name)
367
+ ]
344
368
  )
345
369
  case effect
346
370
  when :replacement
@@ -362,7 +386,10 @@ module Sfn
362
386
  Smash.new(
363
387
  :name => resource_name,
364
388
  :type => type,
365
- :properties => ['AWS::CloudFormation::Init']
389
+ :properties => ['AWS::CloudFormation::Init'],
390
+ :diffs => [
391
+ diff_info
392
+ ]
366
393
  )
367
394
  )
368
395
  end
@@ -373,7 +400,10 @@ module Sfn
373
400
  if(o_resource_name)
374
401
  set_resource(
375
402
  :outputs, results, o_resource_name,
376
- :properties => []
403
+ :properties => [],
404
+ :diffs => [
405
+ diff_info
406
+ ]
377
407
  )
378
408
  end
379
409
  end
@@ -389,6 +419,8 @@ module Sfn
389
419
  if(results[kind][name])
390
420
  results[kind][name][:properties] += resource[:properties]
391
421
  results[kind][name][:properties].uniq!
422
+ results[kind][name][:diffs] += resource[:diffs]
423
+ results[kind][name][:diffs].uniq!
392
424
  else
393
425
  results[kind][name] = resource
394
426
  end
data/lib/sfn/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Sfn
2
2
  # Current library version
3
- VERSION = Gem::Version.new('2.1.2')
3
+ VERSION = Gem::Version.new('2.1.4')
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sfn
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.2
4
+ version: 2.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Roberts
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-22 00:00:00.000000000 Z
11
+ date: 2016-02-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bogo-cli