Add tagging to all applicable EC2 objects. Closes #66.
This commit is contained in:
		
							parent
							
								
									06481ebe7e
								
							
						
					
					
						commit
						955b4c6c4a
					
				| @ -36,7 +36,13 @@ class InstanceState(object): | |||||||
|         self.code = code |         self.code = code | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Instance(BotoInstance): | class TaggedEC2Instance(object): | ||||||
|  |     def get_tags(self, *args, **kwargs): | ||||||
|  |         tags = ec2_backend.describe_tags(self.id) | ||||||
|  |         return tags | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Instance(BotoInstance, TaggedEC2Instance): | ||||||
|     def __init__(self, image_id, user_data, security_groups, **kwargs): |     def __init__(self, image_id, user_data, security_groups, **kwargs): | ||||||
|         super(Instance, self).__init__() |         super(Instance, self).__init__() | ||||||
|         self.id = random_instance_id() |         self.id = random_instance_id() | ||||||
| @ -86,10 +92,6 @@ class Instance(BotoInstance): | |||||||
|         self._state.name = "running" |         self._state.name = "running" | ||||||
|         self._state.code = 16 |         self._state.code = 16 | ||||||
| 
 | 
 | ||||||
|     def get_tags(self, *args, **kwargs): |  | ||||||
|         tags = ec2_backend.describe_tags(self.id) |  | ||||||
|         return tags |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| class InstanceBackend(object): | class InstanceBackend(object): | ||||||
| 
 | 
 | ||||||
