add, delete, describe security groups
This commit is contained in:
parent
fbd9206f23
commit
31f992fbe5
@ -3,7 +3,7 @@ from collections import defaultdict
|
|||||||
from boto.ec2.instance import Instance, InstanceState, Reservation
|
from boto.ec2.instance import Instance, InstanceState, Reservation
|
||||||
|
|
||||||
from moto.core import BaseBackend
|
from moto.core import BaseBackend
|
||||||
from .utils import random_instance_id, random_reservation_id, random_ami_id
|
from .utils import random_instance_id, random_reservation_id, random_ami_id, random_security_group_id
|
||||||
|
|
||||||
|
|
||||||
class InstanceBackend(object):
|
class InstanceBackend(object):
|
||||||
@ -133,7 +133,7 @@ class AmiBackend(object):
|
|||||||
def create_image(self, instance_id, name, description):
|
def create_image(self, instance_id, name, description):
|
||||||
# TODO: check that instance exists and pull info from it.
|
# TODO: check that instance exists and pull info from it.
|
||||||
ami_id = random_ami_id()
|
ami_id = random_ami_id()
|
||||||
instance = ec2_backend.get_instance(instance_id)
|
instance = self.get_instance(instance_id)
|
||||||
if not instance:
|
if not instance:
|
||||||
return None
|
return None
|
||||||
ami = Ami(ami_id, instance, name, description)
|
ami = Ami(ami_id, instance, name, description)
|
||||||
@ -193,7 +193,46 @@ class RegionsAndZonesBackend(object):
|
|||||||
return self.zones
|
return self.zones
|
||||||
|
|
||||||
|
|
||||||
class EC2Backend(BaseBackend, InstanceBackend, TagBackend, AmiBackend, RegionsAndZonesBackend):
|
class SecurityGroup(object):
|
||||||
|
def __init__(self, group_id, name, description):
|
||||||
|
self.id = group_id
|
||||||
|
self.name = name
|
||||||
|
self.description = description
|
||||||
|
|
||||||
|
|
||||||
|
class SecurityGroupBackend(object):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.groups = {}
|
||||||
|
|
||||||
|
def create_security_group(self, name, description):
|
||||||
|
group_id = random_security_group_id()
|
||||||
|
existing_group = self.get_security_group_from_name(name)
|
||||||
|
if existing_group:
|
||||||
|
return None
|
||||||
|
group = SecurityGroup(group_id, name, description)
|
||||||
|
self.groups[group_id] = group
|
||||||
|
return group
|
||||||
|
|
||||||
|
def describe_security_groups(self):
|
||||||
|
return self.groups.values()
|
||||||
|
|
||||||
|
def delete_security_group(self, name_or_group_id):
|
||||||
|
if name_or_group_id in self.groups:
|
||||||
|
# Group Id
|
||||||
|
return self.groups.pop(name_or_group_id)
|
||||||
|
else:
|
||||||
|
# Group Name
|
||||||
|
group = self.get_security_group_from_name(name_or_group_id)
|
||||||
|
if group:
|
||||||
|
return self.groups.pop(group.id)
|
||||||
|
|
||||||
|
def get_security_group_from_name(self, name):
|
||||||
|
for group_id, group in self.groups.iteritems():
|
||||||
|
if group.name == name:
|
||||||
|
return group
|
||||||
|
|
||||||
|
class EC2Backend(BaseBackend, InstanceBackend, TagBackend, AmiBackend, RegionsAndZonesBackend, SecurityGroupBackend):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ from .tags import TagResponse
|
|||||||
|
|
||||||
class EC2Response(object):
|
class EC2Response(object):
|
||||||
|
|
||||||
sub_responses = [InstanceResponse, TagResponse, AmisResponse, AvailabilityZonesAndRegions]
|
sub_responses = [InstanceResponse, TagResponse, AmisResponse, AvailabilityZonesAndRegions, SecurityGroups]
|
||||||
|
|
||||||
def dispatch(self, uri, body, headers):
|
def dispatch(self, uri, body, headers):
|
||||||
if body:
|
if body:
|
||||||
|
@ -5,6 +5,9 @@ from moto.ec2.utils import resource_ids_from_querystring
|
|||||||
|
|
||||||
|
|
||||||
class SecurityGroups(object):
|
class SecurityGroups(object):
|
||||||
|
def __init__(self, querystring):
|
||||||
|
self.querystring = querystring
|
||||||
|
|
||||||
def authorize_security_group_egress(self):
|
def authorize_security_group_egress(self):
|
||||||
raise NotImplementedError('SecurityGroups.authorize_security_group_egress is not yet implemented')
|
raise NotImplementedError('SecurityGroups.authorize_security_group_egress is not yet implemented')
|
||||||
|
|
||||||
@ -12,13 +15,28 @@ class SecurityGroups(object):
|
|||||||
raise NotImplementedError('SecurityGroups.authorize_security_group_ingress is not yet implemented')
|
raise NotImplementedError('SecurityGroups.authorize_security_group_ingress is not yet implemented')
|
||||||
|
|
||||||
def create_security_group(self):
|
def create_security_group(self):
|
||||||
raise NotImplementedError('SecurityGroups.create_security_group is not yet implemented')
|
name = self.querystring.get('GroupName')[0]
|
||||||
|
description = self.querystring.get('GroupDescription')[0]
|
||||||
|
group = ec2_backend.create_security_group(name, description)
|
||||||
|
if not group:
|
||||||
|
# There was an exisitng group
|
||||||
|
return "There was an existing security group with name {}".format(name), dict(status=409)
|
||||||
|
template = Template(CREATE_SECURITY_GROUP_RESPONSE)
|
||||||
|
return template.render(group=group)
|
||||||
|
|
||||||
def delete_security_group(self):
|
def delete_security_group(self):
|
||||||
raise NotImplementedError('SecurityGroups.delete_security_group is not yet implemented')
|
name = self.querystring.get('GroupName')[0]
|
||||||
|
group = ec2_backend.delete_security_group(name)
|
||||||
|
|
||||||
|
if not group:
|
||||||
|
# There was no such group
|
||||||
|
return "There was no security group with name {}".format(name), dict(status=404)
|
||||||
|
return DELETE_GROUP_RESPONSE
|
||||||
|
|
||||||
def describe_security_groups(self):
|
def describe_security_groups(self):
|
||||||
raise NotImplementedError('SecurityGroups.describe_security_groups is not yet implemented')
|
groups = ec2_backend.describe_security_groups()
|
||||||
|
template = Template(DESCRIBE_SECURITY_GROUPS_RESPONSE)
|
||||||
|
return template.render(groups=groups)
|
||||||
|
|
||||||
def revoke_security_group_egress(self):
|
def revoke_security_group_egress(self):
|
||||||
raise NotImplementedError('SecurityGroups.revoke_security_group_egress is not yet implemented')
|
raise NotImplementedError('SecurityGroups.revoke_security_group_egress is not yet implemented')
|
||||||
@ -26,3 +44,43 @@ class SecurityGroups(object):
|
|||||||
def revoke_security_group_ingress(self):
|
def revoke_security_group_ingress(self):
|
||||||
raise NotImplementedError('SecurityGroups.revoke_security_group_ingress is not yet implemented')
|
raise NotImplementedError('SecurityGroups.revoke_security_group_ingress is not yet implemented')
|
||||||
|
|
||||||
|
|
||||||
|
CREATE_SECURITY_GROUP_RESPONSE = """<CreateSecurityGroupResponse xmlns="http://ec2.amazonaws.com/doc/2012-12-01/">
|
||||||
|
<requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId>
|
||||||
|
<return>true</return>
|
||||||
|
<groupId>{{ group.id }}</groupId>
|
||||||
|
</CreateSecurityGroupResponse>"""
|
||||||
|
|
||||||
|
DELETE_GROUP_RESPONSE = """<DeleteSecurityGroupResponse xmlns="http://ec2.amazonaws.com/doc/2012-12-01/">
|
||||||
|
<requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId>
|
||||||
|
<return>true</return>
|
||||||
|
</DeleteSecurityGroupResponse>"""
|
||||||
|
|
||||||
|
DESCRIBE_SECURITY_GROUPS_RESPONSE = """<DescribeSecurityGroupsResponse xmlns="http://ec2.amazonaws.com/doc/2012-12-01/">
|
||||||
|
<requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId>
|
||||||
|
<securityGroupInfo>
|
||||||
|
{% for group in groups %}
|
||||||
|
<item>
|
||||||
|
<ownerId>111122223333</ownerId>
|
||||||
|
<groupId>{{ group.id }}</groupId>
|
||||||
|
<groupName>{{ group.name }}</groupName>
|
||||||
|
<groupDescription>{{ group.description }}</groupDescription>
|
||||||
|
<vpcId/>
|
||||||
|
<ipPermissions>
|
||||||
|
<item>
|
||||||
|
<ipProtocol>tcp</ipProtocol>
|
||||||
|
<fromPort>80</fromPort>
|
||||||
|
<toPort>80</toPort>
|
||||||
|
<groups/>
|
||||||
|
<ipRanges>
|
||||||
|
<item>
|
||||||
|
<cidrIp>0.0.0.0/0</cidrIp>
|
||||||
|
</item>
|
||||||
|
</ipRanges>
|
||||||
|
</item>
|
||||||
|
</ipPermissions>
|
||||||
|
<ipPermissionsEgress/>
|
||||||
|
</item>
|
||||||
|
{% endfor %}
|
||||||
|
</securityGroupInfo>
|
||||||
|
</DescribeSecurityGroupsResponse>"""
|
@ -22,6 +22,10 @@ def random_ami_id():
|
|||||||
return random_id(prefix='ami')
|
return random_id(prefix='ami')
|
||||||
|
|
||||||
|
|
||||||
|
def random_security_group_id():
|
||||||
|
return random_id(prefix='sg')
|
||||||
|
|
||||||
|
|
||||||
def instance_ids_from_querystring(querystring_dict):
|
def instance_ids_from_querystring(querystring_dict):
|
||||||
instance_ids = []
|
instance_ids = []
|
||||||
for key, value in querystring_dict.iteritems():
|
for key, value in querystring_dict.iteritems():
|
||||||
|
@ -1,9 +1,41 @@
|
|||||||
import boto
|
import boto
|
||||||
|
from boto.exception import EC2ResponseError
|
||||||
from sure import expect
|
from sure import expect
|
||||||
|
|
||||||
from moto import mock_ec2
|
from moto import mock_ec2
|
||||||
|
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_security_groups():
|
def test_create_and_describe_security_group():
|
||||||
pass
|
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||||
|
security_group = conn.create_security_group('test security group', 'this is a test security group')
|
||||||
|
|
||||||
|
security_group.name.should.equal('test security group')
|
||||||
|
security_group.description.should.equal('this is a test security group')
|
||||||
|
|
||||||
|
# Trying to create another group with the same name should throw an error
|
||||||
|
conn.create_security_group.when.called_with('test security group', 'this is a test security group').should.throw(EC2ResponseError)
|
||||||
|
|
||||||
|
all_groups = conn.get_all_security_groups()
|
||||||
|
all_groups.should.have.length_of(1)
|
||||||
|
all_groups[0].name.should.equal('test security group')
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ec2
|
||||||
|
def test_deleting_security_groups():
|
||||||
|
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||||
|
security_group1 = conn.create_security_group('test1', 'test1')
|
||||||
|
security_group2 = conn.create_security_group('test2', 'test2')
|
||||||
|
|
||||||
|
conn.get_all_security_groups().should.have.length_of(2)
|
||||||
|
|
||||||
|
# Deleting a group that doesn't exist should throw an error
|
||||||
|
conn.delete_security_group.when.called_with('foobar').should.throw(EC2ResponseError)
|
||||||
|
|
||||||
|
# Delete by name
|
||||||
|
conn.delete_security_group('test2')
|
||||||
|
conn.get_all_security_groups().should.have.length_of(1)
|
||||||
|
|
||||||
|
# Delete by group id
|
||||||
|
conn.delete_security_group(security_group1.id)
|
||||||
|
conn.get_all_security_groups().should.have.length_of(0)
|
||||||
|
Loading…
Reference in New Issue
Block a user