diff --git a/openstack/shared_file_system/v2/_proxy.py b/openstack/shared_file_system/v2/_proxy.py index eae2b0994..25ef24a96 100644 --- a/openstack/shared_file_system/v2/_proxy.py +++ b/openstack/shared_file_system/v2/_proxy.py @@ -14,6 +14,9 @@ from openstack import proxy from openstack import resource from openstack.shared_file_system.v2 import ( availability_zone as _availability_zone) +from openstack.shared_file_system.v2 import ( + share_export_locations as _share_export_locations +) from openstack.shared_file_system.v2 import ( share_network as _share_network ) @@ -46,6 +49,8 @@ class Proxy(proxy.Proxy): "share_snapshot_instance": _share_snapshot_instance.ShareSnapshotInstance, "share_instance": _share_instance.ShareInstance, + "share_export_locations": + _share_export_locations.ShareExportLocation, } def availability_zones(self): @@ -489,3 +494,29 @@ class Proxy(proxy.Proxy): res = self._get_resource(_share_instance.ShareInstance, share_instance_id) res.force_delete(self) + + def export_locations(self, share_id): + """List all export locations with details + + :param share_id: The ID of the share to list export locations from + :returns: List of export locations + :rtype: List of :class:`~openstack.shared_filesystem_storage.v2. + share_export_locations.ShareExportLocations` + """ + return self._list(_share_export_locations.ShareExportLocation, + share_id=share_id) + + def get_export_location(self, export_location, share_id): + """List details of export location + + :param export_location: The export location resource to get + :param share_id: The ID of the share to get export locations from + :returns: Details of identified export location + :rtype: :class:`~openstack.shared_filesystem_storage.v2. + share_export_locations.ShareExportLocations` + """ + + export_location_id = resource.Resource._get_id(export_location) + return self._get( + _share_export_locations.ShareExportLocation, + export_location_id, share_id=share_id) diff --git a/openstack/shared_file_system/v2/share_export_locations.py b/openstack/shared_file_system/v2/share_export_locations.py new file mode 100644 index 000000000..f18bf49f0 --- /dev/null +++ b/openstack/shared_file_system/v2/share_export_locations.py @@ -0,0 +1,44 @@ +# 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 openstack import resource + + +class ShareExportLocation(resource.Resource): + resource_key = "export_location" + resources_key = "export_locations" + base_path = "/shares/%(share_id)s/export_locations" + + # capabilities + allow_list = True + allow_fetch = True + allow_create = False + allow_commit = False + allow_delete = False + allow_head = False + + #: Properties + # The share ID, part of the URI for export locations + share_id = resource.URI("share_id", type='str') + #: The path of the export location. + path = resource.Body("path", type=str) + #: Indicate if export location is preferred. + is_preferred = resource.Body("preferred", type=bool) + #: The share instance ID of the export location. + share_instance_id = resource.Body("share_instance_id", type=str) + #: Indicate if export location is admin only. + is_admin = resource.Body("is_admin_only", type=bool) + #: Indicate when the export location is created at + created_at = resource.Body("created_at", type=str) + #: Indicate when the export location is updated at + updated_at = resource.Body("updated_at", type=str) diff --git a/openstack/tests/functional/shared_file_system/test_export_locations.py b/openstack/tests/functional/shared_file_system/test_export_locations.py new file mode 100644 index 000000000..3391590f2 --- /dev/null +++ b/openstack/tests/functional/shared_file_system/test_export_locations.py @@ -0,0 +1,42 @@ +# 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 openstack.tests.functional.shared_file_system import base + + +class TestExportLocation(base.BaseSharedFileSystemTest): + + min_microversion = '2.9' + + def setUp(self): + super().setUp() + + self.SHARE_NAME = self.getUniqueString() + my_share = self.create_share( + name=self.SHARE_NAME, size=2, share_type="dhss_false", + share_protocol='NFS', description=None) + self.SHARE_ID = my_share.id + + def test_export_locations(self): + exs = self.user_cloud.shared_file_system.export_locations( + self.SHARE_ID + ) + self.assertGreater(len(list(exs)), 0) + for ex in exs: + for attribute in ( + 'id', 'path', 'share_instance_id', + 'updated_at', 'created_at'): + self.assertTrue(hasattr(ex, attribute)) + self.assertIsInstance(getattr(ex, attribute), 'str') + for attribute in ('is_preferred', 'is_admin'): + self.assertTrue(hasattr(ex, attribute)) + self.assertIsInstance(getattr(ex, attribute), 'bool') diff --git a/openstack/tests/unit/shared_file_system/v2/test_share_export_locations.py b/openstack/tests/unit/shared_file_system/v2/test_share_export_locations.py new file mode 100644 index 000000000..0e9940708 --- /dev/null +++ b/openstack/tests/unit/shared_file_system/v2/test_share_export_locations.py @@ -0,0 +1,44 @@ +# 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 openstack.shared_file_system.v2 import share_export_locations as el +from openstack.tests.unit import base + + +IDENTIFIER = '08a87d37-5ca2-4308-86c5-cba06d8d796c' +EXAMPLE = { + "id": "f87589cb-f4bc-4a9b-b481-ab701206eb85", + "path": ("199.19.213.225:/opt/stack/data/manila/mnt/" + "share-6ba490c5-5225-4c3b-9982-14b8f475c6d9"), + "preferred": False, + "share_instance_id": "6ba490c5-5225-4c3b-9982-14b8f475c6d9", + "is_admin_only": False +} + + +class TestShareExportLocations(base.TestCase): + + def test_basic(self): + export = el.ShareExportLocation() + self.assertEqual('export_locations', export.resources_key) + self.assertEqual( + '/shares/%(share_id)s/export_locations', export.base_path) + self.assertTrue(export.allow_list) + + def test_share_export_locations(self): + export = el.ShareExportLocation(**EXAMPLE) + self.assertEqual(EXAMPLE['id'], export.id) + self.assertEqual(EXAMPLE['path'], export.path) + self.assertEqual(EXAMPLE['preferred'], export.is_preferred) + self.assertEqual( + EXAMPLE['share_instance_id'], export.share_instance_id) + self.assertEqual(EXAMPLE['is_admin_only'], export.is_admin) diff --git a/releasenotes/notes/add-shared-file-systems-export-location-a27c1741880c384b.yaml b/releasenotes/notes/add-shared-file-systems-export-location-a27c1741880c384b.yaml new file mode 100644 index 000000000..df1a1243a --- /dev/null +++ b/releasenotes/notes/add-shared-file-systems-export-location-a27c1741880c384b.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Added support to list and show Export Locations + for shares from the Shared File Systems service.