Merge "Switch server shelve, unshelve to SDK"

This commit is contained in:
Zuul 2023-04-03 20:36:13 +00:00 committed by Gerrit Code Review
commit 5d2687bfc4
3 changed files with 260 additions and 293 deletions

View File

@ -4255,7 +4255,7 @@ class ShelveServer(command.Command):
""" """
def get_parser(self, prog_name): def get_parser(self, prog_name):
parser = super(ShelveServer, self).get_parser(prog_name) parser = super().get_parser(prog_name)
parser.add_argument( parser.add_argument(
'servers', 'servers',
metavar='<server>', metavar='<server>',
@ -4287,17 +4287,17 @@ class ShelveServer(command.Command):
self.app.stdout.write('\rProgress: %s' % progress) self.app.stdout.write('\rProgress: %s' % progress)
self.app.stdout.flush() self.app.stdout.flush()
compute_client = self.app.client_manager.compute compute_client = self.app.client_manager.sdk_connection.compute
for server in parsed_args.servers: for server in parsed_args.servers:
server_obj = utils.find_resource( server_obj = compute_client.find_server(
compute_client.servers,
server, server,
ignore_missing=False,
) )
if server_obj.status.lower() in ('shelved', 'shelved_offloaded'): if server_obj.status.lower() in ('shelved', 'shelved_offloaded'):
continue continue
server_obj.shelve() compute_client.shelve_server(server_obj.id)
# if we don't have to wait, either because it was requested explicitly # if we don't have to wait, either because it was requested explicitly
# or is required implicitly, then our job is done # or is required implicitly, then our job is done
@ -4305,47 +4305,53 @@ class ShelveServer(command.Command):
return return
for server in parsed_args.servers: for server in parsed_args.servers:
# We use osc-lib's wait_for_status since that allows for a callback
# TODO(stephenfin): We should wait for these in parallel using e.g. # TODO(stephenfin): We should wait for these in parallel using e.g.
# https://review.opendev.org/c/openstack/osc-lib/+/762503/ # https://review.opendev.org/c/openstack/osc-lib/+/762503/
if not utils.wait_for_status( if not utils.wait_for_status(
compute_client.servers.get, server_obj.id, compute_client.get_server,
server_obj.id,
success_status=('shelved', 'shelved_offloaded'), success_status=('shelved', 'shelved_offloaded'),
callback=_show_progress, callback=_show_progress,
): ):
LOG.error(_('Error shelving server: %s'), server_obj.id) LOG.error(_('Error shelving server: %s'), server_obj.id)
self.app.stdout.write( self.app.stdout.write(
_('Error shelving server: %s\n') % server_obj.id) _('Error shelving server: %s\n') % server_obj.id
)
raise SystemExit raise SystemExit
if not parsed_args.offload: if not parsed_args.offload:
return return
for server in parsed_args.servers: for server in parsed_args.servers:
server_obj = utils.find_resource( server_obj = compute_client.find_server(
compute_client.servers,
server, server,
ignore_missing=False,
) )
if server_obj.status.lower() == 'shelved_offloaded': if server_obj.status.lower() == 'shelved_offloaded':
continue continue
server_obj.shelve_offload() compute_client.shelve_offload_server(server_obj.id)
if not parsed_args.wait: if not parsed_args.wait:
return return
for server in parsed_args.servers: for server in parsed_args.servers:
# We use osc-lib's wait_for_status since that allows for a callback
# TODO(stephenfin): We should wait for these in parallel using e.g. # TODO(stephenfin): We should wait for these in parallel using e.g.
# https://review.opendev.org/c/openstack/osc-lib/+/762503/ # https://review.opendev.org/c/openstack/osc-lib/+/762503/
if not utils.wait_for_status( if not utils.wait_for_status(
compute_client.servers.get, server_obj.id, compute_client.get_server,
server_obj.id,
success_status=('shelved_offloaded',), success_status=('shelved_offloaded',),
callback=_show_progress, callback=_show_progress,
): ):
LOG.error( LOG.error(
_('Error offloading shelved server %s'), server_obj.id) _('Error offloading shelved server %s'), server_obj.id,
)
self.app.stdout.write( self.app.stdout.write(
_('Error offloading shelved server: %s\n') % ( _('Error offloading shelved server: %s\n') % server_obj.id
server_obj.id)) )
raise SystemExit raise SystemExit
@ -4819,7 +4825,7 @@ class UnshelveServer(command.Command):
_description = _("Unshelve server(s)") _description = _("Unshelve server(s)")
def get_parser(self, prog_name): def get_parser(self, prog_name):
parser = super(UnshelveServer, self).get_parser(prog_name) parser = super().get_parser(prog_name)
parser.add_argument( parser.add_argument(
'server', 'server',
metavar='<server>', metavar='<server>',
@ -4830,25 +4836,31 @@ class UnshelveServer(command.Command):
group.add_argument( group.add_argument(
'--availability-zone', '--availability-zone',
default=None, default=None,
help=_('Name of the availability zone in which to unshelve a ' help=_(
'SHELVED_OFFLOADED server (supported by ' 'Name of the availability zone in which to unshelve a '
'--os-compute-api-version 2.77 or above)'), 'SHELVED_OFFLOADED server '
'(supported by --os-compute-api-version 2.77 or above)'
),
) )
group.add_argument( group.add_argument(
'--no-availability-zone', '--no-availability-zone',
action='store_true', action='store_true',
default=False, default=False,
help=_('Unpin the availability zone of a SHELVED_OFFLOADED ' help=_(
'server. Server will be unshelved on a host without ' 'Unpin the availability zone of a SHELVED_OFFLOADED '
'availability zone constraint (supported by ' 'server. Server will be unshelved on a host without '
'--os-compute-api-version 2.91 or above)'), 'availability zone constraint '
'(supported by --os-compute-api-version 2.91 or above)'
),
) )
parser.add_argument( parser.add_argument(
'--host', '--host',
default=None, default=None,
help=_('Name of the destination host in which to unshelve a ' help=_(
'SHELVED_OFFLOADED server (supported by ' 'Name of the destination host in which to unshelve a '
'--os-compute-api-version 2.91 or above)'), 'SHELVED_OFFLOADED server '
'(supported by --os-compute-api-version 2.91 or above)'
),
) )
parser.add_argument( parser.add_argument(
'--wait', '--wait',
@ -4865,11 +4877,11 @@ class UnshelveServer(command.Command):
self.app.stdout.write('\rProgress: %s' % progress) self.app.stdout.write('\rProgress: %s' % progress)
self.app.stdout.flush() self.app.stdout.flush()
compute_client = self.app.client_manager.compute compute_client = self.app.client_manager.sdk_connection.compute
kwargs = {} kwargs = {}
if parsed_args.availability_zone: if parsed_args.availability_zone:
if compute_client.api_version < api_versions.APIVersion('2.77'): if not sdk_utils.supports_microversion(compute_client, '2.77'):
msg = _( msg = _(
'--os-compute-api-version 2.77 or greater is required ' '--os-compute-api-version 2.77 or greater is required '
'to support the --availability-zone option' 'to support the --availability-zone option'
@ -4879,7 +4891,7 @@ class UnshelveServer(command.Command):
kwargs['availability_zone'] = parsed_args.availability_zone kwargs['availability_zone'] = parsed_args.availability_zone
if parsed_args.host: if parsed_args.host:
if compute_client.api_version < api_versions.APIVersion('2.91'): if not sdk_utils.supports_microversion(compute_client, '2.91'):
msg = _( msg = _(
'--os-compute-api-version 2.91 or greater is required ' '--os-compute-api-version 2.91 or greater is required '
'to support the --host option' 'to support the --host option'
@ -4889,7 +4901,7 @@ class UnshelveServer(command.Command):
kwargs['host'] = parsed_args.host kwargs['host'] = parsed_args.host
if parsed_args.no_availability_zone: if parsed_args.no_availability_zone:
if compute_client.api_version < api_versions.APIVersion('2.91'): if not sdk_utils.supports_microversion(compute_client, '2.91'):
msg = _( msg = _(
'--os-compute-api-version 2.91 or greater is required ' '--os-compute-api-version 2.91 or greater is required '
'to support the --no-availability-zone option' 'to support the --no-availability-zone option'
@ -4899,9 +4911,9 @@ class UnshelveServer(command.Command):
kwargs['availability_zone'] = None kwargs['availability_zone'] = None
for server in parsed_args.server: for server in parsed_args.server:
server_obj = utils.find_resource( server_obj = compute_client.find_server(
compute_client.servers,
server, server,
ignore_missing=False,
) )
if server_obj.status.lower() not in ( if server_obj.status.lower() not in (
@ -4909,15 +4921,17 @@ class UnshelveServer(command.Command):
): ):
continue continue
server_obj.unshelve(**kwargs) compute_client.unshelve_server(server_obj.id, **kwargs)
if parsed_args.wait: if parsed_args.wait:
if not utils.wait_for_status( if not utils.wait_for_status(
compute_client.servers.get, server_obj.id, compute_client.get_server,
server_obj.id,
success_status=('active', 'shutoff'), success_status=('active', 'shutoff'),
callback=_show_progress, callback=_show_progress,
): ):
LOG.error(_('Error unshelving server %s'), server_obj.id) LOG.error(_('Error unshelving server %s'), server_obj.id)
self.app.stdout.write( self.app.stdout.write(
_('Error unshelving server: %s\n') % server_obj.id) _('Error unshelving server: %s\n') % server_obj.id
)
raise SystemExit raise SystemExit

View File

@ -176,10 +176,6 @@ class TestServer(compute_fakes.TestComputev2):
return volumes return volumes
def run_method_with_servers(self, method_name, server_count): def run_method_with_servers(self, method_name, server_count):
# Starting with v2.91, the nova api needs to be call with a sentinel
# as availability_zone=None will unpin the server az.
_sentinel = object()
servers = self.setup_servers_mock(server_count) servers = self.setup_servers_mock(server_count)
arglist = [] arglist = []
@ -196,18 +192,7 @@ class TestServer(compute_fakes.TestComputev2):
for s in servers: for s in servers:
method = getattr(s, method_name) method = getattr(s, method_name)
if method_name == 'unshelve': method.assert_called_with()
version = self.app.client_manager.compute.api_version
if version >= api_versions.APIVersion('2.91'):
method.assert_called_with(availability_zone=_sentinel,
host=None)
elif (version >= api_versions.APIVersion('2.77') and
version < api_versions.APIVersion('2.91')):
method.assert_called_with(availability_zone=None)
else:
method.assert_called_with()
else:
method.assert_called_with()
self.assertIsNone(result) self.assertIsNone(result)
def run_method_with_sdk_servers(self, method_name, server_count): def run_method_with_sdk_servers(self, method_name, server_count):
@ -6742,7 +6727,7 @@ class TestServerRemoveFixedIP(TestServer):
# Get the command object to test # Get the command object to test
self.cmd = server.RemoveFixedIP(self.app, None) self.cmd = server.RemoveFixedIP(self.app, None)
# Set unshelve method to be tested. # Set method to be tested.
self.methods = { self.methods = {
'remove_fixed_ip': None, 'remove_fixed_ip': None,
} }
@ -7789,25 +7774,26 @@ class TestServerSet(TestServer):
class TestServerShelve(TestServer): class TestServerShelve(TestServer):
def setUp(self): def setUp(self):
super(TestServerShelve, self).setUp() super().setUp()
self.server = compute_fakes.FakeServer.create_one_sdk_server(
attrs={'status': 'ACTIVE'},
)
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
self.sdk_client.find_server.return_value = self.server
self.sdk_client.shelve_server.return_value = None
# Get the command object to test # Get the command object to test
self.cmd = server.ShelveServer(self.app, None) self.cmd = server.ShelveServer(self.app, None)
def test_shelve(self): def test_shelve(self):
server_info = {'status': 'ACTIVE'} arglist = [self.server.name]
server_methods = {
'shelve': None,
'shelve_offload': None,
}
server = compute_fakes.FakeServer.create_one_server(
attrs=server_info, methods=server_methods)
self.servers_mock.get.return_value = server
arglist = [server.name]
verifylist = [ verifylist = [
('servers', [server.name]), ('servers', [self.server.name]),
('wait', False), ('wait', False),
('offload', False), ('offload', False),
] ]
@ -7816,24 +7802,19 @@ class TestServerShelve(TestServer):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.assertIsNone(result) self.assertIsNone(result)
self.servers_mock.get.assert_called_once_with(server.name) self.sdk_client.find_server.assert_called_with(
server.shelve.assert_called_once_with() self.server.name,
server.shelve_offload.assert_not_called() ignore_missing=False,
)
self.sdk_client.shelve_server.assert_called_with(self.server.id)
self.sdk_client.shelve_offload_server.assert_not_called()
def test_shelve_already_shelved(self): def test_shelve_already_shelved(self):
server_info = {'status': 'SHELVED'} self.server.status = 'SHELVED'
server_methods = {
'shelve': None,
'shelve_offload': None,
}
server = compute_fakes.FakeServer.create_one_server( arglist = [self.server.name]
attrs=server_info, methods=server_methods)
self.servers_mock.get.return_value = server
arglist = [server.name]
verifylist = [ verifylist = [
('servers', [server.name]), ('servers', [self.server.name]),
('wait', False), ('wait', False),
('offload', False), ('offload', False),
] ]
@ -7842,25 +7823,18 @@ class TestServerShelve(TestServer):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.assertIsNone(result) self.assertIsNone(result)
self.servers_mock.get.assert_called_once_with(server.name) self.sdk_client.find_server.assert_called_with(
server.shelve.assert_not_called() self.server.name,
server.shelve_offload.assert_not_called() ignore_missing=False,
)
self.sdk_client.shelve_server.assert_not_called()
self.sdk_client.shelve_offload_server.assert_not_called()
@mock.patch.object(common_utils, 'wait_for_status', return_value=True) @mock.patch.object(common_utils, 'wait_for_status', return_value=True)
def test_shelve_with_wait(self, mock_wait_for_status): def test_shelve_with_wait(self, mock_wait_for_status):
server_info = {'status': 'ACTIVE'} arglist = ['--wait', self.server.name]
server_methods = {
'shelve': None,
'shelve_offload': None,
}
server = compute_fakes.FakeServer.create_one_server(
attrs=server_info, methods=server_methods)
self.servers_mock.get.return_value = server
arglist = ['--wait', server.name]
verifylist = [ verifylist = [
('servers', [server.name]), ('servers', [self.server.name]),
('wait', True), ('wait', True),
('offload', False), ('offload', False),
] ]
@ -7869,31 +7843,24 @@ class TestServerShelve(TestServer):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.assertIsNone(result) self.assertIsNone(result)
self.servers_mock.get.assert_called_once_with(server.name) self.sdk_client.find_server.assert_called_with(
server.shelve.assert_called_once_with() self.server.name,
server.shelve_offload.assert_not_called() ignore_missing=False,
)
self.sdk_client.shelve_server.assert_called_with(self.server.id)
self.sdk_client.shelve_offload_server.assert_not_called()
mock_wait_for_status.assert_called_once_with( mock_wait_for_status.assert_called_once_with(
self.servers_mock.get, self.sdk_client.get_server,
server.id, self.server.id,
callback=mock.ANY, callback=mock.ANY,
success_status=('shelved', 'shelved_offloaded'), success_status=('shelved', 'shelved_offloaded'),
) )
@mock.patch.object(common_utils, 'wait_for_status', return_value=True) @mock.patch.object(common_utils, 'wait_for_status', return_value=True)
def test_shelve_offload(self, mock_wait_for_status): def test_shelve_offload(self, mock_wait_for_status):
server_info = {'status': 'ACTIVE'} arglist = ['--offload', self.server.name]
server_methods = {
'shelve': None,
'shelve_offload': None,
}
server = compute_fakes.FakeServer.create_one_server(
attrs=server_info, methods=server_methods)
self.servers_mock.get.return_value = server
arglist = ['--offload', server.name]
verifylist = [ verifylist = [
('servers', [server.name]), ('servers', [self.server.name]),
('wait', False), ('wait', False),
('offload', True), ('offload', True),
] ]
@ -7902,15 +7869,21 @@ class TestServerShelve(TestServer):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.assertIsNone(result) self.assertIsNone(result)
self.servers_mock.get.assert_has_calls([ # two calls - one to retrieve the server state before shelving and
mock.call(server.name), # another to do this before offloading
mock.call(server.name), self.sdk_client.find_server.assert_has_calls(
]) [
server.shelve.assert_called_once_with() mock.call(self.server.name, ignore_missing=False),
server.shelve_offload.assert_called_once_with() mock.call(self.server.name, ignore_missing=False),
]
)
self.sdk_client.shelve_server.assert_called_with(self.server.id)
self.sdk_client.shelve_offload_server.assert_called_once_with(
self.server.id,
)
mock_wait_for_status.assert_called_once_with( mock_wait_for_status.assert_called_once_with(
self.servers_mock.get, self.sdk_client.get_server,
server.id, self.server.id,
callback=mock.ANY, callback=mock.ANY,
success_status=('shelved', 'shelved_offloaded'), success_status=('shelved', 'shelved_offloaded'),
) )
@ -8447,245 +8420,217 @@ class TestServerUnset(TestServer):
class TestServerUnshelve(TestServer): class TestServerUnshelve(TestServer):
def setUp(self): def setUp(self):
super(TestServerUnshelve, self).setUp() super().setUp()
self.server = compute_fakes.FakeServer.create_one_sdk_server(
attrs={'status': 'SHELVED'},
)
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
self.sdk_client.find_server.return_value = self.server
self.sdk_client.unshelve_server.return_value = None
# Get the command object to test # Get the command object to test
self.cmd = server.UnshelveServer(self.app, None) self.cmd = server.UnshelveServer(self.app, None)
# Set unshelve method to be tested. def test_unshelve(self):
self.methods = {
'unshelve': None,
}
self.attrs = {
'status': 'SHELVED',
}
def test_unshelve_one_server(self):
self.run_method_with_servers('unshelve', 1)
def test_unshelve_multi_servers(self):
self.run_method_with_servers('unshelve', 3)
def test_unshelve_v277(self):
self.app.client_manager.compute.api_version = \
api_versions.APIVersion('2.77')
server = compute_fakes.FakeServer.create_one_server(
attrs=self.attrs, methods=self.methods)
self.servers_mock.get.return_value = server
arglist = [server.id]
verifylist = [('server', [server.id])]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.servers_mock.get.assert_called_with(server.id)
server.unshelve.assert_called_with()
def test_unshelve_with_specified_az_v277(self):
self.app.client_manager.compute.api_version = \
api_versions.APIVersion('2.77')
server = compute_fakes.FakeServer.create_one_server(
attrs=self.attrs, methods=self.methods)
self.servers_mock.get.return_value = server
arglist = [ arglist = [
'--availability-zone', "foo-az", self.server.id,
server.id,
] ]
verifylist = [ verifylist = [
('availability_zone', "foo-az"), ('server', [self.server.id]),
('server', [server.id])
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.servers_mock.get.assert_called_with(server.id) self.sdk_client.find_server.assert_called_once_with(
server.unshelve.assert_called_with(availability_zone="foo-az") self.server.id,
ignore_missing=False,
)
self.sdk_client.unshelve_server.assert_called_once_with(self.server.id)
def test_unshelve_with_specified_az_pre_v277(self): def test_unshelve_with_az(self):
self.app.client_manager.compute.api_version = \ self._set_mock_microversion('2.77')
api_versions.APIVersion('2.76')
server = compute_fakes.FakeServer.create_one_server(
attrs=self.attrs, methods=self.methods)
arglist = [ arglist = [
server.id, '--availability-zone', 'foo-az',
'--availability-zone', "foo-az", self.server.id,
] ]
verifylist = [ verifylist = [
('availability_zone', "foo-az"), ('availability_zone', 'foo-az'),
('server', [server.id]) ('server', [self.server.id])
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.sdk_client.find_server.assert_called_once_with(
self.server.id,
ignore_missing=False,
)
self.sdk_client.unshelve_server.assert_called_once_with(
self.server.id,
availability_zone='foo-az',
)
def test_unshelve_with_az_pre_v277(self):
self._set_mock_microversion('2.76')
arglist = [
self.server.id,
'--availability-zone', 'foo-az',
]
verifylist = [
('availability_zone', 'foo-az'),
('server', [self.server.id])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
ex = self.assertRaises( ex = self.assertRaises(
exceptions.CommandError, exceptions.CommandError,
self.cmd.take_action, self.cmd.take_action,
parsed_args) parsed_args,
)
self.assertIn( self.assertIn(
'--os-compute-api-version 2.77 or greater is required', str(ex)) '--os-compute-api-version 2.77 or greater is required ',
str(ex),
)
def test_unshelve_v291(self): def test_unshelve_with_host(self):
self.app.client_manager.compute.api_version = ( self._set_mock_microversion('2.91')
api_versions.APIVersion('2.91'))
server = compute_fakes.FakeServer.create_one_server(
attrs=self.attrs, methods=self.methods)
self.servers_mock.get.return_value = server
arglist = [server.id]
verifylist = [('server', [server.id])]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.servers_mock.get.assert_called_with(server.id)
server.unshelve.assert_called_with()
def test_unshelve_with_specified_az_v291(self):
self.app.client_manager.compute.api_version = (
api_versions.APIVersion('2.91'))
server = compute_fakes.FakeServer.create_one_server(
attrs=self.attrs, methods=self.methods)
self.servers_mock.get.return_value = server
arglist = [ arglist = [
'--availability-zone', "foo-az", '--host', 'server1',
server.id, self.server.id,
] ]
verifylist = [ verifylist = [
('availability_zone', "foo-az"), ('host', 'server1'),
('server', [server.id]) ('server', [self.server.id])
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.servers_mock.get.assert_called_with(server.id) self.sdk_client.find_server.assert_called_once_with(
server.unshelve.assert_called_with(availability_zone="foo-az") self.server.id,
ignore_missing=False,
)
self.sdk_client.unshelve_server.assert_called_once_with(
self.server.id,
host='server1',
)
def test_unshelve_with_specified_host_v291(self): def test_unshelve_with_host_pre_v291(self):
self.app.client_manager.compute.api_version = ( self._set_mock_microversion('2.90')
api_versions.APIVersion('2.91'))
server = compute_fakes.FakeServer.create_one_server(
attrs=self.attrs, methods=self.methods)
self.servers_mock.get.return_value = server
arglist = [ arglist = [
'--host', "server1", '--host', 'server1',
server.id, self.server.id,
] ]
verifylist = [ verifylist = [
('host', "server1"), ('host', 'server1'),
('server', [server.id]) ('server', [self.server.id])
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args) ex = self.assertRaises(
exceptions.CommandError,
self.cmd.take_action,
parsed_args,
)
self.assertIn(
'--os-compute-api-version 2.91 or greater is required '
'to support the --host option',
str(ex),
)
self.servers_mock.get.assert_called_with(server.id) def test_unshelve_with_no_az(self):
server.unshelve.assert_called_with(host="server1") self._set_mock_microversion('2.91')
def test_unshelve_with_unpin_az_v291(self):
self.app.client_manager.compute.api_version = (
api_versions.APIVersion('2.91'))
server = compute_fakes.FakeServer.create_one_server(
attrs=self.attrs, methods=self.methods)
self.servers_mock.get.return_value = server
arglist = ['--no-availability-zone', server.id]
verifylist = [
('no_availability_zone', True),
('server', [server.id])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.servers_mock.get.assert_called_with(server.id)
server.unshelve.assert_called_with(availability_zone=None)
def test_unshelve_with_specified_az_and_host_v291(self):
self.app.client_manager.compute.api_version = (
api_versions.APIVersion('2.91'))
server = compute_fakes.FakeServer.create_one_server(
attrs=self.attrs, methods=self.methods)
self.servers_mock.get.return_value = server
arglist = [ arglist = [
'--host', "server1",
'--availability-zone', "foo-az",
server.id,
]
verifylist = [
('host', "server1"),
('availability_zone', "foo-az"),
('server', [server.id])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.servers_mock.get.assert_called_with(server.id)
def test_unshelve_with_unpin_az_and_host_v291(self):
self.app.client_manager.compute.api_version = (
api_versions.APIVersion('2.91'))
server = compute_fakes.FakeServer.create_one_server(
attrs=self.attrs, methods=self.methods)
self.servers_mock.get.return_value = server
arglist = [
'--host', "server1",
'--no-availability-zone', '--no-availability-zone',
server.id, self.server.id,
] ]
verifylist = [ verifylist = [
('host', "server1"),
('no_availability_zone', True), ('no_availability_zone', True),
('server', [server.id]) ('server', [self.server.id])
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args) self.cmd.take_action(parsed_args)
self.servers_mock.get.assert_called_with(server.id) self.sdk_client.find_server.assert_called_once_with(
self.server.id,
ignore_missing=False,
)
self.sdk_client.unshelve_server.assert_called_once_with(
self.server.id,
availability_zone=None,
)
def test_unshelve_fails_with_unpin_az_and_az_v291(self): def test_unshelve_with_no_az_pre_v291(self):
self.app.client_manager.compute.api_version = ( self._set_mock_microversion('2.90')
api_versions.APIVersion('2.91'))
arglist = [
'--no-availability-zone',
self.server.id,
]
verifylist = [
('no_availability_zone', True),
('server', [self.server.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.91 or greater is required '
'to support the --no-availability-zone option',
str(ex),
)
def test_unshelve_with_no_az_and_az_conflict(self):
self._set_mock_microversion('2.91')
server = compute_fakes.FakeServer.create_one_server(
attrs=self.attrs, methods=self.methods)
self.servers_mock.get.return_value = server
arglist = [ arglist = [
'--availability-zone', "foo-az", '--availability-zone', "foo-az",
'--no-availability-zone', '--no-availability-zone',
server.id, self.server.id,
] ]
verifylist = [ verifylist = [
('availability_zone', "foo-az"), ('availability_zone', "foo-az"),
('no_availability_zone', True), ('no_availability_zone', True),
('server', [server.id]) ('server', [self.server.id])
] ]
ex = self.assertRaises(utils.ParserException, ex = self.assertRaises(
self.check_parser, utils.ParserException,
self.cmd, arglist, verifylist) self.check_parser,
self.assertIn('argument --no-availability-zone: not allowed ' self.cmd,
'with argument --availability-zone', str(ex)) arglist,
verifylist,
)
self.assertIn(
'argument --no-availability-zone: not allowed '
'with argument --availability-zone',
str(ex),
)
@mock.patch.object(common_utils, 'wait_for_status', return_value=True) @mock.patch.object(common_utils, 'wait_for_status', return_value=True)
def test_unshelve_with_wait(self, mock_wait_for_status): def test_unshelve_with_wait(self, mock_wait_for_status):
server = compute_fakes.FakeServer.create_one_server( arglist = [
attrs=self.attrs, methods=self.methods) '--wait',
self.servers_mock.get.return_value = server self.server.name,
]
arglist = ['--wait', server.name]
verifylist = [ verifylist = [
('server', [server.name]), ('server', [self.server.name]),
('wait', True), ('wait', True),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@ -8693,11 +8638,14 @@ class TestServerUnshelve(TestServer):
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.assertIsNone(result) self.assertIsNone(result)
self.servers_mock.get.assert_called_once_with(server.name) self.sdk_client.find_server.assert_called_with(
server.unshelve.assert_called_once_with() self.server.name,
ignore_missing=False,
)
self.sdk_client.unshelve_server.assert_called_with(self.server.id)
mock_wait_for_status.assert_called_once_with( mock_wait_for_status.assert_called_once_with(
self.servers_mock.get, self.sdk_client.get_server,
server.id, self.server.id,
callback=mock.ANY, callback=mock.ANY,
success_status=('active', 'shutoff'), success_status=('active', 'shutoff'),
) )

View File

@ -0,0 +1,5 @@
---
features:
- |
The ``server shelve`` and ``server unshelve`` commands have been migrated
to SDK.