Support NO_SNAT & NO_DNAT rules in NSX 2.2

Adding flag ro mark the support of new NAAT rules actions in version
2.2, and adding validation for this field on create & update.

Change-Id: I4d99193caac6940911cc071016359a1361428967
This commit is contained in:
Adit Sarfaty 2018-03-20 09:51:09 +02:00
parent f680a5acd2
commit 1cc6aefb62
4 changed files with 50 additions and 10 deletions

View File

@ -660,9 +660,9 @@ class LogicalRouterTestCase(BaseTestResource):
test_constants.FAKE_ROUTER_UUID, router_body=fake_router) test_constants.FAKE_ROUTER_UUID, router_body=fake_router)
self.assertEqual(test_constants.FAKE_ROUTER_FW_SEC_UUID, section_id) self.assertEqual(test_constants.FAKE_ROUTER_FW_SEC_UUID, section_id)
def _test_nat_rule_create(self, nsx_version, add_bypas_arg): def _test_nat_rule_create(self, nsx_version, add_bypas_arg=True,
action='SNAT', expect_failure=False):
router = self.get_mocked_resource() router = self.get_mocked_resource()
action = 'SNAT'
translated_net = '1.1.1.1' translated_net = '1.1.1.1'
priority = 10 priority = 10
@ -679,11 +679,18 @@ class LogicalRouterTestCase(BaseTestResource):
# Ignoring 'bypass_firewall' with version 1.1 # Ignoring 'bypass_firewall' with version 1.1
with mock.patch("vmware_nsxlib.v3.NsxLib.get_version", with mock.patch("vmware_nsxlib.v3.NsxLib.get_version",
return_value=nsx_version): return_value=nsx_version):
router.add_nat_rule(test_constants.FAKE_ROUTER_UUID, try:
action=action, router.add_nat_rule(test_constants.FAKE_ROUTER_UUID,
translated_network=translated_net, action=action,
rule_priority=priority, translated_network=translated_net,
bypass_firewall=False) rule_priority=priority,
bypass_firewall=False)
except exceptions.InvalidInput as e:
if expect_failure:
return
else:
self.fail("Failed to create NAT rule: %s", e)
test_client.assert_json_call( test_client.assert_json_call(
'post', router, 'post', router,
('https://1.2.3.4/api/v1/logical-routers/%s/nat/rules' % ('https://1.2.3.4/api/v1/logical-routers/%s/nat/rules' %
@ -693,11 +700,25 @@ class LogicalRouterTestCase(BaseTestResource):
def test_nat_rule_create_v1(self): def test_nat_rule_create_v1(self):
# Ignoring 'bypass_firewall' with version 1.1 # Ignoring 'bypass_firewall' with version 1.1
self._test_nat_rule_create('1.1.0', False) self._test_nat_rule_create('1.1.0', add_bypas_arg=False)
def test_nat_rule_create_v2(self): def test_nat_rule_create_v2(self):
# Sending 'bypass_firewall' with version 1.1 # Sending 'bypass_firewall' with version 1.1
self._test_nat_rule_create('2.0.0', True) self._test_nat_rule_create('2.0.0')
def test_nat_rule_create_v22_NO_DNAT(self):
# NO_DNAT is supported from 2.2 & up
self._test_nat_rule_create('2.2.0', action='NO_DNAT')
def test_nat_rule_create_v2_NO_DNAT(self):
# NO_DNAT is supported from 2.2 & up
self._test_nat_rule_create('2.0.0', action='NO_DNAT',
expect_failure=True)
def test_nat_rule_create_invalid(self):
# NO_DNAT is supported from 2.2 & up
self._test_nat_rule_create('2.0.0', action='INVALID',
expect_failure=True)
def test_nat_rule_list(self): def test_nat_rule_list(self):
router = self.get_mocked_resource() router = self.get_mocked_resource()

View File

@ -322,7 +322,8 @@ class NsxLib(NsxLibBase):
feature == nsx_constants.FEATURE_ON_BEHALF_OF or feature == nsx_constants.FEATURE_ON_BEHALF_OF or
feature == nsx_constants.FEATURE_RATE_LIMIT or feature == nsx_constants.FEATURE_RATE_LIMIT or
feature == nsx_constants.FEATURE_TRUNK_VLAN or feature == nsx_constants.FEATURE_TRUNK_VLAN or
feature == nsx_constants.FEATURE_ROUTER_TRANSPORT_ZONE): feature == nsx_constants.FEATURE_ROUTER_TRANSPORT_ZONE or
feature == nsx_constants.FEATURE_NO_DNAT_NO_SNAT):
return True return True
if (version.LooseVersion(self.get_version()) >= if (version.LooseVersion(self.get_version()) >=

View File

@ -512,6 +512,20 @@ class NsxLibLogicalRouter(utils.NsxLibApiBase):
'res': resource, 'res': resource,
'values': kwargs}) 'values': kwargs})
def _validate_nat_rule_action(self, action):
if not action:
return
if action in ['SNAT', 'DNAT', 'NO_NAT', 'REFLEXIVE']:
# legal values for all NSX versions
return
if (action not in ['NO_SNAT', 'NO_DNAT'] or (
self.nsxlib and not self.nsxlib.feature_supported(
nsx_constants.FEATURE_NO_DNAT_NO_SNAT))):
raise exceptions.InvalidInput(
operation="Create/Update NAT rule",
arg_val=action,
arg_name='action')
def add_nat_rule(self, logical_router_id, action, translated_network, def add_nat_rule(self, logical_router_id, action, translated_network,
source_net=None, dest_net=None, source_net=None, dest_net=None,
enabled=True, rule_priority=None, enabled=True, rule_priority=None,
@ -519,6 +533,7 @@ class NsxLibLogicalRouter(utils.NsxLibApiBase):
match_resource_type=None, match_resource_type=None,
bypass_firewall=True, bypass_firewall=True,
tags=None): tags=None):
self._validate_nat_rule_action(action)
resource = 'logical-routers/%s/nat/rules' % logical_router_id resource = 'logical-routers/%s/nat/rules' % logical_router_id
body = {'action': action, body = {'action': action,
'enabled': enabled, 'enabled': enabled,
@ -595,6 +610,8 @@ class NsxLibLogicalRouter(utils.NsxLibApiBase):
return self.client.list(resource) return self.client.list(resource)
def update_nat_rule(self, logical_router_id, nat_rule_id, **kwargs): def update_nat_rule(self, logical_router_id, nat_rule_id, **kwargs):
if 'action' in kwargs:
self._validate_nat_rule_action(kwargs['action'])
resource = 'logical-routers/%s/nat/rules/%s' % ( resource = 'logical-routers/%s/nat/rules/%s' % (
logical_router_id, nat_rule_id) logical_router_id, nat_rule_id)
return self._update_resource(resource, kwargs, retry=True) return self._update_resource(resource, kwargs, retry=True)

View File

@ -141,3 +141,4 @@ FEATURE_IPSEC_VPN = 'IPSec VPN'
FEATURE_ON_BEHALF_OF = 'On Behalf Of' FEATURE_ON_BEHALF_OF = 'On Behalf Of'
FEATURE_TRUNK_VLAN = 'Trunk Vlan' FEATURE_TRUNK_VLAN = 'Trunk Vlan'
FEATURE_ROUTER_TRANSPORT_ZONE = 'Router Transport Zone' FEATURE_ROUTER_TRANSPORT_ZONE = 'Router Transport Zone'
FEATURE_NO_DNAT_NO_SNAT = 'No DNAT/No SNAT'