diff --git a/doc/source/user/proxies/shared_file_system.rst b/doc/source/user/proxies/shared_file_system.rst index 6c8b6cb5e..07581978f 100644 --- a/doc/source/user/proxies/shared_file_system.rst +++ b/doc/source/user/proxies/shared_file_system.rst @@ -79,3 +79,14 @@ service. :noindex: :members: share_snapshots, get_share_snapshot, delete_share_snapshot, update_share_snapshot, create_share_snapshot + + +Shared File System Share Networks +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Create and manipulate Share Networks with the Shared File Systems service. + +.. autoclass:: openstack.shared_file_system.v2._proxy.Proxy + :noindex: + :members: share_networks, get_share_network, delete_share_network, + update_share_network, create_share_network diff --git a/doc/source/user/resources/shared_file_system/index.rst b/doc/source/user/resources/shared_file_system/index.rst index 0a4cc5b4e..d769a0a49 100644 --- a/doc/source/user/resources/shared_file_system/index.rst +++ b/doc/source/user/resources/shared_file_system/index.rst @@ -10,3 +10,4 @@ Shared File System service resources v2/share v2/user_message v2/share_snapshot + v2/share_network diff --git a/doc/source/user/resources/shared_file_system/v2/share_network.rst b/doc/source/user/resources/shared_file_system/v2/share_network.rst new file mode 100644 index 000000000..793265d87 --- /dev/null +++ b/doc/source/user/resources/shared_file_system/v2/share_network.rst @@ -0,0 +1,13 @@ +openstack.shared_file_system.v2.share_network +============================================= + +.. automodule:: openstack.shared_file_system.v2.share_network + +The ShareNetwork Class +---------------------- + +The ``ShareNetwork`` class inherits from +:class:`~openstack.resource.Resource`. + +.. autoclass:: openstack.shared_file_system.v2.share_network.ShareNetwork + :members: diff --git a/openstack/shared_file_system/v2/_proxy.py b/openstack/shared_file_system/v2/_proxy.py index c4ffb1a9b..9325d9834 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_network as _share_network +) from openstack.shared_file_system.v2 import ( share_snapshot as _share_snapshot ) @@ -35,6 +38,7 @@ class Proxy(proxy.Proxy): "user_message": _user_message.UserMessage, "limit": _limit.Limit, "share": _share.Share, + "share_network": _share_network.ShareNetwork } def availability_zones(self): @@ -326,3 +330,70 @@ class Proxy(proxy.Proxy): to delete failed to occur in the specified seconds. """ return resource.wait_for_delete(self, res, interval, wait) + + def share_networks(self, details=True, **query): + """Lists all share networks with details. + + :param dict query: Optional query parameters to be sent to limit the + resources being returned. Available parameters include: + + * name~: The user defined name of the resource to filter resources + by. + * project_id: The ID of the user or service making the request. + * description~: The description pattern that can be used to filter + shares, share snapshots, share networks or share groups. + * all_projects: (Admin only). Defines whether to list the requested + resources for all projects. + + :returns: Details of shares networks + :rtype: :class:`~openstack.shared_file_system.v2. + share_network.ShareNetwork` + """ + base_path = '/share-networks/detail' if details else None + return self._list( + _share_network.ShareNetwork, base_path=base_path, **query) + + def get_share_network(self, share_network_id): + """Lists details of a single share network + + :param share_network: The ID of the share network to get + :returns: Details of the identified share network + :rtype: :class:`~openstack.shared_file_system.v2. + share_network.ShareNetwork` + """ + return self._get(_share_network.ShareNetwork, share_network_id) + + def delete_share_network(self, share_network_id, ignore_missing=True): + """Deletes a single share network + + :param share_network_id: The ID of the share network to delete + :rtype: ``None`` + """ + self._delete( + _share_network.ShareNetwork, share_network_id, + ignore_missing=ignore_missing) + + def update_share_network(self, share_network_id, **attrs): + """Updates details of a single share network. + + :param share_network_id: The ID of the share network to update + :pram dict attrs: The attributes to update on the share network + :returns: the updated share network + :rtype: :class:`~openstack.shared_file_system.v2. + share_network.ShareNetwork` + """ + return self._update( + _share_network.ShareNetwork, share_network_id, **attrs) + + def create_share_network(self, **attrs): + """Creates a share network from attributes + + :returns: Details of the new share network + :param dict attrs: Attributes which will be used to create + a :class:`~openstack.shared_file_system.v2. + share_network.ShareNetwork`,comprised of the properties + on the ShareNetwork class. + :rtype: :class:`~openstack.shared_file_system.v2. + share_network.ShareNetwork` + """ + return self._create(_share_network.ShareNetwork, **attrs) diff --git a/openstack/shared_file_system/v2/share_network.py b/openstack/shared_file_system/v2/share_network.py new file mode 100644 index 000000000..1cdc1431f --- /dev/null +++ b/openstack/shared_file_system/v2/share_network.py @@ -0,0 +1,48 @@ +# 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 ShareNetwork(resource.Resource): + resource_key = "share_network" + resources_key = "share_networks" + base_path = "/share-networks" + + # capabilities + allow_create = True + allow_fetch = True + allow_commit = True + allow_delete = True + allow_list = True + allow_head = False + + _query_mapping = resource.QueryParameters( + "project_id", "name", "description", + "created_since", "created_before", "security_service_id", + "limit", "offset", all_projects="all_tenants", + ) + + #: Properties + #: The date and time stamp when the resource was created within the + #: service’s database. + created_at = resource.Body("created_at") + #: The user defined description of the resource. + description = resource.Body("description", type=str) + #: The ID of the project that owns the resource. + project_id = resource.Body("project_id", type=str) + #: A list of share network subnets that pertain to the related share + #: network. + # share_network_subnets = resource.Body("share_network_subnets", type=list) + #: The date and time stamp when the resource was last updated within + #: the service’s database. + updated_at = resource.Body("updated_at", type=str) diff --git a/openstack/tests/functional/shared_file_system/test_share_network.py b/openstack/tests/functional/shared_file_system/test_share_network.py new file mode 100644 index 000000000..72880df96 --- /dev/null +++ b/openstack/tests/functional/shared_file_system/test_share_network.py @@ -0,0 +1,61 @@ +# 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_network as _share_network +from openstack.tests.functional.shared_file_system import base + + +class ShareNetworkTest(base.BaseSharedFileSystemTest): + + def setUp(self): + super(ShareNetworkTest, self).setUp() + + self.SHARE_NETWORK_NAME = self.getUniqueString() + snt = self.user_cloud.shared_file_system.create_share_network( + name=self.SHARE_NETWORK_NAME) + self.assertIsNotNone(snt) + self.assertIsNotNone(snt.id) + self.SHARE_NETWORK_ID = snt.id + + def tearDown(self): + sot = self.user_cloud.shared_file_system.delete_share_network( + self.SHARE_NETWORK_ID, + ignore_missing=True) + self.assertIsNone(sot) + super(ShareNetworkTest, self).tearDown() + + def test_get(self): + sot = self.user_cloud.shared_file_system.get_share_network( + self.SHARE_NETWORK_ID) + assert isinstance(sot, _share_network.ShareNetwork) + self.assertEqual(self.SHARE_NETWORK_ID, sot.id) + + def test_list_share_network(self): + share_nets = self.user_cloud.shared_file_system.share_networks( + details=False + ) + self.assertGreater(len(list(share_nets)), 0) + for share_net in share_nets: + for attribute in ('id', 'name', 'created_at', 'updated_at'): + self.assertTrue(hasattr(share_net, attribute)) + + def test_delete_share_network(self): + sot = self.user_cloud.shared_file_system.delete_share_network( + self.SHARE_NETWORK_ID) + self.assertIsNone(sot) + + def test_update(self): + unt = self.user_cloud.shared_file_system.update_share_network( + self.SHARE_NETWORK_ID, description='updated share network') + get_unt = self.user_cloud.shared_file_system.get_share_network( + unt.id) + self.assertEqual('updated share network', get_unt.description) diff --git a/openstack/tests/unit/shared_file_system/v2/test_proxy.py b/openstack/tests/unit/shared_file_system/v2/test_proxy.py index be1cdc7fd..9c5c879f3 100644 --- a/openstack/tests/unit/shared_file_system/v2/test_proxy.py +++ b/openstack/tests/unit/shared_file_system/v2/test_proxy.py @@ -15,6 +15,7 @@ from unittest import mock from openstack.shared_file_system.v2 import _proxy from openstack.shared_file_system.v2 import limit from openstack.shared_file_system.v2 import share +from openstack.shared_file_system.v2 import share_network from openstack.shared_file_system.v2 import share_snapshot from openstack.shared_file_system.v2 import storage_pool from openstack.shared_file_system.v2 import user_message @@ -172,3 +173,43 @@ class TestShareSnapshotResource(test_proxy_base.TestProxyBase): self.proxy.wait_for_delete(mock_resource) mock_wait.assert_called_once_with(self.proxy, mock_resource, 2, 120) + + +class TestShareNetworkResource(test_proxy_base.TestProxyBase): + + def setUp(self): + super(TestShareNetworkResource, self).setUp() + self.proxy = _proxy.Proxy(self.session) + + def test_share_networks(self): + self.verify_list(self.proxy.share_networks, share_network.ShareNetwork) + + def test_share_networks_detailed(self): + self.verify_list(self.proxy.share_networks, share_network.ShareNetwork, + method_kwargs={"details": True, "name": "my_net"}, + expected_kwargs={"name": "my_net"}) + + def test_share_networks_not_detailed(self): + self.verify_list(self.proxy.share_networks, share_network.ShareNetwork, + method_kwargs={"details": False, "name": "my_net"}, + expected_kwargs={"name": "my_net"}) + + def test_share_network_get(self): + self.verify_get( + self.proxy.get_share_network, share_network.ShareNetwork) + + def test_share_network_delete(self): + self.verify_delete( + self.proxy.delete_share_network, share_network.ShareNetwork, False) + + def test_share_network_delete_ignore(self): + self.verify_delete( + self.proxy.delete_share_network, share_network.ShareNetwork, True) + + def test_share_network_create(self): + self.verify_create( + self.proxy.create_share_network, share_network.ShareNetwork) + + def test_share_network_update(self): + self.verify_update( + self.proxy.update_share_network, share_network.ShareNetwork) diff --git a/openstack/tests/unit/shared_file_system/v2/test_share_network.py b/openstack/tests/unit/shared_file_system/v2/test_share_network.py new file mode 100644 index 000000000..505740ab4 --- /dev/null +++ b/openstack/tests/unit/shared_file_system/v2/test_share_network.py @@ -0,0 +1,65 @@ +# 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_network +from openstack.tests.unit import base + +IDENTIFIER = '6e1821be-c494-4f62-8301-5dcd19f4d615' +EXAMPLE = { + "id": IDENTIFIER, + "project_id": "4b8184eddd6b429a93231c056ae9cd12", + "name": "my_share_net", + "description": "My share network", + "created_at": "2021-06-10T10:11:17.291981", + "updated_at": None, + "share_network_subnets": [] +} + + +class TestShareNetwork(base.TestCase): + + def test_basic(self): + networks = share_network.ShareNetwork() + self.assertEqual('share_networks', networks.resources_key) + self.assertEqual('/share-networks', networks.base_path) + self.assertTrue(networks.allow_list) + self.assertTrue(networks.allow_create) + self.assertTrue(networks.allow_fetch) + self.assertTrue(networks.allow_commit) + self.assertTrue(networks.allow_delete) + self.assertFalse(networks.allow_head) + + self.assertDictEqual({ + "limit": "limit", + "marker": "marker", + "project_id": "project_id", + "created_since": "created_since", + "created_before": "created_before", + "offset": "offset", + "security_service_id": "security_service_id", + "project_id": "project_id", + "all_projects": "all_tenants", + "name": "name", + "description": "description" + }, + networks._query_mapping._mapping) + + def test_share_network(self): + networks = share_network.ShareNetwork(**EXAMPLE) + self.assertEqual(EXAMPLE['id'], networks.id) + self.assertEqual(EXAMPLE['name'], networks.name) + self.assertEqual(EXAMPLE['project_id'], networks.project_id) + self.assertEqual( + EXAMPLE['description'], networks.description) + self.assertEqual( + EXAMPLE['created_at'], networks.created_at) + self.assertEqual(EXAMPLE['updated_at'], networks.updated_at) diff --git a/releasenotes/notes/add-share-network-to-shared-file-c5c9a6b8ccf1d958.yaml b/releasenotes/notes/add-share-network-to-shared-file-c5c9a6b8ccf1d958.yaml new file mode 100644 index 000000000..5177b9977 --- /dev/null +++ b/releasenotes/notes/add-share-network-to-shared-file-c5c9a6b8ccf1d958.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Added support to create, update, list, get, and delete share + networks on the shared file system service.