Adds share group resource to shared file system
Introduce Share groups class with basic methods including list, create, delete, get and update to shared file system service. Change-Id: I7d7e4e7addc1c1b040276e10f8152bc0adb8eeb2
This commit is contained in:

committed by
silvacarloss

parent
377d734de0
commit
0017ffb050
@@ -138,3 +138,15 @@ Shared File Systems service.
|
|||||||
:noindex:
|
:noindex:
|
||||||
:members: access_rules, get_access_rule, create_access_rule,
|
:members: access_rules, get_access_rule, create_access_rule,
|
||||||
delete_access_rule
|
delete_access_rule
|
||||||
|
|
||||||
|
|
||||||
|
Shared File System Share Groups
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Interact with Share groups supported by the Shared File Systems
|
||||||
|
service.
|
||||||
|
|
||||||
|
.. autoclass:: openstack.shared_file_system.v2._proxy.Proxy
|
||||||
|
:noindex:
|
||||||
|
:members: share_groups, get_share_group, delete_share_group,
|
||||||
|
update_share_group, create_share_group, find_share_group
|
||||||
|
@@ -14,4 +14,5 @@ Shared File System service resources
|
|||||||
v2/share_snapshot_instance
|
v2/share_snapshot_instance
|
||||||
v2/share_network
|
v2/share_network
|
||||||
v2/user_message
|
v2/user_message
|
||||||
|
v2/share_group
|
||||||
v2/share_access_rule
|
v2/share_access_rule
|
||||||
|
@@ -0,0 +1,13 @@
|
|||||||
|
openstack.shared_file_system.v2.share_group
|
||||||
|
===========================================
|
||||||
|
|
||||||
|
.. automodule:: openstack.shared_file_system.v2.share_group
|
||||||
|
|
||||||
|
The ShareGroup Class
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
The ``ShareGroup`` class inherits from
|
||||||
|
:class:`~openstack.resource.Resource`.
|
||||||
|
|
||||||
|
.. autoclass:: openstack.shared_file_system.v2.share_group.ShareGroup
|
||||||
|
:members:
|
@@ -17,6 +17,7 @@ from openstack.shared_file_system.v2 import (
|
|||||||
)
|
)
|
||||||
from openstack.shared_file_system.v2 import limit as _limit
|
from openstack.shared_file_system.v2 import limit as _limit
|
||||||
from openstack.shared_file_system.v2 import share as _share
|
from openstack.shared_file_system.v2 import share as _share
|
||||||
|
from openstack.shared_file_system.v2 import share_group as _share_group
|
||||||
from openstack.shared_file_system.v2 import (
|
from openstack.shared_file_system.v2 import (
|
||||||
share_access_rule as _share_access_rule,
|
share_access_rule as _share_access_rule,
|
||||||
)
|
)
|
||||||
@@ -50,6 +51,7 @@ class Proxy(proxy.Proxy):
|
|||||||
"share_instance": _share_instance.ShareInstance,
|
"share_instance": _share_instance.ShareInstance,
|
||||||
"share_export_locations": _share_export_locations.ShareExportLocation,
|
"share_export_locations": _share_export_locations.ShareExportLocation,
|
||||||
"share_access_rule": _share_access_rule.ShareAccessRule,
|
"share_access_rule": _share_access_rule.ShareAccessRule,
|
||||||
|
"share_group": _share_group.ShareGroup,
|
||||||
}
|
}
|
||||||
|
|
||||||
def availability_zones(self):
|
def availability_zones(self):
|
||||||
@@ -211,6 +213,106 @@ class Proxy(proxy.Proxy):
|
|||||||
elif new_size < res.size and no_shrink is not True:
|
elif new_size < res.size and no_shrink is not True:
|
||||||
res.shrink_share(self, new_size)
|
res.shrink_share(self, new_size)
|
||||||
|
|
||||||
|
def share_groups(self, **query):
|
||||||
|
"""Lists all share groups.
|
||||||
|
|
||||||
|
:param kwargs query: Optional query parameters to be sent to limit
|
||||||
|
the share groups being returned. Available parameters include:
|
||||||
|
|
||||||
|
* status: Filters by a share group status.
|
||||||
|
* name: The user defined name of the resource to filter resources
|
||||||
|
by.
|
||||||
|
* description: The user defined description text that can be used
|
||||||
|
to filter resources.
|
||||||
|
* project_id: The project ID of the user or service.
|
||||||
|
* share_server_id: The UUID of the share server.
|
||||||
|
* snapshot_id: The UUID of the share’s base snapshot to filter
|
||||||
|
the request based on.
|
||||||
|
* host: The host name for the back end.
|
||||||
|
* share_network_id: The UUID of the share network to filter
|
||||||
|
resources by.
|
||||||
|
* share_group_type_id: The share group type ID to filter
|
||||||
|
share groups.
|
||||||
|
* share_group_snapshot_id: The source share group snapshot ID to
|
||||||
|
list the share group.
|
||||||
|
* share_types: A list of one or more share type IDs. Allows
|
||||||
|
filtering share groups.
|
||||||
|
* limit: The maximum number of share groups members to return.
|
||||||
|
* offset: The offset to define start point of share or share
|
||||||
|
group listing.
|
||||||
|
* sort_key: The key to sort a list of shares.
|
||||||
|
* sort_dir: The direction to sort a list of shares
|
||||||
|
* name~: The name pattern that can be used to filter shares,
|
||||||
|
share snapshots, share networks or share groups.
|
||||||
|
* description~: The description pattern that can be used to
|
||||||
|
filter shares, share snapshots, share networks or share groups.
|
||||||
|
|
||||||
|
:returns: A generator of manila share group resources
|
||||||
|
:rtype: :class:`~openstack.shared_file_system.v2.
|
||||||
|
share_group.ShareGroup`
|
||||||
|
"""
|
||||||
|
return self._list(_share_group.ShareGroup, **query)
|
||||||
|
|
||||||
|
def get_share_group(self, share_group_id):
|
||||||
|
"""Lists details for a share group.
|
||||||
|
|
||||||
|
:param share: The ID of the share group to get
|
||||||
|
:returns: Details of the identified share group
|
||||||
|
:rtype: :class:`~openstack.shared_file_system.v2.
|
||||||
|
share_group.ShareGroup`
|
||||||
|
"""
|
||||||
|
return self._get(_share_group.ShareGroup, share_group_id)
|
||||||
|
|
||||||
|
def find_share_group(self, name_or_id, ignore_missing=True):
|
||||||
|
"""Finds a single share group
|
||||||
|
|
||||||
|
:param name_or_id: The name or ID of a share group.
|
||||||
|
:param bool ignore_missing: When set to ``False``
|
||||||
|
:class:`~openstack.exceptions.ResourceNotFound` will be
|
||||||
|
raised when the resource does not exist.
|
||||||
|
When set to ``True``, None will be returned when
|
||||||
|
attempting to find a nonexistent resource.
|
||||||
|
:returns: One :class:`~openstack.shared_file_system.v2.
|
||||||
|
share_group.ShareGroup`
|
||||||
|
or None
|
||||||
|
"""
|
||||||
|
return self._find(
|
||||||
|
_share_group.ShareGroup, name_or_id, ignore_missing=ignore_missing
|
||||||
|
)
|
||||||
|
|
||||||
|
def create_share_group(self, **attrs):
|
||||||
|
"""Creates a share group from attributes
|
||||||
|
|
||||||
|
:returns: Details of the new share group
|
||||||
|
:rtype: :class:`~openstack.shared_file_system.v2.
|
||||||
|
share_group.ShareGroup`
|
||||||
|
"""
|
||||||
|
return self._create(_share_group.ShareGroup, **attrs)
|
||||||
|
|
||||||
|
def update_share_group(self, share_group_id, **kwargs):
|
||||||
|
"""Updates details of a single share group
|
||||||
|
|
||||||
|
:param share: The ID of the share group
|
||||||
|
:returns: Updated details of the identified share group
|
||||||
|
:rtype: :class:`~openstack.shared_file_system.v2.
|
||||||
|
share_group.ShareGroup`
|
||||||
|
"""
|
||||||
|
return self._update(_share_group.ShareGroup, share_group_id, **kwargs)
|
||||||
|
|
||||||
|
def delete_share_group(self, share_group_id, ignore_missing=True):
|
||||||
|
"""Deletes a single share group
|
||||||
|
|
||||||
|
:param share: The ID of the share group
|
||||||
|
:returns: Result of the "delete" on share group
|
||||||
|
:rtype: :class:`~openstack.shared_file_system.v2.
|
||||||
|
share_group.ShareGroup`
|
||||||
|
"""
|
||||||
|
return self._delete(
|
||||||
|
_share_group.ShareGroup,
|
||||||
|
share_group_id,
|
||||||
|
ignore_missing=ignore_missing,
|
||||||
|
)
|
||||||
|
|
||||||
def wait_for_status(
|
def wait_for_status(
|
||||||
self, res, status='active', failures=None, interval=2, wait=120
|
self, res, status='active', failures=None, interval=2, wait=120
|
||||||
):
|
):
|
||||||
|
56
openstack/shared_file_system/v2/share_group.py
Normal file
56
openstack/shared_file_system/v2/share_group.py
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# 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 ShareGroup(resource.Resource):
|
||||||
|
resource_key = "share_group"
|
||||||
|
resources_key = "share_groups"
|
||||||
|
base_path = "/share-groups"
|
||||||
|
|
||||||
|
_query_mapping = resource.QueryParameters("share_group_id")
|
||||||
|
|
||||||
|
# capabilities
|
||||||
|
allow_create = True
|
||||||
|
allow_fetch = True
|
||||||
|
allow_commit = True
|
||||||
|
allow_delete = True
|
||||||
|
allow_list = True
|
||||||
|
allow_head = False
|
||||||
|
|
||||||
|
#: Properties
|
||||||
|
#: The availability zone ID that the share group exists within.
|
||||||
|
availability_zone = resource.Body("availability_zone", type=str)
|
||||||
|
#: The consistency snapshot support.
|
||||||
|
consistent_snapshot_support = resource.Body(
|
||||||
|
"consistent_snapshot_support", type=str
|
||||||
|
)
|
||||||
|
#: The date and time stamp when the resource was created within the
|
||||||
|
#: service’s database.
|
||||||
|
created_at = resource.Body("created_at", type=str)
|
||||||
|
#: 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)
|
||||||
|
#: The share group snapshot ID.
|
||||||
|
share_group_snapshot_id = resource.Body(
|
||||||
|
"share_group_snapshot_id", type=str
|
||||||
|
)
|
||||||
|
#: The share group type ID.
|
||||||
|
share_group_type_id = resource.Body("share_group_type_id", type=str)
|
||||||
|
#: The share network ID where the resource is exported to.
|
||||||
|
share_network_id = resource.Body("share_network_id", type=str)
|
||||||
|
#: A list of share type IDs.
|
||||||
|
share_types = resource.Body("share_types", type=list)
|
||||||
|
#: The share status
|
||||||
|
status = resource.Body("status", type=str)
|
@@ -65,3 +65,13 @@ class BaseSharedFileSystemTest(base.BaseFunctionalTest):
|
|||||||
)
|
)
|
||||||
self.assertIsNotNone(share_snapshot.id)
|
self.assertIsNotNone(share_snapshot.id)
|
||||||
return share_snapshot
|
return share_snapshot
|
||||||
|
|
||||||
|
def create_share_group(self, **kwargs):
|
||||||
|
share_group = self.user_cloud.share.create_share_group(**kwargs)
|
||||||
|
self.addCleanup(
|
||||||
|
self.conn.share.delete_share_group,
|
||||||
|
share_group.id,
|
||||||
|
ignore_missing=True,
|
||||||
|
)
|
||||||
|
self.assertIsNotNone(share_group.id)
|
||||||
|
return share_group
|
||||||
|
@@ -0,0 +1,66 @@
|
|||||||
|
# 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_group as _share_group
|
||||||
|
from openstack.tests.functional.shared_file_system import base
|
||||||
|
|
||||||
|
|
||||||
|
class ShareGroupTest(base.BaseSharedFileSystemTest):
|
||||||
|
def setUp(self):
|
||||||
|
super(ShareGroupTest, self).setUp()
|
||||||
|
|
||||||
|
self.SHARE_GROUP_NAME = self.getUniqueString()
|
||||||
|
share_grp = self.user_cloud.shared_file_system.create_share_group(
|
||||||
|
name=self.SHARE_GROUP_NAME
|
||||||
|
)
|
||||||
|
self.user_cloud.shared_file_system.wait_for_status(
|
||||||
|
share_grp,
|
||||||
|
status='available',
|
||||||
|
failures=['error'],
|
||||||
|
interval=5,
|
||||||
|
wait=self._wait_for_timeout,
|
||||||
|
)
|
||||||
|
self.assertIsNotNone(share_grp)
|
||||||
|
self.assertIsNotNone(share_grp.id)
|
||||||
|
self.SHARE_GROUP_ID = share_grp.id
|
||||||
|
|
||||||
|
def test_get(self):
|
||||||
|
sot = self.user_cloud.shared_file_system.get_share_group(
|
||||||
|
self.SHARE_GROUP_ID
|
||||||
|
)
|
||||||
|
assert isinstance(sot, _share_group.ShareGroup)
|
||||||
|
self.assertEqual(self.SHARE_GROUP_ID, sot.id)
|
||||||
|
|
||||||
|
def test_find(self):
|
||||||
|
sot = self.user_cloud.shared_file_system.find_share_group(
|
||||||
|
self.SHARE_GROUP_NAME
|
||||||
|
)
|
||||||
|
assert isinstance(sot, _share_group.ShareGroup)
|
||||||
|
self.assertEqual(self.SHARE_GROUP_NAME, sot.name)
|
||||||
|
self.assertEqual(self.SHARE_GROUP_ID, sot.id)
|
||||||
|
|
||||||
|
def test_list_delete_share_group(self):
|
||||||
|
s_grps = self.user_cloud.shared_file_system.share_groups()
|
||||||
|
self.assertGreater(len(list(s_grps)), 0)
|
||||||
|
for s_grp in s_grps:
|
||||||
|
for attribute in ('id', 'name', 'created_at'):
|
||||||
|
self.assertTrue(hasattr(s_grp, attribute))
|
||||||
|
|
||||||
|
sot = self.conn.shared_file_system.delete_share_group(s_grp)
|
||||||
|
self.assertIsNone(sot)
|
||||||
|
|
||||||
|
def test_update(self):
|
||||||
|
u_gp = self.user_cloud.shared_file_system.update_share_group(
|
||||||
|
self.SHARE_GROUP_ID, description='updated share group'
|
||||||
|
)
|
||||||
|
get_u_gp = self.user_cloud.shared_file_system.get_share_group(u_gp.id)
|
||||||
|
self.assertEqual('updated share group', get_u_gp.description)
|
@@ -16,6 +16,7 @@ from openstack.shared_file_system.v2 import _proxy
|
|||||||
from openstack.shared_file_system.v2 import limit
|
from openstack.shared_file_system.v2 import limit
|
||||||
from openstack.shared_file_system.v2 import share
|
from openstack.shared_file_system.v2 import share
|
||||||
from openstack.shared_file_system.v2 import share_access_rule
|
from openstack.shared_file_system.v2 import share_access_rule
|
||||||
|
from openstack.shared_file_system.v2 import share_group
|
||||||
from openstack.shared_file_system.v2 import share_instance
|
from openstack.shared_file_system.v2 import share_instance
|
||||||
from openstack.shared_file_system.v2 import share_network
|
from openstack.shared_file_system.v2 import share_network
|
||||||
from openstack.shared_file_system.v2 import share_network_subnet
|
from openstack.shared_file_system.v2 import share_network_subnet
|
||||||
@@ -417,3 +418,46 @@ class TestAccessRuleProxy(test_proxy_base.TestProxyBase):
|
|||||||
method_args=['access_id', 'share_id', 'ignore_missing'],
|
method_args=['access_id', 'share_id', 'ignore_missing'],
|
||||||
expected_args=[self.proxy, 'share_id'],
|
expected_args=[self.proxy, 'share_id'],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TestShareGroupResource(test_proxy_base.TestProxyBase):
|
||||||
|
def setUp(self):
|
||||||
|
super(TestShareGroupResource, self).setUp()
|
||||||
|
self.proxy = _proxy.Proxy(self.session)
|
||||||
|
|
||||||
|
def test_share_groups(self):
|
||||||
|
self.verify_list(self.proxy.share_groups, share_group.ShareGroup)
|
||||||
|
|
||||||
|
def test_share_groups_query(self):
|
||||||
|
self.verify_list(
|
||||||
|
self.proxy.share_groups,
|
||||||
|
share_group.ShareGroup,
|
||||||
|
method_kwargs={"query": 1},
|
||||||
|
expected_kwargs={"query": 1},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_share_group_get(self):
|
||||||
|
self.verify_get(self.proxy.get_share_group, share_group.ShareGroup)
|
||||||
|
|
||||||
|
def test_share_group_find(self):
|
||||||
|
self.verify_find(self.proxy.find_share_group, share_group.ShareGroup)
|
||||||
|
|
||||||
|
def test_share_group_delete(self):
|
||||||
|
self.verify_delete(
|
||||||
|
self.proxy.delete_share_group, share_group.ShareGroup, False
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_share_group_delete_ignore(self):
|
||||||
|
self.verify_delete(
|
||||||
|
self.proxy.delete_share_group, share_group.ShareGroup, True
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_share_group_create(self):
|
||||||
|
self.verify_create(
|
||||||
|
self.proxy.create_share_group, share_group.ShareGroup
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_share_group_update(self):
|
||||||
|
self.verify_update(
|
||||||
|
self.proxy.update_share_group, share_group.ShareGroup
|
||||||
|
)
|
||||||
|
@@ -0,0 +1,81 @@
|
|||||||
|
# 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_group
|
||||||
|
from openstack.tests.unit import base
|
||||||
|
|
||||||
|
|
||||||
|
EXAMPLE = {
|
||||||
|
"status": "creating",
|
||||||
|
"description": None,
|
||||||
|
"links": "[]",
|
||||||
|
"availability_zone": None,
|
||||||
|
"source_share_group_snapshot_id": None,
|
||||||
|
"share_network_id": None,
|
||||||
|
"share_server_id": None,
|
||||||
|
"host": None,
|
||||||
|
"share_group_type_id": "89861c2a-10bf-4013-bdd4-3d020466aee4",
|
||||||
|
"consistent_snapshot_support": None,
|
||||||
|
"id": "f9c1f80c-2392-4e34-bd90-fc89cdc5bf93",
|
||||||
|
"name": None,
|
||||||
|
"created_at": "2021-06-03T19:20:33.974421",
|
||||||
|
"project_id": "e23850eeb91d4fa3866af634223e454c",
|
||||||
|
"share_types": ["ecd11f4c-d811-4471-b656-c755c77e02ba"],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class TestShareGroups(base.TestCase):
|
||||||
|
def test_basic(self):
|
||||||
|
share_groups = share_group.ShareGroup()
|
||||||
|
self.assertEqual('share_groups', share_groups.resources_key)
|
||||||
|
self.assertEqual('/share-groups', share_groups.base_path)
|
||||||
|
self.assertTrue(share_groups.allow_list)
|
||||||
|
self.assertTrue(share_groups.allow_fetch)
|
||||||
|
self.assertTrue(share_groups.allow_create)
|
||||||
|
self.assertTrue(share_groups.allow_commit)
|
||||||
|
self.assertTrue(share_groups.allow_delete)
|
||||||
|
self.assertFalse(share_groups.allow_head)
|
||||||
|
|
||||||
|
self.assertDictEqual(
|
||||||
|
{
|
||||||
|
"limit": "limit",
|
||||||
|
"marker": "marker",
|
||||||
|
"share_group_id": "share_group_id",
|
||||||
|
},
|
||||||
|
share_groups._query_mapping._mapping,
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_make_share_groups(self):
|
||||||
|
share_group_res = share_group.ShareGroup(**EXAMPLE)
|
||||||
|
self.assertEqual(EXAMPLE['id'], share_group_res.id)
|
||||||
|
self.assertEqual(EXAMPLE['status'], share_group_res.status)
|
||||||
|
self.assertEqual(
|
||||||
|
EXAMPLE['availability_zone'], share_group_res.availability_zone
|
||||||
|
)
|
||||||
|
self.assertEqual(EXAMPLE['description'], share_group_res.description)
|
||||||
|
self.assertEqual(
|
||||||
|
EXAMPLE['source_share_group_snapshot_id'],
|
||||||
|
share_group_res.share_group_snapshot_id,
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
EXAMPLE['share_network_id'], share_group_res.share_network_id
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
EXAMPLE['share_group_type_id'], share_group_res.share_group_type_id
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
EXAMPLE['consistent_snapshot_support'],
|
||||||
|
share_group_res.consistent_snapshot_support,
|
||||||
|
)
|
||||||
|
self.assertEqual(EXAMPLE['created_at'], share_group_res.created_at)
|
||||||
|
self.assertEqual(EXAMPLE['project_id'], share_group_res.project_id)
|
||||||
|
self.assertEqual(EXAMPLE['share_types'], share_group_res.share_types)
|
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Added support to create, update, list, get, and delete share
|
||||||
|
groups on the shared file system service.
|
Reference in New Issue
Block a user