diff --git a/vmware_nsxlib/tests/unit/v3/nsxlib_testcase.py b/vmware_nsxlib/tests/unit/v3/nsxlib_testcase.py index fb89b806..69aafb3c 100644 --- a/vmware_nsxlib/tests/unit/v3/nsxlib_testcase.py +++ b/vmware_nsxlib/tests/unit/v3/nsxlib_testcase.py @@ -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() diff --git a/vmware_nsxlib/tests/unit/v3/test_resources.py b/vmware_nsxlib/tests/unit/v3/test_resources.py index d0cff624..27ab1276 100644 --- a/vmware_nsxlib/tests/unit/v3/test_resources.py +++ b/vmware_nsxlib/tests/unit/v3/test_resources.py @@ -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): diff --git a/vmware_nsxlib/v3/__init__.py b/vmware_nsxlib/v3/__init__.py index 5eed387c..f6562f33 100644 --- a/vmware_nsxlib/v3/__init__.py +++ b/vmware_nsxlib/v3/__init__.py @@ -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( diff --git a/vmware_nsxlib/v3/core_resources.py b/vmware_nsxlib/v3/core_resources.py index 0e251a12..232383e5 100644 --- a/vmware_nsxlib/v3/core_resources.py +++ b/vmware_nsxlib/v3/core_resources.py @@ -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): diff --git a/vmware_nsxlib/v3/router.py b/vmware_nsxlib/v3/router.py index 2076a466..a786f821 100644 --- a/vmware_nsxlib/v3/router.py +++ b/vmware_nsxlib/v3/router.py @@ -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( diff --git a/vmware_nsxlib/v3/utils.py b/vmware_nsxlib/v3/utils.py index 02bf5dc4..15373e88 100644 --- a/vmware_nsxlib/v3/utils.py +++ b/vmware_nsxlib/v3/utils.py @@ -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