3PAR: Add update_access support

This patch adds support for update_access, a required feature for
the Newton release. allow_access and deny_acess are removed as well.

Implements: blueprint hpe3par-update-access
Change-Id: Ibe908dca68e65e2bad86afe60c73b470e9ff4e44
This commit is contained in:
Alex O'Rourke 2016-07-07 13:33:20 -07:00
parent 42843b0e8a
commit 5e0c233cac
6 changed files with 409 additions and 186 deletions

View File

@ -125,10 +125,11 @@ class HPE3ParShareDriver(driver.ShareDriver):
2.0.3 - Remove file tree on delete when using nested shares #1538800
2.0.4 - Reduce the fsquota by share size
when a share is deleted #1582931
2.0.5 - Add update_access support
"""
VERSION = "2.0.4"
VERSION = "2.0.5"
def __init__(self, *args, **kwargs):
super(HPE3ParShareDriver, self).__init__((True, False),
@ -362,33 +363,22 @@ class HPE3ParShareDriver(driver.ShareDriver):
def ensure_share(self, context, share, share_server=None):
pass
def allow_access(self, context, share, access, share_server=None):
"""Allow access to the share."""
def update_access(self, context, share, access_rules, add_rules,
delete_rules, share_server=None):
"""Update access to the share."""
extra_specs = None
if 'NFS' == share['share_proto']: # Avoiding DB call otherwise
extra_specs = share_types.get_extra_specs_from_share(share)
self._hpe3par.allow_access(share['project_id'],
share['id'],
share['share_proto'],
extra_specs,
access['access_type'],
access['access_to'],
access['access_level'],
self.fpg,
self.vfs)
def deny_access(self, context, share, access, share_server=None):
"""Deny access to the share."""
self._hpe3par.deny_access(share['project_id'],
share['id'],
share['share_proto'],
access['access_type'],
access['access_to'],
access['access_level'],
self.fpg,
self.vfs)
self._hpe3par.update_access(share['project_id'],
share['id'],
share['share_proto'],
extra_specs,
access_rules,
add_rules,
delete_rules,
self.fpg,
self.vfs)
def extend_share(self, share, new_size, share_server=None):
"""Extends size of existing share."""

View File

@ -76,10 +76,11 @@ class HPE3ParMediator(object):
2.0.5 - Reduce the fsquota by share size
when a share is deleted #1582931
2.0.6 - Read-write share from snapshot (using driver mount and copy)
2.0.7 - Add update_access support
"""
VERSION = "2.0.6"
VERSION = "2.0.7"
def __init__(self, **kwargs):
@ -1497,35 +1498,119 @@ class HPE3ParMediator(object):
six.text_type(e))
raise exception.ShareBackendException(msg)
def allow_access(self, project_id, share_id, share_proto,
extra_specs, access_type, access_to, access_level,
fpg, vfs):
"""Grant access to a share."""
def update_access(self, project_id, share_id, share_proto, extra_specs,
access_rules, add_rules, delete_rules, fpg, vfs):
"""Update access to a share."""
protocol = self.ensure_supported_protocol(share_proto)
self._change_access(ALLOW,
project_id,
share_id,
share_proto,
access_type,
access_to,
access_level,
fpg,
vfs,
extra_specs=extra_specs)
if not (delete_rules or add_rules):
# We need to re add all the rules. Check with 3PAR on it's current
# list and only add the deltas.
share = self._find_fshare(project_id,
share_id,
share_proto,
fpg,
vfs)
def deny_access(self, project_id, share_id, share_proto,
access_type, access_to, access_level, fpg, vfs):
"""Deny access to a share."""
ref_users = []
ro_ref_rules = []
if protocol == 'nfs':
ref_rules = share['clients']
self._change_access(DENY,
project_id,
share_id,
share_proto,
access_type,
access_to,
access_level,
fpg,
vfs)
# Check for RO rules.
ro_share = self._find_fshare(project_id,
share_id,
share_proto,
fpg,
vfs,
readonly=True)
if ro_share:
ro_ref_rules = ro_share['clients']
else:
ref_rules = [x[0] for x in share['allowPerm']]
ref_users = ref_rules[:]
# Get IP access as well
ips = share['allowIP']
if not isinstance(ips, list):
# If there is only one IP, the API returns a string
# rather than a list. We need to account for that.
ips = [ips]
ref_rules += ips
# Retrieve base rules.
base_rules = []
for rule in access_rules:
base_rules.append(rule['access_to'])
# Check if we need to remove any rules from 3PAR.
for rule in ref_rules:
if rule in ref_users:
rule_type = 'user'
else:
rule_type = 'ip'
if rule not in base_rules + [LOCAL_IP, LOCAL_IP_RO]:
self._change_access(DENY,
project_id,
share_id,
share_proto,
rule_type,
rule,
None,
fpg,
vfs)
# Check to see if there are any RO rules to remove.
for rule in ro_ref_rules:
if rule not in base_rules + [LOCAL_IP, LOCAL_IP_RO]:
self._change_access(DENY,
project_id,
share_id,
share_proto,
rule_type,
rule,
'ro',
fpg,
vfs)
# Check the rules we need to add.
for rule in access_rules:
if rule['access_to'] not in ref_rules and (
rule['access_to'] not in ro_ref_rules):
# Rule does not exist, we need to add it
self._change_access(ALLOW,
project_id,
share_id,
share_proto,
rule['access_type'],
rule['access_to'],
rule['access_level'],
fpg,
vfs,
extra_specs=extra_specs)
else:
# We have deltas of the rules that need to be added and deleted.
for rule in delete_rules:
self._change_access(DENY,
project_id,
share_id,
share_proto,
rule['access_type'],
rule['access_to'],
rule['access_level'],
fpg,
vfs)
for rule in add_rules:
self._change_access(ALLOW,
project_id,
share_id,
share_proto,
rule['access_type'],
rule['access_to'],
rule['access_level'],
fpg,
vfs,
extra_specs=extra_specs)
def resize_share(self, project_id, share_id, share_proto,
new_size, old_size, fpg, vfs):

View File

@ -67,6 +67,61 @@ EXPECTED_SUPER_SHARE_COMMENT = ('OpenStack super share used to delete nested '
EXPECTED_CIFS_DOMAIN = 'LOCAL_CLUSTER'
EXPECTED_MOUNT_PATH = '/mnt/'
# Access rules. Allow for overwrites.
ACCESS_RULE_NFS = {
'access_type': IP,
'access_to': EXPECTED_IP_1234,
'access_level': READ_WRITE,
}
ACCESS_RULE_CIFS = {
'access_type': USER,
'access_to': USERNAME,
'access_level': READ_WRITE,
}
ADD_RULE_BAD_TYPE = {
'access_type': 'unsupported_other_type',
'access_to': USERNAME,
'access_level': READ_WRITE,
}
ADD_RULE_IP = {
'access_type': IP,
'access_to': EXPECTED_IP_1234,
'access_level': READ_WRITE,
}
ADD_RULE_IP_RO = {
'access_type': IP,
'access_to': EXPECTED_IP_1234,
'access_level': READ_ONLY,
}
ADD_RULE_USER = {
'access_type': USER,
'access_to': USERNAME,
'access_level': READ_WRITE,
}
DELETE_RULE_IP = {
'access_type': IP,
'access_to': EXPECTED_IP_1234,
'access_level': READ_WRITE,
}
DELETE_RULE_USER = {
'access_type': USER,
'access_to': USERNAME,
'access_level': READ_WRITE,
}
DELETE_RULE_IP_RO = {
'access_type': IP,
'access_to': EXPECTED_IP_1234,
'access_level': READ_ONLY,
}
GET_FSQUOTA = {'message': None,
'total': 1,
'members': [{'hardBlock': '1024', 'softBlock': '1024'}]}

View File

@ -478,44 +478,53 @@ class HPE3ParDriverTestCase(test.TestCase):
]
self.mock_mediator.assert_has_calls(expected_calls)
def test_driver_allow_access(self):
def test_driver_update_access_add_rule(self):
self.init_driver()
context = None
self.driver.allow_access(context,
constants.NFS_SHARE_INFO,
constants.ACCESS_INFO)
self.driver.update_access(context,
constants.NFS_SHARE_INFO,
[constants.ACCESS_RULE_NFS],
[constants.ADD_RULE_IP],
[],
constants.ACCESS_INFO)
expected_calls = [
mock.call.allow_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_EXTRA_SPECS,
constants.IP,
constants.EXPECTED_IP_1234,
constants.ACCESS_INFO['access_level'],
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
mock.call.update_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_EXTRA_SPECS,
[constants.ACCESS_RULE_NFS],
[constants.ADD_RULE_IP],
[],
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
]
self.mock_mediator.assert_has_calls(expected_calls)
def test_driver_deny_access(self):
def test_driver_update_access_delete_rule(self):
self.init_driver()
context = None
self.driver.deny_access(context,
constants.NFS_SHARE_INFO,
constants.ACCESS_INFO)
self.driver.update_access(context,
constants.NFS_SHARE_INFO,
[constants.ACCESS_RULE_NFS],
[],
[constants.DELETE_RULE_IP],
constants.ACCESS_INFO)
expected_calls = [
mock.call.deny_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.IP,
constants.EXPECTED_IP_1234,
constants.READ_WRITE,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
mock.call.update_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_EXTRA_SPECS,
[constants.ACCESS_RULE_NFS],
[],
[constants.DELETE_RULE_IP],
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
]
self.mock_mediator.assert_has_calls(expected_calls)

