Merge pull request #126 from stpierre/support-instance-properties
Support instance properties
This commit is contained in:
commit
6c3fb51d10
@ -6,18 +6,11 @@ from .models import autoscaling_backend
|
|||||||
|
|
||||||
|
|
||||||
class AutoScalingResponse(BaseResponse):
|
class AutoScalingResponse(BaseResponse):
|
||||||
|
|
||||||
def _get_param(self, param_name):
|
|
||||||
return self.querystring.get(param_name, [None])[0]
|
|
||||||
|
|
||||||
def _get_int_param(self, param_name):
|
def _get_int_param(self, param_name):
|
||||||
value = self._get_param(param_name)
|
value = self._get_param(param_name)
|
||||||
if value is not None:
|
if value is not None:
|
||||||
return int(value)
|
return int(value)
|
||||||
|
|
||||||
def _get_multi_param(self, param_prefix):
|
|
||||||
return [value[0] for key, value in self.querystring.items() if key.startswith(param_prefix)]
|
|
||||||
|
|
||||||
def _get_list_prefix(self, param_prefix):
|
def _get_list_prefix(self, param_prefix):
|
||||||
results = []
|
results = []
|
||||||
param_index = 1
|
param_index = 1
|
||||||
@ -43,7 +36,7 @@ class AutoScalingResponse(BaseResponse):
|
|||||||
name=self._get_param('LaunchConfigurationName'),
|
name=self._get_param('LaunchConfigurationName'),
|
||||||
image_id=self._get_param('ImageId'),
|
image_id=self._get_param('ImageId'),
|
||||||
key_name=self._get_param('KeyName'),
|
key_name=self._get_param('KeyName'),
|
||||||
security_groups=self._get_multi_param('SecurityGroups.member.'),
|
security_groups=self._get_multi_param('SecurityGroups.member'),
|
||||||
user_data=self._get_param('UserData'),
|
user_data=self._get_param('UserData'),
|
||||||
instance_type=self._get_param('InstanceType'),
|
instance_type=self._get_param('InstanceType'),
|
||||||
instance_monitoring=instance_monitoring,
|
instance_monitoring=instance_monitoring,
|
||||||
|
@ -66,6 +66,14 @@ class BaseResponse(object):
|
|||||||
def _get_param(self, param_name):
|
def _get_param(self, param_name):
|
||||||
return self.querystring.get(param_name, [None])[0]
|
return self.querystring.get(param_name, [None])[0]
|
||||||
|
|
||||||
|
def _get_multi_param(self, param_prefix):
|
||||||
|
if param_prefix.endswith("."):
|
||||||
|
prefix = param_prefix
|
||||||
|
else:
|
||||||
|
prefix = param_prefix + "."
|
||||||
|
return [value[0] for key, value in self.querystring.items()
|
||||||
|
if key.startswith(prefix)]
|
||||||
|
|
||||||
|
|
||||||
def metadata_response(request, full_url, headers):
|
def metadata_response(request, full_url, headers):
|
||||||
"""
|
"""
|
||||||
|
@ -37,13 +37,16 @@ class InstanceState(object):
|
|||||||
|
|
||||||
|
|
||||||
class Instance(BotoInstance):
|
class Instance(BotoInstance):
|
||||||
def __init__(self, image_id, user_data, security_groups):
|
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()
|
||||||
self.image_id = image_id
|
self.image_id = image_id
|
||||||
self._state = InstanceState("running", 16)
|
self._state = InstanceState("running", 16)
|
||||||
self.user_data = user_data
|
self.user_data = user_data
|
||||||
self.security_groups = security_groups
|
self.security_groups = security_groups
|
||||||
|
self.instance_type = kwargs.get("instance_type", "m1.small")
|
||||||
|
self.subnet_id = kwargs.get("subnet_id")
|
||||||
|
self.key_name = kwargs.get("key_name")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create_from_cloudformation_json(cls, resource_name, cloudformation_json):
|
def create_from_cloudformation_json(cls, resource_name, cloudformation_json):
|
||||||
@ -57,6 +60,9 @@ class Instance(BotoInstance):
|
|||||||
user_data=properties.get('UserData'),
|
user_data=properties.get('UserData'),
|
||||||
count=1,
|
count=1,
|
||||||
security_group_names=group_names,
|
security_group_names=group_names,
|
||||||
|
instance_type=properties.get("InstanceType", "m1.small"),
|
||||||
|
subnet_id=properties.get("SubnetId"),
|
||||||
|
key_name=properties.get("KeyName"),
|
||||||
)
|
)
|
||||||
return reservation.instances[0]
|
return reservation.instances[0]
|
||||||
|
|
||||||
@ -96,16 +102,21 @@ class InstanceBackend(object):
|
|||||||
if instance.id == instance_id:
|
if instance.id == instance_id:
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
def add_instances(self, image_id, count, user_data, security_group_names):
|
def add_instances(self, image_id, count, user_data, security_group_names,
|
||||||
|
**kwargs):
|
||||||
new_reservation = Reservation()
|
new_reservation = Reservation()
|
||||||
new_reservation.id = random_reservation_id()
|
new_reservation.id = random_reservation_id()
|
||||||
|
|
||||||
security_groups = [self.get_security_group_from_name(name) for name in security_group_names]
|
security_groups = [self.get_security_group_from_name(name)
|
||||||
|
for name in security_group_names]
|
||||||
|
security_groups.extend(self.get_security_group_from_id(sg_id)
|
||||||
|
for sg_id in kwargs.pop("security_group_ids", []))
|
||||||
for index in range(count):
|
for index in range(count):
|
||||||
new_instance = Instance(
|
new_instance = Instance(
|
||||||
image_id,
|
image_id,
|
||||||
user_data,
|
user_data,
|
||||||
security_groups,
|
security_groups,
|
||||||
|
**kwargs
|
||||||
)
|
)
|
||||||
new_reservation.instances.append(new_instance)
|
new_reservation.instances.append(new_instance)
|
||||||
self.reservations[new_reservation.id] = new_reservation
|
self.reservations[new_reservation.id] = new_reservation
|
||||||
|
@ -8,9 +8,6 @@ from moto.ec2.exceptions import InvalidIdError
|
|||||||
|
|
||||||
|
|
||||||
class InstanceResponse(BaseResponse):
|
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):
|
def describe_instances(self):
|
||||||
instance_ids = instance_ids_from_querystring(self.querystring)
|
instance_ids = instance_ids_from_querystring(self.querystring)
|
||||||
if instance_ids:
|
if instance_ids:
|
||||||
@ -33,7 +30,14 @@ class InstanceResponse(BaseResponse):
|
|||||||
image_id = self.querystring.get('ImageId')[0]
|
image_id = self.querystring.get('ImageId')[0]
|
||||||
user_data = self.querystring.get('UserData')
|
user_data = self.querystring.get('UserData')
|
||||||
security_group_names = self._get_multi_param('SecurityGroup')
|
security_group_names = self._get_multi_param('SecurityGroup')
|
||||||
new_reservation = ec2_backend.add_instances(image_id, min_count, user_data, security_group_names)
|
security_group_ids = self._get_multi_param('SecurityGroupId')
|
||||||
|
instance_type = self.querystring.get("InstanceType", ["m1.small"])[0]
|
||||||
|
subnet_id = self.querystring.get("SubnetId", [None])[0]
|
||||||
|
key_name = self.querystring.get("KeyName", [None])[0]
|
||||||
|
new_reservation = ec2_backend.add_instances(
|
||||||
|
image_id, min_count, user_data, security_group_names,
|
||||||
|
instance_type=instance_type, subnet_id=subnet_id,
|
||||||
|
key_name=key_name, security_group_ids=security_group_ids)
|
||||||
template = Template(EC2_RUN_INSTANCES)
|
template = Template(EC2_RUN_INSTANCES)
|
||||||
return template.render(reservation=new_reservation)
|
return template.render(reservation=new_reservation)
|
||||||
|
|
||||||
@ -110,8 +114,9 @@ EC2_RUN_INSTANCES = """<RunInstancesResponse xmlns="http://ec2.amazonaws.com/doc
|
|||||||
<privateDnsName/>
|
<privateDnsName/>
|
||||||
<dnsName/>
|
<dnsName/>
|
||||||
<reason/>
|
<reason/>
|
||||||
|
<keyName>{{ instance.key_name }}</keyName>
|
||||||
<amiLaunchIndex>0</amiLaunchIndex>
|
<amiLaunchIndex>0</amiLaunchIndex>
|
||||||
<instanceType>m1.small</instanceType>
|
<instanceType>{{ instance.instance_type }}</instanceType>
|
||||||
<launchTime>2007-08-07T11:51:50.000Z</launchTime>
|
<launchTime>2007-08-07T11:51:50.000Z</launchTime>
|
||||||
<placement>
|
<placement>
|
||||||
<availabilityZone>us-east-1b</availabilityZone>
|
<availabilityZone>us-east-1b</availabilityZone>
|
||||||
@ -121,6 +126,7 @@ EC2_RUN_INSTANCES = """<RunInstancesResponse xmlns="http://ec2.amazonaws.com/doc
|
|||||||
<monitoring>
|
<monitoring>
|
||||||
<state>enabled</state>
|
<state>enabled</state>
|
||||||
</monitoring>
|
</monitoring>
|
||||||
|
<subnetId>{{ instance.subnet_id }}</subnetId>
|
||||||
<sourceDestCheck>true</sourceDestCheck>
|
<sourceDestCheck>true</sourceDestCheck>
|
||||||
<groupSet>
|
<groupSet>
|
||||||
{% for group in instance.security_groups %}
|
{% for group in instance.security_groups %}
|
||||||
@ -159,10 +165,10 @@ EC2_DESCRIBE_INSTANCES = """<DescribeInstancesResponse xmlns='http://ec2.amazona
|
|||||||
<privateDnsName>ip-10.0.0.12.ec2.internal</privateDnsName>
|
<privateDnsName>ip-10.0.0.12.ec2.internal</privateDnsName>
|
||||||
<dnsName>ec2-46.51.219.63.compute-1.amazonaws.com</dnsName>
|
<dnsName>ec2-46.51.219.63.compute-1.amazonaws.com</dnsName>
|
||||||
<reason/>
|
<reason/>
|
||||||
<keyName>gsg-keypair</keyName>
|
<keyName>{{ instance.key_name }}</keyName>
|
||||||
<amiLaunchIndex>0</amiLaunchIndex>
|
<amiLaunchIndex>0</amiLaunchIndex>
|
||||||
<productCodes/>
|
<productCodes/>
|
||||||
<instanceType>c1.medium</instanceType>
|
<instanceType>{{ instance.instance_type }}</instanceType>
|
||||||
<launchTime>YYYY-MM-DDTHH:MM:SS+0000</launchTime>
|
<launchTime>YYYY-MM-DDTHH:MM:SS+0000</launchTime>
|
||||||
<placement>
|
<placement>
|
||||||
<availabilityZone>us-west-2a</availabilityZone>
|
<availabilityZone>us-west-2a</availabilityZone>
|
||||||
@ -173,7 +179,7 @@ EC2_DESCRIBE_INSTANCES = """<DescribeInstancesResponse xmlns='http://ec2.amazona
|
|||||||
<monitoring>
|
<monitoring>
|
||||||
<state>disabled</state>
|
<state>disabled</state>
|
||||||
</monitoring>
|
</monitoring>
|
||||||
<subnetId>subnet-1a2b3c4d</subnetId>
|
<subnetId>{{ instance.subnet_id }}</subnetId>
|
||||||
<vpcId>vpc-1a2b3c4d</vpcId>
|
<vpcId>vpc-1a2b3c4d</vpcId>
|
||||||
<privateIpAddress>10.0.0.12</privateIpAddress>
|
<privateIpAddress>10.0.0.12</privateIpAddress>
|
||||||
<ipAddress>46.51.219.63</ipAddress>
|
<ipAddress>46.51.219.63</ipAddress>
|
||||||
|
@ -13,9 +13,6 @@ class SpotInstances(BaseResponse):
|
|||||||
if value is not None:
|
if value is not None:
|
||||||
return int(value)
|
return int(value)
|
||||||
|
|
||||||
def _get_multi_param(self, param_prefix):
|
|
||||||
return [value[0] for key, value in self.querystring.items() if key.startswith(param_prefix)]
|
|
||||||
|
|
||||||
def cancel_spot_instance_requests(self):
|
def cancel_spot_instance_requests(self):
|
||||||
request_ids = self._get_multi_param('SpotInstanceRequestId')
|
request_ids = self._get_multi_param('SpotInstanceRequestId')
|
||||||
requests = ec2_backend.cancel_spot_instance_requests(request_ids)
|
requests = ec2_backend.cancel_spot_instance_requests(request_ids)
|
||||||
@ -49,7 +46,7 @@ class SpotInstances(BaseResponse):
|
|||||||
launch_group = self._get_param('LaunchGroup')
|
launch_group = self._get_param('LaunchGroup')
|
||||||
availability_zone_group = self._get_param('AvailabilityZoneGroup')
|
availability_zone_group = self._get_param('AvailabilityZoneGroup')
|
||||||
key_name = self._get_param('LaunchSpecification.KeyName')
|
key_name = self._get_param('LaunchSpecification.KeyName')
|
||||||
security_groups = self._get_multi_param('LaunchSpecification.SecurityGroup.')
|
security_groups = self._get_multi_param('LaunchSpecification.SecurityGroup')
|
||||||
user_data = self._get_param('LaunchSpecification.UserData')
|
user_data = self._get_param('LaunchSpecification.UserData')
|
||||||
instance_type = self._get_param('LaunchSpecification.InstanceType')
|
instance_type = self._get_param('LaunchSpecification.InstanceType')
|
||||||
placement = self._get_param('LaunchSpecification.Placement.AvailabilityZone')
|
placement = self._get_param('LaunchSpecification.Placement.AvailabilityZone')
|
||||||
|
@ -173,12 +173,54 @@ def test_user_data_with_run_instance():
|
|||||||
|
|
||||||
|
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_run_instance_with_security_group():
|
def test_run_instance_with_security_group_name():
|
||||||
conn = boto.connect_ec2('the_key', 'the_secret')
|
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||||
group = conn.create_security_group('group1', "some description")
|
group = conn.create_security_group('group1', "some description")
|
||||||
|
|
||||||
reservation = conn.run_instances('ami-1234abcd', security_groups=['group1'])
|
reservation = conn.run_instances('ami-1234abcd',
|
||||||
|
security_groups=['group1'])
|
||||||
instance = reservation.instances[0]
|
instance = reservation.instances[0]
|
||||||
|
|
||||||
instance.groups[0].id.should.equal(group.id)
|
instance.groups[0].id.should.equal(group.id)
|
||||||
instance.groups[0].name.should.equal("group1")
|
instance.groups[0].name.should.equal("group1")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ec2
|
||||||
|
def test_run_instance_with_security_group_id():
|
||||||
|
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||||
|
group = conn.create_security_group('group1', "some description")
|
||||||
|
|
||||||
|
reservation = conn.run_instances('ami-1234abcd',
|
||||||
|
security_group_ids=[group.id])
|
||||||
|
instance = reservation.instances[0]
|
||||||
|
|
||||||
|
instance.groups[0].id.should.equal(group.id)
|
||||||
|
instance.groups[0].name.should.equal("group1")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ec2
|
||||||
|
def test_run_instance_with_instance_type():
|
||||||
|
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||||
|
reservation = conn.run_instances('ami-1234abcd', instance_type="t1.micro")
|
||||||
|
instance = reservation.instances[0]
|
||||||
|
|
||||||
|
instance.instance_type.should.equal("t1.micro")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ec2
|
||||||
|
def test_run_instance_with_subnet():
|
||||||
|
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||||
|
reservation = conn.run_instances('ami-1234abcd',
|
||||||
|
subnet_id="subnet-abcd1234")
|
||||||
|
instance = reservation.instances[0]
|
||||||
|
|
||||||
|
instance.subnet_id.should.equal("subnet-abcd1234")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ec2
|
||||||
|
def test_run_instance_with_keypair():
|
||||||
|
conn = boto.connect_ec2('the_key', 'the_secret')
|
||||||
|
reservation = conn.run_instances('ami-1234abcd', key_name="keypair_name")
|
||||||
|
instance = reservation.instances[0]
|
||||||
|
|
||||||
|
instance.key_name.should.equal("keypair_name")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user