Implement nested snat validation test scenario
It's disabled for ovn because it's not, yet, implemented for the driver.
See: https://review.opendev.org/c/openstack/neutron/+/926495
(The feature also requires special configuration for the driver that we
probably won't enable in the gate. This can be discussed though.)
Related-Bug: #2051935
Change-Id: Ie2e49a53857009446e22300e2fff292355cef058
diff --git a/neutron_tempest_plugin/config.py b/neutron_tempest_plugin/config.py
index a6d5c09..d259201 100644
--- a/neutron_tempest_plugin/config.py
+++ b/neutron_tempest_plugin/config.py
@@ -77,6 +77,11 @@
default='openstackgate.local',
help='dns_domain value configured at neutron.conf, which will '
'be used for the DNS configuration of the instances'),
+ cfg.BoolOpt('snat_rules_apply_to_nested_networks',
+ default=False,
+ help='Whether SNAT rules apply recursively to all connected '
+ 'networks. This is the default behavior for ovs and '
+ 'linuxbridge drivers.'),
# Multicast tests settings
cfg.StrOpt('multicast_group_range',
diff --git a/neutron_tempest_plugin/scenario/test_floatingip.py b/neutron_tempest_plugin/scenario/test_floatingip.py
index f222396..24e5820 100644
--- a/neutron_tempest_plugin/scenario/test_floatingip.py
+++ b/neutron_tempest_plugin/scenario/test_floatingip.py
@@ -204,6 +204,60 @@
gateway_external_ip,
servers=[proxy, src_server])
+ @decorators.idempotent_id('b911b124-b6cb-449d-83d9-b34f3665741d')
+ @utils.requires_ext(extension='extraroute', service='network')
+ @testtools.skipUnless(
+ CONF.neutron_plugin_options.snat_rules_apply_to_nested_networks,
+ "Backend doesn't enable nested SNAT.")
+ def test_nested_snat_external_ip(self):
+ """Check connectivity to an external IP from a nested network."""
+ gateway_external_ip = self._get_external_gateway()
+
+ if not gateway_external_ip:
+ raise self.skipTest("IPv4 gateway is not configured for public "
+ "network or public_network_id is not "
+ "configured")
+ proxy = self._create_server()
+ proxy_client = ssh.Client(proxy['fip']['floating_ip_address'],
+ CONF.validation.image_ssh_user,
+ pkey=self.keypair['private_key'])
+
+ # Create a nested router
+ router = self.create_router(
+ router_name=data_utils.rand_name('router'),
+ admin_state_up=True)
+
+ # Attach outer subnet to it
+ outer_port = self.create_port(self.network)
+ self.client.add_router_interface_with_port_id(router['id'],
+ outer_port['id'])
+
+ # Attach a nested subnet to it
+ network = self.create_network()
+ subnet = self.create_subnet(network)
+ self.create_router_interface(router['id'], subnet['id'])
+
+ # Set up static routes in both directions
+ self.client.update_extra_routes(
+ self.router['id'],
+ outer_port['fixed_ips'][0]['ip_address'], subnet['cidr'])
+ self.client.update_extra_routes(
+ router['id'], self.subnet['gateway_ip'], '0.0.0.0/0')
+
+ # Create a server inside the nested network
+ src_server = self._create_server(create_floating_ip=False,
+ network=network)
+
+ # Validate that it can access external gw ip (via nested snat)
+ src_server_ip = src_server['port']['fixed_ips'][0]['ip_address']
+ ssh_client = ssh.Client(src_server_ip,
+ CONF.validation.image_ssh_user,
+ pkey=self.keypair['private_key'],
+ proxy_client=proxy_client)
+ self.check_remote_connectivity(ssh_client,
+ gateway_external_ip,
+ servers=[proxy, src_server])
+
class FloatingIPPortDetailsTest(FloatingIpTestCasesMixin,
base.BaseTempestTestCase):
diff --git a/zuul.d/master_jobs.yaml b/zuul.d/master_jobs.yaml
index 90379a1..3695565 100644
--- a/zuul.d/master_jobs.yaml
+++ b/zuul.d/master_jobs.yaml
@@ -194,6 +194,7 @@
image_is_advanced: true
available_type_drivers: flat,geneve,vlan,gre,local,vxlan
provider_net_base_segm_id: 1
+ snat_rules_apply_to_nested_networks: true
irrelevant-files:
- ^\.pylintrc$
- ^(test-|)requirements.txt$
@@ -285,6 +286,7 @@
neutron_plugin_options:
available_type_drivers: flat,vlan,local,vxlan
firewall_driver: openvswitch
+ snat_rules_apply_to_nested_networks: true
irrelevant-files:
- ^\.pylintrc$
- ^(test-|)requirements.txt$
@@ -400,6 +402,7 @@
neutron_plugin_options:
available_type_drivers: flat,vlan,local,vxlan
firewall_driver: iptables_hybrid
+ snat_rules_apply_to_nested_networks: true
irrelevant-files:
- ^\.pylintrc$
- ^(test-|)requirements.txt$
@@ -575,6 +578,7 @@
available_type_drivers: flat,vlan,local,vxlan
q_agent: linuxbridge
firewall_driver: iptables
+ snat_rules_apply_to_nested_networks: true
irrelevant-files:
- ^\.pylintrc$
- ^(test-|)requirements.txt$
@@ -715,6 +719,7 @@
available_type_drivers: local,flat,vlan,geneve
is_igmp_snooping_enabled: True
firewall_driver: ovn
+ snat_rules_apply_to_nested_networks: false
zuul_copy_output:
'{{ devstack_base_dir }}/data/ovs': 'logs'
'{{ devstack_base_dir }}/data/ovn': 'logs'
@@ -937,6 +942,7 @@
available_type_drivers: flat,geneve,vlan,gre,local,vxlan
l3_agent_mode: dvr_snat
firewall_driver: openvswitch
+ snat_rules_apply_to_nested_networks: true
group-vars:
subnode:
devstack_services: