Add class filter

This commit is contained in:
Ofer Ben-Yacov 2017-01-25 17:48:36 +02:00
parent 403afc3503
commit a1684c81dc
9 changed files with 196 additions and 148 deletions

View File

@ -33,6 +33,6 @@ console_scripts =
neutron.db.alembic_migrations =
wan-qos = wan_qos.db.migration:alembic_migrations
neutronclient.extension =
wan_qos = wan_qos.wanqos_client._wanqos
wan_tc_filter = wan_qos.wanqos_client._wantcfilter
wan_tc_device = wan_qos.wanqos_client._wantcdevice
wan_tc_class = wan_qos.wanqos_client._wantcclass

View File

@ -14,11 +14,12 @@
# under the License.
WANTC = 'WANTC'
WAN_TC = 'wan_tc'
WAN_TC_PATH = 'wan-tcs'
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_CLASS_PATH = 'wan-tc-classs'
WAN_TC_FILTER = 'wan_tc_filter'
WAN_TC_FILTER_PATH = 'wan-tc-filters'

View File

@ -50,8 +50,9 @@ def upgrade():
['parent'], ['id'], ondelete='CASCADE'
)
op.create_table('wan_tc_selector',
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)),
@ -61,14 +62,14 @@ def upgrade():
)
op.create_foreign_key(
'fk_wan_tc__selector_class',
'wan_tc_selector', 'wan_tc_class',
'fk_wan_tc__filter_class',
'wan_tc_filter', 'wan_tc_class',
['class_id'], ['id'],
)
op.create_foreign_key(
'fk_wan_tc_selector_networks',
'wan_tc_selector', 'networks',
'fk_wan_tc_filter_networks',
'wan_tc_filter', 'networks',
['network'], ['id'],
)

View File

@ -46,9 +46,9 @@ class WanTcClass(model_base.BASEV2,
max = sa.Column(sa.String(15))
class WanTcSelector(model_base.BASEV2,
model_base.HasId, model_base.HasProject):
__tablename__ = 'wan_tc_selector'
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'),

View File

@ -290,3 +290,47 @@ class WanTcDb(object):
if column:
query = query.filter(column.in_(value))
return query
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']
)
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
}
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)

View File

@ -21,43 +21,42 @@ from neutron.api.v2 import resource_helper
from wan_qos.common import constants
RESOURCE_ATTRIBUTE_MAP = {
constants.WAN_TC_PATH: {
constants.WAN_TC_FILTER_PATH: {
'id': {'allow_post': False, 'allow_put': False,
'is_visible': True},
'max_rate': {'allow_post': True, 'allow_put': False,
'validate': {'type:string': None},
'is_visible': True, 'default': ''},
'min_rate': {'allow_post': True, 'allow_put': False,
'class_id': {'allow_post': True, 'allow_put': False,
'validate': {'type:string': None},
'is_visible': True, 'default': ''},
'network_id': {'allow_post': True, 'allow_put': False,
'validate': {'type:string': None},
'is_visible': True},
'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}
'validate': {'type:string': None},
'required_by_policy': True,
'is_visible': True}
},
}
class Wanqos(extensions.ExtensionDescriptor):
class Wantcfilter(extensions.ExtensionDescriptor):
@classmethod
def get_name(cls):
return "WAN Traffic Control"
return "WAN Traffic Control filter"
@classmethod
def get_alias(cls):
return "wan-tc"
return "wan-tc-filter"
@classmethod
def get_description(cls):
return "Limit traffic on WAN links"
return "filter to select traffic limit class on WAN links"
@classmethod
def get_updated(cls):
return "2016-12-01T00:00:00-00:00"
return "2017-01-25T00:00:00-00:00"
@classmethod
def get_resources(cls):
@ -82,26 +81,25 @@ class Wanqos(extensions.ExtensionDescriptor):
return {}
class WanQosPluginBase(object):
class WanTcFilterPluginBase(object):
@abc.abstractmethod
def create_wan_tc(self, context, wan_qos):
def create_wan_tc_filter(self, context, wan_tc_filter):
pass
@abc.abstractmethod
def get_wan_tc(self, context, id, fields=None):
def get_wan_tc_filter(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):
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(self, context, id, wan_qos):
def update_wan_tc_filter(self, context, id, wan_tc_filter):
pass
@abc.abstractmethod
def delete_wan_tc(self, context, id):
def delete_wan_tc_filter(self, context, id):
pass

View File

@ -27,7 +27,7 @@ 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 wanqos
from wan_qos.extensions import wantcfilter
from wan_qos.extensions import wantcdevice
from wan_qos.extensions import wantcclass
@ -57,10 +57,11 @@ class PluginRpcCallback(object):
return conf
class WanQosPlugin(wanqos.WanQosPluginBase,
class WanQosPlugin(wantcfilter.WanTcFilterPluginBase,
wantcdevice.WanTcDevicePluginBase,
wantcclass.WanTcClassPluginBase):
supported_extension_aliases = ['wan-tc', 'wan-tc-device', 'wan-tc-class']
supported_extension_aliases = ['wan-tc-filter', 'wan-tc-device',
'wan-tc-class']
def __init__(self):
self.db = wan_qos_db.WanTcDb()
@ -75,6 +76,14 @@ class WanQosPlugin(wanqos.WanQosPluginBase,
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.'
def delete_wan_tc_device(self, context, id):
self.db.delete_wan_tc_device(context, id)
@ -87,14 +96,6 @@ class WanQosPlugin(wanqos.WanQosPluginBase,
return self.db.get_all_devices(context, filters, fields, sorts, limit,
marker, page_reverse)
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.'
def get_wan_tc_class(self, context, id, fields=None):
return self.db.get_class_by_id(context, id)
@ -120,6 +121,26 @@ class WanQosPlugin(wanqos.WanQosPluginBase,
return self.db.get_all_classes(context, filters, fields, sorts, limit,
marker, page_reverse)
def delete_wan_tc_filter(self, context, id):
pass
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):
return self.db.create_wan_tc_filter(context,
wan_tc_filter['wan_tc_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."""
@ -132,23 +153,3 @@ class WanQosPlugin(wanqos.WanQosPluginBase,
else:
tenant_id = context.tenant_id
return tenant_id
def get_wan_tc(self, context, id, fields=None):
pass
def get_wan_tcs(self, context, filters=None, fields=None,
sorts=None, limit=None, marker=None,
page_reverse=False):
pass
def delete_wan_tc(self, context, id):
pass
def update_wan_tc(self, context, id, wan_qos):
pass
def create_wan_tc(self, context, wan_qos):
pass
# self.agent_rpc.create_wan_qos(context, wan_qos)
# tenant_id = self._get_tenant_id_for_create(context, wan_qos_class)

View File

@ -1,79 +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: {}, }
return body
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', 'name', 'network', 'min-rate', 'max-rate']
pagination_support = True
sorting_support = True
class WanTcCreate(extension.ClientExtensionCreate, WanTc):
shell_command = 'wan-tc-create'
def add_known_arguments(self, parser):
pass
def args2body(self, parsed_args):
body = args2body(self, parsed_args)
if parsed_args.tenant_id:
body['wan_qos']['tenant_id'] = parsed_args.tenant_id
return 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 = args2body(self, parsed_args)
return body

View File

@ -0,0 +1,82 @@
# 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 neutronclient.common import exceptions
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='<protocol>',
choices=['vxlan'],
help=_('Protocol name to select'))
parser.add_argument(
'match', metavar='<MATCH>',
help=_('match fields for protocol name to select'))
parser.add_argument(
'class_id', metavar='<CLASS>',
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}