objects: Convert filters to string for list values.

When request from API is passed to get_objects, filters are converted
by modify_fields_to_db. API is passing the arguments with format:
filters = {'key': ['val']}
In some classes (like Subnet, Subnetpool, AllowedAddessPairs) value of
filters has to be converted from IPNetwork, IPAddress and MACAddress
to string value format.

Current implementation in modify_fields_to_db did not take under
consideration that value passed in fields dict can be a list of
CIDRs, IPs or MAC addresses.

Change-Id: I70230a40973f5e7c3d0e325de658830eba036813
Partially-Implements: blueprint adopt-oslo-versioned-objects-for-db
This commit is contained in:
Artur Korzeniewski 2016-07-15 15:35:16 +02:00
parent 2f29a5db3c
commit cf92913105
5 changed files with 24 additions and 9 deletions

View File

@ -386,6 +386,12 @@ class NeutronDbObject(NeutronObject):
return (context.is_admin or
context.tenant_id == db_obj.tenant_id)
@staticmethod
def filter_to_str(value):
if isinstance(value, list):
return [str(val) for val in value]
return str(value)
def _get_changed_persistent_fields(self):
fields = self.obj_get_changes()
for field in self.synthetic_fields:

View File

@ -40,9 +40,9 @@ class AllowedAddressPair(base.NeutronDbObject):
def modify_fields_to_db(cls, fields):
result = super(AllowedAddressPair, cls).modify_fields_to_db(fields)
if 'ip_address' in result:
result['ip_address'] = str(result['ip_address'])
result['ip_address'] = cls.filter_to_str(result['ip_address'])
if 'mac_address' in result:
result['mac_address'] = str(result['mac_address'])
result['mac_address'] = cls.filter_to_str(result['mac_address'])
return result
# TODO(mhickey): get rid of it once we switch the db model to using

View File

@ -82,9 +82,9 @@ class Route(base.NeutronDbObject):
# TODO(korzen) remove this method when IP and CIDR decorator ready
result = super(Route, cls).modify_fields_to_db(fields)
if 'destination' in result:
result['destination'] = str(result['destination'])
result['destination'] = cls.filter_to_str(result['destination'])
if 'nexthop' in fields:
result['nexthop'] = str(result['nexthop'])
result['nexthop'] = cls.filter_to_str(result['nexthop'])
return result
@ -124,9 +124,9 @@ class IPAllocationPool(base.NeutronDbObject):
# TODO(korzen) remove this method when IP and CIDR decorator ready
result = super(IPAllocationPool, cls).modify_fields_to_db(fields)
if 'first_ip' in result:
result['first_ip'] = str(result['first_ip'])
result['first_ip'] = cls.filter_to_str(result['first_ip'])
if 'last_ip' in result:
result['last_ip'] = str(result['last_ip'])
result['last_ip'] = cls.filter_to_str(result['last_ip'])
return result
@ -179,7 +179,7 @@ class Subnet(base.NeutronDbObject):
# TODO(korzen) remove this method when IP and CIDR decorator ready
result = super(Subnet, cls).modify_fields_to_db(fields)
if 'cidr' in result:
result['cidr'] = str(result['cidr'])
result['cidr'] = cls.filter_to_str(result['cidr'])
if 'gateway_ip' in result and result['gateway_ip'] is not None:
result['gateway_ip'] = str(result['gateway_ip'])
result['gateway_ip'] = cls.filter_to_str(result['gateway_ip'])
return result

View File

@ -154,7 +154,7 @@ class SubnetPoolPrefix(base.NeutronDbObject):
def modify_fields_to_db(cls, fields):
result = super(SubnetPoolPrefix, cls).modify_fields_to_db(fields)
if 'cidr' in result:
result['cidr'] = str(result['cidr'])
result['cidr'] = cls.filter_to_str(result['cidr'])
return result
# TODO(ihrachys): get rid of it once we switch the db model to using CIDR

View File

@ -939,6 +939,15 @@ class BaseDbObjectTestCase(_BaseObjectTestCase):
self._test_class.get_objects(self.context, foo=42)
self.assertEqual({'foo': [42]}, self.filtered_args)
def test_filtering_by_fields(self):
obj = self._make_object(self.obj_fields[0])
obj.create()
for field in remove_timestamps_from_fields(self.obj_fields[0]):
filters = {field: [self.obj_fields[0][field]]}
new = self._test_class.get_objects(self.context, **filters)
self.assertEqual([obj], new)
class UniqueObjectBase(test_base.BaseTestCase):
def setUp(self):