CF - Add support for AWS::EC2::VPNGateway (create only) (#4263)

This commit is contained in:
Bert Blommers 2021-10-10 21:43:49 +00:00 committed by GitHub
parent 4795888fda
commit 51e59c7ac5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 118 additions and 32 deletions

View File

@ -5750,7 +5750,7 @@ class InternetGatewayBackend(object):
raise ResourceAlreadyAssociatedError(internet_gateway_id) raise ResourceAlreadyAssociatedError(internet_gateway_id)
vpc = self.get_vpc(vpc_id) vpc = self.get_vpc(vpc_id)
igw.vpc = vpc igw.vpc = vpc
return True return VPCGatewayAttachment(gateway_id=internet_gateway_id, vpc_id=vpc_id)
def get_internet_gateway(self, internet_gateway_id): def get_internet_gateway(self, internet_gateway_id):
igw_ids = [internet_gateway_id] igw_ids = [internet_gateway_id]
@ -5890,12 +5890,16 @@ class VPCGatewayAttachment(CloudFormationModel):
properties = cloudformation_json["Properties"] properties = cloudformation_json["Properties"]
ec2_backend = ec2_backends[region_name] ec2_backend = ec2_backends[region_name]
attachment = ec2_backend.create_vpc_gateway_attachment( vpn_gateway_id = properties.get("VpnGatewayId", None)
gateway_id=properties["InternetGatewayId"], vpc_id=properties["VpcId"] internet_gateway_id = properties.get("InternetGatewayId", None)
) if vpn_gateway_id:
ec2_backend.attach_internet_gateway( attachment = ec2_backend.attach_vpn_gateway(
properties["InternetGatewayId"], properties["VpcId"] vpc_id=properties["VpcId"], vpn_gateway_id=vpn_gateway_id
) )
elif internet_gateway_id:
attachment = ec2_backend.attach_internet_gateway(
internet_gateway_id=internet_gateway_id, vpc_id=properties["VpcId"]
)
return attachment return attachment
@property @property
@ -7106,7 +7110,7 @@ class NetworkAclEntry(TaggedEC2Resource):
self.port_range_to = port_range_to self.port_range_to = port_range_to
class VpnGateway(TaggedEC2Resource): class VpnGateway(CloudFormationModel, TaggedEC2Resource):
def __init__( def __init__(
self, self,
ec2_backend, ec2_backend,
@ -7127,6 +7131,30 @@ class VpnGateway(TaggedEC2Resource):
self.attachments = {} self.attachments = {}
super().__init__() super().__init__()
@staticmethod
def cloudformation_name_type():
return None
@staticmethod
def cloudformation_type():
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcgatewayattachment.html
return "AWS::EC2::VPNGateway"
@classmethod
def create_from_cloudformation_json(
cls, resource_name, cloudformation_json, region_name
):
properties = cloudformation_json["Properties"]
_type = properties["Type"]
asn = properties.get("AmazonSideAsn", None)
ec2_backend = ec2_backends[region_name]
return ec2_backend.create_vpn_gateway(type=_type, amazon_side_asn=asn)
@property
def physical_resource_id(self):
return self.id
def get_filter_value(self, filter_name): def get_filter_value(self, filter_name):
if filter_name == "attachment.vpc-id": if filter_name == "attachment.vpc-id":
return self.attachments.keys() return self.attachments.keys()
@ -8444,7 +8472,6 @@ class EC2Backend(
RouteBackend, RouteBackend,
InternetGatewayBackend, InternetGatewayBackend,
EgressOnlyInternetGatewayBackend, EgressOnlyInternetGatewayBackend,
VPCGatewayAttachmentBackend,
SpotFleetBackend, SpotFleetBackend,
SpotRequestBackend, SpotRequestBackend,
SpotPriceBackend, SpotPriceBackend,

View File

@ -215,37 +215,96 @@ def test_volume_size_through_cloudformation():
volumes["Volumes"][0]["Size"].should.equal(50) volumes["Volumes"][0]["Size"].should.equal(50)
# Has boto3 equivalent @mock_ec2
@mock_ec2_deprecated @mock_cloudformation
@mock_cloudformation_deprecated def test_attach_internet_gateway():
def test_subnet_tags_through_cloudformation(): ec2 = boto3.client("ec2", region_name="us-east-1")
vpc_conn = boto.vpc.connect_to_region("us-west-1") cf = boto3.client("cloudformation", region_name="us-east-1")
vpc = vpc_conn.create_vpc("10.0.0.0/16")
subnet_template = { volume_template = {
"AWSTemplateFormatVersion": "2010-09-09", "AWSTemplateFormatVersion": "2010-09-09",
"Resources": { "Resources": {
"testSubnet": { "DEVLAB1": {
"Type": "AWS::EC2::Subnet", "Type": "AWS::EC2::VPC",
"Properties": {"CidrBlock": "10.0.0.0/16"},
},
"internetgateway": {"Type": "AWS::EC2::InternetGateway"},
"DEVLAB1VPGAttaching": {
"Type": "AWS::EC2::VPCGatewayAttachment",
"Properties": { "Properties": {
"VpcId": vpc.id, "VpcId": {"Ref": "DEVLAB1"},
"CidrBlock": "10.0.0.0/24", "InternetGatewayId": {"Ref": "internetgateway"},
"AvailabilityZone": "us-west-1b",
"Tags": [
{"Key": "foo", "Value": "bar"},
{"Key": "blah", "Value": "baz"},
],
}, },
} },
}, },
} }
cf_conn = boto.cloudformation.connect_to_region("us-west-1") template_json = json.dumps(volume_template)
template_json = json.dumps(subnet_template) stack_name = str(uuid4())[0:6]
cf_conn.create_stack("test_stack", template_body=template_json) cf.create_stack(StackName=stack_name, TemplateBody=template_json)
stack_resources = cf.list_stack_resources(StackName=stack_name)[
"StackResourceSummaries"
]
subnet = vpc_conn.get_all_subnets(filters={"cidrBlock": "10.0.0.0/24"})[0] # Verify VPC is created
subnet.tags["foo"].should.equal("bar") vpc = [r for r in stack_resources if r["ResourceType"] == "AWS::EC2::VPC"][0]
subnet.tags["blah"].should.equal("baz") vpc["LogicalResourceId"].should.equal("DEVLAB1")
vpc_id = vpc["PhysicalResourceId"]
# Verify Internet Gateway is created
gateway_id = get_resource_id("AWS::EC2::InternetGateway", stack_resources)
gateway = ec2.describe_internet_gateways(InternetGatewayIds=[gateway_id])[
"InternetGateways"
][0]
gateway["Attachments"].should.contain({"State": "available", "VpcId": vpc_id})
gateway["Tags"].should.contain(
{"Key": "aws:cloudformation:logical-id", "Value": "internetgateway"}
)
@mock_ec2
@mock_cloudformation
def test_attach_vpn_gateway():
ec2 = boto3.client("ec2", region_name="us-east-1")
cf = boto3.client("cloudformation", region_name="us-east-1")
vpn_gateway_template = {
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"DEVLAB1": {
"Type": "AWS::EC2::VPC",
"Properties": {"CidrBlock": "10.0.0.0/16"},
},
"DEVLAB1DCGateway": {
"Type": "AWS::EC2::VPNGateway",
"Properties": {"Type": "ipsec.1",},
},
"DEVLAB1VPGAttaching": {
"Type": "AWS::EC2::VPCGatewayAttachment",
"Properties": {
"VpcId": {"Ref": "DEVLAB1"},
"VpnGatewayId": {"Ref": "DEVLAB1DCGateway"},
},
"DependsOn": ["DEVLAB1DCGateway"],
},
},
}
template_json = json.dumps(vpn_gateway_template)
stack_name = str(uuid4())[0:6]
cf.create_stack(StackName=stack_name, TemplateBody=template_json)
stack_resources = cf.list_stack_resources(StackName=stack_name)[
"StackResourceSummaries"
]
gateway_id = get_resource_id("AWS::EC2::VPNGateway", stack_resources)
vpc_id = get_resource_id("AWS::EC2::VPC", stack_resources)
gateway = ec2.describe_vpn_gateways(VpnGatewayIds=[gateway_id])["VpnGateways"][0]
gateway["VpcAttachments"].should.contain({"State": "attached", "VpcId": vpc_id})
def get_resource_id(resource_type, stack_resources):
r = [r for r in stack_resources if r["ResourceType"] == resource_type][0]
return r["PhysicalResourceId"]
@mock_ec2 @mock_ec2