Merge "Cover both enabled and disabled cases in nested snat validation test"
diff --git a/neutron_tempest_plugin/api/base_routers.py b/neutron_tempest_plugin/api/base_routers.py
index 94db116..37a84b8 100644
--- a/neutron_tempest_plugin/api/base_routers.py
+++ b/neutron_tempest_plugin/api/base_routers.py
@@ -31,10 +31,14 @@
pass
def _create_router(self, name, admin_state_up=False,
- external_network_id=None, enable_snat=None, **kwargs):
+ external_network_id=None, enable_snat=None,
+ client=None, **kwargs):
# associate a cleanup with created routers to avoid quota limits
- router = self.create_router(name, admin_state_up,
- external_network_id, enable_snat, **kwargs)
+ client = client or self.client
+ router = self._create_router_with_client(
+ client, router_name=name, admin_state_up=admin_state_up,
+ external_network_id=external_network_id, enable_snat=enable_snat,
+ **kwargs)
self.addCleanup(self._cleanup_router, router)
return router
diff --git a/neutron_tempest_plugin/api/test_routers.py b/neutron_tempest_plugin/api/test_routers.py
index 1430b81..1470a7b 100644
--- a/neutron_tempest_plugin/api/test_routers.py
+++ b/neutron_tempest_plugin/api/test_routers.py
@@ -377,7 +377,7 @@
router = self._create_router(data_utils.rand_name('router'))
self.assertEqual(len(router['external_gateways']), 0)
- res = self.client.router_add_external_gateways(
+ res = self.admin_client.router_add_external_gateways(
router['id'],
[{'network_id': CONF.network.public_network_id,
'enable_snat': False}])
@@ -391,7 +391,7 @@
router = self._create_router(data_utils.rand_name('router'))
self.assertEqual(len(router['external_gateways']), 0)
- res = self.client.router_add_external_gateways(
+ res = self.admin_client.router_add_external_gateways(
router['id'],
[
{'network_id': CONF.network.public_network_id,
@@ -424,9 +424,11 @@
router = self._create_router(
data_utils.rand_name('router'),
external_network_id=CONF.network.public_network_id,
- enable_snat=False)
+ enable_snat=False,
+ client=self.admin_client,
+ )
self.assertEqual(len(router['external_gateways']), 1)
- res = self.client.router_add_external_gateways(
+ res = self.admin_client.router_add_external_gateways(
router['id'],
[{'network_id': CONF.network.public_network_id,
'enable_snat': False}])
@@ -437,9 +439,10 @@
router = self._create_router(
data_utils.rand_name('router'),
external_network_id=CONF.network.public_network_id,
- enable_snat=False)
+ enable_snat=False,
+ client=self.admin_client)
self.assertEqual(len(router['external_gateways']), 1)
- res = self.client.router_remove_external_gateways(
+ res = self.admin_client.router_remove_external_gateways(
router['id'],
[{'network_id': CONF.network.public_network_id}])
self.assertEqual(len(res['router']['external_gateways']), 0)
@@ -449,7 +452,7 @@
router = self._create_router(data_utils.rand_name('router'))
self.assertEqual(len(router['external_gateways']), 0)
- res = self.client.router_add_external_gateways(
+ res = self.admin_client.router_add_external_gateways(
router['id'],
[
{'network_id': CONF.network.public_network_id,
@@ -480,7 +483,7 @@
router = self._create_router(data_utils.rand_name('router'))
self.assertEqual(len(router['external_gateways']), 0)
- res = self.client.router_add_external_gateways(
+ res = self.admin_client.router_add_external_gateways(
router['id'],
[
{'network_id': CONF.network.public_network_id,
@@ -503,7 +506,7 @@
remove_gateways[0])
external_gateways[1] = remove_gateways[0]
- res_update_gws = self.client.router_update_external_gateways(
+ res_update_gws = self.admin_client.router_update_external_gateways(
router['id'],
external_gateways)
diff --git a/neutron_tempest_plugin/common/ip.py b/neutron_tempest_plugin/common/ip.py
index 07bbe69..5335219 100644
--- a/neutron_tempest_plugin/common/ip.py
+++ b/neutron_tempest_plugin/common/ip.py
@@ -96,7 +96,7 @@
return self.configure_vlan(addresses, port, vlan_tag, subport_ips,
subport['mac_address'])
- def configure_vlan_transparent(self, port, vlan_tag, ip_addresses):
+ def configure_inner_vlan(self, port, vlan_tag, ip_addresses):
addresses = self.list_addresses()
try:
subport_device = get_vlan_device_name(addresses, ip_addresses)
@@ -108,6 +108,11 @@
return self.configure_vlan(addresses, port, vlan_tag, ip_addresses)
+ # NOTE(ralonsoh): some projects, like whitebox-neutron-tempest-plugin, are
+ # using ``configure_vlan_transparent`` method. The concept of "inner VLAN"
+ # does not exist in the VLAN transparency feature.
+ configure_vlan_transparent = configure_inner_vlan
+
def list_namespaces(self):
namespaces_output = self.execute("netns")
ns_list = []
diff --git a/neutron_tempest_plugin/scenario/test_multiple_gws.py b/neutron_tempest_plugin/scenario/test_multiple_gws.py
index 0a540f6..e4f1d3d 100644
--- a/neutron_tempest_plugin/scenario/test_multiple_gws.py
+++ b/neutron_tempest_plugin/scenario/test_multiple_gws.py
@@ -630,7 +630,8 @@
def test_update_router_single_gw_bfd(self):
ext_network_id = self.ext_networks[0][0]['id']
bfd_container = self.containers[0]
- router = self.create_router(
+ router = self._create_router_with_client(
+ self.admin_client,
router_name=data_utils.rand_name('router'),
admin_state_up=True,
enable_snat=False,
diff --git a/neutron_tempest_plugin/scenario/test_vlan_transparency.py b/neutron_tempest_plugin/scenario/test_vlan_transparency.py
index 11f12e9..85648bc 100644
--- a/neutron_tempest_plugin/scenario/test_vlan_transparency.py
+++ b/neutron_tempest_plugin/scenario/test_vlan_transparency.py
@@ -30,20 +30,27 @@
MAX_VLAN_ID = 4094
-class VlanTransparencyTest(base.BaseTempestTestCase):
- credentials = ['primary', 'admin']
- force_tenant_isolation = False
+class BaseVlanTest(base.BaseAdminTempestTestCase):
- required_extensions = ['vlan-transparent', 'allowed-address-pairs']
+ """Base class common for the tests for the "vlan_transparent" and "qinq".
+
+ This base class covers common things for the tests for networks with
+ enabled either `qinq` or `vlan_transparent` attributes. Those 2 attributes
+ are functionally the same even from the end user's point of view. The only
+ difference between them is ethtype used for the outer VLAN tag but this
+ can't really be tested in the neutron-tempest-plugin tests.
+ """
+
+ network_kwargs = {}
@classmethod
def resource_setup(cls):
- super(VlanTransparencyTest, cls).resource_setup()
+ super(BaseVlanTest, cls).resource_setup()
# setup basic topology for servers we can log into
cls.rand_name = data_utils.rand_name(
cls.__name__.rsplit('.', 1)[-1])
cls.network = cls.create_network(name=cls.rand_name,
- vlan_transparent=True)
+ **cls.network_kwargs)
cls.subnet = cls.create_subnet(network=cls.network,
name=cls.rand_name)
cls.router = cls.create_router_by_client()
@@ -63,7 +70,7 @@
@classmethod
def skip_checks(cls):
- super(VlanTransparencyTest, cls).skip_checks()
+ super().skip_checks()
if not (CONF.neutron_plugin_options.advanced_image_ref or
CONF.neutron_plugin_options.default_image_is_advanced):
raise cls.skipException(
@@ -89,12 +96,11 @@
networks=[{'port': self.vm_ports[-1]['id']}],
name=server_name)['server']
- def _configure_vlan_transparent(self, port, ssh_client,
- vlan_tag, vlan_ip):
+ def _configure_inner_vlan(self, port, ssh_client, vlan_tag, vlan_ip):
ip_command = ip.IPCommand(ssh_client=ssh_client)
addresses = ip_command.list_addresses(port=port)
port_iface = ip.get_port_device_name(addresses, port)
- subport_iface = ip_command.configure_vlan_transparent(
+ subport_iface = ip_command.configure_inner_vlan(
port=port, vlan_tag=vlan_tag, ip_addresses=[vlan_ip])
for address in ip_command.list_addresses(ip_addresses=vlan_ip):
@@ -113,8 +119,9 @@
username=username,
pkey=self.keypair['private_key'])
- def _test_basic_vlan_transparency_connectivity(
+ def _test_basic_inner_vlan_connectivity(
self, port_security=True, use_allowed_address_pairs=False):
+ self._ensure_ethtype()
vlan_tag = data_utils.rand_int_id(start=MIN_VLAN_ID, end=MAX_VLAN_ID)
vlan_ipmask_template = '192.168.%d.{ip_last_byte}/24' % (vlan_tag %
256)
@@ -139,10 +146,10 @@
self._create_ssh_client(floating_ip=floating_ips[i]))
self.check_connectivity(ssh_client=ssh_clients[i])
- self._configure_vlan_transparent(port=self.vm_ports[-1],
- ssh_client=ssh_clients[i],
- vlan_tag=vlan_tag,
- vlan_ip=vlan_ipmasks[i])
+ self._configure_inner_vlan(port=self.vm_ports[-1],
+ ssh_client=ssh_clients[i],
+ vlan_tag=vlan_tag,
+ vlan_ip=vlan_ipmasks[i])
if port_security:
# Ping from vm0 to vm1 via VLAN interface should fail because
@@ -173,12 +180,63 @@
self.vm_ports[-2]['fixed_ips'][0]['ip_address'],
servers=vms)
+
+class VlanTransparencyTest(BaseVlanTest):
+ credentials = ['primary', 'admin']
+ force_tenant_isolation = False
+
+ required_extensions = ['vlan-transparent', 'allowed-address-pairs']
+
+ network_kwargs = {'vlan_transparent': True}
+
+ def _ensure_ethtype(self):
+ self.assertTrue(self.network.get('vlan_transparent'))
+ self.assertFalse(self.network.get('qinq'))
+
@decorators.idempotent_id('a2694e3a-6d4d-4a23-9fcc-c3ed3ef37b16')
def test_vlan_transparent_port_sec_disabled(self):
- self._test_basic_vlan_transparency_connectivity(
+ self._test_basic_inner_vlan_connectivity(
port_security=False, use_allowed_address_pairs=False)
@decorators.idempotent_id('2dd03b4f-9c20-4cda-8c6a-40fa453ec69a')
def test_vlan_transparent_allowed_address_pairs(self):
- self._test_basic_vlan_transparency_connectivity(
+ self._test_basic_inner_vlan_connectivity(
+ port_security=True, use_allowed_address_pairs=True)
+
+
+class VlanQinqTest(BaseVlanTest):
+ credentials = ['primary', 'admin']
+ force_tenant_isolation = False
+
+ required_extensions = ['qinq', 'allowed-address-pairs']
+
+ network_kwargs = {
+ 'qinq': True,
+ 'provider_network_type': 'vlan'}
+
+ @classmethod
+ def resource_setup(cls):
+ cls.network_kwargs['provider_physical_network'] = (
+ CONF.neutron_plugin_options.provider_vlans[0])
+ super().resource_setup()
+
+ @classmethod
+ def skip_checks(cls):
+ super().skip_checks()
+ if not CONF.neutron_plugin_options.provider_vlans:
+ raise cls.skipException(
+ 'Physical network is required to run these tests.')
+
+ def _ensure_ethtype(self):
+ self.assertFalse(self.network.get('vlan_transparent'))
+ self.assertTrue(self.network.get('qinq'))
+
+ @decorators.idempotent_id('ae78398e-9242-46b4-a5fc-227581821fca')
+ def test_vlan_transparent_port_sec_disabled(self):
+ self._test_basic_inner_vlan_connectivity(
+ port_security=False, use_allowed_address_pairs=False)
+
+ @decorators.idempotent_id('6ca983cd-b1c5-4e2c-949e-4be8ffa22a9c')
+ def test_vlan_transparent_allowed_address_pairs(self):
+ self._test_basic_inner_vlan_connectivity(
port_security=True, use_allowed_address_pairs=True)
diff --git a/zuul.d/master_jobs.yaml b/zuul.d/master_jobs.yaml
index b8d2103..b2c79a1 100644
--- a/zuul.d/master_jobs.yaml
+++ b/zuul.d/master_jobs.yaml
@@ -628,6 +628,7 @@
vars:
network_api_extensions_ovn:
- vlan-transparent
+ - qinq
- external-gateway-multihoming
devstack_localrc:
Q_AGENT: ovn
@@ -678,6 +679,7 @@
DEFAULT:
enable_dvr: false
vlan_transparent: true
+ vlan_qinq: true
/$NEUTRON_CORE_PLUGIN_CONF:
ml2:
type_drivers: local,flat,vlan,geneve
@@ -692,6 +694,7 @@
network-feature-enabled:
available_features: "{{ network_available_features | join(',') }}"
neutron_plugin_options:
+ provider_vlans: public,
available_type_drivers: local,flat,vlan,geneve
is_igmp_snooping_enabled: True
firewall_driver: ovn
@@ -1437,7 +1440,7 @@
- job:
name: neutron-tempest-plugin-vpnaas
parent: neutron-tempest-plugin-base
- timeout: 3900
+ timeout: 4500
required-projects:
- openstack/neutron
- openstack/neutron-vpnaas
@@ -1536,6 +1539,7 @@
devstack_localrc:
IPSEC_PACKAGE: strongswan
NETWORK_API_EXTENSIONS: "{{ (network_api_extensions_common + network_api_extensions_vpnaas) | join(',') }}"
+ Q_ML2_PLUGIN_MECHANISM_DRIVERS: ovn
devstack_services:
q-ovn-vpn-agent: true
devstack_local_conf:
diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml
index ee75bf4..1457981 100644
--- a/zuul.d/project.yaml
+++ b/zuul.d/project.yaml
@@ -3,7 +3,6 @@
check:
jobs:
- neutron-tempest-plugin-openvswitch
- - neutron-tempest-plugin-openvswitch-iptables_hybrid
- neutron-tempest-plugin-ovn
- neutron-tempest-plugin-designate-scenario:
# TODO(slaweq) make job voting again once bug
@@ -15,19 +14,19 @@
jobs:
- neutron-tempest-plugin-openvswitch
- neutron-tempest-plugin-ovn
- - neutron-tempest-plugin-openvswitch-iptables_hybrid
#TODO(slaweq): Move neutron-tempest-plugin-dvr-multinode-scenario out of
# the experimental queue when it will be more stable
experimental:
jobs:
- - neutron-tempest-plugin-linuxbridge
- neutron-tempest-plugin-dvr-multinode-scenario
- neutron-tempest-plugin-openvswitch-distributed-dhcp
- neutron-tempest-plugin-openvswitch-iptables_hybrid-distributed-dhcp
- neutron-tempest-plugin-ovn-enforce-scope-old-defaults
+ - neutron-tempest-plugin-openvswitch-iptables_hybrid
periodic:
jobs:
- neutron-tempest-plugin-ovn-enforce-scope-old-defaults
+ - neutron-tempest-plugin-openvswitch-iptables_hybrid
- project-template:
@@ -218,7 +217,14 @@
- neutron-tempest-plugin-bgpvpn-bagpipe-2023-2
- neutron-tempest-plugin-bgpvpn-bagpipe-2024-1
- neutron-tempest-plugin-bgpvpn-bagpipe-2024-2
- - neutron-tempest-plugin-dynamic-routing
+ - neutron-tempest-plugin-dynamic-routing:
+ # TODO(ralonsoh): this job is temporarily disabled; it will be
+ # restored once [1] is merged. This patch has been successfully
+ # tested in [2]. This job is removed from the gate queue,
+ # thus **remember to restore it in this queue too**.
+ # [1]https://review.opendev.org/c/openstack/neutron/+/941202
+ # [2]https://review.opendev.org/c/openstack/neutron-tempest-plugin/+/940906
+ voting: false
- neutron-tempest-plugin-dynamic-routing-2023-2
- neutron-tempest-plugin-dynamic-routing-2024-1
- neutron-tempest-plugin-dynamic-routing-2024-2
@@ -240,6 +246,5 @@
jobs:
- neutron-tempest-plugin-sfc
- neutron-tempest-plugin-bgpvpn-bagpipe
- - neutron-tempest-plugin-dynamic-routing
- neutron-tempest-plugin-fwaas
- neutron-tempest-plugin-vpnaas-ovn