Merge "3PAR driver fails to validate conf share server IPs"

This commit is contained in:
Jenkins 2016-09-23 02:55:08 +00:00 committed by Gerrit Code Review
commit 4b77503863
6 changed files with 142 additions and 19 deletions

View File

@ -211,10 +211,12 @@ class HPE3ParShareDriver(driver.ShareDriver):
when a share is deleted #1582931
2.0.5 - Add update_access support
2.0.6 - Multi pool support per backend
2.0.7 - Fix get_vfs() to correctly validate conf IP addresses at
boot up #1621016
"""
VERSION = "2.0.6"
VERSION = "2.0.7"
def __init__(self, *args, **kwargs):
super(HPE3ParShareDriver, self).__init__((True, False),
@ -264,7 +266,6 @@ class HPE3ParShareDriver(driver.ShareDriver):
def _validate_pool_ips(addresses, conf_pool_ips):
# Pool configured IP addresses should be subset of IP addresses
# retured from vfs
addresses = to_list(addresses)
if not set(conf_pool_ips) <= set(addresses):
msg = _("Incorrect configuration. "
"Configuration pool IP address did not match with "
@ -286,8 +287,6 @@ class HPE3ParShareDriver(driver.ShareDriver):
vfs_info = mediator.get_vfs(pool_name)
if self.driver_handles_share_servers:
# Use discovered IP(s) from array
vfs_info['vfsip']['address'] = to_list(
vfs_info['vfsip']['address'])
self.fpgs[pool_name] = {
vfs_info['vfsname']: vfs_info['vfsip']['address']}
elif conf_pool_ips == []:
@ -300,8 +299,6 @@ class HPE3ParShareDriver(driver.ShareDriver):
raise exception.HPE3ParInvalid(err=msg)
else:
# Use discovered pool ips
vfs_info['vfsip']['address'] = to_list(
vfs_info['vfsip']['address'])
self.fpgs[pool_name] = {
vfs_info['vfsname']: vfs_info['vfsip']['address']}
else:

View File

@ -78,10 +78,12 @@ class HPE3ParMediator(object):
2.0.6 - Read-write share from snapshot (using driver mount and copy)
2.0.7 - Add update_access support
2.0.8 - Multi pools support per backend
2.0.9 - Fix get_vfs() to correctly validate conf IP addresses at
boot up #1621016
"""
VERSION = "2.0.8"
VERSION = "2.0.9"
def __init__(self, **kwargs):
@ -1042,9 +1044,6 @@ class HPE3ParMediator(object):
'share_name': SUPER_SHARE})
return path
def get_vfs_name(self, fpg):
return self.get_vfs(fpg)['vfsname']
def get_vfs(self, fpg, vfs=None):
"""Get the VFS or raise an exception."""
@ -1074,7 +1073,23 @@ class HPE3ParMediator(object):
LOG.error(message)
raise exception.ShareBackendException(msg=message)
return result['members'][0]
value = result['members'][0]
if isinstance(value['vfsip'], dict):
# This is for 3parclient returning only one VFS entry
LOG.debug("3parclient version up to 4.2.1 is in use. Client "
"upgrade may be needed if using a VFS with multiple "
"IP addresses.")
value['vfsip']['address'] = [value['vfsip']['address']]
else:
# This is for 3parclient returning list of VFS entries
# Format get_vfs ret value to combine all IP addresses
discovered_vfs_ips = []
for vfs_entry in value['vfsip']:
if vfs_entry['address']:
discovered_vfs_ips.append(vfs_entry['address'])
value['vfsip'] = value['vfsip'][0]
value['vfsip']['address'] = discovered_vfs_ips
return value
@staticmethod
def _is_share_from_snapshot(fshare):

View File

