Make optional the validation of filters

This fix covers the cases where it's required to be
flexible in the validation of unknown filters.

Change-Id: I1becad77d48556181c5667ad06b2971b8b8517b2
Partially-Implements: blueprint adopt-oslo-versioned-objects-for-db
Closes-Bug: #1622672
This commit is contained in:
Victor Morales 2016-09-05 08:50:06 -05:00 committed by Ihar Hrachyshka
parent cb99ce5c44
commit c8f208c465
11 changed files with 57 additions and 11 deletions

View File

@ -1081,7 +1081,7 @@ class NeutronDbPluginV2(db_base_plugin_common.DbBasePluginCommon,
page_reverse=False):
pager = base_obj.Pager(sorts, limit, page_reverse, marker)
subnetpools = subnetpool_obj.SubnetPool.get_objects(
context, _pager=pager, **filters)
context, _pager=pager, validate_filters=False, **filters)
return [
self._make_subnetpool_dict(pool, fields)
for pool in subnetpools

View File

@ -204,7 +204,8 @@ class NeutronObject(obj_base.VersionedObject,
@classmethod
@abc.abstractmethod
def get_objects(cls, context, _pager=None, **kwargs):
def get_objects(cls, context, _pager=None, validate_filters=True,
**kwargs):
raise NotImplementedError()
def create(self):
@ -405,17 +406,21 @@ class NeutronDbObject(NeutronObject):
return cls._load_object(context, db_obj)
@classmethod
def get_objects(cls, context, _pager=None, **kwargs):
def get_objects(cls, context, _pager=None, validate_filters=True,
**kwargs):
"""
Fetch objects from DB and convert them to versioned objects.
:param context:
:param _pager: a Pager object representing advanced sorting/pagination
criteria
:param validate_filters: Raises an error in case of passing an unknown
filter
:param kwargs: multiple keys defined by key=value pairs
:return: list of objects of NeutronDbObject class
"""
cls.validate_filters(**kwargs)
if validate_filters:
cls.validate_filters(**kwargs)
with db_api.autonested_transaction(context.session):
db_objs = obj_db_api.get_objects(
context, cls.db_model, _pager=_pager,

View File

@ -107,12 +107,14 @@ class QosPolicy(base.NeutronDbObject):
return policy_obj
@classmethod
def get_objects(cls, context, **kwargs):
def get_objects(cls, context, _pager=None, validate_filters=True,
**kwargs):
# We want to get the policy regardless of its tenant id. We'll make
# sure the tenant has permission to access the policy later on.
admin_context = context.elevated()
with db_api.autonested_transaction(admin_context.session):
objs = super(QosPolicy, cls).get_objects(admin_context,
objs = super(QosPolicy, cls).get_objects(admin_context, _pager,
validate_filters,
**kwargs)
result = []
for obj in objs:

View File

@ -39,8 +39,10 @@ class QosRuleType(base.NeutronObject):
# we don't receive context because we don't need db access at all
@classmethod
def get_objects(cls, **kwargs):
cls.validate_filters(**kwargs)
def get_objects(cls, validate_filters=True, **kwargs):
if validate_filters:
cls.validate_filters(**kwargs)
core_plugin = manager.NeutronManager.get_plugin()
# TODO(ihrachys): apply filters to returned result
return [cls(type=type_)
for type_ in core_plugin.supported_qos_rule_types]

View File

@ -41,7 +41,8 @@ class DNSNameServer(base.NeutronDbObject):
}
@classmethod
def get_objects(cls, context, _pager=None, **kwargs):
def get_objects(cls, context, _pager=None, validate_filters=True,
**kwargs):
"""Fetch DNSNameServer objects with default sort by 'order' field.
"""
if not _pager:
@ -50,6 +51,7 @@ class DNSNameServer(base.NeutronDbObject):
# (NOTE) True means ASC, False is DESC
_pager.sorts = [('order', True)]
return super(DNSNameServer, cls).get_objects(context, _pager,
validate_filters,
**kwargs)

View File

@ -90,9 +90,12 @@ class SubnetPool(base.NeutronDbObject):
return pool_obj
@classmethod
def get_objects(cls, context, **kwargs):
def get_objects(cls, context, _pager=None, validate_filters=True,
**kwargs):
with db_api.autonested_transaction(context.session):
objs = super(SubnetPool, cls).get_objects(context, **kwargs)
objs = super(SubnetPool, cls).get_objects(context, _pager,
validate_filters,
**kwargs)
for obj in objs:
obj.reload_prefixes()
return objs

View File

@ -728,3 +728,12 @@ class BaseSearchCriteriaTest(BaseNetworkTest):
# marker
expected_resources[:-1],
self._extract_resources(body))
def _test_list_validation_filters(self):
validation_args = {
'unknown_filter': 'value',
}
body = self.list_method(**validation_args)
resources = self._extract_resources(body)
for resource in resources:
self.assertIn(resource['name'], self.resource_names)

View File

@ -135,3 +135,7 @@ class NetworksSearchCriteriaTest(base.BaseSearchCriteriaTest):
@test.idempotent_id('f1867fc5-e1d6-431f-bc9f-8b882e43a7f9')
def test_list_no_pagination_limit_0(self):
self._test_list_no_pagination_limit_0()
@test.idempotent_id('3574ec9b-a8b8-43e3-9c11-98f5875df6a9')
def test_list_validation_filters(self):
self._test_list_validation_filters()

View File

@ -390,3 +390,7 @@ class SubnetPoolsSearchCriteriaTest(base.BaseSearchCriteriaTest,
@test.idempotent_id('82a13efc-c18f-4249-b8ec-cec7cf26fbd6')
def test_list_no_pagination_limit_0(self):
self._test_list_no_pagination_limit_0()
@test.idempotent_id('27feb3f8-40f4-4e50-8cd2-7d0096a98682')
def test_list_validation_filters(self):
self._test_list_validation_filters()

View File

@ -63,3 +63,7 @@ class SubnetsSearchCriteriaTest(base.BaseSearchCriteriaTest):
@test.idempotent_id('d851937c-9821-4b46-9d18-43e9077ecac0')
def test_list_no_pagination_limit_0(self):
self._test_list_no_pagination_limit_0()
@test.idempotent_id('c0f9280b-9d81-4728-a967-6be22659d4c8')
def test_list_validation_filters(self):
self._test_list_validation_filters()

View File

@ -645,6 +645,17 @@ class BaseObjectIfaceTestCase(_BaseObjectTestCase, test_base.BaseTestCase):
self._test_class.get_objects, self.context,
fake_field='xxx')
def test_get_objects_without_validate_filters(self):
with mock.patch.object(
obj_db_api, 'get_objects',
side_effect=self.fake_get_objects):
objs = self._test_class.get_objects(self.context,
validate_filters=False,
unknown_filter='value')
self.assertItemsEqual(
[get_obj_db_fields(obj) for obj in self.objs],
[get_obj_db_fields(obj) for obj in objs])
def test_count(self):
if not isinstance(self._test_class, base.NeutronDbObject):
self.skipTest('Class %s does not inherit from NeutronDbObject' %