From b097cec84fa7860b8892167203ea0b7d00b38137 Mon Sep 17 00:00:00 2001 From: "jayaanand.borra@netapp.com" Date: Tue, 13 Feb 2024 20:41:05 +0530 Subject: [PATCH] Human readable export location CLI changes OpenStack CLI option is added to support user friently export location. example command: $ openstack share create nfs 1 --name share_name --mount-point-name custom_export_path partially-implements: bp human-readable-export-locations Depends-On: I72ac7e24ddd4330d76cafd5e7f78bac2b0174883 Change-Id: If896065a74fc4ebabd09b677e5eb0329cecfaab9 --- manilaclient/api_versions.py | 2 +- manilaclient/osc/v2/share.py | 19 +++++- manilaclient/tests/unit/osc/v2/fakes.py | 1 + manilaclient/tests/unit/osc/v2/test_share.py | 58 +++++++++++++++++-- manilaclient/tests/unit/v2/test_shares.py | 23 ++++++++ manilaclient/v2/shares.py | 9 ++- ...cation-share-support-d156f23669e458fa.yaml | 19 ++++++ 7 files changed, 123 insertions(+), 8 deletions(-) create mode 100644 releasenotes/notes/human-readable-export-location-share-support-d156f23669e458fa.yaml diff --git a/manilaclient/api_versions.py b/manilaclient/api_versions.py index ffb361bbe..e303dc7ef 100644 --- a/manilaclient/api_versions.py +++ b/manilaclient/api_versions.py @@ -27,7 +27,7 @@ from manilaclient import utils LOG = logging.getLogger(__name__) -MAX_VERSION = '2.83' +MAX_VERSION = '2.84' MIN_VERSION = '2.0' DEPRECATED_VERSION = '1.0' _VERSIONED_METHOD_MAP = {} diff --git a/manilaclient/osc/v2/share.py b/manilaclient/osc/v2/share.py index 882a6e61c..ce677f2f9 100644 --- a/manilaclient/osc/v2/share.py +++ b/manilaclient/osc/v2/share.py @@ -188,6 +188,13 @@ class CreateShare(command.ShowOne): "possible keys are same_host, different_host." "(repeat option to set multiple hints)"), ) + parser.add_argument( + '--mount-point-name', + metavar="", + default=None, + help=_('Optional custom export location. Available for ' + 'microversion >= 2.84') + ) return parser @@ -232,6 +239,15 @@ class CreateShare(command.ShowOne): snapshot_id = snapshot.id size = max(size or 0, snapshot.size) + mount_point_name = None + if parsed_args.mount_point_name: + if share_client.api_version < api_versions.APIVersion('2.84'): + raise exceptions.CommandError( + 'Setting share mount point name is ' + 'available only for API microversion >= 2.84') + else: + mount_point_name = parsed_args.mount_point_name + scheduler_hints = {} if parsed_args.scheduler_hint: if share_client.api_version < api_versions.APIVersion('2.65'): @@ -271,7 +287,8 @@ class CreateShare(command.ShowOne): 'is_public': parsed_args.public, 'availability_zone': parsed_args.availability_zone, 'share_group_id': share_group, - 'scheduler_hints': scheduler_hints + 'scheduler_hints': scheduler_hints, + 'mount_point_name': mount_point_name, } share = share_client.shares.create(**body) diff --git a/manilaclient/tests/unit/osc/v2/fakes.py b/manilaclient/tests/unit/osc/v2/fakes.py index 9b0a3b7b2..139e36f32 100644 --- a/manilaclient/tests/unit/osc/v2/fakes.py +++ b/manilaclient/tests/unit/osc/v2/fakes.py @@ -139,6 +139,7 @@ class FakeShare(object): "revert_to_snapshot_support": False, "source_share_group_snapshot_member_id": None, "scheduler_hints": {}, + "mount_point_name": None, } # Overwrite default attributes. diff --git a/manilaclient/tests/unit/osc/v2/test_share.py b/manilaclient/tests/unit/osc/v2/test_share.py index c481c2f68..080479b05 100644 --- a/manilaclient/tests/unit/osc/v2/test_share.py +++ b/manilaclient/tests/unit/osc/v2/test_share.py @@ -132,7 +132,8 @@ class TestShareCreate(TestShare): share_type=self.share_type.id, size=self.new_share.size, snapshot_id=None, - scheduler_hints={} + scheduler_hints={}, + mount_point_name=None, ) self.assertCountEqual(self.columns, columns) @@ -180,7 +181,8 @@ class TestShareCreate(TestShare): share_type=self.share_type.id, size=self.new_share.size, snapshot_id=None, - scheduler_hints={} + scheduler_hints={}, + mount_point_name=None, ) self.assertCountEqual(self.columns, columns) @@ -227,6 +229,49 @@ class TestShareCreate(TestShare): snapshot_id=None, scheduler_hints={'same_host': shares[0].id, 'different_host': shares[1].id}, + mount_point_name=None, + ) + + self.assertCountEqual(self.columns, columns) + self.assertCountEqual(self.datalist, data) + + def test_share_create_mount_point_name(self): + """Verifies that the mount point name has been passed correctly.""" + self.app.client_manager.share.api_version = api_versions.APIVersion( + "2.84") + + mount_point_name = "fake_mp" + + arglist = [ + self.new_share.share_proto, + str(self.new_share.size), + '--share-type', self.share_type.id, + '--mount-point-name', mount_point_name, + ] + verifylist = [ + ('share_proto', self.new_share.share_proto), + ('size', self.new_share.size), + ('mount_point_name', mount_point_name), + ('share_type', self.share_type.id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.shares_mock.create.assert_called_with( + availability_zone=None, + description=None, + is_public=False, + metadata={}, + name=None, + share_group_id=None, + share_network=None, + share_proto=self.new_share.share_proto, + share_type=self.share_type.id, + size=self.new_share.size, + snapshot_id=None, + scheduler_hints={}, + mount_point_name='fake_mp', ) self.assertCountEqual(self.columns, columns) @@ -269,7 +314,8 @@ class TestShareCreate(TestShare): share_type=None, size=self.new_share.size, snapshot_id=self.share_snapshot.id, - scheduler_hints={} + scheduler_hints={}, + mount_point_name=None, ) self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.datalist, data) @@ -305,7 +351,8 @@ class TestShareCreate(TestShare): share_type=self.share_type.id, size=self.new_share.size, snapshot_id=None, - scheduler_hints={} + scheduler_hints={}, + mount_point_name=None, ) self.shares_mock.get.assert_called_with(self.new_share.id) @@ -345,7 +392,8 @@ class TestShareCreate(TestShare): share_type=self.share_type.id, size=self.new_share.size, snapshot_id=None, - scheduler_hints={} + scheduler_hints={}, + mount_point_name=None, ) mock_logger.error.assert_called_with( diff --git a/manilaclient/tests/unit/v2/test_shares.py b/manilaclient/tests/unit/v2/test_shares.py index d52b3a779..ecbab2388 100644 --- a/manilaclient/tests/unit/v2/test_shares.py +++ b/manilaclient/tests/unit/v2/test_shares.py @@ -140,6 +140,29 @@ class SharesTest(utils.TestCase): availability_zone=availability_zone) cs.assert_called('POST', '/shares', body) + @ddt.data({'mount_point_name': 'fake_mount_pt1'}, + {'mount_point_name': 'fake_mount_pt2'}) + @ddt.unpack + def test_create_share_with_mount_point_name(self, mount_point_name): + body = { + 'share': { + 'is_public': False, + 'share_type': None, + 'name': None, + 'snapshot_id': None, + 'description': None, + 'metadata': {}, + 'share_proto': 'nfs', + 'share_network_id': None, + 'size': 1, + 'availability_zone': None, + 'scheduler_hints': {}, + 'mount_point_name': mount_point_name, + } + } + cs.shares.create('nfs', 1, mount_point_name=mount_point_name) + cs.assert_called('POST', '/shares', body) + @ddt.data( type('ShareUUID', (object, ), {'uuid': '1234'}), type('ShareID', (object, ), {'id': '1234'}), diff --git a/manilaclient/v2/shares.py b/manilaclient/v2/shares.py index 42b56f470..2f419a48a 100644 --- a/manilaclient/v2/shares.py +++ b/manilaclient/v2/shares.py @@ -124,7 +124,8 @@ class ShareManager(base.MetadataCapableManager): def create(self, share_proto, size, snapshot_id=None, name=None, description=None, metadata=None, share_network=None, share_type=None, is_public=False, availability_zone=None, - share_group_id=None, scheduler_hints=None, return_raw=False): + share_group_id=None, scheduler_hints=None, return_raw=False, + mount_point_name=None): """Create a share. :param share_proto: text - share protocol for new share available @@ -142,6 +143,9 @@ class ShareManager(base.MetadataCapableManager): :param scheduler_hints: dict - hints for the scheduler to place share on most appropriate host e.g. keys are same_host for affinity and different_host for anti-affinity + :param mount_point_name: text - share human-readable mount point name. + This name will be reflected in export location once + share is created. :rtype: :class:`Share` """ share_metadata = metadata if metadata is not None else dict() @@ -163,6 +167,9 @@ class ShareManager(base.MetadataCapableManager): if share_group_id: body['share_group_id'] = share_group_id + if mount_point_name: + body['mount_point_name'] = mount_point_name + return self._create('/shares', {'share': body}, 'share', return_raw=return_raw) diff --git a/releasenotes/notes/human-readable-export-location-share-support-d156f23669e458fa.yaml b/releasenotes/notes/human-readable-export-location-share-support-d156f23669e458fa.yaml new file mode 100644 index 000000000..7171aa475 --- /dev/null +++ b/releasenotes/notes/human-readable-export-location-share-support-d156f23669e458fa.yaml @@ -0,0 +1,19 @@ +--- +features: + - In the 2.84 API version, a new option, ``mount_point_name``, has been + introduced to the share creation command. This option allow users + to specify a more intuitive ``mount_point_name`` that will be reflected + in the share's export location. However, for this feature to be available + to users, administrators must first enable an extra-spec in the + share type. In addition, administrators need to set an extra-spec named + ``provisioning:mount_point_prefix``. The Manila service will combine + this prefix with the mount point name that user provides during share + creation. If the ``provisioning:mount_point_prefix`` is not set for + a share type, but ``mount_point_name_support`` is enabled, the share's + export location will default to using the project_id as a prefix. + Please note that shares created with a project_id prefix cannot be + transferred. To move these shares to a different project, + an admin must manually unmount them from the current project and mount + them to the target project. A new capability, ``mount_point_name_support``, + allows the driver to inform the scheduler about its support for the + mount_point_name feature. \ No newline at end of file