@ -33,6 +33,7 @@ CIDR_PREFIX = '24'
# Constants to use with Mock and expect in results
EXPECTED_IP_10203040 = '10.20.30.40'
EXPECTED_IP_10203041 = '10.20.30.41'
EXPECTED_IP_1234 = '1.2.3.4'
EXPECTED_MY_IP = '9.8.7.6'
EXPECTED_IP_127 = '127.0.0.1'
@ -48,6 +49,7 @@ SHARE_ID = 'share-id'
EXPECTED_SHARE_ID = 'osf-share-id'
EXPECTED_SHARE_ID_RO = 'osf-ro-share-id'
EXPECTED_SHARE_NAME = 'share-name'
EXPECTED_NET_NAME = 'testnet'
EXPECTED_FPG = 'pool'
EXPECTED_HOST = 'hostname@backend#' + EXPECTED_FPG
UNEXPECTED_FPG = 'not_a_pool'
@ -64,8 +66,82 @@ EXPECTED_FPG_CONF = [{EXPECTED_FPG: [EXPECTED_IP_10203040]}]
EXPECTED_FSTORE = EXPECTED_PROJECT_ID
EXPECTED_VFS = 'test_vfs'
EXPECTED_GET_VFS = {'vfsname': EXPECTED_VFS,
'vfsip': {'address': EXPECTED_IP_10203040}}
'vfsip': {'address': [EXPECTED_IP_10203040]}}
EXPECTED_GET_VFS_MULTIPLES = {
'vfsname': EXPECTED_VFS,
'vfsip': {'address': [EXPECTED_IP_10203041, EXPECTED_IP_10203040]}}
EXPECTED_CLIENT_GET_VFS_MEMBERS_MULTI = {
'fspname': EXPECTED_VFS,
'vfsip': [
{'networkName': EXPECTED_NET_NAME,
'fspool': EXPECTED_VFS,
'address': EXPECTED_IP_10203040,
'prefixLen': EXPECTED_SUBNET,
'vfs': EXPECTED_VFS,
'vlanTag': EXPECTED_VLAN_TAG,
},
{'networkName': EXPECTED_NET_NAME,
'fspool': EXPECTED_VFS,
'address': EXPECTED_IP_10203041,
'prefixLen': EXPECTED_SUBNET,
'vfs': EXPECTED_VFS,
'vlanTag': EXPECTED_VLAN_TAG,
},
],
'vfsname': EXPECTED_VFS,
}
EXPECTED_MEDIATOR_GET_VFS_RET_VAL_MULTI = {
'fspname': EXPECTED_VFS,
'vfsip': {
'networkName': EXPECTED_NET_NAME,
'fspool': EXPECTED_VFS,
'address': [
EXPECTED_IP_10203040,
EXPECTED_IP_10203041,
],
'prefixLen': EXPECTED_SUBNET,
'vfs': EXPECTED_VFS,
'vlanTag': EXPECTED_VLAN_TAG
},
'vfsname': EXPECTED_VFS,
}
EXPECTED_CLIENT_GET_VFS_MEMBERS = {
'fspname': EXPECTED_VFS,
'vfsip': {
'networkName': EXPECTED_NET_NAME,
'fspool': EXPECTED_VFS,
'address': EXPECTED_IP_10203040,
'prefixLen': EXPECTED_SUBNET,
'vfs': EXPECTED_VFS,
'vlanTag': EXPECTED_VLAN_TAG,
},
'vfsname': EXPECTED_VFS,
}
EXPECTED_MEDIATOR_GET_VFS_RET_VAL = {
'fspname': EXPECTED_VFS,
'vfsip': {
'networkName': EXPECTED_NET_NAME,
'fspool': EXPECTED_VFS,
'address': [EXPECTED_IP_10203040],
'prefixLen': EXPECTED_SUBNET,
'vfs': EXPECTED_VFS,
'vlanTag': EXPECTED_VLAN_TAG,
},
'vfsname': EXPECTED_VFS,
}
EXPECTED_CLIENT_GET_VFS_RETURN_VALUE = {
'total': 1,
'members': [EXPECTED_CLIENT_GET_VFS_MEMBERS],
}
EXPECTED_CLIENT_GET_VFS_RETURN_VALUE_MULTI = {
'total': 1,
'members': [EXPECTED_CLIENT_GET_VFS_MEMBERS_MULTI],
}
EXPECTED_FPG_MAP = {EXPECTED_FPG: {EXPECTED_VFS: [EXPECTED_IP_10203040]}}
EXPECTED_FPG_MAP_MULTI_VFS = {EXPECTED_FPG: {
EXPECTED_VFS: [EXPECTED_IP_10203041, EXPECTED_IP_10203040]}}
EXPECTED_SHARE_IP = '10.50.3.8'
EXPECTED_HPE_DEBUG = True
EXPECTED_COMMENT = "OpenStack Manila - foo-comment"

View File

