Generic validate_request method for logging
This patch adds a generic validate_request method for logging, So logging can be extended to other resources like firewall group. Co-Authored-By: Nguyen Phuong An <AnNP@vn.fujitsu.com> Co-Authored-By: Kim Bao Long <longkb@vn.fujitsu.com> Partial-Bug: #1720727 Change-Id: I9d580645131a9f1b8233ea5f6e0378cd98f023f1
This commit is contained in:
parent
2d30981289
commit
cdb973e77d
|
@ -22,6 +22,9 @@ LOGGING_PLUGIN = 'logging-plugin'
|
||||||
# supported logging types
|
# supported logging types
|
||||||
SECURITY_GROUP = 'security_group'
|
SECURITY_GROUP = 'security_group'
|
||||||
|
|
||||||
|
# target resource types
|
||||||
|
PORT = 'port'
|
||||||
|
|
||||||
RPC_NAMESPACE_LOGGING = 'logging-plugin'
|
RPC_NAMESPACE_LOGGING = 'logging-plugin'
|
||||||
|
|
||||||
# Define for rpc_method_key
|
# Define for rpc_method_key
|
||||||
|
|
|
@ -51,3 +51,9 @@ class LogapiDriverException(n_exc.NeutronException):
|
||||||
|
|
||||||
class CookieNotFound(n_exc.NotFound):
|
class CookieNotFound(n_exc.NotFound):
|
||||||
message = _("Cookie %(cookie_id)s could not be found.")
|
message = _("Cookie %(cookie_id)s could not be found.")
|
||||||
|
|
||||||
|
|
||||||
|
class ValidatedMethodNotFound(n_exc.NeutronException):
|
||||||
|
"""A validated method not found Exception"""
|
||||||
|
message = _('Validated method for %(resource_type)s log '
|
||||||
|
'could not be found.')
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
# Copyright (c) 2018 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 oslo_log import log as logging
|
||||||
|
from sqlalchemy.orm import exc as orm_exc
|
||||||
|
|
||||||
|
from neutron.db import _utils as db_utils
|
||||||
|
from neutron.db.models import securitygroup as sg_db
|
||||||
|
from neutron.objects import ports
|
||||||
|
from neutron.objects import securitygroup as sg_object
|
||||||
|
from neutron.services.logapi.common import constants as log_const
|
||||||
|
from neutron.services.logapi.common import exceptions as log_exc
|
||||||
|
from neutron.services.logapi.common import validators
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def _check_port_bound_sg(context, sg_id, port_id):
|
||||||
|
try:
|
||||||
|
db_utils.model_query(context, sg_db.SecurityGroupPortBinding)\
|
||||||
|
.filter_by(security_group_id=sg_id, port_id=port_id).one()
|
||||||
|
except orm_exc.NoResultFound:
|
||||||
|
raise log_exc.InvalidResourceConstraint(
|
||||||
|
resource=log_const.SECURITY_GROUP,
|
||||||
|
resource_id=sg_id,
|
||||||
|
target_resource=log_const.PORT,
|
||||||
|
target_id=port_id
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _check_sg_exists(context, sg_id):
|
||||||
|
if sg_object.SecurityGroup.count(context, id=sg_id) < 1:
|
||||||
|
raise log_exc.ResourceNotFound(resource_id=sg_id)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_port(context, port_id):
|
||||||
|
port = ports.Port.get_object(context, id=port_id)
|
||||||
|
if not port:
|
||||||
|
raise log_exc.TargetResourceNotFound(target_id=port_id)
|
||||||
|
return port
|
||||||
|
|
||||||
|
|
||||||
|
@validators.ResourceValidateRequest.register(log_const.SECURITY_GROUP)
|
||||||
|
def validate_security_group_request(context, log_data):
|
||||||
|
"""Validate a log request
|
||||||
|
|
||||||
|
This method validates log request is satisfied or not.
|
||||||
|
|
||||||
|
A ResourceNotFound will be raised if resource_id in log_data not exists or
|
||||||
|
a TargetResourceNotFound will be raised if target_id in log_data not
|
||||||
|
exists. This method will also raise a LoggingTypeNotSupported, if there is
|
||||||
|
no log_driver supporting for resource_type in log_data.
|
||||||
|
|
||||||
|
In addition, if log_data specify both resource_id and target_id. A
|
||||||
|
InvalidResourceConstraint will be raised if there is no constraint between
|
||||||
|
resource_id and target_id.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
resource_id = log_data.get('resource_id')
|
||||||
|
target_id = log_data.get('target_id')
|
||||||
|
if resource_id:
|
||||||
|
_check_sg_exists(context, resource_id)
|
||||||
|
if target_id:
|
||||||
|
port = _get_port(context, target_id)
|
||||||
|
if not validators.validate_log_type_for_port(
|
||||||
|
log_const.SECURITY_GROUP, port):
|
||||||
|
raise log_exc.LoggingTypeNotSupported(
|
||||||
|
log_type=log_const.SECURITY_GROUP,
|
||||||
|
port_id=target_id)
|
||||||
|
if resource_id and target_id:
|
||||||
|
_check_port_bound_sg(context, resource_id, target_id)
|
|
@ -19,13 +19,7 @@ from neutron_lib.plugins import constants as plugin_const
|
||||||
from neutron_lib.plugins import directory
|
from neutron_lib.plugins import directory
|
||||||
from neutron_lib.plugins import utils
|
from neutron_lib.plugins import utils
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
from sqlalchemy.orm import exc as orm_exc
|
|
||||||
|
|
||||||
from neutron.db import _utils as db_utils
|
|
||||||
from neutron.db.models import securitygroup as sg_db
|
|
||||||
from neutron.objects import ports
|
|
||||||
from neutron.objects import securitygroup as sg_object
|
|
||||||
from neutron.services.logapi.common import constants as log_const
|
|
||||||
from neutron.services.logapi.common import exceptions as log_exc
|
from neutron.services.logapi.common import exceptions as log_exc
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
@ -36,30 +30,6 @@ SKIPPED_VIF_TYPES = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def _check_port_bound_sg(context, sg_id, port_id):
|
|
||||||
try:
|
|
||||||
db_utils.model_query(context, sg_db.SecurityGroupPortBinding)\
|
|
||||||
.filter_by(security_group_id=sg_id, port_id=port_id).one()
|
|
||||||
except orm_exc.NoResultFound:
|
|
||||||
raise log_exc.InvalidResourceConstraint(resource='security_group',
|
|
||||||
resource_id=sg_id,
|
|
||||||
target_resource='port',
|
|
||||||
target_id=port_id)
|
|
||||||
|
|
||||||
|
|
||||||
def _check_secgroup_exists(context, sg_id):
|
|
||||||
number_of_matching = sg_object.SecurityGroup.count(context, id=sg_id)
|
|
||||||
if number_of_matching < 1:
|
|
||||||
raise log_exc.ResourceNotFound(resource_id=sg_id)
|
|
||||||
|
|
||||||
|
|
||||||
def _get_port(context, port_id):
|
|
||||||
port = ports.Port.get_object(context, id=port_id)
|
|
||||||
if not port:
|
|
||||||
raise log_exc.TargetResourceNotFound(target_id=port_id)
|
|
||||||
return port
|
|
||||||
|
|
||||||
|
|
||||||
def _validate_vnic_type(driver, vnic_type, port_id):
|
def _validate_vnic_type(driver, vnic_type, port_id):
|
||||||
if driver.is_vnic_compatible(vnic_type):
|
if driver.is_vnic_compatible(vnic_type):
|
||||||
return True
|
return True
|
||||||
|
@ -113,30 +83,56 @@ def validate_log_type_for_port(log_type, port):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def validate_request(context, log_data):
|
class ResourceValidateRequest(object):
|
||||||
"""Validate a log request
|
|
||||||
|
|
||||||
This method validates log request is satisfied or not. A ResourceNotFound
|
_instance = None
|
||||||
will be raised if resource_id in log_data not exists or a
|
|
||||||
TargetResourceNotFound will be raised if target_id in log_data not exists.
|
|
||||||
This method will also raise a LoggingTypeNotSupported, if there is no
|
|
||||||
log_driver supporting for resource_type in log_data.
|
|
||||||
|
|
||||||
In addition, if log_data specify both resource_id and target_id. A
|
def __init__(self):
|
||||||
InvalidResourceConstraint will be raised if there is no constraint
|
self.validate_methods = {}
|
||||||
between resource_id and target_id.
|
|
||||||
|
|
||||||
"""
|
@classmethod
|
||||||
resource_id = log_data.get('resource_id')
|
def get_instance(cls):
|
||||||
target_id = log_data.get('target_id')
|
if cls._instance is None:
|
||||||
resource_type = log_data.get('resource_type')
|
cls._instance = cls()
|
||||||
if resource_type == log_const.SECURITY_GROUP:
|
return cls._instance
|
||||||
if resource_id:
|
|
||||||
_check_secgroup_exists(context, resource_id)
|
@property
|
||||||
if target_id:
|
def validate_methods_map(self):
|
||||||
port = _get_port(context, target_id)
|
return self.validate_methods
|
||||||
if not validate_log_type_for_port(resource_type, port):
|
|
||||||
raise log_exc.LoggingTypeNotSupported(log_type=resource_type,
|
def validate_request(self, context, log_data):
|
||||||
port_id=target_id)
|
"""
|
||||||
if resource_id and target_id:
|
This method will get validated method according to resource_type. An
|
||||||
_check_port_bound_sg(context, resource_id, target_id)
|
InvalidLogResourceType exception will be raised if there is no logging
|
||||||
|
driver that supports resource_type as logging resource. In addition,
|
||||||
|
a ValidatedMethodNotFound exception will be raised if a validate method
|
||||||
|
was not registered for resource_type.
|
||||||
|
"""
|
||||||
|
|
||||||
|
resource_type = log_data.get('resource_type')
|
||||||
|
log_plugin = directory.get_plugin(alias=plugin_const.LOG_API)
|
||||||
|
supported_logging_types = log_plugin.supported_logging_types
|
||||||
|
|
||||||
|
if resource_type in supported_logging_types:
|
||||||
|
method = self.get_validated_method(resource_type)
|
||||||
|
method(context, log_data)
|
||||||
|
else:
|
||||||
|
raise log_exc.InvalidLogResourceType(resource_type=resource_type)
|
||||||
|
|
||||||
|
def get_validated_method(self, resource_type):
|
||||||
|
"""Get the validated method for resource_type"""
|
||||||
|
|
||||||
|
method = self.validate_methods[resource_type]
|
||||||
|
if not method:
|
||||||
|
raise log_exc.ValidatedMethodNotFound(resource_type=resource_type)
|
||||||
|
return method
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def register(cls, resource_type):
|
||||||
|
"""This is intended to be used as a decorator to register a validated
|
||||||
|
method for resource_type.
|
||||||
|
"""
|
||||||
|
def func_wrap(func):
|
||||||
|
cls.get_instance().validate_methods[resource_type] = func
|
||||||
|
return func
|
||||||
|
return func_wrap
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
from neutron_lib.api.definitions import portbindings
|
from neutron_lib.api.definitions import portbindings
|
||||||
from neutron_lib.callbacks import resources
|
from neutron_lib.callbacks import resources
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
|
from oslo_utils import importutils
|
||||||
|
|
||||||
from neutron.services.logapi.common import constants as log_const
|
from neutron.services.logapi.common import constants as log_const
|
||||||
from neutron.services.logapi.drivers import base
|
from neutron.services.logapi.drivers import base
|
||||||
|
@ -55,4 +56,8 @@ def register():
|
||||||
server_rpc.get_sg_log_info_for_log_resources}
|
server_rpc.get_sg_log_info_for_log_resources}
|
||||||
]
|
]
|
||||||
DRIVER.register_rpc_methods(log_const.SECURITY_GROUP, rpc_methods)
|
DRIVER.register_rpc_methods(log_const.SECURITY_GROUP, rpc_methods)
|
||||||
|
# Trigger decorator
|
||||||
|
importutils.import_module(
|
||||||
|
'neutron.services.logapi.common.sg_validate'
|
||||||
|
)
|
||||||
LOG.debug('Open vSwitch logging driver registered')
|
LOG.debug('Open vSwitch logging driver registered')
|
||||||
|
|
|
@ -36,6 +36,7 @@ class LoggingPlugin(log_ext.LoggingPluginBase):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(LoggingPlugin, self).__init__()
|
super(LoggingPlugin, self).__init__()
|
||||||
self.driver_manager = driver_mgr.LoggingServiceDriverManager()
|
self.driver_manager = driver_mgr.LoggingServiceDriverManager()
|
||||||
|
self.validator_mgr = validators.ResourceValidateRequest.get_instance()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def supported_logging_types(self):
|
def supported_logging_types(self):
|
||||||
|
@ -67,11 +68,7 @@ class LoggingPlugin(log_ext.LoggingPluginBase):
|
||||||
def create_log(self, context, log):
|
def create_log(self, context, log):
|
||||||
"""Create a log object"""
|
"""Create a log object"""
|
||||||
log_data = log['log']
|
log_data = log['log']
|
||||||
resource_type = log_data['resource_type']
|
self.validator_mgr.validate_request(context, log_data)
|
||||||
if resource_type not in self.supported_logging_types:
|
|
||||||
raise log_exc.InvalidLogResourceType(
|
|
||||||
resource_type=resource_type)
|
|
||||||
validators.validate_request(context, log_data)
|
|
||||||
with db_api.context_manager.writer.using(context):
|
with db_api.context_manager.writer.using(context):
|
||||||
# body 'log' contains both tenant_id and project_id
|
# body 'log' contains both tenant_id and project_id
|
||||||
# but only latter needs to be used to create Log object.
|
# but only latter needs to be used to create Log object.
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
# Copyright (c) 2018 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.
|
||||||
|
|
||||||
|
import mock
|
||||||
|
from neutron_lib.plugins import directory
|
||||||
|
from oslo_utils import importutils
|
||||||
|
from sqlalchemy.orm import exc as orm_exc
|
||||||
|
|
||||||
|
from neutron.objects import ports
|
||||||
|
from neutron.objects import securitygroup as sg_object
|
||||||
|
from neutron.services.logapi.common import exceptions as log_exc
|
||||||
|
from neutron.services.logapi.common import validators
|
||||||
|
from neutron.tests import base
|
||||||
|
|
||||||
|
|
||||||
|
class FakePlugin(object):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.validator_mgr = validators.ResourceValidateRequest.get_instance()
|
||||||
|
self.supported_logging_types = ['security_group']
|
||||||
|
|
||||||
|
|
||||||
|
class TestSGLogRequestValidations(base.BaseTestCase):
|
||||||
|
"""Test validation for a request"""
|
||||||
|
def setUp(self):
|
||||||
|
self.log_plugin = FakePlugin()
|
||||||
|
importutils.import_module('neutron.services.logapi.common.sg_validate')
|
||||||
|
super(TestSGLogRequestValidations, self).setUp()
|
||||||
|
|
||||||
|
def test_validate_request_resource_id_not_exists(self):
|
||||||
|
log_data = {'resource_type': 'security_group',
|
||||||
|
'resource_id': 'fake_sg_id'}
|
||||||
|
|
||||||
|
with mock.patch.object(directory, 'get_plugin',
|
||||||
|
return_value=self.log_plugin):
|
||||||
|
with mock.patch.object(sg_object.SecurityGroup, 'count',
|
||||||
|
return_value=0):
|
||||||
|
self.assertRaises(
|
||||||
|
log_exc.ResourceNotFound,
|
||||||
|
self.log_plugin.validator_mgr.validate_request,
|
||||||
|
mock.ANY,
|
||||||
|
log_data)
|
||||||
|
|
||||||
|
def test_validate_request_target_id_not_exists(self):
|
||||||
|
log_data = {'resource_type': 'security_group',
|
||||||
|
'target_id': 'fake_port_id'}
|
||||||
|
|
||||||
|
with mock.patch.object(directory, 'get_plugin',
|
||||||
|
return_value=self.log_plugin):
|
||||||
|
with mock.patch.object(ports.Port, 'get_object',
|
||||||
|
return_value=None):
|
||||||
|
self.assertRaises(
|
||||||
|
log_exc.TargetResourceNotFound,
|
||||||
|
self.log_plugin.validator_mgr.validate_request,
|
||||||
|
mock.ANY,
|
||||||
|
log_data)
|
||||||
|
|
||||||
|
def test_validate_request_unsupported_logging_type(self):
|
||||||
|
log_data = {'resource_type': 'security_group',
|
||||||
|
'target_id': 'fake_port_id'}
|
||||||
|
|
||||||
|
with mock.patch.object(directory, 'get_plugin',
|
||||||
|
return_value=self.log_plugin):
|
||||||
|
with mock.patch.object(ports.Port, 'get_object',
|
||||||
|
return_value=mock.ANY):
|
||||||
|
with mock.patch.object(validators,
|
||||||
|
'validate_log_type_for_port',
|
||||||
|
return_value=False):
|
||||||
|
self.assertRaises(
|
||||||
|
log_exc.LoggingTypeNotSupported,
|
||||||
|
self.log_plugin.validator_mgr.validate_request,
|
||||||
|
mock.ANY,
|
||||||
|
log_data)
|
||||||
|
|
||||||
|
def test_validate_request_invalid_resource_constraint(self):
|
||||||
|
log_data = {'resource_type': 'security_group',
|
||||||
|
'resource_id': 'fake_sg_id',
|
||||||
|
'target_id': 'fake_port_id'}
|
||||||
|
|
||||||
|
class FakeFiltered(object):
|
||||||
|
def one(self):
|
||||||
|
raise orm_exc.NoResultFound
|
||||||
|
|
||||||
|
class FakeSGPortBinding(object):
|
||||||
|
def filter_by(self, security_group_id, port_id):
|
||||||
|
return FakeFiltered()
|
||||||
|
|
||||||
|
with mock.patch.object(directory, 'get_plugin',
|
||||||
|
return_value=self.log_plugin):
|
||||||
|
with mock.patch.object(
|
||||||
|
sg_object.SecurityGroup, 'count', return_value=1):
|
||||||
|
with mock.patch.object(
|
||||||
|
ports.Port, 'get_object', return_value=mock.ANY):
|
||||||
|
with mock.patch.object(validators,
|
||||||
|
'validate_log_type_for_port',
|
||||||
|
return_value=True):
|
||||||
|
with mock.patch('neutron.db._utils.model_query',
|
||||||
|
return_value=FakeSGPortBinding()):
|
||||||
|
self.assertRaises(
|
||||||
|
log_exc.InvalidResourceConstraint,
|
||||||
|
self.log_plugin.validator_mgr.validate_request,
|
||||||
|
mock.ANY,
|
||||||
|
log_data)
|
|
@ -19,78 +19,39 @@ from neutron_lib import context
|
||||||
from neutron_lib.plugins import constants as plugin_const
|
from neutron_lib.plugins import constants as plugin_const
|
||||||
from neutron_lib.plugins import directory
|
from neutron_lib.plugins import directory
|
||||||
from oslo_utils import uuidutils
|
from oslo_utils import uuidutils
|
||||||
from sqlalchemy.orm import exc as orm_exc
|
|
||||||
|
|
||||||
from neutron.objects import ports
|
from neutron.objects import ports
|
||||||
from neutron.objects import securitygroup as sg_object
|
|
||||||
from neutron.services.logapi.common import exceptions as log_exc
|
|
||||||
from neutron.services.logapi.common import validators
|
from neutron.services.logapi.common import validators
|
||||||
from neutron.tests import base
|
from neutron.tests import base
|
||||||
from neutron.tests.unit.services.logapi.drivers import (
|
from neutron.tests.unit.services.logapi.drivers import (
|
||||||
test_manager as drv_mgr)
|
test_manager as drv_mgr)
|
||||||
|
|
||||||
|
|
||||||
class TestRequestValidations(base.BaseTestCase):
|
class TestRegisterValidateMethods(base.BaseTestCase):
|
||||||
"""Test validation for a request"""
|
|
||||||
|
|
||||||
def test_validate_request_resource_sg_not_exists(self):
|
def setUp(self):
|
||||||
log_data = {'resource_type': 'security_group',
|
self.validator_mgr = validators.ResourceValidateRequest.get_instance()
|
||||||
'resource_id': 'fake_sg_id'}
|
super(TestRegisterValidateMethods, self).setUp()
|
||||||
with mock.patch.object(sg_object.SecurityGroup, 'count',
|
|
||||||
return_value=0):
|
|
||||||
self.assertRaises(log_exc.ResourceNotFound,
|
|
||||||
validators.validate_request,
|
|
||||||
mock.ANY,
|
|
||||||
log_data)
|
|
||||||
|
|
||||||
def test_validate_request_target_resource_port_not_exists(self):
|
def test_register_validate_method(self):
|
||||||
log_data = {'resource_type': 'security_group',
|
self.validator_mgr.validate_methods.clear()
|
||||||
'target_id': 'fake_port_id'}
|
resource_type = 'fake_resource'
|
||||||
with mock.patch.object(ports.Port, 'get_object', return_value=None):
|
|
||||||
self.assertRaises(log_exc.TargetResourceNotFound,
|
|
||||||
validators.validate_request,
|
|
||||||
mock.ANY,
|
|
||||||
log_data)
|
|
||||||
|
|
||||||
def test_validate_request_log_type_not_supported_on_port(self):
|
@validators.ResourceValidateRequest.register(resource_type)
|
||||||
log_data = {'resource_type': 'security_group',
|
def fake_method():
|
||||||
'target_id': 'fake_port_id'}
|
pass
|
||||||
with mock.patch.object(ports.Port, 'get_object',
|
|
||||||
return_value=mock.ANY):
|
|
||||||
with mock.patch.object(validators, 'validate_log_type_for_port',
|
|
||||||
return_value=False):
|
|
||||||
self.assertRaises(log_exc.LoggingTypeNotSupported,
|
|
||||||
validators.validate_request,
|
|
||||||
mock.ANY,
|
|
||||||
log_data)
|
|
||||||
|
|
||||||
def test_validate_request_invalid_resource_constraint(self):
|
self.assertEqual({'fake_resource': fake_method},
|
||||||
log_data = {'resource_type': 'security_group',
|
self.validator_mgr.validate_methods_map)
|
||||||
'resource_id': 'fake_sg_id',
|
|
||||||
'target_id': 'fake_port_id'}
|
|
||||||
|
|
||||||
class FakeFiltered(object):
|
def test_get_validated_method(self):
|
||||||
def one(self):
|
|
||||||
raise orm_exc.NoResultFound
|
|
||||||
|
|
||||||
class FakeSGPortBinding(object):
|
@validators.ResourceValidateRequest.register('fake_resource')
|
||||||
def filter_by(self, security_group_id, port_id):
|
def fake_method():
|
||||||
return FakeFiltered()
|
pass
|
||||||
|
|
||||||
with mock.patch.object(
|
actual = self.validator_mgr.get_validated_method('fake_resource')
|
||||||
sg_object.SecurityGroup, 'count', return_value=1):
|
self.assertEqual(fake_method, actual)
|
||||||
with mock.patch.object(
|
|
||||||
ports.Port, 'get_object', return_value=mock.ANY):
|
|
||||||
with mock.patch.object(validators,
|
|
||||||
'validate_log_type_for_port',
|
|
||||||
return_value=True):
|
|
||||||
with mock.patch('neutron.db._utils.model_query',
|
|
||||||
return_value=FakeSGPortBinding()):
|
|
||||||
self.assertRaises(
|
|
||||||
log_exc.InvalidResourceConstraint,
|
|
||||||
validators.validate_request,
|
|
||||||
mock.ANY,
|
|
||||||
log_data)
|
|
||||||
|
|
||||||
|
|
||||||
class TestLogDriversLoggingTypeValidations(drv_mgr.TestLogDriversManagerBase):
|
class TestLogDriversLoggingTypeValidations(drv_mgr.TestLogDriversManagerBase):
|
||||||
|
|
|
@ -25,6 +25,7 @@ from neutron.objects.logapi import logging_resource as log_object
|
||||||
from neutron.objects import ports
|
from neutron.objects import ports
|
||||||
from neutron.objects import securitygroup as sg_object
|
from neutron.objects import securitygroup as sg_object
|
||||||
from neutron.services.logapi.common import exceptions as log_exc
|
from neutron.services.logapi.common import exceptions as log_exc
|
||||||
|
from neutron.services.logapi.common import sg_validate
|
||||||
from neutron.tests.unit.services.logapi import base
|
from neutron.tests.unit.services.logapi import base
|
||||||
|
|
||||||
DB_PLUGIN_KLASS = 'neutron.db.db_base_plugin_v2.NeutronDbPluginV2'
|
DB_PLUGIN_KLASS = 'neutron.db.db_base_plugin_v2.NeutronDbPluginV2'
|
||||||
|
@ -51,6 +52,12 @@ class TestLoggingPlugin(base.BaseLogTestCase):
|
||||||
["neutron.services.logapi.logging_plugin.LoggingPlugin"])
|
["neutron.services.logapi.logging_plugin.LoggingPlugin"])
|
||||||
|
|
||||||
manager.init()
|
manager.init()
|
||||||
|
mock.patch(
|
||||||
|
'neutron.services.logapi.common.validators.'
|
||||||
|
'ResourceValidateRequest.get_validated_method',
|
||||||
|
return_value=sg_validate.validate_security_group_request
|
||||||
|
).start()
|
||||||
|
|
||||||
self.log_plugin = directory.get_plugin(plugin_const.LOG_API)
|
self.log_plugin = directory.get_plugin(plugin_const.LOG_API)
|
||||||
self.log_plugin.driver_manager = mock.Mock()
|
self.log_plugin.driver_manager = mock.Mock()
|
||||||
log_types = mock.PropertyMock(return_value=SUPPORTED_LOGGING_TYPES)
|
log_types = mock.PropertyMock(return_value=SUPPORTED_LOGGING_TYPES)
|
||||||
|
|
Loading…
Reference in New Issue