View File

@ -1602,18 +1602,93 @@ class HPE3ParMediatorTestCase(test.TestCase):
expected_calls = [mock.call.getfsquota(fpg=constants.EXPECTED_FPG)]
self.mock_client.assert_has_calls(expected_calls)
def test_update_access_resync_rules_nfs(self):
self.init_mediator()
getfshare_result = {
'shareName': constants.EXPECTED_SHARE_NAME,
'fstoreName': constants.EXPECTED_FSTORE,
'clients': [constants.EXPECTED_IP_127],
'comment': constants.EXPECTED_COMMENT,
}
self.mock_client.getfshare.return_value = {
'total': 1,
'members': [getfshare_result],
'message': None,
}
self.mediator.update_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_EXTRA_SPECS,
[constants.ACCESS_RULE_NFS],
None,
None,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
expected_calls = [
mock.call.setfshare(
constants.NFS_LOWER,
constants.EXPECTED_VFS,
constants.EXPECTED_SHARE_NAME,
clientip='+'+constants.EXPECTED_IP_1234,
fpg=constants.EXPECTED_FPG,
fstore=constants.EXPECTED_FSTORE,
comment=constants.EXPECTED_COMMENT),
]
self.mock_client.assert_has_calls(expected_calls)
def test_update_access_resync_rules_cifs(self):
self.init_mediator()
getfshare_result = {
'shareName': constants.EXPECTED_SHARE_NAME,
'fstoreName': constants.EXPECTED_FSTORE,
'allowPerm': [['foo_user', 'fullcontrol']],
'allowIP': '',
'comment': constants.EXPECTED_COMMENT,
}
self.mock_client.getfshare.return_value = {
'total': 1,
'members': [getfshare_result],
'message': None,
}
self.mediator.update_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.CIFS,
constants.EXPECTED_EXTRA_SPECS,
[constants.ACCESS_RULE_CIFS],
None,
None,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
expected_calls = [
mock.call.setfshare(
constants.SMB_LOWER,
constants.EXPECTED_VFS,
constants.EXPECTED_SHARE_NAME,
allowperm='+' + constants.USERNAME + ':fullcontrol',
fpg=constants.EXPECTED_FPG,
fstore=constants.EXPECTED_FSTORE,
comment=constants.EXPECTED_COMMENT),
]
self.mock_client.assert_has_calls(expected_calls)
def test_mediator_allow_ip_ro_access_cifs_error(self):
self.init_mediator()
self.assertRaises(exception.InvalidShareAccess,
self.mediator.allow_access,
self.mediator.update_access,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.CIFS,
constants.EXPECTED_EXTRA_SPECS,
constants.IP,
constants.EXPECTED_IP_10203040,
constants.READ_ONLY,
[constants.ACCESS_RULE_NFS],
[constants.ADD_RULE_IP_RO],
[],
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
@ -1638,14 +1713,14 @@ class HPE3ParMediatorTestCase(test.TestCase):
}
self.assertRaises(exception.InvalidShareAccess,
self.mediator.allow_access,
self.mediator.update_access,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
proto,
constants.CIFS,
constants.EXPECTED_EXTRA_SPECS,
constants.IP,
constants.EXPECTED_IP_10203040,
constants.READ_WRITE,
[constants.ACCESS_RULE_NFS],
[constants.ADD_RULE_IP],
[],
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
@ -1669,15 +1744,16 @@ class HPE3ParMediatorTestCase(test.TestCase):
else:
expected_allowperm = '+%s:fullcontrol' % constants.USERNAME
self.mediator.allow_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.CIFS,
constants.EXPECTED_EXTRA_SPECS,
constants.USER,
constants.USERNAME,
access_level,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
constants.ADD_RULE_USER['access_level'] = access_level
self.mediator.update_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.CIFS,
constants.EXPECTED_EXTRA_SPECS,
[constants.ACCESS_RULE_CIFS],
[constants.ADD_RULE_USER],
[],
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
expected_calls = [
mock.call.setfshare(constants.SMB_LOWER,
@ -1729,14 +1805,15 @@ class HPE3ParMediatorTestCase(test.TestCase):
}
mock_log = self.mock_object(hpe3parmediator, 'LOG')
self.mediator.deny_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
proto,
constants.IP,
constants.EXPECTED_IP_10203040,
constants.READ_WRITE,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
self.mediator.update_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
proto,
constants.EXPECTED_EXTRA_SPECS,
[constants.ACCESS_RULE_NFS],
[],
[constants.DELETE_RULE_IP],
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
self.assertFalse(self.mock_client.setfshare.called)
self.assertTrue(mock_log.error.called)
@ -1747,14 +1824,15 @@ class HPE3ParMediatorTestCase(test.TestCase):
expected_denyperm = '-%s:fullcontrol' % constants.USERNAME
self.mediator.deny_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.CIFS,
constants.USER,
constants.USERNAME,
constants.READ_WRITE,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
self.mediator.update_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.CIFS,
constants.EXPECTED_EXTRA_SPECS,
[constants.ACCESS_RULE_CIFS],
[],
[constants.DELETE_RULE_USER],
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
expected_calls = [
mock.call.setfshare(constants.SMB_LOWER,
@ -1774,15 +1852,15 @@ class HPE3ParMediatorTestCase(test.TestCase):
expected_allowip = '+%s' % constants.EXPECTED_IP_1234
self.mediator.allow_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.CIFS,
constants.EXPECTED_EXTRA_SPECS,
constants.IP,
constants.EXPECTED_IP_1234,
constants.READ_WRITE,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
self.mediator.update_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.CIFS,
constants.EXPECTED_EXTRA_SPECS,
[constants.ACCESS_RULE_NFS],
[constants.ADD_RULE_IP],
[],
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
expected_calls = [
mock.call.setfshare(constants.SMB_LOWER,
@ -1801,14 +1879,15 @@ class HPE3ParMediatorTestCase(test.TestCase):
expected_denyip = '-%s' % constants.EXPECTED_IP_1234
self.mediator.deny_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.CIFS,
constants.IP,
constants.EXPECTED_IP_1234,
constants.READ_WRITE,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
self.mediator.update_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.CIFS,
constants.EXPECTED_EXTRA_SPECS,
[constants.ACCESS_RULE_NFS],
[],
[constants.DELETE_RULE_IP],
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
expected_calls = [
mock.call.setfshare(constants.SMB_LOWER,
@ -1831,15 +1910,15 @@ class HPE3ParMediatorTestCase(test.TestCase):
expected_clientip = '+%s' % constants.EXPECTED_IP_1234
for _ in range(2): # Test 2nd allow w/ already exists message.
self.mediator.allow_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_EXTRA_SPECS,
constants.IP,
constants.EXPECTED_IP_1234,
constants.READ_WRITE,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
self.mediator.update_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_EXTRA_SPECS,
[constants.ACCESS_RULE_NFS],
[constants.ADD_RULE_IP],
[],
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
expected_calls = 2 * [
mock.call.setfshare(constants.NFS.lower(),
@ -1859,14 +1938,15 @@ class HPE3ParMediatorTestCase(test.TestCase):
expected_clientip = '-%s' % constants.EXPECTED_IP_1234
self.mediator.deny_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.IP,
constants.EXPECTED_IP_1234,
constants.READ_WRITE,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
self.mediator.update_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_EXTRA_SPECS,
[constants.ACCESS_RULE_NFS],
[],
[constants.DELETE_RULE_IP],
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
expected_calls = [
mock.call.setfshare(constants.NFS.lower(),
@ -1896,14 +1976,15 @@ class HPE3ParMediatorTestCase(test.TestCase):
expected_clientip = '-%s' % constants.EXPECTED_IP_1234
self.mediator.deny_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.IP,
constants.EXPECTED_IP_1234,
constants.READ_ONLY,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
self.mediator.update_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_EXTRA_SPECS,
[constants.ACCESS_RULE_NFS],
[],
[constants.DELETE_RULE_IP_RO],
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
expected_calls = [
mock.call.setfshare(constants.NFS.lower(),
@ -1937,14 +2018,14 @@ class HPE3ParMediatorTestCase(test.TestCase):
self.init_mediator()
self.assertRaises(exception.HPE3ParInvalid,
self.mediator.allow_access,
self.mediator.update_access,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_EXTRA_SPECS,
constants.USER,
constants.USERNAME,
constants.READ_WRITE,
[constants.ACCESS_RULE_NFS],
[constants.ADD_RULE_USER],
[],
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
@ -1953,14 +2034,14 @@ class HPE3ParMediatorTestCase(test.TestCase):
self.init_mediator()
self.assertRaises(exception.InvalidInput,
self.mediator.allow_access,
self.mediator.update_access,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
'unsupported_other_protocol',
constants.EXPECTED_EXTRA_SPECS,
constants.USER,
constants.USERNAME,
constants.READ_WRITE,
[constants.ACCESS_RULE_NFS],
[constants.ADD_RULE_IP],
[],
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
@ -1969,14 +2050,14 @@ class HPE3ParMediatorTestCase(test.TestCase):
self.init_mediator()
self.assertRaises(exception.InvalidInput,
self.mediator.allow_access,
self.mediator.update_access,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.CIFS,
constants.EXPECTED_EXTRA_SPECS,
'unsupported_other_type',
constants.USERNAME,
constants.READ_WRITE,
[constants.ACCESS_RULE_NFS],
[constants.ADD_RULE_BAD_TYPE],
[],
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
@ -1987,14 +2068,14 @@ class HPE3ParMediatorTestCase(test.TestCase):
mock.Mock(return_value=None))
self.assertRaises(exception.HPE3ParInvalid,
self.mediator.allow_access,
self.mediator.update_access,
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_EXTRA_SPECS,
constants.IP,
constants.EXPECTED_IP_1234,
constants.READ_WRITE,
[constants.ACCESS_RULE_NFS],
[constants.ADD_RULE_IP],
[],
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
@ -2034,15 +2115,15 @@ class HPE3ParMediatorTestCase(test.TestCase):
share_id = 'foo'
self.mediator.allow_access(constants.EXPECTED_PROJECT_ID,
share_id,
constants.NFS,
constants.EXPECTED_EXTRA_SPECS,
constants.IP,
constants.EXPECTED_IP_1234,
constants.READ_ONLY,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
self.mediator.update_access(constants.EXPECTED_PROJECT_ID,
share_id,
constants.NFS,
constants.EXPECTED_EXTRA_SPECS,
[constants.ACCESS_RULE_NFS],
[constants.ADD_RULE_IP_RO],
[],
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
expected_calls = [
mock.call(constants.EXPECTED_PROJECT_ID,
@ -2093,15 +2174,15 @@ class HPE3ParMediatorTestCase(test.TestCase):
'_find_fshare',
mock.Mock(return_value=None))
self.mediator.deny_access(
constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.IP,
constants.READ_WRITE,
constants.EXPECTED_IP_1234,
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
self.mediator.update_access(constants.EXPECTED_PROJECT_ID,
constants.EXPECTED_SHARE_ID,
constants.NFS,
constants.EXPECTED_EXTRA_SPECS,
[constants.ACCESS_RULE_NFS],
[],
[constants.DELETE_RULE_IP],
constants.EXPECTED_FPG,
constants.EXPECTED_VFS)
expected_calls = [
mock.call(constants.EXPECTED_PROJECT_ID,

View File

@ -0,0 +1,3 @@
---
features:
- Add update_access support to HPE 3PAR driver.