Fix broken API os-migrations

The return is not what we are expecting:
  migration-list: 'unicode' object has no attribute 'iteritems'

The conversion of the object nova.objects.MigrationList into a list
is not applied automatically.

Change-Id: I1579b1baf62275bf448f23be9465d4e9bc11ed85
Closes-Bug: #1260249
This commit is contained in:
Sahid Orentino Ferdjaoui 2014-01-16 10:44:33 +01:00
parent fdf248652a
commit 4963fa0fa0
6 changed files with 90 additions and 16 deletions

View File

@ -14,6 +14,7 @@ from nova.api.openstack import extensions
from nova.api.openstack import wsgi
from nova.api.openstack import xmlutil
from nova import compute
from nova.objects import base as obj_base
XMLNS = "http://docs.openstack.org/compute/ext/migrations/api/v2.0"
@ -25,6 +26,19 @@ def authorize(context, action_name):
extensions.extension_authorizer('compute', action)(context)
def output(migrations_obj):
"""Returns the desired output of the API from an object.
From a MigrationsList's object this method returns a list of
primitive objects with the only necessary fields.
"""
objects = obj_base.obj_to_primitive(migrations_obj)
for obj in objects:
del obj['deleted']
del obj['deleted_at']
return objects
class MigrationsTemplate(xmlutil.TemplateBuilder):
def construct(self):
root = xmlutil.TemplateElement('migrations')
@ -57,7 +71,7 @@ class MigrationsController(object):
context = req.environ['nova.context']
authorize(context, "index")
migrations = self.compute_api.get_migrations(context, req.GET)
return {'migrations': migrations}
return {'migrations': output(migrations)}
class Migrations(extensions.ExtensionDescriptor):

View File

@ -12,6 +12,7 @@
from nova.api.openstack import extensions
from nova import compute
from nova.objects import base as obj_base
ALIAS = "os-migrations"
@ -22,6 +23,19 @@ def authorize(context, action_name):
extensions.extension_authorizer('compute', action)(context)
def output(migrations_obj):
"""Returns the desired output of the API from an object.
From a MigrationsList's object this method returns a list of
primitive objects with the only necessary fields.
"""
objects = obj_base.obj_to_primitive(migrations_obj)
for obj in objects:
del obj['deleted']
del obj['deleted_at']
return objects
class MigrationsController(object):
"""Controller for accessing migrations in OpenStack API."""
def __init__(self):
@ -33,7 +47,7 @@ class MigrationsController(object):
context = req.environ['nova.context']
authorize(context, "index")
migrations = self.compute_api.get_migrations(context, req.GET)
return {'migrations': migrations}
return {'migrations': output(migrations)}
class Migrations(extensions.V3APIExtensionBase):

View File

@ -19,6 +19,8 @@ from lxml import etree
from nova.api.openstack.compute.contrib import migrations
from nova import context
from nova import exception
from nova.objects import base
from nova.objects import migration
from nova.openstack.common.fixture import moxstubout
from nova import test
@ -36,6 +38,8 @@ fake_migrations = [
'new_instance_type_id': 2,
'created_at': datetime.datetime(2012, 10, 29, 13, 42, 2),
'updated_at': datetime.datetime(2012, 10, 29, 13, 42, 2),
'deleted_at': None,
'deleted': False
},
{
'id': 5678,
@ -50,9 +54,17 @@ fake_migrations = [
'new_instance_type_id': 6,
'created_at': datetime.datetime(2013, 10, 22, 13, 42, 2),
'updated_at': datetime.datetime(2013, 10, 22, 13, 42, 2),
'deleted_at': None,
'deleted': False
}
]
migrations_obj = base.obj_make_list(
'fake-context',
migration.MigrationList(),
migration.Migration,
fake_migrations)
class FakeRequest(object):
environ = {"nova.context": context.get_admin_context()}
@ -71,16 +83,22 @@ class MigrationsTestCase(test.NoDBTestCase):
self.mox = mox_fixture.mox
def test_index(self):
migrations_in_progress = {'migrations': fake_migrations}
migrations_in_progress = {
'migrations': migrations.output(migrations_obj)}
for mig in migrations_in_progress['migrations']:
self.assertTrue('id' in mig)
self.assertTrue('deleted' not in mig)
self.assertTrue('deleted_at' not in mig)
filters = {'host': 'host1', 'status': 'migrating',
'cell_name': 'ChildCell'}
self.req.GET = filters
self.mox.StubOutWithMock(self.controller.compute_api,
"get_migrations")
self.controller.compute_api.\
get_migrations(self.context, filters).\
AndReturn(fake_migrations)
self.controller.compute_api.get_migrations(
self.context, filters).AndReturn(migrations_obj)
self.mox.ReplayAll()
response = self.controller.index(self.req)
@ -104,7 +122,9 @@ class MigrationsTemplateTest(test.NoDBTestCase):
self.serializer = migrations.MigrationsTemplate()
def test_index_serialization(self):
res_xml = self.serializer.serialize({'migrations': fake_migrations})
migrations_out = migrations.output(migrations_obj)
res_xml = self.serializer.serialize(
{'migrations': migrations_out})
tree = etree.XML(res_xml)
children = tree.findall('migration')
@ -113,7 +133,7 @@ class MigrationsTemplateTest(test.NoDBTestCase):
for idx, child in enumerate(children):
self.assertEqual(child.tag, 'migration')
migration = fake_migrations[idx]
migration = migrations_out[idx]
for attr in migration.keys():
self.assertEqual(str(migration[attr]),
child.get(attr))