| @ -267,7 +269,7 @@ class TagBackend(object): | |||||||
|         return results |         return results | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Ami(object): | class Ami(TaggedEC2Instance): | ||||||
|     def __init__(self, ami_id, instance, name, description): |     def __init__(self, ami_id, instance, name, description): | ||||||
|         self.id = ami_id |         self.id = ami_id | ||||||
|         self.instance = instance |         self.instance = instance | ||||||
| @ -657,7 +659,7 @@ class EBSBackend(object): | |||||||
|         return False |         return False | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class VPC(object): | class VPC(TaggedEC2Instance): | ||||||
|     def __init__(self, vpc_id, cidr_block): |     def __init__(self, vpc_id, cidr_block): | ||||||
|         self.id = vpc_id |         self.id = vpc_id | ||||||
|         self.cidr_block = cidr_block |         self.cidr_block = cidr_block | ||||||
| @ -703,7 +705,7 @@ class VPCBackend(object): | |||||||
|         return vpc |         return vpc | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Subnet(object): | class Subnet(TaggedEC2Instance): | ||||||
|     def __init__(self, subnet_id, vpc_id, cidr_block): |     def __init__(self, subnet_id, vpc_id, cidr_block): | ||||||
|         self.id = subnet_id |         self.id = subnet_id | ||||||
|         self.vpc_id = vpc_id |         self.vpc_id = vpc_id | ||||||
| @ -1061,7 +1063,7 @@ class ElasticAddressBackend(object): | |||||||
|             return False |             return False | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class DHCPOptionsSet(object): | class DHCPOptionsSet(TaggedEC2Instance): | ||||||
|     def __init__(self, domain_name_servers=None, domain_name=None, |     def __init__(self, domain_name_servers=None, domain_name=None, | ||||||
|                  ntp_servers=None, netbios_name_servers=None, |                  ntp_servers=None, netbios_name_servers=None, | ||||||
|                  netbios_node_type=None): |                  netbios_node_type=None): | ||||||
| @ -1113,7 +1115,7 @@ class DHCPOptionsSetBackend(object): | |||||||
|         if options_id in self.dhcp_options_sets: |         if options_id in self.dhcp_options_sets: | ||||||
|             if self.dhcp_options_sets[options_id].vpc: |             if self.dhcp_options_sets[options_id].vpc: | ||||||
|                 raise DependencyViolationError("Cannot delete assigned DHCP options.") |                 raise DependencyViolationError("Cannot delete assigned DHCP options.") | ||||||
|             dhcp_opt = self.dhcp_options_sets.pop(options_id) |             self.dhcp_options_sets.pop(options_id) | ||||||
|         else: |         else: | ||||||
|             raise InvalidDHCPOptionsIdError(options_id) |             raise InvalidDHCPOptionsIdError(options_id) | ||||||
|         return True |         return True | ||||||
|  | |||||||
| @ -92,7 +92,16 @@ DESCRIBE_IMAGES_RESPONSE = """<DescribeImagesResponse xmlns="http://ec2.amazonaw | |||||||
|             </item> |             </item> | ||||||
|           </blockDeviceMapping> |           </blockDeviceMapping> | ||||||
|           <virtualizationType>{{ image.virtualization_type }}</virtualizationType> |           <virtualizationType>{{ image.virtualization_type }}</virtualizationType> | ||||||
|           <tagSet/> |           <tagSet> | ||||||
|  |             {% for tag in image.get_tags() %} | ||||||
|  |               <item> | ||||||
|  |                 <resourceId>{{ tag.resource_id }}</resourceId> | ||||||
|  |                 <resourceType>{{ tag.resource_type }}</resourceType> | ||||||
|  |                 <key>{{ tag.key }}</key> | ||||||
|  |                 <value>{{ tag.value }}</value> | ||||||
|  |               </item> | ||||||
|  |             {% endfor %} | ||||||
|  |           </tagSet> | ||||||
|           <hypervisor>xen</hypervisor> |           <hypervisor>xen</hypervisor> | ||||||
|         </item> |         </item> | ||||||
|     {% endfor %} |     {% endfor %} | ||||||
|  | |||||||
| @ -6,8 +6,8 @@ from moto.ec2.utils import ( | |||||||
| from moto.ec2.models import ec2_backend | from moto.ec2.models import ec2_backend | ||||||
| from moto.ec2.exceptions import( | from moto.ec2.exceptions import( | ||||||
|     InvalidVPCIdError, |     InvalidVPCIdError, | ||||||
|     InvalidParameterValueError |     InvalidParameterValueError, | ||||||
|     ) | ) | ||||||
| 
 | 
 | ||||||
| NETBIOS_NODE_TYPES = [1, 2, 4, 8] | NETBIOS_NODE_TYPES = [1, 2, 4, 8] | ||||||
| 
 | 
 | ||||||
| @ -105,7 +105,16 @@ CREATE_DHCP_OPTIONS_RESPONSE = u""" | |||||||
|         {% endif %} |         {% endif %} | ||||||
|       {% endfor %} |       {% endfor %} | ||||||
|       </dhcpConfigurationSet> |       </dhcpConfigurationSet> | ||||||
|       <tagSet/> |       <tagSet> | ||||||
|  |         {% for tag in dhcp_options_set.get_tags() %} | ||||||
|  |           <item> | ||||||
|  |             <resourceId>{{ tag.resource_id }}</resourceId> | ||||||
|  |             <resourceType>{{ tag.resource_type }}</resourceType> | ||||||
|  |             <key>{{ tag.key }}</key> | ||||||
|  |             <value>{{ tag.value }}</value> | ||||||
|  |           </item> | ||||||
|  |         {% endfor %} | ||||||
|  |       </tagSet> | ||||||
|   </dhcpOptions> |   </dhcpOptions> | ||||||
| </CreateDhcpOptionsResponse> | </CreateDhcpOptionsResponse> | ||||||
| """ | """ | ||||||
| @ -141,7 +150,16 @@ DESCRIBE_DHCP_OPTIONS_RESPONSE = u""" | |||||||
|         {% endif %} |         {% endif %} | ||||||
|       {% endfor %} |       {% endfor %} | ||||||
|       </dhcpConfigurationSet> |       </dhcpConfigurationSet> | ||||||
|       <tagSet/> |       <tagSet> | ||||||
|  |         {% for tag in dhcp_options_set.get_tags() %} | ||||||
|  |           <item> | ||||||
|  |             <resourceId>{{ tag.resource_id }}</resourceId> | ||||||
|  |             <resourceType>{{ tag.resource_type }}</resourceType> | ||||||
|  |             <key>{{ tag.key }}</key> | ||||||
|  |             <value>{{ tag.value }}</value> | ||||||
|  |           </item> | ||||||
|  |         {% endfor %} | ||||||
|  |       </tagSet> | ||||||
|     </dhcpOptions> |     </dhcpOptions> | ||||||
|     {% endfor %} |     {% endfor %} | ||||||
|   </item> |   </item> | ||||||
|  | |||||||
| @ -37,7 +37,16 @@ CREATE_SUBNET_RESPONSE = """ | |||||||
|     <cidrBlock>{{ subnet.cidr_block }}</cidrBlock> |     <cidrBlock>{{ subnet.cidr_block }}</cidrBlock> | ||||||
|     <availableIpAddressCount>251</availableIpAddressCount> |     <availableIpAddressCount>251</availableIpAddressCount> | ||||||
|     <availabilityZone>us-east-1a</availabilityZone> |     <availabilityZone>us-east-1a</availabilityZone> | ||||||
|     <tagSet/> |     <tagSet> | ||||||
|  |       {% for tag in subnet.get_tags() %} | ||||||
|  |         <item> | ||||||
|  |           <resourceId>{{ tag.resource_id }}</resourceId> | ||||||
|  |           <resourceType>{{ tag.resource_type }}</resourceType> | ||||||
|  |           <key>{{ tag.key }}</key> | ||||||
|  |           <value>{{ tag.value }}</value> | ||||||
|  |         </item> | ||||||
|  |       {% endfor %} | ||||||
|  |     </tagSet> | ||||||
|   </subnet> |   </subnet> | ||||||
| </CreateSubnetResponse>""" | </CreateSubnetResponse>""" | ||||||
| 
 | 
 | ||||||
