compute: Migrate 'server rebuild' to SDK
Change-Id: Ic7cdb05327a4a74364f08451e531d02c631b7633 Signed-off-by: Stephen Finucane <stephenfin@redhat.com> Depends-on: https://review.opendev.org/c/openstack/openstacksdk/+/918730
This commit is contained in:
parent
2057462120
commit
8d904a9efb
@ -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
|
||||
)
|
||||
|
@ -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')
|
||||
|
Loading…
x
Reference in New Issue
Block a user