diff -Nru networking-l2gw-11.0.0/AUTHORS networking-l2gw-12.0.1/AUTHORS --- networking-l2gw-11.0.0/AUTHORS 2017-09-19 05:57:23.000000000 +0000 +++ networking-l2gw-12.0.1/AUTHORS 2018-02-25 13:39:46.000000000 +0000 @@ -14,7 +14,9 @@ Chuck Carlino Daniel Mellado Dariusz Smigiel +Dong Jun Doug Hellmann +Emilien Macchi Gal Sagie Gary Kotton Hangdong Zhang @@ -27,6 +29,7 @@ Jeremy Stanley Koteswara Rao Kelam Kyle Mestery +Lajos Katona LiuYong Luigi Toscano Manjunath Patil @@ -41,12 +44,14 @@ Ricardo Noriega Roey Chen SDN Developer +Saverio Proto Selvakumar Selvakumar S Sukhdev Kapur YAMAMOTO Takashi YAMAMOTO Takashi ZhaoBo +Zuul armando-migliaccio ghanshyam ghanshyam diff -Nru networking-l2gw-11.0.0/ChangeLog networking-l2gw-12.0.1/ChangeLog --- networking-l2gw-11.0.0/ChangeLog 2017-09-19 05:57:23.000000000 +0000 +++ networking-l2gw-12.0.1/ChangeLog 2018-02-25 13:39:46.000000000 +0000 @@ -1,9 +1,37 @@ CHANGES ======= +12.0.1 +------ + +* Update UPPER\_CONSTRAINTS\_FILE for stable/queens +* Update .gitreview for stable/queens +* queens: disable tripleo jobs for now +* Updated from global requirements +* Updated from global requirements +* use callbacks from neutron-lib +* Remove bundled in-tree Tempest plugin +* Adding tempest job to verify gate +* Migrating tempest job to Zuulv3 +* Add UT cases for L2GW Update +* Enable L2GW Update with existing connections +* Replace the fixed path prefix with $TEMPEST\_DIR +* Tempest: update to follow code depcreation +* zuul: run TripleO jobs with new zuulv3 layout +* Updated from global requirements +* Updated from global requirements +* use FAULT\_MAP from neutron-lib +* Updated from global requirements +* Add Getting Started section to the README +* Replace deprecated self.is\_agent\_down +* Updated from global requirements +* 'l2gw' entrypoint for Neutron service\_plugins +* Updated from global requirements + 11.0.0 ------ +* Replace deprecated test.attr with decorators.attr * Update the documentation link for doc migration * Take allowed-address-pairs to ucast\_mac\_remote * Updated from global requirements diff -Nru networking-l2gw-11.0.0/contrib/install_and_config_l2gateway_plugin.sh networking-l2gw-12.0.1/contrib/install_and_config_l2gateway_plugin.sh --- networking-l2gw-11.0.0/contrib/install_and_config_l2gateway_plugin.sh 2017-09-19 05:52:35.000000000 +0000 +++ networking-l2gw-12.0.1/contrib/install_and_config_l2gateway_plugin.sh 2018-02-25 13:35:51.000000000 +0000 @@ -85,7 +85,7 @@ dpkg -i $pck_name\_$pck_ver\_$architecture.deb echo enter neutron.conf file path read neutron_conf -l2gw_plugin=", networking_l2gw.services.l2gateway.plugin.L2GatewayPlugin" +l2gw_plugin=", l2gw" while read line do if [[ $line == *"service_plugins"* ]] diff -Nru networking-l2gw-11.0.0/contrib/README_install_and_config_l2gateway_plugin.rst networking-l2gw-12.0.1/contrib/README_install_and_config_l2gateway_plugin.rst --- networking-l2gw-11.0.0/contrib/README_install_and_config_l2gateway_plugin.rst 2017-09-19 05:52:35.000000000 +0000 +++ networking-l2gw-12.0.1/contrib/README_install_and_config_l2gateway_plugin.rst 2018-02-25 13:35:51.000000000 +0000 @@ -55,4 +55,4 @@ neutron-server start/running, process 17876 and also check service_plugins in neutron.conf file whether -networking_l2gw.services.l2gateway.plugin.L2GatewayPlugin is enabled or not. +l2gw is enabled or not. diff -Nru networking-l2gw-11.0.0/debian/changelog networking-l2gw-12.0.1/debian/changelog --- networking-l2gw-11.0.0/debian/changelog 2017-12-08 17:52:30.000000000 +0000 +++ networking-l2gw-12.0.1/debian/changelog 2018-02-27 18:25:20.000000000 +0000 @@ -1,8 +1,30 @@ -networking-l2gw (1:11.0.0-0ubuntu3~cloud0) xenial-queens; urgency=medium +networking-l2gw (1:12.0.1-0ubuntu1~cloud0) xenial-queens; urgency=medium * New upstream release for the Ubuntu Cloud Archive. - -- Openstack Ubuntu Testing Bot Fri, 08 Dec 2017 17:52:30 +0000 + -- Openstack Ubuntu Testing Bot Tue, 27 Feb 2018 18:25:20 +0000 + +networking-l2gw (1:12.0.1-0ubuntu1) bionic; urgency=medium + + * New upstream release for OpenStack Queens. + + -- Corey Bryant Tue, 27 Feb 2018 11:45:52 -0500 + +networking-l2gw (1:12.0.0~git20180223.32631dc1-0ubuntu1) bionic; urgency=medium + + [ James Page ] + * New upstream snapshot. + * d/p/*: Drop, no longer needed. + + [ Corey Bryant ] + * New upstream version. + * d/*: wrap-and-sort -bast. + * d/control: Update Standards-Version to 4.1.2. + * d/control: Bump debhelper compat to 10. + * d/control: Align (Build-)Depends with upstream. + * d/rules: Restore OSLO_PACKAGE_VERSION that was changed on switch to stestr. + + -- Corey Bryant Fri, 23 Feb 2018 08:39:13 -0500 networking-l2gw (1:11.0.0-0ubuntu3) bionic; urgency=medium diff -Nru networking-l2gw-11.0.0/debian/compat networking-l2gw-12.0.1/debian/compat --- networking-l2gw-11.0.0/debian/compat 2017-12-07 23:03:13.000000000 +0000 +++ networking-l2gw-12.0.1/debian/compat 2018-02-27 16:45:52.000000000 +0000 @@ -1 +1 @@ -9 +10 diff -Nru networking-l2gw-11.0.0/debian/control networking-l2gw-12.0.1/debian/control --- networking-l2gw-11.0.0/debian/control 2017-12-07 23:03:13.000000000 +0000 +++ networking-l2gw-12.0.1/debian/control 2018-02-27 16:45:52.000000000 +0000 @@ -3,68 +3,77 @@ Priority: optional Maintainer: Ubuntu Developers XSBC-Original-Maintainer: PKG OpenStack -Uploaders: James Page , - Thomas Goirand , -Build-Depends: debhelper (>= 9~), - dh-python, - openstack-pkg-tools (>= 23~), - python-all, - python-setuptools, - python-sphinx (>= 1.5.1), -Build-Depends-Indep: python-babel (>= 2.3.4), - python-coverage (>= 3.6), - python-ddt (>= 1.0.1), - python-hacking (>= 0.9.2), - python-neutron (>= 1:7.0.0~), - python-neutron-lib (>= 1.9.0), - python-neutronclient (>= 1:6.3.0), - python-os-testr (>= 0.7.0), - python-oslosphinx (>= 2.5.0), - python-oslotest (>= 1:1.10.0), - python-ovsdbapp (>= 0.4.0), - python-pbr (>= 2.0.0), - python-subunit (>= 0.0.18), - python-stestr, - python-tempest (>= 1:16.1.0), - python-testresources (>= 0.2.4), - python-testscenarios (>= 0.4), - python-testtools (>= 1.4.0), - subunit (>= 0.0.18), - testrepository (>= 0.0.18), -Standards-Version: 3.9.6 +Uploaders: + James Page , + Thomas Goirand , +Build-Depends: + debhelper (>= 10~), + dh-python, + openstack-pkg-tools (>= 23~), + python-all, + python-setuptools, + python-sphinx (>= 1.6.2), +Build-Depends-Indep: + python-babel (>= 2.3.4), + python-coverage (>= 4.0), + python-ddt (>= 1.0.1), + python-hacking (>= 0.12.0), + python-mock (>= 2.0.0), + python-neutron (>= 1:7.0.0~), + python-neutron-lib (>= 1.13.0), + python-neutronclient (>= 1:6.3.0), + python-os-testr (>= 1.0.0), + python-oslosphinx (>= 4.7.0), + python-oslotest (>= 1:3.2.0), + python-ovsdbapp (>= 0.8.0), + python-pbr (>= 2.0.0), + python-psycopg2 (>= 2.6.2), + python-pymysql (>= 0.7.6), + python-stestr, + python-subunit (>= 1.0.0), + python-tempest (>= 1:16.1.0), + python-testrepository (>= 0.0.18), + python-testresources (>= 2.0.0), + python-testscenarios (>= 0.4), + python-testtools (>= 2.2.0), + subunit (>= 0.0.18), + testrepository (>= 0.0.18), +Standards-Version: 4.1.2 Homepage: http://neutron.openstack.org/ Vcs-Browser: https://anonscm.debian.org/gitweb/?p=openstack/networking-l2gw.git;a=summary Vcs-Git: https://anonscm.debian.org/git/openstack/networking-l2gw.git -Package: python-networking-l2gw +Package: neutron-l2gateway-agent Architecture: all Section: python -Depends: python-babel (>= 2.3.4), - python-neutron (>= 1:7.0.0~), - python-neutron-lib (>= 1.9.0), - python-neutronclient (>= 1:6.3.0), - python-ovsdbapp (>= 0.4.0), - python-pbr (>= 2.0.0), - ${misc:Depends}, - ${python:Depends}, -Description: OpenStack virtual network service - L2 gateway extension +Depends: + python-networking-l2gw (= ${binary:Version}), + ${misc:Depends}, + ${python:Depends}, +Description: OpenStack virtual network service - L2 gateway agent Neutron provides an API to dynamically request and configure virtual networks. These networks connect "interfaces" from other OpenStack services (such as vNICs from Nova VMs). The Neutron API supports extensions to provide advanced network capabilities, including QoS, ACLs, and network monitoring. . - This package provides the Python files for the Layer 2 gateway extension. + This package provides the Layer 2 gateway agent. -Package: neutron-l2gateway-agent +Package: python-networking-l2gw Architecture: all Section: python -Depends: python-networking-l2gw (= ${binary:Version}), - ${misc:Depends}, - ${python:Depends}, -Description: OpenStack virtual network service - L2 gateway agent +Depends: + python-babel (>= 2.3.4), + python-neutron (>= 1:7.0.0~), + python-neutron-lib (>= 1.13.0), + python-neutronclient (>= 1:6.3.0), + python-ovsdbapp (>= 0.8.0), + python-pbr (>= 2.0.0), + ${misc:Depends}, + ${python:Depends}, +Description: OpenStack virtual network service - L2 gateway extension Neutron provides an API to dynamically request and configure virtual networks. These networks connect "interfaces" from other OpenStack services (such as vNICs from Nova VMs). The Neutron API supports extensions to provide advanced network capabilities, including QoS, ACLs, and network monitoring. . - This package provides the Layer 2 gateway agent. + This package provides the Python files for the Layer 2 gateway extension. diff -Nru networking-l2gw-11.0.0/debian/patches/replace-deprecated-self.is_agent_down.patch networking-l2gw-12.0.1/debian/patches/replace-deprecated-self.is_agent_down.patch --- networking-l2gw-11.0.0/debian/patches/replace-deprecated-self.is_agent_down.patch 2017-12-07 23:03:13.000000000 +0000 +++ networking-l2gw-12.0.1/debian/patches/replace-deprecated-self.is_agent_down.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,62 +0,0 @@ -From 4b454b59d00e2083d83a848015939f9596bf835b Mon Sep 17 00:00:00 2001 -From: Lajos Katona -Date: Mon, 25 Sep 2017 13:22:08 +0200 -Subject: [PATCH] Replace deprecated self.is_agent_down - -Since Ocata neutron.db.agents_db.AgentDbMixin.is_agent_down is -deprecated and in Queenst is replaced with -neutron.agent.common.utils.is_agent_down, see: -https://review.openstack.org/504338 - -Change-Id: I6f797b8a1940579a62284b21dcad06d42cdd1c81 -Closes-Bug: 1719298 ---- - networking_l2gw/services/l2gateway/agent_scheduler.py | 3 ++- - networking_l2gw/tests/unit/services/l2gateway/test_agent_scheduler.py | 3 ++- - 2 files changed, 4 insertions(+), 2 deletions(-) - -diff --git a/networking_l2gw/services/l2gateway/agent_scheduler.py b/networking_l2gw/services/l2gateway/agent_scheduler.py -index d8f336e..1edc8d9 100644 ---- a/networking_l2gw/services/l2gateway/agent_scheduler.py -+++ b/networking_l2gw/services/l2gateway/agent_scheduler.py -@@ -20,6 +20,7 @@ from oslo_config import cfg - from oslo_log import log as logging - from oslo_service import loopingcall - -+from neutron.agent.common import utils - from neutron.db import agents_db - from neutron_lib import context as neutron_context - -@@ -128,7 +129,7 @@ class L2GatewayAgentScheduler(agents_db.AgentDbMixin): - # Monitor agent - agents_to_process = [] - for agent in all_agents: -- if not self.is_agent_down(agent['heartbeat_timestamp']): -+ if not utils.is_agent_down(agent['heartbeat_timestamp']): - agents_to_process.append(agent) - if agents_to_process: - self._select_agent_type(context, agents_to_process) -diff --git a/networking_l2gw/tests/unit/services/l2gateway/test_agent_scheduler.py b/networking_l2gw/tests/unit/services/l2gateway/test_agent_scheduler.py -index 6cf9dec..82d0665 100644 ---- a/networking_l2gw/tests/unit/services/l2gateway/test_agent_scheduler.py -+++ b/networking_l2gw/tests/unit/services/l2gateway/test_agent_scheduler.py -@@ -22,6 +22,7 @@ from oslo_config import cfg - from oslo_service import loopingcall - from oslo_utils import timeutils - -+from neutron.agent.common import utils - from neutron.common import topics - from neutron.db import agents_db - from neutron import manager -@@ -148,7 +149,7 @@ class TestAgentScheduler(base.BaseTestCase): - mock.patch.object( - self.plugin, 'get_agents', - return_value=fake_all_agent_list) as get_agent_list, \ -- mock.patch.object(self.agentsch, 'is_agent_down', -+ mock.patch.object(utils, 'is_agent_down', - return_value=False) as is_agt: - self.agentsch.monitor_agent_state() - self.assertTrue(get_agent_list.called) --- -2.14.1 - diff -Nru networking-l2gw-11.0.0/debian/patches/series networking-l2gw-12.0.1/debian/patches/series --- networking-l2gw-11.0.0/debian/patches/series 2017-12-07 23:03:13.000000000 +0000 +++ networking-l2gw-12.0.1/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -replace-deprecated-self.is_agent_down.patch diff -Nru networking-l2gw-11.0.0/debian/rules networking-l2gw-12.0.1/debian/rules --- networking-l2gw-11.0.0/debian/rules 2017-12-07 23:03:13.000000000 +0000 +++ networking-l2gw-12.0.1/debian/rules 2018-02-27 16:45:52.000000000 +0000 @@ -2,7 +2,7 @@ include /usr/share/openstack-pkg-tools/pkgos.make -export OSLO_PACKAGE_VERSION=$(VERSION) +export OSLO_PACKAGE_VERSION=$(shell echo '$(VERSION)' | cut -d '~' -f 1) %: dh $@ --buildsystem=python_distutils --with python2 diff -Nru networking-l2gw-11.0.0/devstack/plugin.sh networking-l2gw-12.0.1/devstack/plugin.sh --- networking-l2gw-11.0.0/devstack/plugin.sh 2017-09-19 05:52:34.000000000 +0000 +++ networking-l2gw-12.0.1/devstack/plugin.sh 2018-02-25 13:36:04.000000000 +0000 @@ -37,7 +37,7 @@ function configure_tempest_for_l2gw { if is_service_enabled tempest; then iniset $TEMPEST_CONFIG l2gw l2gw_switch "cell08-5930-01::FortyGigE1/0/1|100" - source /opt/stack/new/tempest/.tox/tempest/bin/activate + source $TEMPEST_DIR/.tox/tempest/bin/activate pip install -r $L2GW_DIR/test-requirements.txt deactivate fi diff -Nru networking-l2gw-11.0.0/devstack/settings networking-l2gw-12.0.1/devstack/settings --- networking-l2gw-11.0.0/devstack/settings 2017-09-19 05:52:35.000000000 +0000 +++ networking-l2gw-12.0.1/devstack/settings 2018-02-25 13:35:51.000000000 +0000 @@ -1,7 +1,7 @@ # Devstack settings L2GW_DIR=$DEST/networking-l2gw L2GW_AGENT_BINARY="$NEUTRON_BIN_DIR/neutron-l2gateway-agent" -L2GW_PLUGIN=${L2GW_PLUGIN:-"networking_l2gw.services.l2gateway.plugin.L2GatewayPlugin"} +L2GW_PLUGIN=${L2GW_PLUGIN:-"l2gw"} L2GW_CONF_FILE=/etc/neutron/l2gateway_agent.ini L2GW_PLUGIN_CONF_FILE=/etc/neutron/l2gw_plugin.ini #NETWORKING_L2GW_SERVICE_DRIVER=L2GW:OpenDaylight:networking_odl.l2gateway.driver.OpenDaylightL2gwDriver:default diff -Nru networking-l2gw-11.0.0/networking_l2gw/db/l2gateway/l2gateway_db.py networking-l2gw-12.0.1/networking_l2gw/db/l2gateway/l2gateway_db.py --- networking-l2gw-11.0.0/networking_l2gw/db/l2gateway/l2gateway_db.py 2017-09-19 05:52:34.000000000 +0000 +++ networking-l2gw-12.0.1/networking_l2gw/db/l2gateway/l2gateway_db.py 2018-02-25 13:35:51.000000000 +0000 @@ -13,10 +13,6 @@ # License for the specific language governing permissions and limitations # under the License. -from neutron.callbacks import events -from neutron.callbacks import registry -from neutron.callbacks import resources - from networking_l2gw.db.l2gateway import db_query from networking_l2gw.db.l2gateway import l2gateway_models as models from networking_l2gw.extensions import l2gateway @@ -26,6 +22,9 @@ from networking_l2gw.services.l2gateway.common import l2gw_validators from networking_l2gw.services.l2gateway import exceptions as l2gw_exc +from neutron_lib.callbacks import events +from neutron_lib.callbacks import registry +from neutron_lib.callbacks import resources from neutron_lib import exceptions from neutron_lib.plugins import directory from oslo_log import log as logging @@ -290,24 +289,24 @@ with context.session.begin(subtransactions=True): gw_db = self._get_l2_gateway(context, l2_gw_id) tenant_id = self._get_tenant_id_for_create(context, gw_db) - if self._retrieve_gateway_connections(context, - l2_gw_id, - nw_map): - raise l2gw_exc.L2GatewayConnectionExists(mapping=nw_map, - gateway_id=l2_gw_id) nw_map['tenant_id'] = tenant_id - connection_id = uuidutils.generate_uuid() - nw_map['id'] = connection_id if not segmentation_id: nw_map['segmentation_id'] = "0" - gw_db.network_connections.append( - models.L2GatewayConnection(**nw_map)) - gw_db = models.L2GatewayConnection(id=connection_id, - tenant_id=tenant_id, - network_id=network_id, - l2_gateway_id=l2_gw_id, - segmentation_id=segmentation_id) - return self._make_l2gw_connections_dict(gw_db) + conn_db = self._retrieve_gateway_connections(context, l2_gw_id, + nw_map) + if not conn_db: + connection_id = uuidutils.generate_uuid() + nw_map['id'] = connection_id + gw_db.network_connections.append( + models.L2GatewayConnection(**nw_map)) + gw_db = models.L2GatewayConnection( + id=connection_id, + tenant_id=tenant_id, + network_id=network_id, + l2_gateway_id=l2_gw_id, + segmentation_id=segmentation_id) + return self._make_l2gw_connections_dict(gw_db) + return self._make_l2gw_connections_dict(conn_db[0]) def get_l2_gateway_connections(self, context, filters=None, fields=None, @@ -495,21 +494,41 @@ gw = l2_gateway[self.gateway_resource] devices = None dev_db = None - l2gw_db = None if 'devices' in gw: devices = gw['devices'] + if not devices: + return with context.session.begin(subtransactions=True): - l2gw_db = self._get_l2_gateway(context, id) - if l2gw_db.network_connections: - raise l2gw_exc.L2GatewayInUse(gateway_id=id) + # Attemp to retrieve l2gw + gw_db = self._get_l2_gateway(context, id) if devices: for device in devices: dev_name = device['device_name'] - dev_db = (self._get_l2gw_devices_by_name_andl2gwid( - context, dev_name, id)) + dev_db = self._get_l2gw_devices_by_name_andl2gwid( + context, dev_name, id) if not dev_db: - raise l2gw_exc.L2GatewayDeviceNotFound(device_id="") + raise l2gw_exc.L2GatewayDeviceNotFound( + device_id=dev_name) self.validate_device_name(context, dev_name, id) + interface_list = device['interfaces'] + if not interface_list: + raise l2gw_exc.L2GatewayInterfaceRequired() + if constants.SEG_ID in interface_list[0]: + for interfaces in interface_list: + if constants.SEG_ID not in interfaces: + raise l2gw_exc.L2GatewaySegmentationRequired() + if constants.SEG_ID not in interface_list[0]: + for interfaces in interface_list[1:]: + if constants.SEG_ID in interfaces: + raise l2gw_exc.L2GatewaySegmentationRequired() + if gw_db.devices: + if gw_db.devices[0].interfaces[0]['segmentation_id']: + if constants.SEG_ID not in interface_list[0]: + raise l2gw_exc.L2GatewaySegmentationIDExists() + else: + if constants.SEG_ID in interface_list[0]: + raise l2gw_exc.\ + L2GatewaySegmentationIDNotExists() def validate_l2_gateway_connection_for_create(self, context, l2_gateway_connection): diff -Nru networking-l2gw-11.0.0/networking_l2gw/services/l2gateway/agent_scheduler.py networking-l2gw-12.0.1/networking_l2gw/services/l2gateway/agent_scheduler.py --- networking-l2gw-11.0.0/networking_l2gw/services/l2gateway/agent_scheduler.py 2017-09-19 05:52:34.000000000 +0000 +++ networking-l2gw-12.0.1/networking_l2gw/services/l2gateway/agent_scheduler.py 2018-02-25 13:35:51.000000000 +0000 @@ -20,6 +20,7 @@ from oslo_log import log as logging from oslo_service import loopingcall +from neutron.agent.common import utils from neutron.db import agents_db from neutron_lib import context as neutron_context @@ -128,7 +129,7 @@ # Monitor agent agents_to_process = [] for agent in all_agents: - if not self.is_agent_down(agent['heartbeat_timestamp']): + if not utils.is_agent_down(agent['heartbeat_timestamp']): agents_to_process.append(agent) if agents_to_process: self._select_agent_type(context, agents_to_process) diff -Nru networking-l2gw-11.0.0/networking_l2gw/services/l2gateway/exceptions.py networking-l2gw-12.0.1/networking_l2gw/services/l2gateway/exceptions.py --- networking-l2gw-11.0.0/networking_l2gw/services/l2gateway/exceptions.py 2017-09-19 05:52:34.000000000 +0000 +++ networking-l2gw-12.0.1/networking_l2gw/services/l2gateway/exceptions.py 2018-02-25 13:35:51.000000000 +0000 @@ -13,8 +13,7 @@ # License for the specific language governing permissions and limitations # under the License. -from neutron.api.v2 import base - +from neutron_lib.api import faults from neutron_lib import exceptions from webob import exc as web_exc @@ -66,6 +65,11 @@ message = _("L2 Gateway interface '%(interface_id)s' not found.") +class L2GatewayPhysicalPortNotFound(exceptions.NeutronException): + message = _("Physical Port '%(int_name)s' in Physical switch " + "'%(device_name)s' could not be found") + + class L2GatewayPhysicalPortFaultStatus(exceptions.NeutronException): message = _("Physical Port '%(int_name)s' in Physical switch " "'%(device_name)s' port_fault_status is '%(fault_status)s'") @@ -99,9 +103,14 @@ message = _("L2 Gateway Interface required") -class L2GatewaySegmentationIDExists(exceptions.InUse): +class L2GatewaySegmentationIDExists(exceptions.NeutronException): message = _("The segmentation id is already specified in " - "gateway interface '%(interface_id)s'.") + "existing gateway interfaces.") + + +class L2GatewaySegmentationIDNotExists(exceptions.NeutronException): + message = _("The segmentation id is not specified in " + "existing gateway interfaces.") class L2GatewaySegmentationRequired(exceptions.NeutronException): @@ -126,17 +135,18 @@ message = _("invalid method '%(op_method)s'") -base.FAULT_MAP.update({L2GatewayInUse: web_exc.HTTPConflict, - L2GatewayPortInUse: web_exc.HTTPConflict, - L2GatewayConnectionExists: web_exc.HTTPConflict, - L2GatewayConnectionNotFound: web_exc.HTTPNotFound, - MultipleVxlanSegmentsFound: web_exc.HTTPConflict, - VxlanSegmentationIDNotFound: web_exc.HTTPNotFound, - L2GatewaySegmentationRequired: web_exc.HTTPConflict, - L2MultipleGatewayConnections: web_exc.HTTPConflict, - L2GatewayDuplicateSegmentationID: web_exc.HTTPConflict, - L2AgentNotFoundByHost: web_exc.HTTPNotFound, - OVSDBError: web_exc.HTTPConflict}) +faults.FAULT_MAP.update({L2GatewayInUse: web_exc.HTTPConflict, + L2GatewayPortInUse: web_exc.HTTPConflict, + L2GatewayConnectionExists: web_exc.HTTPConflict, + L2GatewayConnectionNotFound: web_exc.HTTPNotFound, + MultipleVxlanSegmentsFound: web_exc.HTTPConflict, + VxlanSegmentationIDNotFound: web_exc.HTTPNotFound, + L2GatewaySegmentationRequired: web_exc.HTTPConflict, + L2MultipleGatewayConnections: web_exc.HTTPConflict, + L2GatewayDuplicateSegmentationID: + web_exc.HTTPConflict, + L2AgentNotFoundByHost: web_exc.HTTPNotFound, + OVSDBError: web_exc.HTTPConflict}) class L3DvrAgentNotFound(exceptions.NotFound): diff -Nru networking-l2gw-11.0.0/networking_l2gw/services/l2gateway/service_drivers/rpc_l2gw.py networking-l2gw-12.0.1/networking_l2gw/services/l2gateway/service_drivers/rpc_l2gw.py --- networking-l2gw-11.0.0/networking_l2gw/services/l2gateway/service_drivers/rpc_l2gw.py 2017-09-19 05:52:34.000000000 +0000 +++ networking-l2gw-12.0.1/networking_l2gw/services/l2gateway/service_drivers/rpc_l2gw.py 2018-02-25 13:35:51.000000000 +0000 @@ -70,6 +70,7 @@ self.gateway_resource = constants.GATEWAY_RESOURCE_NAME self.l2gateway_db = l2_gw_db.L2GatewayMixin() self.type_manager = managers.TypeManager() + self.port_dict_before_update = [] @property def service_type(self): @@ -347,6 +348,32 @@ int_name=int_name, device_name=device_name, fault_status=port_status) + def _validate_gateway_for_update(self, context, gw): + LOG.debug("L2gwRpcDriver._validate_gateway_for_update gw=%s", + gw) + devices = gw.get('l2_gateway').get('devices') + + for device in devices: + interfaces = device.get('interfaces') + device_name = device.get("device_name") + for interface in interfaces: + interface_name = interface.get('name') + physical_switch = db.get_physical_switch_by_name( + context, device.get('device_name')) + if not physical_switch: + raise l2gw_exc.L2GatewayDeviceNotFound( + device_id=device_name) + ovsdb_identifier = physical_switch.get('ovsdb_identifier') + pp_dict = {'interface_name': interface_name, + 'ovsdb_identifier': ovsdb_identifier, + 'physical_switch_id': physical_switch.get('uuid')} + + ps_port = db.get_physical_port_by_name_and_ps(context, pp_dict) + if not ps_port: + raise l2gw_exc.L2GatewayPhysicalPortNotFound( + int_name=interface_name, + device_name=device_name) + def _validate_connection(self, context, gw_connection): seg_id = gw_connection.get('segmentation_id', None) l2_gw_id = gw_connection.get('l2_gateway_id') @@ -388,8 +415,12 @@ seg_id = gw_connection.get('segmentation_id', None) interfaces = self.service_plugin.get_l2gateway_interfaces_by_device_id( context, device['id']) + LOG.debug("L2gwRpcDriver._process_port_list: ints=%s", + interfaces) for interface in interfaces: interface_name = interface.get('interface_name') + LOG.debug("L2gwRpcDriver._process_port_list: int_name=%s", + interface_name) physical_switch = db.get_physical_switch_by_name( context, device.get('device_name')) if not physical_switch: @@ -417,6 +448,8 @@ raise Exception(msg) pp_dict['uuid'] = ps_port.get('uuid') pp_dict['name'] = ps_port.get('name') + LOG.debug("L2gwRpcDriver._process_port_list: pp_dict.name=%s", + pp_dict['name']) port_dict = self._generate_port_list( context, method, seg_id, interface, pp_dict, logical_switch_uuid, gw_connection) @@ -606,11 +639,115 @@ pass def update_l2_gateway(self, context, l2_gateway_id, l2_gateway): - """Update l2 gateway.""" - pass + """Check the port list for update""" + self.service_plugin._admin_check(context, 'UPDATE') + self._validate_gateway_for_update(context, l2_gateway) + self.port_dict_before_update = [] + # get l2 gateway devices + l2gateway_devices = ( + self.service_plugin.get_l2gateway_devices_by_gateway_id( + context, l2_gateway_id)) + # get l2 gateway connections + gw_connections = self.service_plugin._get_l2_gateway_connections( + context) + + for gw_connection in gw_connections: + for device in l2gateway_devices: + ovsdb_identifier, logical_switch, port_dict \ + = (self._process_port_list(context, device, + gw_connection, "UPDATE")) + self.port_dict_before_update.extend(port_dict) def update_l2_gateway_postcommit(self, context, l2_gateway): - pass + """Process the call from the CLI and trigger the RPC, + + to update the connection of the gateway. + """ + self.service_plugin._admin_check(context, 'UPDATE') + + # get l2 gateway devices + l2gateway_devices = ( + self.service_plugin.get_l2gateway_devices_by_gateway_id( + context, l2_gateway['id'])) + # get l2 gateway connections + gw_connections = self.service_plugin._get_l2_gateway_connections( + context) + + for gw_connection in gw_connections: + u_mac_dict = {} + mac_dict = {} + for device in l2gateway_devices: + locator_list = [] + ovsdb_identifier, logical_switch, port_dict = ( + self._process_port_list(context, device, + gw_connection, "UPDATE")) + ls_dict = self._get_logical_switch_dict( + context, logical_switch, gw_connection) + port_dict_before_update_con = \ + [port for port in self.port_dict_before_update + if port['vlan_bindings'][0]['logical_switch_uuid'] == + logical_switch['uuid']] + port_dict_add = \ + [port for port in port_dict + if port not in port_dict_before_update_con] + port_dict_delete = \ + [port for port in port_dict_before_update_con + if port not in port_dict] + if port_dict_add: + ports = self._get_port_details( + context, gw_connection.get('network_id')) + LOG.debug("L2gwRpcDriver.update_l2_gw: ports=%s", ports) + for port in ports: + mac_list = [] + if port['device_owner']: + dst_ip, ip_address = self._get_ip_details(context, + port) + mac_ip_pairs = [] + if isinstance( + port.get("allowed_address_pairs"), list): + for address_pair in \ + port['allowed_address_pairs']: + mac = address_pair['mac_address'] + mac_ip_pairs.append( + (mac, address_pair['ip_address'])) + mac_ip_pairs.append((port.get('mac_address'), + ip_address)) + + for mac, ip in mac_ip_pairs: + mac_remote = self._get_dict( + ovsdb_schema.UcastMacsRemote( + uuid=None, + mac=mac, + logical_switch_id=None, + physical_locator_id=None, + ip_address=ip)) + if logical_switch: + u_mac_dict['mac'] = mac + u_mac_dict['ovsdb_identifier'] = \ + ovsdb_identifier + u_mac_dict['logical_switch_uuid'] = ( + logical_switch.get('uuid')) + ucast_mac_remote = ( + db.get_ucast_mac_remote_by_mac_and_ls( + context, u_mac_dict)) + if not ucast_mac_remote: + mac_list.append(mac_remote) + else: + mac_list.append(mac_remote) + locator_list = self._get_locator_list( + context, dst_ip, ovsdb_identifier, mac_list, + locator_list) + for locator in locator_list: + mac_dict[locator.get('dst_ip')] = locator.pop('macs') + locator.pop('ovsdb_identifier') + self.agent_rpc.update_connection_to_gateway( + context, ovsdb_identifier, ls_dict, locator_list, + mac_dict, port_dict_add, 'CREATE') + + if port_dict_delete: + self.agent_rpc.update_connection_to_gateway( + context, ovsdb_identifier, ls_dict, locator_list, + mac_dict, port_dict_delete, 'DELETE') def delete_l2_gateway(self, context, id): """delete the l2 gateway by id.""" diff -Nru networking-l2gw-11.0.0/networking_l2gw/tests/api/base_l2gw.py networking-l2gw-12.0.1/networking_l2gw/tests/api/base_l2gw.py --- networking-l2gw-11.0.0/networking_l2gw/tests/api/base_l2gw.py 2017-09-19 05:52:34.000000000 +0000 +++ networking-l2gw-12.0.1/networking_l2gw/tests/api/base_l2gw.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,88 +0,0 @@ -# Copyright 2015 Hewlett-Packard Development Company, L.P. -# Copyright 2015 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -SEGMENTATION_ID_DELIMITER = "#" -INTERFACE_SEG_ID_DELIMITER = "|" -DEVICE_INTERFACE_DELIMITER = "::" -DEVICE_DELIMITER = "," -INTERFACE_DELIMITER = ";" -""" - Sample for providing input for gateway creation in config is noted below - Options provide flexibility to user to create l2gateway - For single device ,single interface with single vlan - l2gw_switch = device_name1::int_name1|vlan1 - For single device multiple interfaces with single or multiple vlans - l2gw_switch = device_name1::int_name1|vlan1#vlan2;int_name2|vlan3 - For multiple devices with mutiple interfaces having single or mutiple vlan - l2gw_switch = device_name1::int_name1|vlan1,device_name2::int_name2|vlan2 -""" - - -def get_interface(interfaces): - interface_dict = [] - for interface in interfaces: - if INTERFACE_SEG_ID_DELIMITER in interface: - int_name = interface.split(INTERFACE_SEG_ID_DELIMITER)[0] - segid = interface.split(INTERFACE_SEG_ID_DELIMITER)[1] - if SEGMENTATION_ID_DELIMITER in segid: - segid = segid.split(SEGMENTATION_ID_DELIMITER) - else: - segid = [segid] - interface_detail = {'name': int_name, 'segmentation_id': segid} - else: - interface_detail = {'name': interface} - interface_dict.append(interface_detail) - return interface_dict - - -def get_l2gw_body(l2gw_conf): - device_dict = [] - devices = l2gw_conf.split(DEVICE_DELIMITER) - for device in devices: - if DEVICE_INTERFACE_DELIMITER in device: - device_name = device.split(DEVICE_INTERFACE_DELIMITER)[0] - interface = device.split(DEVICE_INTERFACE_DELIMITER)[1] - if INTERFACE_DELIMITER in interface: - interface_dict = interface.split(INTERFACE_DELIMITER) - interfaces = get_interface(interface_dict) - else: - interfaces = get_interface([interface]) - device = {'device_name': device_name, - 'interfaces': interfaces} - device_dict.append(device) - body = {'devices': device_dict} - return body - - -def form_dict_devices(devices): - seg_ids = [] - devices1 = dict() - int_seg = [] - for device in devices: - device_name = device['device_name'] - interfaces = device['interfaces'] - for interface in interfaces: - interface_name = interface['name'] - int_seg.append(interface_name) - seg_id = interface['segmentation_id'] - if type(seg_id) is list: - for segid in seg_id: - seg_ids.append(segid) - else: - seg_ids.append(seg_id) - int_seg.append(seg_id) - devices1.setdefault(device_name, []).append(int_seg) - int_seg = [] - return devices1 diff -Nru networking-l2gw-11.0.0/networking_l2gw/tests/api/test_l2gw_extensions.py networking-l2gw-12.0.1/networking_l2gw/tests/api/test_l2gw_extensions.py --- networking-l2gw-11.0.0/networking_l2gw/tests/api/test_l2gw_extensions.py 2017-09-19 05:52:34.000000000 +0000 +++ networking-l2gw-12.0.1/networking_l2gw/tests/api/test_l2gw_extensions.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,215 +0,0 @@ -# Copyright 2015 Hewlett-Packard Development Company, L.P. -# Copyright 2015 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import random - -from neutron.tests.tempest.api import base -from tempest import config -from tempest.lib.common.utils import data_utils -from tempest.lib import decorators -from tempest import test - -from networking_l2gw.tests.api import base_l2gw - -CONF = config.CONF - - -class L2GatewayExtensionTestJSON(base.BaseAdminNetworkTest): - _interface = 'json' - - """ - Tests the following operations in the Neutron API using the REST client for - Neutron: - Create l2gateway - List l2gateways - Show l2gateway - Update l2gateway - Delete l2gateway - Create l2gatewayconnection - List l2gatewayconnections - Show l2gatewayconnection - Delete l2gatewayconnection - """ - - @classmethod - def resource_setup(cls): - super(L2GatewayExtensionTestJSON, cls).resource_setup() - # At least one switch detail should be provided to run the tests - if (len(CONF.l2gw.l2gw_switch) <= 0): - msg = ('At least one switch detail must be defined.') - raise cls.skipException(msg) - if not test.is_extension_enabled('l2-gateway', 'network'): - msg = "L2Gateway Extension not enabled." - raise cls.skipException(msg) - - @decorators.idempotent_id('3ca07946-a3c9-49ac-b058-8be54abecf1f') - def test_create_show_list_update_delete_l2gateway(self): - # Create an L2Gateway - gw_name = data_utils.rand_name('l2gw') - devices = base_l2gw.get_l2gw_body(CONF.l2gw.l2gw_switch)["devices"] - body = self.admin_client.create_l2_gateway( - name=gw_name, devices=devices) - l2_gateway = body['l2_gateway'] - self.addCleanup(self.admin_client.delete_l2_gateway, l2_gateway['id']) - # Show details of L2Gateway - show_body = self.admin_client.show_l2_gateway(l2_gateway['id']) - self.assertEqual(gw_name, show_body['l2_gateway']['name']) - conf_devices = base_l2gw.form_dict_devices(devices) - create_devices = base_l2gw.form_dict_devices(show_body['l2_gateway'] - ['devices']) - # Validate the resource provided in the conf and created - for k, v in zip(conf_devices.items(), create_devices.items()): - self.assertEqual(k, v) - # List L2Gateways - self.admin_client.list_l2_gateways() - # Update the name of an L2Gateway and verify the same - updated_name = 'updated ' + gw_name - update_body = self.admin_client.update_l2_gateway(l2_gateway['id'], - name=updated_name) - self.assertEqual(update_body['l2_gateway']['name'], updated_name) - show_body = self.admin_client.show_l2_gateway(l2_gateway['id']) - self.assertEqual(show_body['l2_gateway']['name'], updated_name) - - @decorators.idempotent_id('3ad5e945-2b42-4ea8-9c03-0bf41d4167f2') - def test_create_show_list_delete_l2gateway_connection(self): - # Create a network - name = data_utils.rand_name('network') - net_body = self.admin_client.create_network(name=name) - net_id = net_body['network']['id'] - self.addCleanup(self.admin_client.delete_network, net_id) - # Create an L2Gateway - gw_name = data_utils.rand_name('l2gw') - devices = base_l2gw.get_l2gw_body(CONF.l2gw.l2gw_switch)["devices"] - l2_gw_body = self.admin_client.create_l2_gateway( - name=gw_name, devices=devices) - l2_gw_id = l2_gw_body['l2_gateway']['id'] - self.addCleanup(self.admin_client.delete_l2_gateway, l2_gw_id) - # Create an L2Gateway Connection - l2_gw_conn_body = self.admin_client.create_l2_gateway_connection( - l2_gateway_id=l2_gw_id, network_id=net_id) - l2_gw_conn_id = l2_gw_conn_body['l2_gateway_connection']['id'] - self.addCleanup(self.admin_client.delete_l2_gateway_connection, - l2_gw_conn_id) - # Show details of created L2 Gateway connection - show_body = self.admin_client.show_l2_gateway_connection(l2_gw_conn_id) - l2_gw_conn = show_body['l2_gateway_connection'] - self.assertEqual(net_id, l2_gw_conn['network_id']) - self.assertEqual(l2_gw_id, l2_gw_conn['l2_gateway_id']) - # List L2Gateway Connections - self.admin_client.list_l2_gateway_connections() - - def test_create_l2gw_conn_with_segid_when_l2gw_created_without_segid(self): - # Create an L2Gateway - gw_name = data_utils.rand_name('l2gw') - devices = base_l2gw.get_l2gw_body(CONF.l2gw.l2gw_switch)["devices"] - if devices[0]['interfaces'][0]['segmentation_id']: - seg_id = devices[0]['interfaces'][0]['segmentation_id'][0] - devices[0]['interfaces'][0].pop('segmentation_id') - body = self.admin_client.create_l2_gateway( - name=gw_name, devices=devices) - l2_gateway = body['l2_gateway'] - l2_gw_id = l2_gateway['id'] - self.addCleanup(self.admin_client.delete_l2_gateway, l2_gw_id) - # Create a network - name = data_utils.rand_name('network') - net_body = self.admin_client.create_network(name=name) - net_id = net_body['network']['id'] - self.addCleanup(self.admin_client.delete_network, net_id) - # Create an L2Gateway Connection - l2_gw_conn_body = self.admin_client.create_l2_gateway_connection( - l2_gateway_id=l2_gw_id, network_id=net_id, - segmentation_id=seg_id) - l2_gw_conn_id = l2_gw_conn_body['l2_gateway_connection']['id'] - l2_gw_seg_id = l2_gw_conn_body['l2_gateway_connection'][ - 'segmentation_id'] - self.addCleanup(self.admin_client.delete_l2_gateway_connection, - l2_gw_conn_id) - # Show details of created L2 Gateway connection - show_body = self.admin_client.show_l2_gateway_connection( - l2_gw_conn_id) - l2_gw_conn = show_body['l2_gateway_connection'] - self.assertEqual(net_id, l2_gw_conn['network_id']) - self.assertEqual(l2_gw_id, l2_gw_conn['l2_gateway_id']) - self.assertEqual(str(l2_gw_seg_id), - str(l2_gw_conn['segmentation_id'])) - - def test_create_update_l2gw_with_multiple_devices(self): - # Generating name for multi-device L2Gateway - gw_name = data_utils.rand_name('l2gw') - # Generating a list consisting 3 random segmentation_ids - seg_id = random.sample(range(2, 4095), 3) - # Generating 3 device and interface names - dev_name1 = data_utils.rand_name('device_name') - interface_name1 = data_utils.rand_name('interface') - dev_name2 = data_utils.rand_name('device_name') - interface_name2 = data_utils.rand_name('interface') - dev_name3 = data_utils.rand_name('device_name') - interface_name3 = data_utils.rand_name('interface') - device_name_list = [dev_name1, dev_name2, dev_name3] - interface_name_list = [ - interface_name1, interface_name2, interface_name3] - # Forming the device for multi-device L2Gateway - devices_list = [{"device_name": device_name_list[0], "interfaces":[{ - "name": interface_name_list[0]}], - "segmentation_id": str(seg_id[0])}, { - "device_name": device_name_list[1], "interfaces":[{ - "name": interface_name_list[1]}], - "segmentation_id": str(seg_id[1])}, { - "device_name": device_name_list[2], "interfaces":[{ - "name": interface_name_list[2]}], - "segmentation_id": str(seg_id[2])}] - # Create the multi-device L2gateway - body = self.admin_client.create_l2_gateway( - name=gw_name, devices=devices_list) - l2_gateway = body['l2_gateway'] - l2_gw_id = l2_gateway['id'] - self.addCleanup(self.admin_client.delete_l2_gateway, l2_gw_id) - # Check the created multi-device L2Gateway - device_list = range(3) - interface_list = range(3) - show_body = self.admin_client.show_l2_gateway(l2_gw_id) - self.assertEqual(gw_name, show_body['l2_gateway']['name']) - self.assertEqual(l2_gateway['id'], show_body['l2_gateway']['id']) - for i in range(3): - device_list[i] = show_body['l2_gateway']['devices'][i][ - 'device_name'] - interface_list[i] = show_body['l2_gateway']['devices'][i][ - 'interfaces'][0]['name'] - for j in [0, 1, 2]: - self.assertIn(device_name_list[j], device_list) - self.assertIn(interface_name_list[j], interface_list) - # Update the gateway device name - device_list_updated = range(3) - interface_list_updated = range(3) - device_updated = [{"device_name": device_name_list[0], "interfaces":[{ - "name": "intNameNew"}]}] - interface_name_list = [ - interface_name_list[2], interface_name_list[1], "intNameNew"] - body = self.admin_client.update_l2_gateway( - l2_gateway['id'], devices=device_updated) - show_body_updated = self.admin_client.show_l2_gateway( - l2_gateway['id']) - # Check updating of multi-device L2gateway - self.assertEqual(gw_name, show_body_updated['l2_gateway']['name']) - self.assertEqual(l2_gateway['id'], - show_body_updated['l2_gateway']['id']) - for k in range(3): - device_list_updated[k] = show_body_updated['l2_gateway'][ - 'devices'][k]['device_name'] - interface_list_updated[k] = show_body_updated['l2_gateway'][ - 'devices'][k]['interfaces'][0]['name'] - for l in range(3): - self.assertIn(device_name_list[l], device_list_updated) - self.assertIn(interface_name_list[l], interface_list_updated) diff -Nru networking-l2gw-11.0.0/networking_l2gw/tests/api/test_l2gw_negative.py networking-l2gw-12.0.1/networking_l2gw/tests/api/test_l2gw_negative.py --- networking-l2gw-11.0.0/networking_l2gw/tests/api/test_l2gw_negative.py 2017-09-19 05:52:35.000000000 +0000 +++ networking-l2gw-12.0.1/networking_l2gw/tests/api/test_l2gw_negative.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,279 +0,0 @@ -# Copyright 2015 Hewlett-Packard Development Company, L.P. -# Copyright 2015 OpenStack Foundation -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from random import randint - -from neutron.tests.tempest.api import base -from tempest import config -from tempest.lib.common.utils import data_utils -from tempest.lib import decorators -from tempest.lib import exceptions as lib_exc -from tempest import test - -from networking_l2gw.tests.api import base_l2gw - -CONF = config.CONF - - -class L2GatewaysNegativeTestJSON(base.BaseNetworkTest): - _interface = 'json' - - @classmethod - def resource_setup(cls): - super(L2GatewaysNegativeTestJSON, cls).resource_setup() - # At least one switch detail should be provided to run the tests - if (len(CONF.l2gw.l2gw_switch) <= 0): - msg = ('At least one switch detail must be defined.') - raise cls.skipException(msg) - if not test.is_extension_enabled('l2-gateway', 'network'): - msg = "L2Gateway Extension not enabled." - raise cls.skipException(msg) - - @test.attr(type=['negative', 'smoke']) - @decorators.idempotent_id('b301d83d-3af3-4712-86dc-a6824e9b14e5') - def test_create_l2gateway_non_admin_user(self): - gw_name = data_utils.rand_name('l2gw') - devices = base_l2gw.get_l2gw_body(CONF.l2gw.l2gw_switch)["devices"] - self.assertRaises(lib_exc.Forbidden, - self.client.create_l2_gateway, - name=gw_name, devices=devices) - - @test.attr(type=['negative', 'smoke']) - @decorators.idempotent_id('68451dfe-b3b5-4eb1-b03f-9935d4a2dbe7') - def test_list_l2gateway_non_admin_user(self): - self.assertRaises(lib_exc.Forbidden, - self.client.list_l2_gateways) - - @test.attr(type=['negative', 'smoke']) - @decorators.idempotent_id('f8589452-7aff-4992-b865-5bb5c41fa755') - def test_update_l2gateway_non_admin_user(self): - non_exist_id = data_utils.rand_name('l2gw') - self.assertRaises(lib_exc.Forbidden, - self.client.update_l2_gateway, - non_exist_id, name="updated_name") - - @test.attr(type=['negative', 'smoke']) - @decorators.idempotent_id('d9f57800-6cae-4770-a2d7-ab60cf7417bf') - def test_delete_l2gateway_non_admin_user(self): - non_exist_id = data_utils.rand_name('l2gw') - self.assertRaises(lib_exc.Forbidden, - self.client.delete_l2_gateway, - non_exist_id) - - @test.attr(type=['negative', 'smoke']) - @decorators.idempotent_id('c6b61a8d-8c82-497d-9fad-9929c9acf035') - def test_create_l2gateway_connection_non_admin_user(self): - non_exist_id = data_utils.rand_name('network') - self.assertRaises(lib_exc.Forbidden, - self.client.create_l2_gateway_connection, - network_id=non_exist_id, l2_gateway_id=non_exist_id) - - @test.attr(type=['negative', 'smoke']) - @decorators.idempotent_id('a56a0180-7d98-414c-9a44-fe47a30fe436') - def test_list_l2gateway_connection_non_admin_user(self): - self.assertRaises(lib_exc.Forbidden, - self.client.list_l2_gateway_connections) - - @test.attr(type=['negative', 'smoke']) - @decorators.idempotent_id('ce42c68d-5c41-4988-8912-233e3fe5c8fd') - def test_delete_l2gateway_connection_non_admin_user(self): - non_exist_id = data_utils.rand_name('l2gwconnection') - self.assertRaises(lib_exc.Forbidden, - self.client.delete_l2_gateway_connection, - non_exist_id) - - -class L2GatewaysNegativeAdminTestJSON(base.BaseAdminNetworkTest): - _interface = 'json' - - @classmethod - def resource_setup(cls): - super(L2GatewaysNegativeAdminTestJSON, cls).resource_setup() - # At least one switch detail should be provided to run the tests - if (len(CONF.l2gw.l2gw_switch) <= 0): - msg = ('At least one switch detail must be defined.') - raise cls.skipException(msg) - if not test.is_extension_enabled('l2-gateway', 'network'): - msg = "L2Gateway Extension not enabled." - raise cls.skipException(msg) - - @test.attr(type=['negative', 'smoke']) - @decorators.idempotent_id('42067b44-3aff-4428-8305-d0496bd38179') - def test_delete_l2gw_associated_l2gw_connection(self): - # Create a network - name = data_utils.rand_name('network') - net_body = self.admin_client.create_network(name=name) - net_id = net_body['network']['id'] - self.addCleanup(self.admin_client.delete_network, net_id) - # Create an L2Gateway - gw_name = data_utils.rand_name('l2gw') - devices = base_l2gw.get_l2gw_body(CONF.l2gw.l2gw_switch)["devices"] - body = self.admin_client.create_l2_gateway( - name=gw_name, devices=devices) - l2_gateway = body['l2_gateway'] - self.addCleanup(self.admin_client.delete_l2_gateway, l2_gateway['id']) - # Create an L2Gateway Connection - l2_gw_conn_body = self.admin_client.create_l2_gateway_connection( - l2_gateway_id=l2_gateway['id'], network_id=net_id) - l2_gw_conn_id = l2_gw_conn_body['l2_gateway_connection']['id'] - self.addCleanup(self.admin_client.delete_l2_gateway_connection, - l2_gw_conn_id) - self.assertRaises(lib_exc.Conflict, - self.admin_client.delete_l2_gateway, - l2_gateway['id']) - - @test.attr(type=['negative', 'smoke']) - def test_create_l2gw_with_empty_device_name(self): - # Create an L2Gateway - seg_id = randint(2, 4094) - seg_id_str = [str(seg_id)] - gw_name = data_utils.rand_name('l2gw') - dev_name = "" - interface_name = data_utils.rand_name('interface') - device = [{"device_name": dev_name, "interfaces": - [{"name": interface_name, "segmentation_id": seg_id_str}]}] - self.assertRaises(lib_exc.BadRequest, - self.admin_client.create_l2_gateway, - name=gw_name, devices=device - ) - - @test.attr(type=['negative', 'smoke']) - def test_create_l2gw_connection_with_invalid_segmentation_id(self): - # Create an L2Gateway - gw_name = data_utils.rand_name('l2gw') - dev_name = data_utils.rand_name('device_name') - interface_name = data_utils.rand_name('interface') - devices = [{"device_name": dev_name, "interfaces": - [{"name": interface_name}]}] - body = self.admin_client.create_l2_gateway( - name=gw_name, devices=devices) - l2_gateway = body['l2_gateway'] - l2_gw_id = l2_gateway['id'] - self.addCleanup(self.admin_client.delete_l2_gateway, l2_gw_id) - - # Create a network - name = data_utils.rand_name('network') - net_body = self.admin_client.create_network(name=name) - net_id = net_body['network']['id'] - self.addCleanup(self.admin_client.delete_network, net_id) - for i in ['-1', '4095', '4096']: - seg_id = [i] - self.assertRaises(lib_exc.BadRequest, - self.admin_client.create_l2_gateway_connection, - l2_gateway_id=l2_gw_id, network_id=net_id, - segmentation_id=seg_id) - - @test.attr(type=['negative', 'smoke']) - def test_create_l2gw_with_invalid_segmentation_id(self): - # Create an L2Gateway - gw_name = data_utils.rand_name('l2gw') - dev_name = data_utils.rand_name('device_name') - interface_name = data_utils.rand_name('interface') - for i in ['-1', '4095', '4096']: - seg_id = [i] - device = [{"device_name": dev_name, "interfaces": - [{"name": interface_name, "segmentation_id": seg_id}]}] - self.assertRaises(lib_exc.BadRequest, - self.admin_client.create_l2_gateway, - name=gw_name, devices=device - ) - - @test.attr(type=['negative', 'smoke']) - def test_create_l2gw_with_empty_interface_name(self): - # Create an L2Gateway - seg_id = randint(2, 4094) - seg_id_str = [str(seg_id)] - gw_name = data_utils.rand_name('l2gw') - dev_name = data_utils.rand_name('device') - interface_name = "" - device = [{"device_name": dev_name, "interfaces": - [{"name": interface_name, "segmentation_id": seg_id_str}]}] - self.assertRaises(lib_exc.BadRequest, - self.admin_client.create_l2_gateway, - name=gw_name, devices=device - ) - - @test.attr(type=['negative', 'smoke']) - def test_delete_non_existent_l2gateway(self): - non_exist_id = data_utils.rand_name('l2gw') - self.assertRaises(lib_exc.NotFound, - self.admin_client.delete_l2_gateway, - non_exist_id) - - @test.attr(type=['negative', 'smoke']) - def test_delete_non_existent_l2gateway_connection(self): - non_exist_id = data_utils.rand_name('l2gwConnection') - self.assertRaises(lib_exc.NotFound, - self.admin_client.delete_l2_gateway_connection, - non_exist_id) - - @test.attr(type=['negative', 'smoke']) - def test_create_l2gw_connection_with_invalid_network_name(self): - # Create an L2Gateway - gw_name = data_utils.rand_name('l2gw') - devices = base_l2gw.get_l2gw_body(CONF.l2gw.l2gw_switch)["devices"] - body = self.admin_client.create_l2_gateway( - name=gw_name, devices=devices) - l2_gateway = body['l2_gateway'] - l2_gw_id = l2_gateway['id'] - self.addCleanup(self.admin_client.delete_l2_gateway, l2_gw_id) - - # Create a network - net_id = "network" - self.assertRaises(lib_exc.NotFound, - self.admin_client.create_l2_gateway_connection, - l2_gateway_id=l2_gw_id, network_id=net_id - ) - - @test.attr(type=['negative', 'smoke']) - def test_update_gateway_with_invalid_device_name(self): - # Create an L2Gateway - gw_name = data_utils.rand_name('l2gw') - devices = base_l2gw.get_l2gw_body(CONF.l2gw.l2gw_switch)["devices"] - body = self.admin_client.create_l2_gateway( - name=gw_name, devices=devices) - l2_gateway = body['l2_gateway'] - self.addCleanup(self.admin_client.delete_l2_gateway, l2_gateway['id']) - device_1 = [{"device_name": ""}] - - # Create a connection again for same L2Gateway and Network - self.assertRaises(lib_exc.BadRequest, - self.admin_client.update_l2_gateway, - gw_name, devices=device_1 - ) - - @test.attr(type=['negative', 'smoke']) - def test_create_l2gw_and_l2gw_connection_both_without_seg_id(self): - # Create an L2Gateway - gw_name = data_utils.rand_name('l2gw') - devices = base_l2gw.get_l2gw_body(CONF.l2gw.l2gw_switch)["devices"] - if devices[0]['interfaces'][0]['segmentation_id']: - devices[0]['interfaces'][0].pop('segmentation_id') - body = self.admin_client.create_l2_gateway( - name=gw_name, devices=devices) - l2_gateway = body['l2_gateway'] - l2_gw_id = l2_gateway['id'] - self.addCleanup(self.admin_client.delete_l2_gateway, l2_gw_id) - - # Create a network - name = data_utils.rand_name('network') - net_body = self.admin_client.create_network(name=name) - net_id = net_body['network']['id'] - self.addCleanup(self.admin_client.delete_network, net_id) - self.assertRaises(lib_exc.BadRequest, - self.admin_client.create_l2_gateway_connection, - l2_gateway_id=l2_gw_id, network_id=net_id - ) diff -Nru networking-l2gw-11.0.0/networking_l2gw/tests/fullstack/test_l2gw.py networking-l2gw-12.0.1/networking_l2gw/tests/fullstack/test_l2gw.py --- networking-l2gw-11.0.0/networking_l2gw/tests/fullstack/test_l2gw.py 2017-09-19 05:52:34.000000000 +0000 +++ networking-l2gw-12.0.1/networking_l2gw/tests/fullstack/test_l2gw.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslotest import base - - -class TestBase(base.BaseTestCase): - - def test_example(self): - pass diff -Nru networking-l2gw-11.0.0/networking_l2gw/tests/scenario/ovsdb_connections.py networking-l2gw-12.0.1/networking_l2gw/tests/scenario/ovsdb_connections.py --- networking-l2gw-11.0.0/networking_l2gw/tests/scenario/ovsdb_connections.py 2017-09-19 05:52:34.000000000 +0000 +++ networking-l2gw-12.0.1/networking_l2gw/tests/scenario/ovsdb_connections.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,153 +0,0 @@ -# Copyright 2015 OpenStack Foundation -# Copyright 2015 Hewlett-Packard Development Company, L.P. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import collections -import json -import logging -import random -import socket -import threading -import time - -logging.basicConfig(level=logging.DEBUG) - - -def default_echo_handler(message, ovsconn): - logging.debug("responding to echo") - ovsconn.send({"result": message.get("params", None), - "error": None, "id": message['id']}) - - -def default_message_handler(message, ovsconn): - ovsconn.responses.append(message) - - -class OVSDBConnection(threading.Thread): - """Connects to an ovsdb server that has manager set using - - ovs-vsctl set-manager ptcp:5000 - - clients can make calls and register a callback for results, callbacks - are linked based on the message ids. - - clients can also register methods which they are interested in by - providing a callback. - """ - - def __init__(self, IP, PORT, **handlers): - super(OVSDBConnection, self).__init__() - self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.socket.connect((IP, PORT)) - self.responses = [] - self.callbacks = {} - self.read_on = True - self.handlers = handlers or {"echo": default_echo_handler} - self.start() - - def send(self, message, callback=None): - if callback: - self.callbacks[message['id']] = callback - self.socket.send(json.dumps(message)) - - def response(self, id): - return [x for x in self.responses if x['id'] == id] - - def set_handler(self, method_name, handler): - self.handlers[method_name] = handler - - def _on_remote_message(self, message): - try: - json_m = json.loads(message, - object_pairs_hook=collections.OrderedDict) - handler_method = json_m.get('method', None) - if handler_method: - self.handlers.get(handler_method, default_message_handler)( - json_m, self) - elif json_m.get("result", None) and json_m['id'] in self.callbacks: - id = json_m['id'] - if not self.callbacks[id](json_m, self): - self.callbacks.pop(id) - - else: - default_message_handler(message, self) - except Exception as e: - logging.exception( - "exception [%s] in handling message [%s]", e.message, message) - - def __echo_response(message, self): - self.send({"result": message.get("params", None), - "error": None, "id": message['id']}) - - def run(self): - - chunks = [] - lc = rc = 0 - while self.read_on: - try: - response = self.socket.recv(4096) - if response: - response = response.decode('utf8') - message_mark = 0 - for i, c in enumerate(response): - if c == '{': - lc += 1 - elif c == '}': - rc += 1 - - if rc > lc: - raise Exception("json string not valid") - - elif lc == rc and lc is not 0: - chunks.append(response[message_mark:i + 1]) - message = "".join(chunks) - self._on_remote_message(message) - lc = rc = 0 - message_mark = i + 1 - chunks = [] - - chunks.append(response[message_mark:]) - except Exception: - # Pass to avoid EOF error - pass - - def stop(self, force=False): - self.read_on = False - if force: - self.socket.close() - - def select_table(self, table): - select_dict = {"op": "select", "table": table, "where": []} - op_id = str(random.getrandbits(128)) - params = ['hardware_vtep'] - params.append(select_dict) - query_select = {"method": "transact", - "params": params, - "id": op_id} - return query_select - - def find_row(self, net_id, count, resp_dec): - for i in range(count): - row = str(resp_dec['result'][0]['rows'][i]) - if net_id in row: - return row - - def get_response(self, OVSDB_IP, OVSDB_PORT, table): - query = self.select_table(table) - self.send(query) - time.sleep(2) - resp = self.responses - resp = str(resp[0]) - return resp diff -Nru networking-l2gw-11.0.0/networking_l2gw/tests/scenario/test_l2gateways.py networking-l2gw-12.0.1/networking_l2gw/tests/scenario/test_l2gateways.py --- networking-l2gw-11.0.0/networking_l2gw/tests/scenario/test_l2gateways.py 2017-09-19 05:52:34.000000000 +0000 +++ networking-l2gw-12.0.1/networking_l2gw/tests/scenario/test_l2gateways.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,386 +0,0 @@ -# Copyright 2015 OpenStack Foundation -# Copyright 2015 Hewlett-Packard Development Company, L.P. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import json -import time - -from neutron.tests.api import base -from neutron.tests.tempest import exceptions -from neutron.tests.tempest import manager -from oslo_log import log -from tempest.lib.common import rest_client -from tempest.lib.common.utils import data_utils -from tempest.lib.common.utils import test_utils -from tempest.lib import exceptions as lib_exc - -from networking_l2gw.tests.api import base_l2gw -from networking_l2gw.tests.scenario import ovsdb_connections -from networking_l2gw.tests.tempest import config - -CONF = config.CONF -LOG = log.getLogger(__name__) -OVSDB_IP = CONF.network.ovsdb_ip -OVSDB_PORT = CONF.network.ovsdb_port -OVSDB_SCHEMA_NAME = CONF.network.ovsdb_schema_name - - -class TestL2GatewayBasic(base.BaseAdminNetworkTest): - - """This test case tests the basic end to end functionality of l2-gateway - - and tests whether the appropriate entries are getting registered in - - the ovsdb. - """ - - @classmethod - def resource_setup(cls): - super(TestL2GatewayBasic, cls).resource_setup() - nova_creds = cls.isolated_creds.get_admin_creds() - cls.auth_provider = manager.get_auth_provider(nova_creds) - - def _create_server( - self, name=None, - network=None, wait_on_boot=True, wait_on_delete=True): - region = CONF.compute.region - image = CONF.compute.image_ref - flavor = CONF.compute.flavor_ref - rs_client = rest_client.RestClient( - self.auth_provider, 'compute', region) - data = {'server': { - 'name': name, - 'imageRef': image, - 'flavorRef': flavor, - 'max_count': 1, - 'min_count': 1, - 'networks': [{'uuid': network}]}} - data = json.dumps(data) - (resp, body,) = rs_client.post('/servers', data) - rs_client.expected_success(202, resp.status) - body = json.loads(body) - server_id = body['server']['id'] - self.wait_for_server_status(server_id, 'ACTIVE') - return server_id - - def _delete_server(self, server=None): - rs_client = rest_client.RestClient( - self.auth_provider, 'compute', 'RegionOne') - (resp, body, ) = rs_client.delete('servers/%s' % str(server)) - self.wait_for_server_termination(server) - rest_client.ResponseBody(resp, body) - - def wait_for_server_status(self, server_id, status, ready_wait=True, - extra_timeout=0, raise_on_error=True): - """Waits for a server to reach a given status.""" - build_timeout = CONF.compute.build_timeout - build_interval = CONF.boto.build_interval - - def _get_task_state(body): - return body.get('OS-EXT-STS:task_state', None) - rs = rest_client.RestClient(self.auth_provider, "compute", "RegionOne") - resp, body = rs.get("servers/%s" % str(server_id)) - body = json.loads(body) - old_status = server_status = body['server']['status'] - old_task_state = task_state = _get_task_state(body) - start_time = int(time.time()) - timeout = build_timeout + extra_timeout - while True: - if status == 'BUILD' and server_status != 'UNKNOWN': - return - if server_status == status: - if ready_wait: - if status == 'BUILD': - return - if str(task_state) == "None": - time.sleep(CONF.compute.ready_wait) - return - else: - return - time.sleep(build_interval) - resp, body = rs.get("servers/%s" % str(server_id)) - body = json.loads(body) - server_status = body['server']['status'] - task_state = _get_task_state(body) - if (server_status != old_status) or (task_state != old_task_state): - oldstatus = '/'.join((old_status, str(old_task_state))) - serverstatus = '/'.join((server_status, str(task_state))) - waitsec = (time.time() - start_time) - LOG.info( - 'State transition %(oldstatus)s => %(serverstatus)s' - 'after %(waitsec)d second wait' % - {'oldstatus': oldstatus, 'serverstatus': serverstatus, - 'waitsec': waitsec} - ) - if (server_status == 'ERROR') and raise_on_error: - if 'fault' in body: - raise exceptions.BuildErrorException(body['fault'], - server_id=server_id) - else: - raise exceptions.BuildErrorException(server_id=server_id) - timed_out = int(time.time()) - start_time >= timeout - if timed_out: - expected_task_state = 'None' if ready_wait else 'n/a' - message = ('Server %(server_id)s failed to reach %(status)s ' - 'status and task state "%(expected_task_state)s" ' - 'within the required time (%(timeout)s s).' % - {'server_id': server_id, - 'status': status, - 'expected_task_state': expected_task_state, - 'timeout': timeout}) - message += ' Current status: %s.' % server_status - message += ' Current task state: %s.' % task_state - caller = test_utils.find_test_caller() - if caller: - message = '(%s) %s' % (caller, message) - raise exceptions.TimeoutException(message) - old_status = server_status - old_task_state = task_state - - def wait_for_server_termination(self, server_id, ignore_error=False): - """Waits for server to reach termination.""" - build_interval = CONF.boto.build_interval - while True: - try: - rs = rest_client.RestClient( - self.auth_provider, 'compute', 'RegionOne') - (resp, body,) = rs.get('servers/%s' % str(server_id)) - body = json.loads(body) - except lib_exc.NotFound: - return - server_status = body['server']['status'] - if server_status == 'ERROR' and not ignore_error: - raise exceptions.BuildErrorException(server_id=server_id) - time.sleep(build_interval) - - def validate_ovsdb(self, seg_id, port, network_id_1, tunnel_key): - # Check Logical_Switch - objConnection = ovsdb_connections.OVSDBConnection(OVSDB_IP, OVSDB_PORT) - resp = objConnection.get_response( - OVSDB_IP, OVSDB_PORT, "Logical_Switch") - resp_dec = json.loads(resp) - count = resp.count('_uuid') - try: - self.assertIn(str(network_id_1), resp) - except Exception: - raise lib_exc.NotFound("Network not found in Logical Switch table") - row = objConnection.find_row(network_id_1, count, resp_dec) - try: - self.assertIn(str(tunnel_key), row) - except Exception: - raise lib_exc.NotFound( - "Tunnel key not found in Logical Switch table") - objConnection.stop("true") - - # Check Physical_Port - objConnection = ovsdb_connections.OVSDBConnection(OVSDB_IP, OVSDB_PORT) - resp = objConnection.get_response( - OVSDB_IP, OVSDB_PORT, "Physical_Port") - count = resp.count('_uuid') - try: - self.assertIn(str(seg_id[0]), resp) - except Exception: - raise lib_exc.NotFound( - "Segmentation ID not found in Physical Port table") - objConnection.stop("true") - - # Check Physical_Locator - objConnection = ovsdb_connections.OVSDBConnection(OVSDB_IP, OVSDB_PORT) - resp = objConnection.get_response( - OVSDB_IP, OVSDB_PORT, "Physical_Locator") - count = resp.count('_uuid') - port_str = str(port) - count_port = port_str.count('fixed_ips') - net_node_host = [] - compute_node_host = [] - # Extracting unique Network node host name and Compute host name - for i in range(count_port): - net_id = port['ports'][i]['network_id'] - device_owner = port['ports'][i]['device_owner'] - if net_id == network_id_1 and device_owner == 'network:dhcp': - if port['ports'][i]['binding:host_id'] not in net_node_host: - net_node_host.append(port['ports'][i]['binding:host_id']) - if port['ports'][i]['device_owner'] == 'compute:None': - if port['ports'][i]['binding:host_id'] not in net_node_host: - compute_node_host.append( - port['ports'][i]['binding:host_id']) - ip_SW = CONF.network.l2gw_switch_ip - host_and_ip = CONF.network.hosts - list_ = host_and_ip.split(', ') - host_ip_dict = {} - for i in list_: - sub_list = i.split(':') - host = sub_list[0] - ip = sub_list[1] - host_ip_dict.update({host: ip}) - for net_node in net_node_host: - ip_NN = host_ip_dict[net_node] - try: - self.assertIn(ip_NN, resp) - except Exception: - raise lib_exc.NotFound( - "Network Node IP not found in Physical Locator table") - for compute_node in compute_node_host: - ip_CN = host_ip_dict[compute_node] - try: - self.assertIn(ip_CN, resp) - except Exception: - raise lib_exc.NotFound( - "Compute Node IP not found in Physical Locator table") - try: - self.assertIn(ip_SW, resp) - except Exception: - raise lib_exc.NotFound( - "Switch IP not found in Physical Locator table") - objConnection.stop("true") - - # Check Ucast_macs_Remote - objConnection = ovsdb_connections.OVSDBConnection(OVSDB_IP, OVSDB_PORT) - resp = objConnection.get_response( - OVSDB_IP, OVSDB_PORT, "Ucast_Macs_Remote") - ip_mac_dict = {} - count_uuid = resp.count('_uuid') - resp_dec = json.loads(resp) - for i in range(count_port): - mac = port['ports'][i]['mac_address'] - ip = port['ports'][i]['fixed_ips'][0]['ip_address'] - ip_mac_dict.update({mac: ip}) - try: - for key, value in ip_mac_dict.items(): - row = objConnection.find_row(key, count_uuid, resp_dec) - self.assertIn(value, row) - except Exception: - raise lib_exc.NotFound( - "MAC & its port not found in UCast MAC Remote table") - objConnection.stop("true") - - def _create_l2_gateway(self, name, devices): - body_l2gateway = self.admin_client.create_l2_gateway( - name=name, devices=devices) - self.addCleanup( - self.admin_client.delete_l2_gateway, - body_l2gateway['l2_gateway']['id']) - return body_l2gateway - - def _create_l2_gw_connection( - self, l2gw, net_id, seg_id=None, explicit=None): - l2gw_id = l2gw['l2_gateway']['id'] - if l2gw['l2_gateway']['devices'][0]['interfaces'][ - 0]['segmentation_id']: - resp_l2gwconn = self.admin_client.create_l2_gateway_connection( - network_id=net_id, l2_gateway_id=l2gw_id) - else: - resp_l2gwconn = self.admin_client.create_l2_gateway_connection( - network_id=net_id, - l2_gateway_id=l2gw_id, segmentation_id=seg_id) - if explicit: - # Connection deleted explicitly, thus addCleanup not called - pass - else: - self.addCleanup( - self.admin_client.delete_l2_gateway_connection, - resp_l2gwconn['l2_gateway_connection']['id']) - return resp_l2gwconn - - def _setup_network_and_server(self, cidr=None): - network = self.create_network() - self.addCleanup(self.client.delete_network, network['id']) - self.create_subnet(network=network, cidr=cidr) - name = data_utils.rand_name('server-smoke') - server_id = self._create_server(name, network=network['id']) - self.addCleanup(self._delete_server, server_id) - return network - - def test_l2gw_create_connection(self): - network = self._setup_network_and_server() - network_body = self.admin_client.show_network(network['id']) - gw_name = data_utils.rand_name('l2gw') - devices = base_l2gw.get_l2gw_body(CONF.network.l2gw_switch)['devices'] - l2_gw_body = self._create_l2_gateway(name=gw_name, devices=devices) - segmentation_id = l2_gw_body['l2_gateway']['devices'][0][ - 'interfaces'][0]['segmentation_id'] - self._create_l2_gw_connection(l2_gw_body, network['id']) - tunnel_key = network_body['network']['provider:segmentation_id'] - port = self.admin_client.list_ports() - self.validate_ovsdb(segmentation_id, port, network['id'], tunnel_key) - - def test_multiple_connections(self): - # Create first connection and validate - network = self._setup_network_and_server() - network_body = self.admin_client.show_network(network['id']) - gw_name = data_utils.rand_name('l2gw') - devices = base_l2gw.get_l2gw_body(CONF.network.l2gw_switch)['devices'] - l2_gw_body = self._create_l2_gateway(name=gw_name, devices=devices) - segmentation_id = l2_gw_body['l2_gateway']['devices'][0][ - 'interfaces'][0]['segmentation_id'] - self._create_l2_gw_connection(l2_gw_body, network['id']) - tunnel_key = network_body['network']['provider:segmentation_id'] - port = self.admin_client.list_ports() - self.validate_ovsdb(segmentation_id, port, network['id'], tunnel_key) - # Create second connection and validate - network_2 = self._setup_network_and_server() - network_body_2 = self.admin_client.show_network(network_2['id']) - gw_name_2 = data_utils.rand_name('l2gw') - devices_2 = base_l2gw.get_l2gw_body( - CONF.network.l2gw_switch_2)['devices'] - l2_gw_body_2 = self._create_l2_gateway( - name=gw_name_2, devices=devices_2) - segmentation_id_2 = l2_gw_body_2['l2_gateway']['devices'][0][ - 'interfaces'][0]['segmentation_id'] - self._create_l2_gw_connection(l2_gw_body_2, network_2['id']) - tunnel_key_2 = network_body_2['network']['provider:segmentation_id'] - port_2 = self.admin_client.list_ports() - self.validate_ovsdb( - segmentation_id_2, port_2, network_2['id'], tunnel_key_2) - - def test_boot_vm_after_create_connection(self): - network = self.create_network() - self.addCleanup(self.client.delete_network, network['id']) - self.create_subnet(network) - gw_name = data_utils.rand_name('l2gw') - devices = base_l2gw.get_l2gw_body(CONF.network.l2gw_switch)['devices'] - l2_gw_body = self._create_l2_gateway(name=gw_name, devices=devices) - segmentation_id = l2_gw_body['l2_gateway']['devices'][0][ - 'interfaces'][0]['segmentation_id'] - self._create_l2_gw_connection(l2_gw_body, network['id']) - name = data_utils.rand_name('server-smoke') - server_id = self._create_server(name, network=network['id']) - self.addCleanup(self._delete_server, server_id) - network_body = self.admin_client.show_network(network['id']) - segmentation_id = l2_gw_body['l2_gateway']['devices'][0][ - 'interfaces'][0]['segmentation_id'] - tunnel_key = network_body['network']['provider:segmentation_id'] - port = self.admin_client.list_ports() - self.validate_ovsdb(segmentation_id, port, network['id'], tunnel_key) - - def test_create_new_connection_after_deleting_old_one(self): - network = self._setup_network_and_server() - network_body = self.admin_client.show_network(network['id']) - gw_name = data_utils.rand_name('l2gw') - devices = base_l2gw.get_l2gw_body(CONF.network.l2gw_switch)['devices'] - l2_gw_body = self._create_l2_gateway(name=gw_name, devices=devices) - segmentation_id = l2_gw_body['l2_gateway']['devices'][0][ - 'interfaces'][0]['segmentation_id'] - # Create a connection and validate ovsdb - l2gw_connection = self._create_l2_gw_connection( - l2_gw_body, network['id'], explicit=True) - tunnel_key = network_body['network']['provider:segmentation_id'] - port = self.admin_client.list_ports() - self.validate_ovsdb(segmentation_id, port, network['id'], tunnel_key) - # Delete and create new connection and validate ovsdb - self.admin_client.delete_l2_gateway_connection( - l2gw_connection['l2_gateway_connection']['id']) - self._create_l2_gw_connection(l2_gw_body, network['id']) - self.validate_ovsdb(segmentation_id, port, network['id'], tunnel_key) diff -Nru networking-l2gw-11.0.0/networking_l2gw/tests/tempest/config.py networking-l2gw-12.0.1/networking_l2gw/tests/tempest/config.py --- networking-l2gw-11.0.0/networking_l2gw/tests/tempest/config.py 2017-09-19 05:52:34.000000000 +0000 +++ networking-l2gw-12.0.1/networking_l2gw/tests/tempest/config.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -# Copyright (c) 2016 Hewlett-Packard Enterprise Development Company, L.P. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - - -from oslo_config import cfg - -# L2Gateway related config information -L2GW_OPTS = [ - cfg.StrOpt('l2gw_switch', - default='', - help='Switch name ,interface and vlan id information '), - cfg.StrOpt('l2gw_switch_2', - default='', - help='Switch name ,interface and vlan id information'), - cfg.StrOpt('hosts', - default='', - help='Network node and compute node host names and IPs'), - cfg.StrOpt('l2gw_switch_ip', - default='', - help='Switch IP'), - cfg.StrOpt('ovsdb_ip', - default='', - help='IP of ovsdb server'), - cfg.IntOpt('ovsdb_port', - default=6632, - help='Port of ovsdb server'), - cfg.StrOpt('ovsdb_schema_name', - default='', - help='schema name of ovsdb') -] - - -l2gw_group = cfg.OptGroup(name='l2gw', - title='Neutron L2GW Options') diff -Nru networking-l2gw-11.0.0/networking_l2gw/tests/tempest/etc/tempest.conf.sample networking-l2gw-12.0.1/networking_l2gw/tests/tempest/etc/tempest.conf.sample --- networking-l2gw-11.0.0/networking_l2gw/tests/tempest/etc/tempest.conf.sample 2017-09-19 05:52:34.000000000 +0000 +++ networking-l2gw-12.0.1/networking_l2gw/tests/tempest/etc/tempest.conf.sample 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -[l2gw] -#List of switch device,interfaces name and segmentation_ids for l2gateway -l2gw_switch = cell08-5930-01::FortyGigE1/0/1|100 -l2gw_switch_2 = cell21-5930-01::FortyGigE1/0/1|101 -#l2gw_switch = cell08-5930-01::FortyGigE1/0/1|100#200;FortyGigE1/0/2|300 -#l2gw_switch = cell08-5930-01::FortyGigE1/0/1|100#200,cell08-5930-02::FortyGigE1/0/2|300 -l2gw_switch_ip = switch_vtep_ip -hosts = cn_host_name:cn_ip, nn_host_name:nn_ip -ovsdb_ip = ovsdb_ip -ovsdb_port = 6632 -ovsdb_schema_name = hardware_vtep - diff -Nru networking-l2gw-11.0.0/networking_l2gw/tests/tempest/plugin.py networking-l2gw-12.0.1/networking_l2gw/tests/tempest/plugin.py --- networking-l2gw-11.0.0/networking_l2gw/tests/tempest/plugin.py 2017-09-19 05:52:34.000000000 +0000 +++ networking-l2gw-12.0.1/networking_l2gw/tests/tempest/plugin.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -# Copyright 2017 -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os - -import networking_l2gw -from tempest.test_discover import plugins - -from networking_l2gw.tests.tempest import config as l2gw_config - - -class NeutronL2gwTempestPlugin(plugins.TempestPlugin): - def load_tests(self): - base_path = os.path.split(os.path.dirname( - os.path.abspath(networking_l2gw.__file__)))[0] - test_dir = "networking_l2gw/tests/api" - full_test_dir = os.path.join(base_path, test_dir) - return full_test_dir, base_path - - def register_opts(self, conf): - conf.register_group(l2gw_config.l2gw_group) - conf.register_opts(l2gw_config.L2GW_OPTS, - group=l2gw_config.l2gw_group) - - def get_opt_lists(self): - return [ - (l2gw_config.l2gw_group.name, l2gw_config.L2GW_OPTS), - ] diff -Nru networking-l2gw-11.0.0/networking_l2gw/tests/unit/db/test_l2gw_db.py networking-l2gw-12.0.1/networking_l2gw/tests/unit/db/test_l2gw_db.py --- networking-l2gw-11.0.0/networking_l2gw/tests/unit/db/test_l2gw_db.py 2017-09-19 05:52:34.000000000 +0000 +++ networking-l2gw-12.0.1/networking_l2gw/tests/unit/db/test_l2gw_db.py 2018-02-25 13:35:51.000000000 +0000 @@ -15,9 +15,9 @@ import mock -from neutron.callbacks import events -from neutron.callbacks import resources from neutron.tests.unit import testlib_api +from neutron_lib.callbacks import events +from neutron_lib.callbacks import resources from neutron_lib import context from networking_l2gw.db.l2gateway import l2gateway_db @@ -92,6 +92,15 @@ "device_name": device_name}]}} return data + def _get_l2_gw_multiple_interface_without_seg_id_data(self, name, + device_name): + """Get l2 gateway data helper method with partial seg id.""" + return {"l2_gateway": {"name": name, + "devices": + [{"interfaces": [{"name": "port1"}, + {"name": "port2"}], + "device_name": device_name}]}} + def _get_l2_gw_invalid_seg_id_data(self, name, device_name): """Get l2 gateway data helper method with invalid seg id.""" @@ -343,6 +352,38 @@ self.assertRaises(exceptions.L2GatewaySegmentationRequired, self._validate_l2_gateway_for_create, data) + def test_l2_gateway_update_with_mul_interfaces_inconsistent_seg_id(self): + """Test l2 gateway update with multiple interfaces.""" + name = "l2gw_1" + dev_name = "device1" + data_orig = self._get_l2_gateway_multiple_interface_data(name, + dev_name) + data = self._get_l2_gw_multiple_interface_partial_seg_id_data(name, + dev_name) + gw_org = self._create_l2gateway(data_orig) + l2gw_id = gw_org['id'] + self.assertRaises(exceptions.L2GatewaySegmentationRequired, + self._validate_l2_gateway_for_update, l2gw_id, data) + + def test_l2_gateway_update_with_mul_interfaces_without_seg_id(self): + """Test l2 gateway update with multiple interfaces without seg_id.""" + name = "l2gw_1" + dev_name = "device1" + data1 = self._get_l2_gateway_multiple_interface_data( + name, dev_name) + data2 = self._get_l2_gw_multiple_interface_without_seg_id_data( + name, dev_name) + gw_org1 = self._create_l2gateway(data1) + l2gw_id1 = gw_org1['id'] + gw_org2 = self._create_l2gateway(data2) + l2gw_id2 = gw_org2['id'] + self.assertRaises(exceptions.L2GatewaySegmentationIDExists, + self._validate_l2_gateway_for_update, + l2gw_id1, data2) + self.assertRaises(exceptions.L2GatewaySegmentationIDNotExists, + self._validate_l2_gateway_for_update, + l2gw_id2, data1) + def test_l2_gateway_create_with_invalid_seg_id(self): """Test l2 gateway create with invalid seg-id.""" name = "l2gw_1" diff -Nru networking-l2gw-11.0.0/networking_l2gw/tests/unit/services/l2gateway/service_drivers/test_rpc_l2gw.py networking-l2gw-12.0.1/networking_l2gw/tests/unit/services/l2gateway/service_drivers/test_rpc_l2gw.py --- networking-l2gw-11.0.0/networking_l2gw/tests/unit/services/l2gateway/service_drivers/test_rpc_l2gw.py 2017-09-19 05:52:34.000000000 +0000 +++ networking-l2gw-12.0.1/networking_l2gw/tests/unit/services/l2gateway/service_drivers/test_rpc_l2gw.py 2018-02-25 13:35:51.000000000 +0000 @@ -1339,3 +1339,296 @@ self.assertRaises(l2gw_exc.L2GatewayInterfaceNotFound, self.plugin.create_l2_gateway_connection, self.db_context, fake_l2gw_conn_dict) + + def test_validate_gateway_for_update_with_invalid_device(self): + self.db_context = ctx.get_admin_context() + fake_l2gw_dict = {"l2_gateway": {"name": "fake_name", + "devices": + [{"interfaces": + [{"name": "port1", + "segmentation_id": [ + "111"]}], + "device_name": "device_name"}]}} + with mock.patch.object(db, + 'get_physical_switch_by_name', + return_value=None): + self.assertRaises(l2gw_exc.L2GatewayDeviceNotFound, + self.plugin._validate_gateway_for_update, + self.db_context, fake_l2gw_dict) + + def test_validate_gateway_for_update_with_invalid_port(self): + self.db_context = ctx.get_admin_context() + fake_l2gw_dict = {"l2_gateway": {"name": "fake_name", + "devices": + [{"interfaces": + [{"name": "port1", + "segmentation_id": [ + "111"]}], + "device_name": "device_name"}]}} + fake_physical_switch = {'uuid': 'fake_id', + 'name': 'fake_device_name', + 'tunnel_ip': 'fake_tunnel_ip', + 'ovsdb_identifier': 'fake_ovsdb_id', + 'switch_fault_status': None} + with mock.patch.object(db, + 'get_physical_switch_by_name', + return_value=fake_physical_switch), \ + mock.patch.object(db, + 'get_physical_port_by_name_and_ps', + return_value=None): + self.assertRaises(l2gw_exc.L2GatewayPhysicalPortNotFound, + self.plugin._validate_gateway_for_update, + self.db_context, fake_l2gw_dict) + + def test_update_l2_gateway(self): + self.db_context = ctx.get_admin_context() + fake_l2gw_dict = {'id': 'fake_l2gw_id', + 'tenant_id': 'fake_tenant_id', + "name": "fake_l2gw_name", + "devices": + [{"interfaces": [{"name": "port1", + "segmentation_id": ["111"]}], + "device_name": "fake_device_name", + 'id': 'fake_device_id'}]} + fake_l2gw_id = 'fake_l2gw_id' + fake_device_dict = {'devices': + [{'device_name': 'fake_device', + 'interfaces': [{'name': 'fake_interface'}]}]} + fake_device_list = [fake_device_dict] + fake_conn_dict = {'l2_gateway_id': 'fake_l2gw_id', + 'ovsdb_identifier': 'fake_ovsdb_id', + 'network_id': 'fake_network_id'} + fake_conn_list = [fake_conn_dict] + fake_vlan_dict = {'vlan': 100, + 'logical_switch_uuid': 'fake_uuid'} + fake_physical_port = ovsdb_schema.PhysicalPort( + uuid='fake_uuid', + name='fake_interface_name', + phys_switch_id='fake_uuid', + vlan_binding_dicts=None, + port_fault_status=None) + fake_phys_port_dict = fake_physical_port.__dict__ + fake_phys_port_dict['vlan_bindings'] = [fake_vlan_dict] + fake_port_list = [fake_phys_port_dict] + ovsdb_id = 'fake_ovsdb_id' + logical_switch = {'uuid': 'fake_id'} + with mock.patch.object(self.service_plugin, + '_admin_check', + return_value=True) as admin_check, \ + mock.patch.object(self.plugin, + '_validate_gateway_for_update') as validate_gateway, \ + mock.patch.object(self.service_plugin, + 'get_l2gateway_devices_by_gateway_id', + return_value=fake_device_list) as device_list, \ + mock.patch.object(self.service_plugin, + '_get_l2_gateway_connections', + return_value=fake_conn_list) as conn_list, \ + mock.patch.object(self.plugin, + '_process_port_list', + return_value=(ovsdb_id, + logical_switch, + fake_port_list)) as port_list: + self.plugin.update_l2_gateway( + self.db_context, fake_l2gw_id, fake_l2gw_dict) + admin_check.assert_called_with(self.db_context, 'UPDATE') + self.assertTrue(validate_gateway.called) + device_list.assert_called_with(self.db_context, 'fake_l2gw_id') + conn_list.assert_called_with(self.db_context) + port_list.assert_called_with( + self.db_context, fake_device_dict, + fake_conn_dict, "UPDATE") + self.assertEqual(self.plugin.port_dict_before_update, + fake_port_list) + + def test_update_l2_gateway_postcommit_with_add_port(self): + self.db_context = ctx.get_admin_context() + fake_l2gw_dict = {'id': 'fake_l2gw_id', + 'tenant_id': 'fake_tenant_id', + "name": "fake_l2gw_name", + "devices": + [{"interfaces": [{"name": "port1", + "segmentation_id": ["111"]}], + "device_name": "fake_device_name", + 'id': 'fake_device_id'}]} + fake_device_dict = {'devices': [{'device_name': 'fake_device_name', + 'interfaces': [{'name': 'port1'}]}]} + fake_device_list = [fake_device_dict] + fake_conn_dict = {'l2_gateway_id': 'fake_l2gw_id', + 'ovsdb_identifier': 'fake_ovsdb_id', + 'network_id': 'fake_network_id'} + fake_conn_list = [fake_conn_dict] + fake_vlan_dict = {'vlan': 100, + 'logical_switch_uuid': 'fake_ls_id'} + fake_physical_port_1 = ovsdb_schema.PhysicalPort( + uuid='fake_uuid_1', + name='fake_interface_name_1', + phys_switch_id='fake_uuid_1', + vlan_binding_dicts=None, + port_fault_status=None) + fake_physical_port_2 = ovsdb_schema.PhysicalPort( + uuid='fake_uuid_2', + name='fake_interface_name_2', + phys_switch_id='fake_uuid_2', + vlan_binding_dicts=None, + port_fault_status=None) + fake_phys_port_dict_1 = fake_physical_port_1.__dict__ + fake_phys_port_dict_1['vlan_bindings'] = [fake_vlan_dict] + fake_phys_port_dict_2 = fake_physical_port_2.__dict__ + fake_phys_port_dict_2['vlan_bindings'] = [fake_vlan_dict] + fake_port_list_before_update = [fake_phys_port_dict_1] + fake_port_list_after_update = [fake_phys_port_dict_1, + fake_phys_port_dict_2] + port_list_add = [fake_phys_port_dict_2] + fake_port = {'device_owner': 'fake_owner', + 'network_id': 'fake_network_id', + 'mac_address': 'fake_mac', + 'ip_address': 'fake_ip', + 'allowed_address_pairs': [{'ip_address': 'fake_ip', + 'mac_address': 'fake_mac'}]} + fake_port_list = [fake_port] + ovsdb_id = 'fake_ovsdb_id' + logical_switch = {'uuid': 'fake_ls_id'} + fake_ls_dict = {'logical_switch_name': 'fake_network_id', + 'ovsdb_identifier': 'fake_ovsdb_id'} + fake_pl_dict = {'uuid': 'fake_uuid', 'dst_ip': 'fake_ip1', + 'ovsdb_identifier': 'fake_ovsdb_id', + 'macs': [fake_port]} + mac_dict = {'fake_ip1': fake_pl_dict['macs']} + fake_pl_list = [fake_pl_dict] + with mock.patch.object(self.plugin, + 'port_dict_before_update', + fake_port_list_before_update), \ + mock.patch.object(self.service_plugin, + '_admin_check', + return_value=True) as admin_check, \ + mock.patch.object(self.service_plugin, + 'get_l2gateway_devices_by_gateway_id', + return_value=fake_device_list) as device_list, \ + mock.patch.object(self.service_plugin, + '_get_l2_gateway_connections', + return_value=fake_conn_list) as conn_list, \ + mock.patch.object(self.plugin, + '_process_port_list', + return_value=(ovsdb_id, + logical_switch, + fake_port_list_after_update)) as port_list, \ + mock.patch.object(self.plugin, + '_get_logical_switch_dict', + return_value=fake_ls_dict) as get_ls, \ + mock.patch.object(self.plugin, + '_get_port_details', + return_value=fake_port_list) as get_port, \ + mock.patch.object(self.plugin, + '_get_ip_details', + return_value=('fake_ip1', + 'fake_ip2')) as get_ip, \ + mock.patch.object(self.plugin, '_get_dict', + return_value=mock.ANY) as get_dict, \ + mock.patch.object(db, + 'get_ucast_mac_remote_by_mac_and_ls') as get_ucast_mac, \ + mock.patch.object(self.plugin, + '_get_locator_list', + return_value=fake_pl_list) as get_pl, \ + mock.patch.object(self.plugin.agent_rpc, + 'update_connection_to_gateway') as update_rpc: + self.plugin.update_l2_gateway_postcommit(self.db_context, + fake_l2gw_dict) + admin_check.assert_called_with(self.db_context, 'UPDATE') + device_list.assert_called_with(self.db_context, 'fake_l2gw_id') + conn_list.assert_called_with(self.db_context) + port_list.assert_called_with( + self.db_context, fake_device_dict, + fake_conn_dict, "UPDATE") + get_ls.assert_called_with(self.db_context, + logical_switch, + fake_conn_dict) + get_port.assert_called_with(self.db_context, 'fake_network_id') + self.assertTrue(get_ip.called) + self.assertTrue(get_dict.called) + self.assertEqual(get_ucast_mac.call_count, 2) + self.assertTrue(get_pl.called) + update_rpc.assert_called_with(self.db_context, ovsdb_id, + fake_ls_dict, fake_pl_list, mac_dict, + port_list_add, 'CREATE') + + def test_update_l2_gateway_postcommit_with_del_port(self): + self.db_context = ctx.get_admin_context() + fake_l2gw_dict = {'id': 'fake_l2gw_id', + 'tenant_id': 'fake_tenant_id', + "name": "fake_l2gw_name", + "devices": + [{"interfaces": [{"name": "port1", + "segmentation_id": ["111"]}], + "device_name": "fake_device_name", + 'id': 'fake_device_id'}]} + fake_device_dict = {'devices': [{'device_name': 'fake_device_name', + 'interfaces': [{'name': 'port1'}]}]} + fake_device_list = [fake_device_dict] + fake_conn_dict = {'l2_gateway_id': 'fake_l2gw_id', + 'ovsdb_identifier': 'fake_ovsdb_id', + 'network_id': 'fake_network_id'} + fake_conn_list = [fake_conn_dict] + fake_vlan_dict = {'vlan': 100, + 'logical_switch_uuid': 'fake_ls_id'} + fake_physical_port_1 = ovsdb_schema.PhysicalPort( + uuid='fake_uuid_1', + name='fake_interface_name_1', + phys_switch_id='fake_uuid_1', + vlan_binding_dicts=None, + port_fault_status=None) + fake_physical_port_2 = ovsdb_schema.PhysicalPort( + uuid='fake_uuid_2', + name='fake_interface_name_2', + phys_switch_id='fake_uuid_2', + vlan_binding_dicts=None, + port_fault_status=None) + fake_phys_port_dict_1 = fake_physical_port_1.__dict__ + fake_phys_port_dict_1['vlan_bindings'] = [fake_vlan_dict] + fake_phys_port_dict_2 = fake_physical_port_2.__dict__ + fake_phys_port_dict_2['vlan_bindings'] = [fake_vlan_dict] + fake_port_list_before_update = [fake_phys_port_dict_1, + fake_phys_port_dict_2] + fake_port_list_after_update = [fake_phys_port_dict_1] + port_list_del = [fake_phys_port_dict_2] + ovsdb_id = 'fake_ovsdb_id' + logical_switch = {'uuid': 'fake_ls_id'} + fake_ls_dict = {'logical_switch_name': 'fake_network_id', + 'ovsdb_identifier': 'fake_ovsdb_id'} + mac_dict = {} + fake_pl_list = [] + with mock.patch.object(self.plugin, + 'port_dict_before_update', + fake_port_list_before_update), \ + mock.patch.object(self.service_plugin, + '_admin_check', + return_value=True) as admin_check, \ + mock.patch.object(self.service_plugin, + 'get_l2gateway_devices_by_gateway_id', + return_value=fake_device_list) as device_list, \ + mock.patch.object(self.service_plugin, + '_get_l2_gateway_connections', + return_value=fake_conn_list) as conn_list, \ + mock.patch.object(self.plugin, + '_process_port_list', + return_value=(ovsdb_id, + logical_switch, + fake_port_list_after_update)) as port_list, \ + mock.patch.object(self.plugin, + '_get_logical_switch_dict', + return_value=fake_ls_dict) as get_ls, \ + mock.patch.object(self.plugin.agent_rpc, + 'update_connection_to_gateway') as update_rpc: + self.plugin.update_l2_gateway_postcommit(self.db_context, + fake_l2gw_dict) + admin_check.assert_called_with(self.db_context, 'UPDATE') + device_list.assert_called_with(self.db_context, 'fake_l2gw_id') + conn_list.assert_called_with(self.db_context) + port_list.assert_called_with( + self.db_context, fake_device_dict, + fake_conn_dict, "UPDATE") + get_ls.assert_called_with(self.db_context, + logical_switch, + fake_conn_dict) + update_rpc.assert_called_with(self.db_context, ovsdb_id, + fake_ls_dict, fake_pl_list, mac_dict, + port_list_del, 'DELETE') diff -Nru networking-l2gw-11.0.0/networking_l2gw/tests/unit/services/l2gateway/test_agent_scheduler.py networking-l2gw-12.0.1/networking_l2gw/tests/unit/services/l2gateway/test_agent_scheduler.py --- networking-l2gw-11.0.0/networking_l2gw/tests/unit/services/l2gateway/test_agent_scheduler.py 2017-09-19 05:52:34.000000000 +0000 +++ networking-l2gw-12.0.1/networking_l2gw/tests/unit/services/l2gateway/test_agent_scheduler.py 2018-02-25 13:35:51.000000000 +0000 @@ -22,6 +22,7 @@ from oslo_service import loopingcall from oslo_utils import timeutils +from neutron.agent.common import utils from neutron.common import topics from neutron.db import agents_db from neutron import manager @@ -148,7 +149,7 @@ mock.patch.object( self.plugin, 'get_agents', return_value=fake_all_agent_list) as get_agent_list, \ - mock.patch.object(self.agentsch, 'is_agent_down', + mock.patch.object(utils, 'is_agent_down', return_value=False) as is_agt: self.agentsch.monitor_agent_state() self.assertTrue(get_agent_list.called) diff -Nru networking-l2gw-11.0.0/networking_l2gw.egg-info/entry_points.txt networking-l2gw-12.0.1/networking_l2gw.egg-info/entry_points.txt --- networking-l2gw-11.0.0/networking_l2gw.egg-info/entry_points.txt 2017-09-19 05:57:23.000000000 +0000 +++ networking-l2gw-12.0.1/networking_l2gw.egg-info/entry_points.txt 2018-02-25 13:39:46.000000000 +0000 @@ -4,10 +4,10 @@ [neutron.db.alembic_migrations] networking-l2gw = networking_l2gw.db.migration:alembic_migrations +[neutron.service_plugins] +l2gw = networking_l2gw.services.l2gateway.plugin:L2GatewayPlugin + [neutronclient.extension] l2_gateway = networking_l2gw.l2gatewayclient.l2gw_client_ext._l2_gateway l2_gateway_connection = networking_l2gw.l2gatewayclient.l2gw_client_ext._l2_gateway_connection -[tempest.test_plugins] -networking_l2gw = networking_l2gw.tests.tempest.plugin:NeutronL2gwTempestPlugin - diff -Nru networking-l2gw-11.0.0/networking_l2gw.egg-info/pbr.json networking-l2gw-12.0.1/networking_l2gw.egg-info/pbr.json --- networking-l2gw-11.0.0/networking_l2gw.egg-info/pbr.json 2017-09-19 05:57:24.000000000 +0000 +++ networking-l2gw-12.0.1/networking_l2gw.egg-info/pbr.json 2018-02-25 13:39:46.000000000 +0000 @@ -1 +1 @@ -{"git_version": "a8ae0e3", "is_release": true} \ No newline at end of file +{"git_version": "32631dc", "is_release": true} \ No newline at end of file diff -Nru networking-l2gw-11.0.0/networking_l2gw.egg-info/PKG-INFO networking-l2gw-12.0.1/networking_l2gw.egg-info/PKG-INFO --- networking-l2gw-11.0.0/networking_l2gw.egg-info/PKG-INFO 2017-09-19 05:57:23.000000000 +0000 +++ networking-l2gw-12.0.1/networking_l2gw.egg-info/PKG-INFO 2018-02-25 13:39:46.000000000 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: networking-l2gw -Version: 11.0.0 +Version: 12.0.1 Summary: API's and implementations to support L2 Gateways in Neutron. Home-page: https://git.openstack.org/cgit/openstack/networking-l2gw Author: OpenStack @@ -46,7 +46,86 @@ Getting started --------------- - * TODO + To get started you have to install the l2gw plugin software on the Controller + node where you are already running the Neutron server. Then you need a new + node, that we call the l2gw node, where you do the actual bridging between a + vxlan tenant network and a physical network. The l2gw node could be a bare + metal switch that supports the OVSDB schema, or a server with OVS installed. In + this example we are going to use a server. + + In this example the l2gw node has a `ens5` interface attached to a physical + segment, and a management interface with IP 10.225.0.27. + + :: + + ip link set up dev ens5 + apt-get install openvswitch-vtep + ovsdb-tool create /etc/openvswitch/vtep.db /usr/share/openvswitch/vtep.ovsschema + ovsdb-tool create /etc/openvswitch/vswitch.db /usr/share/openvswitch/vswitch.ovsschema + ovsdb-server --pidfile --detach --log-file --remote ptcp:6632:10.225.0.27 \ + --remote punix:/var/run/openvswitch/db.sock --remote=db:hardware_vtep,Global,managers \ + /etc/openvswitch/vswitch.db /etc/openvswitch/vtep.db + ovs-vswitchd --log-file --detach --pidfile unix:/var/run/openvswitch/db.sock + ovs-vsctl add-br myphyswitch + vtep-ctl add-ps myphyswitch + vtep-ctl set Physical_Switch myphyswitch tunnel_ips=10.225.0.27 + ovs-vsctl add-port myphyswitch ens5 + vtep-ctl add-port myphyswitch ens5 + /usr/share/openvswitch/scripts/ovs-vtep \ + --log-file=/var/log/openvswitch/ovs-vtep.log \ + --pidfile=/var/run/openvswitch/ovs-vtep.pid \ + --detach myphyswitch + + At this point your l2gw node is running. + + For the configuration of the Openstack control plane you have to check three files: + ``neutron.conf``, `l2gw_plugin.ini `__, and `l2gateway_agent.ini `__ + Edit your ``neutron.conf`` on the controller node and make sure that in the ``service_plugins`` you have the string + ``networking_l2gw.services.l2gateway.plugin.L2GatewayPlugin``. + + You can add it with: + :: + + sudo sed -ri 's/^(service_plugins.*)/\1,networking_l2gw.services.l2gateway.plugin.L2GatewayPlugin/' \ + /etc/neutron/neutron.conf + + Make sure the neutron-server runs with ``--config-file=/etc/neutron/l2gw_plugin.ini``. + The default for the l2gw_plugin.ini file should be okay. + + Now you are ready to create the database tables for the neutron l2gw plugin using the command: + ``neutron-db-manage upgrade heads`` + + The file `l2gateway_agent.ini `__ is used to configure the neutron-l2gateway agent. + The agent is the piece of software that will configure the l2gw node when you interact with the Openstack API. + Here it is important to give the pointer to the switch. + ``ovsdb_hosts = 'ovsdb1:10.225.0.27:6632'`` + + The name ``ovsdb1`` is just a name that will be used in the Openstack database to identify this switch. + + Now that both the l2gw node and the Openstack control plane are configured, we can use the API service to bridge a VXLAN tenant network to a physical interface of the l2gw node. + + First let's create in Openstack a l2-gateway object. We need to give the interface names and the name of the bridge that we used before in the OVS commands. + + ``l2-gateway-create --device name="myphyswitch",interface_names="ens5" openstackname`` + + Use the just created to feed the second command where you do the actual bridging between the VXLAN tenant network and the Physical L2 network. + + ``l2-gateway-connection-create `` + + Now let's see what happened. On the l2gw node you can do the commands: + :: + + ovs-vsctl show + vtep-ctl show + + You should see some VXLAN tunnels are created. You will see a vxlan tunnel to each compute node that is hosting an + instance attached to the tenant network that you bridge. If there is also a router in this tenant network, + you will find a VXLAN tunnel also to the network node. + + References: + * http://networkop.co.uk/blog/2016/05/21/neutron-l2gw/ + * http://kimizhang.com/neutron-l2-gateway-hp-5930-switch-ovsdb-integration/ + * http://openvswitch.org/support/dist-docs-2.5/vtep/README.ovs-vtep.md.html Platform: UNKNOWN diff -Nru networking-l2gw-11.0.0/networking_l2gw.egg-info/requires.txt networking-l2gw-12.0.1/networking_l2gw.egg-info/requires.txt --- networking-l2gw-11.0.0/networking_l2gw.egg-info/requires.txt 2017-09-19 05:57:23.000000000 +0000 +++ networking-l2gw-12.0.1/networking_l2gw.egg-info/requires.txt 2018-02-25 13:39:46.000000000 +0000 @@ -1,5 +1,5 @@ pbr!=2.1.0,>=2.0.0 Babel!=2.4.0,>=2.3.4 -neutron-lib>=1.9.0 +neutron-lib>=1.13.0 python-neutronclient>=6.3.0 -ovsdbapp>=0.4.0 +ovsdbapp>=0.8.0 diff -Nru networking-l2gw-11.0.0/networking_l2gw.egg-info/SOURCES.txt networking-l2gw-12.0.1/networking_l2gw.egg-info/SOURCES.txt --- networking-l2gw-11.0.0/networking_l2gw.egg-info/SOURCES.txt 2017-09-19 05:57:25.000000000 +0000 +++ networking-l2gw-12.0.1/networking_l2gw.egg-info/SOURCES.txt 2018-02-25 13:39:48.000000000 +0000 @@ -1,5 +1,6 @@ .coveragerc .testr.conf +.zuul.yaml AUTHORS CONTRIBUTING.rst ChangeLog @@ -120,21 +121,8 @@ networking_l2gw/services/l2gateway/service_drivers/agent_api.py networking_l2gw/services/l2gateway/service_drivers/rpc_l2gw.py networking_l2gw/tests/__init__.py -networking_l2gw/tests/api/__init__.py -networking_l2gw/tests/api/base_l2gw.py -networking_l2gw/tests/api/test_l2gw_extensions.py -networking_l2gw/tests/api/test_l2gw_negative.py networking_l2gw/tests/contrib/gate_hook.sh networking_l2gw/tests/contrib/post_test_hook.sh -networking_l2gw/tests/fullstack/__init__.py -networking_l2gw/tests/fullstack/test_l2gw.py -networking_l2gw/tests/scenario/__init__.py -networking_l2gw/tests/scenario/ovsdb_connections.py -networking_l2gw/tests/scenario/test_l2gateways.py -networking_l2gw/tests/tempest/__init__.py -networking_l2gw/tests/tempest/config.py -networking_l2gw/tests/tempest/plugin.py -networking_l2gw/tests/tempest/etc/tempest.conf.sample networking_l2gw/tests/unit/__init__.py networking_l2gw/tests/unit/db/__init__.py networking_l2gw/tests/unit/db/test_l2gw_db.py diff -Nru networking-l2gw-11.0.0/PKG-INFO networking-l2gw-12.0.1/PKG-INFO --- networking-l2gw-11.0.0/PKG-INFO 2017-09-19 05:57:25.000000000 +0000 +++ networking-l2gw-12.0.1/PKG-INFO 2018-02-25 13:39:48.000000000 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: networking-l2gw -Version: 11.0.0 +Version: 12.0.1 Summary: API's and implementations to support L2 Gateways in Neutron. Home-page: https://git.openstack.org/cgit/openstack/networking-l2gw Author: OpenStack @@ -46,7 +46,86 @@ Getting started --------------- - * TODO + To get started you have to install the l2gw plugin software on the Controller + node where you are already running the Neutron server. Then you need a new + node, that we call the l2gw node, where you do the actual bridging between a + vxlan tenant network and a physical network. The l2gw node could be a bare + metal switch that supports the OVSDB schema, or a server with OVS installed. In + this example we are going to use a server. + + In this example the l2gw node has a `ens5` interface attached to a physical + segment, and a management interface with IP 10.225.0.27. + + :: + + ip link set up dev ens5 + apt-get install openvswitch-vtep + ovsdb-tool create /etc/openvswitch/vtep.db /usr/share/openvswitch/vtep.ovsschema + ovsdb-tool create /etc/openvswitch/vswitch.db /usr/share/openvswitch/vswitch.ovsschema + ovsdb-server --pidfile --detach --log-file --remote ptcp:6632:10.225.0.27 \ + --remote punix:/var/run/openvswitch/db.sock --remote=db:hardware_vtep,Global,managers \ + /etc/openvswitch/vswitch.db /etc/openvswitch/vtep.db + ovs-vswitchd --log-file --detach --pidfile unix:/var/run/openvswitch/db.sock + ovs-vsctl add-br myphyswitch + vtep-ctl add-ps myphyswitch + vtep-ctl set Physical_Switch myphyswitch tunnel_ips=10.225.0.27 + ovs-vsctl add-port myphyswitch ens5 + vtep-ctl add-port myphyswitch ens5 + /usr/share/openvswitch/scripts/ovs-vtep \ + --log-file=/var/log/openvswitch/ovs-vtep.log \ + --pidfile=/var/run/openvswitch/ovs-vtep.pid \ + --detach myphyswitch + + At this point your l2gw node is running. + + For the configuration of the Openstack control plane you have to check three files: + ``neutron.conf``, `l2gw_plugin.ini `__, and `l2gateway_agent.ini `__ + Edit your ``neutron.conf`` on the controller node and make sure that in the ``service_plugins`` you have the string + ``networking_l2gw.services.l2gateway.plugin.L2GatewayPlugin``. + + You can add it with: + :: + + sudo sed -ri 's/^(service_plugins.*)/\1,networking_l2gw.services.l2gateway.plugin.L2GatewayPlugin/' \ + /etc/neutron/neutron.conf + + Make sure the neutron-server runs with ``--config-file=/etc/neutron/l2gw_plugin.ini``. + The default for the l2gw_plugin.ini file should be okay. + + Now you are ready to create the database tables for the neutron l2gw plugin using the command: + ``neutron-db-manage upgrade heads`` + + The file `l2gateway_agent.ini `__ is used to configure the neutron-l2gateway agent. + The agent is the piece of software that will configure the l2gw node when you interact with the Openstack API. + Here it is important to give the pointer to the switch. + ``ovsdb_hosts = 'ovsdb1:10.225.0.27:6632'`` + + The name ``ovsdb1`` is just a name that will be used in the Openstack database to identify this switch. + + Now that both the l2gw node and the Openstack control plane are configured, we can use the API service to bridge a VXLAN tenant network to a physical interface of the l2gw node. + + First let's create in Openstack a l2-gateway object. We need to give the interface names and the name of the bridge that we used before in the OVS commands. + + ``l2-gateway-create --device name="myphyswitch",interface_names="ens5" openstackname`` + + Use the just created to feed the second command where you do the actual bridging between the VXLAN tenant network and the Physical L2 network. + + ``l2-gateway-connection-create `` + + Now let's see what happened. On the l2gw node you can do the commands: + :: + + ovs-vsctl show + vtep-ctl show + + You should see some VXLAN tunnels are created. You will see a vxlan tunnel to each compute node that is hosting an + instance attached to the tenant network that you bridge. If there is also a router in this tenant network, + you will find a VXLAN tunnel also to the network node. + + References: + * http://networkop.co.uk/blog/2016/05/21/neutron-l2gw/ + * http://kimizhang.com/neutron-l2-gateway-hp-5930-switch-ovsdb-integration/ + * http://openvswitch.org/support/dist-docs-2.5/vtep/README.ovs-vtep.md.html Platform: UNKNOWN diff -Nru networking-l2gw-11.0.0/README.rst networking-l2gw-12.0.1/README.rst --- networking-l2gw-11.0.0/README.rst 2017-09-19 05:52:34.000000000 +0000 +++ networking-l2gw-12.0.1/README.rst 2018-02-25 13:35:51.000000000 +0000 @@ -37,4 +37,83 @@ Getting started --------------- -* TODO +To get started you have to install the l2gw plugin software on the Controller +node where you are already running the Neutron server. Then you need a new +node, that we call the l2gw node, where you do the actual bridging between a +vxlan tenant network and a physical network. The l2gw node could be a bare +metal switch that supports the OVSDB schema, or a server with OVS installed. In +this example we are going to use a server. + +In this example the l2gw node has a `ens5` interface attached to a physical +segment, and a management interface with IP 10.225.0.27. + +:: + + ip link set up dev ens5 + apt-get install openvswitch-vtep + ovsdb-tool create /etc/openvswitch/vtep.db /usr/share/openvswitch/vtep.ovsschema + ovsdb-tool create /etc/openvswitch/vswitch.db /usr/share/openvswitch/vswitch.ovsschema + ovsdb-server --pidfile --detach --log-file --remote ptcp:6632:10.225.0.27 \ + --remote punix:/var/run/openvswitch/db.sock --remote=db:hardware_vtep,Global,managers \ + /etc/openvswitch/vswitch.db /etc/openvswitch/vtep.db + ovs-vswitchd --log-file --detach --pidfile unix:/var/run/openvswitch/db.sock + ovs-vsctl add-br myphyswitch + vtep-ctl add-ps myphyswitch + vtep-ctl set Physical_Switch myphyswitch tunnel_ips=10.225.0.27 + ovs-vsctl add-port myphyswitch ens5 + vtep-ctl add-port myphyswitch ens5 + /usr/share/openvswitch/scripts/ovs-vtep \ + --log-file=/var/log/openvswitch/ovs-vtep.log \ + --pidfile=/var/run/openvswitch/ovs-vtep.pid \ + --detach myphyswitch + +At this point your l2gw node is running. + +For the configuration of the Openstack control plane you have to check three files: +``neutron.conf``, `l2gw_plugin.ini `__, and `l2gateway_agent.ini `__ +Edit your ``neutron.conf`` on the controller node and make sure that in the ``service_plugins`` you have the string +``networking_l2gw.services.l2gateway.plugin.L2GatewayPlugin``. + +You can add it with: +:: + + sudo sed -ri 's/^(service_plugins.*)/\1,networking_l2gw.services.l2gateway.plugin.L2GatewayPlugin/' \ + /etc/neutron/neutron.conf + +Make sure the neutron-server runs with ``--config-file=/etc/neutron/l2gw_plugin.ini``. +The default for the l2gw_plugin.ini file should be okay. + +Now you are ready to create the database tables for the neutron l2gw plugin using the command: +``neutron-db-manage upgrade heads`` + +The file `l2gateway_agent.ini `__ is used to configure the neutron-l2gateway agent. +The agent is the piece of software that will configure the l2gw node when you interact with the Openstack API. +Here it is important to give the pointer to the switch. +``ovsdb_hosts = 'ovsdb1:10.225.0.27:6632'`` + +The name ``ovsdb1`` is just a name that will be used in the Openstack database to identify this switch. + +Now that both the l2gw node and the Openstack control plane are configured, we can use the API service to bridge a VXLAN tenant network to a physical interface of the l2gw node. + +First let's create in Openstack a l2-gateway object. We need to give the interface names and the name of the bridge that we used before in the OVS commands. + +``l2-gateway-create --device name="myphyswitch",interface_names="ens5" openstackname`` + +Use the just created to feed the second command where you do the actual bridging between the VXLAN tenant network and the Physical L2 network. + +``l2-gateway-connection-create `` + +Now let's see what happened. On the l2gw node you can do the commands: +:: + + ovs-vsctl show + vtep-ctl show + +You should see some VXLAN tunnels are created. You will see a vxlan tunnel to each compute node that is hosting an +instance attached to the tenant network that you bridge. If there is also a router in this tenant network, +you will find a VXLAN tunnel also to the network node. + +References: + * http://networkop.co.uk/blog/2016/05/21/neutron-l2gw/ + * http://kimizhang.com/neutron-l2-gateway-hp-5930-switch-ovsdb-integration/ + * http://openvswitch.org/support/dist-docs-2.5/vtep/README.ovs-vtep.md.html diff -Nru networking-l2gw-11.0.0/requirements.txt networking-l2gw-12.0.1/requirements.txt --- networking-l2gw-11.0.0/requirements.txt 2017-09-19 05:52:34.000000000 +0000 +++ networking-l2gw-12.0.1/requirements.txt 2018-02-25 13:36:04.000000000 +0000 @@ -4,6 +4,6 @@ pbr!=2.1.0,>=2.0.0 # Apache-2.0 Babel!=2.4.0,>=2.3.4 # BSD -neutron-lib>=1.9.0 # Apache-2.0 +neutron-lib>=1.13.0 # Apache-2.0 python-neutronclient>=6.3.0 # Apache-2.0 -ovsdbapp>=0.4.0 # Apache-2.0 +ovsdbapp>=0.8.0 # Apache-2.0 diff -Nru networking-l2gw-11.0.0/setup.cfg networking-l2gw-12.0.1/setup.cfg --- networking-l2gw-11.0.0/setup.cfg 2017-09-19 05:57:25.000000000 +0000 +++ networking-l2gw-12.0.1/setup.cfg 2018-02-25 13:39:48.000000000 +0000 @@ -35,8 +35,8 @@ neutronclient.extension = l2_gateway_connection = networking_l2gw.l2gatewayclient.l2gw_client_ext._l2_gateway_connection l2_gateway = networking_l2gw.l2gatewayclient.l2gw_client_ext._l2_gateway -tempest.test_plugins = - networking_l2gw = networking_l2gw.tests.tempest.plugin:NeutronL2gwTempestPlugin +neutron.service_plugins = + l2gw = networking_l2gw.services.l2gateway.plugin:L2GatewayPlugin [build_sphinx] source-dir = doc/source diff -Nru networking-l2gw-11.0.0/test-requirements.txt networking-l2gw-12.0.1/test-requirements.txt --- networking-l2gw-11.0.0/test-requirements.txt 2017-09-19 05:52:35.000000000 +0000 +++ networking-l2gw-12.0.1/test-requirements.txt 2018-02-25 13:35:51.000000000 +0000 @@ -6,16 +6,16 @@ coverage!=4.4,>=4.0 # Apache-2.0 flake8-import-order==0.12 # LGPLv3 -python-subunit>=0.0.18 # Apache-2.0/BSD -sphinx>=1.6.2 # BSD -psycopg2>=2.5 # LGPL/ZPL +python-subunit>=1.0.0 # Apache-2.0/BSD +sphinx!=1.6.6,>=1.6.2 # BSD +psycopg2>=2.6.2 # LGPL/ZPL PyMySQL>=0.7.6 # MIT License oslosphinx>=4.7.0 # Apache-2.0 -oslotest>=1.10.0 # Apache-2.0 +oslotest>=3.2.0 # Apache-2.0 +os-testr>=1.0.0 # Apache-2.0 testrepository>=0.0.18 # Apache-2.0/BSD -testresources>=0.2.4 # Apache-2.0/BSD +testresources>=2.0.0 # Apache-2.0/BSD testscenarios>=0.4 # Apache-2.0/BSD -testtools>=1.4.0 # MIT -tempest>=16.1.0 # Apache-2.0 -mock>=2.0 # BSD +testtools>=2.2.0 # MIT +mock>=2.0.0 # BSD ddt>=1.0.1 # MIT diff -Nru networking-l2gw-11.0.0/tools/tox_install.sh networking-l2gw-12.0.1/tools/tox_install.sh --- networking-l2gw-11.0.0/tools/tox_install.sh 2017-09-19 05:52:34.000000000 +0000 +++ networking-l2gw-12.0.1/tools/tox_install.sh 2018-02-25 13:36:04.000000000 +0000 @@ -18,7 +18,7 @@ ZUUL_CLONER=/usr/zuul-env/bin/zuul-cloner neutron_installed=$(echo "import neutron" | python 2>/dev/null ; echo $?) NEUTRON_DIR=$HOME/neutron -BRANCH_NAME=master +BRANCH_NAME=stable/queens set -e diff -Nru networking-l2gw-11.0.0/tox.ini networking-l2gw-12.0.1/tox.ini --- networking-l2gw-11.0.0/tox.ini 2017-09-19 05:52:34.000000000 +0000 +++ networking-l2gw-12.0.1/tox.ini 2018-02-25 13:36:04.000000000 +0000 @@ -8,7 +8,7 @@ VIRTUAL_ENV={envdir} PYTHONWARNINGS=default::DeprecationWarning usedevelop = True -install_command = {toxinidir}/tools/tox_install.sh {env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} {opts} {packages} +install_command = {toxinidir}/tools/tox_install.sh {env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=stable/queens} {opts} {packages} deps = -r{toxinidir}/requirements.txt -r{toxinidir}/test-requirements.txt whitelist_externals = * @@ -16,10 +16,6 @@ find . -type f -name "*.py[c|o]" -delete bash tools/pretty_tox_serial.sh '{posargs}' -[testenv:fullstack] -basepython = python2.7 -setenv = OS_TEST_PATH=./networking_l2gw/tests/fullstack - [testenv:pep8] commands = flake8 @@ -48,17 +44,5 @@ exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build,.tmp import-order-style = pep8 -[testenv:api] -setenv = - {[testenv]setenv} - OS_TEST_PATH=./networking_l2gw/tests/api - TEMPEST_CONFIG_DIR={env:TEMPEST_CONFIG_DIR:/opt/stack/tempest/etc} - OS_TEST_API_WITH_REST=1 - OS_TEST_TIMEOUT=90 -deps = {[testenv]deps} -commands = - find . -type f -name "*.py[c|o]" -delete - tempest run --serial {posargs} - [hacking] import_exceptions = networking_l2gw._i18n diff -Nru networking-l2gw-11.0.0/.zuul.yaml networking-l2gw-12.0.1/.zuul.yaml --- networking-l2gw-11.0.0/.zuul.yaml 1970-01-01 00:00:00.000000000 +0000 +++ networking-l2gw-12.0.1/.zuul.yaml 2018-02-25 13:36:04.000000000 +0000 @@ -0,0 +1,8 @@ +- project: + name: openstack/networking-l2gw + check: + jobs: + - networking-l2gw-tempest-dummy + gate: + jobs: + - networking-l2gw-tempest-dummy