@@ -116,143 +116,6 @@ def test_on_field_data_sync(self):
116
116
{"key" : "newvalue" },
117
117
)
118
118
119
- def test_on_field_data_ns_deleted (self ):
120
- """Don't fail the sync if one of the namespaces was deleted.
121
- """
122
-
123
- mock_v1 = Mock ()
124
-
125
- def read_namespaced_secret (name , namespace , ** kwargs ):
126
- if namespace == "myns2" :
127
- # Old data in the namespaced secret of the myns namespace.
128
- return V1Secret (
129
- api_version = 'v1' ,
130
- data = {"key" : "oldvalue" },
131
- kind = 'Secret' ,
132
- metadata = create_secret_metadata (
133
- name = "mysecret" ,
134
- namespace = "myns2" ,
135
- ),
136
- type = "Opaque" ,
137
- )
138
- else :
139
- # Deleted namespace.
140
- raise ApiException (status = 404 , reason = "Not Found" )
141
-
142
- mock_v1 .read_namespaced_secret = read_namespaced_secret
143
-
144
- create_namespaced_secret_called_count_for_ns2 = 0
145
-
146
- def create_namespaced_secret (namespace , body , ** kwargs ):
147
- if namespace == "myns2" :
148
- nonlocal create_namespaced_secret_called_count_for_ns2
149
- create_namespaced_secret_called_count_for_ns2 += 1
150
- else :
151
- # Deleted namespace.
152
- raise ApiException (status = 404 , reason = "Not Found" )
153
-
154
- mock_v1 .create_namespaced_secret = create_namespaced_secret
155
-
156
- replace_namespaced_secret_called_count_for_ns2 = 0
157
-
158
- def replace_namespaced_secret (name , namespace , body , ** kwargs ):
159
- if namespace == "myns2" :
160
- nonlocal replace_namespaced_secret_called_count_for_ns2
161
- replace_namespaced_secret_called_count_for_ns2 += 1
162
- self .assertEqual (name , csec .name )
163
-
164
- # Namespaced secret should be updated with the new data.
165
- self .assertEqual (
166
- body .data ,
167
- {"key" : "newvalue" },
168
- )
169
-
170
- return V1Secret (
171
- api_version = 'v1' ,
172
- data = body .data ,
173
- kind = 'Secret' ,
174
- metadata = create_secret_metadata (
175
- name = "mysecret" ,
176
- namespace = "myns2" ,
177
- ),
178
- type = "Opaque" ,
179
- )
180
- else :
181
- # Deleted namespace.
182
- raise ApiException (status = 404 , reason = "Not Found" )
183
-
184
- mock_v1 .replace_namespaced_secret = replace_namespaced_secret
185
-
186
- def read_namespace (name , ** kwargs ):
187
- if name != "myns2" :
188
- # Deleted namespace.
189
- raise ApiException (status = 404 , reason = "Not Found" )
190
-
191
- mock_v1 .read_namespace = read_namespace
192
-
193
- patch_clustersecret_status = Mock ()
194
- patch_clustersecret_status .return_value = {
195
- "metadata" : {"name" : "mysecret" , "uid" : "mysecretuid" },
196
- "data" : {"key" : "newvalue" },
197
- "status" : {"create_fn" : {"syncedns" : ["myns2" ]}},
198
- }
199
-
200
- # Old data in the cache.
201
- csec = BaseClusterSecret (
202
- uid = "mysecretuid" ,
203
- name = "mysecret" ,
204
- body = {
205
- "metadata" : {"name" : "mysecret" , "uid" : "mysecretuid" },
206
- "data" : {"key" : "oldvalue" },
207
- "status" : {"create_fn" : {"syncedns" : ["myns1" , "myns2" ]}},
208
- },
209
- synced_namespace = ["myns1" , "myns2" ],
210
- )
211
-
212
- csecs_cache .set_cluster_secret (csec )
213
-
214
- # New data coming into the callback.
215
- new_body = {
216
- "metadata" : {"name" : "mysecret" , "uid" : "mysecretuid" },
217
- "data" : {"key" : "newvalue" },
218
- "status" : {"create_fn" : {"syncedns" : ["myns1" , "myns2" ]}},
219
- }
220
-
221
- with patch ("handlers.v1" , mock_v1 ), \
222
- patch ("handlers.patch_clustersecret_status" , patch_clustersecret_status ):
223
- on_field_data (
224
- old = {"key" : "oldvalue" },
225
- new = {"key" : "newvalue" },
226
- body = new_body ,
227
- meta = kopf .Meta ({"metadata" : {"name" : "mysecret" }}),
228
- name = "mysecret" ,
229
- uid = "mysecretuid" ,
230
- logger = self .logger ,
231
- reason = "update" ,
232
- )
233
-
234
- # Namespaced secret should be updated with the new data.
235
- self .assertEqual (replace_namespaced_secret_called_count_for_ns2 , 1 )
236
- self .assertEqual (create_namespaced_secret_called_count_for_ns2 , 0 )
237
-
238
- # The namespace should be deleted from the syncedns status of the clustersecret.
239
- patch_clustersecret_status .assert_called_once_with (
240
- logger = self .logger ,
241
- name = csec .name ,
242
- new_status = {'create_fn' : {'syncedns' : ["myns2" ]}},
243
- custom_objects_api = custom_objects_api ,
244
- )
245
-
246
- # Namespace should be deleted from the cache.
247
- self .assertEqual (
248
- csecs_cache .get_cluster_secret ("mysecretuid" ).body .get ("status" ),
249
- {"create_fn" : {"syncedns" : ["myns2" ]}},
250
- )
251
- self .assertEqual (
252
- csecs_cache .get_cluster_secret ("mysecretuid" ).synced_namespace ,
253
- ["myns2" ],
254
- )
255
-
256
119
def test_create_fn (self ):
257
120
"""Namespace name must be correct in the cache.
258
121
"""
@@ -319,6 +182,7 @@ def test_ns_create(self):
319
182
namespace_watcher (
320
183
logger = self .logger ,
321
184
meta = kopf .Meta ({"metadata" : {"name" : "myns" }}),
185
+ reason = "create" ,
322
186
)
323
187
)
324
188
@@ -343,6 +207,54 @@ def test_ns_create(self):
343
207
["default" , "myns" ],
344
208
)
345
209
210
+ def test_ns_delete (self ):
211
+ """Deleted namespace must be removed from cluster secret 'status.create_fn.syncedns' filed.
212
+ """
213
+
214
+ mock_v1 = Mock ()
215
+
216
+ # Define the predefined list of namespaces you want to use in the test (after namespace deletion)
217
+ predefined_nss = [Mock (metadata = V1ObjectMeta (name = ns )) for ns in ["default" ]]
218
+
219
+ # Configure the mock's behavior to return the predefined namespaces when list_namespace is called
220
+ mock_v1 .list_namespace .return_value .items = predefined_nss
221
+
222
+ patch_clustersecret_status = Mock ()
223
+
224
+ # The list of synced namespaces here are before namespace deletion handler is called
225
+ csec = BaseClusterSecret (
226
+ uid = "mysecretuid" ,
227
+ name = "mysecret" ,
228
+ body = {"metadata" : {"name" : "mysecret" }, "data" : "mydata" },
229
+ synced_namespace = ["default" , "myns" ],
230
+ )
231
+
232
+ csecs_cache .set_cluster_secret (csec )
233
+
234
+ with patch ("handlers.v1" , mock_v1 ), \
235
+ patch ("handlers.patch_clustersecret_status" , patch_clustersecret_status ):
236
+ asyncio .run (
237
+ namespace_watcher (
238
+ logger = self .logger ,
239
+ meta = kopf .Meta ({"metadata" : {"name" : "myns" }}),
240
+ reason = "delete" ,
241
+ )
242
+ )
243
+
244
+ # The syncedns status of the clustersecret should not contains deleted namespace.
245
+ patch_clustersecret_status .assert_called_once_with (
246
+ logger = self .logger ,
247
+ name = csec .name ,
248
+ new_status = {'create_fn' : {'syncedns' : ["default" ]}},
249
+ custom_objects_api = custom_objects_api ,
250
+ )
251
+
252
+ # The deleted namespace should not be in the cache.
253
+ self .assertCountEqual (
254
+ csecs_cache .get_cluster_secret ("mysecretuid" ).synced_namespace ,
255
+ ["default" ],
256
+ )
257
+
346
258
def test_startup_fn (self ):
347
259
"""Must not fail on empty namespace in ClusterSecret metadata (it's cluster-wide after all).
348
260
"""
0 commit comments