summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2019-08-23 22:43:35 +0000
committerGerrit Code Review <review@openstack.org>2019-08-23 22:43:35 +0000
commita19253f8575220de2a836a47235e57e3ad017057 (patch)
tree389659ba186c5be1a90fb7f301cdc8b305efdde5
parenta3e44e8b39492e9604724cdfc5c9d2ede06e6c02 (diff)
parent0e7c99c8ead42326d8660103b0c78df70b775fe4 (diff)
downloadpython-novaclient-a19253f8575220de2a836a47235e57e3ad017057.tar.gz
Merge "Add --migration-type and --source-compute to migration-list"
-rw-r--r--doc/source/cli/nova.rst30
-rw-r--r--novaclient/tests/functional/base.py21
-rw-r--r--novaclient/tests/functional/v2/test_migrations.py99
-rw-r--r--novaclient/tests/functional/v2/test_resize.py21
-rw-r--r--novaclient/v2/migrations.py36
-rw-r--r--novaclient/v2/shell.py45
-rw-r--r--releasenotes/notes/bp-more-migration-list-filters-6c801896c7ee5cdc.yaml9
7 files changed, 227 insertions, 34 deletions
diff --git a/doc/source/cli/nova.rst b/doc/source/cli/nova.rst
index 1a0081eb..c0d80eda 100644
--- a/doc/source/cli/nova.rst
+++ b/doc/source/cli/nova.rst
@@ -2556,13 +2556,26 @@ nova migration-list
.. code-block:: console
- usage: nova migration-list [--instance-uuid <instance_uuid>] [--host <host>]
- [--status <status>] [--marker <marker>]
- [--limit <limit>] [--changes-since <changes_since>]
+ usage: nova migration-list [--instance-uuid <instance_uuid>]
+ [--host <host>]
+ [--status <status>]
+ [--migration-type <migration_type>]
+ [--source-compute <source_compute>]
+ [--marker <marker>]
+ [--limit <limit>]
+ [--changes-since <changes_since>]
[--changes-before <changes_before>]
Print a list of migrations.
+**Examples**
+
+To see the list of evacuation operations *from* a compute service host:
+
+.. code-block:: console
+
+ nova migration-list --migration-type evacuation --source-compute host.foo.bar
+
**Optional arguments:**
``--instance-uuid <instance_uuid>``
@@ -2574,6 +2587,17 @@ Print a list of migrations.
``--status <status>``
Fetch migrations for the given status.
+``--migration-type <migration_type>``
+ Filter migrations by type. Valid values are:
+
+ * evacuation
+ * live-migration
+ * migration
+ * resize
+
+``--source-compute <source_compute>``
+ Filter migrations by source compute host name.
+
``--marker <marker>``
The last migration of the previous page; displays list of migrations after
"marker". Note that the marker is the migration UUID.
diff --git a/novaclient/tests/functional/base.py b/novaclient/tests/functional/base.py
index ce50db94..f5c758be 100644
--- a/novaclient/tests/functional/base.py
+++ b/novaclient/tests/functional/base.py
@@ -522,6 +522,27 @@ class ClientTestBase(testtools.TestCase):
return {limit.name: limit.value
for limit in self.client.limits.get(reserved=True).absolute}
+ def _pick_alternate_flavor(self):
+ """Given the flavor picked in the base class setup, this finds the
+ opposite flavor to use for a resize test. For example, if m1.nano is
+ the flavor, then use m1.micro, but those are only available if Tempest
+ is configured. If m1.tiny, then use m1.small.
+ """
+ flavor_name = self.flavor.name
+ if flavor_name == 'm1.nano':
+ # This is an upsize test.
+ return 'm1.micro'
+ if flavor_name == 'm1.micro':
+ # This is a downsize test.
+ return 'm1.nano'
+ if flavor_name == 'm1.tiny':
+ # This is an upsize test.
+ return 'm1.small'
+ if flavor_name == 'm1.small':
+ # This is a downsize test.
+ return 'm1.tiny'
+ self.fail('Unable to find alternate for flavor: %s' % flavor_name)
+
class TenantTestBase(ClientTestBase):
"""Base test class for additional tenant and user creation which
diff --git a/novaclient/tests/functional/v2/test_migrations.py b/novaclient/tests/functional/v2/test_migrations.py
new file mode 100644
index 00000000..855d8ce5
--- /dev/null
+++ b/novaclient/tests/functional/v2/test_migrations.py
@@ -0,0 +1,99 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from oslo_utils import uuidutils
+
+from novaclient.tests.functional import base
+
+
+class TestMigrationList(base.ClientTestBase):
+ """Tests the "nova migration-list" command."""
+
+ def _filter_migrations(
+ self, version, migration_type, source_compute):
+ """
+ Filters migrations by --migration-type and --source-compute.
+
+ :param version: The --os-compute-api-version to use.
+ :param migration_type: The type of migrations to filter.
+ :param source_compute: The source compute service hostname to filter.
+ :return: output of the nova migration-list command with filters applied
+ """
+ return self.nova('migration-list',
+ flags='--os-compute-api-version %s' % version,
+ params='--migration-type %s --source-compute %s' % (
+ migration_type, source_compute))
+
+ def test_migration_list(self):
+ """Tests creating a server, resizing it and then listing and filtering
+ migrations using various microversion milestones.
+ """
+ server_id = self._create_server(flavor=self.flavor.id).id
+ # Find the source compute by getting OS-EXT-SRV-ATTR:host from the
+ # nova show output.
+ server = self.nova('show', params='%s' % server_id)
+ source_compute = self._get_value_from_the_table(
+ server, 'OS-EXT-SRV-ATTR:host')
+ # now resize up
+ alternate_flavor = self._pick_alternate_flavor()
+ self.nova('resize',
+ params='%s %s --poll' % (server_id, alternate_flavor))
+ # now confirm the resize
+ self.nova('resize-confirm', params='%s' % server_id)
+ # wait for the server to be active and then check the migration list
+ self._wait_for_state_change(server_id, 'active')
+ # First, list migrations with v2.1 and our server id should be in the
+ # output. There should only be the one migration.
+ migrations = self.nova('migration-list',
+ flags='--os-compute-api-version 2.1')
+ instance_uuid = self._get_column_value_from_single_row_table(
+ migrations, 'Instance UUID')
+ self.assertEqual(server_id, instance_uuid)
+ # A successfully confirmed resize should have the migration status
+ # of "confirmed".
+ migration_status = self._get_column_value_from_single_row_table(
+ migrations, 'Status')
+ self.assertEqual('confirmed', migration_status)
+ # Now listing migrations with 2.23 should give us the Type column which
+ # should have a value of "resize".
+ migrations = self.nova('migration-list',
+ flags='--os-compute-api-version 2.23')
+ migration_type = self._get_column_value_from_single_row_table(
+ migrations, 'Type')
+ self.assertEqual('resize', migration_type)
+ # Filter migrations with v2.1.
+ migrations = self._filter_migrations('2.1', 'resize', source_compute)
+ # Make sure we got something back.
+ src_compute = self._get_column_value_from_single_row_table(
+ migrations, 'Source Compute')
+ self.assertEqual(source_compute, src_compute)
+ # Filter migrations with v2.59 and make sure there is a migration UUID
+ # value in the output.
+ migrations = self._filter_migrations('2.59', 'resize', source_compute)
+ # _get_column_value_from_single_row_table will raise ValueError if a
+ # value is not found for the given column. We don't actually care what
+ # the migration UUID value is just that the filter works and the UUID
+ # is shown.
+ self._get_column_value_from_single_row_table(migrations, 'UUID')
+ # Filter migrations with v2.66, same as 2.59.
+ migrations = self._filter_migrations('2.66', 'resize', source_compute)
+ self._get_column_value_from_single_row_table(migrations, 'UUID')
+ # Now do a negative test to show that filtering on a migration type
+ # that we don't have a migration for will not return anything.
+ migrations = self._filter_migrations(
+ '2.1', 'evacuation', source_compute)
+ self.assertNotIn(server_id, migrations)
+ # Similarly, make sure we don't get anything back when filtering on
+ # a --source-compute that doesn't exist.
+ migrations = self._filter_migrations(
+ '2.66', 'resize', uuidutils.generate_uuid())
+ self.assertNotIn(server_id, migrations)
diff --git a/novaclient/tests/functional/v2/test_resize.py b/novaclient/tests/functional/v2/test_resize.py
index 0354610f..075a2f9a 100644
--- a/novaclient/tests/functional/v2/test_resize.py
+++ b/novaclient/tests/functional/v2/test_resize.py
@@ -20,27 +20,6 @@ class TestServersResize(base.ClientTestBase):
COMPUTE_API_VERSION = '2.1'
- def _pick_alternate_flavor(self):
- """Given the flavor picked in the base class setup, this finds the
- opposite flavor to use for a resize test. For example, if m1.nano is
- the flavor, then use m1.micro, but those are only available if Tempest
- is configured. If m1.tiny, then use m1.small.
- """
- flavor_name = self.flavor.name
- if flavor_name == 'm1.nano':
- # This is an upsize test.
- return 'm1.micro'
- if flavor_name == 'm1.micro':
- # This is a downsize test.
- return 'm1.nano'
- if flavor_name == 'm1.tiny':
- # This is an upsize test.
- return 'm1.small'
- if flavor_name == 'm1.small':
- # This is a downsize test.
- return 'm1.tiny'
- self.fail('Unable to find alternate for flavor: %s' % flavor_name)
-
def _compare_quota_usage(self, old_usage, new_usage, expect_diff=True):
"""Compares the quota usage in the provided AbsoluteLimits."""
# For a resize, instance usage shouldn't change.
diff --git a/novaclient/v2/migrations.py b/novaclient/v2/migrations.py
index ab62f2c5..0e94b456 100644
--- a/novaclient/v2/migrations.py
+++ b/novaclient/v2/migrations.py
@@ -28,7 +28,8 @@ 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):
+ changes_before=None, migration_type=None,
+ source_compute=None):
opts = {}
if host:
opts['host'] = host
@@ -44,23 +45,34 @@ class MigrationManager(base.ManagerWithFind):
opts['changes-since'] = changes_since
if changes_before:
opts['changes-before'] = changes_before
+ if migration_type:
+ opts['migration_type'] = migration_type
+ if source_compute:
+ opts['source_compute'] = source_compute
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):
+ def list(self, host=None, status=None, instance_uuid=None,
+ migration_type=None, source_compute=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 migration_type: Filter migrations by type. Valid values are:
+ evacuation, live-migration, migration, resize
+ :param source_compute: Filter migrations by source compute host name.
"""
return self._list_base(host=host, status=status,
- instance_uuid=instance_uuid)
+ instance_uuid=instance_uuid,
+ migration_type=migration_type,
+ source_compute=source_compute)
@api_versions.wraps("2.59", "2.65")
def list(self, host=None, status=None, instance_uuid=None,
- marker=None, limit=None, changes_since=None):
+ marker=None, limit=None, changes_since=None,
+ migration_type=None, source_compute=None):
"""
Get a list of migrations.
:param host: filter migrations by host name (optional).
@@ -76,16 +88,21 @@ class MigrationManager(base.ManagerWithFind):
: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 migration_type: Filter migrations by type. Valid values are:
+ evacuation, live-migration, migration, resize
+ :param source_compute: Filter migrations by source compute host name.
"""
return self._list_base(host=host, status=status,
instance_uuid=instance_uuid,
marker=marker, limit=limit,
- changes_since=changes_since)
+ changes_since=changes_since,
+ migration_type=migration_type,
+ source_compute=source_compute)
@api_versions.wraps("2.66")
def list(self, host=None, status=None, instance_uuid=None,
marker=None, limit=None, changes_since=None,
- changes_before=None):
+ changes_before=None, migration_type=None, source_compute=None):
"""
Get a list of migrations.
:param host: filter migrations by host name (optional).
@@ -104,9 +121,14 @@ class MigrationManager(base.ManagerWithFind):
: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.
"""
return self._list_base(host=host, status=status,
instance_uuid=instance_uuid,
marker=marker, limit=limit,
changes_since=changes_since,
- changes_before=changes_before)
+ changes_before=changes_before,
+ migration_type=migration_type,
+ source_compute=source_compute)
diff --git a/novaclient/v2/shell.py b/novaclient/v2/shell.py
index 7b9c0206..34dea57f 100644
--- a/novaclient/v2/shell.py
+++ b/novaclient/v2/shell.py
@@ -5422,10 +5422,23 @@ def _print_migrations(cs, migrations):
dest='status',
metavar='<status>',
help=_('Fetch migrations for the given status.'))
+@utils.arg(
+ '--migration-type',
+ dest='migration_type',
+ metavar='<migration_type>',
+ help=_('Filter migrations by type. Valid values are: evacuation, '
+ 'live-migration, migration, resize'))
+@utils.arg(
+ '--source-compute',
+ dest='source_compute',
+ metavar='<source_compute>',
+ help=_('Filter migrations by source compute host name.'))
def do_migration_list(cs, args):
"""Print a list of migrations."""
migrations = cs.migrations.list(args.host, args.status,
- instance_uuid=args.instance_uuid)
+ instance_uuid=args.instance_uuid,
+ migration_type=args.migration_type,
+ source_compute=args.source_compute)
_print_migrations(cs, migrations)
@@ -5446,6 +5459,17 @@ def do_migration_list(cs, args):
metavar='<status>',
help=_('Fetch migrations for the given status.'))
@utils.arg(
+ '--migration-type',
+ dest='migration_type',
+ metavar='<migration_type>',
+ help=_('Filter migrations by type. Valid values are: evacuation, '
+ 'live-migration, migration, resize'))
+@utils.arg(
+ '--source-compute',
+ dest='source_compute',
+ metavar='<source_compute>',
+ help=_('Filter migrations by source compute host name.'))
+@utils.arg(
'--marker',
dest='marker',
metavar='<marker>',
@@ -5483,7 +5507,9 @@ def do_migration_list(cs, args):
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_since=args.changes_since,
+ migration_type=args.migration_type,
+ source_compute=args.source_compute)
# TODO(yikun): Output a "Marker" column if there is a next link?
_print_migrations(cs, migrations)
@@ -5505,6 +5531,17 @@ def do_migration_list(cs, args):
metavar='<status>',
help=_('Fetch migrations for the given status.'))
@utils.arg(
+ '--migration-type',
+ dest='migration_type',
+ metavar='<migration_type>',
+ help=_('Filter migrations by type. Valid values are: evacuation, '
+ 'live-migration, migration, resize'))
+@utils.arg(
+ '--source-compute',
+ dest='source_compute',
+ metavar='<source_compute>',
+ help=_('Filter migrations by source compute host name.'))
+@utils.arg(
'--marker',
dest='marker',
metavar='<marker>',
@@ -5559,7 +5596,9 @@ def do_migration_list(cs, args):
instance_uuid=args.instance_uuid,
marker=args.marker, limit=args.limit,
changes_since=args.changes_since,
- changes_before=args.changes_before)
+ changes_before=args.changes_before,
+ migration_type=args.migration_type,
+ source_compute=args.source_compute)
_print_migrations(cs, migrations)
diff --git a/releasenotes/notes/bp-more-migration-list-filters-6c801896c7ee5cdc.yaml b/releasenotes/notes/bp-more-migration-list-filters-6c801896c7ee5cdc.yaml
new file mode 100644
index 00000000..14e028d3
--- /dev/null
+++ b/releasenotes/notes/bp-more-migration-list-filters-6c801896c7ee5cdc.yaml
@@ -0,0 +1,9 @@
+---
+features:
+ - |
+ The ``--migration-type`` and ``--source-compute`` options are added to the
+ ``nova migration-list`` CLI and related kwargs are added to the
+ ``novaclient.v2.migrations.MigrationManager.list`` method. These can be
+ used to filter the list of migrations by type (evacuation, live-migration,
+ migration, resize) and the name of the source compute service host involved
+ in the migration.