neutron-classifier/neutron_classifier/services/classification/plugin.py

183 lines
7.1 KiB
Python

# Copyright 2017 Intel Corporation.
#
# 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_log import log as logging
from neutron.objects import base as base_obj
from neutron.objects import classification as n_class_obj
from neutron_classifier.common import constants as nc_consts
from neutron_classifier.common import exceptions
from neutron_classifier.common import validators
from neutron_classifier.db import classification as c_db
from neutron_classifier.extensions import classification
from neutron_classifier.objects import classification as class_obj
from neutron_classifier.objects import classification_type as type_obj
from neutron_classifier.services.classification import advertiser
from neutron_lib.db import api as db_api
LOG = logging.getLogger(__name__)
class ClassificationPlugin(classification.NeutronClassificationPluginBase,
c_db.TrafficClassificationGroupPlugin):
supported_extension_aliases = ['neutron_classifier']
def __init__(self):
super(ClassificationPlugin, self).__init__()
self.driver_manager = advertiser.ClassificationAdvertiser()
def create_classification(self, context, classification):
details = self.break_out_headers(classification)
c_type = details['c_type']
headers = classification['classification']['definition']
for key in headers:
if key not in validators.type_validators[c_type].keys():
raise exceptions.InvalidClassificationDefintion()
cl = class_obj.CLASS_MAP[c_type](context, **details)
with db_api.CONTEXT_WRITER.using(context):
cl.create()
db_dict = self.merge_header(cl)
db_dict['id'] = cl['id']
self.driver_manager.call(nc_consts.CREATE_CLASS, context, cl)
return db_dict
def delete_classification(self, context, classification_id):
cl = n_class_obj.ClassificationBase.\
get_object(context,
id=classification_id)
cl_class = class_obj.CLASS_MAP[cl.c_type]
classification = cl_class.get_object(context, id=classification_id)
validators.check_valid_classifications(context,
[classification_id])
with db_api.CONTEXT_WRITER.using(context):
classification.delete()
self.driver_manager.call(nc_consts.DELETE_CLASS, context,
classification)
def update_classification(self, context, classification_id,
fields_to_update):
fields_to_update = fields_to_update['classification']
field_keys = list(fields_to_update.keys())
valid_keys = ['name', 'description']
for key in field_keys:
if key not in valid_keys:
raise exceptions.InvalidUpdateRequest()
cl = n_class_obj.ClassificationBase.\
get_object(context,
id=classification_id)
cl_class = class_obj.CLASS_MAP[cl.c_type]
with db_api.CONTEXT_WRITER.using(context):
classification = cl_class.update_object(
context, fields_to_update, id=classification_id)
db_dict = self.merge_header(classification)
db_dict['id'] = classification['id']
return db_dict
def get_classification(self, context, classification_id, fields=None):
cl = n_class_obj.ClassificationBase.\
get_object(context,
id=classification_id)
cl_class = class_obj.CLASS_MAP[cl.c_type]
classification = cl_class.get_object(context, id=classification_id)
clas = self.merge_header(classification)
return clas
def get_classifications(self, context, filters=None, fields=None,
sorts=None, limit=None, marker=None,
page_reverse=False):
c_type = filters['c_type'][0]
pager = base_obj.Pager(sorts, limit, page_reverse, marker)
cl = class_obj.CLASS_MAP[c_type].get_objects(context,
_pager=pager)
db_dict = self.merge_headers(cl)
return db_dict
def get_classification_type(self, context, filters=None, fields=None,
sorts=None, limit=None, marker=None,
page_reverse=False):
ret_list = []
if not filters:
filters = {}
for key in class_obj.CLASS_MAP.keys():
types = {}
obj = type_obj.ClassificationType.get_object(key)
types['type'] = obj.type
types['supported_parameters'] = obj.supported_parameters
ret_list.append(types)
return ret_list
def __getattr__(self, resource):
return super(ClassificationPlugin, self).__getattr__(resource)
def break_out_headers(self, classification):
details = classification['classification']
cl_dict = {'name': details['name'],
'description': details['description'],
'project_id': details['project_id'],
'shared': details['shared'],
'c_type': details['c_type'],
'negated': details['negated']}
definition = details['definition']
for key, value in definition.items():
cl_dict[key] = value
return cl_dict
def merge_headers(self, classifications):
if not classifications:
return []
ret_list = []
for clas in classifications:
db_dict = self.merge_header(clas)
db_dict['id'] = clas.get('id', None)
ret_list.append(db_dict)
return ret_list
def merge_header(self, classification):
db_dict = {'id': classification['id'],
'name': classification['name'],
'project_id': classification['project_id'],
'description': classification['description'],
'c_type': classification['c_type'],
'negated': classification['negated'],
'shared': classification['shared']}
c_type = classification['c_type']
headers = validators.type_validators[c_type].keys()
definition = {}
for header in headers:
definition[header] = classification.get(header, None)
db_dict['definition'] = definition
return db_dict
CLASSIFICATION_MAP = {'ethernet': 'EthernetClassifications',
'ipv4': 'IPV4Classifications',
'ipv6': 'IPV6Classifications',
'udp': 'UDPClassifications',
'tcp': 'TCPClassifications'}