From 8e30d17b58f226e49479c02cf38c53f8037eafbc Mon Sep 17 00:00:00 2001 From: Adit Sarfaty Date: Sun, 11 Jun 2017 09:37:29 +0300 Subject: [PATCH] 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 --- .../tests/unit/v3/nsxlib_testcase.py | 3 +- vmware_nsxlib/tests/unit/v3/test_resources.py | 38 +++++++++++++++++++ vmware_nsxlib/v3/__init__.py | 26 ++++++------- vmware_nsxlib/v3/core_resources.py | 13 ++++++- vmware_nsxlib/v3/router.py | 13 ++++--- vmware_nsxlib/v3/utils.py | 3 +- 6 files changed, 75 insertions(+), 21 deletions(-) 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