diff --git a/moto/autoscaling/models.py b/moto/autoscaling/models.py index 6d5fe6ace..cb07c4207 100644 --- a/moto/autoscaling/models.py +++ b/moto/autoscaling/models.py @@ -106,7 +106,8 @@ class FakeAutoScalingGroup(object): reservation = ec2_backend.add_instances( self.launch_config.image_id, count_needed, - self.launch_config.user_data + self.launch_config.user_data, + self.launch_config.security_groups, ) for instance in reservation.instances: instance.autoscaling_group = self diff --git a/moto/ec2/models.py b/moto/ec2/models.py index 5b1f5a1d6..ff17aab85 100644 --- a/moto/ec2/models.py +++ b/moto/ec2/models.py @@ -30,12 +30,13 @@ class InstanceState(object): class Instance(BotoInstance): - def __init__(self, image_id, user_data): + def __init__(self, image_id, user_data, security_groups): super(Instance, self).__init__() self.id = random_instance_id() self.image_id = image_id self._state = InstanceState("running", 16) self.user_data = user_data + self.security_groups = security_groups def start(self, *args, **kwargs): self._state.name = "running" @@ -69,13 +70,16 @@ class InstanceBackend(object): if instance.id == instance_id: return instance - def add_instances(self, image_id, count, user_data): + def add_instances(self, image_id, count, user_data, security_group_names): new_reservation = Reservation() new_reservation.id = random_reservation_id() + + security_groups = [self.get_security_group_from_name(name) for name in security_group_names] for index in range(count): new_instance = Instance( image_id, user_data, + security_groups, ) new_reservation.instances.append(new_instance) self.reservations[new_reservation.id] = new_reservation @@ -369,7 +373,7 @@ class SecurityGroupBackend(object): return vpc.pop(group_id) elif name: # Group Name. Has to be in standard EC2, VPC needs to be identified by group_id - group = self.get_security_group_from_name(name, None) + group = self.get_security_group_from_name(name) if group: return self.groups[None].pop(group.id) @@ -381,9 +385,7 @@ class SecurityGroupBackend(object): if group.id == group_id: return group - - - def get_security_group_from_name(self, name, vpc_id): + def get_security_group_from_name(self, name, vpc_id=None): for group_id, group in self.groups[vpc_id].iteritems(): if group.name == name: return group @@ -441,7 +443,6 @@ class SecurityGroupBackend(object): elif group_id: group = self.get_security_group_from_id(group_id) - source_groups = [] for source_group_name in source_group_names: source_group = self.get_security_group_from_name(source_group_name, vpc_id) @@ -627,12 +628,12 @@ class SpotInstanceRequest(object): self.security_groups = [] if security_groups: for group_name in security_groups: - group = ec2_backend.get_security_group_from_name(group_name, None) + group = ec2_backend.get_security_group_from_name(group_name) if group: self.security_groups.append(group) else: # If not security groups, add the default - default_group = ec2_backend.get_security_group_from_name("default", None) + default_group = ec2_backend.get_security_group_from_name("default") self.security_groups.append(default_group) diff --git a/moto/ec2/responses/instances.py b/moto/ec2/responses/instances.py index 62f406b07..13b23fd3f 100644 --- a/moto/ec2/responses/instances.py +++ b/moto/ec2/responses/instances.py @@ -8,6 +8,9 @@ from moto.ec2.exceptions import InvalidIdError class InstanceResponse(BaseResponse): + def _get_multi_param(self, param_prefix): + return [value[0] for key, value in self.querystring.items() if key.startswith(param_prefix)] + def describe_instances(self): instance_ids = instance_ids_from_querystring(self.querystring) if instance_ids: @@ -29,7 +32,8 @@ class InstanceResponse(BaseResponse): min_count = int(self.querystring.get('MinCount', ['1'])[0]) image_id = self.querystring.get('ImageId')[0] user_data = self.querystring.get('UserData') - new_reservation = ec2_backend.add_instances(image_id, min_count, user_data) + security_group_names = self._get_multi_param('SecurityGroup') + new_reservation = ec2_backend.add_instances(image_id, min_count, user_data, security_group_names) template = Template(EC2_RUN_INSTANCES) return template.render(reservation=new_reservation) @@ -119,10 +123,12 @@ EC2_RUN_INSTANCES = """46.51.219.63 true + {% for group in instance.security_groups %} - sg-1a2b3c4d - my-security-group + {{ group.id }} + {{ group.name }} + {% endfor %} x86_64 ebs diff --git a/tests/test_ec2/test_instances.py b/tests/test_ec2/test_instances.py index d2c386555..9b4cb601a 100644 --- a/tests/test_ec2/test_instances.py +++ b/tests/test_ec2/test_instances.py @@ -170,3 +170,15 @@ def test_user_data_with_run_instance(): instance_attribute.should.be.a(InstanceAttribute) decoded_user_data = base64.decodestring(instance_attribute.get("userData")) decoded_user_data.should.equal("some user data") + + +@mock_ec2 +def test_run_instance_with_security_group(): + conn = boto.connect_ec2('the_key', 'the_secret') + group = conn.create_security_group('group1', "some description") + + reservation = conn.run_instances('ami-1234abcd', security_groups=['group1']) + instance = reservation.instances[0] + + instance.groups[0].id.should.equal(group.id) + instance.groups[0].name.should.equal("group1")