diff --git a/moto/ec2/models.py b/moto/ec2/models.py index 1fa37dc18..f5b68da28 100644 --- a/moto/ec2/models.py +++ b/moto/ec2/models.py @@ -543,7 +543,14 @@ class InstanceBackend(object): setattr(instance, key, value) return instance + def modify_instance_security_groups(self, instance_id, new_group_list): + instance = self.get_instance(instance_id) + setattr(instance, 'security_groups', new_group_list) + return instance + def describe_instance_attribute(self, instance_id, key): + if key == 'group_set': + key = 'security_groups' instance = self.get_instance(instance_id) value = getattr(instance, key) return instance, value @@ -2484,7 +2491,7 @@ class EC2Backend(BaseBackend, InstanceBackend, TagBackend, AmiBackend, elif resource_prefix == EC2_RESOURCE_TO_PREFIX['reserved-instance']: self.raise_not_implemented_error('DescribeReservedInstances') elif resource_prefix == EC2_RESOURCE_TO_PREFIX['route-table']: - self.raise_not_implemented_error('DescribeRouteTables') + self.get_route_table(route_table_id=resource_id) elif resource_prefix == EC2_RESOURCE_TO_PREFIX['security-group']: self.describe_security_groups(group_ids=[resource_id]) elif resource_prefix == EC2_RESOURCE_TO_PREFIX['snapshot']: diff --git a/moto/ec2/responses/instances.py b/moto/ec2/responses/instances.py index 8605969b8..f2fb290d2 100644 --- a/moto/ec2/responses/instances.py +++ b/moto/ec2/responses/instances.py @@ -88,12 +88,18 @@ class InstanceResponse(BaseResponse): instance_ids = instance_ids_from_querystring(self.querystring) instance_id = instance_ids[0] instance, value = self.ec2_backend.describe_instance_attribute(instance_id, key) - template = Template(EC2_DESCRIBE_INSTANCE_ATTRIBUTE) + + if key == "group_set": + template = Template(EC2_DESCRIBE_INSTANCE_GROUPSET_ATTRIBUTE) + else: + template = Template(EC2_DESCRIBE_INSTANCE_ATTRIBUTE) + return template.render(instance=instance, attribute=attribute, value=value) def modify_instance_attribute(self): handlers = [self._dot_value_instance_attribute_handler, - self._block_device_mapping_handler] + self._block_device_mapping_handler, + self._security_grp_instance_attribute_handler] for handler in handlers: success = handler() @@ -163,6 +169,17 @@ class InstanceResponse(BaseResponse): self.ec2_backend.modify_instance_attribute(instance_id, normalized_attribute, value) return EC2_MODIFY_INSTANCE_ATTRIBUTE + def _security_grp_instance_attribute_handler(self): + new_security_grp_list = [] + for key, value in self.querystring.items(): + if 'GroupId.' in key: + new_security_grp_list.append(self.querystring.get(key)[0]) + + instance_ids = instance_ids_from_querystring(self.querystring) + instance_id = instance_ids[0] + self.ec2_backend.modify_instance_security_groups(instance_id, new_security_grp_list) + return EC2_MODIFY_INSTANCE_ATTRIBUTE + EC2_RUN_INSTANCES = """ 59dbff89-35bd-4eac-99ed-be587EXAMPLE @@ -500,6 +517,18 @@ EC2_DESCRIBE_INSTANCE_ATTRIBUTE = """ + 59dbff89-35bd-4eac-99ed-be587EXAMPLE + {{ instance.id }} + <{{ attribute }}> + {% for sg_id in value %} + + {{ sg_id }} + + {% endfor %} + +""" + EC2_MODIFY_INSTANCE_ATTRIBUTE = """ 59dbff89-35bd-4eac-99ed-be587EXAMPLE true diff --git a/moto/ec2/responses/route_tables.py b/moto/ec2/responses/route_tables.py index ae9abff45..f583cbbfb 100644 --- a/moto/ec2/responses/route_tables.py +++ b/moto/ec2/responses/route_tables.py @@ -121,7 +121,16 @@ CREATE_ROUTE_TABLE_RESPONSE = """ {% endfor %} - + + {% for tag in route_table.get_tags() %} + + {{ tag.resource_id }} + {{ tag.resource_type }} + {{ tag.key }} + {{ tag.value }} + + {% endfor %} + """ @@ -172,6 +181,16 @@ DESCRIBE_ROUTE_TABLES_RESPONSE = """ {% endfor %} + + {% for tag in route_table.get_tags() %} + + {{ tag.resource_id }} + {{ tag.resource_type }} + {{ tag.key }} + {{ tag.value }} + + {% endfor %} + {% endfor %} diff --git a/tests/test_ec2/test_instances.py b/tests/test_ec2/test_instances.py index ec404b641..a63f939b1 100644 --- a/tests/test_ec2/test_instances.py +++ b/tests/test_ec2/test_instances.py @@ -274,6 +274,22 @@ def test_instance_attribute_instance_type(): instance_attribute.should.be.a(InstanceAttribute) instance_attribute.get('instanceType').should.equal("m1.small") +@mock_ec2 +def test_modify_instance_attribute_security_groups(): + conn = boto.connect_ec2('the_key', 'the_secret') + reservation = conn.run_instances('ami-1234abcd') + instance = reservation.instances[0] + + sg_id = 'sg-1234abcd' + sg_id2 = 'sg-abcd4321' + instance.modify_attribute("groupSet", [sg_id, sg_id2]) + + instance_attribute = instance.get_attribute("groupSet") + instance_attribute.should.be.a(InstanceAttribute) + group_list = instance_attribute.get('groupSet') + any(g.id == sg_id for g in group_list).should.be.ok + any(g.id == sg_id2 for g in group_list).should.be.ok + @mock_ec2 def test_instance_attribute_user_data(): diff --git a/tests/test_ec2/test_route_tables.py b/tests/test_ec2/test_route_tables.py index c6c199128..e31d34125 100644 --- a/tests/test_ec2/test_route_tables.py +++ b/tests/test_ec2/test_route_tables.py @@ -418,3 +418,22 @@ def test_routes_vpc_peering_connection(): new_route.state.should.equal('blackhole') new_route.destination_cidr_block.should.equal(ROUTE_CIDR) + +@mock_ec2 +def test_network_acl_tagging(): + + conn = boto.connect_vpc('the_key', 'the secret') + vpc = conn.create_vpc("10.0.0.0/16") + + route_table = conn.create_route_table(vpc.id) + route_table.add_tag("a key", "some value") + + tag = conn.get_all_tags()[0] + tag.name.should.equal("a key") + tag.value.should.equal("some value") + + all_route_tables = conn.get_all_route_tables() + test_route_table = next(na for na in all_route_tables + if na.id == route_table.id) + test_route_table.tags.should.have.length_of(1) + test_route_table.tags["a key"].should.equal("some value") \ No newline at end of file