Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions e3/aws/cfn/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class AWSType(Enum):
'AWS::EC2::SubnetRouteTableAssociation'
EC2_VOLUME = 'AWS::EC2::Volume'
EC2_VPC = 'AWS::EC2::VPC'
EC2_VPC_ENDPOINT = 'AWS::EC2::VPC_ENDPOINT'
EC2_VPC_GATEWAY_ATTACHMENT = 'AWS::EC2::VPCGatewayAttachment'
IAM_ROLE = 'AWS::IAM::Role'
IAM_POLICY = 'AWS::IAM::Policy'
Expand Down Expand Up @@ -68,6 +69,21 @@ def __init__(self, content):
self.content = content


class Join(object):
"""Intrinsic function Fn::Join."""

def __init__(self, content, delimiter=""):
"""Initialize a Join object.

:param content: a list
:type content: list
:param delimiter: a join delimiter
:type delimiter: str
"""
self.content = content
self.delimiter = delimiter


# Declare Yaml representer for intrinsic functions

def getatt_representer(dumper, data):
Expand All @@ -83,9 +99,14 @@ def base64_representer(dumper, data):
return dumper.represent_scalar('!Base64', data.content)


def join_representer(dumper, data):
return dumper.represent_sequence('!Join', [data.delimiter, data.content])


yaml.add_representer(GetAtt, getatt_representer)
yaml.add_representer(Ref, ref_representer)
yaml.add_representer(Base64, base64_representer)
yaml.add_representer(Join, join_representer)


class Resource(object):
Expand Down
43 changes: 42 additions & 1 deletion e3/aws/cfn/ec2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
from email.contentmanager import raw_data_manager
from email.message import EmailMessage

from e3.aws.cfn import Resource, AWSType, GetAtt, Base64
from e3.aws.cfn import Resource, AWSType, GetAtt, Base64, Join, Ref
from e3.aws.cfn.iam import PolicyDocument
from e3.aws.ec2.ami import AMI


Expand Down Expand Up @@ -297,6 +298,46 @@ def cidrblock(self):
return self.getatt('CidrBlock')


class VPCEndpoint(Resource):
"""VPC Endpoint to Amazon Service."""

def __init__(self, name, service, vpc, route_tables, policy_document):
"""Initialize a VPC endpoint.

:param name: logical name in the stack of the entity
:type name: str
:param service: name of the service to connect (s3 or dynamodb)
:type service: str
:param vpc: VPC in which the endpoint is attached to
:type vpc: e3.aws.cfn.ec2.VPC
:param route_tables: a list of route table that have access to the
endpoint.
:type route_tables: list[RouteTable]
:param policy_document: policy document attached to the endpoint.
:type policy_docyment: e3.aws.cfn.ec2.security.PolicyDocument
"""
super(VPCEndpoint, self).__init__(name, kind=AWSType.EC2_VPC_ENDPOINT)
assert service in ('dynamodb', 's3'), 'Invalid service: %s' % service
self.service = service
assert isinstance(vpc, VPC), 'VPC instance expected'
self.vpc = vpc
self.route_tables = route_tables
for rt in self.route_tables:
assert isinstance(rt, RouteTable), 'RouteTable expected'
self.policy_document = policy_document
assert isinstance(self.policy_document, PolicyDocument)

@property
def properties(self):
return {
'VpcId': self.vpc.ref,
'ServiceName': Join(["com.amazonaws.",
Ref("AWS::Region"),
"." + self.service]),
'PolicyDocument': self.policy_document.properties,
'RouteTableIds': [rt.ref for rt in self.route_tables]}


class Subnet(Resource):
"""EC2 subnet."""

Expand Down
10 changes: 9 additions & 1 deletion tests/tests_e3_aws/cfn/ec2/main_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
from e3.aws.cfn.ec2 import (VPC, EphemeralDisk, Instance, InternetGateway,
NetworkInterface, Route, RouteTable, Subnet,
SubnetRouteTableAssociation, UserData,
VPCGatewayAttachment)
VPCEndpoint, VPCGatewayAttachment)
from e3.aws.cfn.ec2.security import SecurityGroup
from e3.aws.cfn.iam import Allow, PolicyDocument
from e3.aws.ec2.ami import AMI


Expand All @@ -32,6 +33,13 @@ def test_create_network():
s += SubnetRouteTableAssociation('RTSAssoc',
s['BuildPublicSubnet'],
s['RT'])
p = PolicyDocument().append(Allow(to='GetObject',
on='arn:aws:s3:::abucket/*',
service='ec2.amazonaws.com'))

s += VPCEndpoint('S3EndPoint',
's3', s['BuildVPC'], [s['RT']],
policy_document=p)
assert s.body


Expand Down