convection 2.2.29 → 2.3.0

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