Skip to content

Commit 34a6747

Browse files
authored
add VPCEndpoint reference test (#44)
Issue #, if available: N/A Description of changes: * Adds test coverage for resolving references using `VPCEndpoint` By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent a04fcb3 commit 34a6747

File tree

5 files changed

+207
-1
lines changed

5 files changed

+207
-1
lines changed

test/e2e/conftest.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
import boto3
1515
import pytest
16+
from acktest.aws.identity import get_region
1617

1718
def pytest_addoption(parser):
1819
parser.addoption("--runslow", action="store_true", default=False, help="run slow tests")
@@ -40,4 +41,5 @@ def pytest_collection_modifyitems(config, items):
4041

4142
@pytest.fixture(scope="module")
4243
def ec2_client():
43-
return boto3.client("ec2")
44+
region = get_region()
45+
return boto3.client("ec2", region)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
apiVersion: ec2.services.k8s.aws/v1alpha1
2+
kind: SecurityGroup
3+
metadata:
4+
name: $SECURITY_GROUP_REF_NAME
5+
spec:
6+
description: $SECURITY_GROUP_DESCRIPTION
7+
name: $SECURITY_GROUP_REF_NAME
8+
vpcRef:
9+
from:
10+
name: $VPC_NAME

test/e2e/resources/subnet_ref.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
apiVersion: ec2.services.k8s.aws/v1alpha1
2+
kind: Subnet
3+
metadata:
4+
name: $SUBNET_REF_NAME
5+
spec:
6+
cidrBlock: $SUBNET_CIDR_BLOCK
7+
vpcRef:
8+
from:
9+
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: VPCEndpoint
3+
metadata:
4+
name: $VPC_ENDPOINT_REF_NAME
5+
spec:
6+
serviceName: $SERVICE_NAME
7+
vpcEndpointType: $VPC_ENDPOINT_TYPE
8+
vpcRef:
9+
from:
10+
name: $VPC_NAME
11+
subnetRefs:
12+
- from:
13+
name: $SUBNET_REF_NAME
14+
securityGroupRefs:
15+
- from:
16+
name: $SECURITY_GROUP_REF_NAME

test/e2e/tests/test_references.py

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
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

Comments
 (0)