diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 157ddc7..0000000 --- a/.gitignore +++ /dev/null @@ -1,17 +0,0 @@ -# Python -*.pyc - -# Packages -.eggs -*.egg-info -build/ -dist/ - -# Testing -.tox -.testrepository - -# Editors -*~ -.*.swp -.*sw? diff --git a/.testr.conf b/.testr.conf deleted file mode 100644 index e50fdd0..0000000 --- a/.testr.conf +++ /dev/null @@ -1,4 +0,0 @@ -[DEFAULT] -test_command=OS_STDOUT_CAPTURE=1 OS_STDERR_CAPTURE=1 OS_LOG_CAPTURE=1 ${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./wan_qos/tests/unit} $LISTOPT $IDOPTION | cat -test_id_option=--load-list $IDFILE -test_list_option=--list diff --git a/README.rst b/README.rst index e69de29..86e34d6 100644 --- a/README.rst +++ b/README.rst @@ -0,0 +1,10 @@ +This project is no longer maintained. + +The contents of this repository are still available in the Git +source code management system. To see the contents of this +repository before it reached its end of life, please check out the +previous commit with "git checkout HEAD^1". + +For any further questions, please email +openstack-discuss@lists.openstack.org or join #openstack-dev on +Freenode. diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 816c58e..0000000 --- a/requirements.txt +++ /dev/null @@ -1,25 +0,0 @@ -# The order of packages is significant, because pip processes them in the order -# of appearance. Changing the order has an impact on the overall integration -# process, which may cause wedges in the gate later. - -pbr>=2.0.0 # Apache-2.0 -Babel>=2.3.4 # BSD -kazoo>=2.2 # Apache-2.0 -ovs>=2.7.0 # Apache-2.0 -pyzmq>=14.3.1 # LGPL+BSD -ryu>=4.9 # Apache-2.0 -SQLAlchemy!=1.1.5,!=1.1.6,!=1.1.7,!=1.1.8,>=1.0.10 # MIT -alembic>=0.8.10 # MIT -neutron-lib>=1.3.0 # Apache-2.0 -oslo.config>=3.22.0 # Apache-2.0 -oslo.db>=4.19.0 # Apache-2.0 -oslo.i18n>=2.1.0 # Apache-2.0 -oslo.log>=3.22.0 # Apache-2.0 -oslo.reports>=0.6.0 # Apache-2.0 -oslo.serialization>=1.10.0 # Apache-2.0 -crc16>=0.1.1 # LGPLv3+ -netaddr!=0.7.16,>=0.7.13 # BSD -six>=1.9.0 # MIT -httplib2>=0.7.5 # MIT -WebOb>=1.7.1 # MIT - diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index ee97ec9..0000000 --- a/setup.cfg +++ /dev/null @@ -1,39 +0,0 @@ -[metadata] -name = tc-as-a-service -summary = APIs and implementations to support TC as a Service -description-file = - README.rst -author = OpenStack -author-email = openstack-dev@lists.openstack.org -home-page = http://www.openstack.org/ -classifier = - Environment :: OpenStack - Intended Audience :: Information Technology - Intended Audience :: System Administrators - License :: OSI Approved :: Apache Software License - Operating System :: POSIX :: Linux - Programming Language :: Python - Programming Language :: Python :: 2 - Programming Language :: Python :: 2.7 - Programming Language :: Python :: 3 - Programming Language :: Python :: 3.4 - Programming Language :: Python :: 3.5 - -[files] -packages = - wan_qos -data_files = - etc/neutron = - etc/wan_qos_agent.ini - etc/wan_qos_plugin.ini - -[entry_points] -console_scripts = - neutron-wan-qos-agent = wan_qos.cmd.eventlet.agent:main -neutron.db.alembic_migrations = - wan-qos = wan_qos.db.migration:alembic_migrations -neutronclient.extension = - wan_tc_filter = wan_qos.wanqos_client._wantcfilter - wan_tc_device = wan_qos.wanqos_client._wantcdevice - wan_tc_class = wan_qos.wanqos_client._wantcclass - wan_tc = wan_qos.wanqos_client._wantc diff --git a/setup.py b/setup.py deleted file mode 100644 index 9decd0c..0000000 --- a/setup.py +++ /dev/null @@ -1,27 +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. - -# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT -import setuptools - -# In python < 2.7.4, a lazy loading of package `pbr` will break -# setuptools if some other modules registered functions in `atexit`. -# solution from: http://bugs.python.org/issue15881#msg170215 -try: - import multiprocessing # noqa -except ImportError: - pass - -setuptools.setup( - setup_requires=['pbr>=2.0'], - pbr=True) diff --git a/test-requirements.txt b/test-requirements.txt deleted file mode 100644 index 87b17be..0000000 --- a/test-requirements.txt +++ /dev/null @@ -1,14 +0,0 @@ -# The order of packages is significant, because pip processes them in the order -# of appearance. Changing the order has an impact on the overall integration -# process, which may cause wedges in the gate later. - -hacking!=0.13.0,<0.14,>=0.12.0 # Apache-2.0 - -mock>=2.0 # BSD -python-subunit>=0.0.18 # Apache-2.0/BSD -os-testr>=0.8.0 # Apache-2.0 -oslotest>=1.10.0 # Apache-2.0 -testrepository>=0.0.18 # Apache-2.0/BSD -testresources>=0.2.4 # Apache-2.0/BSD -testscenarios>=0.4 # Apache-2.0/BSD -testtools>=1.4.0 # MIT diff --git a/tools/tox_install.sh b/tools/tox_install.sh deleted file mode 100755 index ba12396..0000000 --- a/tools/tox_install.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/sh - -# Many of neutron's repos suffer from the problem of depending on neutron, -# but it not existing on pypi. - -# This wrapper for tox's package installer will use the existing package -# if it exists, else use zuul-cloner if that program exists, else grab it -# from neutron master via a hard-coded URL. That last case should only -# happen with devs running unit tests locally. - -# From the tox.ini config page: -# install_command=ARGV -# default: -# pip install {opts} {packages} - -ZUUL_CLONER=/usr/zuul-env/bin/zuul-cloner -neutron_installed=$(echo "import neutron" | python 2>/dev/null ; echo $?) -BRANCH_NAME=master - -set -ex - -cwd=$(/bin/pwd) - -CONSTRAINTS_FILE=$1 -shift - -install_cmd="pip install" -if [ $CONSTRAINTS_FILE != "unconstrained" ]; then - install_cmd="$install_cmd -c$CONSTRAINTS_FILE" -fi - -if [ $neutron_installed -eq 0 ]; then - echo "ALREADY INSTALLED" > /tmp/tox_install.txt - echo "Neutron already installed; using existing package" -elif [ -x "$ZUUL_CLONER" ]; then - echo "ZUUL CLONER" > /tmp/tox_install.txt - cd /tmp - export ZUUL_BRANCH=${ZUUL_BRANCH-$BRANCH} - $ZUUL_CLONER --cache-dir \ - /opt/git \ - --branch $BRANCH_NAME \ - git://git.openstack.org \ - openstack/neutron - cd openstack/neutron - $install_cmd -e . - cd "$cwd" -else - echo "PIP HARDCODE" > /tmp/tox_install.txt - $install_cmd -U -egit+https://git.openstack.org/openstack/neutron@$BRANCH_NAME#egg=neutron -fi - -$install_cmd -U $* -exit $? diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 797f0eb..0000000 --- a/tox.ini +++ /dev/null @@ -1,51 +0,0 @@ -[tox] -minversion = 1.6 -envlist = pep8,py27,py35 -skipsdist = True - -[testenv] -# Note the hash seed is set to 0 until neutron can be tested with a -# random hash seed successfully. -setenv = VIRTUAL_ENV={envdir} - PYTHONHASHSEED=0 - PYTHONWARNINGS=default::DeprecationWarning -usedevelop = True -install_command = {toxinidir}/tools/tox_install.sh {env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} {opts} {packages} -deps = -r{toxinidir}/requirements.txt - -r{toxinidir}/test-requirements.txt -whitelist_externals = sh -commands = - ostestr '{posargs}' -# sh tools/pretty_tox.sh '{posargs}' - -[testenv:pep8] -commands = - flake8 - neutron-db-manage --subproject dragonflow check_migration - -[testenv:venv] -commands = {posargs} - -[flake8] -# E126 continuation line over-indented for hanging indent -# H404 multi line docstring should start with a summary -# H405 multi line docstring summary not separated with an empty line -# N530 Direct neutron imports not allowed -# N531 log message does not translate -ignore = E126,H404,H405,N530,N531 -# H904: Delay string interpolations at logging calls -# H203: Use assertIs(Not)None to check for None -enable-extensions=H904,H203 -show-source = true -exclude = ./.*,dist,doc,build,tools - -[testenv:pylint] -deps = - {[testenv]deps} - pylint -commands = - pylint --rcfile=.pylintrc --output-format=colorized {posargs:neutron} - -[hacking] -#import_exceptions = wan_qos._i18n -local-check-factory = neutron_lib.hacking.checks.factory diff --git a/wan_qos/__init__.py b/wan_qos/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/wan_qos/agent/__init__.py b/wan_qos/agent/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/wan_qos/agent/agent_api.py b/wan_qos/agent/agent_api.py deleted file mode 100644 index 7d99ee0..0000000 --- a/wan_qos/agent/agent_api.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright 2016 Huawei corp. -# 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 abc -import six - - -@six.add_metaclass(abc.ABCMeta) -class AgentInterface(object): - "Base class that defines the contract for TC agent" - - @abc.abstractmethod - def clear_all(self): - "Delete all traffic control configurations" - - @abc.abstractmethod - def set_ports(self, in_port, out_port): - "Set the names of the LAN and WAN facing ports" - - @abc.abstractmethod - def set_root_queue(self, tc_dict): - """Sets the root qdisc with its max rate of the WAN link to be set - as upper limit - """ - - @abc.abstractmethod - def create_traffic_class(self, tc_dict): - "Add traffic class using traffic information from the dictionary." - - @abc.abstractmethod - def update_traffic_class(self, tc_dict): - "Update traffic control using information from tc dictionary." - - @abc.abstractmethod - def remove_traffic_class(self, tc_dict): - "Update traffic control using information from tc dictionary." - - @abc.abstractmethod - def create_filter(self, tc_dict): - """Create traffic filter that is used to route packets to the - right queue - """ - - @abc.abstractmethod - def remove_filter(self, tc_dict): - "Remove traffic filter" diff --git a/wan_qos/agent/tc_agent.py b/wan_qos/agent/tc_agent.py deleted file mode 100644 index fdfbaac..0000000 --- a/wan_qos/agent/tc_agent.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright 2016 Huawei corp. -# 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 sys - -import eventlet -from neutron.common import config as common_config -from neutron.conf.agent import common as config -from neutron import service as neutron_service -from oslo_config import cfg -from oslo_service import service - -from wan_qos.common import topics - -eventlet.monkey_patch() - -WANTC_OPTS = [ - cfg.StrOpt('lan_port_name', - default='eth0', - help="The name of the port facing the LAN"), - cfg.StrOpt('lan_max_rate', - default='10mbit', - help="The maximum rate of the LAN port"), - cfg.StrOpt('wan_port_name', - default='eth1', - help="The name of the port facing the WAN"), - cfg.StrOpt('wan_max_rate', - default='10mbit', - help="The maximum rate of the WAN port") -] - - -def main(): - cfg.CONF.register_opts(WANTC_OPTS, 'WANTC') - common_config.init(sys.argv[1:]) - config.setup_logging() - server = neutron_service.Service.create( - binary='tc_agent2', - topic=topics.TC_AGENT, - report_interval=10, - manager='wan_qos.agent.tc_manager.TcAgentManager') - service.launch(cfg.CONF, server).wait() - - -if __name__ == '__main__': - main() diff --git a/wan_qos/agent/tc_driver.py b/wan_qos/agent/tc_driver.py deleted file mode 100644 index f33eff6..0000000 --- a/wan_qos/agent/tc_driver.py +++ /dev/null @@ -1,119 +0,0 @@ -# Copyright 2016 Huawei corp. -# 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 subprocess - -from neutron_lib import exceptions -from oslo_log import log as logging - -from wan_qos.agent import agent_api - -LOG = logging.getLogger(__name__) - - -class TcDriver(agent_api.AgentInterface): - def __init__(self): - self.ports = {} - - def set_ports(self, lan_port, wan_port): - self.ports['lan_port'] = lan_port - self.ports['wan_port'] = wan_port - - def get_ports(self): - return self.ports - - def clear_all(self): - for port in self.ports.values(): - subprocess.call('sudo tc qdisc del dev %s root' % port, shell=True) - - def set_root_queue(self, tc_dict): - subprocess.check_call('sudo tc qdisc add dev %s handle 1: root htb' % - self.ports[tc_dict['port_side']], shell=True) - class_str = 'sudo tc class add dev %s parent 1: classid 1:1 ' \ - 'htb rate %s ceil %s' - subprocess.check_call(class_str % (self.ports[tc_dict['port_side']], - str(tc_dict['max_rate']), - str(tc_dict['max_rate'])), - shell=True) - - def create_traffic_class(self, tc_dict): - """Create new traffic class. - Parameters: - port_side - lan_port / wan_port - parent - the parent class - child - the class id - min - minimum traffic rate (CIR) - max - maximum traffic rate. if not provide, the maximum rate will - be limitted by parent maximum rate. - """ - - LOG.debug('got request for new class: %s', tc_dict) - tc_dict['command'] = 'add' - self._create_or_update_class(tc_dict) - LOG.debug('new class created.') - - def update_traffic_class(self, tc_dict): - tc_dict['command'] = 'change' - self._create_or_update_class(tc_dict) - - def remove_traffic_class(self, tc_dict, with_filter=False): - if with_filter: - self.remove_filter(tc_dict) - cmd = 'sudo tc class del dev %s classid 1:%s' % ( - self.ports[tc_dict['port_side']], - tc_dict['child'] - ) - subprocess.check_call(cmd, shell=True) - - def _create_or_update_class(self, tc_dict): - cmd = 'sudo tc class %s dev %s parent 1:%s classid 1:%s htb' % ( - tc_dict['command'], - self.ports[tc_dict['port_side']], - tc_dict['parent'], tc_dict['child'] - - ) - if 'min' in tc_dict: - cmd += ' rate %s' % tc_dict['min'] - else: - cmd += ' rate 1kbit' - if 'max' in tc_dict: - cmd += ' ceil %s' % tc_dict['max'] - subprocess.check_call(cmd, shell=True) - - def create_filter(self, tc_dict): - - if tc_dict['protocol'] == 'vxlan': - self._create_vxlan_filter(tc_dict) - return - - raise exceptions.BadRequest(msg='Protocol not supported') - - def _create_vxlan_filter(self, tc_dict): - vni = tc_dict['match'].split('=')[1] - cmd = 'sudo tc filter add dev %s parent 1:0' % ( - self.ports[tc_dict['port_side']]) - cmd += ' protocol ip prio 1 u32' - cmd += ' match ip protocol 17 0xFF' # UDP - cmd += ' match u16 0x12B5 0xFFFF at 22' # VxLAN port - cmd += ' match u32 0x%0.6X00 0xFFFFFF00 at 32' % int(vni) - cmd += ' flowid 1:%s' % tc_dict['child'] - LOG.debug('creating filter: %s', cmd) - subprocess.check_call(cmd, shell=True) - - def remove_filter(self, tc_dict): - cmd = 'sudo tc filter del dev %s ' % self.ports[tc_dict['port_side']] - cmd += ' parent 1:0 protocol ip prio 1 u32' - cmd += ' flowid 1:%s' % tc_dict['child'] - subprocess.check_call(cmd, shell=True) diff --git a/wan_qos/agent/tc_manager.py b/wan_qos/agent/tc_manager.py deleted file mode 100644 index 0b4c300..0000000 --- a/wan_qos/agent/tc_manager.py +++ /dev/null @@ -1,168 +0,0 @@ -# Copyright 2016 Huawei corp. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_config import cfg -from oslo_log import log as logging -import oslo_messaging as messaging - -from neutron import manager -from neutron_lib import context as ctx -from neutron_lib import exceptions - -from wan_qos.agent import tc_driver -from wan_qos.common import api -from wan_qos.common import topics - -LOG = logging.getLogger(__name__) - - -class TcAgentManager(manager.Manager): - target = messaging.Target(version='1.0') - - def __init__(self, host=None, conf=None): - self.agent = tc_driver.TcDriver() - if not conf: - self.conf = cfg.CONF - else: - self.conf = conf - if not host: - self.host = self.conf.host - else: - self.host = host - lan_port = self.conf.WANTC.lan_port_name - wan_port = self.conf.WANTC.wan_port_name - self.agent.set_ports(lan_port, wan_port) - self.plugin_rpc = api.TcPluginApi(host, topics.TC_PLUGIN) - self.plugin_rpc.agent_up_notification(ctx.get_admin_context(), - self.agent.get_ports()) - - def init_host(self): - self.agent.clear_all() - tc_dict = { - 'port_side': 'lan_port', - 'max_rate': self.conf.WANTC.lan_max_rate - } - self.agent.set_root_queue(tc_dict) - tc_dict = { - 'port_side': 'wan_port', - 'max_rate': self.conf.WANTC.wan_max_rate - } - self.agent.set_root_queue(tc_dict) - context = ctx.get_admin_context() - agent_conf = self.plugin_rpc.get_configuration_from_db( - context) - class_tree = agent_conf['class_tree'] - if class_tree['id'] == 'root': - self.init_child_classes(class_tree['child_list']) - - if 'filters' in agent_conf: - for filter in agent_conf['filters']: - self.create_wtc_filter(context, filter) - return - raise exceptions.InvalidInput(error_message='Did not get root class') - - def init_child_classes(self, child_list): - for child in child_list: - self.create_wtc_class(None, child) - self.init_child_classes(child['child_list']) - - def after_start(self): - LOG.info("WAN QoS agent started") - - def periodic_tasks(self, context, raise_on_error=False): - LOG.info("periodic task") - self.plugin_rpc.device_heartbeat(context, self.host) - - def create_wtc_class(self, context, wtc_class_dict): - LOG.debug('got request for new class: %s', wtc_class_dict) - class_dict = { - 'parent': wtc_class_dict['parent_class_ext_id'], - 'child': wtc_class_dict['class_ext_id'] - - } - - if wtc_class_dict['min']: - class_dict['min'] = wtc_class_dict['min'] - if wtc_class_dict['max']: - class_dict['max'] = wtc_class_dict['max'] - if ( - wtc_class_dict['direction'] == 'in' or - wtc_class_dict['direction'] == 'both' - ): - class_dict['port_side'] = 'lan_port' - self._create_wtc_class(class_dict) - if ( - wtc_class_dict['direction'] == 'out' or - wtc_class_dict['direction'] == 'both' - ): - class_dict['port_side'] = 'wan_port' - self._create_wtc_class(class_dict) - - def _create_wtc_class(self, class_dict): - self.agent.create_traffic_class(class_dict) - - def delete_wtc_class(self, context, wtc_class_tree): - for child in wtc_class_tree['child_list']: - self.delete_wtc_class(context, child) - self._delete_wtc_class(wtc_class_tree) - - def _delete_wtc_class(self, wtc_class): - tc_dict = { - 'parent': wtc_class['parent_class_ext_id'], - 'child': wtc_class['class_ext_id'] - } - - if wtc_class['direction'] == 'in' or wtc_class['direction'] == 'both': - tc_dict['port_side'] = 'lan_port' - self.agent.remove_traffic_class(tc_dict) - if wtc_class['direction'] == 'out' or wtc_class['direction'] == 'both': - tc_dict['port_side'] = 'wan_port' - self.agent.remove_traffic_class(tc_dict) - - def create_wtc_filter(self, context, wtc_filter): - - wtc_class = self.plugin_rpc.get_class_by_id(context, - wtc_filter['class_id']) - - tc_dict = { - 'child': wtc_class['class_ext_id'], - 'protocol': wtc_filter['protocol'], - 'match': wtc_filter['match'] - } - - port_side = wtc_class['direction'] - - if port_side == 'both' or port_side == 'in': - tc_dict['port_side'] = 'lan_port' - self.agent.create_filter(tc_dict) - if port_side == 'both' or port_side == 'out': - tc_dict['port_side'] = 'wan_port' - self.agent.create_filter(tc_dict) - - def delete_wtc_filter(self, context, wtc_filter): - - wtc_class = wtc_filter['class'] - port_side = wtc_class['direction'] - - tc_dict = { - 'child': wtc_class['class_ext_id'] - } - - if port_side == 'both' or port_side == 'in': - tc_dict['port_side'] = 'lan_port' - self.agent.remove_filter(tc_dict) - if port_side == 'both' or port_side == 'out': - tc_dict['port_side'] = 'wan_port' - self.agent.remove_filter(tc_dict) diff --git a/wan_qos/cmd/__init__.py b/wan_qos/cmd/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/wan_qos/cmd/eventlet/__init__.py b/wan_qos/cmd/eventlet/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/wan_qos/cmd/eventlet/agent.py b/wan_qos/cmd/eventlet/agent.py deleted file mode 100644 index f7074b7..0000000 --- a/wan_qos/cmd/eventlet/agent.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright 2016 Huawei corp. -# 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 wan_qos.agent import tc_agent - - -def main(): - tc_agent.main() diff --git a/wan_qos/common/__init__.py b/wan_qos/common/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/wan_qos/common/api.py b/wan_qos/common/api.py deleted file mode 100644 index 2cef019..0000000 --- a/wan_qos/common/api.py +++ /dev/null @@ -1,81 +0,0 @@ -# Copyright 2016 Huawei corp. -# 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 oslo_messaging - -from neutron.common import rpc as n_rpc - -from wan_qos.common import topics - - -class TcPluginApi(object): - def __init__(self, host, topic=topics.TC_PLUGIN): - self.host = host - target = oslo_messaging.Target(topic=topic, version='1.0') - self.client = n_rpc.get_client(target) - - def agent_up_notification(self, context, ports): - cctxt = self.client.prepare() - host_info = { - 'host': self.host, - 'lan_port': ports['lan_port'], - 'wan_port': ports['wan_port'] - } - cctxt.cast(context, 'agent_up_notification', - host_info=host_info) - - def device_heartbeat(self, context, host): - cctxt = self.client.prepare() - cctxt.cast(context, 'device_heartbeat', - host=host) - - def get_configuration_from_db(self, context): - cctxt = self.client.prepare() - return cctxt.call(context, 'get_configuration_from_db', host=self.host) - - def get_class_by_id(self, context, id): - cctxt = self.client.prepare() - return cctxt.call(context, 'get_class_by_id', id=id) - - -class TcAgentApi(object): - def __init__(self, host, topic=topics.TC_AGENT): - self.host = host - target = oslo_messaging.Target(topic=topic, version='1.0') - self.client = n_rpc.get_client(target) - - def create_wtc_class(self, context, wtc_class_dict): - cctxt = self.client.prepare() - return cctxt.call(context, - 'create_wtc_class', - wtc_class_dict=wtc_class_dict) - - def delete_wtc_class(self, context, wtc_class_tree): - cctxt = self.client.prepare() - return cctxt.call(context, - 'delete_wtc_class', - wtc_class_tree=wtc_class_tree) - - def create_wtc_filter(self, context, wtc_filter): - cctxt = self.client.prepare() - return cctxt.call(context, - 'create_wtc_filter', - wtc_filter=wtc_filter) - - def delete_wtc_filter(self, context, wtc_filter): - cctxt = self.client.prepare() - return cctxt.call(context, - 'delete_wtc_filter', - wtc_filter=wtc_filter) diff --git a/wan_qos/common/constants.py b/wan_qos/common/constants.py deleted file mode 100644 index fd16bbd..0000000 --- a/wan_qos/common/constants.py +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright 2016 Huawei corp. -# 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. - -WANTC = 'WANTC' - -WAN_TC_DEVICE = 'wan_tc_device' -WAN_TC_DEVICE_PATH = 'wan-tc-devices' - -WAN_TC_CLASS = 'wan_tc_class' -WAN_TC_CLASS_PATH = 'wan-tc-classs' - -WAN_TC_FILTER = 'wan_tc_filter' -WAN_TC_FILTER_PATH = 'wan-tc-filters' - -WAN_TC = 'wan_tc' -WAN_TC_PATH = 'wan-tcs' diff --git a/wan_qos/common/topics.py b/wan_qos/common/topics.py deleted file mode 100644 index a244cca..0000000 --- a/wan_qos/common/topics.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2016 Huawei corp. -# 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. - -TC_AGENT = 'wan_qos_agent' -TC_PLUGIN = 'wan_qos_plugin' diff --git a/wan_qos/db/__init__.py b/wan_qos/db/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/wan_qos/db/migration/__init__.py b/wan_qos/db/migration/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/wan_qos/db/migration/alembic_migrations/__init__.py b/wan_qos/db/migration/alembic_migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/wan_qos/db/migration/alembic_migrations/env.py b/wan_qos/db/migration/alembic_migrations/env.py deleted file mode 100644 index 7ec51e4..0000000 --- a/wan_qos/db/migration/alembic_migrations/env.py +++ /dev/null @@ -1,99 +0,0 @@ -# Copyright 2015 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# - -from logging import config as logging_config - -from alembic import context -from neutron_lib.db import model_base -from oslo_config import cfg -from oslo_db.sqlalchemy import session -import sqlalchemy as sa -from sqlalchemy import event - -from neutron.db.migration.alembic_migrations import external -from neutron.db.migration.models import head # noqa - -MYSQL_ENGINE = None -WANTC_VERSION_TABLE = 'wantc_alembic_version' -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 include_object(object, name, type_, reflected, compare_to): - if type_ == 'table' and name in external.TABLES: - return False - else: - return True - - -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['include_object'] = include_object - kwargs['version_table'] = WANTC_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, - include_object=include_object, - version_table=WANTC_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/wan_qos/db/migration/alembic_migrations/script.py.mako b/wan_qos/db/migration/alembic_migrations/script.py.mako deleted file mode 100644 index 9e0b2ce..0000000 --- a/wan_qos/db/migration/alembic_migrations/script.py.mako +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright ${create_date.year} -# -# 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. -# - -"""${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/wan_qos/db/migration/alembic_migrations/versions/__init__.py b/wan_qos/db/migration/alembic_migrations/versions/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/wan_qos/db/migration/alembic_migrations/versions/ocata/__init__.py b/wan_qos/db/migration/alembic_migrations/versions/ocata/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/wan_qos/db/migration/alembic_migrations/versions/ocata/contract/45194b1d3492_first_rev.py b/wan_qos/db/migration/alembic_migrations/versions/ocata/contract/45194b1d3492_first_rev.py deleted file mode 100644 index a38b1dd..0000000 --- a/wan_qos/db/migration/alembic_migrations/versions/ocata/contract/45194b1d3492_first_rev.py +++ /dev/null @@ -1,84 +0,0 @@ -# Copyright 2017 -# -# 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. -# - -"""first rev - -Revision ID: 45194b1d3492 -Revises: None -Create Date: 2017-01-04 13:46:13.433909 - -""" - -# revision identifiers, used by Alembic. -revision = '45194b1d3492' -down_revision = None - -from alembic import op -import sqlalchemy as sa - - -def upgrade(): - op.create_table('wan_tc_class', - sa.Column('id', sa.String(length=36), nullable=False), - sa.Column('parent', sa.String(length=36)), - sa.Column('device_id', sa.String(length=36)), - sa.Column('direction', sa.String(length=4), - nullable=False), - sa.Column('project_id', sa.String(length=36)), - sa.Column('class_ext_id', sa.Integer()), - sa.Column('parent_class_ext_id', sa.Integer()), - sa.Column('min', sa.String(length=15)), - sa.Column('max', sa.String(length=15)), - sa.PrimaryKeyConstraint('id') - ) - - op.create_foreign_key( - 'fk_wtc_class', - 'wan_tc_class', 'wan_tc_class', - ['parent'], ['id'], ondelete='CASCADE' - ) - - op.create_table('wan_tc_filter', - sa.Column('id', sa.String(length=36), nullable=False), - sa.Column('project_id', sa.String(length=36)), - sa.Column('class_id', sa.String(length=36), - nullable=False), - sa.Column('network', sa.String(length=36)), - sa.Column('protocol', sa.String(length=15)), - sa.Column('match', sa.String(length=15)), - sa.PrimaryKeyConstraint('id') - ) - - op.create_foreign_key( - 'fk_wan_tc__filter_class', - 'wan_tc_filter', 'wan_tc_class', - ['class_id'], ['id'], - ) - - op.create_foreign_key( - 'fk_wan_tc_filter_networks', - 'wan_tc_filter', 'networks', - ['network'], ['id'], - ) - - op.create_table( - 'wan_tc_device', - sa.Column('id', sa.String(length=36), nullable=False), - sa.Column('host', sa.String(100), nullable=False), - sa.Column('lan_port', sa.String(15), nullable=False), - sa.Column('wan_port', sa.String(15), nullable=False), - sa.Column('uptime', sa.DateTime()), - sa.Column('heartbeat_timestamp', sa.DateTime()) - ) diff --git a/wan_qos/db/migration/alembic_migrations/versions/ocata/contract/__init__.py b/wan_qos/db/migration/alembic_migrations/versions/ocata/contract/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/wan_qos/db/models/__init__.py b/wan_qos/db/models/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/wan_qos/db/models/wan_tc.py b/wan_qos/db/models/wan_tc.py deleted file mode 100644 index f9b568d..0000000 --- a/wan_qos/db/models/wan_tc.py +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright 2016 Huawei corp. -# 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 sqlalchemy as sa - -from neutron_lib.db import model_base - - -class WanTcDevice(model_base.BASEV2, - model_base.HasId): - __tablename__ = 'wan_tc_device' - host = sa.Column(sa.String(100), nullable=False) - lan_port = sa.Column(sa.String(15), nullable=False) - wan_port = sa.Column(sa.String(15), nullable=False) - uptime = sa.Column(sa.DateTime()) - heartbeat_timestamp = sa.Column(sa.DateTime()) - - -class WanTcClass(model_base.BASEV2, - model_base.HasId, model_base.HasProject): - __tablename__ = 'wan_tc_class' - device_id = sa.Column(sa.String(36), - sa.ForeignKey('wan_tc_device.id', - ondelete='CASCADE'), - nullable=True) - direction = sa.Column(sa.String(4), nullable=False) - class_ext_id = sa.Column(sa.Integer) - parent = sa.Column(sa.String(36), - sa.ForeignKey('wan_tc_class.id', - ondelete='CASCADE'), - nullable=True) - parent_class_ext_id = sa.Column(sa.Integer) - min = sa.Column(sa.String(15)) - max = sa.Column(sa.String(15)) - - -class WanTcFilter(model_base.BASEV2, - model_base.HasId, model_base.HasProject): - __tablename__ = 'wan_tc_filter' - class_id = sa.Column(sa.String(36), - sa.ForeignKey('wan_tc_class.id', - ondelete='CASCADE'), - nullable=False) - network = sa.Column(sa.String(36), - sa.ForeignKey('networks.id', - ondelete='CASCADE')) - protocol = sa.Column(sa.String(15)) - match = sa.Column(sa.String(15)) diff --git a/wan_qos/db/wan_qos_db.py b/wan_qos/db/wan_qos_db.py deleted file mode 100644 index 65a5038..0000000 --- a/wan_qos/db/wan_qos_db.py +++ /dev/null @@ -1,345 +0,0 @@ -# Copyright 2016 Huawei corp. -# 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 threading - -from neutron_lib import exceptions -from neutron_lib import context as ctx -from oslo_log import log as logging -from oslo_utils import timeutils -from oslo_utils import uuidutils - -from wan_qos.db.models import wan_tc as models - -LOG = logging.getLogger(__name__) - - -class WanTcDb(object): - _last_class_ext_id = None - - def __init__(self): - self._lock = threading.Lock() - self._initialize_tables() - - def _initialize_tables(self): - context = ctx.get_admin_context() - root_class = context.session.query(models.WanTcClass).filter_by( - id='root').first() - if not root_class: - with context.session.begin(subtransactions=True): - root_class = models.WanTcClass( - id='root', - class_ext_id=1, - direction='both' - ) - context.session.add(root_class) - - def agent_up_notification(self, context, host_info): - device = context.session.query(models.WanTcDevice).filter_by( - host=host_info['host'] - ).first() - - with context.session.begin(subtransactions=True): - if not device: - LOG.debug('New device connected: %s', host_info) - now = timeutils.utcnow() - wan_tc_device = models.WanTcDevice( - id=uuidutils.generate_uuid(), - host=host_info['host'], - lan_port=host_info['lan_port'], - wan_port=host_info['wan_port'], - uptime=now, - heartbeat_timestamp=now - ) - return context.session.add(wan_tc_device) - else: - LOG.debug('updating uptime for device: %s', host_info['host']) - device.uptime = timeutils.utcnow() - - def device_heartbeat(self, context, host): - device = context.session.query(models.WanTcDevice).filter_by( - host=host - ).first() - if device: - with context.session.begin(subtransactions=True): - device.heartbeat_timestamp = timeutils.utcnow() - else: - LOG.error('Got heartbeat for non-existing device: %s', host) - - def get_all_devices(self, context, filters=None, - fields=None, - sorts=None, limit=None, marker=None, - page_reverse=False): - marker_obj = self._get_marker_obj( - context, 'wan_tc_device', limit, marker) - return self._get_collection(context, models.WanTcDevice, - self._device_to_dict, - filters=filters, fields=fields, - sorts=sorts, limit=limit, - marker_obj=marker_obj, - page_reverse=page_reverse) - - def get_last_class_ext_id(self, context): - - self._lock.acquire() - if not self._last_class_ext_id: - last_class_ext_id_db = context.session.query( - models.WanTcClass.class_ext_id).order_by( - models.WanTcClass.class_ext_id.desc()).first() - if last_class_ext_id_db: - self._last_class_ext_id, = last_class_ext_id_db - else: - self._last_class_ext_id = 10 - self._last_class_ext_id += 1 - next_id = self._last_class_ext_id - self._lock.release() - return next_id - - def create_wan_tc_class(self, context, wtc_class): - - wtc_class_db = models.WanTcClass( - id=uuidutils.generate_uuid(), - direction=wtc_class['direction'], - class_ext_id=self.get_last_class_ext_id(context) - ) - - if 'parent' in wtc_class and wtc_class['parent'] != '': - parent = wtc_class['parent'] - parent_class = self.get_class_by_id(context, parent) - if not parent_class: - raise exceptions.BadRequest(msg='invalid parent id') - wtc_class_db.parent = parent - wtc_class_db.parent_class_ext_id = parent_class['class_ext_id'] - else: - wtc_class_db.parent = 'root' - wtc_class_db.parent_class_ext_id = 1 - - with context.session.begin(subtransactions=True): - - if 'min' in wtc_class: - wtc_class_db.min = wtc_class['min'] - if 'max' in wtc_class: - wtc_class_db.max = wtc_class['max'] - - context.session.add(wtc_class_db) - class_dict = self._class_to_dict(wtc_class_db) - class_dict['parent_class_ext_id'] = wtc_class_db.parent_class_ext_id - return class_dict - - def delete_wtc_class(self, context, id): - wtc_class_db = context.session.query(models.WanTcClass).filter_by( - id=id).first() - if wtc_class_db: - with context.session.begin(subtransactions=True): - context.session.delete(wtc_class_db) - - def get_class_by_id(self, context, id): - wtc_class = context.session.query(models.WanTcClass).filter_by( - id=id).first() - if wtc_class: - return self._class_to_dict(wtc_class) - - def get_all_classes(self, context, filters=None, - fields=None, - sorts=None, limit=None, marker=None, - page_reverse=False): - marker_obj = self._get_marker_obj( - context, 'wan_tc_class', limit, marker) - all_classes = self._get_collection(context, models.WanTcClass, - self._class_to_dict, - filters=filters, fields=fields, - sorts=sorts, limit=limit, - marker_obj=marker_obj, - page_reverse=page_reverse) - if not filters: - for wtc_class in all_classes: - if wtc_class['id'] == 'root': - all_classes.remove(wtc_class) - break - return all_classes - - def _class_to_dict(self, wtc_class, fields=None): - - class_dict = { - 'id': wtc_class.id, - 'direction': wtc_class.direction, - 'min': wtc_class.min, - 'max': wtc_class.max, - 'class_ext_id': wtc_class.class_ext_id, - 'parent': wtc_class.parent, - 'parent_class_ext_id': wtc_class.parent_class_ext_id - } - - return class_dict - - def _device_to_dict(self, device, fields=None): - device_dict = { - 'id': device.id, - 'host': device.host, - 'lan_port': device.lan_port, - 'wan_port': device.wan_port, - 'uptime': device.uptime, - 'last_seen': device.heartbeat_timestamp - } - - return device_dict - - def delete_wan_tc_device(self, context, id): - device = context.session.query(models.WanTcDevice).filter_by( - id=id - ).first() - if device: - with context.session.begin(subtransactions=True): - context.session.delete(device) - else: - LOG.error('Trying to delete none existing device. id=%s', id) - - def get_device(self, context, id): - device = context.session.query(models.WanTcDevice).filter_by( - id=id - ).first() - if device: - return self._device_to_dict(device) - - def get_class_tree(self, start_from_id='root'): - context = ctx.get_admin_context() - root_class_db = context.session.query(models.WanTcClass).filter_by( - id=start_from_id).first() - root_class = self._class_to_dict(root_class_db) - self._get_child_classes(context, root_class) - return root_class - - def _get_child_classes(self, context, parent_class): - child_classes_db = context.session.query(models.WanTcClass).filter_by( - parent=parent_class['id']).all() - parent_class['child_list'] = [] - for child_class_db in child_classes_db: - child_class = self._class_to_dict(child_class_db) - parent_class['child_list'].append(child_class) - self._get_child_classes(context, child_class) - - def create_wan_tc_filter(self, context, wan_tc_filter): - - wtc_filter_db = models.WanTcFilter( - id=uuidutils.generate_uuid(), - protocol=wan_tc_filter['protocol'], - match=wan_tc_filter['match'], - class_id=wan_tc_filter['class_id'] - ) - - if 'network' in wan_tc_filter: - wtc_filter_db.network = wan_tc_filter['network'] - - with context.session.begin(subtransactions=True): - context.session.add(wtc_filter_db) - - return self._filter_to_dict(wtc_filter_db) - - def _filter_to_dict(self, wtc_filter_db, fields=None): - wtc_filter = { - 'id': wtc_filter_db.id, - 'protocol': wtc_filter_db.protocol, - 'match': wtc_filter_db.match, - 'class_id': wtc_filter_db.class_id, - 'network': wtc_filter_db.network - } - - return wtc_filter - - def get_wan_tc_filter(self, context, id, fields=None): - - wtc_filter_db = context.session.query(models.WanTcFilter).filter_by( - id=id).first() - if wtc_filter_db: - return self._filter_to_dict(wtc_filter_db) - return {} - - def get_wan_tc_filters(self, context, filters=None, fields=None, - sorts=None, limit=None, marker=None, - page_reverse=False): - marker_obj = self._get_marker_obj( - context, 'wan_tc_filter', limit, marker) - return self._get_collection(context, models.WanTcFilter, - self._filter_to_dict, - filters=filters, fields=fields, - sorts=sorts, limit=limit, - marker_obj=marker_obj, - page_reverse=page_reverse) - - def delete_wan_tc_filter(self, context, id): - filter_db = context.session.query(models.WanTcFilter).filter_by( - id=id - ).first() - if filter_db: - with context.session.begin(subtransactions=True): - context.session.delete(filter_db) - else: - LOG.error('Trying to delete none existing tc filter. id=%s', id) - - def _get_collection(self, context, model, dict_func, filters=None, - fields=None, sorts=None, limit=None, marker_obj=None, - page_reverse=False): - """Get collection object based on query for resources.""" - if not self._has_attribute(model, filters): - return [] - query = self._get_collection_query(context, model, filters=filters, - sorts=sorts, - limit=limit, - marker_obj=marker_obj, - page_reverse=page_reverse) - items = [dict_func(c, fields) for c in query] - if limit and page_reverse: - items.reverse() - return items - - def _has_attribute(self, model, filters): - if filters: - for key in filters.keys(): - if not hasattr(model, key): - return False - return True - - def _get_collection_query(self, context, model, filters=None, - sorts=None, limit=None, marker_obj=None, - page_reverse=False): - """Get collection query for the models.""" - collection = self._model_query(context, model) - collection = self._apply_filters_to_query(collection, model, filters) - return collection - - def _get_marker_obj(self, context, resource, limit, marker): - """Get marker object for the resource.""" - if limit and marker: - return getattr(self, '_get_%s' % resource)(context, marker) - return None - - def _model_query(self, context, model): - """Query model based on filter.""" - query = context.session.query(model) - query_filter = None - if not context.is_admin and hasattr(model, 'tenant_id'): - query_filter = (model.tenant_id == context.tenant_id) - if query_filter is not None: - query = query.filter(query_filter) - return query - - def _apply_filters_to_query(self, query, model, filters): - """Apply filters to query for the models.""" - if filters: - for key, value in filters.items(): - column = getattr(model, key, None) - if column: - query = query.filter(column.in_(value)) - return query diff --git a/wan_qos/extensions/__init__.py b/wan_qos/extensions/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/wan_qos/extensions/wantc.py b/wan_qos/extensions/wantc.py deleted file mode 100644 index 6bd473e..0000000 --- a/wan_qos/extensions/wantc.py +++ /dev/null @@ -1,111 +0,0 @@ -# Copyright 2017 Huawei corp. -# 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 abc - -from neutron.api.v2 import resource_helper -from neutron_lib.api import extensions - -from wan_qos.common import constants - -RESOURCE_ATTRIBUTE_MAP = { - constants.WAN_TC_PATH: { - 'id': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - 'min': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'is_visible': True, - 'default': '', - }, - 'max': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'is_visible': True, - 'default': '', - }, - 'network': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'is_visible': True, - 'default': '', - }, - 'project_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'required_by_policy': True, - 'is_visible': True} - }, -} - - -class Wantc(extensions.ExtensionDescriptor): - @classmethod - def get_name(cls): - return "WAN Traffic Control single command" - - @classmethod - def get_alias(cls): - return "wan-tc" - - @classmethod - def get_description(cls): - return "Class for limiting traffic on WAN links using single command" - - @classmethod - def get_updated(cls): - return "2017-02-28T00:00:00-00:00" - - @classmethod - def get_resources(cls): - """Returns Ext Resources.""" - - mem_actions = {} - plural_mappings = resource_helper.build_plural_mappings( - {}, RESOURCE_ATTRIBUTE_MAP) - resources = resource_helper.build_resource_info(plural_mappings, - RESOURCE_ATTRIBUTE_MAP, - constants.WANTC, - action_map=mem_actions, - register_quota=True, - translate_name=True) - - return resources - - def get_extended_resources(self, version): - if version == "2.0": - return RESOURCE_ATTRIBUTE_MAP - else: - return {} - - -class WanTcPluginBase(object): - @abc.abstractmethod - def create_wan_tc(self, context, wan_tc): - pass - - @abc.abstractmethod - def get_wan_tc(self, context, id, fields=None): - pass - - @abc.abstractmethod - def get_wan_tcs(self, context, filters=None, fields=None, - sorts=None, limit=None, marker=None, - page_reverse=False): - pass - - @abc.abstractmethod - def update_wan_tc(self, context, id, wan_tc): - pass - - @abc.abstractmethod - def delete_wan_tc(self, context, id): - pass diff --git a/wan_qos/extensions/wantcclass.py b/wan_qos/extensions/wantcclass.py deleted file mode 100644 index 54e7936..0000000 --- a/wan_qos/extensions/wantcclass.py +++ /dev/null @@ -1,114 +0,0 @@ -# Copyright 2016 Huawei corp. -# 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 abc - -from neutron.api.v2 import resource_helper -from neutron_lib.api import extensions - -from wan_qos.common import constants - -RESOURCE_ATTRIBUTE_MAP = { - constants.WAN_TC_CLASS_PATH: { - 'id': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - 'parent': {'allow_post': True, 'allow_put': False, - 'is_visible': True, - 'default': ''}, - 'direction': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'is_visible': True, - 'default': '' - }, - 'min': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'is_visible': True, - 'default': '', - }, - 'max': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'is_visible': True, - 'default': '', - }, - 'project_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'required_by_policy': True, - 'is_visible': True} - }, -} - - -class Wantcclass(extensions.ExtensionDescriptor): - @classmethod - def get_name(cls): - return "WAN Traffic Control class" - - @classmethod - def get_alias(cls): - return "wan-tc-class" - - @classmethod - def get_description(cls): - return "Class for limiting traffic on WAN links" - - @classmethod - def get_updated(cls): - return "2017-01-16T00:00:00-00:00" - - @classmethod - def get_resources(cls): - """Returns Ext Resources.""" - - mem_actions = {} - plural_mappings = resource_helper.build_plural_mappings( - {}, RESOURCE_ATTRIBUTE_MAP) - resources = resource_helper.build_resource_info(plural_mappings, - RESOURCE_ATTRIBUTE_MAP, - constants.WANTC, - action_map=mem_actions, - register_quota=True, - translate_name=True) - - return resources - - def get_extended_resources(self, version): - if version == "2.0": - return RESOURCE_ATTRIBUTE_MAP - else: - return {} - - -class WanTcClassPluginBase(object): - @abc.abstractmethod - def create_wan_tc_class(self, context, wan_tc_class): - pass - - @abc.abstractmethod - def get_wan_tc_class(self, context, id, fields=None): - pass - - @abc.abstractmethod - def get_wan_tc_classs(self, context, filters=None, fields=None, - sorts=None, limit=None, marker=None, - page_reverse=False): - pass - - @abc.abstractmethod - def update_wan_tc_class(self, context, id, wan_tc_class): - pass - - @abc.abstractmethod - def delete_wan_tc_class(self, context, id): - pass diff --git a/wan_qos/extensions/wantcdevice.py b/wan_qos/extensions/wantcdevice.py deleted file mode 100644 index c42a2e1..0000000 --- a/wan_qos/extensions/wantcdevice.py +++ /dev/null @@ -1,99 +0,0 @@ -# Copyright 2016 Huawei corp. -# 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 abc - -from neutron.api.v2 import resource_helper -from neutron_lib.api import extensions - -from wan_qos.common import constants - -RESOURCE_ATTRIBUTE_MAP = { - constants.WAN_TC_DEVICE_PATH: { - 'id': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - 'host': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'lan_port': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'wan_port': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'is_visible': True}, - 'uptime': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'is_visible': True}, - 'last_seen': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'is_visible': True} - }, -} - - -class Wantcdevice(extensions.ExtensionDescriptor): - @classmethod - def get_name(cls): - return "WAN Traffic Control device" - - @classmethod - def get_alias(cls): - return "wan-tc-device" - - @classmethod - def get_description(cls): - return "Device for limiting traffic on WAN links" - - @classmethod - def get_updated(cls): - return "2017-01-15T00:00:00-00:00" - - @classmethod - def get_resources(cls): - """Returns Ext Resources.""" - - mem_actions = {} - plural_mappings = resource_helper.build_plural_mappings( - {}, RESOURCE_ATTRIBUTE_MAP) - resources = resource_helper.build_resource_info(plural_mappings, - RESOURCE_ATTRIBUTE_MAP, - constants.WANTC, - action_map=mem_actions, - register_quota=True, - translate_name=True) - - return resources - - def get_extended_resources(self, version): - if version == "2.0": - return RESOURCE_ATTRIBUTE_MAP - else: - return {} - - -class WanTcDevicePluginBase(object): - @abc.abstractmethod - def get_wan_tc_device(self, context, id, fields=None): - pass - - @abc.abstractmethod - def get_wan_tc_devices(self, context, filters=None, fields=None, - sorts=None, limit=None, marker=None, - page_reverse=False): - pass - - @abc.abstractmethod - def delete_wan_tc_device(self, context, id): - pass diff --git a/wan_qos/extensions/wantcfilter.py b/wan_qos/extensions/wantcfilter.py deleted file mode 100644 index ed8af66..0000000 --- a/wan_qos/extensions/wantcfilter.py +++ /dev/null @@ -1,105 +0,0 @@ -# Copyright 2016 Huawei corp. -# 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 abc - -from neutron.api.v2 import resource_helper -from neutron_lib.api import extensions - -from wan_qos.common import constants - -RESOURCE_ATTRIBUTE_MAP = { - constants.WAN_TC_FILTER_PATH: { - 'id': {'allow_post': False, 'allow_put': False, - 'is_visible': True}, - 'class_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'protocol': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'is_visible': True, 'default': ''}, - 'match': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'is_visible': True}, - 'project_id': {'allow_post': True, 'allow_put': False, - 'validate': {'type:string': None}, - 'required_by_policy': True, - 'is_visible': True} - }, -} - - -class Wantcfilter(extensions.ExtensionDescriptor): - @classmethod - def get_name(cls): - return "WAN Traffic Control filter" - - @classmethod - def get_alias(cls): - return "wan-tc-filter" - - @classmethod - def get_description(cls): - return "filter to select traffic limit class on WAN links" - - @classmethod - def get_updated(cls): - return "2017-01-25T00:00:00-00:00" - - @classmethod - def get_resources(cls): - "Returns Ext Resources." - - mem_actions = {} - plural_mappings = resource_helper.build_plural_mappings( - {}, RESOURCE_ATTRIBUTE_MAP) - resources = resource_helper.build_resource_info(plural_mappings, - RESOURCE_ATTRIBUTE_MAP, - constants.WANTC, - action_map=mem_actions, - register_quota=True, - translate_name=True) - - return resources - - def get_extended_resources(self, version): - if version == "2.0": - return RESOURCE_ATTRIBUTE_MAP - else: - return {} - - -class WanTcFilterPluginBase(object): - @abc.abstractmethod - def create_wan_tc_filter(self, context, wan_tc_filter): - pass - - @abc.abstractmethod - def get_wan_tc_filter(self, context, id, fields=None): - pass - - @abc.abstractmethod - def get_wan_tc_filters(self, context, filters=None, fields=None, - sorts=None, limit=None, marker=None, - page_reverse=False): - pass - - @abc.abstractmethod - def update_wan_tc_filter(self, context, id, wan_tc_filter): - pass - - @abc.abstractmethod - def delete_wan_tc_filter(self, context, id): - pass diff --git a/wan_qos/services/__init__.py b/wan_qos/services/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/wan_qos/services/plugin.py b/wan_qos/services/plugin.py deleted file mode 100644 index 6e7985c..0000000 --- a/wan_qos/services/plugin.py +++ /dev/null @@ -1,240 +0,0 @@ -# Copyright 2016 Huawei corp. -# 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.common import rpc as n_rpc -from neutron.db import agents_db -from neutron_lib import exceptions -from neutron_lib.plugins import directory -from oslo_config import cfg -from oslo_log import log as logging -import oslo_messaging as messaging -from oslo_utils import importutils - -from wan_qos.common import api -from wan_qos.common import constants -from wan_qos.common import topics -from wan_qos.db import wan_qos_db -from wan_qos.extensions import wantc -from wan_qos.extensions import wantcclass -from wan_qos.extensions import wantcdevice -from wan_qos.extensions import wantcfilter - -LOG = logging.getLogger(__name__) - - -class PluginRpcCallback(object): - target = messaging.Target(version='1.0') - - def __init__(self, plugin): - super(PluginRpcCallback, self).__init__() - self.plugin = plugin - LOG.debug('rpc callback started.') - - def agent_up_notification(self, context, host_info): - LOG.debug('got up notification from %s', host_info['host']) - self.plugin.db.agent_up_notification(context, host_info) - - def device_heartbeat(self, context, host): - self.plugin.db.device_heartbeat(context, host) - - def get_configuration_from_db(self, context, host): - conf = { - 'class_tree': self.plugin.db.get_class_tree(), - 'filters': self.plugin.db.get_wan_tc_filters(context) - } - - return conf - - def get_class_by_id(self, context, id): - return self.plugin.db.get_class_by_id(context, id) - - -class WanQosPlugin(wantcfilter.WanTcFilterPluginBase, - wantcdevice.WanTcDevicePluginBase, - wantcclass.WanTcClassPluginBase, - wantc.WanTcPluginBase): - supported_extension_aliases = ['wan-tc-filter', 'wan-tc-device', - 'wan-tc-class', 'wan-tc'] - - def __init__(self): - self.db = wan_qos_db.WanTcDb() - rpc_callback = importutils.import_object( - 'wan_qos.services.plugin.PluginRpcCallback', self) - endpoints = ( - [rpc_callback, agents_db.AgentExtRpcCallback()]) - self.agent_rpc = api.TcAgentApi(cfg.CONF.host) - self.conn = n_rpc.create_connection() - self.conn.create_consumer(topics.TC_PLUGIN, - endpoints, - fanout=False) - self.conn.consume_in_threads() - - def get_plugin_type(self): - """Get type of the plugin.""" - return constants.WANTC - - def get_plugin_description(self): - """Get description of the plugin.""" - return 'Plugin for rate limiting on WAN links.' - - @property - def _core_plugin(self): - return directory.get_plugin() - - def delete_wan_tc_device(self, context, id): - self.db.delete_wan_tc_device(context, id) - - def get_wan_tc_device(self, context, id, fields=None): - return self.db.get_device(context, id) - - def get_wan_tc_devices(self, context, filters=None, fields=None, - sorts=None, limit=None, marker=None, - page_reverse=False): - return self.db.get_all_devices(context, filters, fields, sorts, limit, - marker, page_reverse) - - def get_wan_tc_class(self, context, id, fields=None): - return self.db.get_class_by_id(context, id) - - def update_wan_tc_class(self, context, id, wan_tc_class): - pass - - def create_wan_tc_class(self, context, wan_tc_class): - LOG.debug('got new class request: %s', wan_tc_class) - wtc_class_db = self.db.create_wan_tc_class(context, - wan_tc_class[ - 'wan_tc_class']) - self.agent_rpc.create_wtc_class(context, wtc_class_db) - return wtc_class_db - - def delete_wan_tc_class(self, context, id): - LOG.debug('Got request to delete class id: %s', id) - class_tree = self.db.get_class_tree(id) - self.db.delete_wtc_class(context, id) - self.agent_rpc.delete_wtc_class(context, class_tree) - - def get_wan_tc_classs(self, context, filters=None, fields=None, sorts=None, - limit=None, marker=None, page_reverse=False): - return self.db.get_all_classes(context, filters, fields, sorts, limit, - marker, page_reverse) - - def delete_wan_tc_filter(self, context, id): - wtc_filter = self.get_wan_tc_filter(context, id) - if wtc_filter: - wtc_class = self.get_wan_tc_class(context, wtc_filter['class_id']) - self.db.delete_wan_tc_filter(context, id) - wtc_filter['class'] = wtc_class - self.agent_rpc.delete_wtc_filter(context, wtc_filter) - - def get_wan_tc_filters(self, context, filters=None, fields=None, - sorts=None, limit=None, marker=None, - page_reverse=False): - return self.db.get_wan_tc_filters(context, filters, fields, sorts, - limit, - marker, page_reverse) - - def create_wan_tc_filter(self, context, wan_tc_filter): - wtc_filter = self.db.create_wan_tc_filter(context, - wan_tc_filter[ - 'wan_tc_filter']) - # wtc_class = self.get_wan_tc_class(context, wtc_filter['class_id']) - # wtc_filter['class'] = wtc_class - self.agent_rpc.create_wtc_filter(context, wtc_filter) - return wtc_filter - - def update_wan_tc_filter(self, context, id, wan_tc_filter): - pass - - def get_wan_tc_filter(self, context, id, fields=None): - return self.db.get_wan_tc_filter(context, id, fields) - - @staticmethod - def _get_tenant_id_for_create(self, context, resource): - """Get tenant id for creation of resources.""" - if context.is_admin and 'tenant_id' in resource: - tenant_id = resource['tenant_id'] - elif ( - 'tenant_id' in resource and - resource['tenant_id'] != context.tenant_id - ): - reason = 'Cannot create resource for another tenant' - raise exceptions.AdminRequired(reason=reason) - else: - tenant_id = context.tenant_id - return tenant_id - - def get_wan_tc(self, context, id, fields=None): - filter_db = self.get_wan_tc_filter(context, id, fields) - class_db = self.get_wan_tc_class(context, filter_db['class_id']) - filter_db['min'] = class_db['min'] - filter_db['max'] = class_db['max'] - return filter_db - - def get_wan_tcs(self, context, filters=None, fields=None, sorts=None, - limit=None, marker=None, page_reverse=False): - filters = self.get_wan_tc_filters(context, filters, fields, sorts, - limit, marker, page_reverse) - for filter_db in filters: - class_db = self.get_wan_tc_class(context, filter_db['class_id']) - filter_db['min'] = class_db['min'] - filter_db['max'] = class_db['max'] - - return filters - - def create_wan_tc(self, context, wan_tc): - LOG.debug('got WAN_TC: %s', wan_tc) - wan_tc_req = wan_tc['wan_tc'] - - filter_db = self.get_wan_tc_filters(context, filters={ - 'network': [wan_tc_req['network']]}) - if filter_db: - raise exceptions.InvalidInput( - error_message='Network already has limiter') - - network = self._core_plugin.get_network(context, wan_tc_req['network']) - if network['provider:network_type'] != 'vxlan': - raise exceptions.InvalidInput() - vni = network['provider:segmentation_id'] - tc_class = {'wan_tc_class': { - 'direction': 'both', - 'min': wan_tc_req['min'] - } - } - - if 'max' in wan_tc_req: - tc_class['wan_tc_class']['max'] = wan_tc_req['max'] - - tc_class_db = self.create_wan_tc_class(context, tc_class) - tc_filter_req = {'wan_tc_filter': { - 'protocol': 'vxlan', - 'match': 'vni=%s' % vni, - 'class_id': tc_class_db['id'], - 'network': network['id'] - } - } - tc_filter_db = self.create_wan_tc_filter(context, tc_filter_req) - tc_filter_db['min'] = tc_class_db['min'] - tc_filter_db['max'] = tc_class_db['max'] - return tc_filter_db - - def update_wan_tc(self, context, id, wan_tc): - raise exceptions.BadRequest(msg='Not implemented yet!') - - def delete_wan_tc(self, context, id): - LOG.debug('Deleting TC: %s', id) - tc_filter = self.get_wan_tc_filter(context, id) - class_id = tc_filter['class_id'] - self.delete_wan_tc_filter(context, id) - self.delete_wan_tc_class(context, class_id) diff --git a/wan_qos/tests/__init__.py b/wan_qos/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/wan_qos/tests/system/__init__.py b/wan_qos/tests/system/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/wan_qos/tests/system/plugin.py b/wan_qos/tests/system/plugin.py deleted file mode 100644 index 129619e..0000000 --- a/wan_qos/tests/system/plugin.py +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright 2016 Huawei corp. -# 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 sys -import time - -from neutron.agent.common import config -from neutron.common import config as common_config - -from wan_qos.services import plugin - - -def main(): - common_config.init(sys.argv[1:]) - config.setup_logging() - plugin.WanQosPlugin() - while True: - time.sleep(3) - -if __name__ == '__main__': - main() diff --git a/wan_qos/tests/unit/__init__.py b/wan_qos/tests/unit/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/wan_qos/tests/unit/test_db.py b/wan_qos/tests/unit/test_db.py deleted file mode 100644 index 49cefd5..0000000 --- a/wan_qos/tests/unit/test_db.py +++ /dev/null @@ -1,74 +0,0 @@ -from neutron.tests.unit import testlib_api -from neutron_lib import context as ctx - -from wan_qos.db import wan_qos_db - - -class TestTcDb(testlib_api.SqlTestCase): - def setUp(self): - super(TestTcDb, self).setUp() - self.db = wan_qos_db.WanTcDb() - self.context = ctx.get_admin_context() - - def test_add_class(self): - wtc_class = { - 'direction': 'both', - 'min': '1mbit' - } - wtc_class_db = self.db.create_wan_tc_class(self.context, wtc_class) - - assert wtc_class_db is not None - - def test_get_class_by_id(self): - - class_db_1 = self._add_class(None, 'both', '1mbit', '2mbit') - class_db_2 = self._add_class(class_db_1['id'], 'both', '2mbit', - '3mbit') - self._add_class(class_db_2['id'], 'both', '3mbit', - '4mbit') - - class_by_id = self.db.get_class_by_id(self.context, class_db_1['id']) - # class_by_id = self.db.get_class_by_id(self.context, '111') - print (class_by_id) - - def test_get_class_tree(self): - - class_db_1 = self._add_class(None, 'both', '1mbit', '2mbit') - class_db_2 = self._add_class(class_db_1['id'], 'both', '2mbit', - '3mbit') - class_db_3 = self._add_class(class_db_2['id'], 'both', '3mbit', - '4mbit') - - class_tree = self.db.get_class_tree() - assert class_tree is not None - print (class_tree) - - class_tree = self.db.get_class_tree(class_db_1['id']) - assert class_tree is not None - print (class_tree) - - class_tree = self.db.get_class_tree(class_db_2['id']) - assert class_tree is not None - print (class_tree) - - class_tree = self.db.get_class_tree(class_db_3['id']) - assert class_tree is not None - print (class_tree) - - def test_get_classes(self): - self.test_add_class() - all_classes = self.db.get_all_classes(self.context) - print ('all classes: %s' % all_classes) - - def _add_class(self, parent, direction, min, max): - wtc_class = { - 'direction': direction, - } - if min: - wtc_class['min'] = min - if parent: - wtc_class['parent'] = parent - if max: - wtc_class['max'] = max - - return self.db.create_wan_tc_class(self.context, wtc_class) diff --git a/wan_qos/tests/unit/test_plugin.py b/wan_qos/tests/unit/test_plugin.py deleted file mode 100644 index 1dc9780..0000000 --- a/wan_qos/tests/unit/test_plugin.py +++ /dev/null @@ -1,104 +0,0 @@ -from neutron.tests.unit import testlib_api -from neutron_lib import context as ctx - -from wan_qos.services import plugin - - -class TestPlugin(testlib_api.SqlTestCase): - def setUp(self): - super(TestPlugin, self).setUp() - self.plugin = plugin.WanQosPlugin() - - def test_create_class(self): - wtc_class = { - 'wan_tc_class': { - 'direction': 'both', - 'min': '1mbit' - } - } - - wan_tc = self.plugin.create_wan_tc_class(ctx.get_admin_context(), - wtc_class) - - assert wan_tc is not None - print (wan_tc) - - def test_get_class_by_id(self): - - class_db_1 = self._add_class(None, 'both', '1mbit', '2mbit') - class_db_2 = self._add_class(class_db_1['id'], 'both', '2mbit', - '3mbit') - self._add_class(class_db_2['id'], 'both', '3mbit', - '4mbit') - - tc_class = self.plugin.get_wan_tc_class(ctx.get_admin_context(), - class_db_1['id']) - - print(tc_class) - tc_classes = self.plugin.get_wan_tc_classs(ctx.get_admin_context()) - - print(tc_classes) - - def test_get_all_classes_by_id(self): - - class_db_1 = self._add_class(None, 'both', '1mbit', '2mbit') - print ('class_1: %s ' % class_db_1) - - filters = {'id': [class_db_1['id']]} - # filters = {'id': ['11']} - # filters = {'name': ['111']} - - tc_classes = self.plugin.get_wan_tc_classs(ctx.get_admin_context(), - filters=filters) - - print(tc_classes) - - filters = {'name': ['111']} - - tc_classes = self.plugin.get_wan_tc_classs(ctx.get_admin_context(), - filters=filters) - - print(tc_classes) - - def test_add_filter(self): - - class_db = self._add_class(None, 'both', '1mbit', '2mbit') - filter = self._get_filter(class_db['id']) - filter_db = self.plugin.create_wan_tc_filter(ctx.get_admin_context(), - filter) - - print ('filter: %s' % filter_db) - - filters = { - 'id': [filter_db['id']] - # 'name': ['123'] - } - filter_by_id = self.plugin.get_wan_tc_filters(ctx.get_admin_context(), - filters=filters) - - print('filter by id: %s' % filter_by_id) - - def _get_filter(self, class_id): - - filter = {'wan_tc_filter': { - 'protocol': 'vxlan', - 'match': 'vni=123', - 'class_id': class_id - } - } - - return filter - - def _add_class(self, parent, direction, min, max): - wtc_class = { - 'direction': direction, - } - if min: - wtc_class['min'] = min - if parent: - wtc_class['parent'] = parent - if max: - wtc_class['max'] = max - - return self.plugin.db.create_wan_tc_class(ctx.get_admin_context(), - wtc_class) diff --git a/wan_qos/tests/unit/test_tc_agent.py b/wan_qos/tests/unit/test_tc_agent.py deleted file mode 100644 index 4c15bea..0000000 --- a/wan_qos/tests/unit/test_tc_agent.py +++ /dev/null @@ -1,145 +0,0 @@ -# Copyright (c) 2016 Huawei, 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.tests import base - -from oslo_config import cfg - -from wan_qos.agent import tc_driver -from wan_qos.services import plugin - -WANTC_group = cfg.OptGroup(name='WANTC', - title='WAN QoS options') - -opts = [ - cfg.StrOpt('lan_port_name', - default='enp1s0f0', - help='LAN side port name'), - cfg.StrOpt('lan_max_rate', - default='100mbit', - help='LAN side port rate'), - cfg.StrOpt('wan_port_name', - default='enp1s0f1', - help='WAN side port name'), - cfg.StrOpt('wan_max_rate', - default='100mbit', - help='WAN side port rate') -] - - -class TestTcDriver(base.BaseTestCase): - def setUp(self): - super(TestTcDriver, self).setUp() - cfg.CONF.register_group(WANTC_group) - cfg.CONF.register_opts(opts, group='WANTC') - self.tc_agent = tc_driver.TcDriver() - self.tc_agent.set_ports('enp1s0f0', 'enp1s0f1') - - def test_clear_all(self): - self.tc_agent.clear_all() - - def test_set_root_queue(self): - tc_dict = { - 'port_side': 'lan_port', - 'max_rate': '100mbit' - } - self.tc_agent.set_root_queue(tc_dict) - - tc_dict = { - 'port_side': 'wan_port', - 'max_rate': '100mbit' - } - self.tc_agent.set_root_queue(tc_dict) - - def test_add_limiter(self): - tc_dict = { - 'port_side': 'lan_port', - 'parent': '1', - 'child': '10', - 'min': '200kbit', - 'max': '512kbit' - } - self.tc_agent.create_traffic_limiter(tc_dict) - tc_dict = { - 'port_side': 'wan_port', - 'parent': '1', - 'child': '10', - 'min': '2mbit', - 'max': '2mbit' - } - self.tc_agent.create_traffic_limiter(tc_dict) - tc_dict = { - 'port_side': 'wan_port', - 'parent': '10', - 'child': '100', - 'min': '200kbit', - 'max': '512kbit' - } - self.tc_agent.create_traffic_limiter(tc_dict) - - def test_update_limiter(self): - tc_dict = { - 'port_side': 'lan_port', - 'parent': '1', - 'child': '10', - 'min': '300kbit', - 'max': '400kbit' - } - self.tc_agent.update_traffic_limiter(tc_dict) - tc_dict = { - 'port_side': 'wan_port', - 'parent': '10', - 'child': '100', - 'min': '250kbit', - 'max': '600kbit' - } - self.tc_agent.update_traffic_limiter(tc_dict) - - def test_add_filter(self): - tc_dict = { - 'port_side': 'lan_port', - 'protocol': 'vxlan', - 'vni': 100, - 'child': '10' - } - self.tc_agent.create_filter(tc_dict) - tc_dict = { - 'port_side': 'wan_port', - 'protocol': 'vxlan', - 'vni': 100, - 'child': '100' - } - self.tc_agent.create_filter(tc_dict) - - def test_remove_limiter(self): - tc_dict = { - 'port_side': 'lan_port', - 'parent': '1', - 'child': '10' - } - self.tc_agent.remove_traffic_limiter(tc_dict) - tc_dict = { - 'port_side': 'wan_port', - 'parent': '1', - 'child': '10' - } - self.tc_agent.remove_traffic_limiter(tc_dict) - - -class TestApiMessages(base.BaseTestCase): - def setUp(self): - super(TestApiMessages, self).setUp() - cfg.CONF.register_group(WANTC_group) - cfg.CONF.register_opts(opts, group='WANTC') - self.plugin = plugin.WanQosPlugin() diff --git a/wan_qos/wanqos_client/__init__.py b/wan_qos/wanqos_client/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/wan_qos/wanqos_client/_wantc.py b/wan_qos/wanqos_client/_wantc.py deleted file mode 100644 index 9e47bf8..0000000 --- a/wan_qos/wanqos_client/_wantc.py +++ /dev/null @@ -1,89 +0,0 @@ -# Copyright 2017 Huawei corp. -# 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 neutronclient._i18n import _ -from neutronclient.common import exceptions -from neutronclient.common import extension - -from wan_qos.common import constants - - -class WanTc(extension.NeutronClientExtension): - resource = constants.WAN_TC - resource_plural = '%ss' % constants.WAN_TC - path = constants.WAN_TC_PATH - object_path = '/%s' % path - resource_path = '/%s/%%s' % path - versions = ['2.0'] - - -class WanTcShow(extension.ClientExtensionShow, WanTc): - shell_command = 'wan-tc-show' - - -class WanTcList(extension.ClientExtensionList, WanTc): - shell_command = 'wan-tc-list' - list_columns = ['id', 'network', 'min', 'max'] - pagination_support = True - sorting_support = True - - -class WanTcCreate(extension.ClientExtensionCreate, WanTc): - shell_command = 'wan-tc-create' - - def add_known_arguments(self, parser): - parser.add_argument( - 'network', metavar='', - help=_('Network ID')) - parser.add_argument( - '--min', - dest='min', - help=_('Set committed rate. (mbit / kbit)')) - parser.add_argument( - '--max', - dest='max', - help=_('Set maximum rate. (mbit / kbit)')) - - def args2body(self, parsed_args): - - body = { - 'network': parsed_args.network - } - - if parsed_args.min: - body['min'] = parsed_args.min - else: - raise exceptions.BadRequest('min must be set') - - if parsed_args.max: - body['max'] = parsed_args.max - - return {self.resource: body} - - -class WanTcDelete(extension.ClientExtensionDelete, WanTc): - shell_command = 'wan-tc-delete' - - -class WanTcUpdate(extension.ClientExtensionUpdate, WanTc): - shell_command = 'wan-tc-update' - - def add_known_arguments(self, parser): - pass - - def args2body(self, parsed_args): - body = {} - return {self.resource: body} diff --git a/wan_qos/wanqos_client/_wantcclass.py b/wan_qos/wanqos_client/_wantcclass.py deleted file mode 100644 index 5205db1..0000000 --- a/wan_qos/wanqos_client/_wantcclass.py +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright 2016 Huawei corp. -# 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 neutronclient._i18n import _ -from neutronclient.common import exceptions -from neutronclient.common import extension - -from wan_qos.common import constants - - -class WanTcClass(extension.NeutronClientExtension): - resource = constants.WAN_TC_CLASS - resource_plural = '%ss' % constants.WAN_TC_CLASS - path = constants.WAN_TC_CLASS_PATH - object_path = '/%s' % path - resource_path = '/%s/%%s' % path - versions = ['2.0'] - - -class WanTcClassShow(extension.ClientExtensionShow, WanTcClass): - shell_command = 'wan-tc-class-show' - - -class WanTcClassList(extension.ClientExtensionList, WanTcClass): - shell_command = 'wan-tc-class-list' - list_columns = ['id', 'parent', 'direction', 'min', 'max'] - pagination_support = True - sorting_support = True - - -class WanTcClassCreate(extension.ClientExtensionCreate, WanTcClass): - shell_command = 'wan-tc-class-create' - - def add_known_arguments(self, parser): - parser.add_argument( - 'direction', metavar='', - choices=['both', 'in', 'out'], - help=_('The direction for the limiter. Can be both/in/out')) - parser.add_argument( - '--min', - dest='min', - help=_('Set committed rate. (mbit / kbit)')) - parser.add_argument( - '--max', - dest='max', - help=_('Set maximum rate. (mbit / kbit)')) - parser.add_argument( - '--parent', - dest='parent', - help=_('Set the parent class of this class. Omit if root.')) - - def args2body(self, parsed_args): - - body = { - 'direction': parsed_args.direction - } - - if parsed_args.min: - body['min'] = parsed_args.min - else: - if not parsed_args.max: - raise exceptions.BadRequest('Either min or max must be set') - - if parsed_args.max: - body['max'] = parsed_args.max - - if parsed_args.parent: - body['parent'] = parsed_args.parent - - return {self.resource: body} - - -class WanTcClassDelete(extension.ClientExtensionDelete, WanTcClass): - shell_command = 'wan-tc-class-delete' - - -class WanTcClassUpdate(extension.ClientExtensionUpdate, WanTcClass): - shell_command = 'wan-tc-class-update' - - def add_known_arguments(self, parser): - pass - - def args2body(self, parsed_args): - body = {} - return {self.resource: body} diff --git a/wan_qos/wanqos_client/_wantcdevice.py b/wan_qos/wanqos_client/_wantcdevice.py deleted file mode 100644 index 342ac03..0000000 --- a/wan_qos/wanqos_client/_wantcdevice.py +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright 2016 Huawei corp. -# 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 neutronclient.common import extension - -from wan_qos.common import constants - - -def args2body(self, parsed_args): - body = {constants.WAN_TC_DEVICE: {}, } - return body - - -class WanTcDevice(extension.NeutronClientExtension): - resource = constants.WAN_TC_DEVICE - resource_plural = '%ss' % constants.WAN_TC_DEVICE - path = constants.WAN_TC_DEVICE_PATH - object_path = '/%s' % path - resource_path = '/%s/%%s' % path - versions = ['2.0'] - - -class WanTcDeviceShow(extension.ClientExtensionShow, WanTcDevice): - shell_command = 'wan-tc-device-show' - - -class WanTcDeviceList(extension.ClientExtensionList, WanTcDevice): - shell_command = 'wan-tc-device-list' - list_columns = ['id', 'host', 'lan_port', 'wan_port', - 'uptime', 'last_seen'] - pagination_support = True - sorting_support = True - - -class WanTcDeviceDelete(extension.ClientExtensionDelete, WanTcDevice): - shell_command = 'wan-tc-device-delete' diff --git a/wan_qos/wanqos_client/_wantcfilter.py b/wan_qos/wanqos_client/_wantcfilter.py deleted file mode 100644 index e77b7c3..0000000 --- a/wan_qos/wanqos_client/_wantcfilter.py +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright 2016 Huawei corp. -# 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 neutronclient._i18n import _ -from neutronclient.common import extension - -from wan_qos.common import constants - - -class WanTcFilter(extension.NeutronClientExtension): - resource = constants.WAN_TC_FILTER - resource_plural = '%ss' % constants.WAN_TC_FILTER - path = constants.WAN_TC_FILTER_PATH - object_path = '/%s' % path - resource_path = '/%s/%%s' % path - versions = ['2.0'] - - -class WanTcFilterShow(extension.ClientExtensionShow, WanTcFilter): - shell_command = 'wan-tc-filter-show' - - -class WanTcFilterList(extension.ClientExtensionList, WanTcFilter): - shell_command = 'wan-tc-filter-list' - list_columns = ['id', 'protocol', 'match', 'class_id'] - pagination_support = True - sorting_support = True - - -class WanTcFilterCreate(extension.ClientExtensionCreate, WanTcFilter): - shell_command = 'wan-tc-filter-create' - - def add_known_arguments(self, parser): - parser.add_argument( - 'protocol', metavar='', - choices=['vxlan'], - help=_('Protocol name to select')) - parser.add_argument( - 'match', metavar='', - help=_('match fields for protocol name to select')) - parser.add_argument( - 'class_id', metavar='', - help=_('Class ID to attach the filter to')) - - def args2body(self, parsed_args): - body = { - 'protocol': parsed_args.protocol, - 'match': parsed_args.match, - 'class_id': parsed_args.class_id - } - - return {self.resource: body} - - -class WanTcFilterDelete(extension.ClientExtensionDelete, WanTcFilter): - shell_command = 'wan-tc-filter-delete' - - -class WanTcFilterUpdate(extension.ClientExtensionUpdate, WanTcFilter): - shell_command = 'wan-tc-filter-update' - - def add_known_arguments(self, parser): - pass - - def args2body(self, parsed_args): - body = {} - return {self.resource: body}