Support bypass-firewall param for router NAT rules

Adding nat_pass parameter to router NAT rules creation.
The backend default value for this parameter is True, meaning the
firewall rules will be bypassed.
So this is also the default of the api, for backwards compatibility.

This parameter is acceptable only since nsx v2, so the api needs the
ability to check the supported features before creating the request body.
For that use, the core_resources will now get the nsxlib object at init.

Change-Id: I7c9dfe13a146a47b180fc3df2d4d6174f252e0a3
This commit is contained in:
Adit Sarfaty 2017-06-11 09:37:29 +03:00
parent cb233c65ad
commit 8e30d17b58
6 changed files with 75 additions and 21 deletions

View File

@ -324,7 +324,8 @@ class NsxClientTestCase(NsxLibTestCase):
mocked = resource_class(nsx_client.NSX3Client(
self.mock_nsx_clustered_api(session_response=session_response),
nsx_api_managers=[NSX_MANAGER],
max_attempts=NSX_MAX_ATTEMPTS))
max_attempts=NSX_MAX_ATTEMPTS),
nsxlib=self.nsxlib)
if mock_validate:
mock.patch.object(mocked.client, '_validate_result').start()

View File

@ -489,6 +489,44 @@ class LogicalRouterTestCase(nsxlib_testcase.NsxClientTestCase):
test_constants.FAKE_ROUTER_UUID, router_body=fake_router)
self.assertEqual(test_constants.FAKE_ROUTER_FW_SEC_UUID, section_id)
def _test_nat_rule_create(self, nsx_version, add_bypas_arg):
router = self._mocked_lrouter()
action = 'SNAT'
translated_net = '1.1.1.1'
priority = 10
data = {
'action': action,
'enabled': True,
'translated_network': translated_net,
'rule_priority': priority
}
if add_bypas_arg:
# Expect nat_pass to be sent to the backend
data['nat_pass'] = False
# Ignoring 'bypass_firewall' with version 1.1
with mock.patch("vmware_nsxlib.v3.NsxLib.get_version",
return_value=nsx_version):
router.add_nat_rule(test_constants.FAKE_ROUTER_UUID,
action=action,
translated_network=translated_net,
rule_priority=priority,
bypass_firewall=False)
test_client.assert_json_call(
'post', router,
('https://1.2.3.4/api/v1/logical-routers/%s/nat/rules' %
test_constants.FAKE_ROUTER_UUID),
data=jsonutils.dumps(data, sort_keys=True))
def test_nat_rule_create_v1(self):
# Ignoring 'bypass_firewall' with version 1.1
self._test_nat_rule_create('1.1.0', False)
def test_nat_rule_create_v2(self):
# Sending 'bypass_firewall' with version 1.1
self._test_nat_rule_create('2.0.0', True)
class LogicalRouterPortTestCase(nsxlib_testcase.NsxClientTestCase):

View File

