From 7d7776972117a6dc8697104117b8cec4d83f2c87 Mon Sep 17 00:00:00 2001 From: Manish Godara Date: Mon, 6 Oct 2014 10:03:28 -0700 Subject: [PATCH] Validate network config (vlan) Validate to make sure empty physical networks are not permitted. Added unit test as well. Change-Id: Ie55fab3c53276ed48d5e9d603e8c1dc59fa9cc32 Closes-Bug: 1325664 --- neutron/common/exceptions.py | 4 ++++ neutron/plugins/common/utils.py | 2 ++ neutron/plugins/ml2/drivers/type_vlan.py | 2 -- neutron/tests/unit/ml2/test_type_vlan.py | 22 ++++++++++++++++------ neutron/tests/unit/test_common_utils.py | 16 ++++++++++++++++ 5 files changed, 38 insertions(+), 8 deletions(-) diff --git a/neutron/common/exceptions.py b/neutron/common/exceptions.py index be62388aa..81c1e6e6a 100644 --- a/neutron/common/exceptions.py +++ b/neutron/common/exceptions.py @@ -305,6 +305,10 @@ class NetworkVlanRangeError(NeutronException): super(NetworkVlanRangeError, self).__init__(**kwargs) +class PhysicalNetworkNameError(NeutronException): + message = _("Empty physical network name.") + + class NetworkTunnelRangeError(NeutronException): message = _("Invalid network Tunnel range: " "'%(tunnel_range)s' - %(error)s") diff --git a/neutron/plugins/common/utils.py b/neutron/plugins/common/utils.py index 6abd52554..7addb639a 100644 --- a/neutron/plugins/common/utils.py +++ b/neutron/plugins/common/utils.py @@ -61,6 +61,8 @@ def parse_network_vlan_range(network_vlan_range): vlan_range = (int(vlan_min), int(vlan_max)) except ValueError as ex: raise n_exc.NetworkVlanRangeError(vlan_range=entry, error=ex) + if not network: + raise n_exc.PhysicalNetworkNameError() verify_vlan_range(vlan_range) return network, vlan_range else: diff --git a/neutron/plugins/ml2/drivers/type_vlan.py b/neutron/plugins/ml2/drivers/type_vlan.py index 5cd3c3c8b..efe17a4c3 100644 --- a/neutron/plugins/ml2/drivers/type_vlan.py +++ b/neutron/plugins/ml2/drivers/type_vlan.py @@ -87,8 +87,6 @@ class VlanTypeDriver(helpers.TypeDriverHelper): try: self.network_vlan_ranges = plugin_utils.parse_network_vlan_ranges( cfg.CONF.ml2_type_vlan.network_vlan_ranges) - # TODO(rkukura): Validate that each physical_network name - # is neither empty nor too long. except Exception: LOG.exception(_("Failed to parse network_vlan_ranges. " "Service terminated!")) diff --git a/neutron/tests/unit/ml2/test_type_vlan.py b/neutron/tests/unit/ml2/test_type_vlan.py index 2a7815212..4bf73e688 100644 --- a/neutron/tests/unit/ml2/test_type_vlan.py +++ b/neutron/tests/unit/ml2/test_type_vlan.py @@ -19,18 +19,18 @@ from testtools import matchers from neutron.common import exceptions as exc import neutron.db.api as db from neutron.plugins.common import constants as p_const +from neutron.plugins.common import utils as plugin_utils from neutron.plugins.ml2 import driver_api as api from neutron.plugins.ml2.drivers import type_vlan from neutron.tests.unit import testlib_api +from oslo.config import cfg PROVIDER_NET = 'phys_net1' TENANT_NET = 'phys_net2' VLAN_MIN = 200 VLAN_MAX = 209 -NETWORK_VLAN_RANGES = { - PROVIDER_NET: [], - TENANT_NET: [(VLAN_MIN, VLAN_MAX)], -} +NETWORK_VLAN_RANGES = [PROVIDER_NET, "%s:%s:%s" % + (TENANT_NET, VLAN_MIN, VLAN_MAX)] UPDATED_VLAN_RANGES = { PROVIDER_NET: [], TENANT_NET: [(VLAN_MIN + 5, VLAN_MAX + 5)], @@ -41,11 +41,21 @@ class VlanTypeTest(testlib_api.SqlTestCase): def setUp(self): super(VlanTypeTest, self).setUp() + cfg.CONF.set_override('network_vlan_ranges', NETWORK_VLAN_RANGES, + group='ml2_type_vlan') + self.network_vlan_ranges = plugin_utils.parse_network_vlan_ranges( + NETWORK_VLAN_RANGES) self.driver = type_vlan.VlanTypeDriver() - self.driver.network_vlan_ranges = NETWORK_VLAN_RANGES self.driver._sync_vlan_allocations() self.session = db.get_session() + def test_parse_network_exception_handling(self): + with mock.patch.object(plugin_utils, + 'parse_network_vlan_ranges') as parse_ranges: + parse_ranges.side_effect = Exception('any exception') + self.assertRaises(SystemExit, + self.driver._parse_network_vlan_ranges) + def _get_allocation(self, session, segment): return session.query(type_vlan.VlanAllocation).filter_by( physical_network=segment[api.PHYSICAL_NETWORK], @@ -128,7 +138,7 @@ class VlanTypeTest(testlib_api.SqlTestCase): self.assertFalse( self._get_allocation(self.session, segment).allocated) - check_in_ranges(NETWORK_VLAN_RANGES) + check_in_ranges(self.network_vlan_ranges) self.driver.network_vlan_ranges = UPDATED_VLAN_RANGES self.driver._sync_vlan_allocations() check_in_ranges(UPDATED_VLAN_RANGES) diff --git a/neutron/tests/unit/test_common_utils.py b/neutron/tests/unit/test_common_utils.py index 5534e380d..c4dfb5a1c 100644 --- a/neutron/tests/unit/test_common_utils.py +++ b/neutron/tests/unit/test_common_utils.py @@ -161,6 +161,22 @@ class UtilTestParseVlanRanges(base.BaseTestCase): return self._err_prefix + v_range_str + self._err_range +class TestVlanNetworkNameValid(base.BaseTestCase): + def parse_vlan_ranges(self, vlan_range): + return plugin_utils.parse_network_vlan_ranges(vlan_range) + + def test_validate_provider_phynet_name_mixed(self): + self.assertRaises(n_exc.PhysicalNetworkNameError, + self.parse_vlan_ranges, + ['', ':23:30', 'physnet1', + 'tenant_net:100:200']) + + def test_validate_provider_phynet_name_bad(self): + self.assertRaises(n_exc.PhysicalNetworkNameError, + self.parse_vlan_ranges, + [':1:34']) + + class TestVlanRangeVerifyValid(UtilTestParseVlanRanges): def verify_range(self, vlan_range): return plugin_utils.verify_vlan_range(vlan_range) -- 2.45.2