Make Neutron NVP plugin future-versions friendly
This patch enables the plugin to deal correctly with newer versions of the NVP platform; this is done by allowing the plugin to fall back to the closest known version of the NVP platform. This is acceptable behavior as L2/L3 operations implemented by the platform are most certainly backward compatible. This patch also improves test coverage for this part of the code, which is critical to the correct behavior of the plugin. Fixes bug #1217479 Change-Id: Ifcce47c6ee2bc2bc96ddfe9298d252700aceca3f
This commit is contained in:
parent
6ae42583eb
commit
80df449aa5
@ -84,18 +84,7 @@ def version_dependent(wrapped_func):
|
||||
# should return the NVP version
|
||||
v = (wrapped_func(cluster, *args, **kwargs) or
|
||||
cluster.api_client.get_nvp_version())
|
||||
if v:
|
||||
func = (NVPLIB_FUNC_DICT[func_name][v.major].get(v.minor) or
|
||||
NVPLIB_FUNC_DICT[func_name][v.major]['default'])
|
||||
if func is None:
|
||||
LOG.error(_('NVP version %(ver)s does not support method '
|
||||
'%(fun)s.') % {'ver': v, 'fun': func_name})
|
||||
raise NotImplementedError()
|
||||
else:
|
||||
raise NvpApiClient.ServiceUnavailable('NVP version is not set. '
|
||||
'Unable to complete request'
|
||||
'correctly. Check log for '
|
||||
'NVP communication errors.')
|
||||
func = get_function_by_version(func_name, v)
|
||||
func_kwargs = kwargs
|
||||
arg_spec = inspect.getargspec(func)
|
||||
if not arg_spec.keywords and not arg_spec.varargs:
|
||||
@ -1197,30 +1186,50 @@ def update_lrouter_port_ips(cluster, lrouter_id, lport_id,
|
||||
raise nvp_exc.NvpPluginException(err_msg=msg)
|
||||
|
||||
|
||||
DEFAULT = -1
|
||||
NVPLIB_FUNC_DICT = {
|
||||
'create_lrouter': {
|
||||
2: {'default': create_implicit_routing_lrouter, },
|
||||
3: {'default': create_implicit_routing_lrouter,
|
||||
2: {DEFAULT: create_implicit_routing_lrouter, },
|
||||
3: {DEFAULT: create_implicit_routing_lrouter,
|
||||
2: create_explicit_routing_lrouter, }, },
|
||||
'update_lrouter': {
|
||||
2: {'default': update_implicit_routing_lrouter, },
|
||||
3: {'default': update_implicit_routing_lrouter,
|
||||
2: {DEFAULT: update_implicit_routing_lrouter, },
|
||||
3: {DEFAULT: update_implicit_routing_lrouter,
|
||||
2: update_explicit_routing_lrouter, }, },
|
||||
'create_lrouter_dnat_rule': {
|
||||
2: {'default': create_lrouter_dnat_rule_v2, },
|
||||
3: {'default': create_lrouter_dnat_rule_v3, }, },
|
||||
2: {DEFAULT: create_lrouter_dnat_rule_v2, },
|
||||
3: {DEFAULT: create_lrouter_dnat_rule_v3, }, },
|
||||
'create_lrouter_snat_rule': {
|
||||
2: {'default': create_lrouter_snat_rule_v2, },
|
||||
3: {'default': create_lrouter_snat_rule_v3, }, },
|
||||
2: {DEFAULT: create_lrouter_snat_rule_v2, },
|
||||
3: {DEFAULT: create_lrouter_snat_rule_v3, }, },
|
||||
'create_lrouter_nosnat_rule': {
|
||||
2: {'default': create_lrouter_nosnat_rule_v2, },
|
||||
3: {'default': create_lrouter_nosnat_rule_v3, }, },
|
||||
2: {DEFAULT: create_lrouter_nosnat_rule_v2, },
|
||||
3: {DEFAULT: create_lrouter_nosnat_rule_v3, }, },
|
||||
'get_default_route_explicit_routing_lrouter': {
|
||||
3: {2: get_default_route_explicit_routing_lrouter_v32,
|
||||
3: get_default_route_explicit_routing_lrouter_v33, }, },
|
||||
3: {DEFAULT: get_default_route_explicit_routing_lrouter_v32,
|
||||
2: get_default_route_explicit_routing_lrouter_v32, }, },
|
||||
}
|
||||
|
||||
|
||||
def get_function_by_version(func_name, nvp_ver):
|
||||
if nvp_ver:
|
||||
if nvp_ver.major not in NVPLIB_FUNC_DICT[func_name]:
|
||||
major = max(NVPLIB_FUNC_DICT[func_name].keys())
|
||||
minor = max(NVPLIB_FUNC_DICT[func_name][major].keys())
|
||||
if major > nvp_ver.major:
|
||||
raise NotImplementedError(_("Operation may not be supported"))
|
||||
else:
|
||||
major = nvp_ver.major
|
||||
minor = nvp_ver.minor
|
||||
if nvp_ver.minor not in NVPLIB_FUNC_DICT[func_name][major]:
|
||||
minor = DEFAULT
|
||||
return NVPLIB_FUNC_DICT[func_name][major][minor]
|
||||
else:
|
||||
msg = _('NVP version is not set. Unable to complete request '
|
||||
'correctly. Check log for NVP communication errors.')
|
||||
raise NvpApiClient.ServiceUnavailable(message=msg)
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# QOS API Calls
|
||||
# -----------------------------------------------------------------------------
|
||||
|
@ -1388,5 +1388,37 @@ class TestNvplibClusterManagement(NvplibTestCase):
|
||||
cluster=self.fake_cluster)
|
||||
|
||||
|
||||
class TestNvplibVersioning(base.BaseTestCase):
|
||||
|
||||
def test_function_handling_missing_minor(self):
|
||||
version = NvpApiClient.NVPVersion('2.0')
|
||||
function = nvplib.get_function_by_version('create_lrouter', version)
|
||||
self.assertEqual(nvplib.create_implicit_routing_lrouter,
|
||||
function)
|
||||
|
||||
def test_function_handling_with_both_major_and_minor(self):
|
||||
version = NvpApiClient.NVPVersion('3.2')
|
||||
function = nvplib.get_function_by_version('create_lrouter', version)
|
||||
self.assertEqual(nvplib.create_explicit_routing_lrouter,
|
||||
function)
|
||||
|
||||
def test_function_handling_with_newer_major(self):
|
||||
version = NvpApiClient.NVPVersion('5.2')
|
||||
function = nvplib.get_function_by_version('create_lrouter', version)
|
||||
self.assertEqual(nvplib.create_explicit_routing_lrouter,
|
||||
function)
|
||||
|
||||
def test_function_handling_with_obsolete_major(self):
|
||||
version = NvpApiClient.NVPVersion('1.2')
|
||||
self.assertRaises(NotImplementedError,
|
||||
nvplib.get_function_by_version,
|
||||
'create_lrouter', version)
|
||||
|
||||
def test_function_handling_with_unknown_version(self):
|
||||
self.assertRaises(NvpApiClient.ServiceUnavailable,
|
||||
nvplib.get_function_by_version,
|
||||
'create_lrouter', None)
|
||||
|
||||
|
||||
def _nicira_method(method_name, module_name='nvplib'):
|
||||
return '%s.%s.%s' % ('neutron.plugins.nicira', module_name, method_name)
|
||||
|
Loading…
x
Reference in New Issue
Block a user