diff --git a/.stestr.conf b/.stestr.conf deleted file mode 100644 index 391c451..0000000 --- a/.stestr.conf +++ /dev/null @@ -1,3 +0,0 @@ -[DEFAULT] -test_path=${OS_TEST_PATH:-./neutron_taas/tests/unit} -top_dir=./ diff --git a/.testr.conf b/.testr.conf deleted file mode 100644 index d56c478..0000000 --- a/.testr.conf +++ /dev/null @@ -1,7 +0,0 @@ -[DEFAULT] -test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \ - OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \ - OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \ - ${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./neutron_taas/tests/unit} $LISTOPT $IDOPTION -test_id_option=--load-list $IDFILE -test_list_option=--list diff --git a/.zuul.yaml b/.zuul.yaml index aaa655e..e1dd96b 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -1,27 +1,4 @@ - project: - check: - jobs: - - tap-as-a-service-tempest-dsvm - - openstack-tox-lower-constraints - gate: - jobs: - - tap-as-a-service-tempest-dsvm - - - openstack-tox-lower-constraints -- job: - name: tap-as-a-service-tempest-dsvm - parent: legacy-dsvm-base - run: playbooks/legacy/tempest-dsvm-tap-as-a-service/run.yaml - post-run: playbooks/legacy/tempest-dsvm-tap-as-a-service/post.yaml - timeout: 7800 - required-projects: - - openstack-infra/devstack-gate - - openstack/tap-as-a-service - - openstack/tempest - irrelevant-files: - - ^(test-|)requirements.txt$ - - ^.*\.rst$ - - ^doc/.*$ - - ^neutron_taas/tests/unit/.*$ - - ^setup.cfg$ - - ^specs/.*$ + templates: + - check-requirements + - tempest-plugin-jobs diff --git a/API_REFERENCE.rst b/API_REFERENCE.rst deleted file mode 100644 index ac2826e..0000000 --- a/API_REFERENCE.rst +++ /dev/null @@ -1,277 +0,0 @@ -============================== -Tap as a Service API REFERENCE -============================== - -This documents is an API REFERENCE for Tap-as-a-Service Neutron extension. - -The documents is organized into the following sections: -* TaaS Resources -* API Reference -* TaaS CLI Reference -* Workflow - -TaaS Resources -============== - -TaaS consists of two resources, TapService and TapFlow. - -TapService ----------- - -TapService Represents the port on which the mirrored traffic is delivered. -Any service (VM) that uses the mirrored data is attached to the port. - -.. code-block:: python - - 'tap_services': { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid': None}, 'is_visible': True, - 'primary_key': True}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'required_by_policy': True, 'is_visible': True}, - 'name': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'description': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'port_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True}, - } - -TapFlow -------- - -TapFlow Represents the port from which the traffic needs to be mirrored. - -.. code-block:: python - - 'tap_flows': { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid': None}, 'is_visible': True, - 'primary_key': True}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'required_by_policy': True, 'is_visible': True}, - 'name': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'description': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'tap_service_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'required_by_policy': True, 'is_visible': True}, - 'source_port': {'allow_post': True, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'required_by_policy': True, 'is_visible': True}, - 'direction': {'allow_post': True, 'allow_put': False, - 'validate': {'type:values': direction_enum}, - 'is_visible': True} - } - - direction_enum = ['IN', 'OUT', 'BOTH'] - - -Multiple TapFlow instances can be associated with a single TapService -instance. - -API REFERENCE -============= - -Below is the list of REST APIs that can be used to interact with TaaS Neutron -extension - -1. Create TapService - -\ - - **POST /v2.0/taas/tap_services** - -\ - - Json Request: - -.. code-block:: python - - { - "tap_service": { - "description": "Test_Tap", - "name": "Test", - "port_id": "c9beb5a1-21f5-4225-9eaf-02ddccdd50a9", - "tenant_id": "97e1586d580745d7b311406697aaf097" - } - } - -\ - - Json Response: - -.. code-block:: python - - { - "tap_service": { - "description": "Test_Tap", - "id": "c352f537-ad49-48eb-ab05-1c6b8cb900ff", - "name": "Test", - "port_id": "c9beb5a1-21f5-4225-9eaf-02ddccdd50a9", - "tenant_id": "97e1586d580745d7b311406697aaf097" - } - } - -2. List TapServices - -\ - - **GET /v2.0/taas/tap_services/{tap_service_uuid}** - -\ - - Json Response: - -.. code-block:: python - - { - "tap_services": [ - { - "description": "Test_Tap", - "id": "c352f537-ad49-48eb-ab05-1c6b8cb900ff", - "name": "Test", - "port_id": "c9beb5a1-21f5-4225-9eaf-02ddccdd50a9", - "tenant_id": "97e1586d580745d7b311406697aaf097" - } - ] - } - -3. Delete TapService - -\ - - **DELETE /v2.0/taas/tap_services/{tap_service_uuid}** - -\ - -4. Create TapFlow - -\ - - **POST /v2.0/taas/tap_flows** - -\ - - Json Request: - -.. code-block:: python - - { - "tap_flow": { - "description": "Test_flow1", - "direction": "BOTH", - "name": "flow1", - "source_port": "775a58bb-e2c6-4529-a918-2f019169b5b1", - "tap_service_id": "69bd12b2-0e13-45ec-9045-b674fd9f0468", - "tenant_id": "97e1586d580745d7b311406697aaf097" - } - } - -\ - - Json Response: - -.. code-block:: python - - { - "tap_flow": { - "description": "Test_flow1", - "direction": "BOTH", - "id": "cc47f881-345f-4e62-ad24-bea79eb28304", - "name": "flow1", - "source_port": "775a58bb-e2c6-4529-a918-2f019169b5b1", - "tap_service_id": "69bd12b2-0e13-45ec-9045-b674fd9f0468", - "tenant_id": "97e1586d580745d7b311406697aaf097" - } - } - -5. List TapFlows - -\ - - **GET /v2.0/taas/tap_flows/{tap_flow_uuid}** - -\ - - Json Response: - -.. code-block:: python - - { - "tap_flows": [ - { - "description": "Test_flow1", - "direction": "BOTH", - "id": "cc47f881-345f-4e62-ad24-bea79eb28304", - "name": "flow1", - "source_port": "775a58bb-e2c6-4529-a918-2f019169b5b1", - "tap_service_id": "c352f537-ad49-48eb-ab05-1c6b8cb900ff", - "tenant_id": "97e1586d580745d7b311406697aaf097" - } - ] - } - -6. Delete TapFlow - -\ - - **DELETE /v2.0/taas/tap_flows/{tap_flow_uuid}** - -\ - -TaaS CLI Reference -================== -The TaaS commands can be executed using TaaS CLI, which is integrated with neutron. -It can be used to send REST request and interact with the TaaS -extension. Given below are the detail of the CLIs: - -- **neutron tap-service-create**: Creates a Tap service. -- **neutron tap-service-list**: Lists all the Tap services. -- **neutron tap-service-show**: Show the details for a Tap service. -- **neutron tap-service-update**: Update the information for a Tap service. -- **neutron tap-service-delete**: Delete an existing Tap service. -- **neutron tap-flow-create**: Creates a Tap flow. -- **neutron tap-flow-list**: Lists all the Tap flows. -- **neutron tap-flow-show**: Show the details for a Tap flow. -- **neutron tap-flow-update**: Update the information for a Tap flow. -- **neutron tap-flow-delete**: Delete an existing Tap flow. - -For usage type **--help** after any of the above commands -in the terminal after TaaS has been installed. - -Workflow -========= - -In this section we describe a simple sequence of steps to use TaaS. - -Workflow Sequence ------------------- - -1. Create a Neutron port with 'port_security_enabled' set to 'false'. - -2. Launch a VM (VM on which you want to monitor/receive the mirrored data). - Associate the Neutron port created in step 1 while creating the VM. - -3. Using Neutron Client command for TaaS **neutron tap-service-create** or - via REST APIs create a Tap Service instance by associating the port - created in step 1. - -4. Using Neutron Client command for TaaS **neutron tap-flow-create** or - via REST APIs create a Tap Flow instance by associating the Tap Service - instance created in step 3 and the target Neutron port from which you want - to mirror traffic (assuming the Neutron port from which the traffic - needs to be monitored already exists.) - Mirroring can be done for both incoming and/or outgoing traffic from the - target Neutron port. - -5. Observe the mirrored traffic on the monitoring VM by running tools such as - tcpdump. diff --git a/HACKING.rst b/HACKING.rst deleted file mode 100644 index 744808a..0000000 --- a/HACKING.rst +++ /dev/null @@ -1,4 +0,0 @@ -tap-as-a-service Style Commandments -=============================================== - -Read the OpenStack Style Commandments https://docs.openstack.org/hacking/latest/ diff --git a/INSTALL.rst b/INSTALL.rst deleted file mode 100644 index a830482..0000000 --- a/INSTALL.rst +++ /dev/null @@ -1,29 +0,0 @@ -=================================== -Tap as a Service installation guide -=================================== - -This is the installation guide for enabling Tap-as-a-Service(TaaS) feature in -OpenStack Neutron - -We have tested TaaS with latest version DevStack running on Ubuntu 12.04 and -14.04. TaaS is currently under active development and we will update you of -new features and capabilities as and when they become available. Feel free to -approach us with any issues related to installing or using TaaS. - -Dependencies -============ - -TaaS requires the 'Port Security' Neutron ML2 extension. Please make sure that -this extension has been enabled. - -Adding the following to 'local.conf' while installing DevStack will enable -'Port Security' extension. (It's enabled by default) - - Q_ML2_PLUGIN_EXT_DRIVERS=port_security - - -Installation -============ - -You can use DevStack external plugin. -See `devstack/README.rst`. diff --git a/README.rst b/README.rst index dc6276a..b621a34 100644 --- a/README.rst +++ b/README.rst @@ -1,24 +1,5 @@ -================ -Tap as a Service -================ -Tap-as-a-Service (TaaS) is an extension to the OpenStack network service (Neutron). -It provides remote port mirroring capability for tenant virtual networks. +=================================== +Tempest plugin for Tap as a Service +=================================== -Port mirroring involves sending a copy of packets entering and/or leaving one -port to another port, which is usually different from the original destinations -of the packets being mirrored. - - -This service has been primarily designed to help tenants (or the cloud administrator) -debug complex virtual networks and gain visibility into their VMs, by monitoring the -network traffic associated with them. TaaS honors tenant boundaries and its mirror -sessions are capable of spanning across multiple compute and network nodes. It serves -as an essential infrastructure component that can be utilized for supplying data to a -variety of network analytics and security applications (e.g. IDS). - -* Free software: Apache license -* API Reference: https://github.com/openstack/tap-as-a-service/blob/master/API_REFERENCE.rst -* Source: https://git.openstack.org/cgit/openstack/tap-as-a-service -* Bugs: https://bugs.launchpad.net/tap-as-a-service - -For installing Tap-as-a-Service with Devstack please read the INSTALL.rst file +This repository contains tempest plugin for tap-as-a-service. diff --git a/babel.cfg b/babel.cfg deleted file mode 100644 index 15cd6cb..0000000 --- a/babel.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[python: **.py] - diff --git a/deliverables/queens/tap-as-a-service.yaml b/deliverables/queens/tap-as-a-service.yaml deleted file mode 100644 index c3e0a09..0000000 --- a/deliverables/queens/tap-as-a-service.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -launchpad: tap-as-a-service -type: other -releases: - - projects: - - hash: e528a0ba81f24d0da178bbfac94d517f664aa149 - repo: openstack/tap-as-a-service - version: 3.0.0 -branches: - - name: stable/queens - location: 3.0.0 diff --git a/deliverables/rocky/tap-as-a-service.yaml b/deliverables/rocky/tap-as-a-service.yaml deleted file mode 100644 index 617fcba..0000000 --- a/deliverables/rocky/tap-as-a-service.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -launchpad: tap-as-a-service -type: other -releases: - - projects: - - hash: 57dfbdb8ebbf8d42d0715f7753626ed2ddf38cef - repo: openstack/tap-as-a-service - version: 4.0.0 -branches: - - name: stable/rocky - location: 4.0.0 diff --git a/devstack/README.rst b/devstack/README.rst deleted file mode 100644 index dd31196..0000000 --- a/devstack/README.rst +++ /dev/null @@ -1,10 +0,0 @@ -======================== -DevStack external plugin -======================== - -A `local.conf` recipe to enable tap-as-a-service:: - - [[local|localrc]] - enable_plugin tap-as-a-service https://github.com/openstack/tap-as-a-service - enable_service taas - TAAS_SERVICE_DRIVER=TAAS:TAAS:neutron_taas.services.taas.service_drivers.taas_rpc.TaasRpcDriver:default diff --git a/devstack/devstackgaterc b/devstack/devstackgaterc deleted file mode 100644 index 41dc97c..0000000 --- a/devstack/devstackgaterc +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright 2015 Midokura SARL -# -# 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. - -# -# This script is executed in the OpenStack CI job that runs DevStack + tempest. -# You can find the CI job configuration here: -# -# http://git.openstack.org/cgit/openstack-infra/project-config/tree/jenkins/jobs/tap-as-a-service.yaml -# - -OVERRIDE_ENABLED_SERVICES=key,mysql,rabbit -OVERRIDE_ENABLED_SERVICES+=,g-api,g-reg -OVERRIDE_ENABLED_SERVICES+=,n-api,n-cond,n-cpu,n-crt,n-sch,placement-api -OVERRIDE_ENABLED_SERVICES+=,n-api-meta -OVERRIDE_ENABLED_SERVICES+=,q-agt,q-dhcp,q-l3,q-meta,q-metering,q-svc,quantum -OVERRIDE_ENABLED_SERVICES+=,taas,taas_openvswitch_agent -OVERRIDE_ENABLED_SERVICES+=,tempest,dstat -export OVERRIDE_ENABLED_SERVICES - -# Begin list of exclusions. -r="^(?!.*" - -# exclude the slow tag (part of the default for 'full') -r="$r(?:.*\[.*\bslow\b.*\])" - -# End list of exclusions. -r="$r)" - -r="$r(tempest\.(api.network\.|scenario.test_network)|neutron_taas\.).*$" - -export DEVSTACK_GATE_TEMPEST_REGEX="$r" diff --git a/devstack/plugin.sh b/devstack/plugin.sh deleted file mode 100644 index 993ab59..0000000 --- a/devstack/plugin.sh +++ /dev/null @@ -1,71 +0,0 @@ -#!/bin/bash - -# Copyright 2015 Midokura SARL -# -# 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. - -# This script is meant to be sourced from devstack. It is a wrapper of -# devmido scripts that allows proper exporting of environment variables. - - -function install_taas { - setup_develop $TAAS_PLUGIN_PATH -} - -function configure_taas_plugin { - cp $TAAS_PLUGIN_PATH/etc/taas_plugin.ini $TAAS_PLUGIN_CONF_FILE - neutron_server_config_add $TAAS_PLUGIN_CONF_FILE - neutron_service_plugin_class_add taas -} - -if is_service_enabled taas; then - if [[ "$1" == "stack" ]]; then - if [[ "$2" == "pre-install" ]]; then - : - elif [[ "$2" == "install" ]]; then - install_taas - elif [[ "$2" == "post-config" ]]; then - configure_taas_plugin - neutron-db-manage --subproject tap-as-a-service upgrade head - echo "Configuring taas" - if [ "$TAAS_SERVICE_DRIVER" ]; then - inicomment $TAAS_PLUGIN_CONF_FILE service_providers service_provider - iniadd $TAAS_PLUGIN_CONF_FILE service_providers service_provider $TAAS_SERVICE_DRIVER - fi - elif [[ "$2" == "extra" ]]; then - : - fi - elif [[ "$1" == "unstack" ]]; then - : - fi -fi - -if is_service_enabled q-agt neutron-agent; then - if [[ "$1" == "stack" ]]; then - if [[ "$2" == "pre-install" ]]; then - : - elif [[ "$2" == "install" ]]; then - install_taas - elif [[ "$2" == "post-config" ]]; then - if is_service_enabled q-agt neutron-agent; then - source $NEUTRON_DIR/devstack/lib/l2_agent - plugin_agent_add_l2_agent_extension taas - configure_l2_agent - fi - elif [[ "$2" == "extra" ]]; then - : - fi - elif [[ "$1" == "unstack" ]]; then - : - fi -fi diff --git a/devstack/settings b/devstack/settings deleted file mode 100644 index 12f469b..0000000 --- a/devstack/settings +++ /dev/null @@ -1,6 +0,0 @@ -# Devstack settings -ABSOLUTE_PATH=$(cd `dirname "${BASH_SOURCE[0]}"` && pwd) -TAAS_PLUGIN_PATH=$ABSOLUTE_PATH/.. -TAAS_PLUGIN_CONF_FILE="/etc/neutron/taas_plugin.ini" -TAAS_OVS_AGENT_BINARY="$NEUTRON_BIN_DIR/neutron-taas-openvswitch-agent" -TAAS_OVS_AGENT_CONF_FILE="/etc/neutron/taas.ini" diff --git a/doc/source/api_reference.rst b/doc/source/api_reference.rst deleted file mode 100644 index 19f6e6d..0000000 --- a/doc/source/api_reference.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../../API_REFERENCE.rst diff --git a/doc/source/conf.py b/doc/source/conf.py deleted file mode 100644 index 5d5fd5d..0000000 --- a/doc/source/conf.py +++ /dev/null @@ -1,75 +0,0 @@ -# -*- coding: utf-8 -*- -# 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 sys - -sys.path.insert(0, os.path.abspath('../..')) -# -- General configuration ---------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = [ - 'sphinx.ext.autodoc', - #'sphinx.ext.intersphinx', - 'oslosphinx' -] - -# autodoc generation is a bit aggressive and a nuisance when doing heavy -# text edit cycles. -# execute "export SPHINX_DEBUG=1" in your terminal to disable - -# The suffix of source filenames. -source_suffix = '.rst' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'tap-as-a-service' -copyright = u'2013, OpenStack Foundation' - -# If true, '()' will be appended to :func: etc. cross-reference text. -add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -add_module_names = True - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# -- Options for HTML output -------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. Major themes that come with -# Sphinx are currently 'default' and 'sphinxdoc'. -# html_theme_path = ["."] -# html_theme = '_theme' -# html_static_path = ['static'] - -# Output file base name for HTML help builder. -htmlhelp_basename = '%sdoc' % project - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass -# [howto/manual]). -latex_documents = [ - ('index', - '%s.tex' % project, - u'%s Documentation' % project, - u'OpenStack Foundation', 'manual'), -] - -# Example configuration for intersphinx: refer to the Python standard library. -#intersphinx_mapping = {'http://docs.python.org/': None} diff --git a/doc/source/contributing.rst b/doc/source/contributing.rst deleted file mode 100644 index 1728a61..0000000 --- a/doc/source/contributing.rst +++ /dev/null @@ -1,4 +0,0 @@ -============ -Contributing -============ -.. include:: ../../CONTRIBUTING.rst diff --git a/doc/source/index.rst b/doc/source/index.rst deleted file mode 100644 index 8bd62c9..0000000 --- a/doc/source/index.rst +++ /dev/null @@ -1,27 +0,0 @@ -.. tap-as-a-service documentation master file, created by - sphinx-quickstart on Tue Jul 9 22:26:36 2013. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to tap-as-a-service's documentation! -======================================================== - -Contents: - -.. toctree:: - :maxdepth: 2 - - readme - installation - api_reference - contributing - specs/index - presentations - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - diff --git a/doc/source/installation.rst b/doc/source/installation.rst deleted file mode 100644 index 545ae4f..0000000 --- a/doc/source/installation.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../../INSTALL.rst diff --git a/doc/source/presentations.rst b/doc/source/presentations.rst deleted file mode 100644 index a68f0c8..0000000 --- a/doc/source/presentations.rst +++ /dev/null @@ -1,21 +0,0 @@ -============= -Presentations -============= - -- `Tap-As-A-Service What You Need to Know Now - `_ - - 40 min presentation at OpenStack Summit Austin, April 2016, - including a demo with Horizon. - -- `Using Open Source Security Architecture to Defend against Targeted Attacks` - - - 40 min presentation at OpenStack Summit Austin, April 2016, - including IDS/IPS use cases and a demo with snort. - -- `Tap-as-a-Service (TaaS): Port Monitoring for Neutron Networks - `_ - - 40 min presentation at OpenStack Summit Vancouver, May 2015, - including a demo. diff --git a/doc/source/readme.rst b/doc/source/readme.rst deleted file mode 100644 index a6210d3..0000000 --- a/doc/source/readme.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../../README.rst diff --git a/doc/source/specs b/doc/source/specs deleted file mode 120000 index 87a4030..0000000 --- a/doc/source/specs +++ /dev/null @@ -1 +0,0 @@ -../../specs \ No newline at end of file diff --git a/etc/taas.ini b/etc/taas.ini deleted file mode 100644 index f569f67..0000000 --- a/etc/taas.ini +++ /dev/null @@ -1,5 +0,0 @@ -[taas] -driver = neutron_taas.services.taas.drivers.linux.ovs_taas.OvsTaasDriver -enabled = True -vlan_range_start = 3000 -vlan_range_end = 3500 diff --git a/etc/taas_plugin.ini b/etc/taas_plugin.ini deleted file mode 100644 index 53800f6..0000000 --- a/etc/taas_plugin.ini +++ /dev/null @@ -1,7 +0,0 @@ -[DEFAULT] - - -[service_providers] -# Defines providers for advanced services using the format: -# ::[:default] (multi valued) -service_provider = TAAS:TAAS:neutron_taas.services.taas.service_drivers.taas_rpc.TaasRpcDriver:default diff --git a/lower-constraints.txt b/lower-constraints.txt deleted file mode 100644 index 71831b5..0000000 --- a/lower-constraints.txt +++ /dev/null @@ -1,148 +0,0 @@ -alabaster==0.7.10 -alembic==0.9.8 -amqp==2.2.2 -appdirs==1.4.3 -Babel==2.3.4 -beautifulsoup4==4.6.0 -cachetools==2.0.1 -certifi==2018.1.18 -cffi==1.11.5 -chardet==3.0.4 -cliff==2.11.0 -cmd2==0.8.1 -contextlib2==0.5.5 -coverage==4.0 -debtcollector==1.19.0 -decorator==4.2.1 -deprecation==2.0 -docutils==0.14 -dogpile.cache==0.6.5 -dulwich==0.19.0 -enum-compat==0.0.2 -eventlet==0.20.0 -extras==1.0.0 -fasteners==0.14.1 -fixtures==3.0.0 -flake8==2.5.5 -future==0.16.0 -futurist==1.6.0 -greenlet==0.4.13 -hacking==0.12.0 -httplib2==0.10.3 -idna==2.6 -imagesize==1.0.0 -iso8601==0.1.12 -Jinja2==2.10 -jmespath==0.9.3 -jsonpatch==1.21 -jsonpointer==2.0 -jsonschema==2.6.0 -keystoneauth1==3.4.0 -keystonemiddleware==4.21.0 -kombu==4.1.0 -linecache2==1.0.0 -logutils==0.3.5 -Mako==1.0.7 -MarkupSafe==1.0 -mccabe==0.2.1 -mock==2.0.0 -monotonic==1.4 -mox3==0.25.0 -msgpack-python==0.5.6 -msgpack==0.5.6 -munch==2.2.0 -netaddr==0.7.19 -netifaces==0.10.6 -neutron-lib==1.20.0 -openstacksdk==0.12.0 -os-client-config==1.29.0 -os-service-types==1.2.0 -os-testr==1.0.0 -os-xenapi==0.3.1 -osc-lib==1.10.0 -oslo.cache==1.29.0 -oslo.concurrency==3.26.0 -oslo.config==5.2.0 -oslo.context==2.20.0 -oslo.db==4.35.0 -oslo.i18n==3.20.0 -oslo.log==3.37.0 -oslo.messaging==5.36.0 -oslo.middleware==3.35.0 -oslo.policy==1.34.0 -oslo.privsep==1.28.0 -oslo.reports==1.27.0 -oslo.rootwrap==5.13.0 -oslo.serialization==2.25.0 -oslo.service==1.30.0 -oslo.utils==3.36.0 -oslo.versionedobjects==1.32.0 -oslosphinx==4.7.0 -oslotest==3.2.0 -osprofiler==2.0.0 -ovs==2.8.1 -ovsdbapp==0.10.0 -packaging==17.1 -Paste==2.0.3 -PasteDeploy==1.5.2 -pbr==2.0.0 -pecan==1.2.1 -pep8==1.5.7 -pika-pool==0.1.3 -pika==0.10.0 -prettytable==0.7.2 -psutil==5.4.3 -psycopg2==2.6.2 -pycadf==2.7.0 -pycparser==2.18 -pyflakes==0.8.1 -Pygments==2.2.0 -pyinotify==0.9.6 -PyMySQL==0.7.6 -pyparsing==2.2.0 -pyperclip==1.6.0 -pyroute2==0.4.21 -python-dateutil==2.7.0 -python-designateclient==2.9.0 -python-editor==1.0.3 -python-keystoneclient==3.15.0 -python-mimeparse==1.6.0 -python-neutronclient==6.7.0 -python-novaclient==10.1.0 -python-subunit==1.0.0 -pytz==2018.3 -PyYAML==3.12 -reno==2.5.0 -repoze.lru==0.7 -requests==2.18.4 -requestsexceptions==1.4.0 -rfc3986==1.1.0 -Routes==2.4.1 -ryu==4.23 -simplejson==3.13.2 -six==1.11.0 -snowballstemmer==1.2.1 -Sphinx==1.6.2 -sphinxcontrib-websupport==1.0.1 -sqlalchemy-migrate==0.11.0 -SQLAlchemy==1.2.5 -sqlparse==0.2.4 -statsd==3.2.2 -stestr==2.0.0 -stevedore==1.28.0 -Tempita==0.5.2 -tenacity==4.9.0 -testrepository==0.0.20 -testresources==2.0.0 -testscenarios==0.4 -testtools==2.2.0 -tinyrpc==0.8 -traceback2==1.4.0 -unittest2==1.1.0 -urllib3==1.22 -vine==1.1.4 -voluptuous==0.11.1 -waitress==1.1.0 -WebOb==1.7.4 -WebTest==2.0.29 -wrapt==1.10.11 diff --git a/neutron_taas/_i18n.py b/neutron_taas/_i18n.py deleted file mode 100644 index 2cbbf8e..0000000 --- a/neutron_taas/_i18n.py +++ /dev/null @@ -1,31 +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. - -import oslo_i18n - - -DOMAIN = 'neutron_taas' - -_translators = oslo_i18n.TranslatorFactory(domain=DOMAIN) - -# The primary translation function using the well-known name "_" -_ = _translators.primary - -# The contextual translation function using the name "_C" -_C = _translators.contextual_form - -# The plural translation function using the name "_P" -_P = _translators.plural_form - - -def get_available_languages(): - return oslo_i18n.get_available_languages(DOMAIN) diff --git a/neutron_taas/common/constants.py b/neutron_taas/common/constants.py deleted file mode 100644 index 50a5ec1..0000000 --- a/neutron_taas/common/constants.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (C) 2015 Midokura SARL. -# 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. - -TAAS = 'TAAS' diff --git a/neutron_taas/common/topics.py b/neutron_taas/common/topics.py deleted file mode 100644 index ff08d87..0000000 --- a/neutron_taas/common/topics.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (C) 2015 Midokura SARL. -# 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. - -# TODO(yamamoto): Move these to neutron.common.topics - -TAAS_PLUGIN = 'n-taas-plugin' -TAAS_AGENT = 'n-taas_agent' diff --git a/neutron_taas/db/head.py b/neutron_taas/db/head.py deleted file mode 100644 index 657aaba..0000000 --- a/neutron_taas/db/head.py +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright 2016 VMware, Inc -# -# 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 neutron.db.migration.models import head - -from neutron_taas.db import taas_db # noqa - - -def get_metadata(): - return head.model_base.BASEV2.metadata diff --git a/neutron_taas/db/migration/alembic_migration/README b/neutron_taas/db/migration/alembic_migration/README deleted file mode 100644 index 98e4f9c..0000000 --- a/neutron_taas/db/migration/alembic_migration/README +++ /dev/null @@ -1 +0,0 @@ -Generic single-database configuration. \ No newline at end of file diff --git a/neutron_taas/db/migration/alembic_migration/env.py b/neutron_taas/db/migration/alembic_migration/env.py deleted file mode 100644 index fd82b6b..0000000 --- a/neutron_taas/db/migration/alembic_migration/env.py +++ /dev/null @@ -1,87 +0,0 @@ -# Copyright 2015 Midokura SARL -# -# 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 logging import config as logging_config - -from neutron_lib.db import model_base - -from alembic import context -from oslo_config import cfg -from oslo_db.sqlalchemy import session -import sqlalchemy as sa -from sqlalchemy import event - - -MYSQL_ENGINE = None -TAAS_VERSION_TABLE = 'alembic_version_taas' -config = context.config -neutron_config = config.neutron_config -logging_config.fileConfig(config.config_file_name) -target_metadata = model_base.BASEV2.metadata - - -def set_mysql_engine(): - try: - mysql_engine = neutron_config.command.mysql_engine - except cfg.NoSuchOptError: - mysql_engine = None - - global MYSQL_ENGINE - MYSQL_ENGINE = (mysql_engine or - model_base.BASEV2.__table_args__['mysql_engine']) - - -def run_migrations_offline(): - set_mysql_engine() - - kwargs = dict() - if neutron_config.database.connection: - kwargs['url'] = neutron_config.database.connection - else: - kwargs['dialect_name'] = neutron_config.database.engine - kwargs['version_table'] = TAAS_VERSION_TABLE - context.configure(**kwargs) - - with context.begin_transaction(): - context.run_migrations() - - -@event.listens_for(sa.Table, 'after_parent_attach') -def set_storage_engine(target, parent): - if MYSQL_ENGINE: - target.kwargs['mysql_engine'] = MYSQL_ENGINE - - -def run_migrations_online(): - set_mysql_engine() - engine = session.create_engine(neutron_config.database.connection) - - connection = engine.connect() - context.configure( - connection=connection, - target_metadata=target_metadata, - version_table=TAAS_VERSION_TABLE - ) - try: - with context.begin_transaction(): - context.run_migrations() - finally: - connection.close() - engine.dispose() - - -if context.is_offline_mode(): - run_migrations_offline() -else: - run_migrations_online() diff --git a/neutron_taas/db/migration/alembic_migration/script.py.mako b/neutron_taas/db/migration/alembic_migration/script.py.mako deleted file mode 100644 index 0c9d9c9..0000000 --- a/neutron_taas/db/migration/alembic_migration/script.py.mako +++ /dev/null @@ -1,21 +0,0 @@ -"""${message} - -Revision ID: ${up_revision} -Revises: ${down_revision} -Create Date: ${create_date} - -""" - -# revision identifiers, used by Alembic. -revision = ${repr(up_revision)} -down_revision = ${repr(down_revision)} -% if branch_labels: -branch_labels = ${repr(branch_labels)} -%endif - -from alembic import op -import sqlalchemy as sa -${imports if imports else ""} - -def upgrade(): - ${upgrades if upgrades else "pass"} diff --git a/neutron_taas/db/migration/alembic_migration/versions/CONTRACT_HEAD b/neutron_taas/db/migration/alembic_migration/versions/CONTRACT_HEAD deleted file mode 100644 index b715d7a..0000000 --- a/neutron_taas/db/migration/alembic_migration/versions/CONTRACT_HEAD +++ /dev/null @@ -1 +0,0 @@ -bac61f603e39 diff --git a/neutron_taas/db/migration/alembic_migration/versions/EXPAND_HEAD b/neutron_taas/db/migration/alembic_migration/versions/EXPAND_HEAD deleted file mode 100644 index 4cb3f9f..0000000 --- a/neutron_taas/db/migration/alembic_migration/versions/EXPAND_HEAD +++ /dev/null @@ -1 +0,0 @@ -fddbdec8711a diff --git a/neutron_taas/db/migration/alembic_migration/versions/newton/contract/1817af933379_remove_network_id_from_tap_service.py b/neutron_taas/db/migration/alembic_migration/versions/newton/contract/1817af933379_remove_network_id_from_tap_service.py deleted file mode 100644 index 5af35ba..0000000 --- a/neutron_taas/db/migration/alembic_migration/versions/newton/contract/1817af933379_remove_network_id_from_tap_service.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (c) 2016 Midokura SARL -# 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. - -"""Remove network-id from tap-service - -Revision ID: 1817af933379 -Revises: 80c85b675b6e -Create Date: 2016-04-05 21:59:28.829793 - -""" - -# revision identifiers, used by Alembic. -revision = '1817af933379' -down_revision = '80c85b675b6e' - -from alembic import op - - -def upgrade(): - op.drop_column('tap_services', 'network_id') diff --git a/neutron_taas/db/migration/alembic_migration/versions/newton/contract/2ecce0368a62_add_foreign_key_constraint_on_tap_id_association.py b/neutron_taas/db/migration/alembic_migration/versions/newton/contract/2ecce0368a62_add_foreign_key_constraint_on_tap_id_association.py deleted file mode 100644 index e04224f..0000000 --- a/neutron_taas/db/migration/alembic_migration/versions/newton/contract/2ecce0368a62_add_foreign_key_constraint_on_tap_id_association.py +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright 2016 Midokura SARL -# -# 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. - -"""add foreign key constraint on tap id association - -Revision ID: 2ecce0368a62 -Revises: 1817af933379 -Create Date: 2016-05-19 11:39:52.892610 - -""" - -# revision identifiers, used by Alembic. -revision = '2ecce0368a62' -down_revision = '1817af933379' - -from alembic import op - - -def upgrade(): - op.create_foreign_key( - constraint_name=None, - source_table='tap_id_associations', - referent_table='tap_services', - local_cols=['tap_service_id'], - remote_cols=['id'], - ondelete='CASCADE') diff --git a/neutron_taas/db/migration/alembic_migration/versions/newton/contract/4086b3cffc01_rename_tenant_to_project.py b/neutron_taas/db/migration/alembic_migration/versions/newton/contract/4086b3cffc01_rename_tenant_to_project.py deleted file mode 100644 index 06031a2..0000000 --- a/neutron_taas/db/migration/alembic_migration/versions/newton/contract/4086b3cffc01_rename_tenant_to_project.py +++ /dev/null @@ -1,123 +0,0 @@ -# Copyright 2016 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. -# - -"""rename tenant to project - -Revision ID: 4086b3cffc01 -Revises: 2ecce0368a62 -Create Date: 2016-07-30 22:09:16.372917 - -""" - -# revision identifiers, used by Alembic. -revision = '4086b3cffc01' -down_revision = '2ecce0368a62' - -from alembic import op -import sqlalchemy as sa -from sqlalchemy.engine import reflection - -from neutron.db import migration - - -_INSPECTOR = None - -# milestone identifier, used by neutron-db-manage -neutron_milestone = [migration.NEWTON, migration.OCATA] - - -def get_inspector(): - """Reuse inspector.""" - - global _INSPECTOR - - if _INSPECTOR: - return _INSPECTOR - - else: - bind = op.get_bind() - _INSPECTOR = reflection.Inspector.from_engine(bind) - - return _INSPECTOR - - -def get_tables(): - """Returns hardcoded list of tables which have ``tenant_id`` column. - - The list is hard-coded to match the state of the schema when this upgrade - script is run. - """ - - tables = [ - 'tap_services', - 'tap_flows', - ] - - return tables - - -def get_columns(table): - """Returns list of columns for given table.""" - inspector = get_inspector() - return inspector.get_columns(table) - - -def get_data(): - """Returns combined list of tuples: [(table, column)]. - - The list is built from tables with a tenant_id column. - """ - - output = [] - tables = get_tables() - for table in tables: - columns = get_columns(table) - - for column in columns: - if column['name'] == 'tenant_id': - output.append((table, column)) - - return output - - -def alter_column(table, column): - old_name = 'tenant_id' - new_name = 'project_id' - - op.alter_column( - table_name=table, - column_name=old_name, - new_column_name=new_name, - existing_type=column['type'], - existing_nullable=column['nullable'] - ) - - -def upgrade(): - data = get_data() - for table, column in data: - alter_column(table, column) - - -def contract_creation_exceptions(): - """Special migration for the blueprint to support Keystone V3. - - We drop all tenant_id columns and create project_id columns instead. - """ - - return { - sa.Column: ['.'.join([table, 'project_id']) for table in get_tables()], - sa.Index: get_tables() - } diff --git a/neutron_taas/db/migration/alembic_migration/versions/newton/contract/80c85b675b6e_initial_newton_no_op_contract_script.py b/neutron_taas/db/migration/alembic_migration/versions/newton/contract/80c85b675b6e_initial_newton_no_op_contract_script.py deleted file mode 100644 index 394a1a8..0000000 --- a/neutron_taas/db/migration/alembic_migration/versions/newton/contract/80c85b675b6e_initial_newton_no_op_contract_script.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2016 VMware, Inc. -# -# 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. - -"""initial Newton no op contract script - -Revision ID: 80c85b675b6e -Revises: start_neutron_taas -Create Date: 2016-05-06 04:58:04.510568 - -""" - -from neutron.db.migration import cli - -# revision identifiers, used by Alembic. -revision = '80c85b675b6e' -down_revision = 'start_neutron_taas' -branch_labels = (cli.CONTRACT_BRANCH,) - - -def upgrade(): - pass diff --git a/neutron_taas/db/migration/alembic_migration/versions/newton/expand/04625466c6fa_initial_newton_no_op_expand_script.py b/neutron_taas/db/migration/alembic_migration/versions/newton/expand/04625466c6fa_initial_newton_no_op_expand_script.py deleted file mode 100644 index da588ea..0000000 --- a/neutron_taas/db/migration/alembic_migration/versions/newton/expand/04625466c6fa_initial_newton_no_op_expand_script.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2016 VMware, Inc. -# -# 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. - -"""initial Newton no op expand script - -Revision ID: 04625466c6fa -Revises: start_neutron_taas -Create Date: 2016-05-06 05:17:30.172181 - -""" - -from neutron.db.migration import cli - -# revision identifiers, used by Alembic. -revision = '04625466c6fa' -down_revision = 'start_neutron_taas' -branch_labels = (cli.EXPAND_BRANCH,) - - -def upgrade(): - pass diff --git a/neutron_taas/db/migration/alembic_migration/versions/newton/expand/fddbdec8711a_add_status.py b/neutron_taas/db/migration/alembic_migration/versions/newton/expand/fddbdec8711a_add_status.py deleted file mode 100644 index 22da6c0..0000000 --- a/neutron_taas/db/migration/alembic_migration/versions/newton/expand/fddbdec8711a_add_status.py +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright 2016 FUJITSU LABORATORIES LTD. -# -# 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. - -"""add status - -Revision ID: fddbdec8711a -Revises: 04625466c6fa -Create Date: 2016-06-06 10:54:42.252898 - -""" - -# revision identifiers, used by Alembic. -revision = 'fddbdec8711a' -down_revision = '04625466c6fa' - -from alembic import op -from neutron.db import migration -from neutron_lib import constants -import sqlalchemy as sa - - -# milestone identifier, used by neutron-db-manage -neutron_milestone = [ - migration.NEWTON, - migration.OCATA, - migration.PIKE, - migration.QUEENS, - migration.ROCKY, -] - - -def upgrade(): - op.add_column('tap_services', sa.Column('status', sa.String(16), - server_default=constants.ACTIVE, - nullable=False)) - op.add_column('tap_flows', sa.Column('status', sa.String(16), - server_default=constants.ACTIVE, - nullable=False)) diff --git a/neutron_taas/db/migration/alembic_migration/versions/pike/contract/bac61f603e39_alter_tap_id_associations_to_support_tap_id_reuse.py b/neutron_taas/db/migration/alembic_migration/versions/pike/contract/bac61f603e39_alter_tap_id_associations_to_support_tap_id_reuse.py deleted file mode 100644 index 98b8a9a..0000000 --- a/neutron_taas/db/migration/alembic_migration/versions/pike/contract/bac61f603e39_alter_tap_id_associations_to_support_tap_id_reuse.py +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright 2016-17 -# -# 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. - -"""Alter TapIdAssociations to support tap id reuse - -Revision ID: bac61f603e39 -Revises: 4086b3cffc01 -Create Date: 2016-07-27 09:31:54.200165 - -""" - -# revision identifiers, used by Alembic. -revision = 'bac61f603e39' -down_revision = '4086b3cffc01' - -from alembic import op -from sqlalchemy.engine import reflection - -import sqlalchemy as sa - -from neutron.db import migration - - -# milestone identifier, used by neutron-db-manage -neutron_milestone = [migration.PIKE, migration.QUEENS, migration.ROCKY] - -TABLE_NAME = 'tap_id_associations' - - -def upgrade(): - inspector = reflection.Inspector.from_engine(op.get_bind()) - fk_constraints = inspector.get_foreign_keys(TABLE_NAME) - for fk in fk_constraints: - op.drop_constraint(fk['name'], TABLE_NAME, type_='foreignkey') - - op.create_foreign_key('fk_tap_id_assoc_tap_service', TABLE_NAME, - 'tap_services', ['tap_service_id'], ['id'], - ondelete='SET NULL') - - op.alter_column(TABLE_NAME, 'taas_id', autoincrement=False, - existing_type=sa.INTEGER, nullable=False) - op.alter_column(TABLE_NAME, 'tap_service_id', - existing_type=sa.String(36), nullable=True) - op.create_unique_constraint('unique_taas_id', TABLE_NAME, - ['taas_id']) diff --git a/neutron_taas/db/migration/alembic_migration/versions/start_neutron_taas.py b/neutron_taas/db/migration/alembic_migration/versions/start_neutron_taas.py deleted file mode 100644 index 817516d..0000000 --- a/neutron_taas/db/migration/alembic_migration/versions/start_neutron_taas.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2015 Midokura SARL -# -# 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. - -"""start neutron-taas chain - -Revision ID: start_neutron_taas -Revises: None -Create Date: 2015-11-11 02:36:00.209301 - -""" - -# revision identifiers, used by Alembic. -revision = 'start_neutron_taas' -down_revision = None - - -from neutron_taas.db.migration import taas_init_ops - - -def upgrade(): - taas_init_ops.upgrade() diff --git a/neutron_taas/db/migration/taas_init_ops.py b/neutron_taas/db/migration/taas_init_ops.py deleted file mode 100644 index c65f50e..0000000 --- a/neutron_taas/db/migration/taas_init_ops.py +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright 2015 Ericsson AB -# Copyright (c) 2015 Gigamon -# -# 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. -# - -# Initial schema operations for Tap-as-a-Service service plugin - - -from alembic import op -import sqlalchemy as sa - - -direction_types = sa.Enum('IN', 'OUT', 'BOTH', name='tapflows_direction') - - -def upgrade(): - op.create_table( - 'tap_services', - sa.Column('id', sa.String(length=36), primary_key=True, - nullable=False), - sa.Column('tenant_id', sa.String(length=255), nullable=True), - sa.Column('name', sa.String(length=255), nullable=True), - sa.Column('description', sa.String(length=1024), nullable=True), - sa.Column('port_id', sa.String(36), nullable=False), - sa.Column('network_id', sa.String(36), nullable=True)) - - op.create_table( - 'tap_flows', - sa.Column('id', sa.String(length=36), primary_key=True, - nullable=False), - sa.Column('tenant_id', sa.String(length=255), nullable=True), - sa.Column('name', sa.String(length=255), nullable=True), - sa.Column('description', sa.String(length=1024), nullable=True), - sa.Column('tap_service_id', sa.String(length=36), - sa.ForeignKey("tap_services.id", - ondelete="CASCADE"), nullable=False), - sa.Column('source_port', sa.String(length=36), nullable=False), - sa.Column('direction', direction_types, nullable=False)) - - op.create_table( - 'tap_id_associations', - sa.Column('tap_service_id', sa.String(length=36)), - sa.Column('taas_id', sa.INTEGER, primary_key=True, autoincrement=True)) diff --git a/neutron_taas/db/taas_db.py b/neutron_taas/db/taas_db.py deleted file mode 100644 index 29dfcb7..0000000 --- a/neutron_taas/db/taas_db.py +++ /dev/null @@ -1,287 +0,0 @@ -# Copyright (C) 2015 Ericsson AB -# Copyright (c) 2015 Gigamon -# -# 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 sqlalchemy as sa -from sqlalchemy import orm -from sqlalchemy.orm import exc - -from neutron_lib import constants -from neutron_lib.db import model_base -from neutron_lib.db import model_query -from neutron_lib.db import utils as db_utils -from neutron_lib.plugins import directory -from neutron_taas.extensions import taas -from oslo_config import cfg -from oslo_log import log as logging -from oslo_utils import uuidutils - -LOG = logging.getLogger(__name__) - - -class TapService(model_base.BASEV2, model_base.HasId, - model_base.HasProjectNoIndex): - - # Represents a V2 TapService Object - __tablename__ = 'tap_services' - name = sa.Column(sa.String(255), nullable=True) - description = sa.Column(sa.String(1024), nullable=True) - port_id = sa.Column(sa.String(36), nullable=False) - status = sa.Column(sa.String(16), nullable=False, - server_default=constants.ACTIVE) - - -class TapFlow(model_base.BASEV2, model_base.HasId, - model_base.HasProjectNoIndex): - - # Represents a V2 TapFlow Object - __tablename__ = 'tap_flows' - name = sa.Column(sa.String(255), nullable=True) - description = sa.Column(sa.String(1024), nullable=True) - tap_service_id = sa.Column(sa.String(36), - sa.ForeignKey("tap_services.id", - ondelete="CASCADE"), - nullable=False) - source_port = sa.Column(sa.String(36), nullable=False) - direction = sa.Column(sa.Enum('IN', 'OUT', 'BOTH', - name='tapflows_direction'), - nullable=False) - status = sa.Column(sa.String(16), nullable=False, - server_default=constants.ACTIVE) - - -class TapIdAssociation(model_base.BASEV2): - - # Internal mapping between a TAP Service and - # id to be used by the Agents - __tablename__ = 'tap_id_associations' - tap_service_id = sa.Column(sa.String(36), - sa.ForeignKey("tap_services.id", - ondelete='SET NULL'), - nullable=True) - taas_id = sa.Column(sa.Integer, primary_key=True, unique=True) - tap_service = orm.relationship( - TapService, - backref=orm.backref("tap_service_id", - lazy="joined"), - primaryjoin='TapService.id==TapIdAssociation.tap_service_id') - - -class Taas_db_Mixin(taas.TaasPluginBase): - - def _core_plugin(self): - return directory.get_plugin() - - def _get_tap_service(self, context, id): - try: - return model_query.get_by_id(context, TapService, id) - except exc.NoResultFound: - raise taas.TapServiceNotFound(tap_id=id) - - def _get_tap_id_association(self, context, tap_service_id): - try: - query = model_query.query_with_hooks(context, TapIdAssociation) - return query.filter(TapIdAssociation.tap_service_id == - tap_service_id).one() - except exc.NoResultFound: - raise taas.TapServiceNotFound(tap_id=tap_service_id) - - def _get_tap_flow(self, context, id): - try: - return model_query.get_by_id(context, TapFlow, id) - except Exception: - raise taas.TapFlowNotFound(flow_id=id) - - def _make_tap_service_dict(self, tap_service, fields=None): - res = {'id': tap_service['id'], - 'tenant_id': tap_service['tenant_id'], - 'name': tap_service['name'], - 'description': tap_service['description'], - 'port_id': tap_service['port_id'], - 'status': tap_service['status']} - - return db_utils.resource_fields(res, fields) - - def _make_tap_id_association_dict(self, tap_id_association): - res = {'tap_service_id': tap_id_association['tap_service_id'], - 'taas_id': tap_id_association['taas_id']} - - return res - - def _make_tap_flow_dict(self, tap_flow, fields=None): - res = {'id': tap_flow['id'], - 'tenant_id': tap_flow['tenant_id'], - 'tap_service_id': tap_flow['tap_service_id'], - 'name': tap_flow['name'], - 'description': tap_flow['description'], - 'source_port': tap_flow['source_port'], - 'direction': tap_flow['direction'], - 'status': tap_flow['status']} - - return db_utils.resource_fields(res, fields) - - def create_tap_service(self, context, tap_service): - LOG.debug("create_tap_service() called") - t_s = tap_service['tap_service'] - tenant_id = t_s['tenant_id'] - with context.session.begin(subtransactions=True): - tap_service_db = TapService( - id=uuidutils.generate_uuid(), - tenant_id=tenant_id, - name=t_s['name'], - description=t_s['description'], - port_id=t_s['port_id'], - status=constants.ACTIVE, - ) - context.session.add(tap_service_db) - - return self._make_tap_service_dict(tap_service_db) - - def _rebuild_taas_id_allocation_range(self, context): - query = context.session.query( - TapIdAssociation).all() - - allocate_taas_id_list = [_q.taas_id for _q in query] - first_taas_id = cfg.CONF.taas.vlan_range_start - # Exclude range end - last_taas_id = cfg.CONF.taas.vlan_range_end - all_taas_id_set = set(range(first_taas_id, last_taas_id)) - vaild_taas_id_set = all_taas_id_set - set(allocate_taas_id_list) - - for _id in vaild_taas_id_set: - # new taas id - context.session.add(TapIdAssociation( - taas_id=_id)) - - def _allocate_taas_id_with_tap_service_id(self, context, tap_service_id): - query = context.session.query(TapIdAssociation).filter_by( - tap_service_id=None).first() - if not query: - self._rebuild_taas_id_allocation_range(context) - # try again - query = context.session.query(TapIdAssociation).filter_by( - tap_service_id=None).first() - - if query: - query.update({"tap_service_id": tap_service_id}) - return query - # not found - raise taas.TapServiceLimitReached() - - def create_tap_id_association(self, context, tap_service_id): - LOG.debug("create_tap_id_association() called") - # create the TapIdAssociation object - with context.session.begin(subtransactions=True): - # allocate Taas id. - # if conflict happened, it will raise db.DBDuplicateEntry. - # this will be retry request again in neutron controller framework. - # so we just make sure TapIdAssociation field taas_id is unique - tap_id_association_db = self._allocate_taas_id_with_tap_service_id( - context, tap_service_id) - - return self._make_tap_id_association_dict(tap_id_association_db) - - def create_tap_flow(self, context, tap_flow): - LOG.debug("create_tap_flow() called") - t_f = tap_flow['tap_flow'] - tenant_id = t_f['tenant_id'] - # TODO(Vinay): Check for the tenant_id validation - # TODO(Vinay): Check for the source port validation - with context.session.begin(subtransactions=True): - tap_flow_db = TapFlow( - id=uuidutils.generate_uuid(), - tenant_id=tenant_id, - name=t_f['name'], - description=t_f['description'], - tap_service_id=t_f['tap_service_id'], - source_port=t_f['source_port'], - direction=t_f['direction'], - status=constants.ACTIVE, - ) - context.session.add(tap_flow_db) - - return self._make_tap_flow_dict(tap_flow_db) - - def delete_tap_service(self, context, id): - LOG.debug("delete_tap_service() called") - - count = context.session.query(TapService).filter_by(id=id).delete() - - if not count: - raise taas.TapServiceNotFound(tap_id=id) - - def delete_tap_flow(self, context, id): - LOG.debug("delete_tap_flow() called") - - count = context.session.query(TapFlow).filter_by(id=id).delete() - - if not count: - raise taas.TapFlowNotFound(flow_id=id) - - def get_tap_service(self, context, id, fields=None): - LOG.debug("get_tap_service() called") - - t_s = self._get_tap_service(context, id) - return self._make_tap_service_dict(t_s, fields) - - def get_tap_id_association(self, context, tap_service_id): - LOG.debug("get_tap_id_association() called") - - t_a = self._get_tap_id_association(context, tap_service_id) - return self._make_tap_id_association_dict(t_a) - - def get_tap_flow(self, context, id, fields=None): - LOG.debug("get_tap_flow() called") - - t_f = self._get_tap_flow(context, id) - return self._make_tap_flow_dict(t_f, fields) - - def get_tap_services(self, context, filters=None, fields=None, - sorts=None, limit=None, marker=None, - page_reverse=False): - LOG.debug("get_tap_services() called") - return model_query.get_collection(context, TapService, - self._make_tap_service_dict, - filters=filters, fields=fields) - - def get_tap_flows(self, context, filters=None, fields=None, - sorts=None, limit=None, marker=None, - page_reverse=False): - LOG.debug("get_tap_flows() called") - return model_query.get_collection(context, TapFlow, - self._make_tap_flow_dict, - filters=filters, fields=fields) - - def _get_port_details(self, context, port_id): - with context.session.begin(subtransactions=True): - port = self._core_plugin().get_port(context, port_id) - - return port - - def update_tap_service(self, context, id, tap_service): - LOG.debug("update_tap_service() called") - t_s = tap_service['tap_service'] - with context.session.begin(subtransactions=True): - tap_service_db = self._get_tap_service(context, id) - tap_service_db.update(t_s) - return self._make_tap_service_dict(tap_service_db) - - def update_tap_flow(self, context, id, tap_flow): - LOG.debug("update_tap_flow() called") - t_f = tap_flow['tap_flow'] - with context.session.begin(subtransactions=True): - tap_flow_db = self._get_tap_flow(context, id) - tap_flow_db.update(t_f) - return self._make_tap_flow_dict(tap_flow_db) diff --git a/neutron_taas/extensions/__init__.py b/neutron_taas/extensions/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/neutron_taas/extensions/taas.py b/neutron_taas/extensions/taas.py deleted file mode 100644 index 1e29ecc..0000000 --- a/neutron_taas/extensions/taas.py +++ /dev/null @@ -1,260 +0,0 @@ -# Copyright (C) 2015 Ericsson AB -# Copyright (c) 2015 Gigamon -# -# 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 abc - -from neutron_lib.api import extensions -from neutron_lib import exceptions as qexception -from neutron_lib.services import base as service_base - -from neutron.api.v2 import resource_helper - -from neutron_taas._i18n import _ -from neutron_taas.common import constants - -from oslo_config import cfg - -import six - -# TaaS exception handling classes - - -class TapServiceNotFound(qexception.NotFound): - message = _("Tap Service %(tap_id)s does not exist") - - -class TapFlowNotFound(qexception.NotFound): - message = _("Tap Flow %(flow_id)s does not exist") - - -class InvalidDestinationPort(qexception.NotFound): - message = _("Destination Port %(port)s does not exist") - - -class InvalidSourcePort(qexception.NotFound): - message = _("Source Port %(port)s does not exist") - - -class PortDoesNotBelongToTenant(qexception.NotAuthorized): - message = _("The specified port does not belong to the tenant") - - -class TapServiceNotBelongToTenant(qexception.NotAuthorized): - message = _("Specified Tap Service does not belong to the tenant") - - -class TapServiceLimitReached(qexception.OverQuota): - message = _("Reached the maximum quota for Tap Services") - - -direction_enum = ['IN', 'OUT', 'BOTH'] - - -''' -Resource Attribute Map: - -Note: - -'tap_services' data model refers to the Tap Service created. -port_id specifies destination port to which the mirrored data is sent. -''' - -RESOURCE_ATTRIBUTE_MAP = { - 'tap_services': { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid': None}, 'is_visible': True, - 'primary_key': True}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'required_by_policy': True, 'is_visible': True}, - 'name': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'description': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'port_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True}, - 'status': {'allow_post': False, 'allow_put': False, - 'is_visible': True} - }, - 'tap_flows': { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid': None}, 'is_visible': True, - 'primary_key': True}, - 'tenant_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'required_by_policy': True, 'is_visible': True}, - 'name': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'description': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'tap_service_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'required_by_policy': True, 'is_visible': True}, - 'source_port': {'allow_post': True, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'required_by_policy': True, 'is_visible': True}, - 'direction': {'allow_post': True, 'allow_put': False, - 'validate': {'type:values': direction_enum}, - 'is_visible': True}, - 'status': {'allow_post': False, 'allow_put': False, - 'is_visible': True} - } -} - - -taas_quota_opts = [ - cfg.IntOpt('quota_tap_service', - default=1, - help=_('Number of Tap Service instances allowed per tenant')), - cfg.IntOpt('quota_tap_flow', - default=10, - help=_('Number of Tap flows allowed per tenant')) -] -cfg.CONF.register_opts(taas_quota_opts, 'QUOTAS') - - -TaasOpts = [ - cfg.StrOpt( - 'driver', - default='', - help=_("Name of the TaaS Driver")), - cfg.BoolOpt( - 'enabled', - default=False, - help=_("Enable TaaS")), - cfg.IntOpt( - 'vlan_range_start', - default=3900, - help=_("Starting range of TAAS VLAN IDs")), - cfg.IntOpt( - 'vlan_range_end', - default=4000, - help=_("End range of TAAS VLAN IDs")), -] -cfg.CONF.register_opts(TaasOpts, 'taas') - - -class Taas(extensions.ExtensionDescriptor): - @classmethod - def get_name(cls): - return "Neutron Tap as a Service" - - @classmethod - def get_alias(cls): - return "taas" - - @classmethod - def get_description(cls): - return "Neutron Tap as a Service Extension." - - @classmethod - def get_updated(cls): - return "2015-01-14T10:00:00-00:00" - - @classmethod - def get_plugin_interface(cls): - return TaasPluginBase - - @classmethod - def get_resources(cls): - """Returns Ext Resources.""" - plural_mappings = resource_helper.build_plural_mappings( - {}, RESOURCE_ATTRIBUTE_MAP) - - return resource_helper.build_resource_info(plural_mappings, - RESOURCE_ATTRIBUTE_MAP, - constants.TAAS, - translate_name=False, - allow_bulk=True) - - def update_attributes_map(self, attributes): - super(Taas, self).update_attributes_map( - attributes, extension_attrs_map=RESOURCE_ATTRIBUTE_MAP) - - def get_extended_resources(self, version): - if version == "2.0": - return RESOURCE_ATTRIBUTE_MAP - else: - return {} - - -@six.add_metaclass(abc.ABCMeta) -class TaasPluginBase(service_base.ServicePluginBase): - - def get_plugin_description(self): - return "Tap Service Plugin" - - @classmethod - def get_plugin_type(cls): - return constants.TAAS - - @abc.abstractmethod - def create_tap_service(self, context, tap_service): - """Create a Tap Service.""" - pass - - @abc.abstractmethod - def delete_tap_service(self, context, id): - """Delete a Tap Service.""" - pass - - @abc.abstractmethod - def get_tap_service(self, context, id, fields=None): - """Get a Tap Service.""" - pass - - @abc.abstractmethod - def get_tap_services(self, context, filters=None, fields=None, - sorts=None, limit=None, marker=None, - page_reverse=False): - """List all Tap Services.""" - pass - - @abc.abstractmethod - def update_tap_service(self, context, id, tap_service): - """Update a Tap Service.""" - pass - - @abc.abstractmethod - def create_tap_flow(self, context, tap_flow): - """Create a Tap Flow.""" - pass - - @abc.abstractmethod - def get_tap_flow(self, context, id, fields=None): - """Get a Tap Flow.""" - pass - - @abc.abstractmethod - def delete_tap_flow(self, context, id): - """Delete a Tap Flow.""" - pass - - @abc.abstractmethod - def get_tap_flows(self, context, filters=None, fields=None, - sorts=None, limit=None, marker=None, - page_reverse=False): - """List all Tap Flows.""" - pass - - @abc.abstractmethod - def update_tap_flow(self, context, id, tap_flow): - """Update a Tap Flow.""" - pass diff --git a/neutron_taas/services/__init__.py b/neutron_taas/services/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/neutron_taas/services/taas/__init__.py b/neutron_taas/services/taas/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/neutron_taas/services/taas/agents/__init__.py b/neutron_taas/services/taas/agents/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/neutron_taas/services/taas/agents/extensions/__init__.py b/neutron_taas/services/taas/agents/extensions/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/neutron_taas/services/taas/agents/extensions/taas.py b/neutron_taas/services/taas/agents/extensions/taas.py deleted file mode 100644 index 8d0f549..0000000 --- a/neutron_taas/services/taas/agents/extensions/taas.py +++ /dev/null @@ -1,91 +0,0 @@ -# Copyright 2017 FUJITSU LABORATORIES LTD. -# Copyright 2016 NEC Technologies India Pvt. Ltd. -# -# 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 abc -import six - -from neutron_lib.agent import l2_extension - -from neutron_taas.services.taas.agents.ovs import taas_ovs_agent - -from oslo_config import cfg -from oslo_log import log as logging - -LOG = logging.getLogger(__name__) - - -OPTS = [ - cfg.IntOpt( - 'taas_agent_periodic_interval', - default=5, - help=_('Seconds between periodic task runs') - ) -] -cfg.CONF.register_opts(OPTS) - - -@six.add_metaclass(abc.ABCMeta) -class TaasAgentDriver(object): - """Defines stable abstract interface for TaaS Agent Driver.""" - - @abc.abstractmethod - def initialize(self): - """Perform Taas agent driver initialization.""" - - def consume_api(self, agent_api): - """Consume the AgentAPI instance from the TaasAgentExtension class - - :param agent_api: An instance of an agent specific API - """ - - @abc.abstractmethod - def create_tap_service(self, tap_service): - """Create a Tap Service request in driver.""" - - @abc.abstractmethod - def create_tap_flow(self, tap_flow): - """Create a tap flow request in driver.""" - - @abc.abstractmethod - def delete_tap_service(self, tap_service): - """delete a Tap Service request in driver.""" - - @abc.abstractmethod - def delete_tap_flow(self, tap_flow): - """Delete a tap flow request in driver.""" - - -class TaasAgentExtension(l2_extension.L2AgentExtension): - - def initialize(self, connection, driver_type): - """Initialize agent extension.""" - self.taas_agent = taas_ovs_agent.TaasOvsAgentRpcCallback( - cfg.CONF, driver_type) - self.taas_agent.consume_api(self.agent_api) - self.taas_agent.initialize() - - def consume_api(self, agent_api): - """Receive neutron agent API object - - Allows an extension to gain access to resources internal to the - neutron agent and otherwise unavailable to the extension. - """ - self.agent_api = agent_api - - def handle_port(self, context, port): - pass - - def delete_port(self, context, port): - pass diff --git a/neutron_taas/services/taas/agents/ovs/__init__.py b/neutron_taas/services/taas/agents/ovs/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/neutron_taas/services/taas/agents/ovs/taas_ovs_agent.py b/neutron_taas/services/taas/agents/ovs/taas_ovs_agent.py deleted file mode 100644 index 41a05ee..0000000 --- a/neutron_taas/services/taas/agents/ovs/taas_ovs_agent.py +++ /dev/null @@ -1,144 +0,0 @@ -# Copyright (C) 2015 Ericsson AB -# Copyright (c) 2015 Gigamon -# -# 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 neutron import manager - -from neutron_taas.common import topics -from neutron_taas.services.taas.agents import taas_agent_api as api - -from neutron_lib import rpc as n_rpc -from oslo_config import cfg -from oslo_log import log as logging -from oslo_service import service - -LOG = logging.getLogger(__name__) - - -class TaasOvsPluginApi(api.TaasPluginApiMixin): - # Currently there are not any APIs from the the agent towards plugin - - def __init__(self, topic, host): - super(TaasOvsPluginApi, self).__init__(topic, host) - return - - -class TaasOvsAgentRpcCallback(api.TaasAgentRpcCallbackMixin): - - def __init__(self, conf, driver_type): - LOG.debug("TaaS OVS Agent initialize called") - - self.conf = conf - self.driver_type = driver_type - - super(TaasOvsAgentRpcCallback, self).__init__() - - def initialize(self): - self.taas_driver = manager.NeutronManager.load_class_for_provider( - 'neutron_taas.taas.agent_drivers', self.driver_type)() - self.taas_driver.consume_api(self.agent_api) - self.taas_driver.initialize() - - self._taas_rpc_setup() - TaasOvsAgentService(self).start() - - def consume_api(self, agent_api): - self.agent_api = agent_api - - def _invoke_driver_for_plugin_api(self, context, args, func_name): - LOG.debug("Invoking Driver for %(func_name)s from agent", - {'func_name': func_name}) - - try: - self.taas_driver.__getattribute__(func_name)(args) - except Exception: - LOG.debug("Failed to invoke the driver") - - return - - def create_tap_service(self, context, tap_service, host): - """Handle Rpc from plugin to create a tap_service.""" - if host != self.conf.host: - return - LOG.debug("In RPC Call for Create Tap Service: MSG=%s" % tap_service) - - return self._invoke_driver_for_plugin_api( - context, - tap_service, - 'create_tap_service') - - def create_tap_flow(self, context, tap_flow_msg, host): - if host != self.conf.host: - return - LOG.debug("In RPC Call for Create Tap Flow: MSG=%s" % tap_flow_msg) - - return self._invoke_driver_for_plugin_api( - context, - tap_flow_msg, - 'create_tap_flow') - - def delete_tap_service(self, context, tap_service, host): - # - # Cleanup operations must be performed by all hosts - # where the source and/or destination ports associated - # with this tap service were residing. - # - LOG.debug("In RPC Call for Delete Tap Service: MSG=%s" % tap_service) - - return self._invoke_driver_for_plugin_api( - context, - tap_service, - 'delete_tap_service') - - def delete_tap_flow(self, context, tap_flow_msg, host): - if host != self.conf.host: - return - LOG.debug("In RPC Call for Delete Tap Flow: MSG=%s" % tap_flow_msg) - - return self._invoke_driver_for_plugin_api( - context, - tap_flow_msg, - 'delete_tap_flow') - - def _taas_rpc_setup(self): - # setup RPC to msg taas plugin - self.taas_plugin_rpc = TaasOvsPluginApi( - topics.TAAS_PLUGIN, self.conf.host) - - endpoints = [self] - conn = n_rpc.Connection() - conn.create_consumer(topics.TAAS_AGENT, endpoints, fanout=False) - conn.consume_in_threads() - - def periodic_tasks(self): - # - # Regenerate the flow in br-tun's TAAS_SEND_FLOOD table - # to ensure all existing tunnel ports are included. - # - self.taas_driver.update_tunnel_flood_flow() - - -class TaasOvsAgentService(service.Service): - def __init__(self, driver): - super(TaasOvsAgentService, self).__init__() - self.driver = driver - - def start(self): - super(TaasOvsAgentService, self).start() - self.tg.add_timer( - int(cfg.CONF.taas_agent_periodic_interval), - self.driver.periodic_tasks, - None - ) diff --git a/neutron_taas/services/taas/agents/taas_agent_api.py b/neutron_taas/services/taas/agents/taas_agent_api.py deleted file mode 100644 index 2ee54e9..0000000 --- a/neutron_taas/services/taas/agents/taas_agent_api.py +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright (C) 2015 Ericsson AB -# Copyright (c) 2015 Gigamon -# -# 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 neutron_lib import rpc as n_rpc -from neutron_taas._i18n import _ -from oslo_config import cfg -import oslo_messaging as messaging - - -TaasOpts = [ - cfg.StrOpt( - 'driver', - default='', - help=_("Name of the TaaS Driver")), - cfg.BoolOpt( - 'enabled', - default=False, - help=_("Enable TaaS")), -] -cfg.CONF.register_opts(TaasOpts, 'taas') - - -class TaasPluginApiMixin(object): - - # Currently there are no Calls the Agent makes towards the Plugin. - - def __init__(self, topic, host): - self.host = host - target = messaging.Target(topic=topic, version='1.0') - self.client = n_rpc.get_client(target) - super(TaasPluginApiMixin, self).__init__() - return - - -class TaasAgentRpcCallbackMixin(object): - """Mixin for Taas agent Implementations.""" - - def __init__(self): - super(TaasAgentRpcCallbackMixin, self).__init__() - - def consume_api(self, agent_api): - """Receive neutron agent API object - - Allows an extension to gain access to resources internal to the - neutron agent and otherwise unavailable to the extension. - """ - self.agent_api = agent_api - - def create_tap_service(self, context, tap_service, host): - """Handle RPC cast from plugin to create a tap service.""" - pass - - def delete_tap_service(self, context, tap_service, host): - """Handle RPC cast from plugin to delete a tap service.""" - pass - - def create_tap_flow(self, context, tap_flow_msg, host): - """Handle RPC cast from plugin to create a tap flow""" - pass - - def delete_tap_flow(self, context, tap_flow_msg, host): - """Handle RPC cast from plugin to delete a tap flow""" - pass diff --git a/neutron_taas/services/taas/drivers/__init__.py b/neutron_taas/services/taas/drivers/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/neutron_taas/services/taas/drivers/linux/__init__.py b/neutron_taas/services/taas/drivers/linux/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/neutron_taas/services/taas/drivers/linux/ovs_constants.py b/neutron_taas/services/taas/drivers/linux/ovs_constants.py deleted file mode 100644 index 09fea87..0000000 --- a/neutron_taas/services/taas/drivers/linux/ovs_constants.py +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (C) 2015 Ericsson AB -# Copyright (c) 2015 Gigamon -# -# 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. - - -# OVS tables used by TaaS in br-tap -TAAS_RECV_LOC = 1 -TAAS_RECV_REM = 2 - -# OVS tables used by TaaS in br-tun -TAAS_SEND_UCAST = 30 -TAAS_SEND_FLOOD = 31 -TAAS_CLASSIFY = 35 -TAAS_DST_CHECK = 36 -TAAS_SRC_CHECK = 37 -TAAS_DST_RESPOND = 38 -TAAS_SRC_RESPOND = 39 diff --git a/neutron_taas/services/taas/drivers/linux/ovs_taas.py b/neutron_taas/services/taas/drivers/linux/ovs_taas.py deleted file mode 100644 index e5f8241..0000000 --- a/neutron_taas/services/taas/drivers/linux/ovs_taas.py +++ /dev/null @@ -1,507 +0,0 @@ -# Copyright (C) 2015 Ericsson AB -# Copyright (c) 2015 Gigamon -# -# 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 neutron.agent.common import ovs_lib -from neutron.agent.linux import utils -from neutron.conf.agent import common -# from neutron.plugins.openvswitch.common import constants as ovs_consts -from neutron.plugins.ml2.drivers.openvswitch.agent.common import constants \ - as ovs_consts -from neutron_taas.services.taas.agents.extensions import taas as taas_base -import neutron_taas.services.taas.drivers.linux.ovs_constants \ - as taas_ovs_consts -import neutron_taas.services.taas.drivers.linux.ovs_utils as taas_ovs_utils -from oslo_config import cfg -from oslo_log import log as logging - - -LOG = logging.getLogger(__name__) - -TaaS_DRIVER_NAME = 'Taas OVS driver' - - -class OVSBridge_tap_extension(ovs_lib.OVSBridge): - def __init__(self, br_name, root_helper): - super(OVSBridge_tap_extension, self).__init__(br_name) - - -class OvsTaasDriver(taas_base.TaasAgentDriver): - def __init__(self): - super(OvsTaasDriver, self).__init__() - LOG.debug("Initializing Taas OVS Driver") - self.agent_api = None - self.root_helper = common.get_root_helper(cfg.CONF) - - def initialize(self): - self.int_br = self.agent_api.request_int_br() - self.tun_br = self.agent_api.request_tun_br() - self.tap_br = OVSBridge_tap_extension('br-tap', self.root_helper) - - # Prepare OVS bridges for TaaS - self.setup_ovs_bridges() - - # Setup key-value manager for ingress BCMC flows - self.bcmc_kvm = taas_ovs_utils.key_value_mgr(4096) - - def setup_ovs_bridges(self): - # - # br-int : Integration Bridge - # br-tap : Tap Bridge - # br-tun : Tunnel Bridge - # - - # Create br-tap - self.tap_br.create() - - # Connect br-tap to br-int and br-tun - self.int_br.add_patch_port('patch-int-tap', 'patch-tap-int') - self.tap_br.add_patch_port('patch-tap-int', 'patch-int-tap') - self.tun_br.add_patch_port('patch-tun-tap', 'patch-tap-tun') - self.tap_br.add_patch_port('patch-tap-tun', 'patch-tun-tap') - - # Get patch port IDs - patch_tap_int_id = self.tap_br.get_port_ofport('patch-tap-int') - patch_tap_tun_id = self.tap_br.get_port_ofport('patch-tap-tun') - patch_tun_tap_id = self.tun_br.get_port_ofport('patch-tun-tap') - - # Purge all existing Taas flows from br-tap and br-tun - self.tap_br.delete_flows(table=0) - self.tap_br.delete_flows(table=taas_ovs_consts.TAAS_RECV_LOC) - self.tap_br.delete_flows(table=taas_ovs_consts.TAAS_RECV_REM) - - self.tun_br.delete_flows(table=0, - in_port=patch_tun_tap_id) - self.tun_br.delete_flows(table=taas_ovs_consts.TAAS_SEND_UCAST) - self.tun_br.delete_flows(table=taas_ovs_consts.TAAS_SEND_FLOOD) - self.tun_br.delete_flows(table=taas_ovs_consts.TAAS_CLASSIFY) - self.tun_br.delete_flows(table=taas_ovs_consts.TAAS_DST_CHECK) - self.tun_br.delete_flows(table=taas_ovs_consts.TAAS_SRC_CHECK) - self.tun_br.delete_flows(table=taas_ovs_consts.TAAS_DST_RESPOND) - self.tun_br.delete_flows(table=taas_ovs_consts.TAAS_SRC_RESPOND) - - # - # Configure standard TaaS flows in br-tap - # - self.tap_br.add_flow(table=0, - priority=1, - in_port=patch_tap_int_id, - actions="resubmit(,%s)" % - taas_ovs_consts.TAAS_RECV_LOC) - - self.tap_br.add_flow(table=0, - priority=1, - in_port=patch_tap_tun_id, - actions="resubmit(,%s)" % - taas_ovs_consts.TAAS_RECV_REM) - - self.tap_br.add_flow(table=0, - priority=0, - actions="drop") - - self.tap_br.add_flow(table=taas_ovs_consts.TAAS_RECV_LOC, - priority=0, - actions="output:%s" % str(patch_tap_tun_id)) - - self.tap_br.add_flow(table=taas_ovs_consts.TAAS_RECV_REM, - priority=0, - actions="drop") - - # - # Configure standard Taas flows in br-tun - # - self.tun_br.add_flow(table=0, - priority=1, - in_port=patch_tun_tap_id, - actions="resubmit(,%s)" % - taas_ovs_consts.TAAS_SEND_UCAST) - - self.tun_br.add_flow(table=taas_ovs_consts.TAAS_SEND_UCAST, - priority=0, - actions="resubmit(,%s)" % - taas_ovs_consts.TAAS_SEND_FLOOD) - - flow_action = self._create_tunnel_flood_flow_action() - if flow_action != "": - self.tun_br.add_flow(table=taas_ovs_consts.TAAS_SEND_FLOOD, - priority=0, - actions=flow_action) - - self.tun_br.add_flow(table=taas_ovs_consts.TAAS_CLASSIFY, - priority=2, - reg0=0, - actions="resubmit(,%s)" % - taas_ovs_consts.TAAS_DST_CHECK) - - self.tun_br.add_flow(table=taas_ovs_consts.TAAS_CLASSIFY, - priority=1, - reg0=1, - actions="resubmit(,%s)" % - taas_ovs_consts.TAAS_DST_CHECK) - - self.tun_br.add_flow(table=taas_ovs_consts.TAAS_CLASSIFY, - priority=1, - reg0=2, - actions="resubmit(,%s)" % - taas_ovs_consts.TAAS_SRC_CHECK) - - self.tun_br.add_flow(table=taas_ovs_consts.TAAS_DST_CHECK, - priority=0, - actions="drop") - - self.tun_br.add_flow(table=taas_ovs_consts.TAAS_SRC_CHECK, - priority=0, - actions="drop") - - self.tun_br.add_flow(table=taas_ovs_consts.TAAS_DST_RESPOND, - priority=2, - reg0=0, - actions="output:%s" % str(patch_tun_tap_id)) - - self.tun_br.add_flow(table=taas_ovs_consts.TAAS_DST_RESPOND, - priority=1, - reg0=1, - actions=( - "output:%s," - "move:NXM_OF_VLAN_TCI[0..11]->NXM_NX_TUN_ID" - "[0..11],mod_vlan_vid:2,output:in_port" % - str(patch_tun_tap_id))) - - self.tun_br.add_flow(table=taas_ovs_consts.TAAS_SRC_RESPOND, - priority=1, - actions=( - "learn(table=%s,hard_timeout=60," - "priority=1,NXM_OF_VLAN_TCI[0..11]," - "load:NXM_OF_VLAN_TCI[0..11]->NXM_NX_TUN_ID" - "[0..11],load:0->NXM_OF_VLAN_TCI[0..11]," - "output:NXM_OF_IN_PORT[])" % - taas_ovs_consts.TAAS_SEND_UCAST)) - - return - - def consume_api(self, agent_api): - self.agent_api = agent_api - - def create_tap_service(self, tap_service): - taas_id = tap_service['taas_id'] - port = tap_service['port'] - - # Get OVS port id for tap service port - ovs_port = self.int_br.get_vif_port_by_id(port['id']) - ovs_port_id = ovs_port.ofport - - # Get VLAN id for tap service port - port_dict = self.int_br.get_port_tag_dict() - port_vlan_id = port_dict[ovs_port.port_name] - - # Get patch port IDs - patch_int_tap_id = self.int_br.get_port_ofport('patch-int-tap') - patch_tap_int_id = self.tap_br.get_port_ofport('patch-tap-int') - - # Add flow(s) in br-int - self.int_br.add_flow(table=0, - priority=25, - in_port=patch_int_tap_id, - dl_vlan=taas_id, - actions="mod_vlan_vid:%s,output:%s" % - (str(port_vlan_id), str(ovs_port_id))) - - # Add flow(s) in br-tap - self.tap_br.add_flow(table=taas_ovs_consts.TAAS_RECV_LOC, - priority=1, - dl_vlan=taas_id, - actions="output:in_port") - - self.tap_br.add_flow(table=taas_ovs_consts.TAAS_RECV_REM, - priority=1, - dl_vlan=taas_id, - actions="output:%s" % str(patch_tap_int_id)) - - # Add flow(s) in br-tun - for tunnel_type in ovs_consts.TUNNEL_NETWORK_TYPES: - self.tun_br.add_flow(table=ovs_consts.TUN_TABLE[tunnel_type], - priority=1, - tun_id=taas_id, - actions=( - "move:NXM_OF_VLAN_TCI[0..11]->" - "NXM_NX_REG0[0..11],move:NXM_NX_TUN_ID" - "[0..11]->NXM_OF_VLAN_TCI[0..11]," - "resubmit(,%s)" % - taas_ovs_consts.TAAS_CLASSIFY)) - - self.tun_br.add_flow(table=taas_ovs_consts.TAAS_DST_CHECK, - priority=1, - tun_id=taas_id, - actions="resubmit(,%s)" % - taas_ovs_consts.TAAS_DST_RESPOND) - - # - # Disable mac-address learning in the Linux bridge to which - # the OVS port is attached (via the veth pair). This will - # effectively turn the bridge into a hub, ensuring that all - # incoming mirrored traffic reaches the tap interface (used - # for attaching a VM to the bridge) irrespective of the - # destination mac addresses in mirrored packets. - # - ovs_port_name = ovs_port.port_name - linux_br_name = ovs_port_name.replace('qvo', 'qbr') - utils.execute(['brctl', 'setageing', linux_br_name, 0], - run_as_root=True) - - return - - def delete_tap_service(self, tap_service): - taas_id = tap_service['taas_id'] - - # Get patch port ID - patch_int_tap_id = self.int_br.get_port_ofport('patch-int-tap') - - # Delete flow(s) from br-int - self.int_br.delete_flows(table=0, - in_port=patch_int_tap_id, - dl_vlan=taas_id) - - # Delete flow(s) from br-tap - self.tap_br.delete_flows(table=taas_ovs_consts.TAAS_RECV_LOC, - dl_vlan=taas_id) - - self.tap_br.delete_flows(table=taas_ovs_consts.TAAS_RECV_REM, - dl_vlan=taas_id) - - # Delete flow(s) from br-tun - for tunnel_type in ovs_consts.TUNNEL_NETWORK_TYPES: - self.tun_br.delete_flows(table=ovs_consts.TUN_TABLE[tunnel_type], - tun_id=taas_id) - - self.tun_br.delete_flows(table=taas_ovs_consts.TAAS_DST_CHECK, - tun_id=taas_id) - - self.tun_br.delete_flows(table=taas_ovs_consts.TAAS_SRC_CHECK, - tun_id=taas_id) - - return - - def create_tap_flow(self, tap_flow): - taas_id = tap_flow['taas_id'] - port = tap_flow['port'] - direction = tap_flow['tap_flow']['direction'] - - # Get OVS port id for tap flow port - ovs_port = self.int_br.get_vif_port_by_id(port['id']) - ovs_port_id = ovs_port.ofport - - # Get patch port ID - patch_int_tap_id = self.int_br.get_port_ofport('patch-int-tap') - - # Add flow(s) in br-int - if direction == 'OUT' or direction == 'BOTH': - self.int_br.add_flow(table=0, - priority=20, - in_port=ovs_port_id, - actions="normal,mod_vlan_vid:%s,output:%s" % - (str(taas_id), str(patch_int_tap_id))) - - if direction == 'IN' or direction == 'BOTH': - port_mac = tap_flow['port_mac'] - - # - # Note: The ingress side flow (for unicast traffic) should - # include a check for the 'VLAN id of the Neutron - # network the port belongs to' + 'MAC address of the - # port', to comply with the requirement that port MAC - # addresses are unique only within a Neutron network. - # Unfortunately, at the moment there is no clean way - # to implement such a check, given OVS's handling of - # VLAN tags and Neutron's use of the NORMAL action in - # br-int. - # - # We are therefore temporarily disabling the VLAN id - # check until a mechanism is available to implement - # it correctly. The {broad,multi}cast flow, which is - # also dependent on the VLAN id, has been disabled - # for the same reason. - # - - # Get VLAN id for tap flow port - # port_dict = self.int_br.get_port_tag_dict() - # port_vlan_id = port_dict[ovs_port.port_name] - - self.int_br.add_flow(table=0, - priority=20, - # dl_vlan=port_vlan_id, - dl_dst=port_mac, - actions="normal,mod_vlan_vid:%s,output:%s" % - (str(taas_id), str(patch_int_tap_id))) - - # self._add_update_ingress_bcmc_flow(port_vlan_id, - # taas_id, - # patch_int_tap_id) - - # Add flow(s) in br-tun - for tunnel_type in ovs_consts.TUNNEL_NETWORK_TYPES: - self.tun_br.add_flow(table=ovs_consts.TUN_TABLE[tunnel_type], - priority=1, - tun_id=taas_id, - actions=( - "move:NXM_OF_VLAN_TCI[0..11]->" - "NXM_NX_REG0[0..11],move:NXM_NX_TUN_ID" - "[0..11]->NXM_OF_VLAN_TCI[0..11]," - "resubmit(,%s)" % - taas_ovs_consts.TAAS_CLASSIFY)) - - self.tun_br.add_flow(table=taas_ovs_consts.TAAS_SRC_CHECK, - priority=1, - tun_id=taas_id, - actions="resubmit(,%s)" % - taas_ovs_consts.TAAS_SRC_RESPOND) - - return - - def delete_tap_flow(self, tap_flow): - port = tap_flow['port'] - direction = tap_flow['tap_flow']['direction'] - - # Get OVS port id for tap flow port - ovs_port = self.int_br.get_vif_port_by_id(port['id']) - ovs_port_id = ovs_port.ofport - - # Delete flow(s) from br-int - if direction == 'OUT' or direction == 'BOTH': - self.int_br.delete_flows(table=0, - in_port=ovs_port_id) - - if direction == 'IN' or direction == 'BOTH': - port_mac = tap_flow['port_mac'] - - # - # The VLAN id related checks have been temporarily disabled. - # Please see comment in create_tap_flow() for details. - # - - # taas_id = tap_flow['taas_id'] - - # Get VLAN id for tap flow port - # port_dict = self.int_br.get_port_tag_dict() - # port_vlan_id = port_dict[ovs_port.port_name] - - # Get patch port ID - # patch_int_tap_id = self.int_br.get_port_ofport('patch-int-tap') - - self.int_br.delete_flows(table=0, - # dl_vlan=port_vlan_id, - dl_dst=port_mac) - - # self._del_update_ingress_bcmc_flow(port_vlan_id, - # taas_id, - # patch_int_tap_id) - - return - - def update_tunnel_flood_flow(self): - flow_action = self._create_tunnel_flood_flow_action() - if flow_action != "": - self.tun_br.mod_flow(table=taas_ovs_consts.TAAS_SEND_FLOOD, - actions=flow_action) - - def _create_tunnel_flood_flow_action(self): - - args = ["ovs-vsctl", "list-ports", "br-tun"] - res = utils.execute(args, run_as_root=True) - - port_name_list = res.splitlines() - - flow_action = ("move:NXM_OF_VLAN_TCI[0..11]->NXM_NX_TUN_ID[0..11]," - "mod_vlan_vid:1") - - tunnel_ports_exist = False - - for port_name in port_name_list: - if (port_name != 'patch-int') and (port_name != 'patch-tun-tap'): - flow_action += (",output:%d" % - self.tun_br.get_port_ofport(port_name)) - tunnel_ports_exist = True - - if tunnel_ports_exist: - return flow_action - else: - return "" - - def _create_ingress_bcmc_flow_action(self, taas_id_list, out_port_id): - flow_action = "normal" - for taas_id in taas_id_list: - flow_action += (",mod_vlan_vid:%d,output:%d" % - (taas_id, out_port_id)) - - return flow_action - - # - # Adds or updates a special flow in br-int to mirror (duplicate and - # redirect to 'out_port_id') all ingress broadcast/multicast traffic, - # associated with a VLAN, to possibly multiple tap service instances. - # - def _add_update_ingress_bcmc_flow(self, vlan_id, taas_id, out_port_id): - # Add a tap service instance affiliation with VLAN - self.bcmc_kvm.affiliate(vlan_id, taas_id) - - # Find all tap service instances affiliated with VLAN - taas_id_list = self.bcmc_kvm.list_affiliations(vlan_id) - - # - # Add/update flow to mirror ingress BCMC traffic, associated - # with VLAN, to all affiliated tap-service instances. - # - flow_action = self._create_ingress_bcmc_flow_action(taas_id_list, - out_port_id) - self.int_br.add_flow(table=0, - priority=20, - dl_vlan=vlan_id, - dl_dst="01:00:00:00:00:00/01:00:00:00:00:00", - actions=flow_action) - - return - - # - # Removes or updates a special flow in br-int to mirror (duplicate - # and redirect to 'out_port_id') all ingress broadcast/multicast - # traffic, associated with a VLAN, to possibly multiple tap-service - # instances. - # - def _del_update_ingress_bcmc_flow(self, vlan_id, taas_id, out_port_id): - # Remove a tap-service instance affiliation with VLAN - self.bcmc_kvm.unaffiliate(vlan_id, taas_id) - - # Find all tap-service instances affiliated with VLAN - taas_id_list = self.bcmc_kvm.list_affiliations(vlan_id) - - # - # If there are tap service instances affiliated with VLAN, update - # the flow to mirror ingress BCMC traffic, associated with VLAN, - # to all of them. Otherwise, remove the flow. - # - if taas_id_list: - flow_action = self._create_ingress_bcmc_flow_action(taas_id_list, - out_port_id) - self.int_br.add_flow(table=0, - priority=20, - dl_vlan=vlan_id, - dl_dst="01:00:00:00:00:00/01:00:00:00:00:00", - actions=flow_action) - else: - self.int_br.delete_flows(table=0, - dl_vlan=vlan_id, - dl_dst=("01:00:00:00:00:00/" - "01:00:00:00:00:00")) - - return diff --git a/neutron_taas/services/taas/drivers/linux/ovs_utils.py b/neutron_taas/services/taas/drivers/linux/ovs_utils.py deleted file mode 100644 index b73983d..0000000 --- a/neutron_taas/services/taas/drivers/linux/ovs_utils.py +++ /dev/null @@ -1,99 +0,0 @@ -# Copyright (C) 2015 Ericsson AB -# Copyright (c) 2015 Gigamon -# -# 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. - - -# -# This class implements a simple key-value manager that can support -# the following relationships. -# -# - Multiple values may be affiliated with a key. -# - A value may be affiliated with multiple keys. -# - A value may be affiliated with a key multiple times. -# -class key_value_mgr(object): - # - # Initializes internal state for specified # keys - # - def __init__(self, nr_keys): - self.key_list = [] - for i in range(nr_keys): - self.key_list.append([]) - - return - - # - # Returns specified key-value affilation, if it exists. - # - def _find_affiliation(self, key, value): - aff_list = self.key_list[key] - - for aff in aff_list: - if aff['value'] == value: - return aff - - return None - - # - # Adds an affiliation of 'value' with 'key' - # - def affiliate(self, key, value): - # Locate key-value affiliation - aff = self._find_affiliation(key, value) - if aff is None: - # Create a (new) key-value affiliation - aff = { - 'value': value, - 'refcnt': 0, - } - aff_list = self.key_list[key] - aff_list.append(aff) - - # Increment affiliation reference count - aff['refcnt'] += 1 - - return - - # - # Removes an affiliation of 'value' with 'key' - # - def unaffiliate(self, key, value): - # Locate key-value affiliation - aff = self._find_affiliation(key, value) - if aff is None: - return - - # Decrement affiliation reference count - aff['refcnt'] -= 1 - - # Destroy affiliation iff no outstanding references - if aff['refcnt'] <= 0: - aff_list = self.key_list[key] - aff_list.remove(aff) - - return - - # - # Lists all values affiliated with 'key' - # - # Note: The returned list is a set (contains no duplicates) - # - def list_affiliations(self, key): - aff_list = self.key_list[key] - - value_list = [] - for aff in aff_list: - value_list.append(aff['value']) - - return value_list diff --git a/neutron_taas/services/taas/service_drivers/__init__.py b/neutron_taas/services/taas/service_drivers/__init__.py deleted file mode 100644 index cc0e092..0000000 --- a/neutron_taas/services/taas/service_drivers/__init__.py +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright (C) 2016 Midokura SARL. -# -# 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 abc - -import six - - -@six.add_metaclass(abc.ABCMeta) -class TaasBaseDriver(object): - - def __init__(self, service_plugin): - self.service_plugin = service_plugin - - @property - def service_type(self): - pass - - @abc.abstractmethod - def create_tap_service_precommit(self, context): - pass - - @abc.abstractmethod - def delete_tap_service_precommit(self, context): - pass - - @abc.abstractmethod - def create_tap_flow_precommit(self, context): - pass - - @abc.abstractmethod - def delete_tap_flow_precommit(self, context): - pass - - @abc.abstractmethod - def create_tap_service_postcommit(self, context): - pass - - @abc.abstractmethod - def delete_tap_service_postcommit(self, context): - pass - - @abc.abstractmethod - def create_tap_flow_postcommit(self, context): - pass - - @abc.abstractmethod - def delete_tap_flow_postcommit(self, context): - pass diff --git a/neutron_taas/services/taas/service_drivers/service_driver_context.py b/neutron_taas/services/taas/service_drivers/service_driver_context.py deleted file mode 100644 index 3df97aa..0000000 --- a/neutron_taas/services/taas/service_drivers/service_driver_context.py +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright (C) 2016 Midokura SARL. -# -# 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 neutron_taas.extensions import taas - -from oslo_log import log - -LOG = log.getLogger(__name__) - - -class ServiceDriverContext(object): - """ServiceDriverContext context base class""" - def __init__(self, service_plugin, plugin_context): - self._plugin = service_plugin - self._plugin_context = plugin_context - - -class TapServiceContext(ServiceDriverContext): - - def __init__(self, service_plugin, plugin_context, tap_service): - super(TapServiceContext, self).__init__(service_plugin, plugin_context) - self._tap_service = tap_service - self._tap_id_association = None - self._setup_tap_id_association(tap_service['id']) - - def _setup_tap_id_association(self, tap_service_id): - try: - self._tap_id_association = self._plugin.get_tap_id_association( - self._plugin_context, tap_service_id) - except taas.TapServiceNotFound: - LOG.debug("Not found tap_ip_association for tap_service: %s", - tap_service_id) - - @property - def tap_service(self): - return self._tap_service - - @property - def tap_id_association(self): - return self._tap_id_association - - @tap_id_association.setter - def tap_id_association(self, tap_id_association): - """Set tap_id_association in context""" - self._tap_id_association = tap_id_association - - -class TapFlowContext(ServiceDriverContext): - - def __init__(self, service_plugin, plugin_context, tap_flow): - super(TapFlowContext, self).__init__(service_plugin, plugin_context) - self._tap_flow = tap_flow - - @property - def tap_flow(self): - return self._tap_flow diff --git a/neutron_taas/services/taas/service_drivers/taas_agent_api.py b/neutron_taas/services/taas/service_drivers/taas_agent_api.py deleted file mode 100644 index 4d3fa8e..0000000 --- a/neutron_taas/services/taas/service_drivers/taas_agent_api.py +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright (C) 2016 Midokura SARL. -# Copyright (C) 2015 Ericsson AB -# Copyright (c) 2015 Gigamon -# -# 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 neutron_lib import rpc as n_rpc -from oslo_log import log as logging -import oslo_messaging as messaging - -LOG = logging.getLogger(__name__) - - -class TaasCallbacks(object): - """Currently there are no callbacks to the Taas Plugin.""" - - def __init__(self, plugin): - super(TaasCallbacks, self).__init__() - self.plugin = plugin - return - - -class TaasAgentApi(object): - """RPC calls to agent APIs""" - - def __init__(self, topic, host): - self.host = host - target = messaging.Target(topic=topic, version='1.0') - self.client = n_rpc.get_client(target) - return - - def create_tap_service(self, context, tap_service, host): - LOG.debug("In RPC Call for Create Tap Service: Host=%s, MSG=%s" % - (host, tap_service)) - - cctxt = self.client.prepare(fanout=True) - cctxt.cast(context, 'create_tap_service', tap_service=tap_service, - host=host) - - return - - def create_tap_flow(self, context, tap_flow_msg, host): - LOG.debug("In RPC Call for Create Tap Flow: Host=%s, MSG=%s" % - (host, tap_flow_msg)) - - cctxt = self.client.prepare(fanout=True) - cctxt.cast(context, 'create_tap_flow', tap_flow_msg=tap_flow_msg, - host=host) - - return - - def delete_tap_service(self, context, tap_service, host): - LOG.debug("In RPC Call for Delete Tap Service: Host=%s, MSG=%s" % - (host, tap_service)) - - cctxt = self.client.prepare(fanout=True) - cctxt.cast(context, 'delete_tap_service', tap_service=tap_service, - host=host) - - return - - def delete_tap_flow(self, context, tap_flow_msg, host): - LOG.debug("In RPC Call for Delete Tap Flow: Host=%s, MSG=%s" % - (host, tap_flow_msg)) - - cctxt = self.client.prepare(fanout=True) - cctxt.cast(context, 'delete_tap_flow', tap_flow_msg=tap_flow_msg, - host=host) - - return diff --git a/neutron_taas/services/taas/service_drivers/taas_rpc.py b/neutron_taas/services/taas/service_drivers/taas_rpc.py deleted file mode 100644 index b8efee1..0000000 --- a/neutron_taas/services/taas/service_drivers/taas_rpc.py +++ /dev/null @@ -1,158 +0,0 @@ -# Copyright (C) 2016 Midokura SARL. -# Copyright (C) 2015 Ericsson AB -# Copyright (c) 2015 Gigamon -# -# 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 neutron_lib import exceptions as n_exc -from neutron_lib import rpc as n_rpc -from neutron_taas.common import topics -from neutron_taas.services.taas import service_drivers -from neutron_taas.services.taas.service_drivers import taas_agent_api - -from oslo_config import cfg -from oslo_log import log as logging - -LOG = logging.getLogger(__name__) - - -class TaasRpcDriver(service_drivers.TaasBaseDriver): - """Taas Rpc Service Driver class""" - - def __init__(self, service_plugin): - LOG.debug("Loading TaasRpcDriver.") - super(TaasRpcDriver, self).__init__(service_plugin) - self.endpoints = [taas_agent_api.TaasCallbacks(service_plugin)] - self.conn = n_rpc.Connection() - self.conn.create_consumer(topics.TAAS_PLUGIN, - self.endpoints, fanout=False) - - self.conn.consume_in_threads() - - self.agent_rpc = taas_agent_api.TaasAgentApi( - topics.TAAS_AGENT, - cfg.CONF.host - ) - - return - - def _get_taas_id(self, context, tf): - ts = self.service_plugin.get_tap_service(context, - tf['tap_service_id']) - taas_id = (self.service_plugin.get_tap_id_association( - context, - tap_service_id=ts['id']))['taas_id'] - return taas_id - - def create_tap_service_precommit(self, context): - ts = context.tap_service - tap_id_association = context._plugin.create_tap_id_association( - context._plugin_context, ts['id']) - context.tap_id_association = tap_id_association - - def create_tap_service_postcommit(self, context): - """Send tap service creation RPC message to agent. - - This RPC message includes taas_id that is added vlan_range_start to - so that taas-ovs-agent can use taas_id as VLANID. - """ - # Get taas id associated with the Tap Service - ts = context.tap_service - tap_id_association = context.tap_id_association - taas_vlan_id = tap_id_association['taas_id'] - port = self.service_plugin._get_port_details(context._plugin_context, - ts['port_id']) - host = port['binding:host_id'] - - rpc_msg = {'tap_service': ts, - 'taas_id': taas_vlan_id, - 'port': port} - - self.agent_rpc.create_tap_service(context._plugin_context, - rpc_msg, host) - return - - def delete_tap_service_precommit(self, context): - pass - - def delete_tap_service_postcommit(self, context): - """Send tap service deletion RPC message to agent. - - This RPC message includes taas_id that is added vlan_range_start to - so that taas-ovs-agent can use taas_id as VLANID. - """ - ts = context.tap_service - tap_id_association = context.tap_id_association - taas_vlan_id = tap_id_association['taas_id'] - - try: - port = self.service_plugin._get_port_details( - context._plugin_context, - ts['port_id']) - host = port['binding:host_id'] - except n_exc.PortNotFound: - # if not found, we just pass to None - port = None - host = None - - rpc_msg = {'tap_service': ts, - 'taas_id': taas_vlan_id, - 'port': port} - - self.agent_rpc.delete_tap_service(context._plugin_context, - rpc_msg, host) - return - - def create_tap_flow_precommit(self, context): - pass - - def create_tap_flow_postcommit(self, context): - """Send tap flow creation RPC message to agent.""" - tf = context.tap_flow - taas_id = self._get_taas_id(context._plugin_context, tf) - # Extract the host where the source port is located - port = self.service_plugin._get_port_details(context._plugin_context, - tf['source_port']) - host = port['binding:host_id'] - port_mac = port['mac_address'] - # Send RPC message to both the source port host and - # tap service(destination) port host - rpc_msg = {'tap_flow': tf, - 'port_mac': port_mac, - 'taas_id': taas_id, - 'port': port} - - self.agent_rpc.create_tap_flow(context._plugin_context, rpc_msg, host) - return - - def delete_tap_flow_precommit(self, context): - pass - - def delete_tap_flow_postcommit(self, context): - """Send tap flow deletion RPC message to agent.""" - tf = context.tap_flow - taas_id = self._get_taas_id(context._plugin_context, tf) - # Extract the host where the source port is located - port = self.service_plugin._get_port_details(context._plugin_context, - tf['source_port']) - host = port['binding:host_id'] - port_mac = port['mac_address'] - # Send RPC message to both the source port host and - # tap service(destination) port host - rpc_msg = {'tap_flow': tf, - 'port_mac': port_mac, - 'taas_id': taas_id, - 'port': port} - - self.agent_rpc.delete_tap_flow(context._plugin_context, rpc_msg, host) - return diff --git a/neutron_taas/services/taas/taas_plugin.py b/neutron_taas/services/taas/taas_plugin.py deleted file mode 100644 index 95fb18f..0000000 --- a/neutron_taas/services/taas/taas_plugin.py +++ /dev/null @@ -1,211 +0,0 @@ -# Copyright (C) 2016 Midokura SARL. -# Copyright (C) 2015 Ericsson AB -# Copyright (c) 2015 Gigamon -# -# 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 neutron.db import servicetype_db as st_db -from neutron.services import provider_configuration as pconf -from neutron.services import service_base -from neutron_lib.callbacks import events -from neutron_lib.callbacks import registry -from neutron_lib.callbacks import resources -from neutron_lib import exceptions as n_exc - -from neutron_taas.common import constants -from neutron_taas.db import taas_db -from neutron_taas.extensions import taas as taas_ex -from neutron_taas.services.taas.service_drivers import (service_driver_context - as sd_context) - -from oslo_log import log as logging -from oslo_utils import excutils - -LOG = logging.getLogger(__name__) - - -def add_provider_configuration(type_manager, service_type): - type_manager.add_provider_configuration( - service_type, - pconf.ProviderConfiguration('neutron_taas')) - - -@registry.has_registry_receivers -class TaasPlugin(taas_db.Taas_db_Mixin): - - supported_extension_aliases = ["taas"] - path_prefix = "/taas" - - def __init__(self): - - LOG.debug("TAAS PLUGIN INITIALIZED") - self.service_type_manager = st_db.ServiceTypeManager.get_instance() - add_provider_configuration(self.service_type_manager, constants.TAAS) - self._load_drivers() - self.driver = self._get_driver_for_provider(self.default_provider) - - return - - def _load_drivers(self): - """Loads plugin-drivers specified in configuration.""" - self.drivers, self.default_provider = service_base.load_drivers( - 'TAAS', self) - - def _get_driver_for_provider(self, provider): - if provider in self.drivers: - return self.drivers[provider] - raise n_exc.Invalid("Error retrieving driver for provider %s" % - provider) - - def create_tap_service(self, context, tap_service): - LOG.debug("create_tap_service() called") - - t_s = tap_service['tap_service'] - tenant_id = t_s['tenant_id'] - port_id = t_s['port_id'] - - # Get port details - port = self._get_port_details(context, port_id) - - # Check if the port is owned by the tenant. - if port['tenant_id'] != tenant_id: - raise taas_ex.PortDoesNotBelongToTenant() - - # Extract the host where the port is located - host = port['binding:host_id'] - - if host is not None: - LOG.debug("Host on which the port is created = %s" % host) - else: - LOG.debug("Host could not be found, Port Binding disbaled!") - - # Create tap service in the db model - with context.session.begin(subtransactions=True): - ts = super(TaasPlugin, self).create_tap_service(context, - tap_service) - driver_context = sd_context.TapServiceContext(self, context, ts) - self.driver.create_tap_service_precommit(driver_context) - - try: - self.driver.create_tap_service_postcommit(driver_context) - except Exception: - with excutils.save_and_reraise_exception(): - LOG.error("Failed to create tap service on driver," - "deleting tap_service %s", ts['id']) - super(TaasPlugin, self).delete_tap_service(context, ts['id']) - - return ts - - def delete_tap_service(self, context, id): - LOG.debug("delete_tap_service() called") - - # Get all the tap Flows that are associated with the Tap service - # and delete them as well - t_f_collection = self.get_tap_flows( - context, - filters={'tap_service_id': [id]}, fields=['id']) - - for t_f in t_f_collection: - self.delete_tap_flow(context, t_f['id']) - - with context.session.begin(subtransactions=True): - ts = self.get_tap_service(context, id) - driver_context = sd_context.TapServiceContext(self, context, ts) - super(TaasPlugin, self).delete_tap_service(context, id) - self.driver.delete_tap_service_precommit(driver_context) - - try: - self.driver.delete_tap_service_postcommit(driver_context) - except Exception: - with excutils.save_and_reraise_exception(): - LOG.error("Failed to delete tap service on driver. " - "tap_sevice: %s", id) - - def create_tap_flow(self, context, tap_flow): - LOG.debug("create_tap_flow() called") - - t_f = tap_flow['tap_flow'] - tenant_id = t_f['tenant_id'] - - # Check if the tenant id of the source port is the same as the - # tenant_id of the tap service we are attaching it to. - - ts = self.get_tap_service(context, t_f['tap_service_id']) - ts_tenant_id = ts['tenant_id'] - - if tenant_id != ts_tenant_id: - raise taas_ex.TapServiceNotBelongToTenant() - - # create tap flow in the db model - with context.session.begin(subtransactions=True): - tf = super(TaasPlugin, self).create_tap_flow(context, tap_flow) - driver_context = sd_context.TapFlowContext(self, context, tf) - self.driver.create_tap_flow_precommit(driver_context) - - try: - self.driver.create_tap_flow_postcommit(driver_context) - except Exception: - with excutils.save_and_reraise_exception(): - LOG.error("Failed to create tap flow on driver," - "deleting tap_flow %s", tf['id']) - super(TaasPlugin, self).delete_tap_flow(context, tf['id']) - - return tf - - def delete_tap_flow(self, context, id): - LOG.debug("delete_tap_flow() called") - - with context.session.begin(subtransactions=True): - tf = self.get_tap_flow(context, id) - driver_context = sd_context.TapFlowContext(self, context, tf) - super(TaasPlugin, self).delete_tap_flow(context, id) - self.driver.delete_tap_flow_precommit(driver_context) - - try: - self.driver.delete_tap_flow_postcommit(driver_context) - except Exception: - with excutils.save_and_reraise_exception(): - with excutils.save_and_reraise_exception(): - LOG.error("Failed to delete tap flow on driver. " - "tap_flow: %s", id) - - @registry.receives(resources.PORT, [events.PRECOMMIT_DELETE]) - def handle_delete_port(self, resource, event, trigger, context, **kwargs): - deleted_port = kwargs['port'] - if not deleted_port: - LOG.error("TaaS: Handle Delete Port: Invalid port object received") - return - - deleted_port_id = deleted_port['id'] - LOG.info("TaaS: Handle Delete Port: %s", deleted_port_id) - - # Get list of configured tap-services - t_s_collection = self.get_tap_services( - context, - filters={'port_id': [deleted_port_id]}, fields=['id']) - - for t_s in t_s_collection: - try: - self.delete_tap_service(context, t_s['id']) - except taas_ex.TapServiceNotFound: - LOG.debug("Not found tap_service: %s", t_s['id']) - - t_f_collection = self.get_tap_flows( - context, - filters={'source_port': [deleted_port_id]}, fields=['id']) - - for t_f in t_f_collection: - try: - self.delete_tap_flow(context, t_f['id']) - except taas_ex.TapFlowNotFound: - LOG.debug("Not found tap_flow: %s", t_f['id']) diff --git a/neutron_taas/taas_client/__init__.py b/neutron_taas/taas_client/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/neutron_taas/taas_client/tapflow.py b/neutron_taas/taas_client/tapflow.py deleted file mode 100644 index b395a20..0000000 --- a/neutron_taas/taas_client/tapflow.py +++ /dev/null @@ -1,120 +0,0 @@ -# Copyright 2015 NEC Corporation -# 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 neutron_taas._i18n import _ -from neutronclient.common import extension -from neutronclient.common import utils -from neutronclient.neutron import v2_0 as neutronv20 - - -def _add_updatable_args(parser): - parser.add_argument( - '--name', - help=_('Name of this Tap flow.')) - parser.add_argument( - '--description', - help=_('Description for this Tap flow.')) - - -def _updatable_args2body(parsed_args, body): - neutronv20.update_dict(parsed_args, body, ['name', 'description']) - - -class TapFlow(extension.NeutronClientExtension): - # Define required variables for resource operations. - - resource = 'tap_flow' - resource_plural = '%ss' % resource - object_path = '/taas/%s' % resource_plural - resource_path = '/taas/%s/%%s' % resource_plural - versions = ['2.0'] - - -class ListTapFlow(extension.ClientExtensionList, TapFlow): - """List tap flows.""" - - shell_command = 'tap-flow-list' - list_columns = ['id', 'name', 'source_port', 'tap_service_id', 'status'] - pagination_support = True - sorting_support = True - - -class CreateTapFlow(extension.ClientExtensionCreate, TapFlow): - """Create a tap flow.""" - - shell_command = 'tap-flow-create' - list_columns = ['id', 'name', 'direction', 'source_port'] - - def add_known_arguments(self, parser): - _add_updatable_args(parser) - parser.add_argument( - '--port', - required=True, - metavar="SOURCE_PORT", - help=_('Source port to which the Tap Flow is connected.')) - parser.add_argument( - '--tap-service', - required=True, - metavar="TAP_SERVICE", - help=_('Tap Service to which the Tap Flow belongs.')) - parser.add_argument( - '--direction', - required=True, - metavar="DIRECTION", - choices=['IN', 'OUT', 'BOTH'], - type=utils.convert_to_uppercase, - help=_('Direction of the Tap flow.')) - - def args2body(self, parsed_args): - client = self.get_client() - source_port = neutronv20.find_resourceid_by_name_or_id( - client, 'port', - parsed_args.port) - tap_service_id = neutronv20.find_resourceid_by_name_or_id( - client, 'tap_service', - parsed_args.tap_service) - body = {'source_port': source_port, - 'tap_service_id': tap_service_id} - neutronv20.update_dict(parsed_args, body, ['tenant_id', 'direction']) - _updatable_args2body(parsed_args, body) - return {self.resource: body} - - -class DeleteTapFlow(extension.ClientExtensionDelete, TapFlow): - """Delete a tap flow.""" - - shell_command = 'tap-flow-delete' - - -class ShowTapFlow(extension.ClientExtensionShow, TapFlow): - """Show a tap flow.""" - - shell_command = 'tap-flow-show' - - -class UpdateTapFlow(extension.ClientExtensionUpdate, TapFlow): - """Update a tap flow.""" - - shell_command = 'tap-flow-update' - list_columns = ['id', 'name'] - - def add_known_arguments(self, parser): - _add_updatable_args(parser) - - def args2body(self, parsed_args): - body = {} - _updatable_args2body(parsed_args, body) - return {self.resource: body} diff --git a/neutron_taas/taas_client/tapservice.py b/neutron_taas/taas_client/tapservice.py deleted file mode 100644 index c9939e9..0000000 --- a/neutron_taas/taas_client/tapservice.py +++ /dev/null @@ -1,105 +0,0 @@ -# Copyright 2015 NEC Corporation -# 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 neutron_taas._i18n import _ -from neutronclient.common import extension -from neutronclient.neutron import v2_0 as neutronv20 - - -def _add_updatable_args(parser): - parser.add_argument( - '--name', - help=_('Name of this Tap service.')) - parser.add_argument( - '--description', - help=_('Description for this Tap service.')) - - -def _updatable_args2body(parsed_args, body): - neutronv20.update_dict(parsed_args, body, ['name', 'description']) - - -class TapService(extension.NeutronClientExtension): - # Define required variables for resource operations. - - resource = 'tap_service' - resource_plural = '%ss' % resource - object_path = '/taas/%s' % resource_plural - resource_path = '/taas/%s/%%s' % resource_plural - versions = ['2.0'] - - -class ListTapService(extension.ClientExtensionList, TapService): - """List tap services.""" - - shell_command = 'tap-service-list' - list_columns = ['id', 'name', 'port', 'status'] - pagination_support = True - sorting_support = True - - -class CreateTapService(extension.ClientExtensionCreate, TapService): - """Create a tap service.""" - - shell_command = 'tap-service-create' - list_columns = ['id', 'name', 'port'] - - def add_known_arguments(self, parser): - _add_updatable_args(parser) - parser.add_argument( - '--port', - dest='port_id', - required=True, - metavar="PORT", - help=_('Port to which the Tap service is connected.')) - - def args2body(self, parsed_args): - client = self.get_client() - port_id = neutronv20.find_resourceid_by_name_or_id( - client, 'port', - parsed_args.port_id) - body = {'port_id': port_id} - if parsed_args.tenant_id: - body['tenant_id'] = parsed_args.tenant_id - _updatable_args2body(parsed_args, body) - return {self.resource: body} - - -class DeleteTapService(extension.ClientExtensionDelete, TapService): - """Delete a tap service.""" - - shell_command = 'tap-service-delete' - - -class ShowTapService(extension.ClientExtensionShow, TapService): - """Show a tap service.""" - - shell_command = 'tap-service-show' - - -class UpdateTapService(extension.ClientExtensionUpdate, TapService): - """Update a tap service.""" - - shell_command = 'tap-service-update' - list_columns = ['id', 'name'] - - def add_known_arguments(self, parser): - _add_updatable_args(parser) - - def args2body(self, parsed_args): - body = {} - _updatable_args2body(parsed_args, body) - return {self.resource: body} diff --git a/neutron_taas/tests/__init__.py b/neutron_taas/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/neutron_taas/tests/tempest_plugin/__init__.py b/neutron_taas/tests/tempest_plugin/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/neutron_taas/tests/tempest_plugin/services/__init__.py b/neutron_taas/tests/tempest_plugin/services/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/neutron_taas/tests/tempest_plugin/tests/__init__.py b/neutron_taas/tests/tempest_plugin/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/neutron_taas/tests/tempest_plugin/tests/api/__init__.py b/neutron_taas/tests/tempest_plugin/tests/api/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/neutron_taas/tests/tempest_plugin/tests/scenario/__init__.py b/neutron_taas/tests/tempest_plugin/tests/scenario/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/neutron_taas/tests/unit/__init__.py b/neutron_taas/tests/unit/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/neutron_taas/tests/unit/db/__init__.py b/neutron_taas/tests/unit/db/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/neutron_taas/tests/unit/db/test_migrations.py b/neutron_taas/tests/unit/db/test_migrations.py deleted file mode 100644 index 0c7f847..0000000 --- a/neutron_taas/tests/unit/db/test_migrations.py +++ /dev/null @@ -1,61 +0,0 @@ -# Copyright 2016 VMware, Inc -# -# 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 - -from neutron.db.migration.alembic_migrations import external -from neutron.db.migration import cli as migration -from neutron.tests.functional.db import test_migrations -from neutron.tests.unit import testlib_api - -from neutron_taas.db import head - -# EXTERNAL_TABLES should contain all names of tables that are not related to -# current repo. -EXTERNAL_TABLES = set(external.TABLES) -VERSION_TABLE = 'taas_alembic_version' - - -class _TestModelsMigrationsTAAS(test_migrations._TestModelsMigrations): - - def db_sync(self, engine): - cfg.CONF.set_override('connection', engine.url, group='database') - for conf in migration.get_alembic_configs(): - self.alembic_config = conf - self.alembic_config.neutron_config = cfg.CONF - migration.do_alembic_command(conf, 'upgrade', 'heads') - - def get_metadata(self): - return head.get_metadata() - - def include_object(self, object_, name, type_, reflected, compare_to): - if type_ == 'table' and (name.startswith('alembic') or - name == VERSION_TABLE or - name in EXTERNAL_TABLES): - return False - if type_ == 'index' and reflected and name.startswith("idx_autoinc_"): - return False - return True - - -class TestModelsMigrationsMysql(testlib_api.MySQLTestCaseMixin, - _TestModelsMigrationsTAAS, - testlib_api.SqlTestCaseLight): - pass - - -class TestModelsMigrationsPostgresql(testlib_api.PostgreSQLTestCaseMixin, - _TestModelsMigrationsTAAS, - testlib_api.SqlTestCaseLight): - pass diff --git a/neutron_taas/tests/unit/db/test_taas_db.py b/neutron_taas/tests/unit/db/test_taas_db.py deleted file mode 100644 index 3b7d5f0..0000000 --- a/neutron_taas/tests/unit/db/test_taas_db.py +++ /dev/null @@ -1,208 +0,0 @@ -# Copyright 2016 VMware, Inc. -# 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 neutron.tests.unit import testlib_api - -from neutron_lib import context -from oslo_utils import importutils -from oslo_utils import uuidutils - -from neutron_taas.db import taas_db -from neutron_taas.extensions import taas - - -DB_PLUGIN_KLAAS = 'neutron.db.db_base_plugin_v2.NeutronDbPluginV2' -_uuid = uuidutils.generate_uuid - - -class TaaSDbTestCase(testlib_api.SqlTestCase): - - """Unit test for TaaS DB support.""" - - def setUp(self): - super(TaaSDbTestCase, self).setUp() - self.ctx = context.get_admin_context() - self.mixin = taas_db.Taas_db_Mixin() - self.plugin = importutils.import_object(DB_PLUGIN_KLAAS) - self.tenant_id = 'fake-tenant-id' - - def _get_tap_service_data(self, name='ts-1', port_id=None): - port_id = port_id or _uuid() - return {"tap_service": {"name": name, - "tenant_id": self.tenant_id, - "description": "test tap service", - "port_id": port_id}} - - def _get_tap_flow_data(self, tap_service_id, name='tf-1', - direction='BOTH', source_port=None): - source_port = source_port or _uuid() - return {"tap_flow": {"name": name, - "tenant_id": self.tenant_id, - "description": "test tap flow", - "tap_service_id": tap_service_id, - "source_port": source_port, - "direction": direction}} - - def _get_tap_service(self, tap_service_id): - """Helper method to retrieve tap service.""" - with self.ctx.session.begin(subtransactions=True): - return self.mixin.get_tap_service(self.ctx, tap_service_id) - - def _get_tap_services(self): - """Helper method to retrieve all tap services.""" - with self.ctx.session.begin(subtransactions=True): - return self.mixin.get_tap_services(self.ctx) - - def _create_tap_service(self, tap_service): - """Helper method to create tap service.""" - with self.ctx.session.begin(subtransactions=True): - return self.mixin.create_tap_service(self.ctx, tap_service) - - def _update_tap_service(self, tap_service_id, tap_service): - """Helper method to update tap service.""" - with self.ctx.session.begin(subtransactions=True): - return self.mixin.update_tap_service(self.ctx, - tap_service_id, - tap_service) - - def _delete_tap_service(self, tap_service_id): - """Helper method to delete tap service.""" - with self.ctx.session.begin(subtransactions=True): - return self.mixin.delete_tap_service(self.ctx, tap_service_id) - - def _get_tap_flow(self, tap_flow_id): - """Helper method to retrieve tap flow.""" - with self.ctx.session.begin(subtransactions=True): - return self.mixin.get_tap_flow(self.ctx, tap_flow_id) - - def _get_tap_flows(self): - """Helper method to retrieve all tap flows.""" - with self.ctx.session.begin(subtransactions=True): - return self.mixin.get_tap_flows(self.ctx) - - def _create_tap_flow(self, tap_flow): - """Helper method to create tap flow.""" - with self.ctx.session.begin(subtransactions=True): - return self.mixin.create_tap_flow(self.ctx, tap_flow) - - def _update_tap_flow(self, tap_flow_id, tap_flow): - """Helper method to update tap flow.""" - with self.ctx.session.begin(subtransactions=True): - return self.mixin.update_tap_flow(self.ctx, tap_flow_id, tap_flow) - - def _delete_tap_flow(self, tap_flow_id): - """Helper method to delete tap flow.""" - with self.ctx.session.begin(subtransactions=True): - return self.mixin.delete_tap_flow(self.ctx, tap_flow_id) - - def test_tap_service_get(self): - """Test to retrieve a tap service from the database.""" - name = 'test-tap-service' - data = self._get_tap_service_data(name=name) - result = self._create_tap_service(data) - get_result = self._get_tap_service(result['id']) - self.assertEqual(name, get_result['name']) - - def test_tap_service_create(self): - """Test to create a tap service in the database.""" - name = 'test-tap-service' - port_id = _uuid() - data = self._get_tap_service_data(name=name, port_id=port_id) - result = self._create_tap_service(data) - self.assertEqual(name, result['name']) - self.assertEqual(port_id, result['port_id']) - - def test_tap_service_list(self): - """Test to retrieve all tap services from the database.""" - name_1 = "ts-1" - data_1 = self._get_tap_service_data(name=name_1) - name_2 = "ts-2" - data_2 = self._get_tap_service_data(name=name_2) - self._create_tap_service(data_1) - self._create_tap_service(data_2) - tap_services = self._get_tap_services() - self.assertEqual(2, len(tap_services)) - - def test_tap_service_update(self): - """Test to update a tap service in the database.""" - original_name = "ts-1" - updated_name = "ts-1-got-updated" - data = self._get_tap_service_data(name=original_name) - ts = self._create_tap_service(data) - updated_data = self._get_tap_service_data(name=updated_name) - ts_updated = self._update_tap_service(ts['id'], updated_data) - self.assertEqual(updated_name, ts_updated['name']) - - def test_tap_service_delete(self): - """Test to delete a tap service from the database.""" - data = self._get_tap_service_data() - result = self._create_tap_service(data) - self._delete_tap_service(result['id']) - self.assertRaises(taas.TapServiceNotFound, - self._get_tap_service, result['id']) - - def test_tap_flow_get(self): - """Test to retrieve a tap flow from the database.""" - ts_data = self._get_tap_service_data() - ts = self._create_tap_service(ts_data) - tf_name = 'test-tap-flow' - tf_data = self._get_tap_flow_data(tap_service_id=ts['id'], - name=tf_name) - tf = self._create_tap_flow(tf_data) - get_tf = self._get_tap_flow(tf['id']) - self.assertEqual(tf_name, get_tf['name']) - - def test_tap_flow_create(self): - """Test to create a tap flow in the database.""" - ts_data = self._get_tap_service_data() - ts = self._create_tap_service(ts_data) - tf_name = 'test-tap-flow' - tf_direction = 'IN' - tf_source_port = _uuid() - tf_data = self._get_tap_flow_data(tap_service_id=ts['id'], - name=tf_name, - source_port=tf_source_port, - direction=tf_direction) - tf = self._create_tap_flow(tf_data) - self.assertEqual(tf_name, tf['name']) - self.assertEqual(tf_direction, tf['direction']) - self.assertEqual(tf_source_port, tf['source_port']) - - def test_tap_flow_list(self): - """Test to retrieve all tap flows from the database.""" - ts_data = self._get_tap_service_data() - ts = self._create_tap_service(ts_data) - tf_1_name = "tf-1" - tf_1_data = self._get_tap_flow_data(tap_service_id=ts['id'], - name=tf_1_name) - tf_2_name = "tf-2" - tf_2_data = self._get_tap_flow_data(tap_service_id=ts['id'], - name=tf_2_name) - self._create_tap_flow(tf_1_data) - self._create_tap_flow(tf_2_data) - tap_flows = self._get_tap_flows() - self.assertEqual(2, len(tap_flows)) - - def test_tap_flow_delete(self): - """Test to delete a tap flow from the database.""" - ts_data = self._get_tap_service_data() - ts = self._create_tap_service(ts_data) - tf_name = "test-tap-flow" - tf_data = self._get_tap_flow_data(tap_service_id=ts['id'], - name=tf_name) - tf = self._create_tap_flow(tf_data) - self._delete_tap_flow(tf['id']) - self.assertRaises(taas.TapFlowNotFound, - self._get_tap_flow, tf['id']) diff --git a/neutron_taas/tests/unit/extensions/__init__.py b/neutron_taas/tests/unit/extensions/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/neutron_taas/tests/unit/extensions/test_taas.py b/neutron_taas/tests/unit/extensions/test_taas.py deleted file mode 100644 index e162f23..0000000 --- a/neutron_taas/tests/unit/extensions/test_taas.py +++ /dev/null @@ -1,104 +0,0 @@ -# Copyright 2017 FUJITSU LABORATORIES LTD. - -# 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 copy -import mock -from webob import exc - -from oslo_utils import uuidutils - -from neutron.tests.unit.api.v2 import test_base as test_api_v2 -from neutron.tests.unit.extensions import base as test_api_v2_extension - -from neutron_taas.extensions import taas as taas_ext - -_uuid = uuidutils.generate_uuid -_get_path = test_api_v2._get_path - -TAP_SERVICE_PATH = 'taas/tap_services' -TAP_FLOW_PATH = 'taas/tap_flows' - - -class TaasExtensionTestCase(test_api_v2_extension.ExtensionTestCase): - fmt = 'json' - - def setUp(self): - super(TaasExtensionTestCase, self).setUp() - self.setup_extension( - 'neutron_taas.extensions.taas.TaasPluginBase', - 'TAAS', - taas_ext.Taas, - 'taas', - plural_mappings={} - ) - - def test_create_tap_service(self): - tenant_id = _uuid() - tap_service_data = { - 'tenant_id': tenant_id, - 'name': 'MyTap', - 'description': 'This is my tap service', - 'port_id': _uuid(), - 'project_id': tenant_id, - } - data = {'tap_service': tap_service_data} - expected_ret_val = copy.copy(data['tap_service']) - expected_ret_val.update({'id': _uuid()}) - instance = self.plugin.return_value - instance.create_tap_service.return_value = expected_ret_val - - res = self.api.post(_get_path(TAP_SERVICE_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_tap_service.assert_called_with( - mock.ANY, - tap_service=data) - self.assertEqual(exc.HTTPCreated.code, res.status_int) - res = self.deserialize(res) - self.assertIn('tap_service', res) - self.assertEqual(expected_ret_val, res['tap_service']) - - def test_delete_tap_service(self): - self._test_entity_delete('tap_service') - - def test_create_tap_flow(self): - tenant_id = _uuid() - tap_flow_data = { - 'tenant_id': tenant_id, - 'name': 'MyTapFlow', - 'description': 'This is my tap flow', - 'direction': 'BOTH', - 'tap_service_id': _uuid(), - 'source_port': _uuid(), - 'project_id': tenant_id, - } - data = {'tap_flow': tap_flow_data} - expected_ret_val = copy.copy(data['tap_flow']) - expected_ret_val.update({'id': _uuid()}) - instance = self.plugin.return_value - instance.create_tap_flow.return_value = expected_ret_val - - res = self.api.post(_get_path(TAP_FLOW_PATH, fmt=self.fmt), - self.serialize(data), - content_type='application/%s' % self.fmt) - instance.create_tap_flow.assert_called_with( - mock.ANY, - tap_flow=data) - self.assertEqual(exc.HTTPCreated.code, res.status_int) - res = self.deserialize(res) - self.assertIn('tap_flow', res) - self.assertEqual(expected_ret_val, res['tap_flow']) - - def test_delete_tap_flow(self): - self._test_entity_delete('tap_flow') diff --git a/neutron_taas/tests/unit/services/__init__.py b/neutron_taas/tests/unit/services/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/neutron_taas/tests/unit/services/taas/__init__.py b/neutron_taas/tests/unit/services/taas/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/neutron_taas/tests/unit/services/taas/test_taas_plugin.py b/neutron_taas/tests/unit/services/taas/test_taas_plugin.py deleted file mode 100644 index 1dec6d2..0000000 --- a/neutron_taas/tests/unit/services/taas/test_taas_plugin.py +++ /dev/null @@ -1,276 +0,0 @@ -# Copyright (C) 2015 Midokura SARL. -# 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 contextlib - -import mock -import testtools - -from neutron_lib import context -from neutron_lib import rpc as n_rpc -from neutron_lib.utils import net as n_utils -from oslo_config import cfg -from oslo_utils import uuidutils - -from neutron.tests.unit import testlib_api - -import neutron_taas.db.taas_db # noqa -import neutron_taas.extensions.taas as taas_ext -from neutron_taas.services.taas.service_drivers import taas_agent_api -from neutron_taas.services.taas import taas_plugin - - -class DummyError(Exception): - pass - - -class TestTaasPlugin(testlib_api.SqlTestCase): - def setUp(self): - super(TestTaasPlugin, self).setUp() - mock.patch.object(n_rpc, 'Connection', auto_spec=True).start() - mock.patch.object(taas_agent_api, - 'TaasCallbacks', auto_spec=True).start() - mock.patch.object(taas_agent_api, - 'TaasAgentApi', auto_spec=True).start() - self.driver = mock.MagicMock() - mock.patch('neutron.services.service_base.load_drivers', - return_value=({'dummy_provider': self.driver}, - 'dummy_provider')).start() - mock.patch('neutron.db.servicetype_db.ServiceTypeManager.get_instance', - return_value=mock.MagicMock()).start() - self._plugin = taas_plugin.TaasPlugin() - self._context = context.get_admin_context() - - self._project_id = self._tenant_id = 'tenant-X' - self._network_id = uuidutils.generate_uuid() - self._host_id = 'host-A' - self._port_id = uuidutils.generate_uuid() - self._port_details = { - 'tenant_id': self._tenant_id, - 'binding:host_id': self._host_id, - 'mac_address': n_utils.get_random_mac( - 'fa:16:3e:00:00:00'.split(':')), - } - self._tap_service = { - 'tenant_id': self._tenant_id, - 'name': 'MyTap', - 'description': 'This is my tap service', - 'port_id': self._port_id, - 'project_id': self._project_id, - } - self._tap_flow = { - 'description': 'This is my tap flow', - 'direction': 'BOTH', - 'name': 'MyTapFlow', - 'source_port': self._port_id, - 'tenant_id': self._tenant_id, - 'project_id': self._project_id, - } - - @contextlib.contextmanager - def tap_service(self): - req = { - 'tap_service': self._tap_service, - } - with mock.patch.object(self._plugin, '_get_port_details', - return_value=self._port_details): - yield self._plugin.create_tap_service(self._context, req) - self._tap_service['id'] = mock.ANY - self._tap_service['status'] = 'ACTIVE' - - self.driver.assert_has_calls([ - mock.call.create_tap_service_precommit(mock.ANY), - mock.call.create_tap_service_postcommit(mock.ANY), - ]) - pre_args = self.driver.create_tap_service_precommit.call_args[0][0] - self.assertEqual(self._context, pre_args._plugin_context) - self.assertEqual(self._tap_service, pre_args.tap_service) - post_args = self.driver.create_tap_service_postcommit.call_args[0][0] - self.assertEqual(self._context, post_args._plugin_context) - self.assertEqual(self._tap_service, post_args.tap_service) - - @contextlib.contextmanager - def tap_flow(self, tap_service, tenant_id=None): - self._tap_flow['tap_service_id'] = tap_service - if tenant_id is not None: - self._tap_flow['tenant_id'] = tenant_id - req = { - 'tap_flow': self._tap_flow, - } - with mock.patch.object(self._plugin, '_get_port_details', - return_value=self._port_details): - yield self._plugin.create_tap_flow(self._context, req) - self._tap_flow['id'] = mock.ANY - self._tap_flow['status'] = 'ACTIVE' - self._tap_service['id'] = mock.ANY - - self.driver.assert_has_calls([ - mock.call.create_tap_flow_precommit(mock.ANY), - mock.call.create_tap_flow_postcommit(mock.ANY), - ]) - pre_args = self.driver.create_tap_flow_precommit.call_args[0][0] - self.assertEqual(self._context, pre_args._plugin_context) - self.assertEqual(self._tap_flow, pre_args.tap_flow) - post_args = self.driver.create_tap_flow_postcommit.call_args[0][0] - self.assertEqual(self._context, post_args._plugin_context) - self.assertEqual(self._tap_flow, post_args.tap_flow) - - def test_create_tap_service(self): - with self.tap_service(): - pass - - def test_verify_taas_id_reused(self): - # make small range id - cfg.CONF.set_override("vlan_range_start", 1, group="taas") - cfg.CONF.set_override("vlan_range_end", 3, group="taas") - with self.tap_service() as ts_1, self.tap_service() as ts_2, \ - self.tap_service() as ts_3, self.tap_service() as ts_4: - ts_id_1 = ts_1['id'] - ts_id_2 = ts_2['id'] - ts_id_3 = ts_3['id'] - tap_id_assoc_1 = self._plugin.create_tap_id_association( - self._context, ts_id_1) - tap_id_assoc_2 = self._plugin.create_tap_id_association( - self._context, ts_id_2) - self.assertEqual(set([1, 2]), set([tap_id_assoc_1['taas_id'], - tap_id_assoc_2['taas_id']])) - with testtools.ExpectedException(taas_ext.TapServiceLimitReached): - self._plugin.create_tap_id_association( - self._context, - ts_4['id'] - ) - # free an tap_id and verify could reallocate same taas id - self._plugin.delete_tap_service(self._context, ts_id_1) - tap_id_assoc_3 = self._plugin.create_tap_id_association( - self._context, ts_id_3) - self.assertEqual(set([1, 2]), set([tap_id_assoc_3['taas_id'], - tap_id_assoc_2['taas_id']])) - - def test_create_tap_service_wrong_tenant_id(self): - self._port_details['tenant_id'] = 'other-tenant' - with testtools.ExpectedException(taas_ext.PortDoesNotBelongToTenant), \ - self.tap_service(): - pass - self.assertEqual([], self.driver.mock_calls) - - def test_create_tap_service_reach_limit(self): - # TODO(Yoichiro):Need to move this test to taas_rpc test - pass - - def test_create_tap_service_failed_on_service_driver(self): - attr = {'create_tap_service_postcommit.side_effect': DummyError} - self.driver.configure_mock(**attr) - with testtools.ExpectedException(DummyError): - req = { - 'tap_service': self._tap_service, - } - with mock.patch.object(self._plugin, '_get_port_details', - return_value=self._port_details): - self._plugin.create_tap_service(self._context, req) - - def test_delete_tap_service(self): - with self.tap_service() as ts: - self._plugin.delete_tap_service(self._context, ts['id']) - self.driver.assert_has_calls([ - mock.call.delete_tap_service_precommit(mock.ANY), - mock.call.delete_tap_service_postcommit(mock.ANY), - ]) - pre_args = self.driver.delete_tap_service_precommit.call_args[0][0] - self.assertEqual(self._context, pre_args._plugin_context) - self.assertEqual(self._tap_service, pre_args.tap_service) - post_args = self.driver.delete_tap_service_postcommit.call_args[0][0] - self.assertEqual(self._context, post_args._plugin_context) - self.assertEqual(self._tap_service, post_args.tap_service) - - def test_delete_tap_service_with_flow(self): - with self.tap_service() as ts, \ - self.tap_flow(tap_service=ts['id']): - self._plugin.delete_tap_service(self._context, ts['id']) - self.driver.assert_has_calls([ - mock.call.delete_tap_flow_precommit(mock.ANY), - mock.call.delete_tap_flow_postcommit(mock.ANY), - mock.call.delete_tap_service_precommit(mock.ANY), - mock.call.delete_tap_service_postcommit(mock.ANY), - ]) - pre_args = self.driver.delete_tap_flow_precommit.call_args[0][0] - self.assertEqual(self._context, pre_args._plugin_context) - self.assertEqual(self._tap_flow, pre_args.tap_flow) - post_args = self.driver.delete_tap_flow_postcommit.call_args[0][0] - self.assertEqual(self._context, post_args._plugin_context) - self.assertEqual(self._tap_flow, post_args.tap_flow) - pre_args = self.driver.delete_tap_service_precommit.call_args[0][0] - self.assertEqual(self._context, pre_args._plugin_context) - self.assertEqual(self._tap_service, pre_args.tap_service) - post_args = self.driver.delete_tap_service_postcommit.call_args[0][0] - self.assertEqual(self._context, post_args._plugin_context) - self.assertEqual(self._tap_service, post_args.tap_service) - - def test_delete_tap_service_non_existent(self): - with testtools.ExpectedException(taas_ext.TapServiceNotFound): - self._plugin.delete_tap_service(self._context, 'non-existent') - - def test_delete_tap_service_failed_on_service_driver(self): - attr = {'delete_tap_service_postcommit.side_effect': DummyError} - self.driver.configure_mock(**attr) - with self.tap_service() as ts: - with testtools.ExpectedException(DummyError): - self._plugin.delete_tap_service(self._context, ts['id']) - - def test_create_tap_flow(self): - with self.tap_service() as ts, self.tap_flow(tap_service=ts['id']): - pass - - def test_create_tap_flow_wrong_tenant_id(self): - with self.tap_service() as ts, \ - testtools.ExpectedException(taas_ext.TapServiceNotBelongToTenant), \ - self.tap_flow(tap_service=ts['id'], tenant_id='other-tenant'): - pass - - def test_create_tap_flow_failed_on_service_driver(self): - with self.tap_service() as ts: - attr = {'create_tap_flow_postcommit.side_effect': DummyError} - self.driver.configure_mock(**attr) - with testtools.ExpectedException(DummyError): - self._tap_flow['tap_service_id'] = ts['id'] - req = { - 'tap_flow': self._tap_flow, - } - with mock.patch.object(self._plugin, '_get_port_details', - return_value=self._port_details): - self._plugin.create_tap_flow(self._context, req) - - def test_delete_tap_flow(self): - with self.tap_service() as ts, \ - self.tap_flow(tap_service=ts['id']) as tf: - self._plugin.delete_tap_flow(self._context, tf['id']) - self._tap_flow['id'] = tf['id'] - self.driver.assert_has_calls([ - mock.call.delete_tap_flow_precommit(mock.ANY), - mock.call.delete_tap_flow_postcommit(mock.ANY), - ]) - pre_args = self.driver.delete_tap_flow_precommit.call_args[0][0] - self.assertEqual(self._context, pre_args._plugin_context) - self.assertEqual(self._tap_flow, pre_args.tap_flow) - post_args = self.driver.delete_tap_flow_postcommit.call_args[0][0] - self.assertEqual(self._context, post_args._plugin_context) - self.assertEqual(self._tap_flow, post_args.tap_flow) - - def test_delete_tap_flow_failed_on_service_driver(self): - with self.tap_service() as ts, \ - self.tap_flow(tap_service=ts['id']) as tf: - attr = {'delete_tap_flow_postcommit.side_effect': DummyError} - self.driver.configure_mock(**attr) - with testtools.ExpectedException(DummyError): - self._plugin.delete_tap_flow(self._context, tf['id']) diff --git a/neutron_taas/tests/unit/taas_client/__init__.py b/neutron_taas/tests/unit/taas_client/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/neutron_taas/tests/unit/taas_client/test_cli20_tapflow.py b/neutron_taas/tests/unit/taas_client/test_cli20_tapflow.py deleted file mode 100644 index 9e603f9..0000000 --- a/neutron_taas/tests/unit/taas_client/test_cli20_tapflow.py +++ /dev/null @@ -1,114 +0,0 @@ -# Copyright 2015 NEC Corporation -# 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 mock -import sys - -from neutron_taas.taas_client import tapflow -from neutronclient import shell -from neutronclient.tests.unit import test_cli20 - - -class CLITestV20TapFlowJSON(test_cli20.CLITestV20Base): - resource = 'tap_flow' - resource_plural = '%ss' % resource - - def setUp(self): - self._mock_extension_loading() - super(CLITestV20TapFlowJSON, self).setUp() - self.resources = self.resource_plural - self.register_non_admin_status_resource(self.resource) - - def _create_patch(self, name, func=None): - patcher = mock.patch(name) - thing = patcher.start() - return thing - - def _mock_extension_loading(self): - ext_pkg = 'neutronclient.common.extension' - contrib = self._create_patch(ext_pkg + '._discover_via_entry_points') - contrib.return_value = [("_tap_flow", tapflow)] - return contrib - - def test_ext_cmd_loaded(self): - neutron_shell = shell.NeutronShell('2.0') - extension_cmd = {'tap-flow-create': tapflow.CreateTapFlow, - 'tap-flow-delete': tapflow.DeleteTapFlow, - 'tap-flow-show': tapflow.ShowTapFlow, - 'tap-flow-list': tapflow.ListTapFlow} - for cmd_name, cmd_class in extension_cmd.items(): - found = neutron_shell.command_manager.find_command([cmd_name]) - self.assertEqual(cmd_class, found[0]) - - def _test_create_tap_flow(self, port_id="random_port", - service_id="random_service", - direction="BOTH", arg_attr=None, - name_attr=None, val_attr=None, - name=''): - # Common definition for creating Tap flow - arg_attr = arg_attr or [] - name_attr = name_attr or [] - val_attr = val_attr or [] - cmd = tapflow.CreateTapFlow(test_cli20.MyApp(sys.stdout), None) - tenant_id = 'my-tenant' - my_id = 'my-id' - args = ['--tenant-id', tenant_id, - '--port', port_id, - '--tap-service', service_id, - '--direction', direction] + arg_attr - pos_names = ['source_port', 'tap_service_id', 'direction'] + name_attr - pos_values = [port_id, service_id, direction] + val_attr - self._test_create_resource(self.resource, cmd, name, my_id, args, - pos_names, pos_values, - tenant_id=tenant_id) - - def test_create_tap_flow_mandatory_params(self): - self._test_create_tap_flow() - - def test_create_tap_flow_all_params(self): - name = 'dummyTapFlow' - description = 'Create a dummy tap flow' - self._test_create_tap_flow(name=name, - arg_attr=[ - '--name', name, - '--description', description], - name_attr=['name', 'description'], - val_attr=[name, description]) - - def test_delete_tap_flow(self): - # Delete tap_flow: myid. - cmd = tapflow.DeleteTapFlow(test_cli20.MyApp(sys.stdout), None) - myid = 'myid' - args = [myid] - self._test_delete_resource(self.resource, cmd, myid, args) - - def test_update_tap_flow(self): - # Update tap_flow: myid --name myname. - cmd = tapflow.UpdateTapFlow(test_cli20.MyApp(sys.stdout), None) - self._test_update_resource(self.resource, cmd, 'myid', - ['myid', '--name', 'myname'], - {'name': 'myname'}) - - def test_list_tap_flows(self): - # List tap_flows. - cmd = tapflow.ListTapFlow(test_cli20.MyApp(sys.stdout), None) - self._test_list_resources(self.resources, cmd, True) - - def test_show_tap_flow(self): - # Show tap_flow: --fields id --fields name myid. - cmd = tapflow.ShowTapFlow(test_cli20.MyApp(sys.stdout), None) - args = ['--fields', 'id', '--fields', 'name', self.test_id] - self._test_show_resource(self.resource, cmd, self.test_id, - args, ['id', 'name']) diff --git a/neutron_taas/tests/unit/taas_client/test_cli20_tapservice.py b/neutron_taas/tests/unit/taas_client/test_cli20_tapservice.py deleted file mode 100644 index f2cac09..0000000 --- a/neutron_taas/tests/unit/taas_client/test_cli20_tapservice.py +++ /dev/null @@ -1,113 +0,0 @@ -# Copyright 2015 NEC Corporation -# 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 mock -import sys - -from neutron_taas.taas_client import tapservice -from neutronclient import shell -from neutronclient.tests.unit import test_cli20 - - -class CLITestV20TapServiceJSON(test_cli20.CLITestV20Base): - resource = 'tap_service' - resource_plural = '%ss' % resource - - def setUp(self): - self._mock_extension_loading() - super(CLITestV20TapServiceJSON, self).setUp() - self.resources = self.resource_plural - self.register_non_admin_status_resource(self.resource) - - def _create_patch(self, name, func=None): - patcher = mock.patch(name) - thing = patcher.start() - return thing - - def _mock_extension_loading(self): - ext_pkg = 'neutronclient.common.extension' - contrib = self._create_patch(ext_pkg + '._discover_via_entry_points') - contrib.return_value = [("_tap_service", tapservice)] - return contrib - - def test_ext_cmd_loaded(self): - neutron_shell = shell.NeutronShell('2.0') - extension_cmd = {'tap-service-create': tapservice.CreateTapService, - 'tap-service-delete': tapservice.DeleteTapService, - 'tap-service-show': tapservice.ShowTapService, - 'tap-service-list': tapservice.ListTapService} - for cmd_name, cmd_class in extension_cmd.items(): - found = neutron_shell.command_manager.find_command([cmd_name]) - self.assertEqual(cmd_class, found[0]) - - def _test_create_tap_service(self, port_id="random_port", - name='', - args_attr=None, position_names_attr=None, - position_values_attr=None): - cmd = tapservice.CreateTapService(test_cli20.MyApp(sys.stdout), None) - args_attr = args_attr or [] - position_names_attr = position_names_attr or [] - position_values_attr = position_values_attr or [] - name = name - tenant_id = 'my-tenant' - my_id = 'my-id' - args = ['--tenant-id', tenant_id, - '--port', port_id] + args_attr - position_names = ['port_id'] + position_names_attr - position_values = [port_id] + position_values_attr - self._test_create_resource(self.resource, cmd, name, my_id, args, - position_names, position_values, - tenant_id=tenant_id) - - def test_create_tap_service_mandatory_params(self): - # Create tap_service: --port random_port - self._test_create_tap_service() - - def test_create_tap_service_all_params(self): - # Create tap_service with mandatory params, --name and --description - name = 'new-tap-service' - description = 'This defines a new tap-service' - args_attr = ['--name', name, '--description', description] - position_names_attr = ['name', 'description'] - position_val_attr = [name, description] - self._test_create_tap_service(name=name, args_attr=args_attr, - position_names_attr=position_names_attr, - position_values_attr=position_val_attr) - - def test_delete_tap_service(self): - # Delete tap_service: myid. - cmd = tapservice.DeleteTapService(test_cli20.MyApp(sys.stdout), None) - myid = 'myid' - args = [myid] - self._test_delete_resource(self.resource, cmd, myid, args) - - def test_update_tap_service(self): - # Update tap_service: myid --name myname. - cmd = tapservice.UpdateTapService(test_cli20.MyApp(sys.stdout), None) - self._test_update_resource(self.resource, cmd, 'myid', - ['myid', '--name', 'myname'], - {'name': 'myname'}) - - def test_list_tap_services(self): - # List tap_services. - cmd = tapservice.ListTapService(test_cli20.MyApp(sys.stdout), None) - self._test_list_resources(self.resources, cmd, True) - - def test_show_tap_service(self): - # Show tap_service: --fields id --fields name myid. - cmd = tapservice.ShowTapService(test_cli20.MyApp(sys.stdout), None) - args = ['--fields', 'id', '--fields', 'name', self.test_id] - self._test_show_resource(self.resource, cmd, self.test_id, - args, ['id', 'name']) diff --git a/neutron_taas/__init__.py b/neutron_taas_tempest_plugin/__init__.py similarity index 100% rename from neutron_taas/__init__.py rename to neutron_taas_tempest_plugin/__init__.py diff --git a/neutron_taas/tests/tempest_plugin/plugin.py b/neutron_taas_tempest_plugin/plugin.py similarity index 100% rename from neutron_taas/tests/tempest_plugin/plugin.py rename to neutron_taas_tempest_plugin/plugin.py diff --git a/neutron_taas/common/__init__.py b/neutron_taas_tempest_plugin/services/__init__.py similarity index 100% rename from neutron_taas/common/__init__.py rename to neutron_taas_tempest_plugin/services/__init__.py diff --git a/neutron_taas/tests/tempest_plugin/services/client.py b/neutron_taas_tempest_plugin/services/client.py similarity index 100% rename from neutron_taas/tests/tempest_plugin/services/client.py rename to neutron_taas_tempest_plugin/services/client.py diff --git a/neutron_taas/db/__init__.py b/neutron_taas_tempest_plugin/tests/__init__.py similarity index 100% rename from neutron_taas/db/__init__.py rename to neutron_taas_tempest_plugin/tests/__init__.py diff --git a/neutron_taas/db/migration/__init__.py b/neutron_taas_tempest_plugin/tests/api/__init__.py similarity index 100% rename from neutron_taas/db/migration/__init__.py rename to neutron_taas_tempest_plugin/tests/api/__init__.py diff --git a/neutron_taas/tests/tempest_plugin/tests/api/base.py b/neutron_taas_tempest_plugin/tests/api/base.py similarity index 92% rename from neutron_taas/tests/tempest_plugin/tests/api/base.py rename to neutron_taas_tempest_plugin/tests/api/base.py index c3ffb7e..c3f57e4 100644 --- a/neutron_taas/tests/tempest_plugin/tests/api/base.py +++ b/neutron_taas_tempest_plugin/tests/api/base.py @@ -15,7 +15,7 @@ from tempest.api.network import base -from neutron_taas.tests.tempest_plugin.tests import taas_client +from neutron_taas_tempest_plugin.tests import taas_client class BaseTaaSTest(taas_client.TaaSClientMixin, base.BaseNetworkTest): diff --git a/neutron_taas/tests/tempest_plugin/tests/api/test_taas.py b/neutron_taas_tempest_plugin/tests/api/test_taas.py similarity index 98% rename from neutron_taas/tests/tempest_plugin/tests/api/test_taas.py rename to neutron_taas_tempest_plugin/tests/api/test_taas.py index 5e9b84e..aba8254 100644 --- a/neutron_taas/tests/tempest_plugin/tests/api/test_taas.py +++ b/neutron_taas_tempest_plugin/tests/api/test_taas.py @@ -19,7 +19,7 @@ from tempest import config from tempest.lib import decorators from tempest.lib import exceptions as lib_exc -from neutron_taas.tests.tempest_plugin.tests.api import base +from neutron_taas_tempest_plugin.tests.api import base CONF = config.CONF diff --git a/neutron_taas/db/migration/alembic_migration/__init__.py b/neutron_taas_tempest_plugin/tests/scenario/__init__.py similarity index 100% rename from neutron_taas/db/migration/alembic_migration/__init__.py rename to neutron_taas_tempest_plugin/tests/scenario/__init__.py diff --git a/neutron_taas/tests/tempest_plugin/tests/scenario/base.py b/neutron_taas_tempest_plugin/tests/scenario/base.py similarity index 90% rename from neutron_taas/tests/tempest_plugin/tests/scenario/base.py rename to neutron_taas_tempest_plugin/tests/scenario/base.py index 8b7e66c..0a0df39 100644 --- a/neutron_taas/tests/tempest_plugin/tests/scenario/base.py +++ b/neutron_taas_tempest_plugin/tests/scenario/base.py @@ -13,7 +13,7 @@ # License for the specific language governing permissions and limitations # under the License. -from neutron_taas.tests.tempest_plugin.tests.scenario import manager +from neutron_taas_tempest_plugin.tests.scenario import manager class TaaSScenarioTest(manager.NetworkScenarioTest): diff --git a/neutron_taas/tests/tempest_plugin/tests/scenario/manager.py b/neutron_taas_tempest_plugin/tests/scenario/manager.py similarity index 100% rename from neutron_taas/tests/tempest_plugin/tests/scenario/manager.py rename to neutron_taas_tempest_plugin/tests/scenario/manager.py diff --git a/neutron_taas/tests/tempest_plugin/tests/scenario/test_taas.py b/neutron_taas_tempest_plugin/tests/scenario/test_taas.py similarity index 94% rename from neutron_taas/tests/tempest_plugin/tests/scenario/test_taas.py rename to neutron_taas_tempest_plugin/tests/scenario/test_taas.py index 3aa2dea..7d89716 100644 --- a/neutron_taas/tests/tempest_plugin/tests/scenario/test_taas.py +++ b/neutron_taas_tempest_plugin/tests/scenario/test_taas.py @@ -17,7 +17,7 @@ from tempest.common import utils from tempest import config from tempest.lib import decorators -from neutron_taas.tests.tempest_plugin.tests.scenario import base +from neutron_taas_tempest_plugin.tests.scenario import base CONF = config.CONF diff --git a/neutron_taas/tests/tempest_plugin/tests/taas_client.py b/neutron_taas_tempest_plugin/tests/taas_client.py similarity index 98% rename from neutron_taas/tests/tempest_plugin/tests/taas_client.py rename to neutron_taas_tempest_plugin/tests/taas_client.py index 8a53a1a..f5c7dc3 100644 --- a/neutron_taas/tests/tempest_plugin/tests/taas_client.py +++ b/neutron_taas_tempest_plugin/tests/taas_client.py @@ -17,7 +17,7 @@ from tempest import config from tempest.lib.common.utils import data_utils from tempest.lib.common.utils import test_utils -from neutron_taas.tests.tempest_plugin.services import client +from neutron_taas_tempest_plugin.services import client CONF = config.CONF diff --git a/openstack-common.conf b/openstack-common.conf deleted file mode 100644 index f7400fc..0000000 --- a/openstack-common.conf +++ /dev/null @@ -1,6 +0,0 @@ -[DEFAULT] - -# The list of modules to copy from oslo-incubator.git - -# The base module to hold the copy of openstack.common -base=neutron_taas diff --git a/playbooks/legacy/tempest-dsvm-tap-as-a-service/post.yaml b/playbooks/legacy/tempest-dsvm-tap-as-a-service/post.yaml deleted file mode 100644 index e07f551..0000000 --- a/playbooks/legacy/tempest-dsvm-tap-as-a-service/post.yaml +++ /dev/null @@ -1,15 +0,0 @@ -- hosts: primary - tasks: - - - name: Copy files from {{ ansible_user_dir }}/workspace/ on node - synchronize: - src: '{{ ansible_user_dir }}/workspace/' - dest: '{{ zuul.executor.log_root }}' - mode: pull - copy_links: true - verify_host: true - rsync_opts: - - --include=/logs/** - - --include=*/ - - --exclude=* - - --prune-empty-dirs diff --git a/playbooks/legacy/tempest-dsvm-tap-as-a-service/run.yaml b/playbooks/legacy/tempest-dsvm-tap-as-a-service/run.yaml deleted file mode 100644 index 1a109b9..0000000 --- a/playbooks/legacy/tempest-dsvm-tap-as-a-service/run.yaml +++ /dev/null @@ -1,62 +0,0 @@ -- hosts: all - name: Autoconverted job legacy-tempest-dsvm-tap-as-a-service from old job gate-tempest-dsvm-tap-as-a-service - tasks: - - - name: Ensure legacy workspace directory - file: - path: '{{ ansible_user_dir }}/workspace' - state: directory - - - shell: - cmd: | - set -e - set -x - cat > clonemap.yaml << EOF - clonemap: - - name: openstack-infra/devstack-gate - dest: devstack-gate - EOF - /usr/zuul-env/bin/zuul-cloner -m clonemap.yaml --cache-dir /opt/git \ - git://git.openstack.org \ - openstack-infra/devstack-gate - executable: /bin/bash - chdir: '{{ ansible_user_dir }}/workspace' - environment: '{{ zuul | zuul_legacy_vars }}' - - - shell: - cmd: | - set -e - set -x - cat << 'EOF' >>"/tmp/dg-local.conf" - [[local|localrc]] - enable_plugin tap-as-a-service git://git.openstack.org/openstack/tap-as-a-service - - EOF - executable: /bin/bash - chdir: '{{ ansible_user_dir }}/workspace' - environment: '{{ zuul | zuul_legacy_vars }}' - - - shell: - cmd: | - set -e - set -x - export PYTHONUNBUFFERED=true - export DEVSTACK_GATE_TEMPEST=1 - export DEVSTACK_GATE_NEUTRON=1 - export DEVSTACK_GATE_TEMPEST_ALL_PLUGINS=1 - export BRANCH_OVERRIDE=default - if [ "$BRANCH_OVERRIDE" != "default" ] ; then - export OVERRIDE_ZUUL_BRANCH=$BRANCH_OVERRIDE - fi - - # Enable tap-as-a-service - export PROJECTS="openstack/tap-as-a-service $PROJECTS" - export ENABLED_SERVICES=taas,taas_openvswitch_agent - - export DEVSTACK_GATE_SETTINGS=/opt/stack/new/tap-as-a-service/devstack/devstackgaterc - - cp devstack-gate/devstack-vm-gate-wrap.sh ./safe-devstack-vm-gate-wrap.sh - ./safe-devstack-vm-gate-wrap.sh - executable: /bin/bash - chdir: '{{ ansible_user_dir }}/workspace' - environment: '{{ zuul | zuul_legacy_vars }}' diff --git a/releasenotes/notes/.placeholder b/releasenotes/notes/.placeholder deleted file mode 100644 index e69de29..0000000 diff --git a/releasenotes/notes/clear-tap-resources-on-port-delete-9583cdd7cd6098ea.yaml b/releasenotes/notes/clear-tap-resources-on-port-delete-9583cdd7cd6098ea.yaml deleted file mode 100644 index c6ba622..0000000 --- a/releasenotes/notes/clear-tap-resources-on-port-delete-9583cdd7cd6098ea.yaml +++ /dev/null @@ -1,9 +0,0 @@ ---- -prelude: > - Deleting a port associated with some tap resources (tap service or tap - flow) shall now cascade delete those associated tap resources as well. - It should be noted that this change alters the API behaviour in the sense - that earlier deleting a port did not clear the associated tap resources. -issues: - - | - Fixes bug `1814937 `_. diff --git a/releasenotes/source/_static/.placeholder b/releasenotes/source/_static/.placeholder deleted file mode 100644 index e69de29..0000000 diff --git a/releasenotes/source/conf.py b/releasenotes/source/conf.py deleted file mode 100644 index e10af5b..0000000 --- a/releasenotes/source/conf.py +++ /dev/null @@ -1,310 +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. -# -# tap-as-a-service documentation build configuration file, created by -# sphinx-quickstart on Sun May 8 12:21:42 2016. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# sys.path.insert(0, os.path.abspath('.')) - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -# needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'reno.sphinxext', - 'oslosphinx', -] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# source_suffix = ['.rst', '.md'] -source_suffix = '.rst' - -# The encoding of source files. -# source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'tap-as-a-service' -copyright = u'2017, Tap-as-a-service developers' -author = u'Tap-as-a-service developers' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -import pbr.version -version_info = pbr.version.VersionInfo('tap-as-a-service') -version = version_info.version_string_with_vcs() -# The full version, including alpha/beta/rc tags. -release = version_info.canonical_version_string() - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -# language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -# today = '' -# Else, today_fmt is used as the format for a strftime call. -# today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This patterns also effect to html_static_path and html_extra_path -exclude_patterns = [] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -# default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -# add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -# add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -# show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -# modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -# keep_warnings = False - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = False - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. - -html_theme = 'default' -# html_theme = 'openstackdocs' - -# openstackdocstheme options -# repository_name = 'openstack/%s' % project -# bug_project = project -# bug_tag = 'doc' -# html_last_updated_fmt = '%Y-%m-%d %H:%M' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -# html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -# html_theme_path = [] - -# The name for this set of Sphinx documents. -# " v documentation" by default. -# html_title = u'tap-as-a-service v1.0.1.0' - -# A shorter title for the navigation bar. Default is the same as html_title. -# html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -# html_logo = None - -# The name of an image file (relative to this directory) to use as a favicon of -# the docs. This file should be a Windows icon file (.ico) being 16x16 or -# 32x32 pixels large. -# html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -# html_extra_path = [] - -# If not None, a 'Last updated on:' timestamp is inserted at every page -# bottom, using the given strftime format. -# The empty string is equivalent to '%b %d, %Y'. -# html_last_updated_fmt = None - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -# html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -# html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -# html_additional_pages = {} - -# If false, no module index is generated. -# html_domain_indices = True - -# If false, no index is generated. -# html_use_index = True - -# If true, the index is split into individual pages for each letter. -# html_split_index = False - -# If true, links to the reST sources are added to the pages. -# html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -# html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -# html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -# html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -# html_file_suffix = None - -# Language to be used for generating the HTML full-text search index. -# Sphinx supports the following languages: -# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' -# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh' -# html_search_language = 'en' - -# A dictionary with options for the search language support, empty by default. -# 'ja' uses this config value. -# 'zh' user can custom change `jieba` dictionary path. -# html_search_options = {'type': 'default'} - -# The name of a javascript file (relative to the configuration directory) that -# implements a search results scorer. If empty, the default will be used. -# html_search_scorer = 'scorer.js' - -# Output file base name for HTML help builder. -htmlhelp_basename = 'tap-as-a-servicedoc' - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # 'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - # 'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - # 'preamble': '', - - # Latex figure (float) alignment - # 'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'tap-as-a-service.tex', u'tap-as-a-service Documentation', - u'OpenStack', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -# latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -# latex_use_parts = False - -# If true, show page references after internal links. -# latex_show_pagerefs = False - -# If true, show URL addresses after external links. -# latex_show_urls = False - -# Documents to append as an appendix to all manuals. -# latex_appendices = [] - -# If false, no module index is generated. -# latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'tap-as-a-service', u'tap-as-a-service Documentation', - [author], 1) -] - -# If true, show URL addresses after external links. -# man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'tap-as-a-service', u'tap-as-a-service Documentation', - author, 'tap-as-a-service', 'One line description of project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -# texinfo_appendices = [] - -# If false, no module index is generated. -# texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -# texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -# texinfo_no_detailmenu = False - -# -- Options for Internationalization output ------------------------------ -locale_dirs = ['locale/'] diff --git a/releasenotes/source/index.rst b/releasenotes/source/index.rst deleted file mode 100644 index 9724bd5..0000000 --- a/releasenotes/source/index.rst +++ /dev/null @@ -1,15 +0,0 @@ -.. tap-as-a-service documentation master file, created by - sphinx-quickstart on Sun May 8 12:21:42 2016. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Tap-as-a-service Release Notes -============================== - -Contents: - -.. toctree:: - :maxdepth: 2 - - unreleased - queens diff --git a/releasenotes/source/queens.rst b/releasenotes/source/queens.rst deleted file mode 100644 index 36ac616..0000000 --- a/releasenotes/source/queens.rst +++ /dev/null @@ -1,6 +0,0 @@ -=================================== - Queens Series Release Notes -=================================== - -.. release-notes:: - :branch: stable/queens diff --git a/releasenotes/source/unreleased.rst b/releasenotes/source/unreleased.rst deleted file mode 100644 index 875030f..0000000 --- a/releasenotes/source/unreleased.rst +++ /dev/null @@ -1,5 +0,0 @@ -============================ -Current Series Release Notes -============================ - -.. release-notes:: diff --git a/requirements.txt b/requirements.txt index 7f1a451..6de9f4e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,10 +3,3 @@ # process, which may cause wedges in the gate later. pbr!=2.1.0,>=2.0.0 # Apache-2.0 -Babel!=2.4.0,>=2.3.4 # BSD -neutron>=12.0.0 # Apache-2.0 -neutron-lib>=1.20.0 # Apache-2.0 - -# Opt-in for neutron-lib consumption patches -# http://lists.openstack.org/pipermail/openstack-dev/2018-September/135063.html -# neutron-lib-current diff --git a/setup.cfg b/setup.cfg index 1333cca..db18ec9 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] -name = tap-as-a-service -summary = Tap-as-a-Service (TaaS) is an extension to the OpenStack network service (Neutron), it provides remote port mirroring capability for tenant virtual networks. +name = tap-as-a-service-tempest-plugin +summary = Tempest plugin for Tap-as-a-Service description-file = README.rst author = OpenStack @@ -20,7 +20,7 @@ classifier = [files] packages = - neutron_taas + neutron_taas_tempest_plugin [build_sphinx] source-dir = doc/source @@ -35,34 +35,9 @@ build-dir = releasenotes/build source-dir = releasenotes/source all_files = 1 -[compile_catalog] -directory = neutron_taas/locale -domain = neutron_taas - -[update_catalog] -domain = neutron_taas -output_dir = neutron_taas/locale -input_file = neutron_taas/locale/neutron_taas.pot - -[extract_messages] -keywords = _ gettext ngettext l_ lazy_gettext -mapping_file = babel.cfg -output_file = neutron_taas/locale/neutron_taas.pot - [entry_points] -neutron.agent.l2.extensions = - taas = neutron_taas.services.taas.agents.extensions.taas:TaasAgentExtension -neutron_taas.taas.agent_drivers = - ovs = neutron_taas.services.taas.drivers.linux.ovs_taas:OvsTaasDriver -neutron.service_plugins = - taas = neutron_taas.services.taas.taas_plugin:TaasPlugin -neutron.db.alembic_migrations = - tap-as-a-service = neutron_taas.db.migration:alembic_migration tempest.test_plugins = - tap-as-a-service = neutron_taas.tests.tempest_plugin.plugin:NeutronTaaSPlugin -neutronclient.extension = - tap_service = neutron_taas.taas_client.tapservice - tap_flow = neutron_taas.taas_client.tapflow + tap-as-a-service = neutron_taas_tempest_plugin.plugin:NeutronTaaSPlugin [pbr] autodoc_index_modules = True diff --git a/specs/index.rst b/specs/index.rst deleted file mode 100644 index 8ee682f..0000000 --- a/specs/index.rst +++ /dev/null @@ -1,14 +0,0 @@ -.. tap-as-a-service specs documentation index - -============== -Specifications -============== - -Mitaka specs -============ - -.. toctree:: - :glob: - :maxdepth: 1 - - mitaka/* diff --git a/specs/mitaka/tap-as-a-service.rst b/specs/mitaka/tap-as-a-service.rst deleted file mode 100644 index 9fa468c..0000000 --- a/specs/mitaka/tap-as-a-service.rst +++ /dev/null @@ -1,474 +0,0 @@ -.. - This work is licensed under a Creative Commons Attribution 3.0 Unported - License. - - http://creativecommons.org/licenses/by/3.0/legalcode - -============================ -Tap-as-a-Service for Neutron -============================ - - -Launchpad blueprint: - - https://blueprints.launchpad.net/neutron/+spec/tap-as-a-service - -This spec explains an extension for the port mirroring functionality. Port -mirroring involves sending a copy of packets ingressing and/or egressing one -port (where ingress means entering a VM and egress means leaving a VM) to -another port, (usually different from the packet's original destination). -A port could be attached to a VM or a networking resource like router. - -While the blueprint describes the functionality of mirroring Neutron ports as -an extension to the port object, the spec proposes to offer port mirroring as a -service, which will enable more advanced use-cases (e.g. intrusion detection) -to be deployed. - -The proposed port mirroring capability shall be introduced in Neutron as a -service called "Tap-as-a-Service". - -Problem description -=================== - -Neutron currently does not support the functionality of port mirroring for -tenant networks. This feature will greatly benefit tenants and admins, who -want to debug their virtual networks and gain visibility into their VMs by -monitoring and analyzing the network traffic associated with them (e.g. IDS). - -This spec focuses on mirroring traffic from one Neutron port to another; -future versions may address mirroring from a Neutron port to an arbitrary -interface (not managed by Neutron) on a compute host or the network controller. - -Different usage scenarios for the service are listed below: - - 1. Tapping/mirroring network traffic ingressing and/or egressing a particular - Neutron port. - 2. Tapping/mirroring all network traffic on a tenant network. - 3. Tenant or admin will be able to do tap/traffic mirroring based on a - policy rule and set destination as a Neutron port, which can be linked - to a virtual machine as normal Nova operations or to a physical machine - via l2-gateway functionality. - 4. Admin will be able to do packet level network debugging for the virtual - network. - 5. Provide a way for real time analytics based on different criteria, like - tenants, ports, traffic types (policy) etc. - -Note that some of the above use-cases are not covered by this proposal, at -least for the first step. - - -Proposed change -=============== - -The proposal is to introduce a new Neutron service plugin, called -"Tap-as-a-Service", -which provides tapping (port-mirroring) capability for Neutron networks; -tenant or provider networks. This service will be modeled similar to other -Neutron services such as the firewall, load-balancer, L3-router etc. - -The proposed service will allow the tenants to create a tap service instance -to which they can add Neutron ports that need to be mirrored by creating tap -flows. The tap service itself will be a Neutron port, which will be the -destination port for the mirrored traffic. - -The destination Tap-as-a-Service Neutron port should be created beforehand on -a network owned by the tenant who is requesting the service. The ports to be -mirrored that are added to the service must be owned by the same tenant who -created the tap service instance. Even on a shared network, a tenant will only -be allowed to mirror the traffic from ports that they own on the shared -network and not traffic from ports that they do not own on the shared network. - -The ports owned by the tenant that are mirrored can be on networks other -than the network on which tap service port is created. This allows the tenant -to mirror traffic from any port it owns on a network on to the same -Tap-as-a-Service Neutron port. - -The tenant can launch a VM specifying the tap destination port for the VM -interface (--nic port-id=tap_port_uuid), thus receiving mirrored traffic for -further processing (dependent on use case) on that VM. - -The following would be the work flow for using this service from a tenant's -point of view - - 0. Create a Neutron port which will be used as the destination port. - This can be a part of ordinary VM launch. - - 1. Create a tap service instance, specifying the Neutron port. - - 2. If you haven't yet, launch a monitoring or traffic analysis VM and - connect it to the destination port for the tap service instance. - - 3. Associate Neutron ports with a tap service instance if/when they need to be - monitored. - - 4. Disassociate Neutron ports from a tap service instance if/when they no - longer need to be monitored. - - 5. Destroy a tap-service instance when it is no longer needed. - - 6. Delete the destination port when it is no longer neeeded. - -Please note that the normal work flow of launching a VM is not affected while -using TaaS. - - -Alternatives ------------- - -As an alternative to introducing port mirroring functionality under Neutron -services, it could be added as an extension to the existing Neutron v2 APIs. - - -Data model impact ------------------ - -Tap-as-a-Service introduces the following data models into Neutron as database -schemas. - -1. tap_service - -+-------------+--------+----------+-----------+---------------+-------------------------+ -| Attribute | Type | Access | Default | Validation/ | Description | -| Name | | (CRUD) | Value | Conversion | | -+=============+========+==========+===========+===============+=========================+ -| id | UUID | R, all | generated | N/A | UUID of the tap | -| | | | | | service instance. | -+-------------+--------+----------+-----------+---------------+-------------------------+ -| project_id | String | CR, all | Requester | N/A | ID of the | -| | | | | | project creating | -| | | | | | the service | -+-------------+--------+----------+-----------+---------------+-------------------------+ -| name | String | CRU, all | Empty | N/A | Name for the service | -| | | | | | instance. | -+-------------+--------+----------+-----------+---------------+-------------------------+ -| description | String | CRU, all | Empty | N/A | Description of the | -| | | | | | service instance. | -+-------------+--------+----------+-----------+---------------+-------------------------+ -| port_id | UUID | CR, all | N/A | UUID of a | An existing Neutron port| -| | | | | valid Neutron | to which traffic will | -| | | | | port | be mirrored | -+-------------+--------+----------+-----------+---------------+-------------------------+ -| status | String | R, all | N/A | N/A | The operation status of | -| | | | | | the resource | -| | | | | | (ACTIVE, PENDING_foo, | -| | | | | | ERROR, ...) | -+-------------+--------+----------+-----------+---------------+-------------------------+ - -2. tap_flow - -+----------------+--------+----------+-----------+---------------+-------------------------+ -| Attribute | Type | Access | Default | Validation/ | Description | -| Name | | (CRUD) | Value | Conversion | | -+================+========+==========+===========+===============+=========================+ -| id | UUID | R, all | generated | N/A | UUID of the | -| | | | | | tap flow instance. | -+----------------+--------+----------+-----------+---------------+-------------------------+ -| name | String | CRU, all | Empty | N/A | Name for the tap flow | -| | | | | | instance. | -+----------------+--------+----------+-----------+---------------+-------------------------+ -| description | String | CRU, all | Empty | N/A | Description of the | -| | | | | | tap flow instance. | -+----------------+--------+----------+-----------+---------------+-------------------------+ -| tap_service_id | UUID | CR, all | N/A | Valid tap | UUID of the tap | -| | | | | service UUID | service instance. | -+----------------+--------+----------+-----------+---------------+-------------------------+ -| source_port | UUID | CR, all | N/A | UUID of a | UUID of the Neutron | -| | | | | valid Neutron | port that needed to be | -| | | | | port | mirrored | -+----------------+--------+----------+-----------+---------------+-------------------------+ -| direction | ENUM | CR, all | BOTH | | Whether to mirror the | -| | (IN, | | | | traffic leaving or | -| | OUT, | | | | arriving at the | -| | BOTH) | | | | source port | -| | | | | | IN: Network -> VM | -| | | | | | OUT: VM -> Network | -+----------------+--------+----------+-----------+---------------+-------------------------+ -| status | String | R, all | N/A | N/A | The operation status of | -| | | | | | the resource | -| | | | | | (ACTIVE, PENDING_foo, | -| | | | | | ERROR, ...) | -+----------------+--------+----------+-----------+---------------+-------------------------+ - - -REST API impact ---------------- - -Tap-as-a-Service shall be offered over the RESTFull API interface under -the following namespace: - -http://wiki.openstack.org/Neutron/TaaS/API_1.0 - -The resource attribute map for TaaS is provided below: - -.. code-block:: python - - direction_enum = ['IN', 'OUT', 'BOTH'] - - RESOURCE_ATTRIBUTE_MAP = { - 'tap_service': { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid': None}, 'is_visible': True, - 'primary_key': True}, - 'project_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'required_by_policy': True, 'is_visible': True}, - 'name': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'description': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'port_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'is_visible': True}, - 'status': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - }, - 'tap_flow': { - 'id': {'allow_post': False, 'allow_put': False, - 'validate': {'type:uuid': None}, 'is_visible': True, - 'primary_key': True}, - 'name': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'description': {'allow_post': True, 'allow_put': True, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'tap_service_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'required_by_policy': True, 'is_visible': True}, - 'source_port': {'allow_post': True, 'allow_put': False, - 'validate': {'type:uuid': None}, - 'required_by_policy': True, 'is_visible': True}, - 'direction': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': direction_enum}, - 'is_visible': True}, - 'status': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - } - } - - -Security impact ---------------- - -A TaaS instance comprises a collection of source Neutron ports (whose -ingress and/or egress traffic are being mirrored) and a destination Neutron -port (where the mirrored traffic is received). Security Groups will be -handled differently for these two classes of ports, as described below: - -Destination Side: - -Ingress Security Group filters, including the filter that prevents MAC-address -spoofing, will be disabled for the destination Neutron port. This will ensure -that all of the mirrored packets received at this port are able to reach the -monitoring VM attached to it. - -Source Side: - -Ideally it would be nice to mirror all packets entering and/or leaving the -virtual NICs associated with the VMs that are being monitored. This means -capturing ingress traffic after it passes the inbound Security Group filters -and capturing egress traffic before it passes the outbound Security Group -filters. - -However, due to the manner in which Security Groups are currently implemented -in OpenStack (i.e. north of the Open vSwitch ports, using Linux IP Tables) this -is not possible because port mirroring support resides inside Open vSwitch. -Therefore, in the first version of TaaS, Security Groups will be ignored for -the source Neutron ports; this effectively translates into capturing ingress -traffic before it passes the inbound Security Group filters and capturing -egress traffic after it passes the outbound Security Group filters. In other -words, port mirroring will be implemented for all packets entering and/or -leaving the Open vSwitch ports associated with the respective virtual NICs of -the VMs that are being monitored. - -There is a separate effort that has been initiated to implement Security Groups -within OpenvSwitch. A later version of TaaS may make use of this feature, if -and when it is available, so that we can realize the ideal behavior described -above. It should be noted that such an enhancement should not require a change -to the TaaS data model. - -Keeping data privacy aspects in mind and preventing the data center admin -from snooping on tenant's network traffic without their knowledge, the admin -shall not be allowed to mirror traffic from any ports that belong to tenants. -Hence creation of 'Tap_Flow' is only permitted on ports that are owned by the -creating tenant. - -If an admin wants to monitor tenant's traffic, the admin will have to join that -tenant as a member. This will ensure that the tenant is aware that the admin -might be monitoring their traffic. - - -Notifications impact --------------------- - -A set of new RPC calls for communication between the TaaS server and agents -are required and will be put in place as part of the reference implementation. - - -IPv6 impact --------------------- -None - - -Other end user impact ---------------------- - -Users will be able to invoke and access the TaaS APIs through -python-neutronclient. - - -Performance Impact ------------------- - -The performance impact of mirroring traffic needs to be examined and -quantified. The impact of a tenant potentially mirroring all traffic from -all ports could be large and needs more examination. - -Some alternatives to reduce the amount of mirrored traffic are listed below. - - 1. Rate limiting on the ports being mirrored. - 2. Filters to select certain flows ingressing/egressing a port to be - mirrored. - 3. Having a quota on the number of TaaS Flows that can be defined by the - tenant. - - -Other deployer impact ---------------------- - -Configurations for the service plugin will be added later. - -A new bridge (br-tap) mentioned in Implementation section. - - -Developer impact ----------------- -This will be a new extension API, and will not affect the existing API. - - -Community impact ----------------- -None - - -Follow up work --------------- - -Going forward, TaaS would be incorporated with Service Insertion [2]_ similar -to other existing services like FWaaS, LBaaS, and VPNaaS. - -While integrating Tap-as-a-Service with Service Insertion the key changes to -the data model needed would be the removal of 'network_id' and 'port_id' from -the 'Tap_Service' data model. - -Some policy based filtering rules would help alleviate the potential performance -issues. - -We might want to ensure exclusive use of the destination port. - -We might want to create the destination port automatically on tap-service -creation, rather than specifying an existing port. In that case, network_id -should be taken as a parameter for tap-service creation, instead of port_id. - -We might want to allow the destination port be used for purposes other than -just launching a VM on it, for example the port could be used as an -'external-port' [1]_ to get the mirrored data out from the tenant virtual -network on a device or network not managed by openstack. - -We might want to introduce a way to tap a whole traffic for the specified -network. - -We need a mechanism to coordinate usage of various resources with other -agent extensions. E.g. OVS flows, tunnel IDs, VLAN IDs. - - -Implementation -============== - -The reference implementation for TaaS will be based on Open vSwitch. In -addition to the existing integration (br-int) and tunnel (br-tun) bridges, a -separate tap bridge (br-tap) will be used. The tap bridge provides nice -isolation for supporting more complex TaaS features (e.g. filtering mirrored -packets) in the future. - -The tapping operation will be realized by adding higher priority flows in -br-int, which duplicate the ingress and/or egress packets associated with -specific ports (belonging to the VMs being monitored) and send the copies to -br-tap. Packets sent to br-tap will also be tagged with an appropriate VLAN id -corresponding to the associated TaaS instance (in the initial release these -VLAN ids may be reserved from highest to lowest; in later releases it should be -coordinated with the Neutron service). The original packets will continue to be -processed normally, so as not to affect the traffic patterns of the VMs being -monitored. - -Flows will be placed in br-tap to determine if the mirrored traffic should be -sent to br-tun or not. If the destination port of a Tap-aaS instance happens to -reside on the same host as a source port, packets from that source port will be -returned to br-int; otherwise they will be forwarded to br-tun for delivery to -a remote node. - -Packets arriving at br-tun from br-tap will get routed to the destination ports -of appropriate TaaS instances using the same GRE or VXLAN tunnel network that -is used to pass regular traffic between hosts. Separate tunnel IDs will be used -to isolate different TaaS instances from one another and from the normal -(non-mirrored) traffic passing through the bridge. This will ensure that proper -action can be taken on the receiving end of a tunnel so that mirrored traffic -is sent to br-tap instead of br-int. Special flows will be used in br-tun to -automatically learn about the location of the destination ports of TaaS -instances. - -Packets entering br-tap from br-tun will be forwarded to br-int only if the -destination port of the corresponding TaaS instance resides on the same host. -Finally, packets entering br-int from br-tap will be delivered to the -appropriate destination port after the TaaS instance VLAN id is replaced with -the VLAN id for the port. - - -Assignee(s) ------------ - -* Vinay Yadhav - - -Work Items ----------- - -* TaaS API and data model implementation. -* TaaS OVS driver. -* OVS agent changes for port mirroring. - - -Dependencies -============ - -None - - -Testing -======= - -* Unit Tests to be added. -* Functional tests in tempest to be added. -* API Tests in Tempest to be added. - - -Documentation Impact -==================== - -* User Documentation needs to be updated -* Developer Documentation needs to be updated - - -References -========== - -.. [1] External port - https://review.openstack.org/#/c/87825 - -.. [2] Service base and insertion - https://review.openstack.org/#/c/93128 - -.. [3] NFV unaddressed interfaces - https://review.openstack.org/#/c/97715/ diff --git a/test-requirements.txt b/test-requirements.txt index 4373b7e..f9a67e4 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -7,12 +7,7 @@ hacking!=0.13.0,<0.14,>=0.12.0 # Apache-2.0 coverage!=4.4,>=4.0 # Apache-2.0 python-subunit>=1.0.0 # Apache-2.0/BSD sphinx!=1.6.6,!=1.6.7,>=1.6.2 # BSD -psycopg2>=2.6.2 # LGPL/ZPL -PyMySQL>=0.7.6 # MIT License oslosphinx>=4.7.0 # Apache-2.0 oslotest>=3.2.0 # Apache-2.0 os-testr>=1.0.0 # Apache-2.0 reno>=2.5.0 # Apache-2.0 -testresources>=2.0.0 # Apache-2.0/BSD -testscenarios>=0.4 # Apache-2.0/BSD -testtools>=2.2.0 # MIT diff --git a/tools/test-setup.sh b/tools/test-setup.sh deleted file mode 100755 index 00c765e..0000000 --- a/tools/test-setup.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash -xe - -# This script will be run by OpenStack CI before unit tests are run, -# it sets up the test system as needed. -# Developers should setup their test systems in a similar way. - -# This setup needs to be run as a user that can run sudo. - -# The root password for the MySQL database; pass it in via -# MYSQL_ROOT_PW. -DB_ROOT_PW=${MYSQL_ROOT_PW:-insecure_slave} - -# This user and its password are used by the tests, if you change it, -# your tests might fail. -DB_USER=openstack_citest -DB_PW=openstack_citest - -sudo -H mysqladmin -u root password $DB_ROOT_PW - -# It's best practice to remove anonymous users from the database. If -# an anonymous user exists, then it matches first for connections and -# other connections from that host will not work. -sudo -H mysql -u root -p$DB_ROOT_PW -h localhost -e " - DELETE FROM mysql.user WHERE User=''; - FLUSH PRIVILEGES; - GRANT ALL PRIVILEGES ON *.* - TO '$DB_USER'@'%' identified by '$DB_PW' WITH GRANT OPTION;" - -# Now create our database. -mysql -u $DB_USER -p$DB_PW -h 127.0.0.1 -e " - SET default_storage_engine=MYISAM; - DROP DATABASE IF EXISTS openstack_citest; - CREATE DATABASE openstack_citest CHARACTER SET utf8;" - -# Same for PostgreSQL - -# Setup user -root_roles=$(sudo -H -u postgres psql -t -c " - SELECT 'HERE' from pg_roles where rolname='$DB_USER'") -if [[ ${root_roles} == *HERE ]];then - sudo -H -u postgres psql -c "ALTER ROLE $DB_USER WITH SUPERUSER LOGIN PASSWORD '$DB_PW'" -else - sudo -H -u postgres psql -c "CREATE ROLE $DB_USER WITH SUPERUSER LOGIN PASSWORD '$DB_PW'" -fi - -# Store password for tests -cat << EOF > $HOME/.pgpass -*:*:*:$DB_USER:$DB_PW -EOF -chmod 0600 $HOME/.pgpass - -# Now create our database -psql -h 127.0.0.1 -U $DB_USER -d template1 -c "DROP DATABASE IF EXISTS openstack_citest" -createdb -h 127.0.0.1 -U $DB_USER -l C -T template0 -E utf8 openstack_citest diff --git a/tox.ini b/tox.ini index bb173b7..505343c 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = docs,py35,py27,pep8 +envlist = pep8 minversion = 1.8 skipsdist = True @@ -17,41 +17,13 @@ commands = find . -type f -name "*.py[c|o]" -delete ostestr --regex '{posargs}' whitelist_externals = find -[tox:jenkins] -sitepackages = True - -[testenv:py27] -setenv = OS_FAIL_ON_MISSING_DEPS=1 - [testenv:pep8] commands = flake8 - neutron-db-manage --subproject tap-as-a-service --database-connection sqlite:// check_migration [testenv:venv] commands = {posargs} -[testenv:cover] -basepython = python2.7 -setenv = - {[testenv]setenv} - PYTHON=coverage run --source neutron_taas --parallel-mode -commands = - stestr run --no-subunit-trace {posargs} - coverage combine - coverage report --fail-under=50 --skip-covered - coverage html -d cover - coverage xml -o cover/coverage.xml - -[testenv:docs] -commands = python setup.py build_sphinx - -[testenv:releasenotes] -commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html - -[testenv:debug] -commands = oslo_debug_helper {posargs} - [flake8] # E123, E125 skipped as they are invalid PEP-8. @@ -59,30 +31,3 @@ show-source = True ignore = E123,E125 builtins = _ exclude=.venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,build - -[hacking] -import_exceptions = neutron_taas._i18n - -[testenv:lower-constraints] -basepython = python3 -deps = - -c{toxinidir}/lower-constraints.txt - -r{toxinidir}/test-requirements.txt - -r{toxinidir}/requirements.txt - -[testenv:dev] -# run locally (not in the gate) using editable mode -# https://pip.pypa.io/en/stable/reference/pip_install/#editable-installs -commands = - pip install -q -e "git+https://git.openstack.org/openstack/neutron#egg=neutron" - -[testenv:py3-dev] -basepython = python3 -commands = - {[testenv:dev]commands} - {[testenv]commands} - -[testenv:pep8-dev] -commands = - {[testenv:dev]commands} - {[testenv:pep8]commands}