Skip to content

Commit ffc48b2

Browse files
authored
Add tests to ensure resource reference is not replaced by controller (#220)
Issue [#1880](aws-controllers-k8s/community#1880) Description of changes: These tests ensure that after an update, the controller won't replace the resource reference with the ID itself. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent ddb3682 commit ffc48b2

File tree

4 files changed

+144
-2
lines changed

4 files changed

+144
-2
lines changed

pkg/resource/route_table/hooks.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,9 @@ func (rm *resourceManager) customUpdateRouteTable(
236236
}
237237
}
238238

239-
return updated, nil
239+
newDesired := rm.concreteResource(desired.DeepCopy())
240+
newDesired.ko.Status = updated.ko.Status
241+
return newDesired, nil
240242
}
241243

242244
func (rm *resourceManager) requiredFieldsMissingForCreateRoute(
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
apiVersion: ec2.services.k8s.aws/v1alpha1
2+
kind: InternetGateway
3+
metadata:
4+
name: $INTERNET_GATEWAY_NAME
5+
spec:
6+
vpcRef:
7+
from:
8+
name: $VPC_NAME
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
apiVersion: ec2.services.k8s.aws/v1alpha1
2+
kind: RouteTable
3+
metadata:
4+
name: $ROUTE_TABLE_NAME
5+
spec:
6+
routes:
7+
- destinationCIDRBlock: $DEST_CIDR_BLOCK
8+
gatewayRef:
9+
from:
10+
name: $INTERNET_GATEWAY_NAME
11+
vpcRef:
12+
from:
13+
name: $VPC_NAME
14+
tags:
15+
- key: $TAG_KEY
16+
value: $TAG_VALUE

test/e2e/tests/test_references.py

Lines changed: 117 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from e2e.tests.helper import EC2Validator
2828

2929
CREATE_WAIT_AFTER_SECONDS = 20
30+
MODIFY_WAIT_AFTER_SECONDS = 30
3031
DELETE_WAIT_AFTER_SECONDS = 10
3132
DELETE_TIMEOUT_SECONDS = 300
3233

@@ -167,4 +168,119 @@ def test_references(self, ec2_client):
167168
ec2_validator.assert_vpc_endpoint(vpc_endpoint_id, exists=False)
168169
ec2_validator.assert_subnet(subnet_id, exists=False)
169170
ec2_validator.assert_security_group(sg_id, exists=False)
170-
ec2_validator.assert_vpc(vpc_id, exists=False)
171+
ec2_validator.assert_vpc(vpc_id, exists=False)
172+
173+
def test_array_references(self, ec2_client):
174+
route_table_name = random_suffix_name("route-table-test", 24)
175+
vpc_name = random_suffix_name("vpc-ref-test", 24)
176+
gateway_name = random_suffix_name("gateway-ref-test", 24)
177+
178+
test_values = REPLACEMENT_VALUES.copy()
179+
test_values["ROUTE_TABLE_NAME"] = route_table_name
180+
test_values["DEST_CIDR_BLOCK"] = "0.0.0.0/0"
181+
test_values["INTERNET_GATEWAY_NAME"] = gateway_name
182+
test_values["VPC_NAME"] = vpc_name
183+
test_values["CIDR_BLOCK"] = "10.0.0.0/16"
184+
test_values["ENABLE_DNS_SUPPORT"] = "False"
185+
test_values["ENABLE_DNS_HOSTNAMES"] = "False"
186+
test_values["DISALLOW_DEFAULT_SECURITY_GROUP_RULE"] = "False"
187+
188+
# Load CRs
189+
route_table_resource_data = load_ec2_resource(
190+
"route_table_ref",
191+
additional_replacements=test_values
192+
)
193+
vpc_resource_data = load_ec2_resource(
194+
"vpc",
195+
additional_replacements=test_values
196+
)
197+
gateway_resource_data = load_ec2_resource(
198+
"internet_gateway_ref",
199+
additional_replacements=test_values
200+
)
201+
202+
# This test creates resources in order,
203+
204+
# Create VPC
205+
vpc_ref = k8s.CustomResourceReference(
206+
CRD_GROUP, CRD_VERSION, 'vpcs',
207+
vpc_name, namespace="default",
208+
)
209+
k8s.create_custom_resource(vpc_ref, vpc_resource_data)
210+
211+
# Create Internet Gateway
212+
gateway_ref = k8s.CustomResourceReference(
213+
CRD_GROUP, CRD_VERSION, 'internetgateways',
214+
gateway_name, namespace="default",
215+
)
216+
k8s.create_custom_resource(gateway_ref, gateway_resource_data)
217+
218+
# Create route table
219+
route_table_ref = k8s.CustomResourceReference(
220+
CRD_GROUP, CRD_VERSION, 'routetables',
221+
route_table_name, namespace="default",
222+
)
223+
k8s.create_custom_resource(route_table_ref, route_table_resource_data)
224+
225+
# Wait a few seconds so resources are synced
226+
time.sleep(CREATE_WAIT_AFTER_SECONDS)
227+
assert k8s.wait_on_condition(vpc_ref, "ACK.ResourceSynced", "True", wait_periods=5)
228+
assert k8s.wait_on_condition(gateway_ref, "ACK.ResourceSynced", "True", wait_periods=5)
229+
assert k8s.wait_on_condition(route_table_ref, "ACK.ResourceSynced", "True", wait_periods=10)
230+
231+
assert k8s.wait_on_condition(gateway_ref, "ACK.ReferencesResolved", "True", wait_periods=5)
232+
assert k8s.wait_on_condition(route_table_ref, "ACK.ReferencesResolved", "True", wait_periods=10)
233+
234+
# Acquire Internet Gateway ID
235+
gateway_cr = k8s.get_resource(gateway_ref)
236+
assert 'status' in gateway_cr
237+
gateway_id = gateway_cr["status"]["internetGatewayID"]
238+
239+
# Ensure routetable contains reference in spec
240+
route_table_cr = k8s.get_resource(route_table_ref)
241+
assert 'spec' in route_table_cr
242+
assert 'vpcRef' in route_table_cr['spec']
243+
assert route_table_cr['spec']['vpcRef']['from']['name'] == vpc_name
244+
assert 'routes' in route_table_cr['spec']
245+
assert len(route_table_cr['spec']['routes']) == 1
246+
assert 'gatewayID' not in route_table_cr['spec']['routes'][0]
247+
assert 'gatewayRef' in route_table_cr['spec']['routes'][0]
248+
assert route_table_cr['spec']['routes'][0]['gatewayRef']['from']['name'] == gateway_name
249+
assert 'status' in route_table_cr
250+
assert 'routeStatuses' in route_table_cr['status']
251+
found_gateway_id = False
252+
for rs in route_table_cr['status']['routeStatuses']:
253+
if 'gatewayID' in rs and rs['gatewayID'] == gateway_id:
254+
found_gateway_id = True
255+
assert found_gateway_id
256+
257+
user_tag = {
258+
"tag": "my_tag",
259+
"value": "my_val"
260+
}
261+
route_table_update = {
262+
'spec': {
263+
'tags': [user_tag]
264+
}
265+
}
266+
k8s.patch_custom_resource(route_table_ref, route_table_update)
267+
time.sleep(MODIFY_WAIT_AFTER_SECONDS)
268+
assert k8s.wait_on_condition(route_table_ref, "ACK.ResourceSynced", "True", wait_periods=5)
269+
assert k8s.wait_on_condition(route_table_ref, "ACK.ReferencesResolved", "True", wait_periods=5)
270+
271+
# Ensure that the reference has not changed
272+
route_table_cr = k8s.get_resource(route_table_ref)
273+
assert 'spec' in route_table_cr
274+
assert 'routes' in route_table_cr['spec']
275+
assert len(route_table_cr['spec']['routes']) == 1
276+
assert 'gatewayID' not in route_table_cr['spec']['routes'][0]
277+
assert 'gatewayRef' in route_table_cr['spec']['routes'][0]
278+
assert route_table_cr['spec']['routes'][0]['gatewayRef']['from']['name'] == gateway_name
279+
280+
# Delete All
281+
_, deleted = k8s.delete_custom_resource(route_table_ref)
282+
assert deleted
283+
_, deleted = k8s.delete_custom_resource(gateway_ref)
284+
assert deleted
285+
_, deleted = k8s.delete_custom_resource(vpc_ref)
286+
assert deleted

0 commit comments

Comments
 (0)