1
- import pytest
2
1
import time
3
2
import logging
3
+ import pytest
4
+ import boto3
4
5
5
6
from acktest import tags
6
7
from acktest .resources import random_suffix_name
17
18
DELETE_WAIT_AFTER_SECONDS = 10
18
19
MODIFY_WAIT_AFTER_SECONDS = 5
19
20
DEFAULT_WAIT_AFTER_SECONDS = 5
21
+ PATCH_WAIT_AFTER_SECONDS = 30
20
22
21
23
@pytest .fixture
22
24
def simple_vpc_peering_connection (request ):
25
+ '''
26
+ Fixture for creating a Peering Connection using 'VPCID' and 'PeerVPCID'
27
+ '''
23
28
resource_name = random_suffix_name ("simple-vpc-peering-connection-test" , 40 )
24
29
resources = get_bootstrap_resources ()
25
30
@@ -29,11 +34,11 @@ def simple_vpc_peering_connection(request):
29
34
replacements = REPLACEMENT_VALUES .copy ()
30
35
replacements ["VPC_NAME" ] = resource_name
31
36
replacements ["CIDR_BLOCK" ] = "10.1.0.0/16"
32
- replacements ["ENABLE_DNS_SUPPORT" ] = "False "
33
- replacements ["ENABLE_DNS_HOSTNAMES" ] = "False "
37
+ replacements ["ENABLE_DNS_SUPPORT" ] = "True "
38
+ replacements ["ENABLE_DNS_HOSTNAMES" ] = "True "
34
39
replacements ["TAG_KEY" ] = "initialtagkey"
35
40
replacements ["TAG_VALUE" ] = "initialtagvalue"
36
-
41
+
37
42
marker = request .node .get_closest_marker ("resource_data" )
38
43
if marker is not None :
39
44
data = marker .args [0 ]
@@ -62,7 +67,6 @@ def simple_vpc_peering_connection(request):
62
67
assert k8s .get_resource_exists (vpc_ref )
63
68
64
69
# Create the VPC Peering Connection
65
-
66
70
# Replacements for VPC Peering Connection
67
71
replacements ["VPC_PEERING_CONNECTION_NAME" ] = resource_name
68
72
replacements ["VPC_ID" ] = resources .SharedTestVPC .vpc_id
@@ -89,11 +93,11 @@ def simple_vpc_peering_connection(request):
89
93
wait_for_vpc_peering_connection_status (ref )
90
94
# Get the CR again after waiting for the Status to be updated
91
95
cr = k8s .wait_resource_consumed_by_controller (ref )
92
- assert cr ["status" ]["status" ]["code" ] == "active"
96
+ assert cr ["status" ]["status" ]["code" ] == "active"
93
97
94
98
yield (ref , cr )
95
99
96
- # Delete VPC Peering Connection k8s resource
100
+ # Delete VPC Peering Connection k8s resource
97
101
try :
98
102
_ , deleted = k8s .delete_custom_resource (ref , 3 , 10 )
99
103
assert deleted
@@ -102,12 +106,15 @@ def simple_vpc_peering_connection(request):
102
106
103
107
time .sleep (DELETE_WAIT_AFTER_SECONDS )
104
108
105
- # Delete VPC resource
109
+ # Delete VPC resource
106
110
_ , vpc_deleted = k8s .delete_custom_resource (vpc_ref , 3 , 10 )
107
111
assert vpc_deleted is True
108
112
109
113
@pytest .fixture
110
114
def ref_vpc_peering_connection (request ):
115
+ '''
116
+ Fixture for creating a Peering Connection using 'VPCRef' and 'PeerVPCRef'
117
+ '''
111
118
resource_name = random_suffix_name ("ref-vpc-peering-connection-test" , 40 )
112
119
113
120
# Create 2 VPCs with ACK to test Peering with and refer to them by their k8s resource name
@@ -116,11 +123,9 @@ def ref_vpc_peering_connection(request):
116
123
replacements = REPLACEMENT_VALUES .copy ()
117
124
replacements ["VPC_NAME" ] = resource_name + "-1"
118
125
replacements ["CIDR_BLOCK" ] = "10.0.0.0/16"
119
- replacements ["ENABLE_DNS_SUPPORT" ] = "False"
120
- replacements ["ENABLE_DNS_HOSTNAMES" ] = "False"
121
- replacements ["TAG_KEY" ] = "initialtagkey"
122
- replacements ["TAG_VALUE" ] = "initialtagvalue"
123
-
126
+ replacements ["ENABLE_DNS_SUPPORT" ] = "True"
127
+ replacements ["ENABLE_DNS_HOSTNAMES" ] = "True"
128
+
124
129
# Load VPC CR
125
130
vpc_1_resource_data = load_ec2_resource (
126
131
"vpc" ,
@@ -143,7 +148,7 @@ def ref_vpc_peering_connection(request):
143
148
# Replacements for Test VPC 2 (squashes previous values used by VPC 1)
144
149
replacements ["VPC_NAME" ] = resource_name + "-2"
145
150
replacements ["CIDR_BLOCK" ] = "10.1.0.0/16"
146
-
151
+
147
152
# Load VPC CR
148
153
vpc_2_resource_data = load_ec2_resource (
149
154
"vpc" ,
@@ -189,13 +194,115 @@ def ref_vpc_peering_connection(request):
189
194
assert cr is not None
190
195
assert k8s .get_resource_exists (ref )
191
196
wait_for_vpc_peering_connection_status (ref )
192
- # Get the CR again after waiting for the Status to be updated
197
+
198
+ yield (ref , cr )
199
+
200
+ # Delete VPC Peering Connection k8s resource
201
+ try :
202
+ _ , deleted = k8s .delete_custom_resource (ref , 3 , 10 )
203
+ assert deleted
204
+ except :
205
+ pass
206
+
207
+ time .sleep (DELETE_WAIT_AFTER_SECONDS )
208
+
209
+ # Delete 2 x VPC resources
210
+ try :
211
+ _ , vpc_1_deleted = k8s .delete_custom_resource (vpc_1_ref , 3 , 10 )
212
+ _ , vpc_2_deleted = k8s .delete_custom_resource (vpc_2_ref , 3 , 10 )
213
+ assert vpc_1_deleted is True
214
+ assert vpc_2_deleted is True
215
+ except :
216
+ pass
217
+
218
+ @pytest .fixture
219
+ def peering_options_vpc_peering_connection (request ):
220
+ '''
221
+ Fixture for creating a Peering Connection with Peering Options set to True
222
+ '''
223
+ resource_name = random_suffix_name ("peering-options-vpc-p-c-test" , 40 )
224
+
225
+ # Create 2 VPCs with ACK to test Peering with and refer to them by their k8s resource name
226
+
227
+ # Replacements for Test VPC 1
228
+ replacements = REPLACEMENT_VALUES .copy ()
229
+ replacements ["VPC_NAME" ] = resource_name + "-1"
230
+ replacements ["CIDR_BLOCK" ] = "10.0.0.0/16"
231
+ replacements ["ENABLE_DNS_SUPPORT" ] = "True"
232
+ replacements ["ENABLE_DNS_HOSTNAMES" ] = "True"
233
+
234
+ # Load VPC CR
235
+ vpc_1_resource_data = load_ec2_resource (
236
+ "vpc" ,
237
+ additional_replacements = replacements ,
238
+ )
239
+ logging .debug (vpc_1_resource_data )
240
+
241
+ # Create k8s resource
242
+ vpc_1_ref = k8s .CustomResourceReference (
243
+ CRD_GROUP , CRD_VERSION , VPC_RESOURCE_PLURAL ,
244
+ replacements ["VPC_NAME" ], namespace = "default" ,
245
+ )
246
+ k8s .create_custom_resource (vpc_1_ref , vpc_1_resource_data )
247
+ time .sleep (CREATE_WAIT_AFTER_SECONDS )
248
+
249
+ vpc_1_cr = k8s .wait_resource_consumed_by_controller (vpc_1_ref )
250
+ assert vpc_1_cr is not None
251
+ assert k8s .get_resource_exists (vpc_1_ref )
252
+
253
+ # Replacements for Test VPC 2 (squashes previous values used by VPC 1)
254
+ replacements ["VPC_NAME" ] = resource_name + "-2"
255
+ replacements ["CIDR_BLOCK" ] = "10.1.0.0/16"
256
+
257
+ # Load VPC CR
258
+ vpc_2_resource_data = load_ec2_resource (
259
+ "vpc" ,
260
+ additional_replacements = replacements ,
261
+ )
262
+ logging .debug (vpc_2_resource_data )
263
+
264
+ # Create k8s resource
265
+ vpc_2_ref = k8s .CustomResourceReference (
266
+ CRD_GROUP , CRD_VERSION , VPC_RESOURCE_PLURAL ,
267
+ replacements ["VPC_NAME" ], namespace = "default" ,
268
+ )
269
+ k8s .create_custom_resource (vpc_2_ref , vpc_2_resource_data )
270
+ time .sleep (CREATE_WAIT_AFTER_SECONDS )
271
+
272
+ vpc_2_cr = k8s .wait_resource_consumed_by_controller (vpc_2_ref )
273
+ assert vpc_2_cr is not None
274
+ assert k8s .get_resource_exists (vpc_2_ref )
275
+
276
+ # Create the VPC Peering Connection
277
+
278
+ # Replacements for VPC Peering Connection
279
+ replacements ["VPC_PEERING_CONNECTION_NAME" ] = resource_name
280
+ replacements ["VPC_ID" ] = vpc_1_cr ["status" ]["vpcID" ]
281
+ replacements ["PEER_VPC_ID" ] = vpc_2_cr ["status" ]["vpcID" ]
282
+
283
+ # Load VPCPeeringConnection CR
284
+ resource_data = load_ec2_resource (
285
+ "vpc_peering_connection_peering_options" ,
286
+ additional_replacements = replacements ,
287
+ )
288
+ logging .debug (resource_data )
289
+
290
+ # Create k8s resource
291
+ ref = k8s .CustomResourceReference (
292
+ CRD_GROUP , CRD_VERSION , RESOURCE_PLURAL ,
293
+ resource_name , namespace = "default" ,
294
+ )
295
+ k8s .create_custom_resource (ref , resource_data )
296
+ time .sleep (CREATE_WAIT_AFTER_SECONDS )
297
+
193
298
cr = k8s .wait_resource_consumed_by_controller (ref )
194
- assert cr ["status" ]["status" ]["code" ] == "active"
299
+ assert cr is not None
300
+ assert k8s .get_resource_exists (ref )
301
+ wait_for_vpc_peering_connection_status (ref )
195
302
196
303
yield (ref , cr )
197
304
198
- # Delete VPC Peering Connection k8s resource
305
+ # Delete VPC Peering Connection k8s resource
199
306
try :
200
307
_ , deleted = k8s .delete_custom_resource (ref , 3 , 10 )
201
308
assert deleted
@@ -205,30 +312,61 @@ def ref_vpc_peering_connection(request):
205
312
time .sleep (DELETE_WAIT_AFTER_SECONDS )
206
313
207
314
# Delete 2 x VPC resources
208
- try :
315
+ try :
209
316
_ , vpc_1_deleted = k8s .delete_custom_resource (vpc_1_ref , 3 , 10 )
210
317
_ , vpc_2_deleted = k8s .delete_custom_resource (vpc_2_ref , 3 , 10 )
211
318
assert vpc_1_deleted is True
212
319
assert vpc_2_deleted is True
213
320
except :
214
321
pass
215
322
216
- def wait_for_vpc_peering_connection_status (ref , timeout_seconds = 120 ):
323
+ def wait_for_vpc_peering_connection_status (ref , timeout_seconds = 300 ):
324
+ '''
325
+ Loops until the VPC Peering Connection's Status Code is 'active'
326
+ '''
217
327
start_time = time .time ()
218
328
while time .time () - start_time < timeout_seconds :
219
- resource = k8s .wait_resource_consumed_by_controller (ref )
220
- print ("CR contents" , resource )
221
- if resource ["status" ]["status" ]["code" ] == "active" :
222
- logging .debug ("VPC Peering Connection Status Code is 'active'" , resource )
223
- return resource
329
+ k8s_resource = k8s .wait_resource_consumed_by_controller (ref )
330
+ if k8s_resource ["status" ]["status" ]["code" ] == "active" :
331
+ logging .debug ("VPC Peering Connection Status Code is 'active'" , k8s_resource )
332
+ return k8s_resource
224
333
time .sleep (5 )
225
- print ("CR contents" , resource )
226
- raise TimeoutError (f"Timed out waiting for VPC Peering Connection status to become 'active'" , "Current status code" , resource ["status" ]["status" ]["code" ])
334
+
335
+ # Fallback to AWS API if K8s resource status is not being updated (To be removed once k8s resource's status updates normally)
336
+ c = boto3 .client ('ec2' )
337
+ aws_resource = c .describe_vpc_peering_connections (VpcPeeringConnectionIds = [k8s_resource ["status" ]["vpcPeeringConnectionID" ]])
338
+ if aws_resource ["VpcPeeringConnections" ][0 ]["Status" ]["Code" ] == "active" :
339
+ logging .debug ("VPC Peering Connection Status Code is 'active' (fallback to AWS API)" , k8s_resource , "AWS resource" , aws_resource )
340
+ return k8s_resource
341
+
342
+ # Both options timed out
343
+ raise TimeoutError ("Timed out waiting for VPC Peering Connection status to become 'active'" ,
344
+ "Current status code" , k8s_resource ["status" ]["status" ]["code" ])
345
+
346
+ def wait_for_vpc_peering_connection_peering_options (ec2_client , boolean , vpc_peering_connection_id , timeout_seconds = 300 ):
347
+ '''
348
+ Loops until the VPC Peering Connection's Peering Options are set to the provided boolean value
349
+ '''
350
+ start_time = time .time ()
351
+ ec2_validator = EC2Validator (ec2_client )
352
+ while time .time () - start_time < timeout_seconds :
353
+ aws_resource = ec2_validator .get_vpc_peering_connection (vpc_peering_connection_id )
354
+ if (aws_resource ['AccepterVpcInfo' ]['PeeringOptions' ]['AllowDnsResolutionFromRemoteVpc' ] == boolean and
355
+ aws_resource ['RequesterVpcInfo' ]['PeeringOptions' ]['AllowDnsResolutionFromRemoteVpc' ] == boolean ):
356
+ logging .debug ("VPC Peering Connection Peering Options are " + str (boolean ), aws_resource )
357
+ return aws_resource
358
+ time .sleep (5 )
359
+ raise TimeoutError ("Timed out waiting for VPC Peering Connection Peering Options to become " + str (boolean ),
360
+ "Current values are" , aws_resource ['AccepterVpcInfo' ]['PeeringOptions' ]['AllowDnsResolutionFromRemoteVpc' ],
361
+ "and" , aws_resource ['RequesterVpcInfo' ]['PeeringOptions' ]['AllowDnsResolutionFromRemoteVpc' ])
227
362
228
363
@service_marker
229
364
@pytest .mark .canary
230
365
class TestVPCPeeringConnections :
231
366
def test_create_delete_ref (self , ec2_client , ref_vpc_peering_connection ):
367
+ '''
368
+ Creates a Peering Connection using 'VPCRef' and 'PeerVPCRef'
369
+ '''
232
370
(ref , cr ) = ref_vpc_peering_connection
233
371
vpc_peering_connection_id = cr ["status" ]["vpcPeeringConnectionID" ]
234
372
@@ -246,6 +384,9 @@ def test_create_delete_ref(self, ec2_client, ref_vpc_peering_connection):
246
384
ec2_validator .assert_vpc_peering_connection (vpc_peering_connection_id , exists = False )
247
385
248
386
def test_create_delete (self , ec2_client , simple_vpc_peering_connection ):
387
+ '''
388
+ Creates a Peering Connection using 'VPCID' and 'PeerVPCID' and 'Tags'
389
+ '''
249
390
(ref , cr ) = simple_vpc_peering_connection
250
391
vpc_peering_connection_id = cr ["status" ]["vpcPeeringConnectionID" ]
251
392
@@ -263,6 +404,9 @@ def test_create_delete(self, ec2_client, simple_vpc_peering_connection):
263
404
ec2_validator .assert_vpc_peering_connection (vpc_peering_connection_id , exists = False )
264
405
265
406
def test_crud_tags (self , ec2_client , simple_vpc_peering_connection ):
407
+ '''
408
+ Creates a Peering Connection with a set of 'Tags', then updates them
409
+ '''
266
410
(ref , cr ) = simple_vpc_peering_connection
267
411
268
412
resource = k8s .get_resource (ref )
@@ -286,7 +430,7 @@ def test_crud_tags(self, ec2_client, simple_vpc_peering_connection):
286
430
expected = user_tags ,
287
431
actual = vpc_peering_connection ["Tags" ],
288
432
)
289
-
433
+
290
434
# Update tags
291
435
update_tags = [
292
436
{
@@ -355,3 +499,57 @@ def test_crud_tags(self, ec2_client, simple_vpc_peering_connection):
355
499
# Check VPC Peering Connection no longer exists in AWS
356
500
ec2_validator .assert_vpc_peering_connection (resource_id , exists = False )
357
501
502
+ def test_update_peering_options (self , ec2_client , peering_options_vpc_peering_connection ):
503
+ '''
504
+ Creates a Peering Connection with Peering Options set to True, it then updates them to False
505
+ '''
506
+ (ref , cr ) = peering_options_vpc_peering_connection
507
+ vpc_peering_connection_id = cr ["status" ]["vpcPeeringConnectionID" ]
508
+
509
+ # Check VPC Peering Connection exists
510
+ ec2_validator = EC2Validator (ec2_client )
511
+ ec2_validator .assert_vpc_peering_connection (vpc_peering_connection_id )
512
+
513
+ # Check resource synced successfully, after waiting for requeue after Patch Peering Options to True
514
+ time .sleep (PATCH_WAIT_AFTER_SECONDS )
515
+ assert k8s .wait_on_condition (ref , "ACK.ResourceSynced" , "True" , wait_periods = 5 )
516
+
517
+ # Check Peering Options in AWS
518
+ aws_res = wait_for_vpc_peering_connection_peering_options (ec2_client , True , vpc_peering_connection_id )
519
+ assert aws_res ['AccepterVpcInfo' ]['PeeringOptions' ]['AllowDnsResolutionFromRemoteVpc' ] is True
520
+ assert aws_res ['RequesterVpcInfo' ]['PeeringOptions' ]['AllowDnsResolutionFromRemoteVpc' ] is True
521
+
522
+ # Payload used to update the VPC Peering Connection
523
+ update_peering_options_payload = {
524
+ "spec" : {
525
+ "requesterPeeringConnectionOptions" : {
526
+ "allowDNSResolutionFromRemoteVPC" : False ,
527
+ },
528
+ "accepterPeeringConnectionOptions" : {
529
+ "allowDNSResolutionFromRemoteVPC" : False ,
530
+ },
531
+ },
532
+ }
533
+
534
+ # Patch the VPCPeeringConnection with the payload
535
+ k8s .patch_custom_resource (ref , update_peering_options_payload )
536
+ time .sleep (MODIFY_WAIT_AFTER_SECONDS )
537
+
538
+ # Check resource synced successfully
539
+ assert k8s .wait_on_condition (ref , "ACK.ResourceSynced" , "True" , wait_periods = 5 )
540
+
541
+ # Check for updated peering options
542
+ latest_aws_res = wait_for_vpc_peering_connection_peering_options (ec2_client , False , vpc_peering_connection_id )
543
+ assert latest_aws_res ['AccepterVpcInfo' ]['PeeringOptions' ]['AllowDnsResolutionFromRemoteVpc' ] is False
544
+ assert latest_aws_res ['RequesterVpcInfo' ]['PeeringOptions' ]['AllowDnsResolutionFromRemoteVpc' ] is False
545
+
546
+ # Delete k8s resource
547
+ try :
548
+ _ , deleted = k8s .delete_custom_resource (ref , 3 , 10 )
549
+ assert deleted
550
+ except :
551
+ pass
552
+ time .sleep (DELETE_WAIT_AFTER_SECONDS )
553
+
554
+ # Check VPC Peering Connection no longer exists in AWS
555
+ ec2_validator .assert_vpc_peering_connection (vpc_peering_connection_id , exists = False )
0 commit comments