30
30
CREATE_WAIT_AFTER_SECONDS = 10
31
31
MODIFY_WAIT_AFTER_SECONDS = 10
32
32
DELETE_WAIT_AFTER_SECONDS = 10
33
+ ACK_SYSTEM_TAG_PREFIX = "services.k8s.aws/"
34
+ AWS_SYSTEM_TAG_PREFIX = "aws:"
33
35
34
36
class AdoptionPolicy (str , Enum ):
35
37
NONE = ""
@@ -66,6 +68,36 @@ def adoption_policy_adopt_bucket(s3_client):
66
68
_ , deleted = k8s .delete_custom_resource (ref , DELETE_WAIT_AFTER_SECONDS )
67
69
assert deleted
68
70
71
+ @pytest .fixture (scope = "module" )
72
+ def adopt_stack_bucket (s3_client ):
73
+ replacements = REPLACEMENT_VALUES .copy ()
74
+ bucket_name = replacements ["STACK_BUCKET_NAME" ]
75
+ replacements ["ADOPTION_POLICY" ] = AdoptionPolicy .ADOPT
76
+ replacements ["ADOPTION_FIELDS" ] = f'{{\\ \" name\\ \" : \\ \" { bucket_name } \\ \" }}'
77
+
78
+ resource_data = load_s3_resource (
79
+ "bucket_adoption_stack" ,
80
+ additional_replacements = replacements ,
81
+ )
82
+
83
+ # Create k8s resource
84
+ ref = k8s .CustomResourceReference (
85
+ CRD_GROUP , CRD_VERSION , "buckets" ,
86
+ bucket_name , namespace = "default" )
87
+ k8s .create_custom_resource (ref , resource_data )
88
+
89
+ time .sleep (CREATE_WAIT_AFTER_SECONDS )
90
+ cr = k8s .wait_resource_consumed_by_controller (ref )
91
+
92
+ assert cr is not None
93
+ assert k8s .get_resource_exists (ref )
94
+
95
+ yield (ref , cr )
96
+
97
+ _ , deleted = k8s .delete_custom_resource (ref , DELETE_WAIT_AFTER_SECONDS )
98
+ assert deleted
99
+
100
+
69
101
@service_marker
70
102
@pytest .mark .canary
71
103
class TestAdoptionPolicyBucket :
@@ -101,4 +133,57 @@ def test_adoption_policy(
101
133
versioning = latest .Versioning ()
102
134
assert versioning .status == status
103
135
136
+ def test_adoption_update_tags (
137
+ self , s3_client , adopt_stack_bucket , s3_resource
138
+ ):
139
+ (ref , cr ) = adopt_stack_bucket
140
+
141
+ # Spec will be added by controller
142
+ assert 'spec' in cr
143
+ assert 'name' in cr ['spec' ]
144
+ assert 'tagSet' not in cr ['spec' ]['tagging' ]
145
+ bucket_name = cr ['spec' ]['name' ]
104
146
147
+ updates = {
148
+ "spec" : {
149
+ "tagging" : {
150
+ "tagSet" : [
151
+ {"key" : "newKey" , "value" : "newVal" }
152
+ ]
153
+ }
154
+ }
155
+ }
156
+
157
+ k8s .patch_custom_resource (ref , updates )
158
+ time .sleep (MODIFY_WAIT_AFTER_SECONDS )
159
+
160
+ cr = k8s .wait_resource_consumed_by_controller (ref )
161
+ assert cr is not None
162
+ assert 'spec' in cr
163
+ assert 'tagging' in cr ['spec' ]
164
+ assert 'tagSet' in cr ['spec' ]['tagging' ]
165
+
166
+ latest = get_bucket (s3_resource , bucket_name )
167
+ assert latest is not None
168
+ tagging = latest .Tagging ()
169
+
170
+ latest = cleanTags (tagging .tag_set )
171
+ # +2 here because we want to see if we're also filtering
172
+ # through the aws tags, besides just the ack tags
173
+ assert len (tagging .tag_set ) > len (latest ) + 2
174
+ desired = cr ['spec' ]['tagging' ]['tagSet' ]
175
+ for i in range (1 ):
176
+ assert desired [i ]["key" ] == latest [i ]["Key" ]
177
+ assert desired [i ]["value" ] == latest [i ]["Value" ]
178
+
179
+
180
+ def cleanTags (tags : list ,
181
+ key_member_name : str = 'Key' ,
182
+ ) -> list :
183
+ if isinstance (tags , list ):
184
+ return [
185
+ t for t in tags if not t [key_member_name ].startswith (AWS_SYSTEM_TAG_PREFIX )
186
+ and not t [key_member_name ].startswith (ACK_SYSTEM_TAG_PREFIX )
187
+ ]
188
+ else :
189
+ raise RuntimeError ('tags parameter can only be list type' )
0 commit comments