summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzhangbailin <zhangbailin@inspur.com>2019-08-07 11:36:10 +0800
committerMatt Riedemann <mriedem.os@gmail.com>2019-10-16 14:07:28 +0000
commit8744bea0e3ebe5bc4d0d899189bfa0bcdcb0a08f (patch)
tree02f734034376bd0a67e35ba7b4c794aeaa83646e
parent6c0e4d7a3940ba6d4d11d0c89933cc00b898ed9e (diff)
downloadpython-novaclient-8744bea0e3ebe5bc4d0d899189bfa0bcdcb0a08f.tar.gz
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
-rw-r--r--doc/source/cli/nova.rst10
-rw-r--r--novaclient/__init__.py2
-rw-r--r--novaclient/tests/unit/v2/fakes.py20
-rw-r--r--novaclient/tests/unit/v2/test_migrations.py57
-rw-r--r--novaclient/tests/unit/v2/test_shell.py74
-rw-r--r--novaclient/v2/migrations.py47
-rw-r--r--novaclient/v2/shell.py43
-rw-r--r--releasenotes/notes/microversion-v2_80-c2394316f9212865.yaml20
8 files changed, 263 insertions, 10 deletions
diff --git a/doc/source/cli/nova.rst b/doc/source/cli/nova.rst
index cada3d62..b94e52af 100644
--- a/doc/source/cli/nova.rst
+++ b/doc/source/cli/nova.rst
@@ -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
diff --git a/novaclient/__init__.py b/novaclient/__init__.py
index a4f9b4ee..c4f56fba 100644
--- a/novaclient/__init__.py
+++ b/novaclient/__init__.py
@@ -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")
diff --git a/novaclient/tests/unit/v2/fakes.py b/novaclient/tests/unit/v2/fakes.py
index 3430679b..6302c116 100644
--- a/novaclient/tests/unit/v2/fakes.py
+++ b/novaclient/tests/unit/v2/fakes.py
@@ -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):
diff --git a/novaclient/tests/unit/v2/test_migrations.py b/novaclient/tests/unit/v2/test_migrations.py
index fcafa6d2..09d09405 100644
--- a/novaclient/tests/unit/v2/test_migrations.py
+++ b/novaclient/tests/unit/v2/test_migrations.py
@@ -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))
diff --git a/novaclient/tests/unit/v2/test_shell.py b/novaclient/tests/unit/v2/test_shell.py
index 06b27ad3..79118afc 100644
--- a/novaclient/tests/unit/v2/test_shell.py
+++ b/novaclient/tests/unit/v2/test_shell.py
@@ -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):
diff --git a/novaclient/v2/migrations.py b/novaclient/v2/migrations.py
index 3aecd1e7..1fe764b5 100644
--- a/novaclient/v2/migrations.py
+++ b/novaclient/v2/migrations.py
@@ -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)
diff --git a/novaclient/v2/shell.py b/novaclient/v2/shell.py
index b656baba..2125ea99 100644
--- a/novaclient/v2/shell.py
+++ b/novaclient/v2/shell.py
@@ -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)
diff --git a/releasenotes/notes/microversion-v2_80-c2394316f9212865.yaml b/releasenotes/notes/microversion-v2_80-c2394316f9212865.yaml
new file mode 100644
index 00000000..cace47d1
--- /dev/null
+++ b/releasenotes/notes/microversion-v2_80-c2394316f9212865.yaml
@@ -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