Microversion 2.59 - Migrations list pagination
Add optional parameters 'limit', 'marker' and 'changes-since' to the os-migrations endpoints for pagination. /os-migrations?limit={limit}&marker={migrations_uuid} /os-migrations?changes-since={changes-since} Change-Id: I7437a61ee07c339b43d008204d1416044a407b68 Implement: blueprint add-pagination-and-change-since-for-migration-list Depends-on: I7e01f95d7173d9217f76e838b3ea71555151ef56
This commit is contained in:
parent
8d80a5e099
commit
ad0c036fb6
@ -25,4 +25,4 @@ API_MIN_VERSION = api_versions.APIVersion("2.1")
|
||||
# when client supported the max version, and bumped sequentially, otherwise
|
||||
# the client may break due to server side new version may include some
|
||||
# backward incompatible change.
|
||||
API_MAX_VERSION = api_versions.APIVersion("2.58")
|
||||
API_MAX_VERSION = api_versions.APIVersion("2.59")
|
||||
|
@ -2049,6 +2049,10 @@ class FakeSessionClient(base_client.SessionClient):
|
||||
migration1.update({"migration_type": "live-migration"})
|
||||
migration2.update({"migration_type": "live-migration"})
|
||||
|
||||
if self.api_version >= api_versions.APIVersion("2.59"):
|
||||
migration1.update({"uuid": "11111111-07d5-11e1-90e3-e3dffe0c5983"})
|
||||
migration2.update({"uuid": "22222222-07d5-11e1-90e3-e3dffe0c5983"})
|
||||
|
||||
migration_list = []
|
||||
instance_uuid = kw.get('instance_uuid', None)
|
||||
if instance_uuid == migration1['instance_uuid']:
|
||||
|
@ -28,15 +28,7 @@ class MigrationsTest(utils.TestCase):
|
||||
for m in ml:
|
||||
self.assertIsInstance(m, migrations.Migration)
|
||||
self.assertRaises(AttributeError, getattr, m, "migration_type")
|
||||
|
||||
def test_list_migrations_v223(self):
|
||||
cs = fakes.FakeClient(api_versions.APIVersion("2.23"))
|
||||
ml = cs.migrations.list()
|
||||
self.assert_request_id(ml, fakes.FAKE_REQUEST_ID_LIST)
|
||||
cs.assert_called('GET', '/os-migrations')
|
||||
for m in ml:
|
||||
self.assertIsInstance(m, migrations.Migration)
|
||||
self.assertEqual(m.migration_type, 'live-migration')
|
||||
self.assertRaises(AttributeError, getattr, m, "uuid")
|
||||
|
||||
def test_list_migrations_with_filters(self):
|
||||
ml = self.cs.migrations.list('host1', 'finished')
|
||||
@ -58,3 +50,48 @@ class MigrationsTest(utils.TestCase):
|
||||
'instance_uuid=instance_id_456&status=finished'))
|
||||
self.assertEqual(1, len(ml))
|
||||
self.assertEqual('instance_id_456', ml[0].instance_uuid)
|
||||
|
||||
|
||||
class MigrationsV223Test(MigrationsTest):
|
||||
def setUp(self):
|
||||
super(MigrationsV223Test, self).setUp()
|
||||
self.cs.api_version = api_versions.APIVersion("2.23")
|
||||
|
||||
def test_list_migrations(self):
|
||||
ml = self.cs.migrations.list()
|
||||
self.assert_request_id(ml, fakes.FAKE_REQUEST_ID_LIST)
|
||||
self.cs.assert_called('GET', '/os-migrations')
|
||||
for m in ml:
|
||||
self.assertIsInstance(m, migrations.Migration)
|
||||
self.assertEqual(m.migration_type, 'live-migration')
|
||||
self.assertRaises(AttributeError, getattr, m, "uuid")
|
||||
|
||||
|
||||
class MigrationsV259Test(MigrationsV223Test):
|
||||
def setUp(self):
|
||||
super(MigrationsV259Test, self).setUp()
|
||||
self.cs.api_version = api_versions.APIVersion("2.59")
|
||||
|
||||
def test_list_migrations(self):
|
||||
ml = self.cs.migrations.list()
|
||||
self.assert_request_id(ml, fakes.FAKE_REQUEST_ID_LIST)
|
||||
self.cs.assert_called('GET', '/os-migrations')
|
||||
for m in ml:
|
||||
self.assertIsInstance(m, migrations.Migration)
|
||||
self.assertEqual(m.migration_type, 'live-migration')
|
||||
self.assertTrue(hasattr(m, 'uuid'))
|
||||
|
||||
def test_list_migrations_with_limit_marker_params(self):
|
||||
marker = '12140183-c814-4ddf-8453-6df43028aa67'
|
||||
params = {'limit': 10,
|
||||
'marker': marker,
|
||||
'changes_since': '2012-02-29T06:23:22'}
|
||||
|
||||
ms = self.cs.migrations.list(**params)
|
||||
self.assert_request_id(ms, fakes.FAKE_REQUEST_ID_LIST)
|
||||
self.cs.assert_called('GET',
|
||||
'/os-migrations?'
|
||||
'changes-since=%s&limit=10&marker=%s'
|
||||
% ('2012-02-29T06%3A23%3A22', marker))
|
||||
for m in ms:
|
||||
self.assertIsInstance(m, migrations.Migration)
|
||||
|
@ -3036,14 +3036,55 @@ class ShellTest(utils.TestCase):
|
||||
self.assert_called('GET', '/os-migrations')
|
||||
|
||||
def test_migration_list_v223(self):
|
||||
self.run_command('migration-list', api_version="2.23")
|
||||
out, _ = self.run_command('migration-list', api_version="2.23")
|
||||
self.assert_called('GET', '/os-migrations')
|
||||
# Make sure there is no UUID in the output. Uses "| UUID" to
|
||||
# avoid collisions with the "Instance UUID" column.
|
||||
self.assertNotIn('| UUID', out)
|
||||
|
||||
def test_migration_list_with_filters(self):
|
||||
self.run_command('migration-list --host host1 --status finished')
|
||||
self.assert_called('GET',
|
||||
'/os-migrations?host=host1&status=finished')
|
||||
|
||||
def test_migration_list_marker_pre_v259_not_allowed(self):
|
||||
cmd = 'migration-list --marker %s'
|
||||
self.assertRaises(SystemExit, self.run_command,
|
||||
cmd % FAKE_UUID_1, api_version='2.58')
|
||||
|
||||
def test_migration_list_limit_pre_v259_not_allowed(self):
|
||||
cmd = 'migration-list --limit 10'
|
||||
self.assertRaises(SystemExit, self.run_command,
|
||||
cmd, api_version='2.58')
|
||||
|
||||
def test_migration_list_changes_since_pre_v259_not_allowed(self):
|
||||
cmd = 'migration-list --changes-since 2016-02-29T06:23:22'
|
||||
self.assertRaises(SystemExit, self.run_command,
|
||||
cmd, api_version='2.58')
|
||||
|
||||
def test_migration_list_limit_marker_v259(self):
|
||||
out, _ = self.run_command(
|
||||
'migration-list --limit 10 --marker %s' % FAKE_UUID_1,
|
||||
api_version='2.59')
|
||||
self.assert_called(
|
||||
'GET',
|
||||
'/os-migrations?limit=10&marker=%s' % FAKE_UUID_1)
|
||||
# Make sure the UUID column is now in the output. Uses "| UUID" to
|
||||
# avoid collisions with the "Instance UUID" column.
|
||||
self.assertIn('| UUID', out)
|
||||
|
||||
def test_migration_list_with_changes_since_v259(self):
|
||||
self.run_command('migration-list --changes-since 2016-02-29T06:23:22',
|
||||
api_version='2.59')
|
||||
self.assert_called(
|
||||
'GET', '/os-migrations?changes-since=2016-02-29T06%3A23%3A22')
|
||||
|
||||
def test_migration_list_with_changes_since_invalid_value_v259(self):
|
||||
ex = self.assertRaises(exceptions.CommandError, self.run_command,
|
||||
'migration-list --changes-since 0123456789',
|
||||
api_version='2.59')
|
||||
self.assertIn('Invalid changes-since value', six.text_type(ex))
|
||||
|
||||
@mock.patch('novaclient.v2.shell._find_server')
|
||||
@mock.patch('os.system')
|
||||
def test_ssh(self, mock_system, mock_find_server):
|
||||
|
@ -14,6 +14,7 @@
|
||||
migration interface
|
||||
"""
|
||||
|
||||
from novaclient import api_versions
|
||||
from novaclient import base
|
||||
|
||||
|
||||
@ -25,12 +26,8 @@ class Migration(base.Resource):
|
||||
class MigrationManager(base.ManagerWithFind):
|
||||
resource_class = Migration
|
||||
|
||||
def list(self, host=None, status=None, instance_uuid=None):
|
||||
"""
|
||||
Get a list of migrations.
|
||||
:param host: (optional) filter migrations by host name.
|
||||
:param status: (optional) filter migrations by status.
|
||||
"""
|
||||
def _list_base(self, host=None, status=None, instance_uuid=None,
|
||||
marker=None, limit=None, changes_since=None):
|
||||
opts = {}
|
||||
if host:
|
||||
opts['host'] = host
|
||||
@ -38,5 +35,43 @@ class MigrationManager(base.ManagerWithFind):
|
||||
opts['status'] = status
|
||||
if instance_uuid:
|
||||
opts['instance_uuid'] = instance_uuid
|
||||
if marker:
|
||||
opts['marker'] = marker
|
||||
if limit:
|
||||
opts['limit'] = limit
|
||||
if changes_since:
|
||||
opts['changes-since'] = changes_since
|
||||
|
||||
return self._list("/os-migrations", "migrations", filters=opts)
|
||||
|
||||
@api_versions.wraps("2.0", "2.58")
|
||||
def list(self, host=None, status=None, instance_uuid=None):
|
||||
"""
|
||||
Get a list of migrations.
|
||||
:param host: filter migrations by host name (optional).
|
||||
:param status: filter migrations by status (optional).
|
||||
:param instance_uuid: filter migrations by instance uuid (optional).
|
||||
"""
|
||||
return self._list_base(host=host, status=status,
|
||||
instance_uuid=instance_uuid)
|
||||
|
||||
@api_versions.wraps("2.59")
|
||||
def list(self, host=None, status=None, instance_uuid=None,
|
||||
marker=None, limit=None, changes_since=None):
|
||||
"""
|
||||
Get a list of migrations.
|
||||
:param host: filter migrations by host name (optional).
|
||||
:param status: filter migrations by status (optional).
|
||||
:param instance_uuid: filter migrations by instance uuid (optional).
|
||||
:param marker: Begin returning migrations that appear later in the
|
||||
migrations list than that represented by this migration UUID
|
||||
(optional).
|
||||
:param limit: maximum number of migrations to return (optional).
|
||||
:param changes_since: only return migrations updated after. The
|
||||
provided time should be an ISO 8061 formatted time. ex
|
||||
2016-03-04T06:27:59Z . (optional).
|
||||
"""
|
||||
return self._list_base(host=host, status=status,
|
||||
instance_uuid=instance_uuid,
|
||||
marker=marker, limit=limit,
|
||||
changes_since=changes_since)
|
||||
|
@ -4992,6 +4992,10 @@ def _print_migrations(cs, migrations):
|
||||
|
||||
formatters = {'Old Flavor': old_flavor, 'New Flavor': new_flavor}
|
||||
|
||||
# Insert migrations UUID after ID
|
||||
if cs.api_version >= api_versions.APIVersion("2.59"):
|
||||
fields.insert(0, "UUID")
|
||||
|
||||
if cs.api_version >= api_versions.APIVersion("2.23"):
|
||||
fields.insert(0, "Id")
|
||||
fields.append("Type")
|
||||
@ -5000,6 +5004,7 @@ def _print_migrations(cs, migrations):
|
||||
utils.print_list(migrations, fields, formatters)
|
||||
|
||||
|
||||
@api_versions.wraps("2.0", "2.58")
|
||||
@utils.arg(
|
||||
'--instance-uuid',
|
||||
dest='instance_uuid',
|
||||
@ -5020,3 +5025,62 @@ def do_migration_list(cs, args):
|
||||
migrations = cs.migrations.list(args.host, args.status,
|
||||
instance_uuid=args.instance_uuid)
|
||||
_print_migrations(cs, migrations)
|
||||
|
||||
|
||||
@api_versions.wraps("2.59")
|
||||
@utils.arg(
|
||||
'--instance-uuid',
|
||||
dest='instance_uuid',
|
||||
metavar='<instance_uuid>',
|
||||
help=_('Fetch migrations for the given instance.'))
|
||||
@utils.arg(
|
||||
'--host',
|
||||
dest='host',
|
||||
metavar='<host>',
|
||||
help=_('Fetch migrations for the given host.'))
|
||||
@utils.arg(
|
||||
'--status',
|
||||
dest='status',
|
||||
metavar='<status>',
|
||||
help=_('Fetch migrations for the given status.'))
|
||||
@utils.arg(
|
||||
'--marker',
|
||||
dest='marker',
|
||||
metavar='<marker>',
|
||||
default=None,
|
||||
help=_('The last migration of the previous page; displays list of '
|
||||
'migrations after "marker". Note that the marker is the '
|
||||
'migration UUID.'))
|
||||
@utils.arg(
|
||||
'--limit',
|
||||
dest='limit',
|
||||
metavar='<limit>',
|
||||
type=int,
|
||||
default=None,
|
||||
help=_('Maximum number of migrations to display. Note that there is a '
|
||||
'configurable max limit on the server, and the limit that is used '
|
||||
'will be the minimum between what is requested here and what '
|
||||
'is configured in the server.'))
|
||||
@utils.arg(
|
||||
'--changes-since',
|
||||
dest='changes_since',
|
||||
metavar='<changes_since>',
|
||||
default=None,
|
||||
help=_('List only migrations changed after a certain point of time. '
|
||||
'The provided time should be an ISO 8061 formatted time. '
|
||||
'ex 2016-03-04T06:27:59Z .'))
|
||||
def do_migration_list(cs, args):
|
||||
"""Print a list of migrations."""
|
||||
if args.changes_since:
|
||||
try:
|
||||
timeutils.parse_isotime(args.changes_since)
|
||||
except ValueError:
|
||||
raise exceptions.CommandError(_('Invalid changes-since value: %s')
|
||||
% args.changes_since)
|
||||
|
||||
migrations = cs.migrations.list(args.host, args.status,
|
||||
instance_uuid=args.instance_uuid,
|
||||
marker=args.marker, limit=args.limit,
|
||||
changes_since=args.changes_since)
|
||||
# TODO(yikun): Output a "Marker" column if there is a next link?
|
||||
_print_migrations(cs, migrations)
|
||||
|
@ -0,0 +1,8 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Added support for microversion v2.59 which introduces pagination support
|
||||
for migrations with the help of new optional parameters ``limit``,
|
||||
``marker``, and also adds the new filter ``changes-since``. Users can use
|
||||
``changes-since`` filter to filter the results based on the last time the
|
||||
migration was updated.
|
Loading…
Reference in New Issue
Block a user