sfn 2.1.2 → 2.1.4

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