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
|
||||
|
||||
|
||||
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):
|
||||
super(Instance, self).__init__()
|
||||
self.id = random_instance_id()
|
||||
@ -86,10 +92,6 @@ class Instance(BotoInstance):
|
||||
self._state.name = "running"
|
||||
self._state.code = 16
|
||||
|
||||
def get_tags(self, *args, **kwargs):
|
||||
tags = ec2_backend.describe_tags(self.id)
|
||||
return tags
|
||||
|
||||
|
||||
class InstanceBackend(object):
|
||||
|
||||
@ -267,7 +269,7 @@ class TagBackend(object):
|
||||
return results
|
||||
|
||||
|
||||
class Ami(object):
|
||||
class Ami(TaggedEC2Instance):
|
||||
def __init__(self, ami_id, instance, name, description):
|
||||
self.id = ami_id
|
||||
self.instance = instance
|
||||
@ -657,7 +659,7 @@ class EBSBackend(object):
|
||||
return False
|
||||
|
||||
|
||||
class VPC(object):
|
||||
class VPC(TaggedEC2Instance):
|
||||
def __init__(self, vpc_id, cidr_block):
|
||||
self.id = vpc_id
|
||||
self.cidr_block = cidr_block
|
||||
@ -703,7 +705,7 @@ class VPCBackend(object):
|
||||
return vpc
|
||||
|
||||
|
||||
class Subnet(object):
|
||||
class Subnet(TaggedEC2Instance):
|
||||
def __init__(self, subnet_id, vpc_id, cidr_block):
|
||||
self.id = subnet_id
|
||||
self.vpc_id = vpc_id
|
||||
@ -1061,7 +1063,7 @@ class ElasticAddressBackend(object):
|
||||
return False
|
||||
|
||||
|
||||
class DHCPOptionsSet(object):
|
||||
class DHCPOptionsSet(TaggedEC2Instance):
|
||||
def __init__(self, domain_name_servers=None, domain_name=None,
|
||||
ntp_servers=None, netbios_name_servers=None,
|
||||
netbios_node_type=None):
|
||||
@ -1071,7 +1073,7 @@ class DHCPOptionsSet(object):
|
||||
"ntp-servers": ntp_servers,
|
||||
"netbios-name-servers": netbios_name_servers,
|
||||
"netbios-node-type": netbios_node_type,
|
||||
}
|
||||
}
|
||||
self.id = random_dhcp_option_id()
|
||||
self.vpc = None
|
||||
|
||||
@ -1113,7 +1115,7 @@ class DHCPOptionsSetBackend(object):
|
||||
if options_id in self.dhcp_options_sets:
|
||||
if self.dhcp_options_sets[options_id].vpc:
|
||||
raise DependencyViolationError("Cannot delete assigned DHCP options.")
|
||||
dhcp_opt = self.dhcp_options_sets.pop(options_id)
|
||||
self.dhcp_options_sets.pop(options_id)
|
||||
else:
|
||||
raise InvalidDHCPOptionsIdError(options_id)
|
||||
return True
|
||||
|
@ -92,7 +92,16 @@ DESCRIBE_IMAGES_RESPONSE = """<DescribeImagesResponse xmlns="http://ec2.amazonaw
|
||||
</item>
|
||||
</blockDeviceMapping>
|
||||
<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>
|
||||
</item>
|
||||
{% endfor %}
|
||||
|
@ -6,8 +6,8 @@ from moto.ec2.utils import (
|
||||
from moto.ec2.models import ec2_backend
|
||||
from moto.ec2.exceptions import(
|
||||
InvalidVPCIdError,
|
||||
InvalidParameterValueError
|
||||
)
|
||||
InvalidParameterValueError,
|
||||
)
|
||||
|
||||
NETBIOS_NODE_TYPES = [1, 2, 4, 8]
|
||||
|
||||
@ -52,7 +52,7 @@ class DHCPOptions(BaseResponse):
|
||||
ntp_servers=ntp_servers,
|
||||
netbios_name_servers=netbios_name_servers,
|
||||
netbios_node_type=netbios_node_type
|
||||
)
|
||||
)
|
||||
|
||||
template = Template(CREATE_DHCP_OPTIONS_RESPONSE)
|
||||
return template.render(dhcp_options_set=dhcp_options_set)
|
||||
@ -105,7 +105,16 @@ CREATE_DHCP_OPTIONS_RESPONSE = u"""
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</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>
|
||||
</CreateDhcpOptionsResponse>
|
||||
"""
|
||||
@ -141,7 +150,16 @@ DESCRIBE_DHCP_OPTIONS_RESPONSE = u"""
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</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>
|
||||
{% endfor %}
|
||||
</item>
|
||||
|
@ -37,7 +37,16 @@ CREATE_SUBNET_RESPONSE = """
|
||||
<cidrBlock>{{ subnet.cidr_block }}</cidrBlock>
|
||||
<availableIpAddressCount>251</availableIpAddressCount>
|
||||
<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>
|
||||
</CreateSubnetResponse>"""
|
||||
|
||||
@ -59,7 +68,16 @@ DESCRIBE_SUBNETS_RESPONSE = """
|
||||
<cidrBlock>{{ subnet.cidr_block }}</cidrBlock>
|
||||
<availableIpAddressCount>251</availableIpAddressCount>
|
||||
<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>
|
||||
{% endfor %}
|
||||
</subnetSet>
|
||||
|
@ -35,7 +35,16 @@ CREATE_VPC_RESPONSE = """
|
||||
<cidrBlock>{{ vpc.cidr_block }}</cidrBlock>
|
||||
<dhcpOptionsId>dopt-1a2b3c4d2</dhcpOptionsId>
|
||||
<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>
|
||||
</CreateVpcResponse>"""
|
||||
|
||||
@ -50,7 +59,16 @@ DESCRIBE_VPCS_RESPONSE = """
|
||||
<cidrBlock>{{ vpc.cidr_block }}</cidrBlock>
|
||||
<dhcpOptionsId>dopt-7a8b9c2d</dhcpOptionsId>
|
||||
<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>
|
||||
{% endfor %}
|
||||
</vpcSet>
|
||||
|
@ -22,6 +22,26 @@ def test_ami_create_and_delete():
|
||||
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
|
||||
def test_ami_create_from_missing_instance():
|
||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||
|
@ -114,5 +114,22 @@ def test_delete_dhcp_options():
|
||||
def test_delete_dhcp_options_invalid_id():
|
||||
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)
|
||||
|
||||
|
||||
@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(
|
||||
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(
|
||||
"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…
Reference in New Issue
Block a user