Simplify the way drivers report support for ipv6
Driver shouldn't have to report support for ipv6 in two places. Drivers that assert ipv6_implemented=True just need to implement get_configured_ip_versions. Likewise ipv4 support is computed by the same method. Closes-bug: #1734127 Change-Id: I382767918a65b91e99ac1e604304ad01fac332e6
This commit is contained in:
parent
e741319d57
commit
42db1e34a7
@ -106,15 +106,16 @@ class NetworkBaseAPI(db_base.Base):
|
||||
pass
|
||||
|
||||
@property
|
||||
def enabled_ip_version(self):
|
||||
if not hasattr(self, '_enabled_ip_version'):
|
||||
def enabled_ip_versions(self):
|
||||
if not hasattr(self, '_enabled_ip_versions'):
|
||||
self._enabled_ip_versions = set()
|
||||
if self.configuration.network_plugin_ipv6_enabled:
|
||||
self._enabled_ip_version = 6
|
||||
elif self.configuration.network_plugin_ipv4_enabled:
|
||||
self._enabled_ip_version = 4
|
||||
else:
|
||||
self._enabled_ip_versions.add(6)
|
||||
if self.configuration.network_plugin_ipv4_enabled:
|
||||
self._enabled_ip_versions.add(4)
|
||||
if not self._enabled_ip_versions:
|
||||
msg = _("Either 'network_plugin_ipv4_enabled' or "
|
||||
"'network_plugin_ipv6_enabled' "
|
||||
"should be configured to 'True'.")
|
||||
raise exception.NetworkBadConfigurationException(reason=msg)
|
||||
return self._enabled_ip_version
|
||||
return self._enabled_ip_versions
|
||||
|
@ -242,7 +242,7 @@ class ShareDriver(object):
|
||||
self.configuration = kwargs.get('configuration', None)
|
||||
self.initialized = False
|
||||
self._stats = {}
|
||||
self.ip_version = None
|
||||
self.ip_versions = None
|
||||
self.ipv6_implemented = False
|
||||
|
||||
self.pools = []
|
||||
@ -1111,7 +1111,6 @@ class ShareDriver(object):
|
||||
replication_domain=self.replication_domain,
|
||||
filter_function=self.get_filter_function(),
|
||||
goodness_function=self.get_goodness_function(),
|
||||
ipv4_support=True,
|
||||
)
|
||||
if isinstance(data, dict):
|
||||
common.update(data)
|
||||
@ -2447,13 +2446,20 @@ class ShareDriver(object):
|
||||
"shares created on it.")
|
||||
return []
|
||||
|
||||
def get_configured_ip_version(self):
|
||||
""""Get Configured IP versions when DHSS is false.
|
||||
def get_configured_ip_versions(self):
|
||||
""""Get allowed IP versions.
|
||||
|
||||
The supported versions are returned with list, possible
|
||||
values are: [4], [6] or [4, 6]
|
||||
Each driver could override the method to return the IP version
|
||||
which represents its self configuration.
|
||||
values are: [4], [6], or [4, 6]
|
||||
|
||||
Drivers that assert ipv6_implemented = True must override
|
||||
this method. If the returned list includes 4, then shares
|
||||
created by this driver must have an IPv4 export location.
|
||||
If the list includes 6, then shares created by the driver
|
||||
must have an IPv6 export location.
|
||||
|
||||
Drivers should check that their storage controller actually
|
||||
has IPv4/IPv6 enabled and configured properly.
|
||||
"""
|
||||
|
||||
# For drivers that haven't implemented IPv6, assume legacy behavior
|
||||
@ -2467,40 +2473,29 @@ class ShareDriver(object):
|
||||
|
||||
When DHSS is true, the capabilities are determined by driver
|
||||
and configured network plugin.
|
||||
When DHSS is false, the capabilities are determined by driver and its
|
||||
configuration.
|
||||
When DHSS is false, the capabilities are determined by driver
|
||||
only.
|
||||
:param data: the capability dictionary
|
||||
:returns: capability data
|
||||
"""
|
||||
ipv4_support = data.get('ipv4_support', False)
|
||||
ipv6_support = data.get('ipv6_support', False)
|
||||
if self.ip_version is None:
|
||||
if self.driver_handles_share_servers:
|
||||
user_network_version = self.network_api.enabled_ip_version
|
||||
if self.admin_network_api:
|
||||
if (user_network_version ==
|
||||
self.admin_network_api.enabled_ip_version):
|
||||
self.ip_version = user_network_version
|
||||
self.ip_versions = self.get_configured_ip_versions()
|
||||
if isinstance(self.ip_versions, list):
|
||||
self.ip_versions = set(self.ip_versions)
|
||||
else:
|
||||
LOG.warning("The enabled IP version for the admin "
|
||||
"network plugin is different from "
|
||||
"that of user network plugin, this "
|
||||
"may lead to the backend never being "
|
||||
"chosen by the scheduler when ip "
|
||||
"version is specified in the share "
|
||||
"type.")
|
||||
else:
|
||||
self.ip_version = user_network_version
|
||||
else:
|
||||
self.ip_version = self.get_configured_ip_version()
|
||||
self.ip_versions = set(list(self.ip_versions))
|
||||
|
||||
if not isinstance(self.ip_version, list):
|
||||
self.ip_version = [self.ip_version]
|
||||
|
||||
data['ipv4_support'] = (4 in self.ip_version) and ipv4_support
|
||||
data['ipv6_support'] = (6 in self.ip_version) and ipv6_support
|
||||
if not (data['ipv4_support'] or data['ipv6_support']):
|
||||
LOG.error("Backend %s capabilities 'ipv4_support' "
|
||||
"and 'ipv6_support' are both False.",
|
||||
if not self.ip_versions:
|
||||
LOG.error("Backend %s supports neither IPv4 nor IPv6.",
|
||||
data['share_backend_name'])
|
||||
|
||||
if self.driver_handles_share_servers:
|
||||
network_versions = self.network_api.enabled_ip_versions
|
||||
self.ip_versions = self.ip_versions & network_versions
|
||||
if not self.ip_versions:
|
||||
LOG.error("The enabled IP version of the network plugin is "
|
||||
"not compatible with the version supported by "
|
||||
"backend %s.", data['share_backend_name'])
|
||||
|
||||
data['ipv4_support'] = (4 in self.ip_versions)
|
||||
data['ipv6_support'] = (6 in self.ip_versions)
|
||||
return data
|
||||
|
@ -216,7 +216,6 @@ class LVMShareDriver(LVMMixin, driver.ShareDriver):
|
||||
'mount_snapshot_support': True,
|
||||
'driver_name': 'LVMShareDriver',
|
||||
'pools': self.get_share_server_pools(),
|
||||
'ipv6_support': True
|
||||
}
|
||||
super(LVMShareDriver, self)._update_share_stats(data)
|
||||
|
||||
@ -432,8 +431,7 @@ class LVMShareDriver(LVMMixin, driver.ShareDriver):
|
||||
super(LVMShareDriver, self).delete_snapshot(context, snapshot,
|
||||
share_server)
|
||||
|
||||
def get_configured_ip_version(self):
|
||||
""""Get Configured IP versions when DHSS is false."""
|
||||
def get_configured_ip_versions(self):
|
||||
if self.configured_ip_version is None:
|
||||
try:
|
||||
self.configured_ip_version = []
|
||||
|
@ -235,5 +235,5 @@ class NetAppCmodeMultiSvmShareDriver(driver.ShareDriver):
|
||||
fallback_create,
|
||||
share_server)
|
||||
|
||||
def get_configured_ip_version(self):
|
||||
return self.library.get_configured_ip_version()
|
||||
def get_configured_ip_versions(self):
|
||||
return self.library.get_configured_ip_versions()
|
||||
|
@ -251,5 +251,5 @@ class NetAppCmodeSingleSvmShareDriver(driver.ShareDriver):
|
||||
fallback_create,
|
||||
share_server)
|
||||
|
||||
def get_configured_ip_version(self):
|
||||
return self.library.get_configured_ip_version()
|
||||
def get_configured_ip_versions(self):
|
||||
return self.library.get_configured_ip_versions()
|
||||
|
@ -385,7 +385,7 @@ class NetAppCmodeMultiSVMFileStorageLibrary(
|
||||
except exception.NetAppException:
|
||||
LOG.exception("Deleting Vserver VLAN failed.")
|
||||
|
||||
def get_configured_ip_version(self):
|
||||
def get_configured_ip_versions(self):
|
||||
versions = [4]
|
||||
options = self._client.get_net_options()
|
||||
if options['ipv6-enabled']:
|
||||
|
@ -148,7 +148,7 @@ class NetAppCmodeSingleSVMFileStorageLibrary(
|
||||
return 0
|
||||
|
||||
@na_utils.trace
|
||||
def get_configured_ip_version(self):
|
||||
def get_configured_ip_versions(self):
|
||||
ipv4 = False
|
||||
ipv6 = False
|
||||
vserver_client = self._get_api_client(vserver=self._vserver)
|
||||
|
@ -407,16 +407,16 @@ class LVMShareDriverTestCase(test.TestCase):
|
||||
(None, ['1001::1001'], [6]), (None, ['1.1.1.0'], [4]),
|
||||
(None, ['1001::1001/129', '1.1.1.0'], False))
|
||||
@ddt.unpack
|
||||
def test_get_configured_ip_version(
|
||||
def test_get_configured_ip_versions(
|
||||
self, configured_ip, configured_ips, configured_ip_version):
|
||||
CONF.set_default('lvm_share_export_ip', configured_ip)
|
||||
CONF.set_default('lvm_share_export_ips', configured_ips)
|
||||
if configured_ip_version:
|
||||
self.assertEqual(configured_ip_version,
|
||||
self._driver.get_configured_ip_version())
|
||||
self._driver.get_configured_ip_versions())
|
||||
else:
|
||||
self.assertRaises(exception.InvalidInput,
|
||||
self._driver.get_configured_ip_version)
|
||||
self._driver.get_configured_ip_versions)
|
||||
|
||||
def test_mount_device(self):
|
||||
mount_path = self._get_mount_path(self.share)
|
||||
|
@ -1085,67 +1085,57 @@ class ShareDriverTestCase(test.TestCase):
|
||||
'fake_context', 'fake_snapshot', ['r1', 'r2'],
|
||||
[], [])
|
||||
|
||||
@ddt.data({'capability': (True, True),
|
||||
'user_admin_networks': [[4], [4]],
|
||||
@ddt.data({'user_networks': set([4]), 'conf': [4],
|
||||
'expected': {'ipv4': True, 'ipv6': False}},
|
||||
{'capability': (True, True),
|
||||
'user_admin_networks': [[6], [6]],
|
||||
'expected': {'ipv4': False, 'ipv6': True}},
|
||||
{'capability': (False, False),
|
||||
'user_admin_networks': [[4], [4]],
|
||||
{'user_networks': set([6]), 'conf': [4],
|
||||
'expected': {'ipv4': False, 'ipv6': False}},
|
||||
{'capability': (True, True),
|
||||
'user_admin_networks': [[4], [6]],
|
||||
'expected': {'ipv4': False, 'ipv6': False}},
|
||||
{'capability': (False, False),
|
||||
'user_admin_networks': [[6], [4]],
|
||||
'expected': {'ipv4': False, 'ipv6': False}},)
|
||||
@ddt.unpack
|
||||
def test_add_ip_version_capability_if_dhss_true(self, capability,
|
||||
user_admin_networks,
|
||||
expected):
|
||||
share_driver = self._instantiate_share_driver(None, True)
|
||||
version = PropertyMock(side_effect=user_admin_networks)
|
||||
type(share_driver.network_api).enabled_ip_version = version
|
||||
data = {'share_backend_name': 'fake_backend',
|
||||
'ipv4_support': capability[0],
|
||||
'ipv6_support': capability[1]}
|
||||
|
||||
result = share_driver.add_ip_version_capability(data)
|
||||
|
||||
self.assertIsNotNone(result['ipv4_support'])
|
||||
self.assertEqual(expected['ipv4'], result['ipv4_support'])
|
||||
self.assertIsNotNone(result['ipv6_support'])
|
||||
self.assertEqual(expected['ipv6'], result['ipv6_support'])
|
||||
|
||||
@ddt.data({'capability': (True, False),
|
||||
'conf': [4],
|
||||
{'user_networks': set([4, 6]), 'conf': [4],
|
||||
'expected': {'ipv4': True, 'ipv6': False}},
|
||||
{'capability': (True, True),
|
||||
'conf': [6],
|
||||
'expected': {'ipv4': False, 'ipv6': True}},
|
||||
{'capability': (False, False),
|
||||
'conf': [4],
|
||||
{'user_networks': set([4]), 'conf': [6],
|
||||
'expected': {'ipv4': False, 'ipv6': False}},
|
||||
{'capability': (False, True),
|
||||
'conf': [4],
|
||||
'expected': {'ipv4': False, 'ipv6': False}},
|
||||
{'capability': (False, True),
|
||||
'conf': [6],
|
||||
{'user_networks': set([6]), 'conf': [6],
|
||||
'expected': {'ipv4': False, 'ipv6': True}},
|
||||
{'capability': (True, True),
|
||||
'conf': [4, 6],
|
||||
{'user_networks': set([4, 6]), 'conf': [6],
|
||||
'expected': {'ipv4': False, 'ipv6': True}},
|
||||
{'user_networks': set([4]), 'conf': [4, 6],
|
||||
'expected': {'ipv4': True, 'ipv6': False}},
|
||||
{'user_networks': set([6]), 'conf': [4, 6],
|
||||
'expected': {'ipv4': False, 'ipv6': True}},
|
||||
{'user_networks': set([4, 6]), 'conf': [4, 6],
|
||||
'expected': {'ipv4': True, 'ipv6': True}},
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_add_ip_version_capability_if_dhss_false(self, capability,
|
||||
conf, expected):
|
||||
share_driver = self._instantiate_share_driver(None, False)
|
||||
self.mock_object(share_driver, 'get_configured_ip_version',
|
||||
def test_add_ip_version_capability_if_dhss_true(self,
|
||||
user_networks,
|
||||
conf,
|
||||
expected):
|
||||
share_driver = self._instantiate_share_driver(None, True)
|
||||
self.mock_object(share_driver, 'get_configured_ip_versions',
|
||||
mock.Mock(return_value=conf))
|
||||
data = {'share_backend_name': 'fake_backend',
|
||||
'ipv4_support': capability[0],
|
||||
'ipv6_support': capability[1]}
|
||||
versions = PropertyMock(return_value=user_networks)
|
||||
type(share_driver.network_api).enabled_ip_versions = versions
|
||||
data = {'share_backend_name': 'fake_backend'}
|
||||
|
||||
result = share_driver.add_ip_version_capability(data)
|
||||
|
||||
self.assertIsNotNone(result['ipv4_support'])
|
||||
self.assertEqual(expected['ipv4'], result['ipv4_support'])
|
||||
self.assertIsNotNone(result['ipv6_support'])
|
||||
self.assertEqual(expected['ipv6'], result['ipv6_support'])
|
||||
|
||||
@ddt.data({'conf': [4],
|
||||
'expected': {'ipv4': True, 'ipv6': False}},
|
||||
{'conf': [6],
|
||||
'expected': {'ipv4': False, 'ipv6': True}},
|
||||
{'conf': [4, 6],
|
||||
'expected': {'ipv4': True, 'ipv6': True}},
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_add_ip_version_capability_if_dhss_false(self, conf, expected):
|
||||
share_driver = self._instantiate_share_driver(None, False)
|
||||
self.mock_object(share_driver, 'get_configured_ip_versions',
|
||||
mock.Mock(return_value=conf))
|
||||
data = {'share_backend_name': 'fake_backend'}
|
||||
result = share_driver.add_ip_version_capability(data)
|
||||
|
||||
self.assertIsNotNone(result['ipv4_support'])
|
||||
|
@ -129,12 +129,12 @@ class NetworkBaseAPITestCase(test.TestCase):
|
||||
exception.NetworkBadConfigurationException,
|
||||
result._verify_share_network, 'foo_id', None)
|
||||
|
||||
@ddt.data((True, False, 6), (False, True, 4),
|
||||
(True, True, 6), (None, None, False))
|
||||
@ddt.data((True, False, set([6])), (False, True, set([4])),
|
||||
(True, True, set([4, 6])), (False, False, set()))
|
||||
@ddt.unpack
|
||||
def test_enabled_ip_version(self, network_plugin_ipv6_enabled,
|
||||
def test_enabled_ip_versions(self, network_plugin_ipv6_enabled,
|
||||
network_plugin_ipv4_enabled,
|
||||
enable_ip_version):
|
||||
enable_ip_versions):
|
||||
class FakeNetworkAPI(network.NetworkBaseAPI):
|
||||
def allocate_network(self, *args, **kwargs):
|
||||
pass
|
||||
@ -149,9 +149,9 @@ class NetworkBaseAPITestCase(test.TestCase):
|
||||
|
||||
result = FakeNetworkAPI()
|
||||
|
||||
if enable_ip_version:
|
||||
self.assertTrue(hasattr(result, 'enabled_ip_version'))
|
||||
self.assertEqual(enable_ip_version, result.enabled_ip_version)
|
||||
if enable_ip_versions:
|
||||
self.assertTrue(hasattr(result, 'enabled_ip_versions'))
|
||||
self.assertEqual(enable_ip_versions, result.enabled_ip_versions)
|
||||
else:
|
||||
self.assertRaises(exception.NetworkBadConfigurationException,
|
||||
getattr, result, 'enabled_ip_version')
|
||||
getattr, result, 'enabled_ip_versions')
|
||||
|
4
releasenotes/notes/bug-1734127-a239d022bef4a002.yaml
Normal file
4
releasenotes/notes/bug-1734127-a239d022bef4a002.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
fixes:
|
||||
- Fixed logic in driver base class that determines whether
|
||||
IPv6 is supported at runtime.
|
Loading…
Reference in New Issue
Block a user