View File

@ -17,6 +17,8 @@ import datetime
from nova.api.openstack.compute.plugins.v3 import migrations
from nova import context
from nova import exception
from nova.objects import base
from nova.objects import migration
from nova.openstack.common.fixture import moxstubout
from nova import test
@ -35,6 +37,8 @@ fake_migrations = [
'new_instance_type_id': 2,
'created_at': datetime.datetime(2012, 10, 29, 13, 42, 2),
'updated_at': datetime.datetime(2012, 10, 29, 13, 42, 2),
'deleted_at': None,
'deleted': False
},
{
'id': 5678,
@ -49,9 +53,17 @@ fake_migrations = [
'new_instance_type_id': 6,
'created_at': datetime.datetime(2013, 10, 22, 13, 42, 2),
'updated_at': datetime.datetime(2013, 10, 22, 13, 42, 2),
'deleted_at': None,
'deleted': False
}
]
migrations_obj = base.obj_make_list(
'fake-context',
migration.MigrationList(),
migration.Migration,
fake_migrations)
class FakeRequest(object):
environ = {"nova.context": context.get_admin_context()}
@ -70,16 +82,22 @@ class MigrationsTestCase(test.NoDBTestCase):
self.mox = mox_fixture.mox
def test_index(self):
migrations_in_progress = {'migrations': fake_migrations}
migrations_in_progress = {
'migrations': migrations.output(migrations_obj)}
for mig in migrations_in_progress['migrations']:
self.assertTrue('id' in mig)
self.assertTrue('deleted' not in mig)
self.assertTrue('deleted_at' not in mig)
filters = {'host': 'host1', 'status': 'migrating',
'cell_name': 'ChildCell'}
self.req.GET = filters
self.mox.StubOutWithMock(self.controller.compute_api,
"get_migrations")
self.controller.compute_api.\
get_migrations(self.context, filters).\
AndReturn(fake_migrations)
self.controller.compute_api.get_migrations(
self.context, filters).AndReturn(migrations_obj)
self.mox.ReplayAll()
response = self.controller.index(self.req)

View File

@ -4053,7 +4053,9 @@ class MigrationsSamplesJsonTest(ApiSampleTestBaseV2):
'old_instance_type_id': 1,
'new_instance_type_id': 2,
'created_at': datetime.datetime(2012, 10, 29, 13, 42, 2),
'updated_at': datetime.datetime(2012, 10, 29, 13, 42, 2)
'updated_at': datetime.datetime(2012, 10, 29, 13, 42, 2),
'deleted_at': None,
'deleted': False
},
{
'id': 5678,
@ -4067,7 +4069,9 @@ class MigrationsSamplesJsonTest(ApiSampleTestBaseV2):
'old_instance_type_id': 5,
'new_instance_type_id': 6,
'created_at': datetime.datetime(2013, 10, 22, 13, 42, 2),
'updated_at': datetime.datetime(2013, 10, 22, 13, 42, 2)
'updated_at': datetime.datetime(2013, 10, 22, 13, 42, 2),
'deleted_at': None,
'deleted': False
}
]
return fake_migrations

View File

@ -36,7 +36,9 @@ class MigrationsSamplesJsonTest(api_sample_base.ApiSampleTestBaseV3):
'old_instance_type_id': 1,
'new_instance_type_id': 2,
'created_at': datetime.datetime(2012, 10, 29, 13, 42, 2),
'updated_at': datetime.datetime(2012, 10, 29, 13, 42, 2)
'updated_at': datetime.datetime(2012, 10, 29, 13, 42, 2),
'deleted_at': None,
'deleted': False
},
{
'id': 5678,
@ -50,7 +52,9 @@ class MigrationsSamplesJsonTest(api_sample_base.ApiSampleTestBaseV3):
'old_instance_type_id': 5,
'new_instance_type_id': 6,
'created_at': datetime.datetime(2013, 10, 22, 13, 42, 2),
'updated_at': datetime.datetime(2013, 10, 22, 13, 42, 2)
'updated_at': datetime.datetime(2013, 10, 22, 13, 42, 2),
'deleted_at': None,
'deleted': False
}
]
return fake_migrations