| @ -59,7 +68,16 @@ DESCRIBE_SUBNETS_RESPONSE = """ | |||||||
|         <cidrBlock>{{ subnet.cidr_block }}</cidrBlock> |         <cidrBlock>{{ subnet.cidr_block }}</cidrBlock> | ||||||
|         <availableIpAddressCount>251</availableIpAddressCount> |         <availableIpAddressCount>251</availableIpAddressCount> | ||||||
|         <availabilityZone>us-east-1a</availabilityZone> |         <availabilityZone>us-east-1a</availabilityZone> | ||||||
|         <tagSet/> |         <tagSet> | ||||||
|  |           {% for tag in subnet.get_tags() %} | ||||||
|  |             <item> | ||||||
|  |               <resourceId>{{ tag.resource_id }}</resourceId> | ||||||
|  |               <resourceType>{{ tag.resource_type }}</resourceType> | ||||||
|  |               <key>{{ tag.key }}</key> | ||||||
|  |               <value>{{ tag.value }}</value> | ||||||
|  |             </item> | ||||||
|  |           {% endfor %} | ||||||
|  |         </tagSet> | ||||||
|       </item> |       </item> | ||||||
|     {% endfor %} |     {% endfor %} | ||||||
|   </subnetSet> |   </subnetSet> | ||||||
|  | |||||||
| @ -35,7 +35,16 @@ CREATE_VPC_RESPONSE = """ | |||||||
|       <cidrBlock>{{ vpc.cidr_block }}</cidrBlock> |       <cidrBlock>{{ vpc.cidr_block }}</cidrBlock> | ||||||
|       <dhcpOptionsId>dopt-1a2b3c4d2</dhcpOptionsId> |       <dhcpOptionsId>dopt-1a2b3c4d2</dhcpOptionsId> | ||||||
|       <instanceTenancy>default</instanceTenancy> |       <instanceTenancy>default</instanceTenancy> | ||||||
|       <tagSet/> |       <tagSet> | ||||||
|  |         {% for tag in vpc.get_tags() %} | ||||||
|  |           <item> | ||||||
|  |             <resourceId>{{ tag.resource_id }}</resourceId> | ||||||
|  |             <resourceType>{{ tag.resource_type }}</resourceType> | ||||||
|  |             <key>{{ tag.key }}</key> | ||||||
|  |             <value>{{ tag.value }}</value> | ||||||
|  |           </item> | ||||||
|  |         {% endfor %} | ||||||
|  |       </tagSet> | ||||||
|    </vpc> |    </vpc> | ||||||
| </CreateVpcResponse>""" | </CreateVpcResponse>""" | ||||||
| 
 | 
 | ||||||
