From c9051bc615b6b6afa591f5924e0570b53bcc342f Mon Sep 17 00:00:00 2001 From: Michal Kelner Mishali Date: Sun, 10 Mar 2019 14:34:52 +0200 Subject: [PATCH] NSX|V3+P: Limit number of subnet static routes per backend Adding a parameter that sets the allowed static routes per subnet, according to backend limitations. Change-Id: I968fdef53bb9dab41a54561ca36b2e6880505d05 Signed-off-by: Michal Kelner Mishali --- vmware_nsx/plugins/common_v3/plugin.py | 16 +++++++++++++++ vmware_nsx/tests/unit/nsx_v3/test_plugin.py | 22 +++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/vmware_nsx/plugins/common_v3/plugin.py b/vmware_nsx/plugins/common_v3/plugin.py index 6cb92910da..0e150fbc75 100644 --- a/vmware_nsx/plugins/common_v3/plugin.py +++ b/vmware_nsx/plugins/common_v3/plugin.py @@ -1756,6 +1756,7 @@ class NsxPluginV3Base(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, pass def _create_subnet(self, context, subnet): + self._validate_number_of_subnet_static_routes(subnet) self._validate_host_routes_input(subnet) # TODO(berlin): public external subnet announcement @@ -1934,6 +1935,20 @@ class NsxPluginV3Base(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, """Should be implemented by each plugin""" pass + def _validate_number_of_subnet_static_routes(self, subnet_input): + s = subnet_input['subnet'] + request_host_routes = (validators.is_attr_set(s.get('host_routes')) and + s['host_routes']) + num_allowed_on_backend = nsxlib_consts.MAX_STATIC_ROUTES + if request_host_routes: + if len(request_host_routes) > num_allowed_on_backend: + err_msg = (_( + "Number of static routes is limited at the backend to %(" + "backend)s. Requested %(requested)s") % + {'backend': nsxlib_consts.MAX_STATIC_ROUTES, + 'requested': len(request_host_routes)}) + raise n_exc.InvalidInput(error_message=err_msg) + def get_subnets(self, context, filters=None, fields=None, sorts=None, limit=None, marker=None, page_reverse=False): filters = filters or {} @@ -1977,6 +1992,7 @@ class NsxPluginV3Base(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, def _update_subnet(self, context, subnet_id, subnet): updated_subnet = None orig_subnet = self.get_subnet(context, subnet_id) + self._validate_number_of_subnet_static_routes(subnet) self._validate_host_routes_input( subnet, orig_enable_dhcp=orig_subnet['enable_dhcp'], diff --git a/vmware_nsx/tests/unit/nsx_v3/test_plugin.py b/vmware_nsx/tests/unit/nsx_v3/test_plugin.py index cad9ce740a..7c88f33ea6 100644 --- a/vmware_nsx/tests/unit/nsx_v3/test_plugin.py +++ b/vmware_nsx/tests/unit/nsx_v3/test_plugin.py @@ -927,6 +927,28 @@ class TestSubnetsV2(test_plugin.TestSubnetsV2, NsxV3PluginTestCaseMixin): self.plugin.create_subnet, context.get_admin_context(), data) + def test_fail_create_static_routes_per_subnet_over_limit(self): + with self.network() as network: + data = {'subnet': {'network_id': network['network']['id'], + 'cidr': '10.0.0.0/16', + 'name': 'sub1', + 'dns_nameservers': None, + 'allocation_pools': None, + 'tenant_id': 'tenant_one', + 'enable_dhcp': False, + 'ip_version': 4}} + count = 1 + host_routes = [] + while count < 28: + host_routes.append("'host_routes': [{'destination': " + "'135.207.0.0/%s', 'nexthop': " + "'1.2.3.%s'}]" % (count, count)) + count += 1 + data['subnet']['host_routes'] = host_routes + self.assertRaises(n_exc.InvalidInput, + self.plugin.create_subnet, + context.get_admin_context(), data) + def test_create_subnet_disable_dhcp_with_host_route_fails(self): with self.network() as network: data = {'subnet': {'network_id': network['network']['id'],