summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/compute/v2/server.py102
-rw-r--r--openstackclient/tests/unit/compute/v2/test_server.py208
2 files changed, 305 insertions, 5 deletions
diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py
index 0780c49e..5da1984d 100644
--- a/openstackclient/compute/v2/server.py
+++ b/openstackclient/compute/v2/server.py
@@ -21,6 +21,7 @@ import io
import json
import logging
import os
+import uuid
from cliff import columns as cliff_columns
import iso8601
@@ -3037,6 +3038,18 @@ class ListMigration(command.Lister):
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.
@@ -3069,13 +3082,38 @@ class ShowMigration(command.ShowOne):
)
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,
)
- server_migration = compute_client.server_migrations.get(
- server.id, parsed_args.migration,
- )
+
+ # 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',
@@ -3136,12 +3174,39 @@ class AbortMigration(command.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, parsed_args.migration)
+ server.id, migration_id,
+ )
class ForceCompleteMigration(command.Command):
@@ -3174,12 +3239,39 @@ class ForceCompleteMigration(command.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, parsed_args.migration)
+ server.id, migration_id,
+ )
class PauseServer(command.Command):
diff --git a/openstackclient/tests/unit/compute/v2/test_server.py b/openstackclient/tests/unit/compute/v2/test_server.py
index 480dcfe1..e1002d28 100644
--- a/openstackclient/tests/unit/compute/v2/test_server.py
+++ b/openstackclient/tests/unit/compute/v2/test_server.py
@@ -6232,6 +6232,88 @@ class TestServerMigrationShow(TestServer):
'--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):
@@ -6283,6 +6365,69 @@ class TestServerMigrationAbort(TestServer):
'--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):
@@ -6334,6 +6479,69 @@ class TestServerMigrationForceComplete(TestServer):
'--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):