| @ -50,7 +59,16 @@ DESCRIBE_VPCS_RESPONSE = """ | |||||||
|         <cidrBlock>{{ vpc.cidr_block }}</cidrBlock> |         <cidrBlock>{{ vpc.cidr_block }}</cidrBlock> | ||||||
|         <dhcpOptionsId>dopt-7a8b9c2d</dhcpOptionsId> |         <dhcpOptionsId>dopt-7a8b9c2d</dhcpOptionsId> | ||||||
|         <instanceTenancy>default</instanceTenancy> |         <instanceTenancy>default</instanceTenancy> | ||||||
|         <tagSet/> |         <tagSet> | ||||||
|  |           {% for tag in vpc.get_tags() %} | ||||||
|  |             <item> | ||||||
|  |               <resourceId>{{ tag.resource_id }}</resourceId> | ||||||
|  |               <resourceType>{{ tag.resource_type }}</resourceType> | ||||||
|  |               <key>{{ tag.key }}</key> | ||||||
|  |               <value>{{ tag.value }}</value> | ||||||
|  |             </item> | ||||||
|  |           {% endfor %} | ||||||
|  |         </tagSet> | ||||||
|       </item> |       </item> | ||||||
|     {% endfor %} |     {% endfor %} | ||||||
|   </vpcSet> |   </vpcSet> | ||||||
|  | |||||||
| @ -22,6 +22,26 @@ def test_ami_create_and_delete(): | |||||||
|     success = conn.deregister_image.when.called_with(image).should.throw(EC2ResponseError) |     success = conn.deregister_image.when.called_with(image).should.throw(EC2ResponseError) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @mock_ec2 | ||||||
|  | def test_ami_tagging(): | ||||||
|  |     conn = boto.connect_vpc('the_key', 'the_secret') | ||||||
|  |     reservation = conn.run_instances('ami-1234abcd') | ||||||
|  |     instance = reservation.instances[0] | ||||||
|  |     conn.create_image(instance.id, "test-ami", "this is a test ami") | ||||||
|  |     image = conn.get_all_images()[0] | ||||||
|  | 
 | ||||||
|  |     image.add_tag("a key", "some value") | ||||||
|  | 
 | ||||||
|  |     tag = conn.get_all_tags()[0] | ||||||
|  |     tag.name.should.equal("a key") | ||||||
|  |     tag.value.should.equal("some value") | ||||||
|  | 
 | ||||||
|  |     # Refresh the DHCP options | ||||||
|  |     image = conn.get_all_images()[0] | ||||||
|  |     image.tags.should.have.length_of(1) | ||||||
|  |     image.tags["a key"].should.equal("some value") | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| @mock_ec2 | @mock_ec2 | ||||||
| def test_ami_create_from_missing_instance(): | def test_ami_create_from_missing_instance(): | ||||||
|     conn = boto.connect_ec2('the_key', 'the_secret') |     conn = boto.connect_ec2('the_key', 'the_secret') | ||||||
|  | |||||||
| @ -114,5 +114,22 @@ def test_delete_dhcp_options(): | |||||||
| def test_delete_dhcp_options_invalid_id(): | def test_delete_dhcp_options_invalid_id(): | ||||||
|     conn = boto.connect_vpc('the_key', 'the_secret') |     conn = boto.connect_vpc('the_key', 'the_secret') | ||||||
| 
 | 
 | ||||||
|     dhcp_option = conn.create_dhcp_options() |     conn.create_dhcp_options() | ||||||
|     conn.delete_dhcp_options.when.called_with("1").should.throw(EC2ResponseError) |     conn.delete_dhcp_options.when.called_with("1").should.throw(EC2ResponseError) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @mock_ec2 | ||||||
|  | def test_dhcp_tagging(): | ||||||
|  |     conn = boto.connect_vpc('the_key', 'the_secret') | ||||||
|  |     dhcp_option = conn.create_dhcp_options() | ||||||
|  | 
 | ||||||
|  |     dhcp_option.add_tag("a key", "some value") | ||||||
|  | 
 | ||||||
|  |     tag = conn.get_all_tags()[0] | ||||||
|  |     tag.name.should.equal("a key") | ||||||
|  |     tag.value.should.equal("some value") | ||||||
|  | 
 | ||||||
|  |     # Refresh the DHCP options | ||||||
|  |     dhcp_option = conn.get_all_dhcp_options()[0] | ||||||
|  |     dhcp_option.tags.should.have.length_of(1) | ||||||
|  |     dhcp_option.tags["a key"].should.equal("some value") | ||||||
|  | |||||||
| @ -21,3 +21,21 @@ def test_subnets(): | |||||||
| 
 | 
 | ||||||
|     conn.delete_subnet.when.called_with( |     conn.delete_subnet.when.called_with( | ||||||
|         subnet.id).should.throw(EC2ResponseError) |         subnet.id).should.throw(EC2ResponseError) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @mock_ec2 | ||||||
|  | def test_subnet_tagging(): | ||||||
|  |     conn = boto.connect_vpc('the_key', 'the_secret') | ||||||
|  |     vpc = conn.create_vpc("10.0.0.0/16") | ||||||
|  |     subnet = conn.create_subnet(vpc.id, "10.0.0.0/18") | ||||||
|  | 
 | ||||||
|  |     subnet.add_tag("a key", "some value") | ||||||
|  | 
 | ||||||
|  |     tag = conn.get_all_tags()[0] | ||||||
|  |     tag.name.should.equal("a key") | ||||||
|  |     tag.value.should.equal("some value") | ||||||
|  | 
 | ||||||
|  |     # Refresh the subnet | ||||||
|  |     subnet = conn.get_all_subnets()[0] | ||||||
|  |     subnet.tags.should.have.length_of(1) | ||||||
|  |     subnet.tags["a key"].should.equal("some value") | ||||||
|  | |||||||
| @ -21,3 +21,20 @@ def test_vpcs(): | |||||||
| 
 | 
 | ||||||
|     conn.delete_vpc.when.called_with( |     conn.delete_vpc.when.called_with( | ||||||
|         "vpc-1234abcd").should.throw(EC2ResponseError) |         "vpc-1234abcd").should.throw(EC2ResponseError) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @mock_ec2 | ||||||
|  | def test_vpc_tagging(): | ||||||
|  |     conn = boto.connect_vpc() | ||||||
|  |     vpc = conn.create_vpc("10.0.0.0/16") | ||||||
|  | 
 | ||||||
|  |     vpc.add_tag("a key", "some value") | ||||||
|  | 
 | ||||||
|  |     tag = conn.get_all_tags()[0] | ||||||
|  |     tag.name.should.equal("a key") | ||||||
|  |     tag.value.should.equal("some value") | ||||||
|  | 
 | ||||||
|  |     # Refresh the vpc | ||||||
|  |     vpc = conn.get_all_vpcs()[0] | ||||||
|  |     vpc.tags.should.have.length_of(1) | ||||||
|  |     vpc.tags["a key"].should.equal("some value") | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user