From 922a885aec53523d6d200a638e438dd7d625c045 Mon Sep 17 00:00:00 2001 From: Stefan Dinescu Date: Thu, 19 Dec 2019 15:47:00 +0200 Subject: [PATCH] Allow yaml formatting for controllerfs-list In oder to be easily parsed by ansible, the controllerfs-list command should support yaml output format. Change-Id: Ic766980645d618d54d34bd04d82339fd2cd36562 Depends-On: https://review.opendev.org/#/c/749492/ Partial-bug: 1854169 Signed-off-by: Stefan Dinescu (cherry picked from master commit b0e76a69277441b6becec6533214bdbbb38e6058) --- .../cgtsclient/tests/v1/test_controllerfs.py | 123 ++++++++++++++++ .../tests/v1/test_controllerfs_shell.py | 131 ++++++++++++++++++ .../cgtsclient/v1/controller_fs_shell.py | 36 +++-- 3 files changed, 282 insertions(+), 8 deletions(-) create mode 100644 sysinv/cgts-client/cgts-client/cgtsclient/tests/v1/test_controllerfs.py create mode 100644 sysinv/cgts-client/cgts-client/cgtsclient/tests/v1/test_controllerfs_shell.py diff --git a/sysinv/cgts-client/cgts-client/cgtsclient/tests/v1/test_controllerfs.py b/sysinv/cgts-client/cgts-client/cgtsclient/tests/v1/test_controllerfs.py new file mode 100644 index 0000000000..5056481a5a --- /dev/null +++ b/sysinv/cgts-client/cgts-client/cgtsclient/tests/v1/test_controllerfs.py @@ -0,0 +1,123 @@ +# +# Copyright (c) 2020 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +import copy +import testtools + +from cgtsclient.tests import utils +import cgtsclient.v1.controller_fs + +CONTROLLER_FS = { + 'uuid': '66666666-7777-8888-9999-000000000000', + 'name': 'cfs', + 'size': 10, + 'logical_volume': 'cfs-lv', + 'replicated': True, + 'state': 'available' +} + +UPDATED_CONTROLLER_FS = copy.deepcopy(CONTROLLER_FS) +NEW_SIZE = 20 +UPDATED_CONTROLLER_FS['size'] = NEW_SIZE +SYSTEM_UUID = "11111111-2222-3333-4444-5555-000000000000" + +fixtures = { + '/v1/controller_fs': + { + 'GET': ( + {}, + {"controller_fs": [CONTROLLER_FS]}, + ), + }, + '/v1/controller_fs/%s' % CONTROLLER_FS['uuid']: + { + 'GET': ( + {}, + CONTROLLER_FS, + ), + 'PATCH': ( + {}, + UPDATED_CONTROLLER_FS, + ), + }, + '/v1/isystems/%s/controller_fs/update_many' % SYSTEM_UUID: + { + 'PUT': ( + {}, + {}, + ), + }, +} + + +class ControllerFsManagerTest(testtools.TestCase): + + def setUp(self): + super(ControllerFsManagerTest, self).setUp() + self.api = utils.FakeAPI(fixtures) + self.mgr = cgtsclient.v1.controller_fs.ControllerFsManager(self.api) + + def test_controller_fs_list(self): + controllerfs = self.mgr.list() + expect = [ + ('GET', '/v1/controller_fs', {}, None), + ] + self.assertEqual(self.api.calls, expect) + self.assertEqual(len(controllerfs), 1) + + def test_controller_fs_show(self): + controllerfs = self.mgr.get(CONTROLLER_FS['uuid']) + expect = [ + ('GET', '/v1/controller_fs/%s' % CONTROLLER_FS['uuid'], {}, None), + ] + self.assertEqual(self.api.calls, expect) + self.assertEqual(controllerfs.uuid, CONTROLLER_FS['uuid']) + + def test_controller_fs_update(self): + patch = [ + { + 'op': 'replace', + 'value': NEW_SIZE, + 'path': '/size' + }, + { + 'op': 'replace', + 'value': CONTROLLER_FS['name'], + 'path': '/name' + } + ] + controllerfs = self.mgr.update(CONTROLLER_FS['uuid'], patch) + expect = [ + ('PATCH', '/v1/controller_fs/%s' % CONTROLLER_FS['uuid'], {}, patch), + ] + self.assertEqual(self.api.calls, expect) + self.assertEqual(controllerfs.size, NEW_SIZE) + + def test_controller_fs_update_many(self): + # One patch is a list of two dictionaries. + # for update_many, this is a list of lists + patches = [ + [ + { + 'op': 'replace', + 'value': NEW_SIZE, + 'path': '/size' + }, + { + 'op': 'replace', + 'value': CONTROLLER_FS['name'], + 'path': '/name' + } + ] + ] + self.mgr.update_many(SYSTEM_UUID, patches) + expect = [ + ('PUT', '/v1/isystems/%s/controller_fs/update_many' % SYSTEM_UUID, {}, patches), + ] + + # Since update_many is just a PUT, we don't expect any output from it, so we can't + # do a proper asert here. We just check if the request made is the one we expected. + self.assertEqual(self.api.calls, expect) diff --git a/sysinv/cgts-client/cgts-client/cgtsclient/tests/v1/test_controllerfs_shell.py b/sysinv/cgts-client/cgts-client/cgtsclient/tests/v1/test_controllerfs_shell.py new file mode 100644 index 0000000000..acdd710c7e --- /dev/null +++ b/sysinv/cgts-client/cgts-client/cgtsclient/tests/v1/test_controllerfs_shell.py @@ -0,0 +1,131 @@ +# +# Copyright (c) 2020 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +import copy +import mock + +from cgtsclient.tests import test_shell +from cgtsclient.v1.controller_fs import ControllerFs +from cgtsclient.v1.isystem import isystem + +FAKE_CONTROLLER_FS = { + 'uuid': '66666666-7777-8888-9999-000000000000', + 'name': 'fake', + 'size': 10, + 'logical_volume': 'fake-lv', + 'replicated': True, + 'state': 'available', + 'created_at': None, + 'updated_at': None +} + +FAKE_ISYSTEM = { + 'uuid': '11111111-2222-3333-4444-5555-000000000000' +} + +MODIFY_CONTROLLER_FS = copy.deepcopy(FAKE_CONTROLLER_FS) +MODIFY_CONTROLLER_FS['size'] = 15 +MODIFY_CONTROLLER_FS['state'] = 'drbd_fs_resizing_in_progress' + + +class ControllerFsTest(test_shell.ShellTest): + + def setUp(self): + super(ControllerFsTest, self).setUp() + + # Mock the client + p = mock.patch('cgtsclient.client._get_endpoint') + self.mock_cgtsclient_client_get_endpoint = p.start() + self.mock_cgtsclient_client_get_endpoint.return_value = \ + 'http://fakelocalhost:6385/v1' + self.addCleanup(p.stop) + p = mock.patch('cgtsclient.client._get_ksclient') + self.mock_cgtsclient_client_get_ksclient = p.start() + self.addCleanup(p.stop) + + # Mock the ControllerFsManager + self.controller_fs_manager_list_result = [ + ControllerFs(None, FAKE_CONTROLLER_FS, True)] + + def mock_controller_fs_manager_list(obj): + return self.controller_fs_manager_list_result + self.mocked_controller_fs_manager_list = mock.patch( + 'cgtsclient.v1.controller_fs.ControllerFsManager.list', + mock_controller_fs_manager_list) + self.mocked_controller_fs_manager_list.start() + self.addCleanup(self.mocked_controller_fs_manager_list.stop) + + self.controller_fs_manager_get_result = \ + ControllerFs(None, FAKE_CONTROLLER_FS, True) + + def mock_controller_fs_manager_get(obj): + return self.controller_fs_manager_get_result + self.mocked_controller_fs_manager_get = mock.patch( + 'cgtsclient.v1.controller_fs.ControllerFsManager.get', + mock_controller_fs_manager_get) + self.mocked_controller_fs_manager_get.start() + self.addCleanup(self.mocked_controller_fs_manager_get.stop) + + def mock_controller_fs_manager_update_many(obj, system_uuid, patch_list): + return None + + self.mocked_controller_fs_manager_update_many = mock.patch( + 'cgtsclient.v1.controller_fs.ControllerFsManager.update_many', + mock_controller_fs_manager_update_many) + self.mocked_controller_fs_manager_update_many.start() + self.addCleanup(self.mocked_controller_fs_manager_update_many.stop) + + # Mock isystemManager + self.isystem_manager_list_result = [ + isystem(None, FAKE_ISYSTEM, None)] + + def mock_isystem_manager_list(obj): + return self.isystem_manager_list_result + + self.mocked_isystem_manager_list = mock.patch( + 'cgtsclient.v1.isystem.isystemManager.list', + mock_isystem_manager_list) + self.mocked_isystem_manager_list.start() + self.addCleanup(self.mocked_isystem_manager_list.stop) + + def test_controller_fs_list(self): + self.make_env() + + results = self.shell("controllerfs-list --nowrap") + + self.assertIn(str(FAKE_CONTROLLER_FS['uuid']), results) + self.assertIn(str(FAKE_CONTROLLER_FS['name']), results) + self.assertIn(str(FAKE_CONTROLLER_FS['size']), results) + self.assertIn(str(FAKE_CONTROLLER_FS['logical_volume']), results) + self.assertIn(str(FAKE_CONTROLLER_FS['replicated']), results) + self.assertIn(str(FAKE_CONTROLLER_FS['state']), results) + + def test_controller_fs_show(self): + self.make_env() + + result = self.shell("controllerfs-show fake") + self.assertIn(str(FAKE_CONTROLLER_FS['uuid']), result) + self.assertIn(str(FAKE_CONTROLLER_FS['name']), result) + self.assertIn(str(FAKE_CONTROLLER_FS['size']), result) + self.assertIn(str(FAKE_CONTROLLER_FS['logical_volume']), result) + self.assertIn(str(FAKE_CONTROLLER_FS['replicated']), result) + self.assertIn(str(FAKE_CONTROLLER_FS['state']), result) + self.assertIn(str(FAKE_CONTROLLER_FS['created_at']), result) + self.assertIn(str(FAKE_CONTROLLER_FS['updated_at']), result) + + def test_controller_fs_modify(self): + self.make_env() + self.controller_fs_manager_list_result = [ + ControllerFs(None, MODIFY_CONTROLLER_FS, True)] + + results = self.shell("controllerfs-modify fake=15") + + self.assertIn(str(MODIFY_CONTROLLER_FS['uuid']), results) + self.assertIn(str(MODIFY_CONTROLLER_FS['name']), results) + self.assertIn(str(MODIFY_CONTROLLER_FS['size']), results) + self.assertIn(str(MODIFY_CONTROLLER_FS['logical_volume']), results) + self.assertIn(str(MODIFY_CONTROLLER_FS['replicated']), results) + self.assertIn(str(MODIFY_CONTROLLER_FS['state']), results) diff --git a/sysinv/cgts-client/cgts-client/cgtsclient/v1/controller_fs_shell.py b/sysinv/cgts-client/cgts-client/cgtsclient/v1/controller_fs_shell.py index 38346beb4f..8b7df91736 100644 --- a/sysinv/cgts-client/cgts-client/cgtsclient/v1/controller_fs_shell.py +++ b/sysinv/cgts-client/cgts-client/cgtsclient/v1/controller_fs_shell.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2017 Wind River Systems, Inc. +# Copyright (c) 2013-2020 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -39,6 +39,13 @@ def _print_controller_fs_show(controller_fs): action='append', default=[], help="Modify controller filesystem sizes") +@utils.arg('--column', + action='append', + default=[], + help="Specify the column(s) to include, can be repeated") +@utils.arg('--format', + choices=['table', 'yaml', 'value'], + help="specify the output format, defaults to table") def do_controllerfs_modify(cc, args): """Modify controller filesystem sizes.""" @@ -59,7 +66,7 @@ def do_controllerfs_modify(cc, args): except exc.HTTPNotFound: raise exc.CommandError('Failed to modify controller filesystems') - _print_controllerfs_list(cc) + _print_controllerfs_list(cc, args) @utils.arg('name', @@ -72,15 +79,28 @@ def do_controllerfs_show(cc, args): _print_controller_fs_show(controller_fs) -def _print_controllerfs_list(cc): +def _print_controllerfs_list(cc, args): controller_fs_list = cc.controller_fs.list() - field_labels = ['UUID', 'FS Name', 'Size in GiB', 'Logical Volume', - 'Replicated', 'State'] - fields = ['uuid', 'name', 'size', 'logical_volume', 'replicated', 'state'] - utils.print_list(controller_fs_list, fields, field_labels, sortby=1) + if args.column: + fields = args.column + field_labels = args.column + else: + field_labels = ['UUID', 'FS Name', 'Size in GiB', 'Logical Volume', + 'Replicated', 'State'] + fields = ['uuid', 'name', 'size', 'logical_volume', 'replicated', 'state'] + + utils.print_list(controller_fs_list, fields, field_labels, + sortby=0, output_format=args.format) +@utils.arg('--column', + action='append', + default=[], + help="Specify the column(s) to include, can be repeated") +@utils.arg('--format', + choices=['table', 'yaml', 'value'], + help="specify the output format, defaults to table") def do_controllerfs_list(cc, args): """Show list of controller filesystems""" - _print_controllerfs_list(cc) + _print_controllerfs_list(cc, args)