@ -117,10 +117,11 @@ class HPE3ParDriverTestCase(test.TestCase):
self.driver = hpe3pardriver.HPE3ParShareDriver(
configuration=self.conf)
def test_driver_setup_success(self):
def test_driver_setup_success(self,
get_vfs_ret_val=constants.EXPECTED_GET_VFS):
"""Driver do_setup without any errors."""
self.mock_mediator.get_vfs.return_value = constants.EXPECTED_GET_VFS
self.mock_mediator.get_vfs.return_value = get_vfs_ret_val
self.driver.do_setup(None)
conf = self.conf
@ -162,6 +163,15 @@ class HPE3ParDriverTestCase(test.TestCase):
self.test_driver_setup_success()
self.assertEqual(constants.EXPECTED_FPG_MAP, self.driver.fpgs)
def test_driver_setup_no_dhss_multi_getvfs_success(self):
"""Driver do_setup when dhss=False, getvfs returns multiple IPs."""
self.conf.driver_handles_share_servers = False
self.test_driver_setup_success(
get_vfs_ret_val=constants.EXPECTED_GET_VFS_MULTIPLES)
self.assertEqual(constants.EXPECTED_FPG_MAP,
self.driver.fpgs)
def test_driver_setup_success_no_dhss_no_conf_ss_ip(self):
"""test driver's do_setup()
@ -177,7 +187,7 @@ class HPE3ParDriverTestCase(test.TestCase):
self.test_driver_setup_success()
self.assertEqual(constants.EXPECTED_FPG_MAP, self.driver.fpgs)
self.conf.hpe3par_fpg = original_fpg
constants.EXPECTED_FPG_CONF = original_fpg
def test_driver_setup_failure_no_dhss_no_conf_ss_ip(self):
"""Configured IP address is required for dhss=False."""
@ -193,7 +203,7 @@ class HPE3ParDriverTestCase(test.TestCase):
self.assertRaises(exception.HPE3ParInvalid,
self.driver.do_setup, None)
self.conf.hpe3par_fpg = fpg_without_ss_ip
constants.EXPECTED_FPG_CONF = fpg_without_ss_ip
def test_driver_setup_mediator_error(self):
"""Driver do_setup when the mediator setup fails."""

View File

@ -121,12 +121,12 @@ class HPE3ParMediatorTestCase(test.TestCase):
conn_timeout=constants.TIMEOUT)])
def test_mediator_vfs_exception(self):
"""Backend exception during get_vfs_name."""
"""Backend exception during get_vfs."""
self.init_mediator()
self.mock_client.getvfs.side_effect = Exception('non-manila-except')
self.assertRaises(exception.ManilaException,
self.mediator.get_vfs_name,
self.mediator.get_vfs,
fpg=constants.EXPECTED_FPG)
expected_calls = [
mock.call.getvfs(fpg=constants.EXPECTED_FPG, vfs=None),
@ -138,13 +138,30 @@ class HPE3ParMediatorTestCase(test.TestCase):
self.init_mediator()
self.mock_client.getvfs.return_value = {'total': 0}
self.assertRaises(exception.ManilaException,
self.mediator.get_vfs_name,
self.mediator.get_vfs,
fpg=constants.EXPECTED_FPG)
expected_calls = [
mock.call.getvfs(fpg=constants.EXPECTED_FPG, vfs=None),
]
self.mock_client.assert_has_calls(expected_calls)
@ddt.data((constants.EXPECTED_CLIENT_GET_VFS_RETURN_VALUE,
constants.EXPECTED_MEDIATOR_GET_VFS_RET_VAL),
(constants.EXPECTED_CLIENT_GET_VFS_RETURN_VALUE_MULTI,
constants.EXPECTED_MEDIATOR_GET_VFS_RET_VAL_MULTI))
@ddt.unpack
def test_mediator_get_vfs(self, get_vfs_val, exp_vfs_val):
"""VFS not found."""
self.init_mediator()
self.mock_client.getvfs.return_value = get_vfs_val
ret_val = self.mediator.get_vfs(constants.EXPECTED_FPG)
self.assertEqual(exp_vfs_val, ret_val)
expected_calls = [
mock.call.getvfs(fpg=constants.EXPECTED_FPG, vfs=None),
]
self.mock_client.assert_has_calls(expected_calls)
def init_mediator(self):
"""Basic mediator setup for re-use with tests that need one."""

View File

@ -0,0 +1,8 @@
---
issues:
- 3parclient up to version 4.2.1 always returns only 1 VFS IP address.
This may cause 3PAR driver boot up failure while validating VFS IP
addresses against IP addresses configured in manila.conf.
fixes:
- Fixed 3PAR driver boot up failure while validating share server IP address
provided in manila.conf against IP address set on array.