From df80a6e73db2b5bd77b19d85634d7be0c00f39b0 Mon Sep 17 00:00:00 2001 From: Kevin Benton Date: Sat, 14 May 2016 05:39:31 -0700 Subject: [PATCH] Enforce UUID of port/subnet ID for router interfaces The add_router_interface/remove_router_interface actions are not subject to the typical attribute map validation so the input values for port_id and subnet_id were not being checked for UUID likeness. This lead to an ugly traceback if a boolean value was present which could fill logs with garbage if a tenant kept doing it. This patch calls the API validator for UUIDs in the _validate_interface_info function where we validate requests to add_router_inferface and remove_router_interface. Conflicts: neutron/db/l3_db.py Change-Id: I0a0d3279a21c815fb78528860fc2a35c1d5a4e2d Closes-Bug: #1584510 (cherry picked from commit 18280216cb7405856ba52f7eee0b1b214dcebd7b) --- neutron/db/l3_db.py | 6 ++++++ neutron/tests/unit/extensions/test_l3.py | 18 ++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/neutron/db/l3_db.py b/neutron/db/l3_db.py index f6f86c9e47d..c3fa58d6a25 100644 --- a/neutron/db/l3_db.py +++ b/neutron/db/l3_db.py @@ -518,6 +518,12 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase): if not (port_id_specified or subnet_id_specified): msg = _("Either subnet_id or port_id must be specified") raise n_exc.BadRequest(resource='router', msg=msg) + for key in ('port_id', 'subnet_id'): + if key not in interface_info: + continue + err = attributes._validate_uuid(interface_info[key]) + if err: + raise n_exc.BadRequest(resource='router', msg=err) if not for_removal: if port_id_specified and subnet_id_specified: msg = _("Cannot specify both subnet-id and port-id") diff --git a/neutron/tests/unit/extensions/test_l3.py b/neutron/tests/unit/extensions/test_l3.py index e9e339744d8..f1ecae6c30d 100644 --- a/neutron/tests/unit/extensions/test_l3.py +++ b/neutron/tests/unit/extensions/test_l3.py @@ -379,9 +379,9 @@ class L3NatTestCaseMixin(object): tenant_id=None, msg=None): interface_data = {} - if subnet_id: + if subnet_id is not None: interface_data.update({'subnet_id': subnet_id}) - if port_id: + if port_id is not None: interface_data.update({'port_id': port_id}) req = self.new_action_request('routers', interface_data, router_id, @@ -960,6 +960,20 @@ class L3NatTestCaseBase(L3NatTestCaseMixin): # nsx metadata access case self.assertIn(payload['tenant_id'], [stid, ''], msg) + def test_router_add_interface_bad_values(self): + with self.router() as r: + exp_code = exc.HTTPBadRequest.code + self._router_interface_action('add', + r['router']['id'], + False, + None, + expected_code=exp_code) + self._router_interface_action('add', + r['router']['id'], + None, + False, + expected_code=exp_code) + def test_router_add_interface_subnet(self): fake_notifier.reset() with self.router() as r: