1
+ # Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You may
4
+ # not use this file except in compliance with the License. A copy of the
5
+ # License is located at
6
+ #
7
+ # http://aws.amazon.com/apache2.0/
8
+ #
9
+ # or in the "license" file accompanying this file. This file is distributed
10
+ # on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11
+ # express or implied. See the License for the specific language governing
12
+ # permissions and limitations under the License.
13
+
14
+ """Integration tests for EC2 resource references
15
+ """
16
+
17
+ from os import environ
18
+ import datetime
19
+ import pytest
20
+ import time
21
+
22
+ from acktest .resources import random_suffix_name
23
+ from acktest .k8s import resource as k8s
24
+ from acktest .aws .identity import get_region
25
+ from e2e import service_marker , CRD_GROUP , CRD_VERSION , load_ec2_resource
26
+ from e2e .replacement_values import REPLACEMENT_VALUES
27
+ from e2e .tests .helper import EC2Validator
28
+
29
+ CREATE_WAIT_AFTER_SECONDS = 20
30
+ DELETE_WAIT_AFTER_SECONDS = 10
31
+ DELETE_TIMEOUT_SECONDS = 300
32
+
33
+ def wait_for_delete_or_die (ec2_client , vpc_endpoint_id , timeout ):
34
+ while True :
35
+ if datetime .datetime .now () >= timeout :
36
+ pytest .fail ("Timed out waiting for VPC Endpoint to be deleted from EC2" )
37
+ time .sleep (DELETE_WAIT_AFTER_SECONDS )
38
+ try :
39
+ ec2_client .describe_vpc_endpoints (VpcEndpointIds = [vpc_endpoint_id ])
40
+ except ec2_client .exceptions .ClientError :
41
+ break
42
+
43
+ @service_marker
44
+ @pytest .mark .canary
45
+ class TestEC2References :
46
+ def test_references (self , ec2_client ):
47
+ vpc_endpoint_name = random_suffix_name ("vpc-endpoint-test" , 24 )
48
+ vpc_name = random_suffix_name ("vpc-ref-test" , 24 )
49
+ subnet_name = random_suffix_name ("subnet-ref-test" , 24 )
50
+ security_group_name = random_suffix_name ("sec-group-ref-test" , 24 )
51
+
52
+ test_values = REPLACEMENT_VALUES .copy ()
53
+ test_values ["VPC_ENDPOINT_REF_NAME" ] = vpc_endpoint_name
54
+ # Type 'Interface' allows the use of Security Groups and Subnet
55
+ test_values ["VPC_ENDPOINT_TYPE" ] = "Interface"
56
+ test_values ["SERVICE_NAME" ] = f'com.amazonaws.{ get_region ()} .s3'
57
+ test_values ["VPC_NAME" ] = vpc_name
58
+ test_values ["CIDR_BLOCK" ] = "10.0.0.0/16"
59
+ test_values ["SUBNET_CIDR_BLOCK" ] = "10.0.255.0/24"
60
+ test_values ["SUBNET_REF_NAME" ] = subnet_name
61
+ test_values ["SECURITY_GROUP_REF_NAME" ] = security_group_name
62
+ test_values ["SECURITY_GROUP_DESCRIPTION" ] = "TestingSecurityGroup-ack-ref"
63
+
64
+ # Load CRs
65
+ vpc_endpoint_resource_data = load_ec2_resource (
66
+ "vpc_endpoint_ref" ,
67
+ additional_replacements = test_values ,
68
+ )
69
+ sg_resource_data = load_ec2_resource (
70
+ "security_group_ref" ,
71
+ additional_replacements = test_values ,
72
+ )
73
+ subnet_resource_data = load_ec2_resource (
74
+ "subnet_ref" ,
75
+ additional_replacements = test_values ,
76
+ )
77
+ vpc_resource_data = load_ec2_resource (
78
+ "vpc" ,
79
+ additional_replacements = test_values ,
80
+ )
81
+
82
+ # This test creates resources in reverse order (VPC last) so that reference
83
+ # resolution fails upon resource creation. Eventually, resources become synced
84
+ # and references resolve.
85
+
86
+ # Create VPC Endpoint. Requires: VPC, Subnet, and SecurityGroup
87
+ vpc_endpoint_ref = k8s .CustomResourceReference (
88
+ CRD_GROUP , CRD_VERSION , 'vpcendpoints' ,
89
+ vpc_endpoint_name , namespace = "default" ,
90
+ )
91
+ k8s .create_custom_resource (vpc_endpoint_ref , vpc_endpoint_resource_data )
92
+
93
+ # Create Subnet. Requires: VPC
94
+ subnet_ref = k8s .CustomResourceReference (
95
+ CRD_GROUP , CRD_VERSION , 'subnets' ,
96
+ subnet_name , namespace = "default" ,
97
+ )
98
+ k8s .create_custom_resource (subnet_ref , subnet_resource_data )
99
+
100
+ # Create SecurityGroups. Requires: VPC
101
+ sg_ref = k8s .CustomResourceReference (
102
+ CRD_GROUP , CRD_VERSION , 'securitygroups' ,
103
+ security_group_name , namespace = "default" ,
104
+ )
105
+ k8s .create_custom_resource (sg_ref , sg_resource_data )
106
+
107
+ # Create VPC. Requires: None
108
+ vpc_ref = k8s .CustomResourceReference (
109
+ CRD_GROUP , CRD_VERSION , 'vpcs' ,
110
+ vpc_name , namespace = "default" ,
111
+ )
112
+ k8s .create_custom_resource (vpc_ref , vpc_resource_data )
113
+
114
+ # Wait a few seconds so resources get persisted in etcd
115
+ time .sleep (CREATE_WAIT_AFTER_SECONDS )
116
+
117
+ # Check resources sync & resolve
118
+ assert k8s .wait_on_condition (vpc_ref , "ACK.ResourceSynced" , "True" , wait_periods = 5 )
119
+ assert k8s .wait_on_condition (sg_ref , "ACK.ResourceSynced" , "True" , wait_periods = 5 )
120
+ assert k8s .wait_on_condition (subnet_ref , "ACK.ResourceSynced" , "True" , wait_periods = 5 )
121
+
122
+ assert k8s .wait_on_condition (sg_ref , "ACK.ReferencesResolved" , "True" , wait_periods = 5 )
123
+ assert k8s .wait_on_condition (subnet_ref , "ACK.ReferencesResolved" , "True" , wait_periods = 5 )
124
+ assert k8s .wait_on_condition (vpc_endpoint_ref , "ACK.ReferencesResolved" , "True" , wait_periods = 5 )
125
+
126
+ # Acquire resource IDs
127
+ vpc_endpoint_cr = k8s .get_resource (vpc_endpoint_ref )
128
+ vpc_endpoint_id = vpc_endpoint_cr ["status" ]["vpcEndpointID" ]
129
+ subnet_cr = k8s .get_resource (subnet_ref )
130
+ subnet_id = subnet_cr ["status" ]["subnetID" ]
131
+ sg_cr = k8s .get_resource (sg_ref )
132
+ sg_id = sg_cr ["status" ]["id" ]
133
+ vpc_cr = k8s .get_resource (vpc_ref )
134
+ vpc_id = vpc_cr ["status" ]["vpcID" ]
135
+
136
+ # Check resources exist in AWS
137
+ ec2_validator = EC2Validator (ec2_client )
138
+ ec2_validator .assert_vpc_endpoint (vpc_endpoint_id )
139
+ ec2_validator .assert_subnet (subnet_id )
140
+ ec2_validator .assert_security_group (sg_id )
141
+ ec2_validator .assert_vpc (vpc_id )
142
+
143
+ # Delete resources
144
+ _ , deleted = k8s .delete_custom_resource (vpc_endpoint_ref , 6 , 5 )
145
+ assert deleted is True
146
+
147
+ # If VPC Endpoint is not completely removed server-side, then remaining
148
+ # resources will NOT delete successfully due to dependency exceptions
149
+ now = datetime .datetime .now ()
150
+ timeout = now + datetime .timedelta (seconds = DELETE_TIMEOUT_SECONDS )
151
+ wait_for_delete_or_die (ec2_client , vpc_endpoint_id , timeout )
152
+
153
+ _ , deleted = k8s .delete_custom_resource (subnet_ref , 6 , 5 )
154
+ assert deleted is True
155
+ time .sleep (DELETE_WAIT_AFTER_SECONDS )
156
+
157
+ _ , deleted = k8s .delete_custom_resource (sg_ref , 6 , 5 )
158
+ assert deleted is True
159
+ time .sleep (DELETE_WAIT_AFTER_SECONDS )
160
+
161
+ _ , deleted = k8s .delete_custom_resource (vpc_ref , 6 , 5 )
162
+ assert deleted is True
163
+ time .sleep (DELETE_WAIT_AFTER_SECONDS )
164
+
165
+ # Check resources no longer exist in AWS
166
+ ec2_validator .assert_vpc_endpoint (vpc_endpoint_id , exists = False )
167
+ ec2_validator .assert_subnet (subnet_id , exists = False )
168
+ ec2_validator .assert_security_group (sg_id , exists = False )
169
+ ec2_validator .assert_vpc (vpc_id , exists = False )
0 commit comments