neutron/neutron/services/logapi/logging_plugin.py

145 lines
6.1 KiB
Python

# Copyright (c) 2017 Fujitsu Limited
# 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_lib.api.definitions import logging
from neutron_lib.callbacks import events
from neutron_lib.callbacks import registry
from neutron_lib.callbacks import resources
from neutron_lib.db import api as db_api
from neutron_lib.services.logapi import constants as log_const
from neutron.db import db_base_plugin_common
from neutron.extensions import logging as log_ext
from neutron.objects import base as base_obj
from neutron.objects.logapi import logging_resource as log_object
from neutron.services.logapi.common import db_api as log_db_api
from neutron.services.logapi.common import exceptions as log_exc
from neutron.services.logapi.common import validators
from neutron.services.logapi.drivers import manager as driver_mgr
@registry.has_registry_receivers
class LoggingPlugin(log_ext.LoggingPluginBase):
"""Implementation of the Neutron logging api plugin."""
supported_extension_aliases = [logging.ALIAS]
__native_pagination_support = True
__native_sorting_support = True
__filter_validation_support = True
def __init__(self):
super(LoggingPlugin, self).__init__()
self.driver_manager = driver_mgr.LoggingServiceDriverManager()
self.validator_mgr = validators.ResourceValidateRequest.get_instance()
@property
def supported_logging_types(self):
# supported_logging_types are be dynamically loaded from log_drivers
return self.driver_manager.supported_logging_types
def _clean_logs(self, context, sg_id=None, port_id=None):
with db_api.CONTEXT_WRITER.using(context):
sg_logs = log_db_api.get_logs_bound_sg(
context, sg_id=sg_id, port_id=port_id, exclusive=True)
for log in sg_logs:
self.delete_log(context, log['id'])
@registry.receives(resources.SECURITY_GROUP, [events.AFTER_DELETE])
def _clean_logs_by_resource_id(self, resource, event, trigger, payload):
# log.resource_id == SG
self._clean_logs(payload.context.elevated(), sg_id=payload.resource_id)
@registry.receives(resources.PORT, [events.AFTER_DELETE])
def _clean_logs_by_target_id(self, resource, event, trigger, payload):
# log.target_id == port
self._clean_logs(payload.context.elevated(),
port_id=payload.resource_id)
@db_base_plugin_common.filter_fields
@db_base_plugin_common.convert_result_to_dict
def get_logs(self, context, filters=None, fields=None, sorts=None,
limit=None, marker=None, page_reverse=False):
"""Return information for available log objects"""
filters = filters or {}
pager = base_obj.Pager(sorts, limit, page_reverse, marker)
return log_object.Log.get_objects(context, _pager=pager, **filters)
def _get_log(self, context, log_id):
"""Return the log object or raise if not found"""
log_obj = log_object.Log.get_object(context, id=log_id)
if not log_obj:
raise log_exc.LogResourceNotFound(log_id=log_id)
return log_obj
@db_base_plugin_common.filter_fields
@db_base_plugin_common.convert_result_to_dict
def get_log(self, context, log_id, fields=None):
return self._get_log(context, log_id)
@db_base_plugin_common.convert_result_to_dict
def create_log(self, context, log):
"""Create a log object"""
log_data = log['log']
self.validator_mgr.validate_request(context, log_data)
with db_api.CONTEXT_WRITER.using(context):
# body 'log' contains both tenant_id and project_id
# but only latter needs to be used to create Log object.
# We need to remove redundant keyword.
log_data.pop('tenant_id', None)
log_obj = log_object.Log(context=context, **log_data)
log_obj.create()
if log_obj.enabled:
self.driver_manager.call(
log_const.CREATE_LOG_PRECOMMIT, context, log_obj)
if log_obj.enabled:
self.driver_manager.call(
log_const.CREATE_LOG, context, log_obj)
return log_obj
@db_base_plugin_common.convert_result_to_dict
def update_log(self, context, log_id, log):
"""Update information for the specified log object"""
log_data = log['log']
with db_api.CONTEXT_WRITER.using(context):
log_obj = log_object.Log(context, id=log_id)
log_obj.update_fields(log_data, reset_changes=True)
log_obj.update()
need_notify = 'enabled' in log_data
if need_notify:
self.driver_manager.call(
log_const.UPDATE_LOG_PRECOMMIT, context, log_obj)
if need_notify:
self.driver_manager.call(
log_const.UPDATE_LOG, context, log_obj)
return log_obj
def delete_log(self, context, log_id):
"""Delete the specified log object"""
with db_api.CONTEXT_WRITER.using(context):
log_obj = self._get_log(context, log_id)
log_obj.delete()
self.driver_manager.call(
log_const.DELETE_LOG_PRECOMMIT, context, log_obj)
self.driver_manager.call(
log_const.DELETE_LOG, context, log_obj)
def get_loggable_resources(self, context, filters=None, fields=None,
sorts=None, limit=None,
marker=None, page_reverse=False):
"""Get supported logging types"""
return [{'type': type_}
for type_ in self.supported_logging_types]