@ -137,27 +137,27 @@ class NsxLib(NsxLibBase):
def init_api(self):
self.port_mirror = core_resources.NsxLibPortMirror(
self.client, self.nsxlib_config)
self.client, self.nsxlib_config, nsxlib=self)
self.bridge_endpoint = core_resources.NsxLibBridgeEndpoint(
self.client, self.nsxlib_config)
self.client, self.nsxlib_config, nsxlib=self)
self.logical_switch = core_resources.NsxLibLogicalSwitch(
self.client, self.nsxlib_config)
self.client, self.nsxlib_config, nsxlib=self)
self.logical_router = core_resources.NsxLibLogicalRouter(
self.client, self.nsxlib_config)
self.client, self.nsxlib_config, nsxlib=self)
self.switching_profile = core_resources.NsxLibSwitchingProfile(
self.client, self.nsxlib_config)
self.client, self.nsxlib_config, nsxlib=self)
self.qos_switching_profile = core_resources.NsxLibQosSwitchingProfile(
self.client, self.nsxlib_config)
self.client, self.nsxlib_config, nsxlib=self)
self.edge_cluster = core_resources.NsxLibEdgeCluster(
self.client, self.nsxlib_config)
self.client, self.nsxlib_config, nsxlib=self)
self.bridge_cluster = core_resources.NsxLibBridgeCluster(
self.client, self.nsxlib_config)
self.client, self.nsxlib_config, nsxlib=self)
self.transport_zone = core_resources.NsxLibTransportZone(
self.client, self.nsxlib_config)
self.client, self.nsxlib_config, nsxlib=self)
self.native_dhcp_profile = core_resources.NsxLibDhcpProfile(
self.client, self.nsxlib_config)
self.client, self.nsxlib_config, nsxlib=self)
self.native_md_proxy = core_resources.NsxLibMetadataProxy(
self.client, self.nsxlib_config)
self.client, self.nsxlib_config, nsxlib=self)
self.firewall_section = security.NsxLibFirewallSection(
self.client, self.nsxlib_config)
self.ns_group = security.NsxLibNsGroup(
@ -165,9 +165,9 @@ class NsxLib(NsxLibBase):
self.native_dhcp = native_dhcp.NsxLibNativeDhcp(
self.client, self.nsxlib_config)
self.ip_block_subnet = core_resources.NsxLibIpBlockSubnet(
self.client, self.nsxlib_config)
self.client, self.nsxlib_config, nsxlib=self)
self.ip_block = core_resources.NsxLibIpBlock(
self.client, self.nsxlib_config)
self.client, self.nsxlib_config, nsxlib=self)
self.ip_set = security.NsxLibIPSet(
self.client, self.nsxlib_config)
self.logical_port = resources.LogicalPort(

View File

@ -418,7 +418,8 @@ class NsxLibLogicalRouter(utils.NsxLibApiBase):
source_net=None, dest_net=None,
enabled=True, rule_priority=None,
match_ports=None, match_protocol=None,
match_resource_type=None):
match_resource_type=None,
bypass_firewall=True):
resource = 'logical-routers/%s/nat/rules' % logical_router_id
body = {'action': action,
'enabled': enabled,
@ -435,6 +436,16 @@ class NsxLibLogicalRouter(utils.NsxLibApiBase):
nsx_constants.L4_PORT_SET_NSSERVICE),
'destination_ports': match_ports,
'l4_protocol': match_protocol or nsx_constants.TCP}
# nat_pass parameter is supported with the router firewall feature
if (self.nsxlib and
self.nsxlib.feature_supported(
nsx_constants.FEATURE_ROUTER_FIREWALL)):
body['nat_pass'] = bypass_firewall
elif not bypass_firewall:
LOG.error("Ignoring bypass_firewall for router %s nat rule: "
"this feature is not supported.", logical_router_id)
return self.client.create(resource, body)
def add_static_route(self, logical_router_id, dest_cidr, nexthop):

View File

@ -128,11 +128,12 @@ class RouterLib(object):
logical_router_id,
translated_network=gw_ip)
def add_gw_snat_rule(self, logical_router_id, gw_ip):
def add_gw_snat_rule(self, logical_router_id, gw_ip, bypass_firewall=True):
return self.nsxlib.logical_router.add_nat_rule(
logical_router_id, action="SNAT",
translated_network=gw_ip,
rule_priority=GW_NAT_PRI)
rule_priority=GW_NAT_PRI,
bypass_firewall=bypass_firewall)
def update_router_edge_cluster(self, nsx_router_id, edge_cluster_uuid):
return self._router_client.update(nsx_router_id,
@ -161,18 +162,20 @@ class RouterLib(object):
port['id'], subnets=address_groups)
def add_fip_nat_rules(self, logical_router_id, ext_ip, int_ip,
match_ports=None):
match_ports=None, bypass_firewall=True):
self.nsxlib.logical_router.add_nat_rule(
logical_router_id, action="SNAT",
translated_network=ext_ip,
source_net=int_ip,
rule_priority=FIP_NAT_PRI)
rule_priority=FIP_NAT_PRI,
bypass_firewall=bypass_firewall)
self.nsxlib.logical_router.add_nat_rule(
logical_router_id, action="DNAT",
translated_network=int_ip,
dest_net=ext_ip,
rule_priority=FIP_NAT_PRI,
match_ports=match_ports)
match_ports=match_ports,
bypass_firewall=bypass_firewall)
def delete_fip_nat_rules_by_internal_ip(self, logical_router_id, int_ip):
self.nsxlib.logical_router.delete_nat_rule_by_values(

View File

@ -136,9 +136,10 @@ def build_extra_args(body, extra_args, **kwargs):
class NsxLibApiBase(object):
"""Base class for nsxlib api """
def __init__(self, client, nsxlib_config=None):
def __init__(self, client, nsxlib_config=None, nsxlib=None):
self.client = client
self.nsxlib_config = nsxlib_config
self.nsxlib = nsxlib
super(NsxLibApiBase, self).__init__()
@abc.abstractproperty