Fix GetConsoleOutput and GetPasswordData

1 Add optional receiving instance_id as a list of id with single id
2 Encode console output and password data

There is one more Depends-On which we can't wait for so it's purely 
informational: Depends-On: I36ef88a561e60fb5dc3e687cb8bc02b27ec2e814

Depends-On: I711314408ec7c4ea75f93348a7335843713e9a2b

Change-Id: I0d62238bbf3a549344d578e131e8be9b3f268cf1
This commit is contained in:
Feodor Tersin 2015-04-09 16:53:22 +03:00 committed by Alexandre Levine
parent a0b412ca70
commit d8409de68a
3 changed files with 27 additions and 8 deletions

View File

@ -693,7 +693,7 @@ class CloudController(object):
Information about one or more account attributes.
"""
@module_and_param_types(instance, 'i_id')
@module_and_param_types(instance, 'i_id_or_ids')
def get_password_data(self, context, instance_id):
"""Retrieves the encrypted administrator password for Windows instance.
@ -708,7 +708,7 @@ class CloudController(object):
you launched the instance.
"""
@module_and_param_types(instance, 'i_id')
@module_and_param_types(instance, 'i_id_or_ids')
def get_console_output(self, context, instance_id):
"""Gets the console output for the specified instance.

View File

@ -53,7 +53,21 @@ CONF.register_opts(ec2_opts)
"""
Validator = common.Validator
class Validator(common.Validator):
def i_id_or_ids(self, value):
# NOTE(ft): boto specifies an instance id to GetConsoleOutput as
# a list with the id. This is an AWS undocumented feature for all (?)
# parameters, but ec2api will support it in certain operations only.
if type(value) is list:
if len(value) != 1:
msg = (
_("The parameter 'InstanceId' may only be specified once.")
if len(value) else
_('No instanceId specified'))
raise exception.InvalidParameterCombination(msg)
value = value[0]
self.i_id(value)
def get_instance_engine():
@ -200,8 +214,8 @@ class InstanceDescriber(common.TaggableItemsDescriber):
KIND = 'i'
FILTER_MAP = {
'availability-zone': ('placement', 'availabilityZone'),
'block-device-mapping.delete-on-termination': ['blockDeviceMapping',
('ebs', 'deleteOnTermination')],
'block-device-mapping.delete-on-termination': [
'blockDeviceMapping', ('ebs', 'deleteOnTermination')],
'block-device-mapping.device-name': ['blockDeviceMapping',
'deviceName'],
'block-device-mapping.status': ['blockDeviceMapping',
@ -430,6 +444,8 @@ def start_instances(context, instance_id):
def get_password_data(context, instance_id):
if type(instance_id) is list:
instance_id = instance_id[0]
instance = ec2utils.get_db_item(context, instance_id)
nova = clients.nova(context)
os_instance = nova.servers.get(instance['os_id'])
@ -439,10 +455,12 @@ def get_password_data(context, instance_id):
now = timeutils.utcnow()
return {"instanceId": instance_id,
"timestamp": now,
"passwordData": password}
"passwordData": base64.b64encode(password)}
def get_console_output(context, instance_id):
if type(instance_id) is list:
instance_id = instance_id[0]
instance = ec2utils.get_db_item(context, instance_id)
nova = clients.nova(context)
os_instance = nova.servers.get(instance['os_id'])
@ -450,7 +468,7 @@ def get_console_output(context, instance_id):
now = timeutils.utcnow()
return {"instanceId": instance_id,
"timestamp": now,
"output": console_output}
"output": base64.b64encode(console_output)}
def describe_instance_attribute(context, instance_id, attribute):

View File

@ -673,9 +673,10 @@ class InstanceTestCase(base.ApiTestCase):
utcnow.return_value = datetime.datetime(2015, 1, 19, 23, 34, 45, 123)
resp = self.execute(operation,
{'InstanceId': fakes.ID_EC2_INSTANCE_2})
expected_data = base64.b64encode(getter.return_value)
self.assertEqual({'instanceId': fakes.ID_EC2_INSTANCE_2,
'timestamp': '2015-01-19T23:34:45.000Z',
key: 'fake_data'},
key: expected_data},
resp)
self.db_api.get_item_by_id.assert_called_once_with(
mock.ANY, fakes.ID_EC2_INSTANCE_2)