Switch compute service list, delete and set to sdk.
Switch the compute service commands from novaclient to SDK. Change-Id: I16498905101d6c2702a3ccbaf8cf5e3098d51992
This commit is contained in:
parent
0a887a4786
commit
b5a2714b83
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from novaclient import api_versions
|
from openstack import utils as sdk_utils
|
||||||
from osc_lib.command import command
|
from osc_lib.command import command
|
||||||
from osc_lib import exceptions
|
from osc_lib import exceptions
|
||||||
from osc_lib import utils
|
from osc_lib import utils
|
||||||
@ -40,16 +40,24 @@ class DeleteService(command.Command):
|
|||||||
help=_("Compute service(s) to delete (ID only). If using "
|
help=_("Compute service(s) to delete (ID only). If using "
|
||||||
"``--os-compute-api-version`` 2.53 or greater, the ID is "
|
"``--os-compute-api-version`` 2.53 or greater, the ID is "
|
||||||
"a UUID which can be retrieved by listing compute services "
|
"a UUID which can be retrieved by listing compute services "
|
||||||
"using the same 2.53+ microversion.")
|
"using the same 2.53+ microversion. "
|
||||||
|
"If deleting a compute service, be sure to stop the actual "
|
||||||
|
"compute process on the physical host before deleting the "
|
||||||
|
"service with this command. Failing to do so can lead to "
|
||||||
|
"the running service re-creating orphaned compute_nodes "
|
||||||
|
"table records in the database.")
|
||||||
)
|
)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
compute_client = self.app.client_manager.compute
|
compute_client = self.app.client_manager.sdk_connection.compute
|
||||||
result = 0
|
result = 0
|
||||||
for s in parsed_args.service:
|
for s in parsed_args.service:
|
||||||
try:
|
try:
|
||||||
compute_client.services.delete(s)
|
compute_client.delete_service(
|
||||||
|
s,
|
||||||
|
ignore_missing=False
|
||||||
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
result += 1
|
result += 1
|
||||||
LOG.error(_("Failed to delete compute service with "
|
LOG.error(_("Failed to delete compute service with "
|
||||||
@ -91,38 +99,40 @@ class ListService(command.Lister):
|
|||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
compute_client = self.app.client_manager.compute
|
compute_client = self.app.client_manager.sdk_connection.compute
|
||||||
|
columns = (
|
||||||
|
"id",
|
||||||
|
"binary",
|
||||||
|
"host",
|
||||||
|
"availability_zone",
|
||||||
|
"status",
|
||||||
|
"state",
|
||||||
|
"updated_at",
|
||||||
|
)
|
||||||
|
column_headers = (
|
||||||
|
"ID",
|
||||||
|
"Binary",
|
||||||
|
"Host",
|
||||||
|
"Zone",
|
||||||
|
"Status",
|
||||||
|
"State",
|
||||||
|
"Updated At",
|
||||||
|
)
|
||||||
if parsed_args.long:
|
if parsed_args.long:
|
||||||
columns = (
|
columns += ("disabled_reason",)
|
||||||
"ID",
|
column_headers += ("Disabled Reason",)
|
||||||
"Binary",
|
if sdk_utils.supports_microversion(compute_client, '2.11'):
|
||||||
"Host",
|
columns += ("is_forced_down",)
|
||||||
"Zone",
|
column_headers += ("Forced Down",)
|
||||||
"Status",
|
|
||||||
"State",
|
data = compute_client.services(
|
||||||
"Updated At",
|
host=parsed_args.host,
|
||||||
"Disabled Reason"
|
binary=parsed_args.service
|
||||||
)
|
)
|
||||||
has_forced_down = (
|
return (
|
||||||
compute_client.api_version >= api_versions.APIVersion('2.11'))
|
column_headers,
|
||||||
if has_forced_down:
|
(utils.get_item_properties(s, columns) for s in data)
|
||||||
columns += ("Forced Down",)
|
)
|
||||||
else:
|
|
||||||
columns = (
|
|
||||||
"ID",
|
|
||||||
"Binary",
|
|
||||||
"Host",
|
|
||||||
"Zone",
|
|
||||||
"Status",
|
|
||||||
"State",
|
|
||||||
"Updated At"
|
|
||||||
)
|
|
||||||
data = compute_client.services.list(parsed_args.host,
|
|
||||||
parsed_args.service)
|
|
||||||
return (columns,
|
|
||||||
(utils.get_item_properties(
|
|
||||||
s, columns,
|
|
||||||
) for s in data))
|
|
||||||
|
|
||||||
|
|
||||||
class SetService(command.Command):
|
class SetService(command.Command):
|
||||||
@ -175,7 +185,7 @@ class SetService(command.Command):
|
|||||||
return parser
|
return parser
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _find_service_by_host_and_binary(cs, host, binary):
|
def _find_service_by_host_and_binary(compute_client, host, binary):
|
||||||
"""Utility method to find a compute service by host and binary
|
"""Utility method to find a compute service by host and binary
|
||||||
|
|
||||||
:param host: the name of the compute service host
|
:param host: the name of the compute service host
|
||||||
@ -183,7 +193,7 @@ class SetService(command.Command):
|
|||||||
:returns: novaclient.v2.services.Service dict-like object
|
:returns: novaclient.v2.services.Service dict-like object
|
||||||
:raises: CommandError if no or multiple results were found
|
:raises: CommandError if no or multiple results were found
|
||||||
"""
|
"""
|
||||||
services = cs.list(host=host, binary=binary)
|
services = list(compute_client.services(host=host, binary=binary))
|
||||||
# Did we find anything?
|
# Did we find anything?
|
||||||
if not len(services):
|
if not len(services):
|
||||||
msg = _('Compute service for host "%(host)s" and binary '
|
msg = _('Compute service for host "%(host)s" and binary '
|
||||||
@ -202,8 +212,7 @@ class SetService(command.Command):
|
|||||||
return services[0]
|
return services[0]
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
compute_client = self.app.client_manager.compute
|
compute_client = self.app.client_manager.sdk_connection.compute
|
||||||
cs = compute_client.services
|
|
||||||
|
|
||||||
if (parsed_args.enable or not parsed_args.disable) and \
|
if (parsed_args.enable or not parsed_args.disable) and \
|
||||||
parsed_args.disable_reason:
|
parsed_args.disable_reason:
|
||||||
@ -216,14 +225,17 @@ class SetService(command.Command):
|
|||||||
# services. If 2.53+ is used we need to find the nova-compute
|
# services. If 2.53+ is used we need to find the nova-compute
|
||||||
# service using the --host and --service (binary) values.
|
# service using the --host and --service (binary) values.
|
||||||
requires_service_id = (
|
requires_service_id = (
|
||||||
compute_client.api_version >= api_versions.APIVersion('2.53'))
|
sdk_utils.supports_microversion(compute_client, '2.53'))
|
||||||
service_id = None
|
service_id = None
|
||||||
if requires_service_id:
|
if requires_service_id:
|
||||||
# TODO(mriedem): Add an --id option so users can pass the service
|
# TODO(mriedem): Add an --id option so users can pass the service
|
||||||
# id (as a uuid) directly rather than make us look it up using
|
# id (as a uuid) directly rather than make us look it up using
|
||||||
# host/binary.
|
# host/binary.
|
||||||
service_id = SetService._find_service_by_host_and_binary(
|
service_id = SetService._find_service_by_host_and_binary(
|
||||||
cs, parsed_args.host, parsed_args.service).id
|
compute_client,
|
||||||
|
parsed_args.host,
|
||||||
|
parsed_args.service
|
||||||
|
).id
|
||||||
|
|
||||||
result = 0
|
result = 0
|
||||||
enabled = None
|
enabled = None
|
||||||
@ -235,21 +247,18 @@ class SetService(command.Command):
|
|||||||
|
|
||||||
if enabled is not None:
|
if enabled is not None:
|
||||||
if enabled:
|
if enabled:
|
||||||
args = (service_id,) if requires_service_id else (
|
compute_client.enable_service(
|
||||||
parsed_args.host, parsed_args.service)
|
service_id,
|
||||||
cs.enable(*args)
|
parsed_args.host,
|
||||||
|
parsed_args.service
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
if parsed_args.disable_reason:
|
compute_client.disable_service(
|
||||||
args = (service_id, parsed_args.disable_reason) if \
|
service_id,
|
||||||
requires_service_id else (
|
parsed_args.host,
|
||||||
parsed_args.host,
|
parsed_args.service,
|
||||||
parsed_args.service,
|
parsed_args.disable_reason
|
||||||
parsed_args.disable_reason)
|
)
|
||||||
cs.disable_log_reason(*args)
|
|
||||||
else:
|
|
||||||
args = (service_id,) if requires_service_id else (
|
|
||||||
parsed_args.host, parsed_args.service)
|
|
||||||
cs.disable(*args)
|
|
||||||
except Exception:
|
except Exception:
|
||||||
status = "enabled" if enabled else "disabled"
|
status = "enabled" if enabled else "disabled"
|
||||||
LOG.error("Failed to set service status to %s", status)
|
LOG.error("Failed to set service status to %s", status)
|
||||||
@ -261,15 +270,17 @@ class SetService(command.Command):
|
|||||||
if parsed_args.up:
|
if parsed_args.up:
|
||||||
force_down = False
|
force_down = False
|
||||||
if force_down is not None:
|
if force_down is not None:
|
||||||
if compute_client.api_version < api_versions.APIVersion(
|
if not sdk_utils.supports_microversion(compute_client, '2.11'):
|
||||||
'2.11'):
|
|
||||||
msg = _('--os-compute-api-version 2.11 or later is '
|
msg = _('--os-compute-api-version 2.11 or later is '
|
||||||
'required')
|
'required')
|
||||||
raise exceptions.CommandError(msg)
|
raise exceptions.CommandError(msg)
|
||||||
try:
|
try:
|
||||||
args = (service_id, force_down) if requires_service_id else (
|
compute_client.update_service_forced_down(
|
||||||
parsed_args.host, parsed_args.service, force_down)
|
service_id,
|
||||||
cs.force_down(*args)
|
parsed_args.host,
|
||||||
|
parsed_args.service,
|
||||||
|
force_down
|
||||||
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
state = "down" if force_down else "up"
|
state = "down" if force_down else "up"
|
||||||
LOG.error("Failed to set service state to %s", state)
|
LOG.error("Failed to set service state to %s", state)
|
||||||
|
@ -22,6 +22,7 @@ from novaclient import api_versions
|
|||||||
from openstack.compute.v2 import flavor as _flavor
|
from openstack.compute.v2 import flavor as _flavor
|
||||||
from openstack.compute.v2 import server
|
from openstack.compute.v2 import server
|
||||||
from openstack.compute.v2 import server_interface as _server_interface
|
from openstack.compute.v2 import server_interface as _server_interface
|
||||||
|
from openstack.compute.v2 import service
|
||||||
from openstack.compute.v2 import volume_attachment
|
from openstack.compute.v2 import volume_attachment
|
||||||
|
|
||||||
from openstackclient.api import compute_v2
|
from openstackclient.api import compute_v2
|
||||||
@ -764,7 +765,7 @@ class FakeService(object):
|
|||||||
:param dict attrs:
|
:param dict attrs:
|
||||||
A dictionary with all attributes
|
A dictionary with all attributes
|
||||||
:return:
|
:return:
|
||||||
A FakeResource object, with id, host, binary, and so on
|
A fake Service object, with id, host, binary, and so on
|
||||||
"""
|
"""
|
||||||
attrs = attrs or {}
|
attrs = attrs or {}
|
||||||
|
|
||||||
@ -774,21 +775,18 @@ class FakeService(object):
|
|||||||
'host': 'host-' + uuid.uuid4().hex,
|
'host': 'host-' + uuid.uuid4().hex,
|
||||||
'binary': 'binary-' + uuid.uuid4().hex,
|
'binary': 'binary-' + uuid.uuid4().hex,
|
||||||
'status': 'enabled',
|
'status': 'enabled',
|
||||||
'zone': 'zone-' + uuid.uuid4().hex,
|
'availability_zone': 'zone-' + uuid.uuid4().hex,
|
||||||
'state': 'state-' + uuid.uuid4().hex,
|
'state': 'state-' + uuid.uuid4().hex,
|
||||||
'updated_at': 'time-' + uuid.uuid4().hex,
|
'updated_at': 'time-' + uuid.uuid4().hex,
|
||||||
'disabled_reason': 'earthquake',
|
'disabled_reason': 'earthquake',
|
||||||
# Introduced in API microversion 2.11
|
# Introduced in API microversion 2.11
|
||||||
'forced_down': False,
|
'is_forced_down': False,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Overwrite default attributes.
|
# Overwrite default attributes.
|
||||||
service_info.update(attrs)
|
service_info.update(attrs)
|
||||||
|
|
||||||
service = fakes.FakeResource(info=copy.deepcopy(service_info),
|
return service.Service(**service_info)
|
||||||
loaded=True)
|
|
||||||
|
|
||||||
return service
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_services(attrs=None, count=2):
|
def create_services(attrs=None, count=2):
|
||||||
|
@ -17,6 +17,7 @@ from unittest import mock
|
|||||||
from unittest.mock import call
|
from unittest.mock import call
|
||||||
|
|
||||||
from novaclient import api_versions
|
from novaclient import api_versions
|
||||||
|
from openstack import utils as sdk_utils
|
||||||
from osc_lib import exceptions
|
from osc_lib import exceptions
|
||||||
|
|
||||||
from openstackclient.compute.v2 import service
|
from openstackclient.compute.v2 import service
|
||||||
@ -28,9 +29,9 @@ class TestService(compute_fakes.TestComputev2):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestService, self).setUp()
|
super(TestService, self).setUp()
|
||||||
|
|
||||||
# Get a shortcut to the ServiceManager Mock
|
self.app.client_manager.sdk_connection = mock.Mock()
|
||||||
self.service_mock = self.app.client_manager.compute.services
|
self.app.client_manager.sdk_connection.compute = mock.Mock()
|
||||||
self.service_mock.reset_mock()
|
self.sdk_client = self.app.client_manager.sdk_connection.compute
|
||||||
|
|
||||||
|
|
||||||
class TestServiceDelete(TestService):
|
class TestServiceDelete(TestService):
|
||||||
@ -40,7 +41,7 @@ class TestServiceDelete(TestService):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestServiceDelete, self).setUp()
|
super(TestServiceDelete, self).setUp()
|
||||||
|
|
||||||
self.service_mock.delete.return_value = None
|
self.sdk_client.delete_service.return_value = None
|
||||||
|
|
||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = service.DeleteService(self.app, None)
|
self.cmd = service.DeleteService(self.app, None)
|
||||||
@ -56,8 +57,9 @@ class TestServiceDelete(TestService):
|
|||||||
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
result = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
self.service_mock.delete.assert_called_with(
|
self.sdk_client.delete_service.assert_called_with(
|
||||||
self.services[0].binary,
|
self.services[0].binary,
|
||||||
|
ignore_missing=False
|
||||||
)
|
)
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
|
|
||||||
@ -74,8 +76,8 @@ class TestServiceDelete(TestService):
|
|||||||
|
|
||||||
calls = []
|
calls = []
|
||||||
for s in self.services:
|
for s in self.services:
|
||||||
calls.append(call(s.binary))
|
calls.append(call(s.binary, ignore_missing=False))
|
||||||
self.service_mock.delete.assert_has_calls(calls)
|
self.sdk_client.delete_service.assert_has_calls(calls)
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
|
|
||||||
def test_multi_services_delete_with_exception(self):
|
def test_multi_services_delete_with_exception(self):
|
||||||
@ -89,7 +91,7 @@ class TestServiceDelete(TestService):
|
|||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
delete_mock_result = [None, exceptions.CommandError]
|
delete_mock_result = [None, exceptions.CommandError]
|
||||||
self.service_mock.delete = (
|
self.sdk_client.delete_service = (
|
||||||
mock.Mock(side_effect=delete_mock_result)
|
mock.Mock(side_effect=delete_mock_result)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -100,8 +102,14 @@ class TestServiceDelete(TestService):
|
|||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
'1 of 2 compute services failed to delete.', str(e))
|
'1 of 2 compute services failed to delete.', str(e))
|
||||||
|
|
||||||
self.service_mock.delete.assert_any_call(self.services[0].binary)
|
self.sdk_client.delete_service.assert_any_call(
|
||||||
self.service_mock.delete.assert_any_call('unexist_service')
|
self.services[0].binary,
|
||||||
|
ignore_missing=False
|
||||||
|
)
|
||||||
|
self.sdk_client.delete_service.assert_any_call(
|
||||||
|
'unexist_service',
|
||||||
|
ignore_missing=False
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestServiceList(TestService):
|
class TestServiceList(TestService):
|
||||||
@ -125,7 +133,7 @@ class TestServiceList(TestService):
|
|||||||
service.id,
|
service.id,
|
||||||
service.binary,
|
service.binary,
|
||||||
service.host,
|
service.host,
|
||||||
service.zone,
|
service.availability_zone,
|
||||||
service.status,
|
service.status,
|
||||||
service.state,
|
service.state,
|
||||||
service.updated_at,
|
service.updated_at,
|
||||||
@ -135,7 +143,7 @@ class TestServiceList(TestService):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestServiceList, self).setUp()
|
super(TestServiceList, self).setUp()
|
||||||
|
|
||||||
self.service_mock.list.return_value = [self.service]
|
self.sdk_client.services.return_value = [self.service]
|
||||||
|
|
||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = service.ListService(self.app, None)
|
self.cmd = service.ListService(self.app, None)
|
||||||
@ -156,15 +164,18 @@ class TestServiceList(TestService):
|
|||||||
# containing the data to be listed.
|
# containing the data to be listed.
|
||||||
columns, data = self.cmd.take_action(parsed_args)
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
self.service_mock.list.assert_called_with(
|
self.sdk_client.services.assert_called_with(
|
||||||
self.service.host,
|
host=self.service.host,
|
||||||
self.service.binary,
|
binary=self.service.binary,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(self.data, list(data))
|
self.assertEqual(self.data, list(data))
|
||||||
|
|
||||||
def test_service_list_with_long_option(self):
|
@mock.patch.object(sdk_utils, 'supports_microversion')
|
||||||
|
def test_service_list_with_long_option(self, sm_mock):
|
||||||
|
sm_mock.return_value = False
|
||||||
|
|
||||||
arglist = [
|
arglist = [
|
||||||
'--host', self.service.host,
|
'--host', self.service.host,
|
||||||
'--service', self.service.binary,
|
'--service', self.service.binary,
|
||||||
@ -182,15 +193,18 @@ class TestServiceList(TestService):
|
|||||||
# containing the data to be listed.
|
# containing the data to be listed.
|
||||||
columns, data = self.cmd.take_action(parsed_args)
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
self.service_mock.list.assert_called_with(
|
self.sdk_client.services.assert_called_with(
|
||||||
self.service.host,
|
host=self.service.host,
|
||||||
self.service.binary,
|
binary=self.service.binary,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(self.columns_long, columns)
|
self.assertEqual(self.columns_long, columns)
|
||||||
self.assertEqual(self.data_long, list(data))
|
self.assertEqual(self.data_long, list(data))
|
||||||
|
|
||||||
def test_service_list_with_long_option_2_11(self):
|
@mock.patch.object(sdk_utils, 'supports_microversion')
|
||||||
|
def test_service_list_with_long_option_2_11(self, sm_mock):
|
||||||
|
sm_mock.return_value = True
|
||||||
|
|
||||||
arglist = [
|
arglist = [
|
||||||
'--host', self.service.host,
|
'--host', self.service.host,
|
||||||
'--service', self.service.binary,
|
'--service', self.service.binary,
|
||||||
@ -210,14 +224,14 @@ class TestServiceList(TestService):
|
|||||||
# containing the data to be listed.
|
# containing the data to be listed.
|
||||||
columns, data = self.cmd.take_action(parsed_args)
|
columns, data = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
self.service_mock.list.assert_called_with(
|
self.sdk_client.services.assert_called_with(
|
||||||
self.service.host,
|
host=self.service.host,
|
||||||
self.service.binary,
|
binary=self.service.binary,
|
||||||
)
|
)
|
||||||
|
|
||||||
# In 2.11 there is also a forced_down column.
|
# In 2.11 there is also a forced_down column.
|
||||||
columns_long = self.columns_long + ('Forced Down',)
|
columns_long = self.columns_long + ('Forced Down',)
|
||||||
data_long = [self.data_long[0] + (self.service.forced_down,)]
|
data_long = [self.data_long[0] + (self.service.is_forced_down,)]
|
||||||
|
|
||||||
self.assertEqual(columns_long, columns)
|
self.assertEqual(columns_long, columns)
|
||||||
self.assertEqual(data_long, list(data))
|
self.assertEqual(data_long, list(data))
|
||||||
@ -230,12 +244,14 @@ class TestServiceSet(TestService):
|
|||||||
|
|
||||||
self.service = compute_fakes.FakeService.create_one_service()
|
self.service = compute_fakes.FakeService.create_one_service()
|
||||||
|
|
||||||
self.service_mock.enable.return_value = self.service
|
self.sdk_client.enable_service.return_value = self.service
|
||||||
self.service_mock.disable.return_value = self.service
|
self.sdk_client.disable_service.return_value = self.service
|
||||||
|
|
||||||
self.cmd = service.SetService(self.app, None)
|
self.cmd = service.SetService(self.app, None)
|
||||||
|
|
||||||
def test_set_nothing(self):
|
@mock.patch.object(sdk_utils, 'supports_microversion')
|
||||||
|
def test_set_nothing(self, sm_mock):
|
||||||
|
sm_mock.return_value = False
|
||||||
arglist = [
|
arglist = [
|
||||||
self.service.host,
|
self.service.host,
|
||||||
self.service.binary,
|
self.service.binary,
|
||||||
@ -247,12 +263,13 @@ class TestServiceSet(TestService):
|
|||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
result = self.cmd.take_action(parsed_args)
|
result = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
self.service_mock.enable.assert_not_called()
|
self.sdk_client.enable_service.assert_not_called()
|
||||||
self.service_mock.disable.assert_not_called()
|
self.sdk_client.disable_service.assert_not_called()
|
||||||
self.service_mock.disable_log_reason.assert_not_called()
|
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
|
|
||||||
def test_service_set_enable(self):
|
@mock.patch.object(sdk_utils, 'supports_microversion')
|
||||||
|
def test_service_set_enable(self, sm_mock):
|
||||||
|
sm_mock.return_value = False
|
||||||
arglist = [
|
arglist = [
|
||||||
'--enable',
|
'--enable',
|
||||||
self.service.host,
|
self.service.host,
|
||||||
@ -267,13 +284,16 @@ class TestServiceSet(TestService):
|
|||||||
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
result = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
self.service_mock.enable.assert_called_with(
|
self.sdk_client.enable_service.assert_called_with(
|
||||||
|
None,
|
||||||
self.service.host,
|
self.service.host,
|
||||||
self.service.binary
|
self.service.binary
|
||||||
)
|
)
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
|
|
||||||
def test_service_set_disable(self):
|
@mock.patch.object(sdk_utils, 'supports_microversion')
|
||||||
|
def test_service_set_disable(self, sm_mock):
|
||||||
|
sm_mock.return_value = False
|
||||||
arglist = [
|
arglist = [
|
||||||
'--disable',
|
'--disable',
|
||||||
self.service.host,
|
self.service.host,
|
||||||
@ -288,13 +308,17 @@ class TestServiceSet(TestService):
|
|||||||
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
result = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
self.service_mock.disable.assert_called_with(
|
self.sdk_client.disable_service.assert_called_with(
|
||||||
|
None,
|
||||||
self.service.host,
|
self.service.host,
|
||||||
self.service.binary
|
self.service.binary,
|
||||||
|
None
|
||||||
)
|
)
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
|
|
||||||
def test_service_set_disable_with_reason(self):
|
@mock.patch.object(sdk_utils, 'supports_microversion')
|
||||||
|
def test_service_set_disable_with_reason(self, sm_mock):
|
||||||
|
sm_mock.return_value = False
|
||||||
reason = 'earthquake'
|
reason = 'earthquake'
|
||||||
arglist = [
|
arglist = [
|
||||||
'--disable',
|
'--disable',
|
||||||
@ -312,14 +336,17 @@ class TestServiceSet(TestService):
|
|||||||
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
result = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
self.service_mock.disable_log_reason.assert_called_with(
|
self.sdk_client.disable_service.assert_called_with(
|
||||||
|
None,
|
||||||
self.service.host,
|
self.service.host,
|
||||||
self.service.binary,
|
self.service.binary,
|
||||||
reason
|
reason
|
||||||
)
|
)
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
|
|
||||||
def test_service_set_only_with_disable_reason(self):
|
@mock.patch.object(sdk_utils, 'supports_microversion')
|
||||||
|
def test_service_set_only_with_disable_reason(self, sm_mock):
|
||||||
|
sm_mock.return_value = False
|
||||||
reason = 'earthquake'
|
reason = 'earthquake'
|
||||||
arglist = [
|
arglist = [
|
||||||
'--disable-reason', reason,
|
'--disable-reason', reason,
|
||||||
@ -339,7 +366,9 @@ class TestServiceSet(TestService):
|
|||||||
self.assertEqual("Cannot specify option --disable-reason without "
|
self.assertEqual("Cannot specify option --disable-reason without "
|
||||||
"--disable specified.", str(e))
|
"--disable specified.", str(e))
|
||||||
|
|
||||||
def test_service_set_enable_with_disable_reason(self):
|
@mock.patch.object(sdk_utils, 'supports_microversion')
|
||||||
|
def test_service_set_enable_with_disable_reason(self, sm_mock):
|
||||||
|
sm_mock.return_value = False
|
||||||
reason = 'earthquake'
|
reason = 'earthquake'
|
||||||
arglist = [
|
arglist = [
|
||||||
'--enable',
|
'--enable',
|
||||||
@ -361,7 +390,9 @@ class TestServiceSet(TestService):
|
|||||||
self.assertEqual("Cannot specify option --disable-reason without "
|
self.assertEqual("Cannot specify option --disable-reason without "
|
||||||
"--disable specified.", str(e))
|
"--disable specified.", str(e))
|
||||||
|
|
||||||
def test_service_set_state_up(self):
|
@mock.patch.object(sdk_utils, 'supports_microversion')
|
||||||
|
def test_service_set_state_up(self, sm_mock):
|
||||||
|
sm_mock.side_effect = [False, True]
|
||||||
arglist = [
|
arglist = [
|
||||||
'--up',
|
'--up',
|
||||||
self.service.host,
|
self.service.host,
|
||||||
@ -373,16 +404,20 @@ class TestServiceSet(TestService):
|
|||||||
('service', self.service.binary),
|
('service', self.service.binary),
|
||||||
]
|
]
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
self.app.client_manager.compute.api_version = api_versions.APIVersion(
|
|
||||||
'2.11')
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
result = self.cmd.take_action(parsed_args)
|
||||||
self.service_mock.force_down.assert_called_once_with(
|
self.sdk_client.update_service_forced_down.assert_called_once_with(
|
||||||
self.service.host, self.service.binary, False)
|
None,
|
||||||
self.assertNotCalled(self.service_mock.enable)
|
self.service.host,
|
||||||
self.assertNotCalled(self.service_mock.disable)
|
self.service.binary,
|
||||||
|
False
|
||||||
|
)
|
||||||
|
self.assertNotCalled(self.sdk_client.enable_service)
|
||||||
|
self.assertNotCalled(self.sdk_client.disable_service)
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
|
|
||||||
def test_service_set_state_down(self):
|
@mock.patch.object(sdk_utils, 'supports_microversion')
|
||||||
|
def test_service_set_state_down(self, sm_mock):
|
||||||
|
sm_mock.side_effect = [False, True]
|
||||||
arglist = [
|
arglist = [
|
||||||
'--down',
|
'--down',
|
||||||
self.service.host,
|
self.service.host,
|
||||||
@ -394,16 +429,20 @@ class TestServiceSet(TestService):
|
|||||||
('service', self.service.binary),
|
('service', self.service.binary),
|
||||||
]
|
]
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
self.app.client_manager.compute.api_version = api_versions.APIVersion(
|
|
||||||
'2.11')
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
result = self.cmd.take_action(parsed_args)
|
||||||
self.service_mock.force_down.assert_called_once_with(
|
self.sdk_client.update_service_forced_down.assert_called_once_with(
|
||||||
self.service.host, self.service.binary, True)
|
None,
|
||||||
self.assertNotCalled(self.service_mock.enable)
|
self.service.host,
|
||||||
self.assertNotCalled(self.service_mock.disable)
|
self.service.binary,
|
||||||
|
True
|
||||||
|
)
|
||||||
|
self.assertNotCalled(self.sdk_client.enable_service)
|
||||||
|
self.assertNotCalled(self.sdk_client.disable_service)
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
|
|
||||||
def test_service_set_enable_and_state_down(self):
|
@mock.patch.object(sdk_utils, 'supports_microversion')
|
||||||
|
def test_service_set_enable_and_state_down(self, sm_mock):
|
||||||
|
sm_mock.side_effect = [False, True]
|
||||||
arglist = [
|
arglist = [
|
||||||
'--enable',
|
'--enable',
|
||||||
'--down',
|
'--down',
|
||||||
@ -417,16 +456,23 @@ class TestServiceSet(TestService):
|
|||||||
('service', self.service.binary),
|
('service', self.service.binary),
|
||||||
]
|
]
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
self.app.client_manager.compute.api_version = api_versions.APIVersion(
|
|
||||||
'2.11')
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
result = self.cmd.take_action(parsed_args)
|
||||||
self.service_mock.enable.assert_called_once_with(
|
self.sdk_client.enable_service.assert_called_once_with(
|
||||||
self.service.host, self.service.binary)
|
None,
|
||||||
self.service_mock.force_down.assert_called_once_with(
|
self.service.host,
|
||||||
self.service.host, self.service.binary, True)
|
self.service.binary
|
||||||
|
)
|
||||||
|
self.sdk_client.update_service_forced_down.assert_called_once_with(
|
||||||
|
None,
|
||||||
|
self.service.host,
|
||||||
|
self.service.binary,
|
||||||
|
True
|
||||||
|
)
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
|
|
||||||
def test_service_set_enable_and_state_down_with_exception(self):
|
@mock.patch.object(sdk_utils, 'supports_microversion')
|
||||||
|
def test_service_set_enable_and_state_down_with_exception(self, sm_mock):
|
||||||
|
sm_mock.side_effect = [False, True]
|
||||||
arglist = [
|
arglist = [
|
||||||
'--enable',
|
'--enable',
|
||||||
'--down',
|
'--down',
|
||||||
@ -441,18 +487,22 @@ class TestServiceSet(TestService):
|
|||||||
]
|
]
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
self.app.client_manager.compute.api_version = api_versions.APIVersion(
|
with mock.patch.object(self.sdk_client, 'enable_service',
|
||||||
'2.11')
|
|
||||||
with mock.patch.object(self.service_mock, 'enable',
|
|
||||||
side_effect=Exception()):
|
side_effect=Exception()):
|
||||||
self.assertRaises(exceptions.CommandError,
|
self.assertRaises(exceptions.CommandError,
|
||||||
self.cmd.take_action, parsed_args)
|
self.cmd.take_action, parsed_args)
|
||||||
self.service_mock.force_down.assert_called_once_with(
|
self.sdk_client.update_service_forced_down.assert_called_once_with(
|
||||||
self.service.host, self.service.binary, True)
|
None,
|
||||||
|
self.service.host,
|
||||||
|
self.service.binary,
|
||||||
|
True
|
||||||
|
)
|
||||||
|
|
||||||
def test_service_set_2_53_disable_down(self):
|
@mock.patch.object(sdk_utils, 'supports_microversion')
|
||||||
|
def test_service_set_2_53_disable_down(self, sm_mock):
|
||||||
# Tests disabling and forcing down a compute service with microversion
|
# Tests disabling and forcing down a compute service with microversion
|
||||||
# 2.53 which requires looking up the service by host and binary.
|
# 2.53 which requires looking up the service by host and binary.
|
||||||
|
sm_mock.return_value = True
|
||||||
arglist = [
|
arglist = [
|
||||||
'--disable',
|
'--disable',
|
||||||
'--down',
|
'--down',
|
||||||
@ -466,18 +516,27 @@ class TestServiceSet(TestService):
|
|||||||
('service', self.service.binary),
|
('service', self.service.binary),
|
||||||
]
|
]
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
self.app.client_manager.compute.api_version = api_versions.APIVersion(
|
|
||||||
'2.53')
|
|
||||||
service_id = '339478d0-0b95-4a94-be63-d5be05dfeb1c'
|
service_id = '339478d0-0b95-4a94-be63-d5be05dfeb1c'
|
||||||
self.service_mock.list.return_value = [mock.Mock(id=service_id)]
|
self.sdk_client.services.return_value = [mock.Mock(id=service_id)]
|
||||||
result = self.cmd.take_action(parsed_args)
|
result = self.cmd.take_action(parsed_args)
|
||||||
self.service_mock.disable.assert_called_once_with(service_id)
|
self.sdk_client.disable_service.assert_called_once_with(
|
||||||
self.service_mock.force_down.assert_called_once_with(service_id, True)
|
service_id,
|
||||||
|
self.service.host,
|
||||||
|
self.service.binary,
|
||||||
|
None
|
||||||
|
)
|
||||||
|
self.sdk_client.update_service_forced_down.assert_called_once_with(
|
||||||
|
service_id,
|
||||||
|
self.service.host,
|
||||||
|
self.service.binary,
|
||||||
|
True)
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
|
|
||||||
def test_service_set_2_53_disable_reason(self):
|
@mock.patch.object(sdk_utils, 'supports_microversion')
|
||||||
|
def test_service_set_2_53_disable_reason(self, sm_mock):
|
||||||
# Tests disabling with reason a compute service with microversion
|
# Tests disabling with reason a compute service with microversion
|
||||||
# 2.53 which requires looking up the service by host and binary.
|
# 2.53 which requires looking up the service by host and binary.
|
||||||
|
sm_mock.return_value = True
|
||||||
reason = 'earthquake'
|
reason = 'earthquake'
|
||||||
arglist = [
|
arglist = [
|
||||||
'--disable',
|
'--disable',
|
||||||
@ -492,18 +551,22 @@ class TestServiceSet(TestService):
|
|||||||
('service', self.service.binary),
|
('service', self.service.binary),
|
||||||
]
|
]
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
self.app.client_manager.compute.api_version = api_versions.APIVersion(
|
|
||||||
'2.53')
|
|
||||||
service_id = '339478d0-0b95-4a94-be63-d5be05dfeb1c'
|
service_id = '339478d0-0b95-4a94-be63-d5be05dfeb1c'
|
||||||
self.service_mock.list.return_value = [mock.Mock(id=service_id)]
|
self.sdk_client.services.return_value = [mock.Mock(id=service_id)]
|
||||||
result = self.cmd.take_action(parsed_args)
|
result = self.cmd.take_action(parsed_args)
|
||||||
self.service_mock.disable_log_reason.assert_called_once_with(
|
self.sdk_client.disable_service.assert_called_once_with(
|
||||||
service_id, reason)
|
service_id,
|
||||||
|
self.service.host,
|
||||||
|
self.service.binary,
|
||||||
|
reason
|
||||||
|
)
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
|
|
||||||
def test_service_set_2_53_enable_up(self):
|
@mock.patch.object(sdk_utils, 'supports_microversion')
|
||||||
|
def test_service_set_2_53_enable_up(self, sm_mock):
|
||||||
# Tests enabling and bringing up a compute service with microversion
|
# Tests enabling and bringing up a compute service with microversion
|
||||||
# 2.53 which requires looking up the service by host and binary.
|
# 2.53 which requires looking up the service by host and binary.
|
||||||
|
sm_mock.return_value = True
|
||||||
arglist = [
|
arglist = [
|
||||||
'--enable',
|
'--enable',
|
||||||
'--up',
|
'--up',
|
||||||
@ -517,30 +580,37 @@ class TestServiceSet(TestService):
|
|||||||
('service', self.service.binary),
|
('service', self.service.binary),
|
||||||
]
|
]
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
self.app.client_manager.compute.api_version = api_versions.APIVersion(
|
|
||||||
'2.53')
|
|
||||||
service_id = '339478d0-0b95-4a94-be63-d5be05dfeb1c'
|
service_id = '339478d0-0b95-4a94-be63-d5be05dfeb1c'
|
||||||
self.service_mock.list.return_value = [mock.Mock(id=service_id)]
|
self.sdk_client.services.return_value = [mock.Mock(id=service_id)]
|
||||||
result = self.cmd.take_action(parsed_args)
|
result = self.cmd.take_action(parsed_args)
|
||||||
self.service_mock.enable.assert_called_once_with(service_id)
|
self.sdk_client.enable_service.assert_called_once_with(
|
||||||
self.service_mock.force_down.assert_called_once_with(service_id, False)
|
service_id,
|
||||||
|
self.service.host,
|
||||||
|
self.service.binary
|
||||||
|
)
|
||||||
|
self.sdk_client.update_service_forced_down.assert_called_once_with(
|
||||||
|
service_id,
|
||||||
|
self.service.host,
|
||||||
|
self.service.binary,
|
||||||
|
False
|
||||||
|
)
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
|
|
||||||
def test_service_set_find_service_by_host_and_binary_no_results(self):
|
def test_service_set_find_service_by_host_and_binary_no_results(self):
|
||||||
# Tests that no compute services are found by host and binary.
|
# Tests that no compute services are found by host and binary.
|
||||||
self.service_mock.list.return_value = []
|
self.sdk_client.services.return_value = []
|
||||||
ex = self.assertRaises(exceptions.CommandError,
|
ex = self.assertRaises(exceptions.CommandError,
|
||||||
self.cmd._find_service_by_host_and_binary,
|
self.cmd._find_service_by_host_and_binary,
|
||||||
self.service_mock, 'fake-host', 'nova-compute')
|
self.sdk_client, 'fake-host', 'nova-compute')
|
||||||
self.assertIn('Compute service for host "fake-host" and binary '
|
self.assertIn('Compute service for host "fake-host" and binary '
|
||||||
'"nova-compute" not found.', str(ex))
|
'"nova-compute" not found.', str(ex))
|
||||||
|
|
||||||
def test_service_set_find_service_by_host_and_binary_many_results(self):
|
def test_service_set_find_service_by_host_and_binary_many_results(self):
|
||||||
# Tests that more than one compute service is found by host and binary.
|
# Tests that more than one compute service is found by host and binary.
|
||||||
self.service_mock.list.return_value = [mock.Mock(), mock.Mock()]
|
self.sdk_client.services.return_value = [mock.Mock(), mock.Mock()]
|
||||||
ex = self.assertRaises(exceptions.CommandError,
|
ex = self.assertRaises(exceptions.CommandError,
|
||||||
self.cmd._find_service_by_host_and_binary,
|
self.cmd._find_service_by_host_and_binary,
|
||||||
self.service_mock, 'fake-host', 'nova-compute')
|
self.sdk_client, 'fake-host', 'nova-compute')
|
||||||
self.assertIn('Multiple compute services found for host "fake-host" '
|
self.assertIn('Multiple compute services found for host "fake-host" '
|
||||||
'and binary "nova-compute". Unable to proceed.',
|
'and binary "nova-compute". Unable to proceed.',
|
||||||
str(ex))
|
str(ex))
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
features:
|
||||||
|
- |
|
||||||
|
Switch the compute service commands from novaclient to SDK.
|
Loading…
Reference in New Issue
Block a user