Resource locks and access rules restrictions
Implement resource locks and access rules restrictions feature in the openstacksdk. Depends-On: Ib9f65a4523222f1224d51534c5061f90501b59d3 Change-Id: I45f9b06b1b41756d34f39604c82e28fd4eb102de
This commit is contained in:
parent
568921ce5b
commit
4e0d693816
@ -133,7 +133,9 @@ Shared File System Share Access Rules
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Create, View, and Delete access rules for shares from the
|
||||
Shared File Systems service.
|
||||
Shared File Systems service. Access rules can also have their deletion
|
||||
and visibility restricted during creation. A lock reason can also be
|
||||
specified. The deletion restriction can be removed during the access removal.
|
||||
|
||||
.. autoclass:: openstack.shared_file_system.v2._proxy.Proxy
|
||||
:noindex:
|
||||
@ -177,3 +179,16 @@ Shared File Systems service.
|
||||
:members: get_share_metadata, get_share_metadata_item,
|
||||
create_share_metadata, update_share_metadata,
|
||||
delete_share_metadata
|
||||
|
||||
|
||||
Shared File System Resource Locks
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Create, list, update and delete locks for resources. When a resource is
|
||||
locked, it means that it can be deleted only by services, admins or
|
||||
the user that created the lock.
|
||||
|
||||
.. autoclass:: openstack.shared_file_system.v2._proxy.Proxy
|
||||
:noindex:
|
||||
:members: resource_locks, get_resource_lock, update_resource_lock,
|
||||
delete_resource_lock, create_resource_lock
|
||||
|
@ -17,3 +17,4 @@ Shared File System service resources
|
||||
v2/share_group
|
||||
v2/share_access_rule
|
||||
v2/share_group_snapshot
|
||||
v2/resource_locks
|
||||
|
@ -0,0 +1,13 @@
|
||||
openstack.shared_file_system.v2.resource_locks
|
||||
==============================================
|
||||
|
||||
.. automodule:: openstack.shared_file_system.v2.resource_locks
|
||||
|
||||
The Resource Locks Class
|
||||
------------------------
|
||||
|
||||
The ``ResourceLock`` class inherits from
|
||||
:class:`~openstack.resource.Resource`.
|
||||
|
||||
.. autoclass:: openstack.shared_file_system.v2.resource_locks.ResourceLock
|
||||
:members:
|
@ -632,6 +632,13 @@ class Proxy(adapter.Adapter):
|
||||
:returns: The result of the ``create``
|
||||
:rtype: :class:`~openstack.resource.Resource`
|
||||
"""
|
||||
# Check for attributes whose names conflict with the parameters
|
||||
# specified in the method.
|
||||
conflicting_attrs = attrs.get('__conflicting_attrs', {})
|
||||
if conflicting_attrs:
|
||||
for k, v in conflicting_attrs.items():
|
||||
attrs[k] = v
|
||||
attrs.pop('__conflicting_attrs')
|
||||
conn = self._get_connection()
|
||||
res = resource_type.new(connection=conn, **attrs)
|
||||
return res.create(self, base_path=base_path)
|
||||
|
@ -16,6 +16,7 @@ from openstack.shared_file_system.v2 import (
|
||||
availability_zone as _availability_zone,
|
||||
)
|
||||
from openstack.shared_file_system.v2 import limit as _limit
|
||||
from openstack.shared_file_system.v2 import resource_locks as _resource_locks
|
||||
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 (
|
||||
@ -56,6 +57,7 @@ class Proxy(proxy.Proxy):
|
||||
"share_access_rule": _share_access_rule.ShareAccessRule,
|
||||
"share_group": _share_group.ShareGroup,
|
||||
"share_group_snapshot": _share_group_snapshot.ShareGroupSnapshot,
|
||||
"resource_locks": _resource_locks.ResourceLock,
|
||||
}
|
||||
|
||||
def availability_zones(self):
|
||||
@ -354,7 +356,13 @@ class Proxy(proxy.Proxy):
|
||||
)
|
||||
|
||||
def wait_for_status(
|
||||
self, res, status='active', failures=None, interval=2, wait=120
|
||||
self,
|
||||
res,
|
||||
status='active',
|
||||
failures=None,
|
||||
interval=2,
|
||||
wait=120,
|
||||
status_attr_name='status',
|
||||
):
|
||||
"""Wait for a resource to be in a particular status.
|
||||
:param res: The resource to wait on to reach the specified status.
|
||||
@ -367,6 +375,8 @@ class Proxy(proxy.Proxy):
|
||||
checks. Default to 2.
|
||||
:param wait: Maximum number of seconds to wait before the change.
|
||||
Default to 120.
|
||||
:param status_attr_name: name of the attribute to reach the desired
|
||||
status.
|
||||
:returns: The resource is returned on success.
|
||||
:raises: :class:`~openstack.exceptions.ResourceTimeout` if transition
|
||||
to the desired status failed to occur in specified seconds.
|
||||
@ -377,7 +387,13 @@ class Proxy(proxy.Proxy):
|
||||
"""
|
||||
failures = [] if failures is None else failures
|
||||
return resource.wait_for_status(
|
||||
self, res, status, failures, interval, wait
|
||||
self,
|
||||
res,
|
||||
status,
|
||||
failures,
|
||||
interval,
|
||||
wait,
|
||||
attribute=status_attr_name,
|
||||
)
|
||||
|
||||
def storage_pools(self, details=True, **query):
|
||||
@ -846,17 +862,25 @@ class Proxy(proxy.Proxy):
|
||||
_share_access_rule.ShareAccessRule, base_path=base_path, **attrs
|
||||
)
|
||||
|
||||
def delete_access_rule(self, access_id, share_id, ignore_missing=True):
|
||||
def delete_access_rule(
|
||||
self, access_id, share_id, ignore_missing=True, *, unrestrict=False
|
||||
):
|
||||
"""Deletes an access rule
|
||||
|
||||
:param access_id: The id of the access rule to get
|
||||
:param share_id: The ID of the share
|
||||
:param unrestrict: If Manila must attempt removing locks while deleting
|
||||
|
||||
:rtype: ``requests.models.Response`` HTTP response from internal
|
||||
requests client
|
||||
"""
|
||||
res = self._get_resource(_share_access_rule.ShareAccessRule, access_id)
|
||||
res.delete(self, share_id, ignore_missing=ignore_missing)
|
||||
return res.delete(
|
||||
self,
|
||||
share_id,
|
||||
ignore_missing=ignore_missing,
|
||||
unrestrict=unrestrict,
|
||||
)
|
||||
|
||||
def share_group_snapshots(self, details=True, **query):
|
||||
"""Lists all share group snapshots.
|
||||
@ -1065,3 +1089,112 @@ class Proxy(proxy.Proxy):
|
||||
raise exceptions.SDKException(
|
||||
"Some keys failed to be deleted %s" % keys_failed_to_delete
|
||||
)
|
||||
|
||||
def resource_locks(self, **query):
|
||||
"""Lists all resource locks.
|
||||
|
||||
:param kwargs query: Optional query parameters to be sent to limit
|
||||
the resource locks being returned. Available parameters include:
|
||||
|
||||
* project_id: The project ID of the user that the lock is
|
||||
created for.
|
||||
* user_id: The ID of a user to filter resource locks by.
|
||||
* all_projects: list locks from all projects (Admin Only)
|
||||
* resource_id: The ID of the resource that the locks pertain to
|
||||
filter resource locks by.
|
||||
* resource_action: The action prevented by the filtered resource
|
||||
locks.
|
||||
* resource_type: The type of the resource that the locks pertain
|
||||
to filter resource locks by.
|
||||
* lock_context: The lock creator’s context to filter locks by.
|
||||
* lock_reason: The lock reason that can be used to filter resource
|
||||
locks. (Inexact search is also available with lock_reason~)
|
||||
* created_since: Search for the list of resources that were created
|
||||
after the specified date. The date is in ‘yyyy-mm-dd’ format.
|
||||
* created_before: Search for the list of resources that were
|
||||
created prior to the specified date. The date is in
|
||||
‘yyyy-mm-dd’ format.
|
||||
* limit: The maximum number of resource locks to return.
|
||||
* offset: The offset to define start point of resource lock
|
||||
listing.
|
||||
* sort_key: The key to sort a list of shares.
|
||||
* sort_dir: The direction to sort a list of shares
|
||||
* with_count: Whether to show count in API response or not,
|
||||
default is False. This query parameter is useful with
|
||||
pagination.
|
||||
|
||||
:returns: A generator of manila resource locks
|
||||
:rtype: :class:`~openstack.shared_file_system.v2.
|
||||
resource_locks.ResourceLock`
|
||||
"""
|
||||
return self._list(_resource_locks.ResourceLock, **query)
|
||||
|
||||
def get_resource_lock(self, resource_lock):
|
||||
"""Show details of a resource lock.
|
||||
|
||||
:param resource_lock: The ID of a resource lock or a
|
||||
:class:`~openstack.shared_file_system.v2.
|
||||
resource_locks.ResourceLock` instance.
|
||||
:returns: Details of the identified resource lock.
|
||||
:rtype: :class:`~openstack.shared_file_system.v2.
|
||||
resource_locks.ResourceLock`
|
||||
"""
|
||||
return self._get(_resource_locks.ResourceLock, resource_lock)
|
||||
|
||||
def update_resource_lock(self, resource_lock, **attrs):
|
||||
"""Updates details of a single resource lock.
|
||||
|
||||
:param resource_lock: The ID of a resource lock or a
|
||||
:class:`~openstack.shared_file_system.v2.
|
||||
resource_locks.ResourceLock` instance.
|
||||
:param dict attrs: The attributes to update on the resource lock
|
||||
:returns: the updated resource lock
|
||||
:rtype: :class:`~openstack.shared_file_system.v2.
|
||||
resource_locks.ResourceLock`
|
||||
"""
|
||||
return self._update(
|
||||
_resource_locks.ResourceLock, resource_lock, **attrs
|
||||
)
|
||||
|
||||
def delete_resource_lock(self, resource_lock, ignore_missing=True):
|
||||
"""Deletes a single resource lock
|
||||
|
||||
:param resource_lock: The ID of a resource lock or a
|
||||
:class:`~openstack.shared_file_system.v2.
|
||||
resource_locks.ResourceLock` instance.
|
||||
:returns: Result of the ``delete``
|
||||
:rtype: ``None``
|
||||
"""
|
||||
return self._delete(
|
||||
_resource_locks.ResourceLock,
|
||||
resource_lock,
|
||||
ignore_missing=ignore_missing,
|
||||
)
|
||||
|
||||
def create_resource_lock(self, **attrs):
|
||||
"""Locks a resource.
|
||||
|
||||
:param dict attrs: Attributes which will be used to create
|
||||
a :class:`~openstack.shared_file_system.v2.
|
||||
resource_locks.ResourceLock`, comprised of the properties
|
||||
on the ResourceLock class. Available parameters include:
|
||||
|
||||
* ``resource_id``: ID of the resource to be locked.
|
||||
* ``resource_type``: type of the resource (share, access_rule).
|
||||
* ``resource_action``: action to be locked (delete, show).
|
||||
* ``lock_reason``: reason why you're locking the resource
|
||||
(Optional).
|
||||
:returns: Details of the lock
|
||||
:rtype: :class:`~openstack.shared_file_system.v2.
|
||||
resource_locks.ResourceLock`
|
||||
"""
|
||||
|
||||
if attrs.get('resource_type'):
|
||||
# The _create method has a parameter named resource_type, which
|
||||
# refers to the type of resource to be created, so we need to avoid
|
||||
# a conflict of parameters we are sending to the method.
|
||||
attrs['__conflicting_attrs'] = {
|
||||
'resource_type': attrs.get('resource_type')
|
||||
}
|
||||
attrs.pop('resource_type')
|
||||
return self._create(_resource_locks.ResourceLock, **attrs)
|
||||
|
73
openstack/shared_file_system/v2/resource_locks.py
Normal file
73
openstack/shared_file_system/v2/resource_locks.py
Normal file
@ -0,0 +1,73 @@
|
||||
# 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 ResourceLock(resource.Resource):
|
||||
resource_key = "resource_lock"
|
||||
resources_key = "resource_locks"
|
||||
base_path = "/resource-locks"
|
||||
|
||||
# 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",
|
||||
"created_since",
|
||||
"created_before",
|
||||
"limit",
|
||||
"offset",
|
||||
"id",
|
||||
"resource_id",
|
||||
"resource_type",
|
||||
"resource_action",
|
||||
"user_id",
|
||||
"lock_context",
|
||||
"lock_reason",
|
||||
"lock_reason~",
|
||||
"sort_key",
|
||||
"sort_dir",
|
||||
"with_count",
|
||||
"all_projects",
|
||||
)
|
||||
# The resource was introduced in this microversion, so it is the minimum
|
||||
# version to use it. Openstacksdk currently doesn't allow to set
|
||||
# minimum microversions.
|
||||
_max_microversion = '2.81'
|
||||
|
||||
#: Properties
|
||||
#: The date and time stamp when the resource was created within the
|
||||
#: service’s database.
|
||||
created_at = resource.Body("created_at", type=str)
|
||||
#: The date and time stamp when the resource was last modified within the
|
||||
#: service’s database.
|
||||
updated_at = resource.Body("updated_at", type=str)
|
||||
#: The ID of the user that owns the lock
|
||||
user_id = resource.Body("user_id", type=str)
|
||||
#: The ID of the project that owns the lock.
|
||||
project_id = resource.Body("project_id", type=str)
|
||||
#: The type of the resource that is locked, i.e.: share, access rule.
|
||||
resource_type = resource.Body("resource_type", type=str)
|
||||
#: The UUID of the resource that is locked.
|
||||
resource_id = resource.Body("resource_id", type=str)
|
||||
#: What action is currently locked, i.e.: deletion, visibility of fields.
|
||||
resource_action = resource.Body("resource_action", type=str)
|
||||
#: The reason specified while the lock was being placed.
|
||||
lock_reason = resource.Body("lock_reason", type=str)
|
||||
#: The context that placed the lock (user, admin or service).
|
||||
lock_context = resource.Body("lock_context", type=str)
|
@ -16,7 +16,7 @@ from openstack import utils
|
||||
|
||||
|
||||
class ShareAccessRule(resource.Resource):
|
||||
resource_key = "share_access_rule"
|
||||
resource_key = "access"
|
||||
resources_key = "access_list"
|
||||
base_path = "/share-access-rules"
|
||||
|
||||
@ -30,7 +30,8 @@ class ShareAccessRule(resource.Resource):
|
||||
|
||||
_query_mapping = resource.QueryParameters("share_id")
|
||||
|
||||
_max_microversion = '2.45'
|
||||
# Restricted access rules became available in 2.82
|
||||
_max_microversion = '2.82'
|
||||
|
||||
#: Properties
|
||||
#: The access credential of the entity granted share access.
|
||||
@ -56,6 +57,12 @@ class ShareAccessRule(resource.Resource):
|
||||
#: The date and time stamp when the resource was last updated within
|
||||
#: the service’s database.
|
||||
updated_at = resource.Body("updated_at", type=str)
|
||||
#: Whether the visibility of some sensitive fields is restricted or not
|
||||
lock_visibility = resource.Body("lock_visibility", type=bool)
|
||||
#: Whether the deletion of the access rule should be restricted or not
|
||||
lock_deletion = resource.Body("lock_deletion", type=bool)
|
||||
#: Reason for placing the loc
|
||||
lock_reason = resource.Body("lock_reason", type=bool)
|
||||
|
||||
def _action(self, session, body, url, action='patch', microversion=None):
|
||||
headers = {'Accept': ''}
|
||||
@ -75,8 +82,12 @@ class ShareAccessRule(resource.Resource):
|
||||
**kwargs
|
||||
)
|
||||
|
||||
def delete(self, session, share_id, ignore_missing=True):
|
||||
def delete(
|
||||
self, session, share_id, ignore_missing=True, *, unrestrict=False
|
||||
):
|
||||
body = {"deny_access": {"access_id": self.id}}
|
||||
if unrestrict:
|
||||
body['deny_access']['unrestrict'] = True
|
||||
url = utils.urljoin("/shares", share_id, "action")
|
||||
response = self._action(session, body, url)
|
||||
try:
|
||||
|
@ -22,8 +22,8 @@ class BaseSharedFileSystemTest(base.BaseFunctionalTest):
|
||||
self.require_service(
|
||||
'shared-file-system', min_microversion=self.min_microversion
|
||||
)
|
||||
self._set_operator_cloud(shared_file_system_api_version='2.78')
|
||||
self._set_user_cloud(shared_file_system_api_version='2.78')
|
||||
self._set_operator_cloud(shared_file_system_api_version='2.82')
|
||||
self._set_user_cloud(shared_file_system_api_version='2.82')
|
||||
|
||||
def create_share(self, **kwargs):
|
||||
share = self.user_cloud.share.create_share(**kwargs)
|
||||
@ -75,3 +75,13 @@ class BaseSharedFileSystemTest(base.BaseFunctionalTest):
|
||||
)
|
||||
self.assertIsNotNone(share_group.id)
|
||||
return share_group
|
||||
|
||||
def create_resource_lock(self, **kwargs):
|
||||
resource_lock = self.user_cloud.share.create_resource_lock(**kwargs)
|
||||
self.addCleanup(
|
||||
self.user_cloud.share.delete_resource_lock,
|
||||
resource_lock.id,
|
||||
ignore_missing=True,
|
||||
)
|
||||
self.assertIsNotNone(resource_lock.id)
|
||||
return resource_lock
|
||||
|
@ -0,0 +1,96 @@
|
||||
# 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 resource_locks as _resource_locks
|
||||
from openstack.tests.functional.shared_file_system import base
|
||||
|
||||
|
||||
class ResourceLocksTest(base.BaseSharedFileSystemTest):
|
||||
def setUp(self):
|
||||
super(ResourceLocksTest, self).setUp()
|
||||
|
||||
self.SHARE_NAME = self.getUniqueString()
|
||||
share = self.user_cloud.shared_file_system.create_share(
|
||||
name=self.SHARE_NAME,
|
||||
size=2,
|
||||
share_type="dhss_false",
|
||||
share_protocol='NFS',
|
||||
description=None,
|
||||
)
|
||||
self.SHARE_ID = share.id
|
||||
self.user_cloud.shared_file_system.wait_for_status(
|
||||
share,
|
||||
status='available',
|
||||
failures=['error'],
|
||||
interval=5,
|
||||
wait=self._wait_for_timeout,
|
||||
)
|
||||
access_rule = self.user_cloud.share.create_access_rule(
|
||||
self.SHARE_ID,
|
||||
access_level="rw",
|
||||
access_type="ip",
|
||||
access_to="0.0.0.0/0",
|
||||
)
|
||||
self.user_cloud.shared_file_system.wait_for_status(
|
||||
access_rule,
|
||||
status='active',
|
||||
failures=['error'],
|
||||
interval=5,
|
||||
wait=self._wait_for_timeout,
|
||||
status_attr_name='state',
|
||||
)
|
||||
self.assertIsNotNone(share)
|
||||
self.assertIsNotNone(share.id)
|
||||
self.ACCESS_ID = access_rule.id
|
||||
share_lock = self.create_resource_lock(
|
||||
resource_action='delete',
|
||||
resource_type='share',
|
||||
resource_id=self.SHARE_ID,
|
||||
lock_reason='openstacksdk testing',
|
||||
)
|
||||
access_lock = self.create_resource_lock(
|
||||
resource_action='show',
|
||||
resource_type='access_rule',
|
||||
resource_id=self.ACCESS_ID,
|
||||
lock_reason='openstacksdk testing',
|
||||
)
|
||||
self.SHARE_LOCK_ID = share_lock.id
|
||||
self.ACCESS_LOCK_ID = access_lock.id
|
||||
|
||||
def test_get(self):
|
||||
share_lock = self.user_cloud.shared_file_system.get_resource_lock(
|
||||
self.SHARE_LOCK_ID
|
||||
)
|
||||
access_lock = self.user_cloud.shared_file_system.get_resource_lock(
|
||||
self.ACCESS_LOCK_ID
|
||||
)
|
||||
assert isinstance(share_lock, _resource_locks.ResourceLock)
|
||||
assert isinstance(access_lock, _resource_locks.ResourceLock)
|
||||
self.assertEqual(self.SHARE_LOCK_ID, share_lock.id)
|
||||
self.assertEqual(self.ACCESS_LOCK_ID, access_lock.id)
|
||||
self.assertEqual('show', access_lock.resource_action)
|
||||
|
||||
def test_list(self):
|
||||
resource_locks = self.user_cloud.share.resource_locks()
|
||||
self.assertGreater(len(list(resource_locks)), 0)
|
||||
lock_attrs = (
|
||||
'id',
|
||||
'lock_reason',
|
||||
'resource_type',
|
||||
'resource_action',
|
||||
'lock_context',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
)
|
||||
for lock in resource_locks:
|
||||
for attribute in lock_attrs:
|
||||
self.assertTrue(hasattr(lock, attribute))
|
@ -75,3 +75,16 @@ class ShareAccessRuleTest(base.BaseSharedFileSystemTest):
|
||||
'metadata',
|
||||
):
|
||||
self.assertTrue(hasattr(rule, attribute))
|
||||
|
||||
def test_create_delete_access_rule_with_locks(self):
|
||||
access_rule = self.user_cloud.share.create_access_rule(
|
||||
self.SHARE_ID,
|
||||
access_level="rw",
|
||||
access_type="ip",
|
||||
access_to="203.0.113.10",
|
||||
lock_deletion=True,
|
||||
lock_visibility=True,
|
||||
)
|
||||
self.user_cloud.share.delete_access_rule(
|
||||
access_rule['id'], self.SHARE_ID, unrestrict=True
|
||||
)
|
||||
|
@ -14,6 +14,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 resource_locks
|
||||
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_group
|
||||
@ -130,7 +131,7 @@ class TestSharedFileSystemShare(TestSharedFileSystemProxy):
|
||||
self.proxy.wait_for_status(mock_resource, 'ACTIVE')
|
||||
|
||||
mock_wait.assert_called_once_with(
|
||||
self.proxy, mock_resource, 'ACTIVE', [], 2, 120
|
||||
self.proxy, mock_resource, 'ACTIVE', [], 2, 120, attribute='status'
|
||||
)
|
||||
|
||||
|
||||
@ -473,8 +474,49 @@ class TestAccessRuleProxy(test_proxy_base.TestProxyBase):
|
||||
"openstack.shared_file_system.v2.share_access_rule."
|
||||
+ "ShareAccessRule.delete",
|
||||
self.proxy.delete_access_rule,
|
||||
method_args=['access_id', 'share_id', 'ignore_missing'],
|
||||
method_args=[
|
||||
'access_id',
|
||||
'share_id',
|
||||
'ignore_missing',
|
||||
],
|
||||
expected_args=[self.proxy, 'share_id'],
|
||||
expected_kwargs={'unrestrict': False},
|
||||
)
|
||||
|
||||
|
||||
class TestResourceLocksProxy(test_proxy_base.TestProxyBase):
|
||||
def setUp(self):
|
||||
super(TestResourceLocksProxy, self).setUp()
|
||||
self.proxy = _proxy.Proxy(self.session)
|
||||
|
||||
def test_list_resource_locks(self):
|
||||
self.verify_list(
|
||||
self.proxy.resource_locks, resource_locks.ResourceLock
|
||||
)
|
||||
|
||||
def test_resource_lock_get(self):
|
||||
self.verify_get(
|
||||
self.proxy.get_resource_lock, resource_locks.ResourceLock
|
||||
)
|
||||
|
||||
def test_resource_lock_delete(self):
|
||||
self.verify_delete(
|
||||
self.proxy.delete_resource_lock, resource_locks.ResourceLock, False
|
||||
)
|
||||
|
||||
def test_resource_lock_delete_ignore(self):
|
||||
self.verify_delete(
|
||||
self.proxy.delete_resource_lock, resource_locks.ResourceLock, True
|
||||
)
|
||||
|
||||
def test_resource_lock_create(self):
|
||||
self.verify_create(
|
||||
self.proxy.create_resource_lock, resource_locks.ResourceLock
|
||||
)
|
||||
|
||||
def test_resource_lock_update(self):
|
||||
self.verify_update(
|
||||
self.proxy.update_resource_lock, resource_locks.ResourceLock
|
||||
)
|
||||
|
||||
|
||||
|
@ -0,0 +1,8 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Added support to manipulate resource locks from the shared file system
|
||||
service.
|
||||
- |
|
||||
Added support to restrict the visibility and deletion of the shared file
|
||||
system share access rules.
|
Loading…
Reference in New Issue
Block a user