Merge "Do not ignore 'fields' query parameter when building next url" into stable/rocky
This commit is contained in:
commit
02b852d59c
|
@ -157,9 +157,10 @@ class ChassisCollection(collection.Collection):
|
|||
sanitize=False)
|
||||
for ch in chassis]
|
||||
url = url or None
|
||||
collection.next = collection.get_next(limit, url=url, **kwargs)
|
||||
collection.next = collection.get_next(limit, url=url, fields=fields,
|
||||
**kwargs)
|
||||
for item in collection.chassis:
|
||||
item.sanitize(fields)
|
||||
item.sanitize(fields)
|
||||
return collection
|
||||
|
||||
@classmethod
|
||||
|
|
|
@ -39,6 +39,11 @@ class Collection(base.APIBase):
|
|||
return wtypes.Unset
|
||||
|
||||
resource_url = url or self._type
|
||||
fields = kwargs.pop('fields', None)
|
||||
# NOTE(saga): If fields argument is present in kwargs and not None. It
|
||||
# is a list so convert it into a comma seperated string.
|
||||
if fields:
|
||||
kwargs['fields'] = ','.join(fields)
|
||||
q_args = ''.join(['%s=%s&' % (key, kwargs[key]) for key in kwargs])
|
||||
next_args = '?%(args)slimit=%(limit)d&marker=%(marker)s' % {
|
||||
'args': q_args, 'limit': limit,
|
||||
|
|
|
@ -1319,10 +1319,10 @@ class NodeCollection(collection.Collection):
|
|||
collection.nodes = [Node.convert_with_links(n, fields=fields,
|
||||
sanitize=False)
|
||||
for n in nodes]
|
||||
collection.next = collection.get_next(limit, url=url, **kwargs)
|
||||
|
||||
for node in collection.nodes:
|
||||
node.sanitize(fields)
|
||||
collection.next = collection.get_next(limit, url=url, fields=fields,
|
||||
**kwargs)
|
||||
for item in collection.nodes:
|
||||
item.sanitize(fields)
|
||||
|
||||
return collection
|
||||
|
||||
|
|
|
@ -299,8 +299,8 @@ class PortCollection(collection.Collection):
|
|||
|
||||
collection.ports.append(port)
|
||||
|
||||
collection.next = collection.get_next(limit, url=url, **kwargs)
|
||||
|
||||
collection.next = collection.get_next(limit, url=url, fields=fields,
|
||||
**kwargs)
|
||||
for item in collection.ports:
|
||||
item.sanitize(fields=fields)
|
||||
|
||||
|
|
|
@ -232,8 +232,9 @@ class PortgroupCollection(collection.Collection):
|
|||
collection.portgroups = [Portgroup.convert_with_links(p, fields=fields,
|
||||
sanitize=False)
|
||||
for p in rpc_portgroups]
|
||||
collection.next = collection.get_next(limit, url=url, **kwargs)
|
||||
|
||||
collection.next = collection.get_next(limit, url=url, fields=fields,
|
||||
**kwargs)
|
||||
for item in collection.portgroups:
|
||||
item.sanitize(fields=fields)
|
||||
|
||||
|
|
|
@ -201,7 +201,8 @@ class VolumeConnectorCollection(collection.Collection):
|
|||
for p in rpc_connectors]
|
||||
if detail:
|
||||
kwargs['detail'] = detail
|
||||
collection.next = collection.get_next(limit, url=url, **kwargs)
|
||||
collection.next = collection.get_next(limit, url=url, fields=fields,
|
||||
**kwargs)
|
||||
for connector in collection.connectors:
|
||||
connector.sanitize(fields)
|
||||
return collection
|
||||
|
|
|
@ -217,9 +217,10 @@ class VolumeTargetCollection(collection.Collection):
|
|||
for p in rpc_targets]
|
||||
if detail:
|
||||
kwargs['detail'] = detail
|
||||
collection.next = collection.get_next(limit, url=url, **kwargs)
|
||||
collection.next = collection.get_next(limit, url=url, fields=fields,
|
||||
**kwargs)
|
||||
for target in collection.targets:
|
||||
target.sanitize(fields)
|
||||
target.sanitize(fields=fields)
|
||||
return collection
|
||||
|
||||
@classmethod
|
||||
|
|
|
@ -230,6 +230,22 @@ class TestListChassis(test_api_base.BaseApiTest):
|
|||
next_marker = data['chassis'][-1]['uuid']
|
||||
self.assertIn(next_marker, data['next'])
|
||||
|
||||
def test_collection_links_custom_fields(self):
|
||||
fields = 'extra,uuid'
|
||||
cfg.CONF.set_override('max_limit', 3, 'api')
|
||||
for i in range(5):
|
||||
obj_utils.create_test_chassis(
|
||||
self.context, uuid=uuidutils.generate_uuid())
|
||||
|
||||
data = self.get_json(
|
||||
'/chassis?fields=%s' % fields,
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
|
||||
self.assertEqual(3, len(data['chassis']))
|
||||
next_marker = data['chassis'][-1]['uuid']
|
||||
self.assertIn(next_marker, data['next'])
|
||||
self.assertIn('fields', data['next'])
|
||||
|
||||
def test_get_collection_pagination_no_uuid(self):
|
||||
fields = 'extra'
|
||||
limit = 2
|
||||
|
|
|
@ -736,6 +736,25 @@ class TestListNodes(test_api_base.BaseApiTest):
|
|||
next_marker = data['nodes'][-1]['uuid']
|
||||
self.assertIn(next_marker, data['next'])
|
||||
|
||||
def test_collection_links_custom_fields(self):
|
||||
fields = 'driver_info,uuid'
|
||||
cfg.CONF.set_override('max_limit', 3, 'api')
|
||||
nodes = []
|
||||
for id in range(5):
|
||||
node = obj_utils.create_test_node(self.context,
|
||||
uuid=uuidutils.generate_uuid(),
|
||||
driver_info={'fake': 'value'},
|
||||
properties={'fake': 'bar'})
|
||||
nodes.append(node.uuid)
|
||||
data = self.get_json(
|
||||
'/nodes?fields=%s' % fields,
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(3, len(data['nodes']))
|
||||
|
||||
next_marker = data['nodes'][-1]['uuid']
|
||||
self.assertIn(next_marker, data['next'])
|
||||
self.assertIn('fields', data['next'])
|
||||
|
||||
def test_get_collection_pagination_no_uuid(self):
|
||||
fields = 'name'
|
||||
limit = 2
|
||||
|
|
|
@ -609,6 +609,25 @@ class TestListPorts(test_api_base.BaseApiTest):
|
|||
next_marker = data['ports'][-1]['uuid']
|
||||
self.assertIn(next_marker, data['next'])
|
||||
|
||||
def test_collection_links_custom_fields(self):
|
||||
fields = 'address,uuid'
|
||||
cfg.CONF.set_override('max_limit', 3, 'api')
|
||||
for i in range(5):
|
||||
obj_utils.create_test_port(
|
||||
self.context,
|
||||
uuid=uuidutils.generate_uuid(),
|
||||
node_id=self.node.id,
|
||||
address='52:54:00:cf:2d:3%s' % i)
|
||||
|
||||
data = self.get_json(
|
||||
'/ports?fields=%s' % fields,
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
|
||||
self.assertEqual(3, len(data['ports']))
|
||||
next_marker = data['ports'][-1]['uuid']
|
||||
self.assertIn(next_marker, data['next'])
|
||||
self.assertIn('fields', data['next'])
|
||||
|
||||
def test_port_by_address(self):
|
||||
address_template = "aa:bb:cc:dd:ee:f%d"
|
||||
for id_ in range(3):
|
||||
|
|
|
@ -327,6 +327,26 @@ class TestListPortgroups(test_api_base.BaseApiTest):
|
|||
next_marker = data['portgroups'][-1]['uuid']
|
||||
self.assertIn(next_marker, data['next'])
|
||||
|
||||
def test_collection_links_custom_fields(self):
|
||||
fields = 'address,uuid'
|
||||
cfg.CONF.set_override('max_limit', 3, 'api')
|
||||
for i in range(5):
|
||||
obj_utils.create_test_portgroup(
|
||||
self.context,
|
||||
uuid=uuidutils.generate_uuid(),
|
||||
node_id=self.node.id,
|
||||
name='portgroup%s' % i,
|
||||
address='52:54:00:cf:2d:3%s' % i)
|
||||
|
||||
data = self.get_json(
|
||||
'/portgroups?fields=%s' % fields,
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
|
||||
self.assertEqual(3, len(data['portgroups']))
|
||||
next_marker = data['portgroups'][-1]['uuid']
|
||||
self.assertIn(next_marker, data['next'])
|
||||
self.assertIn('fields', data['next'])
|
||||
|
||||
def test_get_collection_pagination_no_uuid(self):
|
||||
fields = 'address'
|
||||
limit = 2
|
||||
|
|
|
@ -273,6 +273,28 @@ class TestListVolumeConnectors(test_api_base.BaseApiTest):
|
|||
next_marker = data['connectors'][-1]['uuid']
|
||||
self.assertIn(next_marker, data['next'])
|
||||
|
||||
def test_collection_links_custom_fields(self):
|
||||
cfg.CONF.set_override('max_limit', 3, 'api')
|
||||
connectors = []
|
||||
fields = 'uuid,extra'
|
||||
for i in range(5):
|
||||
connector = obj_utils.create_test_volume_connector(
|
||||
self.context, node_id=self.node.id,
|
||||
uuid=uuidutils.generate_uuid(),
|
||||
connector_id='test-connector_id-%s' % i)
|
||||
connectors.append(connector.uuid)
|
||||
|
||||
data = self.get_json(
|
||||
'/volume/connectors?fields=%s' % fields,
|
||||
headers=self.headers)
|
||||
|
||||
self.assertEqual(3, len(data['connectors']))
|
||||
self.assertIn('volume/connectors', data['next'])
|
||||
|
||||
next_marker = data['connectors'][-1]['uuid']
|
||||
self.assertIn(next_marker, data['next'])
|
||||
self.assertIn('fields', data['next'])
|
||||
|
||||
def test_get_collection_pagination_no_uuid(self):
|
||||
fields = 'connector_id'
|
||||
limit = 2
|
||||
|
|
|
@ -258,6 +258,24 @@ class TestListVolumeTargets(test_api_base.BaseApiTest):
|
|||
self.assertIn(next_marker, data['next'])
|
||||
self.assertIn('volume/targets', data['next'])
|
||||
|
||||
def test_collection_links_custom_fields(self):
|
||||
fields = 'uuid,extra'
|
||||
cfg.CONF.set_override('max_limit', 3, 'api')
|
||||
targets = []
|
||||
for id_ in range(5):
|
||||
target = obj_utils.create_test_volume_target(
|
||||
self.context, node_id=self.node.id,
|
||||
uuid=uuidutils.generate_uuid(), boot_index=id_)
|
||||
targets.append(target.uuid)
|
||||
data = self.get_json('/volume/targets?fields=%s' % fields,
|
||||
headers=self.headers)
|
||||
self.assertEqual(3, len(data['targets']))
|
||||
|
||||
next_marker = data['targets'][-1]['uuid']
|
||||
self.assertIn(next_marker, data['next'])
|
||||
self.assertIn('volume/targets', data['next'])
|
||||
self.assertIn('fields', data['next'])
|
||||
|
||||
def test_get_collection_pagination_no_uuid(self):
|
||||
fields = 'boot_index'
|
||||
limit = 2
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
fixes:
|
||||
- |
|
||||
Fixes issue where the resource list API returned results with requested
|
||||
fields only until the API MAX_LIMIT. After the API MAX_LIMIT is reached the
|
||||
API started ignoring user requested fields. This fix will make sure that
|
||||
the next url generated by the pagination code will include the user
|
||||
requested fields as query parameter.
|
Loading…
Reference in New Issue