Microversion 2.80: Add user_id/project_id to migration-list API
Add ``user_id`` and ``project_id`` to the ``GET /os-migrations`` API, and it can called ``--user-id <user_id>`` and/or ``--project-id <project_id>`` by ``nova migration-list`` CLI. Showing the ``user_id`` and ``project_id`` when using api_version>=2.80 with the server-migration-list or server-migration-show APIs. Depends-On: https://review.opendev.org/#/c/674243/ Part of blueprint add-user-id-field-to-the-migrations-table Change-Id: I11343ca265ab2b6b6f46877897d8223ef340c258
This commit is contained in:
parent
6c0e4d7a39
commit
8744bea0e3
@ -2516,6 +2516,8 @@ nova migration-list
|
||||
[--limit <limit>]
|
||||
[--changes-since <changes_since>]
|
||||
[--changes-before <changes_before>]
|
||||
[--project-id <project_id>]
|
||||
[--user-id <user_id>]
|
||||
|
||||
Print a list of migrations.
|
||||
|
||||
@ -2573,6 +2575,14 @@ To see the list of evacuation operations *from* a compute service host:
|
||||
point of time. The provided time should be an ISO 8061 formatted time.
|
||||
e.g. 2016-03-04T06:27:59Z . (Supported by API versions '2.66' - '2.latest')
|
||||
|
||||
``--project-id <project_id>``
|
||||
Filter the migrations by the given project ID.
|
||||
(Supported by API versions '2.80' - '2.latest')
|
||||
|
||||
``--user-id <user_id>``
|
||||
Filter the migrations by the given user ID.
|
||||
(Supported by API versions '2.80' - '2.latest')
|
||||
|
||||
.. _nova_pause:
|
||||
|
||||
nova pause
|
||||
|
@ -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.79")
|
||||
API_MAX_VERSION = api_versions.APIVersion("2.80")
|
||||
|
@ -2288,6 +2288,14 @@ class FakeSessionClient(base_client.SessionClient):
|
||||
migration1.update({"uuid": "11111111-07d5-11e1-90e3-e3dffe0c5983"})
|
||||
migration2.update({"uuid": "22222222-07d5-11e1-90e3-e3dffe0c5983"})
|
||||
|
||||
if self.api_version >= api_versions.APIVersion("2.80"):
|
||||
migration1.update({
|
||||
"project_id": "b59c18e5fa284fd384987c5cb25a1853",
|
||||
"user_id": "13cc0930d27c4be0acc14d7c47a3e1f7"})
|
||||
migration2.update({
|
||||
"project_id": "b59c18e5fa284fd384987c5cb25a1853",
|
||||
"user_id": "13cc0930d27c4be0acc14d7c47a3e1f7"})
|
||||
|
||||
migration_list = []
|
||||
instance_uuid = kw.get('instance_uuid', None)
|
||||
if instance_uuid == migration1['instance_uuid']:
|
||||
@ -2379,6 +2387,12 @@ class FakeSessionClient(base_client.SessionClient):
|
||||
"disk_remaining_bytes": 230000,
|
||||
"updated_at": "2016-01-29T13:42:02.000000"
|
||||
}}
|
||||
|
||||
if self.api_version >= api_versions.APIVersion("2.80"):
|
||||
migration['migration'].update({
|
||||
"project_id": "b59c18e5fa284fd384987c5cb25a1853",
|
||||
"user_id": "13cc0930d27c4be0acc14d7c47a3e1f7"})
|
||||
|
||||
return (200, FAKE_RESPONSE_HEADERS, migration)
|
||||
|
||||
@api_versions.wraps(start_version="2.23")
|
||||
@ -2402,6 +2416,12 @@ class FakeSessionClient(base_client.SessionClient):
|
||||
"disk_remaining_bytes": 230000,
|
||||
"updated_at": "2016-01-29T13:42:02.000000"
|
||||
}]}
|
||||
|
||||
if self.api_version >= api_versions.APIVersion("2.80"):
|
||||
migrations['migrations'][0].update({
|
||||
"project_id": "b59c18e5fa284fd384987c5cb25a1853",
|
||||
"user_id": "13cc0930d27c4be0acc14d7c47a3e1f7"})
|
||||
|
||||
return (200, FAKE_RESPONSE_HEADERS, migrations)
|
||||
|
||||
def delete_servers_1234_migrations_1(self):
|
||||
|
@ -10,6 +10,8 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import six
|
||||
|
||||
from novaclient import api_versions
|
||||
from novaclient.tests.unit import utils
|
||||
from novaclient.tests.unit.v2 import fakes
|
||||
@ -112,3 +114,58 @@ class MigrationsV266Test(MigrationsV259Test):
|
||||
'2012-02-29T06%3A23%3A22')
|
||||
for m in ms:
|
||||
self.assertIsInstance(m, migrations.Migration)
|
||||
|
||||
|
||||
class MigrationsV280Test(MigrationsV266Test):
|
||||
def setUp(self):
|
||||
super(MigrationsV280Test, self).setUp()
|
||||
self.cs.api_version = api_versions.APIVersion("2.80")
|
||||
|
||||
def test_list_migrations_with_user_id(self):
|
||||
user_id = '13cc0930d27c4be0acc14d7c47a3e1f7'
|
||||
params = {'user_id': user_id}
|
||||
ms = self.cs.migrations.list(**params)
|
||||
self.assert_request_id(ms, fakes.FAKE_REQUEST_ID_LIST)
|
||||
self.cs.assert_called('GET', '/os-migrations?user_id=%s' % user_id)
|
||||
for m in ms:
|
||||
self.assertIsInstance(m, migrations.Migration)
|
||||
|
||||
def test_list_migrations_with_project_id(self):
|
||||
project_id = 'b59c18e5fa284fd384987c5cb25a1853'
|
||||
params = {'project_id': project_id}
|
||||
ms = self.cs.migrations.list(**params)
|
||||
self.assert_request_id(ms, fakes.FAKE_REQUEST_ID_LIST)
|
||||
self.cs.assert_called('GET', '/os-migrations?project_id=%s'
|
||||
% project_id)
|
||||
for m in ms:
|
||||
self.assertIsInstance(m, migrations.Migration)
|
||||
|
||||
def test_list_migrations_with_user_and_project_id(self):
|
||||
user_id = '13cc0930d27c4be0acc14d7c47a3e1f7'
|
||||
project_id = 'b59c18e5fa284fd384987c5cb25a1853'
|
||||
params = {'user_id': user_id, 'project_id': project_id}
|
||||
ms = self.cs.migrations.list(**params)
|
||||
self.assert_request_id(ms, fakes.FAKE_REQUEST_ID_LIST)
|
||||
self.cs.assert_called('GET',
|
||||
'/os-migrations?project_id=%s&user_id=%s'
|
||||
% (project_id, user_id))
|
||||
for m in ms:
|
||||
self.assertIsInstance(m, migrations.Migration)
|
||||
|
||||
def test_list_migrations_with_user_id_pre_v280(self):
|
||||
self.cs.api_version = api_versions.APIVersion('2.79')
|
||||
user_id = '13cc0930d27c4be0acc14d7c47a3e1f7'
|
||||
ex = self.assertRaises(TypeError,
|
||||
self.cs.migrations.list,
|
||||
user_id=user_id)
|
||||
self.assertIn("unexpected keyword argument 'user_id'",
|
||||
six.text_type(ex))
|
||||
|
||||
def test_list_migrations_with_project_id_pre_v280(self):
|
||||
self.cs.api_version = api_versions.APIVersion('2.79')
|
||||
project_id = '23cc0930d27c4be0acc14d7c47a3e1f7'
|
||||
ex = self.assertRaises(TypeError,
|
||||
self.cs.migrations.list,
|
||||
project_id=project_id)
|
||||
self.assertIn("unexpected keyword argument 'project_id'",
|
||||
six.text_type(ex))
|
||||
|
@ -2955,11 +2955,39 @@ class ShellTest(utils.TestCase):
|
||||
api_version='2.23')
|
||||
self.assert_called('GET', '/servers/1234/migrations')
|
||||
|
||||
def test_list_migrations_pre_v280(self):
|
||||
out = self.run_command('server-migration-list sample-server',
|
||||
api_version='2.79')[0]
|
||||
self.assert_called('GET', '/servers/1234/migrations')
|
||||
self.assertNotIn('User ID', out)
|
||||
self.assertNotIn('Project ID', out)
|
||||
|
||||
def test_list_migrations_v280(self):
|
||||
out = self.run_command('server-migration-list sample-server',
|
||||
api_version='2.80')[0]
|
||||
self.assert_called('GET', '/servers/1234/migrations')
|
||||
self.assertIn('User ID', out)
|
||||
self.assertIn('Project ID', out)
|
||||
|
||||
def test_get_migration(self):
|
||||
self.run_command('server-migration-show sample-server 1',
|
||||
api_version='2.23')
|
||||
self.assert_called('GET', '/servers/1234/migrations/1')
|
||||
|
||||
def test_get_migration_pre_v280(self):
|
||||
out = self.run_command('server-migration-show sample-server 1',
|
||||
api_version='2.79')[0]
|
||||
self.assert_called('GET', '/servers/1234/migrations/1')
|
||||
self.assertNotIn('user_id', out)
|
||||
self.assertNotIn('project_id', out)
|
||||
|
||||
def test_get_migration_v280(self):
|
||||
out = self.run_command('server-migration-show sample-server 1',
|
||||
api_version='2.80')[0]
|
||||
self.assert_called('GET', '/servers/1234/migrations/1')
|
||||
self.assertIn('user_id', out)
|
||||
self.assertIn('project_id', out)
|
||||
|
||||
def test_live_migration_abort(self):
|
||||
self.run_command('live-migration-abort sample-server 1',
|
||||
api_version='2.24')
|
||||
@ -4063,6 +4091,52 @@ class ShellTest(utils.TestCase):
|
||||
self.assertRaises(SystemExit, self.run_command, cmd,
|
||||
api_version='2.65')
|
||||
|
||||
def test_migration_list_with_user_id_v280(self):
|
||||
user_id = '13cc0930d27c4be0acc14d7c47a3e1f7'
|
||||
out = self.run_command('migration-list --user-id %s' % user_id,
|
||||
api_version='2.80')[0]
|
||||
self.assert_called('GET', '/os-migrations?user_id=%s' % user_id)
|
||||
self.assertIn('User ID', out)
|
||||
self.assertIn('Project ID', out)
|
||||
|
||||
def test_migration_list_with_project_id_v280(self):
|
||||
project_id = 'b59c18e5fa284fd384987c5cb25a1853'
|
||||
out = self.run_command('migration-list --project-id %s' % project_id,
|
||||
api_version='2.80')[0]
|
||||
self.assert_called('GET', '/os-migrations?project_id=%s' % project_id)
|
||||
self.assertIn('User ID', out)
|
||||
self.assertIn('Project ID', out)
|
||||
|
||||
def test_migration_list_with_user_and_project_id_v280(self):
|
||||
user_id = '13cc0930d27c4be0acc14d7c47a3e1f7'
|
||||
project_id = 'b59c18e5fa284fd384987c5cb25a1853'
|
||||
out = self.run_command('migration-list --project-id %(project_id)s '
|
||||
'--user-id %(user_id)s' %
|
||||
{'user_id': user_id, 'project_id': project_id},
|
||||
api_version='2.80')[0]
|
||||
self.assert_called('GET', '/os-migrations?project_id=%s&user_id=%s'
|
||||
% (project_id, user_id))
|
||||
self.assertIn('User ID', out)
|
||||
self.assertIn('Project ID', out)
|
||||
|
||||
def test_migration_list_with_user_id_pre_v280_not_allowed(self):
|
||||
user_id = '13cc0930d27c4be0acc14d7c47a3e1f7'
|
||||
cmd = 'migration-list --user-id %s' % user_id
|
||||
self.assertRaises(SystemExit, self.run_command, cmd,
|
||||
api_version='2.79')
|
||||
|
||||
def test_migration_list_with_project_id_pre_v280_not_allowed(self):
|
||||
project_id = 'b59c18e5fa284fd384987c5cb25a1853'
|
||||
cmd = 'migration-list --project-id %s' % project_id
|
||||
self.assertRaises(SystemExit, self.run_command, cmd,
|
||||
api_version='2.79')
|
||||
|
||||
def test_migration_list_pre_v280(self):
|
||||
out = self.run_command('migration-list', api_version='2.79')[0]
|
||||
self.assert_called('GET', '/os-migrations')
|
||||
self.assertNotIn('User ID', out)
|
||||
self.assertNotIn('Project ID', out)
|
||||
|
||||
@mock.patch('novaclient.v2.shell._find_server')
|
||||
@mock.patch('os.system')
|
||||
def test_ssh(self, mock_system, mock_find_server):
|
||||
|
@ -29,7 +29,7 @@ class MigrationManager(base.ManagerWithFind):
|
||||
def _list_base(self, host=None, status=None, instance_uuid=None,
|
||||
marker=None, limit=None, changes_since=None,
|
||||
changes_before=None, migration_type=None,
|
||||
source_compute=None):
|
||||
source_compute=None, user_id=None, project_id=None):
|
||||
opts = {}
|
||||
if host:
|
||||
opts['host'] = host
|
||||
@ -49,6 +49,10 @@ class MigrationManager(base.ManagerWithFind):
|
||||
opts['migration_type'] = migration_type
|
||||
if source_compute:
|
||||
opts['source_compute'] = source_compute
|
||||
if user_id:
|
||||
opts['user_id'] = user_id
|
||||
if project_id:
|
||||
opts['project_id'] = project_id
|
||||
|
||||
return self._list("/os-migrations", "migrations", filters=opts)
|
||||
|
||||
@ -99,7 +103,7 @@ class MigrationManager(base.ManagerWithFind):
|
||||
migration_type=migration_type,
|
||||
source_compute=source_compute)
|
||||
|
||||
@api_versions.wraps("2.66")
|
||||
@api_versions.wraps("2.66", "2.79")
|
||||
def list(self, host=None, status=None, instance_uuid=None,
|
||||
marker=None, limit=None, changes_since=None,
|
||||
changes_before=None, migration_type=None, source_compute=None):
|
||||
@ -132,3 +136,42 @@ class MigrationManager(base.ManagerWithFind):
|
||||
changes_before=changes_before,
|
||||
migration_type=migration_type,
|
||||
source_compute=source_compute)
|
||||
|
||||
@api_versions.wraps("2.80")
|
||||
def list(self, host=None, status=None, instance_uuid=None,
|
||||
marker=None, limit=None, changes_since=None,
|
||||
changes_before=None, migration_type=None,
|
||||
source_compute=None, user_id=None, project_id=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).
|
||||
Note the API server has a configurable default limit. If no limit is
|
||||
specified here or limit is larger than default, the default limit will
|
||||
be used.
|
||||
:param changes_since: Only return migrations changed later or equal
|
||||
to a certain point of time. The provided time should be an ISO 8061
|
||||
formatted time. e.g. 2016-03-04T06:27:59Z . (optional).
|
||||
:param changes_before: Only return migrations changed earlier or
|
||||
equal to a certain point of time. The provided time should be an ISO
|
||||
8061 formatted time. e.g. 2016-03-05T06:27:59Z . (optional).
|
||||
:param migration_type: Filter migrations by type. Valid values are:
|
||||
evacuation, live-migration, migration, resize
|
||||
:param source_compute: Filter migrations by source compute host name.
|
||||
:param user_id: filter migrations by user (optional).
|
||||
:param project_id: filter migrations by project (optional).
|
||||
"""
|
||||
return self._list_base(host=host, status=status,
|
||||
instance_uuid=instance_uuid,
|
||||
marker=marker, limit=limit,
|
||||
changes_since=changes_since,
|
||||
changes_before=changes_before,
|
||||
migration_type=migration_type,
|
||||
source_compute=source_compute,
|
||||
user_id=user_id,
|
||||
project_id=project_id)
|
||||
|
@ -3597,6 +3597,10 @@ def do_server_migration_list(cs, args):
|
||||
"memory_remaining_bytes", "disk_total_bytes",
|
||||
"disk_processed_bytes", "disk_remaining_bytes"]
|
||||
|
||||
if cs.api_version >= api_versions.APIVersion("2.80"):
|
||||
fields.append("Project ID")
|
||||
fields.append("User ID")
|
||||
|
||||
formatters = map(lambda field: utils.make_field_formatter(field)[1],
|
||||
format_key)
|
||||
formatters = dict(zip(format_name, formatters))
|
||||
@ -5391,6 +5395,10 @@ def _print_migrations(cs, migrations):
|
||||
fields.append("Type")
|
||||
formatters.update({"Type": migration_type})
|
||||
|
||||
if cs.api_version >= api_versions.APIVersion("2.80"):
|
||||
fields.append("Project ID")
|
||||
fields.append("User ID")
|
||||
|
||||
utils.print_list(migrations, fields, formatters)
|
||||
|
||||
|
||||
@ -5564,6 +5572,20 @@ def do_migration_list(cs, args):
|
||||
'of time. The provided time should be an ISO 8061 formatted time. '
|
||||
'e.g. 2016-03-04T06:27:59Z .'),
|
||||
start_version="2.66")
|
||||
@utils.arg(
|
||||
'--project-id',
|
||||
dest='project_id',
|
||||
metavar='<project_id>',
|
||||
default=None,
|
||||
help=_('Filter the migrations by the given project ID.'),
|
||||
start_version='2.80')
|
||||
@utils.arg(
|
||||
'--user-id',
|
||||
dest='user_id',
|
||||
metavar='<user_id>',
|
||||
default=None,
|
||||
help=_('Filter the migrations by the given user ID.'),
|
||||
start_version='2.80')
|
||||
def do_migration_list(cs, args):
|
||||
"""Print a list of migrations."""
|
||||
if args.changes_since:
|
||||
@ -5580,13 +5602,20 @@ def do_migration_list(cs, args):
|
||||
raise exceptions.CommandError(_('Invalid changes-before value: %s')
|
||||
% args.changes_before)
|
||||
|
||||
migrations = cs.migrations.list(args.host, args.status,
|
||||
instance_uuid=args.instance_uuid,
|
||||
marker=args.marker, limit=args.limit,
|
||||
changes_since=args.changes_since,
|
||||
changes_before=args.changes_before,
|
||||
migration_type=args.migration_type,
|
||||
source_compute=args.source_compute)
|
||||
kwargs = dict(
|
||||
instance_uuid=args.instance_uuid,
|
||||
marker=args.marker,
|
||||
limit=args.limit,
|
||||
changes_since=args.changes_since,
|
||||
changes_before=args.changes_before,
|
||||
migration_type=args.migration_type,
|
||||
source_compute=args.source_compute)
|
||||
|
||||
if cs.api_version >= api_versions.APIVersion('2.80'):
|
||||
kwargs['project_id'] = args.project_id
|
||||
kwargs['user_id'] = args.user_id
|
||||
|
||||
migrations = cs.migrations.list(args.host, args.status, **kwargs)
|
||||
_print_migrations(cs, migrations)
|
||||
|
||||
|
||||
|
20
releasenotes/notes/microversion-v2_80-c2394316f9212865.yaml
Normal file
20
releasenotes/notes/microversion-v2_80-c2394316f9212865.yaml
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Added support for `microversion 2.80`_ which adds ``user_id``
|
||||
and ``project_id`` filter parameters to the ``GET /os-migrations`` API.
|
||||
|
||||
New kwargs ``project_id`` and ``user_id`` have been added to
|
||||
the following python API binding:
|
||||
|
||||
- novaclient.v2.migrations.MigrationManager.list
|
||||
|
||||
The following CLI changes have been made:
|
||||
|
||||
- The ``--project-id`` and ``--user-id`` options are added to the
|
||||
``nova migration-list`` CLI.
|
||||
- The ``nova server-migration-list`` and ``nova server-migration-show``
|
||||
commands will show the ``Project ID`` and ``User ID`` values when
|
||||
using microversion 2.80 or greater.
|
||||
|
||||
.. _microversion 2.80: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id72
|
Loading…
Reference in New Issue
Block a user