Support different options for deleting NAT rules

Support different methods for deleting router nat rules
- delete a single rule with gw-ip
- delete a single rule with gw-ip and source ip
- delete all rules matching a gw-ip

Change-Id: Id43a2ced7d6526f538f485f345c20ba44673c7b2
This commit is contained in:
Adit Sarfaty 2017-06-28 15:07:16 +03:00
parent 3163126c45
commit af1d3cb1e5
3 changed files with 90 additions and 10 deletions

View File

@ -549,6 +549,47 @@ class LogicalRouterTestCase(nsxlib_testcase.NsxClientTestCase):
(test_constants.FAKE_ROUTER_UUID, rule_id)),
data=jsonutils.dumps(data, sort_keys=True))
def test_delete_nat_rule_by_gw(self):
router = self._mocked_lrouter()
rule_id = '123'
gw_ip = '3.3.3.3'
existing_rules = [{
'translated_network': gw_ip,
'logical_router_id': test_constants.FAKE_ROUTER_UUID,
'id': rule_id,
'action': 'SNAT',
'resource_type': 'NatRule'}]
with mock.patch.object(router.client, 'list',
return_value={'results': existing_rules}):
router.delete_nat_rule_by_values(test_constants.FAKE_ROUTER_UUID,
translated_network=gw_ip)
test_client.assert_json_call(
'delete', router,
('https://1.2.3.4/api/v1/logical-routers/%s/nat/rules/%s' %
(test_constants.FAKE_ROUTER_UUID, rule_id)))
def test_delete_nat_rule_by_gw_and_source(self):
router = self._mocked_lrouter()
rule_id = '123'
gw_ip = '3.3.3.3'
source_net = '4.4.4.4'
existing_rules = [{
'translated_network': gw_ip,
'logical_router_id': test_constants.FAKE_ROUTER_UUID,
'id': rule_id,
'match_source_network': source_net,
'action': 'SNAT',
'resource_type': 'NatRule'}]
with mock.patch.object(router.client, 'list',
return_value={'results': existing_rules}):
router.delete_nat_rule_by_values(test_constants.FAKE_ROUTER_UUID,
translated_network=gw_ip,
match_source_network=source_net)
test_client.assert_json_call(
'delete', router,
('https://1.2.3.4/api/v1/logical-routers/%s/nat/rules/%s' %
(test_constants.FAKE_ROUTER_UUID, rule_id)))
class LogicalRouterPortTestCase(nsxlib_testcase.NsxClientTestCase):

View File

@ -436,10 +436,19 @@ class NsxLibLogicalRouter(utils.NsxLibApiBase):
return 'logical-routers'
def _delete_resource_by_values(self, resource,
skip_not_found=True, **kwargs):
resources_get = self.client.get(resource)
skip_not_found=True,
strict_mode=True,
**kwargs):
"""Delete resource objects matching the values in kwargs
If skip_not_found is True - do not raise an exception if no object was
found.
If strict_mode is True - warnings will be issued if 0 or >1 objects
where deleted.
"""
resources_list = self.client.list(resource)
matched_num = 0
for res in resources_get['results']:
for res in resources_list['results']:
if utils.dict_match(kwargs, res):
LOG.debug("Deleting %s from resource %s", res, resource)
delete_resource = resource + "/" + str(res['id'])
@ -447,17 +456,18 @@ class NsxLibLogicalRouter(utils.NsxLibApiBase):
matched_num = matched_num + 1
if matched_num == 0:
if skip_not_found:
LOG.warning("No resource in %(res)s matched for values: "
"%(values)s", {'res': resource,
'values': kwargs})
if strict_mode:
LOG.warning("No resource in %(res)s matched for values: "
"%(values)s", {'res': resource,
'values': kwargs})
else:
err_msg = (_("No resource in %(res)s matched for values: "
"%(values)s") % {'res': resource,
'values': kwargs})
raise exceptions.ResourceNotFound(
manager=self.cluster.nsx_api_managers,
manager=self.client.nsx_api_managers,
operation=err_msg)
elif matched_num > 1:
elif matched_num > 1 and strict_mode:
LOG.warning("%(num)s resources in %(res)s matched for values: "
"%(values)s", {'num': matched_num,
'res': resource,
@ -528,9 +538,16 @@ class NsxLibLogicalRouter(utils.NsxLibApiBase):
nat_rule_id)
self.client.delete(resource)
def delete_nat_rule_by_values(self, logical_router_id, **kwargs):
def delete_nat_rule_by_values(self, logical_router_id,
strict_mode=True,
skip_not_found=True,
**kwargs):
resource = 'logical-routers/%s/nat/rules' % logical_router_id
return self._delete_resource_by_values(resource, **kwargs)
return self._delete_resource_by_values(
resource,
skip_not_found=skip_not_found,
strict_mode=strict_mode,
**kwargs)
def list_nat_rules(self, logical_router_id):
resource = 'logical-routers/%s/nat/rules' % logical_router_id

View File

@ -124,10 +124,32 @@ class RouterLib(object):
enabled=enabled)
def delete_gw_snat_rule(self, logical_router_id, gw_ip):
"""Delete router snat rule matching the gw ip
assuming there is only one
"""
return self.nsxlib.logical_router.delete_nat_rule_by_values(
logical_router_id,
translated_network=gw_ip)
def delete_gw_snat_rule_by_source(self, logical_router_id, gw_ip,
source_net, skip_not_found=False):
"""Delete router snat rule matching the gw ip & source"""
return self.nsxlib.logical_router.delete_nat_rule_by_values(
logical_router_id,
translated_network=gw_ip,
match_source_network=source_net,
# Do not fail or warn if not found, unless asked for
skip_not_found=skip_not_found, strict_mode=(not skip_not_found))
def delete_gw_snat_rules(self, logical_router_id, gw_ip):
"""Delete all the snat rules on the router with a specific gw ip"""
return self.nsxlib.logical_router.delete_nat_rule_by_values(
logical_router_id,
translated_network=gw_ip,
# Do not fail or warn if not found
skip_not_found=True, strict_mode=False)
def add_gw_snat_rule(self, logical_router_id, gw_ip, source_net=None,
bypass_firewall=True):
return self.nsxlib.logical_router.add_nat_rule(