convection 2.2.29 → 2.3.0

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: 076060eec9c4e8108a8f6bab08a8f5bf9dacfdd7
4
- data.tar.gz: a4921ecbc1f0cde9308eebcd78209d7079085283
3
+ metadata.gz: 80472b7ae2163bf2c2bff8dc870c2e3571257a1d
4
+ data.tar.gz: b3b70747b74829069d110b96eccc74b1ae70e902
5
5
  SHA512:
6
- metadata.gz: 1d9326cdef296ee8069a2506d008aad5206059a1f6a11ab7f0da3b3e3af4b303677aa7a748dbcef9e8ca3a6cad9485d41e1b8adedad14eb0e1e10e4c88f35ee2
7
- data.tar.gz: 655a27c52359dba267a2b088932ba36179e297fb592e16bbfcaa55db464e7ab3dbb550cdcb6f7139857496f958e33156076cc129ca7350078c5a0c107d42804a
6
+ metadata.gz: fec53677c235b009423cc61dafb3ae9f0a4bd4400d3ee65e67f13441631b21993542d880663aa8017269fd7271e6f99ee083dd2fcb5459fa8cd4f6b9bcd5e989
7
+ data.tar.gz: 2f7011b1226f5397465f2c4a9d534cc63fab2c29dea4572d117cd346a024d38ec86e65498505d417e99da24256ac9df9101a0448a50294d7abe99584f20e276c
@@ -28,6 +28,11 @@ Metrics/LineLength:
28
28
  Exclude:
29
29
  - 'lib/convection/dsl/terraform_intrinsic_functions.rb'
30
30
 
31
+ # Ignore block length limits for DSLs
32
+ Metrics/BlockLength:
33
+ Exclude:
34
+ - 'spec/**/*.rb'
35
+
31
36
  # AbcSize:
32
37
  # Max: 24
33
38
  # ClassLength:
@@ -7,13 +7,14 @@ module Convection
7
7
  # Difference between an item in two templates
8
8
  ##
9
9
  class Diff
10
+ include Comparable
10
11
  extend Mixin::Colorize
11
12
 
12
13
  attr_reader :key
13
- attr_reader :action
14
+ attr_accessor :action
14
15
  attr_reader :ours
15
16
  attr_reader :theirs
16
- colorize :action, :green => [:create], :yellow => [:update], :red => [:delete, :replace]
17
+ colorize :action, :green => [:create], :yellow => [:update, :retain], :red => [:delete, :replace]
17
18
 
18
19
  def initialize(key, ours, theirs)
19
20
  @key = key
@@ -40,10 +41,24 @@ module Convection
40
41
  when :update then "#{ key }: #{ theirs } => #{ ours }"
41
42
  when :replace then "#{ key }: #{ theirs } => #{ ours }"
42
43
  when :delete then key
44
+ when :retain then key
43
45
  end
44
46
 
45
47
  [action, message, color]
46
48
  end
49
+
50
+ def <=>(other)
51
+ value = @key <=> other.key
52
+ return value if value != 0
53
+
54
+ value = @ours <=> other.ours
55
+ return value if value != 0
56
+
57
+ value = @theirs <=> other.theirs
58
+ return value if value != 0
59
+
60
+ @action <=> other.action
61
+ end
47
62
  end
48
63
  end
49
64
  end
@@ -297,7 +297,45 @@ module Convection
297
297
  end
298
298
 
299
299
  def diff(other, stack_ = nil, retain: false)
300
- render(stack_, retain: retain).diff(other).map { |diff| Diff.new(diff[0], *diff[1]) }
300
+ # We want to accurately show when the DeletionPolicy is getting deleted and also when resources are going to be retained.
301
+ # Sample DeletionPolicy Removal output
302
+ # us-east-1 compare Compare local state of stack test-logs-deletion with remote template
303
+ # us-east-1 delete Resources.sgtestConvectionDeletion.DeletionPolicy
304
+ #
305
+ # Sample Mixed Retain/Delete Resources
306
+ # us-east-1 retain Resources.ELBLoggingPolicy.DependsOn.AWS::S3::BucketPolicy.0
307
+ # us-east-1 retain Resources.ELBLoggingPolicy.DeletionPolicy
308
+ # us-east-1 delete Resources.sgtestConvectionDeletion.Type
309
+ # us-east-1 delete Resources.sgtestConvectionDeletion.Properties.AWS::EC2::SecurityGroup.GroupDescription
310
+ # us-east-1 delete Resources.sgtestConvectionDeletion.Properties.AWS::EC2::SecurityGroup.VpcId
311
+ #
312
+ events = render(stack_, retain: retain).diff(other).map { |diff| Diff.new(diff[0], *diff[1]) }
313
+
314
+ # Top level events (changes to the resource directly) have keys with a format "Resources.{NAME}.{KEY}".
315
+ # So we can count the number of separators to find them.
316
+ top_level_events = events.select { |event| event.key.count('.') <= 2 }
317
+
318
+ # We know something's a deleted resource when it has a top level "Type" attribute.
319
+ type_suffix = '.Type'.freeze
320
+ deleted_resources = top_level_events.select do |event|
321
+ event.action == :delete && event.key.end_with?(type_suffix)
322
+ end
323
+ deleted_resources.map! { |event| event.key[0...-type_suffix.length] }
324
+
325
+ # We know something's a retainable resource when it has a top level "DeletionPolicy" attribute.
326
+ delete_policy_suffix = '.DeletionPolicy'.freeze
327
+ retainable_resources = top_level_events.select do |event|
328
+ event.action == :delete && event.key.end_with?(delete_policy_suffix) && event.theirs == 'Retain'
329
+ end
330
+ retainable_resources.map! { |event| event.key[0...-delete_policy_suffix.length] }
331
+ retainable_resources.keep_if { |name| deleted_resources.include?(name) }
332
+
333
+ events.each do |event|
334
+ retained = retainable_resources.any? { |name| event.action == :delete && event.key.start_with?(name) }
335
+ event.action = :retain if retained
336
+ end
337
+
338
+ events
301
339
  end
302
340
 
303
341
  def to_json(stack_ = nil, pretty = false, retain: false)
@@ -49,6 +49,79 @@ class Convection::Model::Template
49
49
  end
50
50
  end
51
51
 
52
+ describe '#diff' do
53
+ context 'when diffing resources with deletion_policy' do
54
+ it 'emits retain events when the entire resource is deleted' do
55
+ local = Convection.template do
56
+ end
57
+
58
+ remote = Convection.template do
59
+ resource 'Test' do
60
+ type 'Test'
61
+ property 'Key', 'Value'
62
+ deletion_policy 'Retain'
63
+ end
64
+ end
65
+
66
+ retained = [
67
+ Convection::Model::Diff.new('Resources.Test.Properties.Test.Key', nil, 'Value'),
68
+ Convection::Model::Diff.new('Resources.Test.DeletionPolicy', nil, 'Retain'),
69
+ Convection::Model::Diff.new('Resources.Test.Type', nil, 'Test')
70
+ ]
71
+ retained.each { |event| event.action = :retain }
72
+
73
+ events = local.diff(remote.render)
74
+ expect(events.sort).to eq(retained.sort)
75
+ end
76
+
77
+ it 'emits delete events when only part of the resource is deleted' do
78
+ local = Convection.template do
79
+ resource 'Test' do
80
+ type 'Test'
81
+ end
82
+ end
83
+
84
+ remote = Convection.template do
85
+ resource 'Test' do
86
+ type 'Test'
87
+ property 'Key', 'Value'
88
+ deletion_policy 'Retain'
89
+ end
90
+ end
91
+
92
+ deleted = [
93
+ Convection::Model::Diff.new('Resources.Test.Properties.Test.Key', nil, 'Value'),
94
+ Convection::Model::Diff.new('Resources.Test.DeletionPolicy', nil, 'Retain')
95
+ ]
96
+ deleted.each { |event| event.action = :delete }
97
+
98
+ events = local.diff(remote.render)
99
+ expect(events.sort).to eq(deleted.sort)
100
+ end
101
+
102
+ it 'emits delete events even when properties match Type and DeletePolicy' do
103
+ local = Convection.template do
104
+ end
105
+
106
+ remote = Convection.template do
107
+ resource 'Test' do
108
+ property 'Type', 'Test'
109
+ property 'DeletionPolicy', 'Retain'
110
+ end
111
+ end
112
+
113
+ deleted = [
114
+ Convection::Model::Diff.new('Resources.Test.Properties.Type', nil, 'Test'),
115
+ Convection::Model::Diff.new('Resources.Test.Properties.DeletionPolicy', nil, 'Retain')
116
+ ]
117
+ deleted.each { |event| event.action = :delete }
118
+
119
+ events = local.diff(remote.render)
120
+ expect(events.sort).to eq(deleted.sort)
121
+ end
122
+ end
123
+ end
124
+
52
125
  subject do
53
126
  template_json
54
127
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: convection
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.29
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Manero
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-27 00:00:00.000000000 Z
11
+ date: 2018-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport