diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py index 5999ad4fe4..aa4accf4ec 100644 --- a/openstackclient/compute/v2/server.py +++ b/openstackclient/compute/v2/server.py @@ -16,6 +16,7 @@ """Compute v2 Server action implementations""" import argparse +import base64 import getpass import json import logging @@ -3505,11 +3506,11 @@ class RebuildServer(command.ShowOne): self.app.stdout.write('\rProgress: %s' % progress) self.app.stdout.flush() - compute_client = self.app.client_manager.compute + compute_client = self.app.client_manager.sdk_connection.compute image_client = self.app.client_manager.image - server = utils.find_resource( - compute_client.servers, parsed_args.server + server = compute_client.find_server( + parsed_args.server, ignore_missing=False ) # If parsed_args.image is not set and if the instance is image backed, @@ -3521,7 +3522,7 @@ class RebuildServer(command.ShowOne): parsed_args.image, ignore_missing=False ) else: - if not server.image: + if not server.image or not server.image.id: msg = _( 'The --image option is required when rebuilding a ' 'volume-backed server' @@ -3538,10 +3539,10 @@ class RebuildServer(command.ShowOne): kwargs['preserve_ephemeral'] = parsed_args.preserve_ephemeral if parsed_args.properties: - kwargs['meta'] = parsed_args.properties + kwargs['metadata'] = parsed_args.properties if parsed_args.description: - if compute_client.api_version < api_versions.APIVersion('2.19'): + if not sdk_utils.supports_microversion(compute_client, '2.19'): msg = _( '--os-compute-api-version 2.19 or greater is required to ' 'support the --description option' @@ -3551,7 +3552,7 @@ class RebuildServer(command.ShowOne): kwargs['description'] = parsed_args.description if parsed_args.key_name: - if compute_client.api_version < api_versions.APIVersion('2.54'): + if not sdk_utils.supports_microversion(compute_client, '2.54'): msg = _( '--os-compute-api-version 2.54 or greater is required to ' 'support the --key-name option' @@ -3560,7 +3561,7 @@ class RebuildServer(command.ShowOne): kwargs['key_name'] = parsed_args.key_name elif parsed_args.no_key_name: - if compute_client.api_version < api_versions.APIVersion('2.54'): + if not sdk_utils.supports_microversion(compute_client, '2.54'): msg = _( '--os-compute-api-version 2.54 or greater is required to ' 'support the --no-key-name option' @@ -3569,9 +3570,8 @@ class RebuildServer(command.ShowOne): kwargs['key_name'] = None - userdata = None if parsed_args.user_data: - if compute_client.api_version < api_versions.APIVersion('2.54'): + if not sdk_utils.supports_microversion(compute_client, '2.54'): msg = _( '--os-compute-api-version 2.54 or greater is required to ' 'support the --user-data option' @@ -3579,27 +3579,29 @@ class RebuildServer(command.ShowOne): raise exceptions.CommandError(msg) try: - userdata = open(parsed_args.user_data) + with open(parsed_args.user_data, 'rb') as fh: + # TODO(stephenfin): SDK should do this for us + user_data = base64.b64encode(fh.read()).decode('utf-8') except OSError as e: msg = _("Can't open '%(data)s': %(exception)s") raise exceptions.CommandError( msg % {'data': parsed_args.user_data, 'exception': e} ) - kwargs['userdata'] = userdata + kwargs['user_data'] = user_data elif parsed_args.no_user_data: - if compute_client.api_version < api_versions.APIVersion('2.54'): + if not sdk_utils.supports_microversion(compute_client, '2.54'): msg = _( '--os-compute-api-version 2.54 or greater is required to ' 'support the --no-user-data option' ) raise exceptions.CommandError(msg) - kwargs['userdata'] = None + kwargs['user_data'] = None # TODO(stephenfin): Handle OS_TRUSTED_IMAGE_CERTIFICATE_IDS if parsed_args.trusted_image_certs: - if compute_client.api_version < api_versions.APIVersion('2.63'): + if not sdk_utils.supports_microversion(compute_client, '2.63'): msg = _( '--os-compute-api-version 2.63 or greater is required to ' 'support the --trusted-certs option' @@ -3609,7 +3611,7 @@ class RebuildServer(command.ShowOne): certs = parsed_args.trusted_image_certs kwargs['trusted_image_certificates'] = certs elif parsed_args.no_trusted_image_certs: - if compute_client.api_version < api_versions.APIVersion('2.63'): + if not sdk_utils.supports_microversion(compute_client, '2.63'): msg = _( '--os-compute-api-version 2.63 or greater is required to ' 'support the --no-trusted-certs option' @@ -3619,7 +3621,7 @@ class RebuildServer(command.ShowOne): kwargs['trusted_image_certificates'] = None if parsed_args.hostname: - if compute_client.api_version < api_versions.APIVersion('2.90'): + if not sdk_utils.supports_microversion(compute_client, '2.90'): msg = _( '--os-compute-api-version 2.90 or greater is required to ' 'support the --hostname option' @@ -3628,9 +3630,8 @@ class RebuildServer(command.ShowOne): kwargs['hostname'] = parsed_args.hostname - v2_93 = api_versions.APIVersion('2.93') if parsed_args.reimage_boot_volume: - if compute_client.api_version < v2_93: + if not sdk_utils.supports_microversion(compute_client, '2.93'): msg = _( '--os-compute-api-version 2.93 or greater is required to ' 'support the --reimage-boot-volume option' @@ -3639,8 +3640,8 @@ class RebuildServer(command.ShowOne): else: # force user to explicitly request reimaging of volume-backed # server - if not server.image: - if compute_client.api_version >= v2_93: + if not server.image or not server.image.id: + if sdk_utils.supports_microversion(compute_client, '2.93'): msg = ( '--reimage-boot-volume is required to rebuild a ' 'volume-backed server' @@ -3672,15 +3673,13 @@ class RebuildServer(command.ShowOne): msg = _("The server status is not ACTIVE, SHUTOFF or ERROR.") raise exceptions.CommandError(msg) - try: - server = server.rebuild(image, parsed_args.password, **kwargs) - finally: - if userdata and hasattr(userdata, 'close'): - userdata.close() + server = compute_client.rebuild_server( + server, image, admin_password=parsed_args.password, **kwargs + ) if parsed_args.wait: if utils.wait_for_status( - compute_client.servers.get, + compute_client.get_server, server.id, callback=_show_progress, success_status=success_status, @@ -3690,8 +3689,6 @@ class RebuildServer(command.ShowOne): msg = _('Error rebuilding server: %s') % server.id raise exceptions.CommandError(msg) - # TODO(stephenfin): Remove when the whole command is using SDK - compute_client = self.app.client_manager.sdk_connection.compute data = _prep_server_detail( compute_client, image_client, server, refresh=False ) diff --git a/openstackclient/tests/unit/compute/v2/test_server.py b/openstackclient/tests/unit/compute/v2/test_server.py index 5878d15307..9bac34bb9f 100644 --- a/openstackclient/tests/unit/compute/v2/test_server.py +++ b/openstackclient/tests/unit/compute/v2/test_server.py @@ -12,6 +12,7 @@ # License for the specific language governing permissions and limitations # under the License. +import base64 import collections import copy import getpass @@ -6227,59 +6228,47 @@ class TestServerRebuild(TestServer): def setUp(self): super().setUp() - # Return value for utils.find_resource for image self.image = image_fakes.create_one_image() self.image_client.get_image.return_value = self.image - # Fake the rebuilt new server. attrs = { + 'status': 'ACTIVE', 'image': {'id': self.image.id}, - 'networks': {}, - 'adminPass': 'passw0rd', } - new_server = compute_fakes.create_one_server(attrs=attrs) - - # Fake the server to be rebuilt. The IDs of them should be the same. - attrs['id'] = new_server.id - attrs['status'] = 'ACTIVE' - methods = { - 'rebuild': new_server, - } - self.server = compute_fakes.create_one_server( - attrs=attrs, methods=methods - ) - - # Return value for utils.find_resource for server. - self.servers_mock.get.return_value = self.server + self.server = compute_fakes.create_one_sdk_server(attrs=attrs) + self.compute_sdk_client.find_server.return_value = self.server + self.compute_sdk_client.rebuild_server.return_value = self.server self.cmd = server.RebuildServer(self.app, None) def test_rebuild_with_image_name(self): image_name = 'my-custom-image' - user_image = image_fakes.create_one_image(attrs={'name': image_name}) - self.image_client.find_image.return_value = user_image + image = image_fakes.create_one_image(attrs={'name': image_name}) + self.image_client.find_image.return_value = image - attrs = { - 'image': {'id': user_image.id}, - 'networks': {}, - 'adminPass': 'passw0rd', - } - new_server = compute_fakes.create_one_server(attrs=attrs) - self.server.rebuild.return_value = new_server + arglist = [ + self.server.id, + '--image', + image_name, + ] + verifylist = [ + ('server', self.server.id), + ('image', image_name), + ] - arglist = [self.server.id, '--image', image_name] - verifylist = [('server', self.server.id), ('image', image_name)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - - # Get the command object to test. self.cmd.take_action(parsed_args) - self.servers_mock.get.assert_called_with(self.server.id) + self.compute_sdk_client.find_server.assert_called_once_with( + self.server.id, ignore_missing=False + ) self.image_client.find_image.assert_called_with( image_name, ignore_missing=False ) - self.image_client.get_image.assert_called_with(user_image.id) - self.server.rebuild.assert_called_with(user_image, None) + self.image_client.get_image.assert_called_with(self.image.id) + self.compute_sdk_client.rebuild_server.assert_called_once_with( + self.server, image, admin_password=None + ) def test_rebuild_with_current_image(self): arglist = [ @@ -6291,10 +6280,16 @@ class TestServerRebuild(TestServer): # Get the command object to test. self.cmd.take_action(parsed_args) - self.servers_mock.get.assert_called_with(self.server.id) + self.compute_sdk_client.find_server.assert_called_once_with( + self.server.id, ignore_missing=False + ) self.image_client.find_image.assert_not_called() - self.image_client.get_image.assert_called_with(self.image.id) - self.server.rebuild.assert_called_with(self.image, None) + self.image_client.get_image.assert_has_calls( + [mock.call(self.image.id), mock.call(self.image.id)] + ) + self.compute_sdk_client.rebuild_server.assert_called_once_with( + self.server, self.image, admin_password=None + ) def test_rebuild_with_volume_backed_server_no_image(self): # the volume-backed server will have the image attribute set to an @@ -6307,8 +6302,8 @@ class TestServerRebuild(TestServer): verifylist = [ ('server', self.server.id), ] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) + parsed_args = self.check_parser(self.cmd, arglist, verifylist) exc = self.assertRaises( exceptions.CommandError, self.cmd.take_action, parsed_args ) @@ -6325,14 +6320,20 @@ class TestServerRebuild(TestServer): ('server', self.server.id), ('name', name), ] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # Get the command object to test + parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) - self.servers_mock.get.assert_called_with(self.server.id) - self.image_client.get_image.assert_called_with(self.image.id) - self.server.rebuild.assert_called_with(self.image, None, name=name) + self.compute_sdk_client.find_server.assert_called_once_with( + self.server.id, ignore_missing=False + ) + self.image_client.find_image.assert_not_called() + self.image_client.get_image.assert_has_calls( + [mock.call(self.image.id), mock.call(self.image.id)] + ) + self.compute_sdk_client.rebuild_server.assert_called_once_with( + self.server, self.image, admin_password=None, name=name + ) def test_rebuild_with_preserve_ephemeral(self): arglist = [ @@ -6343,15 +6344,22 @@ class TestServerRebuild(TestServer): ('server', self.server.id), ('preserve_ephemeral', True), ] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # Get the command object to test + parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) - self.servers_mock.get.assert_called_with(self.server.id) - self.image_client.get_image.assert_called_with(self.image.id) - self.server.rebuild.assert_called_with( - self.image, None, preserve_ephemeral=True + self.compute_sdk_client.find_server.assert_called_once_with( + self.server.id, ignore_missing=False + ) + self.image_client.find_image.assert_not_called() + self.image_client.get_image.assert_has_calls( + [mock.call(self.image.id), mock.call(self.image.id)] + ) + self.compute_sdk_client.rebuild_server.assert_called_once_with( + self.server, + self.image, + admin_password=None, + preserve_ephemeral=True, ) def test_rebuild_with_no_preserve_ephemeral(self): @@ -6368,24 +6376,40 @@ class TestServerRebuild(TestServer): # Get the command object to test self.cmd.take_action(parsed_args) - self.servers_mock.get.assert_called_with(self.server.id) - self.image_client.get_image.assert_called_with(self.image.id) - self.server.rebuild.assert_called_with( - self.image, None, preserve_ephemeral=False + self.compute_sdk_client.find_server.assert_called_once_with( + self.server.id, ignore_missing=False + ) + self.image_client.find_image.assert_not_called() + self.image_client.get_image.assert_has_calls( + [mock.call(self.image.id), mock.call(self.image.id)] + ) + self.compute_sdk_client.rebuild_server.assert_called_once_with( + self.server, + self.image, + admin_password=None, + preserve_ephemeral=False, ) def test_rebuild_with_password(self): password = 'password-xxx' arglist = [self.server.id, '--password', password] verifylist = [('server', self.server.id), ('password', password)] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # Get the command object to test + parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) - self.servers_mock.get.assert_called_with(self.server.id) - self.image_client.get_image.assert_called_with(self.image.id) - self.server.rebuild.assert_called_with(self.image, password) + self.compute_sdk_client.find_server.assert_called_once_with( + self.server.id, ignore_missing=False + ) + self.image_client.find_image.assert_not_called() + self.image_client.get_image.assert_has_calls( + [mock.call(self.image.id), mock.call(self.image.id)] + ) + self.compute_sdk_client.rebuild_server.assert_called_once_with( + self.server, + self.image, + admin_password=password, + ) def test_rebuild_with_description(self): self.set_compute_api_version('2.19') @@ -6393,14 +6417,22 @@ class TestServerRebuild(TestServer): description = 'description1' arglist = [self.server.id, '--description', description] verifylist = [('server', self.server.id), ('description', description)] - 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.servers_mock.get.assert_called_with(self.server.id) - self.image_client.get_image.assert_called_with(self.image.id) - self.server.rebuild.assert_called_with( - self.image, None, description=description + self.compute_sdk_client.find_server.assert_called_once_with( + self.server.id, ignore_missing=False + ) + self.image_client.find_image.assert_not_called() + self.image_client.get_image.assert_has_calls( + [mock.call(self.image.id), mock.call(self.image.id)] + ) + self.compute_sdk_client.rebuild_server.assert_called_once_with( + self.server, + self.image, + admin_password=None, + description=description, ) def test_rebuild_with_description_pre_v219(self): @@ -6409,8 +6441,8 @@ class TestServerRebuild(TestServer): description = 'description1' arglist = [self.server.id, '--description', description] verifylist = [('server', self.server.id), ('description', description)] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) + parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( exceptions.CommandError, self.cmd.take_action, parsed_args ) @@ -6425,25 +6457,30 @@ class TestServerRebuild(TestServer): ('wait', True), ('server', self.server.id), ] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # Get the command object to test. + parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) - # kwargs = dict(success_status=['active', 'verify_resize'],) + self.compute_sdk_client.find_server.assert_called_once_with( + self.server.id, ignore_missing=False + ) + self.image_client.find_image.assert_not_called() + self.image_client.get_image.assert_has_calls( + [mock.call(self.image.id), mock.call(self.image.id)] + ) + self.compute_sdk_client.rebuild_server.assert_called_once_with( + self.server, + self.image, + admin_password=None, + ) mock_wait_for_status.assert_called_once_with( - self.servers_mock.get, + self.compute_sdk_client.get_server, self.server.id, callback=mock.ANY, success_status=['active'], - # **kwargs ) - self.servers_mock.get.assert_called_with(self.server.id) - self.image_client.get_image.assert_called_with(self.image.id) - self.server.rebuild.assert_called_with(self.image, None) - @mock.patch.object(common_utils, 'wait_for_status', return_value=False) def test_rebuild_with_wait_fails(self, mock_wait_for_status): arglist = [ @@ -6454,23 +6491,30 @@ class TestServerRebuild(TestServer): ('wait', True), ('server', self.server.id), ] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) + parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( exceptions.CommandError, self.cmd.take_action, parsed_args ) + self.compute_sdk_client.find_server.assert_called_once_with( + self.server.id, ignore_missing=False + ) + self.image_client.find_image.assert_not_called() + self.image_client.get_image.assert_called_once_with(self.image.id) + self.compute_sdk_client.rebuild_server.assert_called_once_with( + self.server, + self.image, + admin_password=None, + ) + mock_wait_for_status.assert_called_once_with( - self.servers_mock.get, + self.compute_sdk_client.get_server, self.server.id, callback=mock.ANY, success_status=['active'], ) - self.servers_mock.get.assert_called_with(self.server.id) - self.image_client.get_image.assert_called_with(self.image.id) - self.server.rebuild.assert_called_with(self.image, None) - @mock.patch.object(common_utils, 'wait_for_status', return_value=True) def test_rebuild_with_wait_shutoff_status(self, mock_wait_for_status): self.server.status = 'SHUTOFF' @@ -6482,25 +6526,30 @@ class TestServerRebuild(TestServer): ('wait', True), ('server', self.server.id), ] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # Get the command object to test. + parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) - # kwargs = dict(success_status=['active', 'verify_resize'],) + self.compute_sdk_client.find_server.assert_called_once_with( + self.server.id, ignore_missing=False + ) + self.image_client.find_image.assert_not_called() + self.image_client.get_image.assert_has_calls( + [mock.call(self.image.id), mock.call(self.image.id)] + ) + self.compute_sdk_client.rebuild_server.assert_called_once_with( + self.server, + self.image, + admin_password=None, + ) mock_wait_for_status.assert_called_once_with( - self.servers_mock.get, + self.compute_sdk_client.get_server, self.server.id, callback=mock.ANY, success_status=['shutoff'], - # **kwargs ) - self.servers_mock.get.assert_called_with(self.server.id) - self.image_client.get_image.assert_called_with(self.image.id) - self.server.rebuild.assert_called_with(self.image, None) - @mock.patch.object(common_utils, 'wait_for_status', return_value=True) def test_rebuild_with_wait_error_status(self, mock_wait_for_status): self.server.status = 'ERROR' @@ -6512,25 +6561,30 @@ class TestServerRebuild(TestServer): ('wait', True), ('server', self.server.id), ] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # Get the command object to test. + parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) - # kwargs = dict(success_status=['active', 'verify_resize'],) + self.compute_sdk_client.find_server.assert_called_once_with( + self.server.id, ignore_missing=False + ) + self.image_client.find_image.assert_not_called() + self.image_client.get_image.assert_has_calls( + [mock.call(self.image.id), mock.call(self.image.id)] + ) + self.compute_sdk_client.rebuild_server.assert_called_once_with( + self.server, + self.image, + admin_password=None, + ) mock_wait_for_status.assert_called_once_with( - self.servers_mock.get, + self.compute_sdk_client.get_server, self.server.id, callback=mock.ANY, success_status=['active'], - # **kwargs ) - self.servers_mock.get.assert_called_with(self.server.id) - self.image_client.get_image.assert_called_with(self.image.id) - self.server.rebuild.assert_called_with(self.image, None) - def test_rebuild_wrong_status_fails(self): self.server.status = 'SHELVED' arglist = [ @@ -6539,15 +6593,18 @@ class TestServerRebuild(TestServer): verifylist = [ ('server', self.server.id), ] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) + parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( exceptions.CommandError, self.cmd.take_action, parsed_args ) - self.servers_mock.get.assert_called_with(self.server.id) - self.image_client.get_image.assert_called_with(self.image.id) - self.server.rebuild.assert_not_called() + self.compute_sdk_client.find_server.assert_called_once_with( + self.server.id, ignore_missing=False + ) + self.image_client.find_image.assert_not_called() + self.image_client.get_image.assert_called_once_with(self.image.id) + self.compute_sdk_client.rebuild_server.assert_not_called() def test_rebuild_with_property(self): arglist = [ @@ -6562,15 +6619,22 @@ class TestServerRebuild(TestServer): ('server', self.server.id), ('properties', expected_properties), ] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - # Get the command object to test + parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) - self.servers_mock.get.assert_called_with(self.server.id) - self.image_client.get_image.assert_called_with(self.image.id) - self.server.rebuild.assert_called_with( - self.image, None, meta=expected_properties + self.compute_sdk_client.find_server.assert_called_once_with( + self.server.id, ignore_missing=False + ) + self.image_client.find_image.assert_not_called() + self.image_client.get_image.assert_has_calls( + [mock.call(self.image.id), mock.call(self.image.id)] + ) + self.compute_sdk_client.rebuild_server.assert_called_once_with( + self.server, + self.image, + admin_password=None, + metadata=expected_properties, ) def test_rebuild_with_keypair_name(self): @@ -6586,14 +6650,22 @@ class TestServerRebuild(TestServer): ('server', self.server.id), ('key_name', self.server.key_name), ] - 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.servers_mock.get.assert_called_with(self.server.id) - self.image_client.get_image.assert_called_with(self.image.id) - self.server.rebuild.assert_called_with( - self.image, None, key_name=self.server.key_name + self.compute_sdk_client.find_server.assert_called_once_with( + self.server.id, ignore_missing=False + ) + self.image_client.find_image.assert_not_called() + self.image_client.get_image.assert_has_calls( + [mock.call(self.image.id), mock.call(self.image.id)] + ) + self.compute_sdk_client.rebuild_server.assert_called_once_with( + self.server, + self.image, + admin_password=None, + key_name=self.server.key_name, ) def test_rebuild_with_keypair_name_pre_v254(self): @@ -6626,12 +6698,23 @@ class TestServerRebuild(TestServer): verifylist = [ ('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.servers_mock.get.assert_called_with(self.server.id) - self.image_client.get_image.assert_called_with(self.image.id) - self.server.rebuild.assert_called_with(self.image, None, key_name=None) + + self.compute_sdk_client.find_server.assert_called_once_with( + self.server.id, ignore_missing=False + ) + self.image_client.find_image.assert_not_called() + self.image_client.get_image.assert_has_calls( + [mock.call(self.image.id), mock.call(self.image.id)] + ) + self.compute_sdk_client.rebuild_server.assert_called_once_with( + self.server, + self.image, + admin_password=None, + key_name=None, + ) def test_rebuild_with_keypair_name_and_unset(self): self.server.key_name = 'mykey' @@ -6653,14 +6736,10 @@ class TestServerRebuild(TestServer): verifylist, ) - @mock.patch('openstackclient.compute.v2.server.open') - def test_rebuild_with_user_data(self, mock_open): + def test_rebuild_with_user_data(self): self.set_compute_api_version('2.57') - mock_file = mock.Mock(name='File') - mock_open.return_value = mock_file - mock_open.read.return_value = '#!/bin/sh' - + user_data = b'#!/bin/sh' arglist = [ self.server.id, '--user-data', @@ -6670,22 +6749,29 @@ class TestServerRebuild(TestServer): ('server', self.server.id), ('user_data', 'userdata.sh'), ] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - self.cmd.take_action(parsed_args) + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + with mock.patch( + 'openstackclient.compute.v2.server.open', + mock.mock_open(read_data=user_data), + ) as mock_file: + self.cmd.take_action(parsed_args) # Ensure the userdata file is opened - mock_open.assert_called_with('userdata.sh') + mock_file.assert_called_with('userdata.sh', 'rb') - # Ensure the userdata file is closed - mock_file.close.assert_called_with() - - self.servers_mock.get.assert_called_with(self.server.id) - self.image_client.get_image.assert_called_with(self.image.id) - self.server.rebuild.assert_called_with( + self.compute_sdk_client.find_server.assert_called_once_with( + self.server.id, ignore_missing=False + ) + self.image_client.find_image.assert_not_called() + self.image_client.get_image.assert_has_calls( + [mock.call(self.image.id), mock.call(self.image.id)] + ) + self.compute_sdk_client.rebuild_server.assert_called_once_with( + self.server, self.image, - None, - userdata=mock_file, + admin_password=None, + user_data=base64.b64encode(user_data).decode('utf-8'), ) def test_rebuild_with_user_data_pre_v257(self): @@ -6700,8 +6786,8 @@ class TestServerRebuild(TestServer): ('server', self.server.id), ('user_data', 'userdata.sh'), ] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) + parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( exceptions.CommandError, self.cmd.take_action, parsed_args ) @@ -6718,12 +6804,23 @@ class TestServerRebuild(TestServer): ('server', self.server.id), ('no_user_data', True), ] - 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.servers_mock.get.assert_called_with(self.server.id) - self.image_client.get_image.assert_called_with(self.image.id) - self.server.rebuild.assert_called_with(self.image, None, userdata=None) + + self.compute_sdk_client.find_server.assert_called_once_with( + self.server.id, ignore_missing=False + ) + self.image_client.find_image.assert_not_called() + self.image_client.get_image.assert_has_calls( + [mock.call(self.image.id), mock.call(self.image.id)] + ) + self.compute_sdk_client.rebuild_server.assert_called_once_with( + self.server, + self.image, + admin_password=None, + user_data=None, + ) def test_rebuild_with_no_user_data_pre_v254(self): self.set_compute_api_version('2.53') @@ -6736,8 +6833,8 @@ class TestServerRebuild(TestServer): ('server', self.server.id), ('no_user_data', True), ] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) + parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( exceptions.CommandError, self.cmd.take_action, parsed_args ) @@ -6771,14 +6868,22 @@ class TestServerRebuild(TestServer): ('server', self.server.id), ('trusted_image_certs', ['foo', 'bar']), ] - 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.servers_mock.get.assert_called_with(self.server.id) - self.image_client.get_image.assert_called_with(self.image.id) - self.server.rebuild.assert_called_with( - self.image, None, trusted_image_certificates=['foo', 'bar'] + self.compute_sdk_client.find_server.assert_called_once_with( + self.server.id, ignore_missing=False + ) + self.image_client.find_image.assert_not_called() + self.image_client.get_image.assert_has_calls( + [mock.call(self.image.id), mock.call(self.image.id)] + ) + self.compute_sdk_client.rebuild_server.assert_called_once_with( + self.server, + self.image, + admin_password=None, + trusted_image_certificates=['foo', 'bar'], ) def test_rebuild_with_trusted_image_cert_pre_v263(self): @@ -6795,8 +6900,8 @@ class TestServerRebuild(TestServer): ('server', self.server.id), ('trusted_image_certs', ['foo', 'bar']), ] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) + parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( exceptions.CommandError, self.cmd.take_action, parsed_args ) @@ -6812,13 +6917,22 @@ class TestServerRebuild(TestServer): ('server', self.server.id), ('no_trusted_image_certs', True), ] - 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.servers_mock.get.assert_called_with(self.server.id) - self.image_client.get_image.assert_called_with(self.image.id) - self.server.rebuild.assert_called_with( - self.image, None, trusted_image_certificates=None + + self.compute_sdk_client.find_server.assert_called_once_with( + self.server.id, ignore_missing=False + ) + self.image_client.find_image.assert_not_called() + self.image_client.get_image.assert_has_calls( + [mock.call(self.image.id), mock.call(self.image.id)] + ) + self.compute_sdk_client.rebuild_server.assert_called_once_with( + self.server, + self.image, + admin_password=None, + trusted_image_certificates=None, ) def test_rebuild_with_no_trusted_image_cert_pre_v263(self): @@ -6841,16 +6955,31 @@ class TestServerRebuild(TestServer): def test_rebuild_with_hostname(self): self.set_compute_api_version('2.90') - arglist = [self.server.id, '--hostname', 'new-hostname'] - verifylist = [('server', self.server.id), ('hostname', 'new-hostname')] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) + arglist = [ + self.server.id, + '--hostname', + 'new-hostname', + ] + verifylist = [ + ('server', self.server.id), + ('hostname', 'new-hostname'), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) - self.servers_mock.get.assert_called_with(self.server.id) - self.image_client.get_image.assert_called_with(self.image.id) - self.server.rebuild.assert_called_with( - self.image, None, hostname='new-hostname' + self.compute_sdk_client.find_server.assert_called_once_with( + self.server.id, ignore_missing=False + ) + self.image_client.find_image.assert_not_called() + self.image_client.get_image.assert_has_calls( + [mock.call(self.image.id), mock.call(self.image.id)] + ) + self.compute_sdk_client.rebuild_server.assert_called_once_with( + self.server, + self.image, + admin_password=None, + hostname='new-hostname', ) def test_rebuild_with_hostname_pre_v290(self): @@ -6877,24 +7006,12 @@ class TestServerRebuildVolumeBacked(TestServer): self.image_client.find_image.return_value = self.new_image attrs = { + 'status': 'ACTIVE', 'image': '', - 'networks': {}, - 'adminPass': 'passw0rd', } - new_server = compute_fakes.create_one_server(attrs=attrs) - - # Fake the server to be rebuilt. The IDs of them should be the same. - attrs['id'] = new_server.id - attrs['status'] = 'ACTIVE' - methods = { - 'rebuild': new_server, - } - self.server = compute_fakes.create_one_server( - attrs=attrs, methods=methods - ) - - # Return value for utils.find_resource for server. - self.servers_mock.get.return_value = self.server + self.server = compute_fakes.create_one_sdk_server(attrs=attrs) + self.compute_sdk_client.find_server.return_value = self.server + self.compute_sdk_client.rebuild_server.return_value = self.server self.cmd = server.RebuildServer(self.app, None) @@ -6912,12 +7029,20 @@ class TestServerRebuildVolumeBacked(TestServer): ('reimage_boot_volume', True), ('image', self.new_image.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.servers_mock.get.assert_called_with(self.server.id) - self.server.rebuild.assert_called_with(self.new_image, None) + self.compute_sdk_client.find_server.assert_called_once_with( + self.server.id, ignore_missing=False + ) + self.image_client.find_image.assert_called_with( + self.new_image.id, ignore_missing=False + ) + self.image_client.get_image.assert_not_called() + self.compute_sdk_client.rebuild_server.assert_called_once_with( + self.server, self.new_image, admin_password=None + ) def test_rebuild_with_no_reimage_boot_volume(self): self.set_compute_api_version('2.93')