diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py
index 5da1984d0f..47c9c82629 100644
--- a/openstackclient/compute/v2/server.py
+++ b/openstackclient/compute/v2/server.py
@@ -21,7 +21,6 @@ import io
 import json
 import logging
 import os
-import uuid
 
 from cliff import columns as cliff_columns
 import iso8601
@@ -2812,468 +2811,6 @@ revert to release the new server and restart the old one.""")
                 raise SystemExit
 
 
-class ListMigration(command.Lister):
-    _description = _("""List server migrations""")
-
-    def get_parser(self, prog_name):
-        parser = super(ListMigration, self).get_parser(prog_name)
-        parser.add_argument(
-            '--server',
-            metavar='<server>',
-            help=_(
-                'Filter migrations by server (name or ID)'
-            )
-        )
-        parser.add_argument(
-            '--host',
-            metavar='<host>',
-            help=_(
-                'Filter migrations by source or destination host'
-            ),
-        )
-        parser.add_argument(
-            '--status',
-            metavar='<status>',
-            help=_('Filter migrations by status')
-        )
-        parser.add_argument(
-            '--type',
-            metavar='<type>',
-            choices=[
-                'evacuation', 'live-migration', 'cold-migration', 'resize',
-            ],
-            help=_('Filter migrations by type'),
-        )
-        parser.add_argument(
-            '--marker',
-            metavar='<marker>',
-            help=_(
-                "The last migration of the previous page; displays list "
-                "of migrations after 'marker'. Note that the marker is "
-                "the migration UUID. "
-                "(supported with --os-compute-api-version 2.59 or above)"
-            ),
-        )
-        parser.add_argument(
-            '--limit',
-            metavar='<limit>',
-            type=int,
-            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 of what is requested "
-                "here and what is configured in the server. "
-                "(supported with --os-compute-api-version 2.59 or above)"
-            ),
-        )
-        parser.add_argument(
-            '--changes-since',
-            dest='changes_since',
-            metavar='<changes-since>',
-            help=_(
-                "List only 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``. "
-                "(supported with --os-compute-api-version 2.59 or above)"
-            ),
-        )
-        parser.add_argument(
-            '--changes-before',
-            dest='changes_before',
-            metavar='<changes-before>',
-            help=_(
-                "List only 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-04T06:27:59Z``. "
-                "(supported with --os-compute-api-version 2.66 or above)"
-            ),
-        )
-        parser.add_argument(
-            '--project',
-            metavar='<project>',
-            help=_(
-                "Filter migrations by project (name or ID) "
-                "(supported with --os-compute-api-version 2.80 or above)"
-            ),
-        )
-        identity_common.add_project_domain_option_to_parser(parser)
-        parser.add_argument(
-            '--user',
-            metavar='<user>',
-            help=_(
-                "Filter migrations by user (name or ID) "
-                "(supported with --os-compute-api-version 2.80 or above)"
-            ),
-        )
-        identity_common.add_user_domain_option_to_parser(parser)
-        return parser
-
-    def print_migrations(self, parsed_args, compute_client, migrations):
-        column_headers = [
-            'Source Node', 'Dest Node', 'Source Compute', 'Dest Compute',
-            'Dest Host', 'Status', 'Server UUID', 'Old Flavor', 'New Flavor',
-            'Created At', 'Updated At',
-        ]
-
-        # Response fields coming back from the REST API are not always exactly
-        # the same as the column header names.
-        columns = [
-            'source_node', 'dest_node', 'source_compute', 'dest_compute',
-            'dest_host', 'status', 'instance_uuid', 'old_instance_type_id',
-            'new_instance_type_id', 'created_at', 'updated_at',
-        ]
-
-        # Insert migrations UUID after ID
-        if compute_client.api_version >= api_versions.APIVersion("2.59"):
-            column_headers.insert(0, "UUID")
-            columns.insert(0, "uuid")
-
-        if compute_client.api_version >= api_versions.APIVersion("2.23"):
-            column_headers.insert(0, "Id")
-            columns.insert(0, "id")
-            column_headers.insert(len(column_headers) - 2, "Type")
-            columns.insert(len(columns) - 2, "migration_type")
-
-        if compute_client.api_version >= api_versions.APIVersion("2.80"):
-            if parsed_args.project:
-                column_headers.insert(len(column_headers) - 2, "Project")
-                columns.insert(len(columns) - 2, "project_id")
-            if parsed_args.user:
-                column_headers.insert(len(column_headers) - 2, "User")
-                columns.insert(len(columns) - 2, "user_id")
-
-        return (
-            column_headers,
-            (utils.get_item_properties(mig, columns) for mig in migrations),
-        )
-
-    def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.compute
-        identity_client = self.app.client_manager.identity
-
-        search_opts = {
-            'host': parsed_args.host,
-            'status': parsed_args.status,
-        }
-
-        if parsed_args.server:
-            search_opts['instance_uuid'] = utils.find_resource(
-                compute_client.servers,
-                parsed_args.server,
-            ).id
-
-        if parsed_args.type:
-            migration_type = parsed_args.type
-            # we're using an alias because the default value is confusing
-            if migration_type == 'cold-migration':
-                migration_type = 'migration'
-            search_opts['migration_type'] = migration_type
-
-        if parsed_args.marker:
-            if compute_client.api_version < api_versions.APIVersion('2.59'):
-                msg = _(
-                    '--os-compute-api-version 2.59 or greater is required to '
-                    'support the --marker option'
-                )
-                raise exceptions.CommandError(msg)
-            search_opts['marker'] = parsed_args.marker
-
-        if parsed_args.limit:
-            if compute_client.api_version < api_versions.APIVersion('2.59'):
-                msg = _(
-                    '--os-compute-api-version 2.59 or greater is required to '
-                    'support the --limit option'
-                )
-                raise exceptions.CommandError(msg)
-            search_opts['limit'] = parsed_args.limit
-
-        if parsed_args.changes_since:
-            if compute_client.api_version < api_versions.APIVersion('2.59'):
-                msg = _(
-                    '--os-compute-api-version 2.59 or greater is required to '
-                    'support the --changes-since option'
-                )
-                raise exceptions.CommandError(msg)
-            search_opts['changes_since'] = parsed_args.changes_since
-
-        if parsed_args.changes_before:
-            if compute_client.api_version < api_versions.APIVersion('2.66'):
-                msg = _(
-                    '--os-compute-api-version 2.66 or greater is required to '
-                    'support the --changes-before option'
-                )
-                raise exceptions.CommandError(msg)
-            search_opts['changes_before'] = parsed_args.changes_before
-
-        if parsed_args.project:
-            if compute_client.api_version < api_versions.APIVersion('2.80'):
-                msg = _(
-                    '--os-compute-api-version 2.80 or greater is required to '
-                    'support the --project option'
-                )
-                raise exceptions.CommandError(msg)
-
-            search_opts['project_id'] = identity_common.find_project(
-                identity_client,
-                parsed_args.project,
-                parsed_args.project_domain,
-            ).id
-
-        if parsed_args.user:
-            if compute_client.api_version < api_versions.APIVersion('2.80'):
-                msg = _(
-                    '--os-compute-api-version 2.80 or greater is required to '
-                    'support the --user option'
-                )
-                raise exceptions.CommandError(msg)
-
-            search_opts['user_id'] = identity_common.find_user(
-                identity_client,
-                parsed_args.user,
-                parsed_args.user_domain,
-            ).id
-
-        migrations = compute_client.migrations.list(**search_opts)
-
-        return self.print_migrations(parsed_args, compute_client, migrations)
-
-
-def _get_migration_by_uuid(compute_client, server_id, migration_uuid):
-    for migration in compute_client.server_migrations.list(server_id):
-        if migration.uuid == migration_uuid:
-            return migration
-            break
-    else:
-        msg = _(
-            'In-progress live migration %s is not found for server %s.'
-        )
-        raise exceptions.CommandError(msg % (migration_uuid, server_id))
-
-
-class ShowMigration(command.ShowOne):
-    """Show an in-progress live migration for a given server.
-
-    Note that it is not possible to show cold migrations or completed
-    live-migrations. Use 'openstack server migration list' to get details for
-    these.
-    """
-
-    def get_parser(self, prog_name):
-        parser = super().get_parser(prog_name)
-        parser.add_argument(
-            'server',
-            metavar='<server>',
-            help=_('Server (name or ID)'),
-        )
-        parser.add_argument(
-            'migration',
-            metavar='<migration>',
-            help=_("Migration (ID)"),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.compute
-
-        if compute_client.api_version < api_versions.APIVersion('2.24'):
-            msg = _(
-                '--os-compute-api-version 2.24 or greater is required to '
-                'support the server migration show command'
-            )
-            raise exceptions.CommandError(msg)
-
-        if not parsed_args.migration.isdigit():
-            try:
-                uuid.UUID(parsed_args.migration)
-            except ValueError:
-                msg = _(
-                    'The <migration> argument must be an ID or UUID'
-                )
-                raise exceptions.CommandError(msg)
-
-            if compute_client.api_version < api_versions.APIVersion('2.59'):
-                msg = _(
-                    '--os-compute-api-version 2.59 or greater is required to '
-                    'retrieve server migrations by UUID'
-                )
-                raise exceptions.CommandError(msg)
-
-        server = utils.find_resource(
-            compute_client.servers,
-            parsed_args.server,
-        )
-
-        # the nova API doesn't currently allow retrieval by UUID but it's a
-        # reasonably common operation so emulate this behavior by listing
-        # migrations - the responses are identical
-        if not parsed_args.migration.isdigit():
-            server_migration = _get_migration_by_uuid(
-                compute_client, server.id, parsed_args.migration,
-            )
-        else:
-            server_migration = compute_client.server_migrations.get(
-                server.id, parsed_args.migration,
-            )
-
-        columns = (
-            'ID',
-            'Server UUID',
-            'Status',
-            'Source Compute',
-            'Source Node',
-            'Dest Compute',
-            'Dest Host',
-            'Dest Node',
-            'Memory Total Bytes',
-            'Memory Processed Bytes',
-            'Memory Remaining Bytes',
-            'Disk Total Bytes',
-            'Disk Processed Bytes',
-            'Disk Remaining Bytes',
-            'Created At',
-            'Updated At',
-        )
-
-        if compute_client.api_version >= api_versions.APIVersion('2.59'):
-            columns += ('UUID',)
-
-        if compute_client.api_version >= api_versions.APIVersion('2.80'):
-            columns += ('User ID', 'Project ID')
-
-        data = utils.get_item_properties(server_migration, columns)
-        return columns, data
-
-
-class AbortMigration(command.Command):
-    """Cancel an ongoing live migration.
-
-    This command requires ``--os-compute-api-version`` 2.24 or greater.
-    """
-
-    def get_parser(self, prog_name):
-        parser = super(AbortMigration, self).get_parser(prog_name)
-        parser.add_argument(
-            'server',
-            metavar='<server>',
-            help=_('Server (name or ID)'),
-        )
-        parser.add_argument(
-            'migration',
-            metavar='<migration>',
-            help=_("Migration (ID)"),
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.compute
-
-        if compute_client.api_version < api_versions.APIVersion('2.24'):
-            msg = _(
-                '--os-compute-api-version 2.24 or greater is required to '
-                'support the server migration abort command'
-            )
-            raise exceptions.CommandError(msg)
-
-        if not parsed_args.migration.isdigit():
-            try:
-                uuid.UUID(parsed_args.migration)
-            except ValueError:
-                msg = _(
-                    'The <migration> argument must be an ID or UUID'
-                )
-                raise exceptions.CommandError(msg)
-
-            if compute_client.api_version < api_versions.APIVersion('2.59'):
-                msg = _(
-                    '--os-compute-api-version 2.59 or greater is required to '
-                    'abort server migrations by UUID'
-                )
-                raise exceptions.CommandError(msg)
-
-        server = utils.find_resource(
-            compute_client.servers,
-            parsed_args.server,
-        )
-
-        # the nova API doesn't currently allow retrieval by UUID but it's a
-        # reasonably common operation so emulate this behavior by listing
-        # migrations - the responses are identical
-        migration_id = parsed_args.migration
-        if not parsed_args.migration.isdigit():
-            migration_id = _get_migration_by_uuid(
-                compute_client, server.id, parsed_args.migration,
-            ).id
-
-        compute_client.server_migrations.live_migration_abort(
-            server.id, migration_id,
-        )
-
-
-class ForceCompleteMigration(command.Command):
-    """Force an ongoing live migration to complete.
-
-    This command requires ``--os-compute-api-version`` 2.22 or greater.
-    """
-
-    def get_parser(self, prog_name):
-        parser = super(ForceCompleteMigration, self).get_parser(prog_name)
-        parser.add_argument(
-            'server',
-            metavar='<server>',
-            help=_('Server (name or ID)'),
-        )
-        parser.add_argument(
-            'migration',
-            metavar='<migration>',
-            help=_('Migration (ID)')
-        )
-        return parser
-
-    def take_action(self, parsed_args):
-        compute_client = self.app.client_manager.compute
-
-        if compute_client.api_version < api_versions.APIVersion('2.22'):
-            msg = _(
-                '--os-compute-api-version 2.22 or greater is required to '
-                'support the server migration force complete command'
-            )
-            raise exceptions.CommandError(msg)
-
-        if not parsed_args.migration.isdigit():
-            try:
-                uuid.UUID(parsed_args.migration)
-            except ValueError:
-                msg = _(
-                    'The <migration> argument must be an ID or UUID'
-                )
-                raise exceptions.CommandError(msg)
-
-            if compute_client.api_version < api_versions.APIVersion('2.59'):
-                msg = _(
-                    '--os-compute-api-version 2.59 or greater is required to '
-                    'abort server migrations by UUID'
-                )
-                raise exceptions.CommandError(msg)
-
-        server = utils.find_resource(
-            compute_client.servers,
-            parsed_args.server,
-        )
-
-        # the nova API doesn't currently allow retrieval by UUID but it's a
-        # reasonably common operation so emulate this behavior by listing
-        # migrations - the responses are identical
-        migration_id = parsed_args.migration
-        if not parsed_args.migration.isdigit():
-            migration_id = _get_migration_by_uuid(
-                compute_client, server.id, parsed_args.migration,
-            ).id
-
-        compute_client.server_migrations.live_migrate_force_complete(
-            server.id, migration_id,
-        )
-
-
 class PauseServer(command.Command):
     _description = _("Pause server(s)")
 
diff --git a/openstackclient/compute/v2/server_migration.py b/openstackclient/compute/v2/server_migration.py
new file mode 100644
index 0000000000..919b67bdcb
--- /dev/null
+++ b/openstackclient/compute/v2/server_migration.py
@@ -0,0 +1,485 @@
+# 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.
+
+"""Compute v2 Server Migration action implementations"""
+
+import uuid
+
+from novaclient import api_versions
+from osc_lib.command import command
+from osc_lib import exceptions
+from osc_lib import utils
+
+from openstackclient.i18n import _
+from openstackclient.identity import common as identity_common
+
+
+class ListMigration(command.Lister):
+    _description = _("""List server migrations""")
+
+    def get_parser(self, prog_name):
+        parser = super(ListMigration, self).get_parser(prog_name)
+        parser.add_argument(
+            '--server',
+            metavar='<server>',
+            help=_(
+                'Filter migrations by server (name or ID)'
+            )
+        )
+        parser.add_argument(
+            '--host',
+            metavar='<host>',
+            help=_(
+                'Filter migrations by source or destination host'
+            ),
+        )
+        parser.add_argument(
+            '--status',
+            metavar='<status>',
+            help=_('Filter migrations by status')
+        )
+        parser.add_argument(
+            '--type',
+            metavar='<type>',
+            choices=[
+                'evacuation', 'live-migration', 'cold-migration', 'resize',
+            ],
+            help=_('Filter migrations by type'),
+        )
+        parser.add_argument(
+            '--marker',
+            metavar='<marker>',
+            help=_(
+                "The last migration of the previous page; displays list "
+                "of migrations after 'marker'. Note that the marker is "
+                "the migration UUID. "
+                "(supported with --os-compute-api-version 2.59 or above)"
+            ),
+        )
+        parser.add_argument(
+            '--limit',
+            metavar='<limit>',
+            type=int,
+            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 of what is requested "
+                "here and what is configured in the server. "
+                "(supported with --os-compute-api-version 2.59 or above)"
+            ),
+        )
+        parser.add_argument(
+            '--changes-since',
+            dest='changes_since',
+            metavar='<changes-since>',
+            help=_(
+                "List only 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``. "
+                "(supported with --os-compute-api-version 2.59 or above)"
+            ),
+        )
+        parser.add_argument(
+            '--changes-before',
+            dest='changes_before',
+            metavar='<changes-before>',
+            help=_(
+                "List only 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-04T06:27:59Z``. "
+                "(supported with --os-compute-api-version 2.66 or above)"
+            ),
+        )
+        parser.add_argument(
+            '--project',
+            metavar='<project>',
+            help=_(
+                "Filter migrations by project (name or ID) "
+                "(supported with --os-compute-api-version 2.80 or above)"
+            ),
+        )
+        identity_common.add_project_domain_option_to_parser(parser)
+        parser.add_argument(
+            '--user',
+            metavar='<user>',
+            help=_(
+                "Filter migrations by user (name or ID) "
+                "(supported with --os-compute-api-version 2.80 or above)"
+            ),
+        )
+        identity_common.add_user_domain_option_to_parser(parser)
+        return parser
+
+    def print_migrations(self, parsed_args, compute_client, migrations):
+        column_headers = [
+            'Source Node', 'Dest Node', 'Source Compute', 'Dest Compute',
+            'Dest Host', 'Status', 'Server UUID', 'Old Flavor', 'New Flavor',
+            'Created At', 'Updated At',
+        ]
+
+        # Response fields coming back from the REST API are not always exactly
+        # the same as the column header names.
+        columns = [
+            'source_node', 'dest_node', 'source_compute', 'dest_compute',
+            'dest_host', 'status', 'instance_uuid', 'old_instance_type_id',
+            'new_instance_type_id', 'created_at', 'updated_at',
+        ]
+
+        # Insert migrations UUID after ID
+        if compute_client.api_version >= api_versions.APIVersion("2.59"):
+            column_headers.insert(0, "UUID")
+            columns.insert(0, "uuid")
+
+        if compute_client.api_version >= api_versions.APIVersion("2.23"):
+            column_headers.insert(0, "Id")
+            columns.insert(0, "id")
+            column_headers.insert(len(column_headers) - 2, "Type")
+            columns.insert(len(columns) - 2, "migration_type")
+
+        if compute_client.api_version >= api_versions.APIVersion("2.80"):
+            if parsed_args.project:
+                column_headers.insert(len(column_headers) - 2, "Project")
+                columns.insert(len(columns) - 2, "project_id")
+            if parsed_args.user:
+                column_headers.insert(len(column_headers) - 2, "User")
+                columns.insert(len(columns) - 2, "user_id")
+
+        return (
+            column_headers,
+            (utils.get_item_properties(mig, columns) for mig in migrations),
+        )
+
+    def take_action(self, parsed_args):
+        compute_client = self.app.client_manager.compute
+        identity_client = self.app.client_manager.identity
+
+        search_opts = {
+            'host': parsed_args.host,
+            'status': parsed_args.status,
+        }
+
+        if parsed_args.server:
+            search_opts['instance_uuid'] = utils.find_resource(
+                compute_client.servers,
+                parsed_args.server,
+            ).id
+
+        if parsed_args.type:
+            migration_type = parsed_args.type
+            # we're using an alias because the default value is confusing
+            if migration_type == 'cold-migration':
+                migration_type = 'migration'
+            search_opts['migration_type'] = migration_type
+
+        if parsed_args.marker:
+            if compute_client.api_version < api_versions.APIVersion('2.59'):
+                msg = _(
+                    '--os-compute-api-version 2.59 or greater is required to '
+                    'support the --marker option'
+                )
+                raise exceptions.CommandError(msg)
+            search_opts['marker'] = parsed_args.marker
+
+        if parsed_args.limit:
+            if compute_client.api_version < api_versions.APIVersion('2.59'):
+                msg = _(
+                    '--os-compute-api-version 2.59 or greater is required to '
+                    'support the --limit option'
+                )
+                raise exceptions.CommandError(msg)
+            search_opts['limit'] = parsed_args.limit
+
+        if parsed_args.changes_since:
+            if compute_client.api_version < api_versions.APIVersion('2.59'):
+                msg = _(
+                    '--os-compute-api-version 2.59 or greater is required to '
+                    'support the --changes-since option'
+                )
+                raise exceptions.CommandError(msg)
+            search_opts['changes_since'] = parsed_args.changes_since
+
+        if parsed_args.changes_before:
+            if compute_client.api_version < api_versions.APIVersion('2.66'):
+                msg = _(
+                    '--os-compute-api-version 2.66 or greater is required to '
+                    'support the --changes-before option'
+                )
+                raise exceptions.CommandError(msg)
+            search_opts['changes_before'] = parsed_args.changes_before
+
+        if parsed_args.project:
+            if compute_client.api_version < api_versions.APIVersion('2.80'):
+                msg = _(
+                    '--os-compute-api-version 2.80 or greater is required to '
+                    'support the --project option'
+                )
+                raise exceptions.CommandError(msg)
+
+            search_opts['project_id'] = identity_common.find_project(
+                identity_client,
+                parsed_args.project,
+                parsed_args.project_domain,
+            ).id
+
+        if parsed_args.user:
+            if compute_client.api_version < api_versions.APIVersion('2.80'):
+                msg = _(
+                    '--os-compute-api-version 2.80 or greater is required to '
+                    'support the --user option'
+                )
+                raise exceptions.CommandError(msg)
+
+            search_opts['user_id'] = identity_common.find_user(
+                identity_client,
+                parsed_args.user,
+                parsed_args.user_domain,
+            ).id
+
+        migrations = compute_client.migrations.list(**search_opts)
+
+        return self.print_migrations(parsed_args, compute_client, migrations)
+
+
+def _get_migration_by_uuid(compute_client, server_id, migration_uuid):
+    for migration in compute_client.server_migrations.list(server_id):
+        if migration.uuid == migration_uuid:
+            return migration
+            break
+    else:
+        msg = _(
+            'In-progress live migration %s is not found for server %s.'
+        )
+        raise exceptions.CommandError(msg % (migration_uuid, server_id))
+
+
+class ShowMigration(command.ShowOne):
+    """Show an in-progress live migration for a given server.
+
+    Note that it is not possible to show cold migrations or completed
+    live-migrations. Use 'openstack server migration list' to get details for
+    these.
+    """
+
+    def get_parser(self, prog_name):
+        parser = super().get_parser(prog_name)
+        parser.add_argument(
+            'server',
+            metavar='<server>',
+            help=_('Server (name or ID)'),
+        )
+        parser.add_argument(
+            'migration',
+            metavar='<migration>',
+            help=_("Migration (ID)"),
+        )
+        return parser
+
+    def take_action(self, parsed_args):
+        compute_client = self.app.client_manager.compute
+
+        if compute_client.api_version < api_versions.APIVersion('2.24'):
+            msg = _(
+                '--os-compute-api-version 2.24 or greater is required to '
+                'support the server migration show command'
+            )
+            raise exceptions.CommandError(msg)
+
+        if not parsed_args.migration.isdigit():
+            try:
+                uuid.UUID(parsed_args.migration)
+            except ValueError:
+                msg = _(
+                    'The <migration> argument must be an ID or UUID'
+                )
+                raise exceptions.CommandError(msg)
+
+            if compute_client.api_version < api_versions.APIVersion('2.59'):
+                msg = _(
+                    '--os-compute-api-version 2.59 or greater is required to '
+                    'retrieve server migrations by UUID'
+                )
+                raise exceptions.CommandError(msg)
+
+        server = utils.find_resource(
+            compute_client.servers,
+            parsed_args.server,
+        )
+
+        # the nova API doesn't currently allow retrieval by UUID but it's a
+        # reasonably common operation so emulate this behavior by listing
+        # migrations - the responses are identical
+        if not parsed_args.migration.isdigit():
+            server_migration = _get_migration_by_uuid(
+                compute_client, server.id, parsed_args.migration,
+            )
+        else:
+            server_migration = compute_client.server_migrations.get(
+                server.id, parsed_args.migration,
+            )
+
+        columns = (
+            'ID',
+            'Server UUID',
+            'Status',
+            'Source Compute',
+            'Source Node',
+            'Dest Compute',
+            'Dest Host',
+            'Dest Node',
+            'Memory Total Bytes',
+            'Memory Processed Bytes',
+            'Memory Remaining Bytes',
+            'Disk Total Bytes',
+            'Disk Processed Bytes',
+            'Disk Remaining Bytes',
+            'Created At',
+            'Updated At',
+        )
+
+        if compute_client.api_version >= api_versions.APIVersion('2.59'):
+            columns += ('UUID',)
+
+        if compute_client.api_version >= api_versions.APIVersion('2.80'):
+            columns += ('User ID', 'Project ID')
+
+        data = utils.get_item_properties(server_migration, columns)
+        return columns, data
+
+
+class AbortMigration(command.Command):
+    """Cancel an ongoing live migration.
+
+    This command requires ``--os-compute-api-version`` 2.24 or greater.
+    """
+
+    def get_parser(self, prog_name):
+        parser = super(AbortMigration, self).get_parser(prog_name)
+        parser.add_argument(
+            'server',
+            metavar='<server>',
+            help=_('Server (name or ID)'),
+        )
+        parser.add_argument(
+            'migration',
+            metavar='<migration>',
+            help=_("Migration (ID)"),
+        )
+        return parser
+
+    def take_action(self, parsed_args):
+        compute_client = self.app.client_manager.compute
+
+        if compute_client.api_version < api_versions.APIVersion('2.24'):
+            msg = _(
+                '--os-compute-api-version 2.24 or greater is required to '
+                'support the server migration abort command'
+            )
+            raise exceptions.CommandError(msg)
+
+        if not parsed_args.migration.isdigit():
+            try:
+                uuid.UUID(parsed_args.migration)
+            except ValueError:
+                msg = _(
+                    'The <migration> argument must be an ID or UUID'
+                )
+                raise exceptions.CommandError(msg)
+
+            if compute_client.api_version < api_versions.APIVersion('2.59'):
+                msg = _(
+                    '--os-compute-api-version 2.59 or greater is required to '
+                    'abort server migrations by UUID'
+                )
+                raise exceptions.CommandError(msg)
+
+        server = utils.find_resource(
+            compute_client.servers,
+            parsed_args.server,
+        )
+
+        # the nova API doesn't currently allow retrieval by UUID but it's a
+        # reasonably common operation so emulate this behavior by listing
+        # migrations - the responses are identical
+        migration_id = parsed_args.migration
+        if not parsed_args.migration.isdigit():
+            migration_id = _get_migration_by_uuid(
+                compute_client, server.id, parsed_args.migration,
+            ).id
+
+        compute_client.server_migrations.live_migration_abort(
+            server.id, migration_id,
+        )
+
+
+class ForceCompleteMigration(command.Command):
+    """Force an ongoing live migration to complete.
+
+    This command requires ``--os-compute-api-version`` 2.22 or greater.
+    """
+
+    def get_parser(self, prog_name):
+        parser = super(ForceCompleteMigration, self).get_parser(prog_name)
+        parser.add_argument(
+            'server',
+            metavar='<server>',
+            help=_('Server (name or ID)'),
+        )
+        parser.add_argument(
+            'migration',
+            metavar='<migration>',
+            help=_('Migration (ID)')
+        )
+        return parser
+
+    def take_action(self, parsed_args):
+        compute_client = self.app.client_manager.compute
+
+        if compute_client.api_version < api_versions.APIVersion('2.22'):
+            msg = _(
+                '--os-compute-api-version 2.22 or greater is required to '
+                'support the server migration force complete command'
+            )
+            raise exceptions.CommandError(msg)
+
+        if not parsed_args.migration.isdigit():
+            try:
+                uuid.UUID(parsed_args.migration)
+            except ValueError:
+                msg = _(
+                    'The <migration> argument must be an ID or UUID'
+                )
+                raise exceptions.CommandError(msg)
+
+            if compute_client.api_version < api_versions.APIVersion('2.59'):
+                msg = _(
+                    '--os-compute-api-version 2.59 or greater is required to '
+                    'abort server migrations by UUID'
+                )
+                raise exceptions.CommandError(msg)
+
+        server = utils.find_resource(
+            compute_client.servers,
+            parsed_args.server,
+        )
+
+        # the nova API doesn't currently allow retrieval by UUID but it's a
+        # reasonably common operation so emulate this behavior by listing
+        # migrations - the responses are identical
+        migration_id = parsed_args.migration
+        if not parsed_args.migration.isdigit():
+            migration_id = _get_migration_by_uuid(
+                compute_client, server.id, parsed_args.migration,
+            ).id
+
+        compute_client.server_migrations.live_migrate_force_complete(
+            server.id, migration_id,
+        )
diff --git a/openstackclient/tests/unit/compute/v2/test_server.py b/openstackclient/tests/unit/compute/v2/test_server.py
index e1002d2806..188781097b 100644
--- a/openstackclient/tests/unit/compute/v2/test_server.py
+++ b/openstackclient/tests/unit/compute/v2/test_server.py
@@ -31,7 +31,6 @@ from osc_lib import utils as common_utils
 
 from openstackclient.compute.v2 import server
 from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes
-from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
 from openstackclient.tests.unit.image.v2 import fakes as image_fakes
 from openstackclient.tests.unit.network.v2 import fakes as network_fakes
 from openstackclient.tests.unit import utils
@@ -5559,990 +5558,6 @@ class TestServerMigrate(TestServer):
         self.assertNotCalled(self.servers_mock.live_migrate)
 
 
-class TestListMigration(TestServer):
-    """Test fetch all migrations."""
-
-    MIGRATION_COLUMNS = [
-        'Source Node', 'Dest Node', 'Source Compute',
-        'Dest Compute', 'Dest Host', 'Status', 'Server UUID',
-        'Old Flavor', 'New Flavor', 'Created At', 'Updated At'
-    ]
-
-    # These are the fields that come back in the response from the REST API.
-    MIGRATION_FIELDS = [
-        'source_node', 'dest_node', 'source_compute', 'dest_compute',
-        'dest_host', 'status', 'instance_uuid', 'old_instance_type_id',
-        'new_instance_type_id', 'created_at', 'updated_at'
-    ]
-
-    def setUp(self):
-        super(TestListMigration, self).setUp()
-
-        self.server = compute_fakes.FakeServer.create_one_server()
-        self.servers_mock.get.return_value = self.server
-
-        self.migrations = compute_fakes.FakeMigration.create_migrations(
-            count=3)
-        self.migrations_mock.list.return_value = self.migrations
-
-        self.data = (common_utils.get_item_properties(
-            s, self.MIGRATION_FIELDS) for s in self.migrations)
-
-        # Get the command object to test
-        self.cmd = server.ListMigration(self.app, None)
-
-    def test_server_migration_list_no_options(self):
-        arglist = []
-        verifylist = []
-
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        columns, data = self.cmd.take_action(parsed_args)
-
-        # Set expected values
-        kwargs = {
-            'status': None,
-            'host': None,
-        }
-
-        self.migrations_mock.list.assert_called_with(**kwargs)
-
-        self.assertEqual(self.MIGRATION_COLUMNS, columns)
-        self.assertEqual(tuple(self.data), tuple(data))
-
-    def test_server_migration_list(self):
-        arglist = [
-            '--server', 'server1',
-            '--host', 'host1',
-            '--status', 'migrating',
-            '--type', 'cold-migration',
-        ]
-        verifylist = [
-            ('server', 'server1'),
-            ('host', 'host1'),
-            ('status', 'migrating'),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        columns, data = self.cmd.take_action(parsed_args)
-
-        # Set expected values
-        kwargs = {
-            'status': 'migrating',
-            'host': 'host1',
-            'instance_uuid': self.server.id,
-            'migration_type': 'migration',
-        }
-
-        self.servers_mock.get.assert_called_with('server1')
-        self.migrations_mock.list.assert_called_with(**kwargs)
-
-        self.assertEqual(self.MIGRATION_COLUMNS, columns)
-        self.assertEqual(tuple(self.data), tuple(data))
-
-
-class TestListMigrationV223(TestListMigration):
-    """Test fetch all migrations. """
-
-    MIGRATION_COLUMNS = [
-        'Id', 'Source Node', 'Dest Node', 'Source Compute', 'Dest Compute',
-        'Dest Host', 'Status', 'Server UUID', 'Old Flavor', 'New Flavor',
-        'Type', 'Created At', 'Updated At'
-    ]
-
-    # These are the fields that come back in the response from the REST API.
-    MIGRATION_FIELDS = [
-        'id', 'source_node', 'dest_node', 'source_compute', 'dest_compute',
-        'dest_host', 'status', 'instance_uuid', 'old_instance_type_id',
-        'new_instance_type_id', 'migration_type', 'created_at', 'updated_at'
-    ]
-
-    def setUp(self):
-        super(TestListMigrationV223, self).setUp()
-
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.23')
-
-    def test_server_migration_list(self):
-        arglist = [
-            '--status', 'migrating'
-        ]
-        verifylist = [
-            ('status', 'migrating')
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        columns, data = self.cmd.take_action(parsed_args)
-
-        # Set expected values
-        kwargs = {
-            'status': 'migrating',
-            'host': None,
-        }
-
-        self.migrations_mock.list.assert_called_with(**kwargs)
-
-        self.assertEqual(self.MIGRATION_COLUMNS, columns)
-        self.assertEqual(tuple(self.data), tuple(data))
-
-
-class TestListMigrationV259(TestListMigration):
-    """Test fetch all migrations. """
-
-    MIGRATION_COLUMNS = [
-        'Id', 'UUID', 'Source Node', 'Dest Node', 'Source Compute',
-        'Dest Compute', 'Dest Host', 'Status', 'Server UUID',
-        'Old Flavor', 'New Flavor', 'Type', 'Created At', 'Updated At'
-    ]
-
-    # These are the fields that come back in the response from the REST API.
-    MIGRATION_FIELDS = [
-        'id', 'uuid', 'source_node', 'dest_node', 'source_compute',
-        'dest_compute', 'dest_host', 'status', 'instance_uuid',
-        'old_instance_type_id', 'new_instance_type_id', 'migration_type',
-        'created_at', 'updated_at'
-    ]
-
-    def setUp(self):
-        super(TestListMigrationV259, self).setUp()
-
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.59')
-
-    def test_server_migration_list(self):
-        arglist = [
-            '--status', 'migrating',
-            '--limit', '1',
-            '--marker', 'test_kp',
-            '--changes-since', '2019-08-09T08:03:25Z'
-        ]
-        verifylist = [
-            ('status', 'migrating'),
-            ('limit', 1),
-            ('marker', 'test_kp'),
-            ('changes_since', '2019-08-09T08:03:25Z')
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        columns, data = self.cmd.take_action(parsed_args)
-
-        # Set expected values
-        kwargs = {
-            'status': 'migrating',
-            'limit': 1,
-            'marker': 'test_kp',
-            'host': None,
-            'changes_since': '2019-08-09T08:03:25Z',
-        }
-
-        self.migrations_mock.list.assert_called_with(**kwargs)
-
-        self.assertEqual(self.MIGRATION_COLUMNS, columns)
-        self.assertEqual(tuple(self.data), tuple(data))
-
-    def test_server_migration_list_with_limit_pre_v259(self):
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.58')
-        arglist = [
-            '--status', 'migrating',
-            '--limit', '1'
-        ]
-        verifylist = [
-            ('status', 'migrating'),
-            ('limit', 1)
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        ex = self.assertRaises(
-            exceptions.CommandError,
-            self.cmd.take_action,
-            parsed_args)
-        self.assertIn(
-            '--os-compute-api-version 2.59 or greater is required',
-            str(ex))
-
-    def test_server_migration_list_with_marker_pre_v259(self):
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.58')
-        arglist = [
-            '--status', 'migrating',
-            '--marker', 'test_kp'
-        ]
-        verifylist = [
-            ('status', 'migrating'),
-            ('marker', 'test_kp')
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        ex = self.assertRaises(
-            exceptions.CommandError,
-            self.cmd.take_action,
-            parsed_args)
-        self.assertIn(
-            '--os-compute-api-version 2.59 or greater is required',
-            str(ex))
-
-    def test_server_migration_list_with_changes_since_pre_v259(self):
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.58')
-        arglist = [
-            '--status', 'migrating',
-            '--changes-since', '2019-08-09T08:03:25Z'
-        ]
-        verifylist = [
-            ('status', 'migrating'),
-            ('changes_since', '2019-08-09T08:03:25Z')
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        ex = self.assertRaises(
-            exceptions.CommandError,
-            self.cmd.take_action,
-            parsed_args)
-        self.assertIn(
-            '--os-compute-api-version 2.59 or greater is required',
-            str(ex))
-
-
-class TestListMigrationV266(TestListMigration):
-    """Test fetch all migrations by changes-before. """
-
-    MIGRATION_COLUMNS = [
-        'Id', 'UUID', 'Source Node', 'Dest Node', 'Source Compute',
-        'Dest Compute', 'Dest Host', 'Status', 'Server UUID',
-        'Old Flavor', 'New Flavor', 'Type', 'Created At', 'Updated At'
-    ]
-
-    # These are the fields that come back in the response from the REST API.
-    MIGRATION_FIELDS = [
-        'id', 'uuid', 'source_node', 'dest_node', 'source_compute',
-        'dest_compute', 'dest_host', 'status', 'instance_uuid',
-        'old_instance_type_id', 'new_instance_type_id', 'migration_type',
-        'created_at', 'updated_at'
-    ]
-
-    def setUp(self):
-        super(TestListMigrationV266, self).setUp()
-
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.66')
-
-    def test_server_migration_list_with_changes_before(self):
-        arglist = [
-            '--status', 'migrating',
-            '--limit', '1',
-            '--marker', 'test_kp',
-            '--changes-since', '2019-08-07T08:03:25Z',
-            '--changes-before', '2019-08-09T08:03:25Z'
-        ]
-        verifylist = [
-            ('status', 'migrating'),
-            ('limit', 1),
-            ('marker', 'test_kp'),
-            ('changes_since', '2019-08-07T08:03:25Z'),
-            ('changes_before', '2019-08-09T08:03:25Z')
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        columns, data = self.cmd.take_action(parsed_args)
-
-        # Set expected values
-        kwargs = {
-            'status': 'migrating',
-            'limit': 1,
-            'marker': 'test_kp',
-            'host': None,
-            'changes_since': '2019-08-07T08:03:25Z',
-            'changes_before': '2019-08-09T08:03:25Z',
-        }
-
-        self.migrations_mock.list.assert_called_with(**kwargs)
-
-        self.assertEqual(self.MIGRATION_COLUMNS, columns)
-        self.assertEqual(tuple(self.data), tuple(data))
-
-    def test_server_migration_list_with_changes_before_pre_v266(self):
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.65')
-        arglist = [
-            '--status', 'migrating',
-            '--changes-before', '2019-08-09T08:03:25Z'
-        ]
-        verifylist = [
-            ('status', 'migrating'),
-            ('changes_before', '2019-08-09T08:03:25Z')
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        ex = self.assertRaises(
-            exceptions.CommandError,
-            self.cmd.take_action,
-            parsed_args)
-        self.assertIn(
-            '--os-compute-api-version 2.66 or greater is required',
-            str(ex))
-
-
-class TestListMigrationV280(TestListMigration):
-    """Test fetch all migrations by user-id and/or project-id. """
-
-    MIGRATION_COLUMNS = [
-        'Id', 'UUID', 'Source Node', 'Dest Node', 'Source Compute',
-        'Dest Compute', 'Dest Host', 'Status', 'Server UUID',
-        'Old Flavor', 'New Flavor', 'Type', 'Created At', 'Updated At'
-    ]
-
-    # These are the fields that come back in the response from the REST API.
-    MIGRATION_FIELDS = [
-        'id', 'uuid', 'source_node', 'dest_node', 'source_compute',
-        'dest_compute', 'dest_host', 'status', 'instance_uuid',
-        'old_instance_type_id', 'new_instance_type_id', 'migration_type',
-        'created_at', 'updated_at'
-    ]
-
-    project = identity_fakes.FakeProject.create_one_project()
-    user = identity_fakes.FakeUser.create_one_user()
-
-    def setUp(self):
-        super(TestListMigrationV280, self).setUp()
-
-        self.projects_mock = self.app.client_manager.identity.projects
-        self.projects_mock.reset_mock()
-
-        self.users_mock = self.app.client_manager.identity.users
-        self.users_mock.reset_mock()
-
-        self.projects_mock.get.return_value = self.project
-        self.users_mock.get.return_value = self.user
-
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.80')
-
-    def test_server_migration_list_with_project(self):
-        arglist = [
-            '--status', 'migrating',
-            '--limit', '1',
-            '--marker', 'test_kp',
-            '--changes-since', '2019-08-07T08:03:25Z',
-            '--changes-before', '2019-08-09T08:03:25Z',
-            '--project', self.project.id
-        ]
-        verifylist = [
-            ('status', 'migrating'),
-            ('limit', 1),
-            ('marker', 'test_kp'),
-            ('changes_since', '2019-08-07T08:03:25Z'),
-            ('changes_before', '2019-08-09T08:03:25Z'),
-            ('project', self.project.id)
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        columns, data = self.cmd.take_action(parsed_args)
-
-        # Set expected values
-        kwargs = {
-            'status': 'migrating',
-            'limit': 1,
-            'marker': 'test_kp',
-            'host': None,
-            'project_id': self.project.id,
-            'changes_since': '2019-08-07T08:03:25Z',
-            'changes_before': "2019-08-09T08:03:25Z",
-        }
-
-        self.migrations_mock.list.assert_called_with(**kwargs)
-
-        self.MIGRATION_COLUMNS.insert(
-            len(self.MIGRATION_COLUMNS) - 2, "Project")
-        self.MIGRATION_FIELDS.insert(
-            len(self.MIGRATION_FIELDS) - 2, "project_id")
-        self.assertEqual(self.MIGRATION_COLUMNS, columns)
-        self.assertEqual(tuple(self.data), tuple(data))
-        # Clean up global variables MIGRATION_COLUMNS
-        self.MIGRATION_COLUMNS.remove('Project')
-        # Clean up global variables MIGRATION_FIELDS
-        self.MIGRATION_FIELDS.remove('project_id')
-
-    def test_get_migrations_with_project_pre_v280(self):
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.79')
-        arglist = [
-            '--status', 'migrating',
-            '--changes-before', '2019-08-09T08:03:25Z',
-            '--project', '0c2accde-644a-45fa-8c10-e76debc7fbc3'
-        ]
-        verifylist = [
-            ('status', 'migrating'),
-            ('changes_before', '2019-08-09T08:03:25Z'),
-            ('project', '0c2accde-644a-45fa-8c10-e76debc7fbc3')
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        ex = self.assertRaises(
-            exceptions.CommandError,
-            self.cmd.take_action,
-            parsed_args)
-        self.assertIn(
-            '--os-compute-api-version 2.80 or greater is required',
-            str(ex))
-
-    def test_server_migration_list_with_user(self):
-        arglist = [
-            '--status', 'migrating',
-            '--limit', '1',
-            '--marker', 'test_kp',
-            '--changes-since', '2019-08-07T08:03:25Z',
-            '--changes-before', '2019-08-09T08:03:25Z',
-            '--user', self.user.id,
-        ]
-        verifylist = [
-            ('status', 'migrating'),
-            ('limit', 1),
-            ('marker', 'test_kp'),
-            ('changes_since', '2019-08-07T08:03:25Z'),
-            ('changes_before', '2019-08-09T08:03:25Z'),
-            ('user', self.user.id),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        columns, data = self.cmd.take_action(parsed_args)
-
-        # Set expected values
-        kwargs = {
-            'status': 'migrating',
-            'limit': 1,
-            'marker': 'test_kp',
-            'host': None,
-            'user_id': self.user.id,
-            'changes_since': '2019-08-07T08:03:25Z',
-            'changes_before': "2019-08-09T08:03:25Z",
-        }
-
-        self.migrations_mock.list.assert_called_with(**kwargs)
-
-        self.MIGRATION_COLUMNS.insert(
-            len(self.MIGRATION_COLUMNS) - 2, "User")
-        self.MIGRATION_FIELDS.insert(
-            len(self.MIGRATION_FIELDS) - 2, "user_id")
-        self.assertEqual(self.MIGRATION_COLUMNS, columns)
-        self.assertEqual(tuple(self.data), tuple(data))
-        # Clean up global variables MIGRATION_COLUMNS
-        self.MIGRATION_COLUMNS.remove('User')
-        # Clean up global variables MIGRATION_FIELDS
-        self.MIGRATION_FIELDS.remove('user_id')
-
-    def test_get_migrations_with_user_pre_v280(self):
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.79')
-        arglist = [
-            '--status', 'migrating',
-            '--changes-before', '2019-08-09T08:03:25Z',
-            '--user', self.user.id,
-        ]
-        verifylist = [
-            ('status', 'migrating'),
-            ('changes_before', '2019-08-09T08:03:25Z'),
-            ('user', self.user.id),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        ex = self.assertRaises(
-            exceptions.CommandError,
-            self.cmd.take_action,
-            parsed_args)
-        self.assertIn(
-            '--os-compute-api-version 2.80 or greater is required',
-            str(ex))
-
-    def test_server_migration_list_with_project_and_user(self):
-        arglist = [
-            '--status', 'migrating',
-            '--limit', '1',
-            '--changes-since', '2019-08-07T08:03:25Z',
-            '--changes-before', '2019-08-09T08:03:25Z',
-            '--project', self.project.id,
-            '--user', self.user.id,
-        ]
-        verifylist = [
-            ('status', 'migrating'),
-            ('limit', 1),
-            ('changes_since', '2019-08-07T08:03:25Z'),
-            ('changes_before', '2019-08-09T08:03:25Z'),
-            ('project', self.project.id),
-            ('user', self.user.id),
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        columns, data = self.cmd.take_action(parsed_args)
-
-        # Set expected values
-        kwargs = {
-            'status': 'migrating',
-            'limit': 1,
-            'host': None,
-            'project_id': self.project.id,
-            'user_id': self.user.id,
-            'changes_since': '2019-08-07T08:03:25Z',
-            'changes_before': "2019-08-09T08:03:25Z",
-        }
-
-        self.migrations_mock.list.assert_called_with(**kwargs)
-
-        self.MIGRATION_COLUMNS.insert(
-            len(self.MIGRATION_COLUMNS) - 2, "Project")
-        self.MIGRATION_FIELDS.insert(
-            len(self.MIGRATION_FIELDS) - 2, "project_id")
-        self.MIGRATION_COLUMNS.insert(
-            len(self.MIGRATION_COLUMNS) - 2, "User")
-        self.MIGRATION_FIELDS.insert(
-            len(self.MIGRATION_FIELDS) - 2, "user_id")
-        self.assertEqual(self.MIGRATION_COLUMNS, columns)
-        self.assertEqual(tuple(self.data), tuple(data))
-        # Clean up global variables MIGRATION_COLUMNS
-        self.MIGRATION_COLUMNS.remove('Project')
-        self.MIGRATION_FIELDS.remove('project_id')
-        self.MIGRATION_COLUMNS.remove('User')
-        self.MIGRATION_FIELDS.remove('user_id')
-
-    def test_get_migrations_with_project_and_user_pre_v280(self):
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.79')
-        arglist = [
-            '--status', 'migrating',
-            '--changes-before', '2019-08-09T08:03:25Z',
-            '--project', self.project.id,
-            '--user', self.user.id,
-        ]
-        verifylist = [
-            ('status', 'migrating'),
-            ('changes_before', '2019-08-09T08:03:25Z'),
-            ('project', self.project.id),
-            ('user', self.user.id)
-        ]
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        ex = self.assertRaises(
-            exceptions.CommandError,
-            self.cmd.take_action,
-            parsed_args)
-        self.assertIn(
-            '--os-compute-api-version 2.80 or greater is required',
-            str(ex))
-
-
-class TestServerMigrationShow(TestServer):
-
-    def setUp(self):
-        super().setUp()
-
-        self.server = compute_fakes.FakeServer.create_one_server()
-        self.servers_mock.get.return_value = self.server
-
-        self.server_migration = compute_fakes.FakeServerMigration\
-            .create_one_server_migration()
-        self.server_migrations_mock.get.return_value = self.server_migration
-
-        self.columns = (
-            'ID',
-            'Server UUID',
-            'Status',
-            'Source Compute',
-            'Source Node',
-            'Dest Compute',
-            'Dest Host',
-            'Dest Node',
-            'Memory Total Bytes',
-            'Memory Processed Bytes',
-            'Memory Remaining Bytes',
-            'Disk Total Bytes',
-            'Disk Processed Bytes',
-            'Disk Remaining Bytes',
-            'Created At',
-            'Updated At',
-        )
-
-        self.data = (
-            self.server_migration.id,
-            self.server_migration.server_uuid,
-            self.server_migration.status,
-            self.server_migration.source_compute,
-            self.server_migration.source_node,
-            self.server_migration.dest_compute,
-            self.server_migration.dest_host,
-            self.server_migration.dest_node,
-            self.server_migration.memory_total_bytes,
-            self.server_migration.memory_processed_bytes,
-            self.server_migration.memory_remaining_bytes,
-            self.server_migration.disk_total_bytes,
-            self.server_migration.disk_processed_bytes,
-            self.server_migration.disk_remaining_bytes,
-            self.server_migration.created_at,
-            self.server_migration.updated_at,
-        )
-
-        # Get the command object to test
-        self.cmd = server.ShowMigration(self.app, None)
-
-    def _test_server_migration_show(self):
-        arglist = [
-            self.server.id,
-            '2',  # arbitrary migration ID
-        ]
-        verifylist = []
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-
-        self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
-
-        self.servers_mock.get.assert_called_with(self.server.id)
-        self.server_migrations_mock.get.assert_called_with(
-            self.server.id, '2',)
-
-    def test_server_migration_show(self):
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.24')
-
-        self._test_server_migration_show()
-
-    def test_server_migration_show_v259(self):
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.59')
-
-        self.columns += ('UUID',)
-        self.data += (self.server_migration.uuid,)
-
-        self._test_server_migration_show()
-
-    def test_server_migration_show_v280(self):
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.80')
-
-        self.columns += ('UUID', 'User ID', 'Project ID')
-        self.data += (
-            self.server_migration.uuid,
-            self.server_migration.user_id,
-            self.server_migration.project_id,
-        )
-
-        self._test_server_migration_show()
-
-    def test_server_migration_show_pre_v224(self):
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.23')
-
-        arglist = [
-            self.server.id,
-            '2',  # arbitrary migration ID
-        ]
-        verifylist = []
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        ex = self.assertRaises(
-            exceptions.CommandError,
-            self.cmd.take_action,
-            parsed_args)
-        self.assertIn(
-            '--os-compute-api-version 2.24 or greater is required',
-            str(ex))
-
-    def test_server_migration_show_by_uuid(self):
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.59')
-        self.server_migrations_mock.list.return_value = [self.server_migration]
-
-        self.columns += ('UUID',)
-        self.data += (self.server_migration.uuid,)
-
-        arglist = [
-            self.server.id,
-            self.server_migration.uuid,  # arbitrary migration UUID
-        ]
-        verifylist = []
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        columns, data = self.cmd.take_action(parsed_args)
-
-        self.assertEqual(self.columns, columns)
-        self.assertEqual(self.data, data)
-
-        self.servers_mock.get.assert_called_with(self.server.id)
-        self.server_migrations_mock.list.assert_called_with(self.server.id)
-        self.server_migrations_mock.get.assert_not_called()
-
-    def test_server_migration_show_by_uuid_no_matches(self):
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.59')
-        self.server_migrations_mock.list.return_value = []
-
-        arglist = [
-            self.server.id,
-            '69f95745-bfe3-4302-90f7-5b0022cba1ce',  # arbitrary migration UUID
-        ]
-        verifylist = []
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        ex = self.assertRaises(
-            exceptions.CommandError,
-            self.cmd.take_action,
-            parsed_args)
-        self.assertIn(
-            'In-progress live migration 69f95745-bfe3-4302-90f7-5b0022cba1ce',
-            str(ex))
-
-    def test_server_migration_show_by_uuid_pre_v259(self):
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.58')
-
-        arglist = [
-            self.server.id,
-            '69f95745-bfe3-4302-90f7-5b0022cba1ce',  # arbitrary migration UUID
-        ]
-        verifylist = []
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        ex = self.assertRaises(
-            exceptions.CommandError,
-            self.cmd.take_action,
-            parsed_args)
-        self.assertIn(
-            '--os-compute-api-version 2.59 or greater is required',
-            str(ex))
-
-    def test_server_migration_show_invalid_id(self):
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.24')
-
-        arglist = [
-            self.server.id,
-            'foo',  # invalid migration ID
-        ]
-        verifylist = []
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        ex = self.assertRaises(
-            exceptions.CommandError,
-            self.cmd.take_action,
-            parsed_args)
-        self.assertIn(
-            'The <migration> argument must be an ID or UUID',
-            str(ex))
-
-
-class TestServerMigrationAbort(TestServer):
-
-    def setUp(self):
-        super(TestServerMigrationAbort, self).setUp()
-
-        self.server = compute_fakes.FakeServer.create_one_server()
-
-        # Return value for utils.find_resource for server.
-        self.servers_mock.get.return_value = self.server
-
-        # Get the command object to test
-        self.cmd = server.AbortMigration(self.app, None)
-
-    def test_migration_abort(self):
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.24')
-
-        arglist = [
-            self.server.id,
-            '2',  # arbitrary migration ID
-        ]
-        verifylist = []
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        self.servers_mock.get.assert_called_with(self.server.id)
-        self.server_migrations_mock.live_migration_abort.assert_called_with(
-            self.server.id, '2',)
-        self.assertIsNone(result)
-
-    def test_migration_abort_pre_v224(self):
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.23')
-
-        arglist = [
-            self.server.id,
-            '2',  # arbitrary migration ID
-        ]
-        verifylist = []
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        ex = self.assertRaises(
-            exceptions.CommandError,
-            self.cmd.take_action,
-            parsed_args)
-        self.assertIn(
-            '--os-compute-api-version 2.24 or greater is required',
-            str(ex))
-
-    def test_server_migration_abort_by_uuid(self):
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.59')
-
-        self.server_migration = compute_fakes.FakeServerMigration\
-            .create_one_server_migration()
-        self.server_migrations_mock.list.return_value = [self.server_migration]
-
-        arglist = [
-            self.server.id,
-            self.server_migration.uuid,  # arbitrary migration UUID
-        ]
-        verifylist = []
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        self.servers_mock.get.assert_called_with(self.server.id)
-        self.server_migrations_mock.list.assert_called_with(self.server.id)
-        self.server_migrations_mock.live_migration_abort.assert_called_with(
-            self.server.id, self.server_migration.id)
-        self.assertIsNone(result)
-
-    def test_server_migration_abort_by_uuid_no_matches(self):
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.59')
-
-        self.server_migrations_mock.list.return_value = []
-
-        arglist = [
-            self.server.id,
-            '69f95745-bfe3-4302-90f7-5b0022cba1ce',  # arbitrary migration UUID
-        ]
-        verifylist = []
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        ex = self.assertRaises(
-            exceptions.CommandError,
-            self.cmd.take_action,
-            parsed_args)
-        self.assertIn(
-            'In-progress live migration 69f95745-bfe3-4302-90f7-5b0022cba1ce',
-            str(ex))
-
-    def test_server_migration_abort_by_uuid_pre_v259(self):
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.58')
-
-        arglist = [
-            self.server.id,
-            '69f95745-bfe3-4302-90f7-5b0022cba1ce',  # arbitrary migration UUID
-        ]
-        verifylist = []
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        ex = self.assertRaises(
-            exceptions.CommandError,
-            self.cmd.take_action,
-            parsed_args)
-        self.assertIn(
-            '--os-compute-api-version 2.59 or greater is required',
-            str(ex))
-
-
-class TestServerMigrationForceComplete(TestServer):
-
-    def setUp(self):
-        super(TestServerMigrationForceComplete, self).setUp()
-
-        self.server = compute_fakes.FakeServer.create_one_server()
-
-        # Return value for utils.find_resource for server.
-        self.servers_mock.get.return_value = self.server
-
-        # Get the command object to test
-        self.cmd = server.ForceCompleteMigration(self.app, None)
-
-    def test_migration_force_complete(self):
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.22')
-
-        arglist = [
-            self.server.id,
-            '2',  # arbitrary migration ID
-        ]
-        verifylist = []
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        self.servers_mock.get.assert_called_with(self.server.id)
-        self.server_migrations_mock.live_migrate_force_complete\
-            .assert_called_with(self.server.id, '2',)
-        self.assertIsNone(result)
-
-    def test_migration_force_complete_pre_v222(self):
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.21')
-
-        arglist = [
-            self.server.id,
-            '2',  # arbitrary migration ID
-        ]
-        verifylist = []
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        ex = self.assertRaises(
-            exceptions.CommandError,
-            self.cmd.take_action,
-            parsed_args)
-        self.assertIn(
-            '--os-compute-api-version 2.22 or greater is required',
-            str(ex))
-
-    def test_server_migration_force_complete_by_uuid(self):
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.59')
-
-        self.server_migration = compute_fakes.FakeServerMigration\
-            .create_one_server_migration()
-        self.server_migrations_mock.list.return_value = [self.server_migration]
-
-        arglist = [
-            self.server.id,
-            self.server_migration.uuid,  # arbitrary migration UUID
-        ]
-        verifylist = []
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        result = self.cmd.take_action(parsed_args)
-
-        self.servers_mock.get.assert_called_with(self.server.id)
-        self.server_migrations_mock.list.assert_called_with(self.server.id)
-        self.server_migrations_mock.live_migrate_force_complete\
-            .assert_called_with(self.server.id, self.server_migration.id)
-        self.assertIsNone(result)
-
-    def test_server_migration_force_complete_by_uuid_no_matches(self):
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.59')
-
-        self.server_migrations_mock.list.return_value = []
-
-        arglist = [
-            self.server.id,
-            '69f95745-bfe3-4302-90f7-5b0022cba1ce',  # arbitrary migration UUID
-        ]
-        verifylist = []
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        ex = self.assertRaises(
-            exceptions.CommandError,
-            self.cmd.take_action,
-            parsed_args)
-        self.assertIn(
-            'In-progress live migration 69f95745-bfe3-4302-90f7-5b0022cba1ce',
-            str(ex))
-
-    def test_server_migration_force_complete_by_uuid_pre_v259(self):
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.58')
-
-        arglist = [
-            self.server.id,
-            '69f95745-bfe3-4302-90f7-5b0022cba1ce',  # arbitrary migration UUID
-        ]
-        verifylist = []
-        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-
-        ex = self.assertRaises(
-            exceptions.CommandError,
-            self.cmd.take_action,
-            parsed_args)
-        self.assertIn(
-            '--os-compute-api-version 2.59 or greater is required',
-            str(ex))
-
-
 class TestServerPause(TestServer):
 
     def setUp(self):
diff --git a/openstackclient/tests/unit/compute/v2/test_server_migration.py b/openstackclient/tests/unit/compute/v2/test_server_migration.py
new file mode 100644
index 0000000000..c4cbac47e2
--- /dev/null
+++ b/openstackclient/tests/unit/compute/v2/test_server_migration.py
@@ -0,0 +1,1028 @@
+# 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 unittest import mock
+
+from novaclient import api_versions
+from osc_lib import exceptions
+from osc_lib import utils as common_utils
+
+from openstackclient.compute.v2 import server_migration
+from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes
+from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
+
+
+class TestServerMigration(compute_fakes.TestComputev2):
+
+    def setUp(self):
+        super().setUp()
+
+        # Get a shortcut to the compute client ServerManager Mock
+        self.servers_mock = self.app.client_manager.compute.servers
+        self.servers_mock.reset_mock()
+
+        # Get a shortcut to the compute client ServerMigrationsManager Mock
+        self.server_migrations_mock = \
+            self.app.client_manager.compute.server_migrations
+        self.server_migrations_mock.reset_mock()
+
+        # Get a shortcut to the compute client MigrationManager mock
+        self.migrations_mock = self.app.client_manager.compute.migrations
+        self.migrations_mock.reset_mock()
+
+        self.app.client_manager.sdk_connection = mock.Mock()
+        self.app.client_manager.sdk_connection.compute = mock.Mock()
+        self.sdk_client = self.app.client_manager.sdk_connection.compute
+
+
+class TestListMigration(TestServerMigration):
+    """Test fetch all migrations."""
+
+    MIGRATION_COLUMNS = [
+        'Source Node', 'Dest Node', 'Source Compute',
+        'Dest Compute', 'Dest Host', 'Status', 'Server UUID',
+        'Old Flavor', 'New Flavor', 'Created At', 'Updated At'
+    ]
+
+    # These are the fields that come back in the response from the REST API.
+    MIGRATION_FIELDS = [
+        'source_node', 'dest_node', 'source_compute', 'dest_compute',
+        'dest_host', 'status', 'instance_uuid', 'old_instance_type_id',
+        'new_instance_type_id', 'created_at', 'updated_at'
+    ]
+
+    def setUp(self):
+        super().setUp()
+
+        self.server = compute_fakes.FakeServer.create_one_server()
+        self.servers_mock.get.return_value = self.server
+
+        self.migrations = compute_fakes.FakeMigration.create_migrations(
+            count=3)
+        self.migrations_mock.list.return_value = self.migrations
+
+        self.data = (common_utils.get_item_properties(
+            s, self.MIGRATION_FIELDS) for s in self.migrations)
+
+        # Get the command object to test
+        self.cmd = server_migration.ListMigration(self.app, None)
+
+    def test_server_migration_list_no_options(self):
+        arglist = []
+        verifylist = []
+
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        columns, data = self.cmd.take_action(parsed_args)
+
+        # Set expected values
+        kwargs = {
+            'status': None,
+            'host': None,
+        }
+
+        self.migrations_mock.list.assert_called_with(**kwargs)
+
+        self.assertEqual(self.MIGRATION_COLUMNS, columns)
+        self.assertEqual(tuple(self.data), tuple(data))
+
+    def test_server_migration_list(self):
+        arglist = [
+            '--server', 'server1',
+            '--host', 'host1',
+            '--status', 'migrating',
+            '--type', 'cold-migration',
+        ]
+        verifylist = [
+            ('server', 'server1'),
+            ('host', 'host1'),
+            ('status', 'migrating'),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        columns, data = self.cmd.take_action(parsed_args)
+
+        # Set expected values
+        kwargs = {
+            'status': 'migrating',
+            'host': 'host1',
+            'instance_uuid': self.server.id,
+            'migration_type': 'migration',
+        }
+
+        self.servers_mock.get.assert_called_with('server1')
+        self.migrations_mock.list.assert_called_with(**kwargs)
+
+        self.assertEqual(self.MIGRATION_COLUMNS, columns)
+        self.assertEqual(tuple(self.data), tuple(data))
+
+
+class TestListMigrationV223(TestListMigration):
+    """Test fetch all migrations. """
+
+    MIGRATION_COLUMNS = [
+        'Id', 'Source Node', 'Dest Node', 'Source Compute', 'Dest Compute',
+        'Dest Host', 'Status', 'Server UUID', 'Old Flavor', 'New Flavor',
+        'Type', 'Created At', 'Updated At'
+    ]
+
+    # These are the fields that come back in the response from the REST API.
+    MIGRATION_FIELDS = [
+        'id', 'source_node', 'dest_node', 'source_compute', 'dest_compute',
+        'dest_host', 'status', 'instance_uuid', 'old_instance_type_id',
+        'new_instance_type_id', 'migration_type', 'created_at', 'updated_at'
+    ]
+
+    def setUp(self):
+        super().setUp()
+
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.23')
+
+    def test_server_migration_list(self):
+        arglist = [
+            '--status', 'migrating'
+        ]
+        verifylist = [
+            ('status', 'migrating')
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        columns, data = self.cmd.take_action(parsed_args)
+
+        # Set expected values
+        kwargs = {
+            'status': 'migrating',
+            'host': None,
+        }
+
+        self.migrations_mock.list.assert_called_with(**kwargs)
+
+        self.assertEqual(self.MIGRATION_COLUMNS, columns)
+        self.assertEqual(tuple(self.data), tuple(data))
+
+
+class TestListMigrationV259(TestListMigration):
+    """Test fetch all migrations. """
+
+    MIGRATION_COLUMNS = [
+        'Id', 'UUID', 'Source Node', 'Dest Node', 'Source Compute',
+        'Dest Compute', 'Dest Host', 'Status', 'Server UUID',
+        'Old Flavor', 'New Flavor', 'Type', 'Created At', 'Updated At'
+    ]
+
+    # These are the fields that come back in the response from the REST API.
+    MIGRATION_FIELDS = [
+        'id', 'uuid', 'source_node', 'dest_node', 'source_compute',
+        'dest_compute', 'dest_host', 'status', 'instance_uuid',
+        'old_instance_type_id', 'new_instance_type_id', 'migration_type',
+        'created_at', 'updated_at'
+    ]
+
+    def setUp(self):
+        super().setUp()
+
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.59')
+
+    def test_server_migration_list(self):
+        arglist = [
+            '--status', 'migrating',
+            '--limit', '1',
+            '--marker', 'test_kp',
+            '--changes-since', '2019-08-09T08:03:25Z'
+        ]
+        verifylist = [
+            ('status', 'migrating'),
+            ('limit', 1),
+            ('marker', 'test_kp'),
+            ('changes_since', '2019-08-09T08:03:25Z')
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        columns, data = self.cmd.take_action(parsed_args)
+
+        # Set expected values
+        kwargs = {
+            'status': 'migrating',
+            'limit': 1,
+            'marker': 'test_kp',
+            'host': None,
+            'changes_since': '2019-08-09T08:03:25Z',
+        }
+
+        self.migrations_mock.list.assert_called_with(**kwargs)
+
+        self.assertEqual(self.MIGRATION_COLUMNS, columns)
+        self.assertEqual(tuple(self.data), tuple(data))
+
+    def test_server_migration_list_with_limit_pre_v259(self):
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.58')
+        arglist = [
+            '--status', 'migrating',
+            '--limit', '1'
+        ]
+        verifylist = [
+            ('status', 'migrating'),
+            ('limit', 1)
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        ex = self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args)
+        self.assertIn(
+            '--os-compute-api-version 2.59 or greater is required',
+            str(ex))
+
+    def test_server_migration_list_with_marker_pre_v259(self):
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.58')
+        arglist = [
+            '--status', 'migrating',
+            '--marker', 'test_kp'
+        ]
+        verifylist = [
+            ('status', 'migrating'),
+            ('marker', 'test_kp')
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        ex = self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args)
+        self.assertIn(
+            '--os-compute-api-version 2.59 or greater is required',
+            str(ex))
+
+    def test_server_migration_list_with_changes_since_pre_v259(self):
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.58')
+        arglist = [
+            '--status', 'migrating',
+            '--changes-since', '2019-08-09T08:03:25Z'
+        ]
+        verifylist = [
+            ('status', 'migrating'),
+            ('changes_since', '2019-08-09T08:03:25Z')
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        ex = self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args)
+        self.assertIn(
+            '--os-compute-api-version 2.59 or greater is required',
+            str(ex))
+
+
+class TestListMigrationV266(TestListMigration):
+    """Test fetch all migrations by changes-before. """
+
+    MIGRATION_COLUMNS = [
+        'Id', 'UUID', 'Source Node', 'Dest Node', 'Source Compute',
+        'Dest Compute', 'Dest Host', 'Status', 'Server UUID',
+        'Old Flavor', 'New Flavor', 'Type', 'Created At', 'Updated At'
+    ]
+
+    # These are the fields that come back in the response from the REST API.
+    MIGRATION_FIELDS = [
+        'id', 'uuid', 'source_node', 'dest_node', 'source_compute',
+        'dest_compute', 'dest_host', 'status', 'instance_uuid',
+        'old_instance_type_id', 'new_instance_type_id', 'migration_type',
+        'created_at', 'updated_at'
+    ]
+
+    def setUp(self):
+        super().setUp()
+
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.66')
+
+    def test_server_migration_list_with_changes_before(self):
+        arglist = [
+            '--status', 'migrating',
+            '--limit', '1',
+            '--marker', 'test_kp',
+            '--changes-since', '2019-08-07T08:03:25Z',
+            '--changes-before', '2019-08-09T08:03:25Z'
+        ]
+        verifylist = [
+            ('status', 'migrating'),
+            ('limit', 1),
+            ('marker', 'test_kp'),
+            ('changes_since', '2019-08-07T08:03:25Z'),
+            ('changes_before', '2019-08-09T08:03:25Z')
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        columns, data = self.cmd.take_action(parsed_args)
+
+        # Set expected values
+        kwargs = {
+            'status': 'migrating',
+            'limit': 1,
+            'marker': 'test_kp',
+            'host': None,
+            'changes_since': '2019-08-07T08:03:25Z',
+            'changes_before': '2019-08-09T08:03:25Z',
+        }
+
+        self.migrations_mock.list.assert_called_with(**kwargs)
+
+        self.assertEqual(self.MIGRATION_COLUMNS, columns)
+        self.assertEqual(tuple(self.data), tuple(data))
+
+    def test_server_migration_list_with_changes_before_pre_v266(self):
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.65')
+        arglist = [
+            '--status', 'migrating',
+            '--changes-before', '2019-08-09T08:03:25Z'
+        ]
+        verifylist = [
+            ('status', 'migrating'),
+            ('changes_before', '2019-08-09T08:03:25Z')
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        ex = self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args)
+        self.assertIn(
+            '--os-compute-api-version 2.66 or greater is required',
+            str(ex))
+
+
+class TestListMigrationV280(TestListMigration):
+    """Test fetch all migrations by user-id and/or project-id. """
+
+    MIGRATION_COLUMNS = [
+        'Id', 'UUID', 'Source Node', 'Dest Node', 'Source Compute',
+        'Dest Compute', 'Dest Host', 'Status', 'Server UUID',
+        'Old Flavor', 'New Flavor', 'Type', 'Created At', 'Updated At'
+    ]
+
+    # These are the fields that come back in the response from the REST API.
+    MIGRATION_FIELDS = [
+        'id', 'uuid', 'source_node', 'dest_node', 'source_compute',
+        'dest_compute', 'dest_host', 'status', 'instance_uuid',
+        'old_instance_type_id', 'new_instance_type_id', 'migration_type',
+        'created_at', 'updated_at'
+    ]
+
+    project = identity_fakes.FakeProject.create_one_project()
+    user = identity_fakes.FakeUser.create_one_user()
+
+    def setUp(self):
+        super().setUp()
+
+        self.projects_mock = self.app.client_manager.identity.projects
+        self.projects_mock.reset_mock()
+
+        self.users_mock = self.app.client_manager.identity.users
+        self.users_mock.reset_mock()
+
+        self.projects_mock.get.return_value = self.project
+        self.users_mock.get.return_value = self.user
+
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.80')
+
+    def test_server_migration_list_with_project(self):
+        arglist = [
+            '--status', 'migrating',
+            '--limit', '1',
+            '--marker', 'test_kp',
+            '--changes-since', '2019-08-07T08:03:25Z',
+            '--changes-before', '2019-08-09T08:03:25Z',
+            '--project', self.project.id
+        ]
+        verifylist = [
+            ('status', 'migrating'),
+            ('limit', 1),
+            ('marker', 'test_kp'),
+            ('changes_since', '2019-08-07T08:03:25Z'),
+            ('changes_before', '2019-08-09T08:03:25Z'),
+            ('project', self.project.id)
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        columns, data = self.cmd.take_action(parsed_args)
+
+        # Set expected values
+        kwargs = {
+            'status': 'migrating',
+            'limit': 1,
+            'marker': 'test_kp',
+            'host': None,
+            'project_id': self.project.id,
+            'changes_since': '2019-08-07T08:03:25Z',
+            'changes_before': "2019-08-09T08:03:25Z",
+        }
+
+        self.migrations_mock.list.assert_called_with(**kwargs)
+
+        self.MIGRATION_COLUMNS.insert(
+            len(self.MIGRATION_COLUMNS) - 2, "Project")
+        self.MIGRATION_FIELDS.insert(
+            len(self.MIGRATION_FIELDS) - 2, "project_id")
+        self.assertEqual(self.MIGRATION_COLUMNS, columns)
+        self.assertEqual(tuple(self.data), tuple(data))
+        # Clean up global variables MIGRATION_COLUMNS
+        self.MIGRATION_COLUMNS.remove('Project')
+        # Clean up global variables MIGRATION_FIELDS
+        self.MIGRATION_FIELDS.remove('project_id')
+
+    def test_get_migrations_with_project_pre_v280(self):
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.79')
+        arglist = [
+            '--status', 'migrating',
+            '--changes-before', '2019-08-09T08:03:25Z',
+            '--project', '0c2accde-644a-45fa-8c10-e76debc7fbc3'
+        ]
+        verifylist = [
+            ('status', 'migrating'),
+            ('changes_before', '2019-08-09T08:03:25Z'),
+            ('project', '0c2accde-644a-45fa-8c10-e76debc7fbc3')
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        ex = self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args)
+        self.assertIn(
+            '--os-compute-api-version 2.80 or greater is required',
+            str(ex))
+
+    def test_server_migration_list_with_user(self):
+        arglist = [
+            '--status', 'migrating',
+            '--limit', '1',
+            '--marker', 'test_kp',
+            '--changes-since', '2019-08-07T08:03:25Z',
+            '--changes-before', '2019-08-09T08:03:25Z',
+            '--user', self.user.id,
+        ]
+        verifylist = [
+            ('status', 'migrating'),
+            ('limit', 1),
+            ('marker', 'test_kp'),
+            ('changes_since', '2019-08-07T08:03:25Z'),
+            ('changes_before', '2019-08-09T08:03:25Z'),
+            ('user', self.user.id),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        columns, data = self.cmd.take_action(parsed_args)
+
+        # Set expected values
+        kwargs = {
+            'status': 'migrating',
+            'limit': 1,
+            'marker': 'test_kp',
+            'host': None,
+            'user_id': self.user.id,
+            'changes_since': '2019-08-07T08:03:25Z',
+            'changes_before': "2019-08-09T08:03:25Z",
+        }
+
+        self.migrations_mock.list.assert_called_with(**kwargs)
+
+        self.MIGRATION_COLUMNS.insert(
+            len(self.MIGRATION_COLUMNS) - 2, "User")
+        self.MIGRATION_FIELDS.insert(
+            len(self.MIGRATION_FIELDS) - 2, "user_id")
+        self.assertEqual(self.MIGRATION_COLUMNS, columns)
+        self.assertEqual(tuple(self.data), tuple(data))
+        # Clean up global variables MIGRATION_COLUMNS
+        self.MIGRATION_COLUMNS.remove('User')
+        # Clean up global variables MIGRATION_FIELDS
+        self.MIGRATION_FIELDS.remove('user_id')
+
+    def test_get_migrations_with_user_pre_v280(self):
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.79')
+        arglist = [
+            '--status', 'migrating',
+            '--changes-before', '2019-08-09T08:03:25Z',
+            '--user', self.user.id,
+        ]
+        verifylist = [
+            ('status', 'migrating'),
+            ('changes_before', '2019-08-09T08:03:25Z'),
+            ('user', self.user.id),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        ex = self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args)
+        self.assertIn(
+            '--os-compute-api-version 2.80 or greater is required',
+            str(ex))
+
+    def test_server_migration_list_with_project_and_user(self):
+        arglist = [
+            '--status', 'migrating',
+            '--limit', '1',
+            '--changes-since', '2019-08-07T08:03:25Z',
+            '--changes-before', '2019-08-09T08:03:25Z',
+            '--project', self.project.id,
+            '--user', self.user.id,
+        ]
+        verifylist = [
+            ('status', 'migrating'),
+            ('limit', 1),
+            ('changes_since', '2019-08-07T08:03:25Z'),
+            ('changes_before', '2019-08-09T08:03:25Z'),
+            ('project', self.project.id),
+            ('user', self.user.id),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        columns, data = self.cmd.take_action(parsed_args)
+
+        # Set expected values
+        kwargs = {
+            'status': 'migrating',
+            'limit': 1,
+            'host': None,
+            'project_id': self.project.id,
+            'user_id': self.user.id,
+            'changes_since': '2019-08-07T08:03:25Z',
+            'changes_before': "2019-08-09T08:03:25Z",
+        }
+
+        self.migrations_mock.list.assert_called_with(**kwargs)
+
+        self.MIGRATION_COLUMNS.insert(
+            len(self.MIGRATION_COLUMNS) - 2, "Project")
+        self.MIGRATION_FIELDS.insert(
+            len(self.MIGRATION_FIELDS) - 2, "project_id")
+        self.MIGRATION_COLUMNS.insert(
+            len(self.MIGRATION_COLUMNS) - 2, "User")
+        self.MIGRATION_FIELDS.insert(
+            len(self.MIGRATION_FIELDS) - 2, "user_id")
+        self.assertEqual(self.MIGRATION_COLUMNS, columns)
+        self.assertEqual(tuple(self.data), tuple(data))
+        # Clean up global variables MIGRATION_COLUMNS
+        self.MIGRATION_COLUMNS.remove('Project')
+        self.MIGRATION_FIELDS.remove('project_id')
+        self.MIGRATION_COLUMNS.remove('User')
+        self.MIGRATION_FIELDS.remove('user_id')
+
+    def test_get_migrations_with_project_and_user_pre_v280(self):
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.79')
+        arglist = [
+            '--status', 'migrating',
+            '--changes-before', '2019-08-09T08:03:25Z',
+            '--project', self.project.id,
+            '--user', self.user.id,
+        ]
+        verifylist = [
+            ('status', 'migrating'),
+            ('changes_before', '2019-08-09T08:03:25Z'),
+            ('project', self.project.id),
+            ('user', self.user.id)
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        ex = self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args)
+        self.assertIn(
+            '--os-compute-api-version 2.80 or greater is required',
+            str(ex))
+
+
+class TestServerMigrationShow(TestServerMigration):
+
+    def setUp(self):
+        super().setUp()
+
+        self.server = compute_fakes.FakeServer.create_one_server()
+        self.servers_mock.get.return_value = self.server
+
+        self.server_migration = compute_fakes.FakeServerMigration\
+            .create_one_server_migration()
+        self.server_migrations_mock.get.return_value = self.server_migration
+
+        self.columns = (
+            'ID',
+            'Server UUID',
+            'Status',
+            'Source Compute',
+            'Source Node',
+            'Dest Compute',
+            'Dest Host',
+            'Dest Node',
+            'Memory Total Bytes',
+            'Memory Processed Bytes',
+            'Memory Remaining Bytes',
+            'Disk Total Bytes',
+            'Disk Processed Bytes',
+            'Disk Remaining Bytes',
+            'Created At',
+            'Updated At',
+        )
+
+        self.data = (
+            self.server_migration.id,
+            self.server_migration.server_uuid,
+            self.server_migration.status,
+            self.server_migration.source_compute,
+            self.server_migration.source_node,
+            self.server_migration.dest_compute,
+            self.server_migration.dest_host,
+            self.server_migration.dest_node,
+            self.server_migration.memory_total_bytes,
+            self.server_migration.memory_processed_bytes,
+            self.server_migration.memory_remaining_bytes,
+            self.server_migration.disk_total_bytes,
+            self.server_migration.disk_processed_bytes,
+            self.server_migration.disk_remaining_bytes,
+            self.server_migration.created_at,
+            self.server_migration.updated_at,
+        )
+
+        # Get the command object to test
+        self.cmd = server_migration.ShowMigration(self.app, None)
+
+    def _test_server_migration_show(self):
+        arglist = [
+            self.server.id,
+            '2',  # arbitrary migration ID
+        ]
+        verifylist = []
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
+
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.data, data)
+
+        self.servers_mock.get.assert_called_with(self.server.id)
+        self.server_migrations_mock.get.assert_called_with(
+            self.server.id, '2',)
+
+    def test_server_migration_show(self):
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.24')
+
+        self._test_server_migration_show()
+
+    def test_server_migration_show_v259(self):
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.59')
+
+        self.columns += ('UUID',)
+        self.data += (self.server_migration.uuid,)
+
+        self._test_server_migration_show()
+
+    def test_server_migration_show_v280(self):
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.80')
+
+        self.columns += ('UUID', 'User ID', 'Project ID')
+        self.data += (
+            self.server_migration.uuid,
+            self.server_migration.user_id,
+            self.server_migration.project_id,
+        )
+
+        self._test_server_migration_show()
+
+    def test_server_migration_show_pre_v224(self):
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.23')
+
+        arglist = [
+            self.server.id,
+            '2',  # arbitrary migration ID
+        ]
+        verifylist = []
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        ex = self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args)
+        self.assertIn(
+            '--os-compute-api-version 2.24 or greater is required',
+            str(ex))
+
+    def test_server_migration_show_by_uuid(self):
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.59')
+        self.server_migrations_mock.list.return_value = [self.server_migration]
+
+        self.columns += ('UUID',)
+        self.data += (self.server_migration.uuid,)
+
+        arglist = [
+            self.server.id,
+            self.server_migration.uuid,  # arbitrary migration UUID
+        ]
+        verifylist = []
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
+
+        self.assertEqual(self.columns, columns)
+        self.assertEqual(self.data, data)
+
+        self.servers_mock.get.assert_called_with(self.server.id)
+        self.server_migrations_mock.list.assert_called_with(self.server.id)
+        self.server_migrations_mock.get.assert_not_called()
+
+    def test_server_migration_show_by_uuid_no_matches(self):
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.59')
+        self.server_migrations_mock.list.return_value = []
+
+        arglist = [
+            self.server.id,
+            '69f95745-bfe3-4302-90f7-5b0022cba1ce',  # arbitrary migration UUID
+        ]
+        verifylist = []
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        ex = self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args)
+        self.assertIn(
+            'In-progress live migration 69f95745-bfe3-4302-90f7-5b0022cba1ce',
+            str(ex))
+
+    def test_server_migration_show_by_uuid_pre_v259(self):
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.58')
+
+        arglist = [
+            self.server.id,
+            '69f95745-bfe3-4302-90f7-5b0022cba1ce',  # arbitrary migration UUID
+        ]
+        verifylist = []
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        ex = self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args)
+        self.assertIn(
+            '--os-compute-api-version 2.59 or greater is required',
+            str(ex))
+
+    def test_server_migration_show_invalid_id(self):
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.24')
+
+        arglist = [
+            self.server.id,
+            'foo',  # invalid migration ID
+        ]
+        verifylist = []
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        ex = self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args)
+        self.assertIn(
+            'The <migration> argument must be an ID or UUID',
+            str(ex))
+
+
+class TestServerMigrationAbort(TestServerMigration):
+
+    def setUp(self):
+        super().setUp()
+
+        self.server = compute_fakes.FakeServer.create_one_server()
+
+        # Return value for utils.find_resource for server.
+        self.servers_mock.get.return_value = self.server
+
+        # Get the command object to test
+        self.cmd = server_migration.AbortMigration(self.app, None)
+
+    def test_migration_abort(self):
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.24')
+
+        arglist = [
+            self.server.id,
+            '2',  # arbitrary migration ID
+        ]
+        verifylist = []
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        result = self.cmd.take_action(parsed_args)
+
+        self.servers_mock.get.assert_called_with(self.server.id)
+        self.server_migrations_mock.live_migration_abort.assert_called_with(
+            self.server.id, '2',)
+        self.assertIsNone(result)
+
+    def test_migration_abort_pre_v224(self):
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.23')
+
+        arglist = [
+            self.server.id,
+            '2',  # arbitrary migration ID
+        ]
+        verifylist = []
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        ex = self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args)
+        self.assertIn(
+            '--os-compute-api-version 2.24 or greater is required',
+            str(ex))
+
+    def test_server_migration_abort_by_uuid(self):
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.59')
+
+        self.server_migration = compute_fakes.FakeServerMigration\
+            .create_one_server_migration()
+        self.server_migrations_mock.list.return_value = [self.server_migration]
+
+        arglist = [
+            self.server.id,
+            self.server_migration.uuid,  # arbitrary migration UUID
+        ]
+        verifylist = []
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        result = self.cmd.take_action(parsed_args)
+
+        self.servers_mock.get.assert_called_with(self.server.id)
+        self.server_migrations_mock.list.assert_called_with(self.server.id)
+        self.server_migrations_mock.live_migration_abort.assert_called_with(
+            self.server.id, self.server_migration.id)
+        self.assertIsNone(result)
+
+    def test_server_migration_abort_by_uuid_no_matches(self):
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.59')
+
+        self.server_migrations_mock.list.return_value = []
+
+        arglist = [
+            self.server.id,
+            '69f95745-bfe3-4302-90f7-5b0022cba1ce',  # arbitrary migration UUID
+        ]
+        verifylist = []
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        ex = self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args)
+        self.assertIn(
+            'In-progress live migration 69f95745-bfe3-4302-90f7-5b0022cba1ce',
+            str(ex))
+
+    def test_server_migration_abort_by_uuid_pre_v259(self):
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.58')
+
+        arglist = [
+            self.server.id,
+            '69f95745-bfe3-4302-90f7-5b0022cba1ce',  # arbitrary migration UUID
+        ]
+        verifylist = []
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        ex = self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args)
+        self.assertIn(
+            '--os-compute-api-version 2.59 or greater is required',
+            str(ex))
+
+
+class TestServerMigrationForceComplete(TestServerMigration):
+
+    def setUp(self):
+        super().setUp()
+
+        self.server = compute_fakes.FakeServer.create_one_server()
+
+        # Return value for utils.find_resource for server.
+        self.servers_mock.get.return_value = self.server
+
+        # Get the command object to test
+        self.cmd = server_migration.ForceCompleteMigration(self.app, None)
+
+    def test_migration_force_complete(self):
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.22')
+
+        arglist = [
+            self.server.id,
+            '2',  # arbitrary migration ID
+        ]
+        verifylist = []
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        result = self.cmd.take_action(parsed_args)
+
+        self.servers_mock.get.assert_called_with(self.server.id)
+        self.server_migrations_mock.live_migrate_force_complete\
+            .assert_called_with(self.server.id, '2',)
+        self.assertIsNone(result)
+
+    def test_migration_force_complete_pre_v222(self):
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.21')
+
+        arglist = [
+            self.server.id,
+            '2',  # arbitrary migration ID
+        ]
+        verifylist = []
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        ex = self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args)
+        self.assertIn(
+            '--os-compute-api-version 2.22 or greater is required',
+            str(ex))
+
+    def test_server_migration_force_complete_by_uuid(self):
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.59')
+
+        self.server_migration = compute_fakes.FakeServerMigration\
+            .create_one_server_migration()
+        self.server_migrations_mock.list.return_value = [self.server_migration]
+
+        arglist = [
+            self.server.id,
+            self.server_migration.uuid,  # arbitrary migration UUID
+        ]
+        verifylist = []
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        result = self.cmd.take_action(parsed_args)
+
+        self.servers_mock.get.assert_called_with(self.server.id)
+        self.server_migrations_mock.list.assert_called_with(self.server.id)
+        self.server_migrations_mock.live_migrate_force_complete\
+            .assert_called_with(self.server.id, self.server_migration.id)
+        self.assertIsNone(result)
+
+    def test_server_migration_force_complete_by_uuid_no_matches(self):
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.59')
+
+        self.server_migrations_mock.list.return_value = []
+
+        arglist = [
+            self.server.id,
+            '69f95745-bfe3-4302-90f7-5b0022cba1ce',  # arbitrary migration UUID
+        ]
+        verifylist = []
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        ex = self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args)
+        self.assertIn(
+            'In-progress live migration 69f95745-bfe3-4302-90f7-5b0022cba1ce',
+            str(ex))
+
+    def test_server_migration_force_complete_by_uuid_pre_v259(self):
+        self.app.client_manager.compute.api_version = api_versions.APIVersion(
+            '2.58')
+
+        arglist = [
+            self.server.id,
+            '69f95745-bfe3-4302-90f7-5b0022cba1ce',  # arbitrary migration UUID
+        ]
+        verifylist = []
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        ex = self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args)
+        self.assertIn(
+            '--os-compute-api-version 2.59 or greater is required',
+            str(ex))
diff --git a/setup.cfg b/setup.cfg
index b4718b1fb5..79e805f04e 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -111,12 +111,8 @@ openstack.compute.v2 =
     server_migrate = openstackclient.compute.v2.server:MigrateServer
     server_migrate_confirm = openstackclient.compute.v2.server:MigrateConfirm
     server_migrate_revert = openstackclient.compute.v2.server:MigrateRevert
-    server_migration_abort = openstackclient.compute.v2.server:AbortMigration
     server_migration_confirm = openstackclient.compute.v2.server:ConfirmMigration
-    server_migration_force_complete = openstackclient.compute.v2.server:ForceCompleteMigration
-    server_migration_list = openstackclient.compute.v2.server:ListMigration
     server_migration_revert = openstackclient.compute.v2.server:RevertMigration
-    server_migration_show = openstackclient.compute.v2.server:ShowMigration
     server_pause = openstackclient.compute.v2.server:PauseServer
     server_reboot = openstackclient.compute.v2.server:RebootServer
     server_rebuild = openstackclient.compute.v2.server:RebuildServer
@@ -157,6 +153,11 @@ openstack.compute.v2 =
 
     server_image_create = openstackclient.compute.v2.server_image:CreateServerImage
 
+    server_migration_abort = openstackclient.compute.v2.server_migration:AbortMigration
+    server_migration_force_complete = openstackclient.compute.v2.server_migration:ForceCompleteMigration
+    server_migration_list = openstackclient.compute.v2.server_migration:ListMigration
+    server_migration_show = openstackclient.compute.v2.server_migration:ShowMigration
+
     server_volume_list = openstackclient.compute.v2.server_volume:ListServerVolume
     server_volume_update = openstackclient.compute.v2.server_volume:UpdateServerVolume