From b43a4ce74766b2c1494d1c0a798f00f7204ca40b Mon Sep 17 00:00:00 2001 From: suzhengwei Date: Mon, 13 Feb 2023 17:30:08 +0800 Subject: [PATCH] support for Masakari VMove It supports Masakari VMove API in microversion 1.3. Change-Id: Ic8b50de98b0d44b832944f2e57567a8e0c3faca5 --- masakariclient/osc/v1/vmove.py | 134 ++++++++++++++++++ masakariclient/plugin.py | 3 +- .../tests/unit/osc/v1/test_vmove.py | 93 ++++++++++++ ...blueprint-add-vmoves-a74335fec8446523.yaml | 5 + setup.cfg | 2 + 5 files changed, 236 insertions(+), 1 deletion(-) create mode 100644 masakariclient/osc/v1/vmove.py create mode 100644 masakariclient/tests/unit/osc/v1/test_vmove.py create mode 100644 releasenotes/notes/blueprint-add-vmoves-a74335fec8446523.yaml diff --git a/masakariclient/osc/v1/vmove.py b/masakariclient/osc/v1/vmove.py new file mode 100644 index 0000000..13f4fc8 --- /dev/null +++ b/masakariclient/osc/v1/vmove.py @@ -0,0 +1,134 @@ +# Copyright(c) 2022 Inspur +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging + +from openstack import exceptions as sdk_exc +from osc_lib.command import command +from osc_lib import exceptions +from osc_lib import utils + +from masakariclient.common.i18n import _ +import masakariclient.common.utils as masakariclient_utils + +# Get the logger of this module +LOG = logging.getLogger(__name__) + + +class ListVMove(command.Lister): + """List VMoves.""" + + def get_parser(self, prog_name): + parser = super(ListVMove, self).get_parser(prog_name) + parser.add_argument( + 'notification_id', + metavar='', + help=_('UUID of notification.') + ) + parser.add_argument( + '--limit', + metavar='', + help=_('Limit the number of vmoves returned') + ) + parser.add_argument( + '--marker', + metavar='', + help=_('Only return vmoves that appear after the given vmove ID') + ) + parser.add_argument( + '--sort', + metavar='[:]', + help=_("Sorting option which is a string containing a list of " + "keys separated by commas. Each key can be optionally " + "appended by a sort direction (:asc or :desc). The valid " + "sort keys are: ['type', 'status', 'start_time', " + "'end_time']") + ) + parser.add_argument( + '--filters', + metavar='<"key1=value1;key2=value2...">', + help=_("Filter parameters to apply on returned vmoves. " + "This can be specified multiple times, or once with " + "parameters separated by a semicolon. The valid filter " + "keys are: ['type', 'status'"), + action='append' + ) + return parser + + def take_action(self, parsed_args): + masakari_client = self.app.client_manager.ha + + columns = ['uuid', 'server_id', 'server_name', + 'source_host', 'dest_host', + 'start_time', 'end_time', + 'type', 'status'] + + queries = masakariclient_utils.format_sort_filter_params(parsed_args) + vmoves = masakari_client.vmoves(parsed_args.notification_id, + **queries) + formatters = {} + return ( + columns, + (utils.get_item_properties(p, columns, formatters=formatters) + for p in vmoves) + ) + + +class ShowVMove(command.ShowOne): + """Show vmove details.""" + + def get_parser(self, prog_name): + parser = super(ShowVMove, self).get_parser(prog_name) + parser.add_argument( + 'notification_id', + metavar='', + help=_('UUID of COMPUTE_NODE type notification.') + ) + parser.add_argument( + 'vmove_id', + metavar='', + help='UUID of the VMove', + ) + return parser + + def take_action(self, parsed_args): + masakari_client = self.app.client_manager.ha + return _show_vmove(masakari_client, parsed_args.notification_id, + parsed_args.vmove_id) + + +def _show_vmove(masakari_client, notification_id, vmove_id): + try: + vmove = masakari_client.get_vmove(vmove_id, notification_id) + except sdk_exc.ResourceNotFound: + raise exceptions.CommandError(_('VMove %s is not found.') + % vmove_id) + + formatters = {} + columns = [ + 'created_at', + 'updated_at', + 'uuid', + 'server_id', + 'server_name', + 'source_host', + 'dest_host', + 'start_time', + 'end_time', + 'type', + 'status', + 'message' + ] + return columns, utils.get_dict_properties(vmove.to_dict(), columns, + formatters=formatters) diff --git a/masakariclient/plugin.py b/masakariclient/plugin.py index 36f8609..0444c35 100644 --- a/masakariclient/plugin.py +++ b/masakariclient/plugin.py @@ -19,7 +19,7 @@ from osc_lib import utils LOG = logging.getLogger(__name__) -DEFAULT_HA_API_VERSION = '1.2' +DEFAULT_HA_API_VERSION = '1.3' API_VERSION_OPTION = 'os_ha_api_version' API_NAME = 'ha' @@ -28,6 +28,7 @@ SUPPORTED_VERSIONS = [ '1.0', '1.1', '1.2', + '1.3', ] API_VERSIONS = {v: None diff --git a/masakariclient/tests/unit/osc/v1/test_vmove.py b/masakariclient/tests/unit/osc/v1/test_vmove.py new file mode 100644 index 0000000..a3c7066 --- /dev/null +++ b/masakariclient/tests/unit/osc/v1/test_vmove.py @@ -0,0 +1,93 @@ +# Copyright(c) 2022 Inspur +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from unittest import mock +import uuid + +from osc_lib import utils + +from masakariclient.osc.v1.vmove import ShowVMove +from masakariclient.tests import base + +VMOVE_ID = uuid.uuid4() +NOTIFICATION_ID = uuid.uuid4() +SERVER_ID = uuid.uuid4() + + +class FakeNamespace(object): + """Fake parser object.""" + def __init__(self, notification_id=None, vmove_id=None): + super(FakeNamespace, self).__init__() + self.notification_id = notification_id + self.vmove_id = vmove_id + + +class FakeVMove(object): + """Fake notification show detail.""" + def __init__(self,): + super(FakeVMove, self).__init__() + + def to_dict(self): + return { + 'created_at': '2023-01-28T14:55:27.000000', + 'uuid': VMOVE_ID, + 'notification_id': NOTIFICATION_ID, + 'server_id': SERVER_ID, + 'server_name': 'test', + 'source_host': 'host1', + 'dest_host': 'host2', + 'start_time': '2023-01-28T14:55:27.000000', + 'end_time': "2023-01-28T14:55:31.000000", + 'status': 'succeeded', + 'type': 'evacuation', + 'message': None, + } + + +class BaseV1VMove(base.TestCase): + def setUp(self): + super(BaseV1VMove, self).setUp() + + self.app = mock.Mock() + self.app_args = mock.Mock() + self.client_manager = mock.Mock() + self.app.client_manager.ha = self.client_manager + self.columns = [ + 'created_at', 'updated_at', + 'uuid', 'server_id', 'server_name', + 'source_host', 'dest_host', + 'start_time', 'end_time', + 'type', 'status', 'message' + ] + self.dummy_vmove = FakeVMove() + + +class TestV1ShowVMove(BaseV1VMove): + def setUp(self): + super(TestV1ShowVMove, self).setUp() + self.show_vmove = ShowVMove(self.app, self.app_args, + cmd_name='vmove show') + + @mock.patch.object(utils, 'get_dict_properties') + def test_take_action(self, mock_get_dict_properties): + parsed_args = FakeNamespace(notification_id=NOTIFICATION_ID, + vmove_id=VMOVE_ID) + self.app.client_manager.ha.get_vmove.return_value = self.dummy_vmove + + # show the vmove specified by uuid + self.show_vmove.take_action(parsed_args) + self.app.client_manager.ha.get_vmove.assert_called_once_with( + VMOVE_ID, NOTIFICATION_ID) + mock_get_dict_properties.assert_called_once_with( + self.dummy_vmove.to_dict(), self.columns, formatters={}) diff --git a/releasenotes/notes/blueprint-add-vmoves-a74335fec8446523.yaml b/releasenotes/notes/blueprint-add-vmoves-a74335fec8446523.yaml new file mode 100644 index 0000000..5916127 --- /dev/null +++ b/releasenotes/notes/blueprint-add-vmoves-a74335fec8446523.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Adds support for Masakari VMove API in microversion 1.3. + `Blueprint vm-evacuations-for-host-recovery `__ diff --git a/setup.cfg b/setup.cfg index af9ecdb..34301df 100644 --- a/setup.cfg +++ b/setup.cfg @@ -32,6 +32,8 @@ openstack.ha.v1 = notification_create = masakariclient.osc.v1.notification:CreateNotification notification_show = masakariclient.osc.v1.notification:ShowNotification notification_list = masakariclient.osc.v1.notification:ListNotification + notification_vmove_show = masakariclient.osc.v1.vmove:ShowVMove + notification_vmove_list = masakariclient.osc.v1.vmove:ListVMove segment_create = masakariclient.osc.v1.segment:CreateSegment segment_update = masakariclient.osc.v1.segment:UpdateSegment segment_delete = masakariclient.osc.v1.segment:DeleteSegment