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 +4 -4
- data/.rubocop.yml +5 -0
- data/lib/convection/model/diff.rb +17 -2
- data/lib/convection/model/template.rb +39 -1
- data/spec/convection/model/template/template_spec.rb +73 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 80472b7ae2163bf2c2bff8dc870c2e3571257a1d
|
4
|
+
data.tar.gz: b3b70747b74829069d110b96eccc74b1ae70e902
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fec53677c235b009423cc61dafb3ae9f0a4bd4400d3ee65e67f13441631b21993542d880663aa8017269fd7271e6f99ee083dd2fcb5459fa8cd4f6b9bcd5e989
|
7
|
+
data.tar.gz: 2f7011b1226f5397465f2c4a9d534cc63fab2c29dea4572d117cd346a024d38ec86e65498505d417e99da24256ac9df9101a0448a50294d7abe99584f20e276c
|
data/.rubocop.yml
CHANGED
@@ -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
|
-
|
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
|
-
|
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.
|
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-
|
11
|
+
date: 2018-09-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|