diff --git a/ironic/api/controllers/v1/node.py b/ironic/api/controllers/v1/node.py index d3106f4153..775d4aeece 100644 --- a/ironic/api/controllers/v1/node.py +++ b/ironic/api/controllers/v1/node.py @@ -1310,8 +1310,20 @@ class NodesController(rest.RestController): _("The sort_key value %(key)s is an invalid field for " "sorting") % {'key': sort_key}) + # The query parameters for the 'next' URL + parameters = {} + if instance_uuid: + # NOTE(rloo) if instance_uuid is specified, the other query + # parameters are ignored. Since there can be at most one node that + # has this instance_uuid, we do not want to generate a 'next' link. + nodes = self._get_nodes_by_instance(instance_uuid) + + # NOTE(rloo) if limit==1 and len(nodes)==1 (see + # Collection.has_next()), a 'next' link will + # be generated, which we don't want. + limit = 0 else: filters = {} if chassis_uuid: @@ -1331,11 +1343,12 @@ class NodesController(rest.RestController): sort_key=sort_key, sort_dir=sort_dir, filters=filters) - parameters = {'sort_key': sort_key, 'sort_dir': sort_dir} - if associated: - parameters['associated'] = associated - if maintenance: - parameters['maintenance'] = maintenance + parameters = {'sort_key': sort_key, 'sort_dir': sort_dir} + if associated: + parameters['associated'] = associated + if maintenance: + parameters['maintenance'] = maintenance + return NodeCollection.convert_with_links(nodes, limit, url=resource_url, fields=fields, diff --git a/ironic/tests/unit/api/controllers/v1/test_node.py b/ironic/tests/unit/api/controllers/v1/test_node.py index 84d6c1c4f0..3346b0431d 100644 --- a/ironic/tests/unit/api/controllers/v1/test_node.py +++ b/ironic/tests/unit/api/controllers/v1/test_node.py @@ -533,6 +533,22 @@ class TestListNodes(test_api_base.BaseApiTest): next_marker = data['nodes'][-1]['uuid'] self.assertIn(next_marker, data['next']) + def test_collection_links_instance_uuid_param(self): + cfg.CONF.set_override('max_limit', 1, 'api') + nodes = [] + for id in range(2): + node = obj_utils.create_test_node( + self.context, + uuid=uuidutils.generate_uuid(), + instance_uuid=uuidutils.generate_uuid(), + resource_class='tst_resource') + nodes.append(node) + + query_str = 'instance_uuid=%s' % nodes[0].instance_uuid + data = self.get_json('/nodes?%s' % query_str) + self.assertEqual(1, len(data['nodes'])) + self.assertNotIn('next', data) + def test_sort_key(self): nodes = [] for id in range(3): diff --git a/releasenotes/notes/next-link-for-instance-uuid-f46eafe5b575f3de.yaml b/releasenotes/notes/next-link-for-instance-uuid-f46eafe5b575f3de.yaml new file mode 100644 index 0000000000..a87723dcde --- /dev/null +++ b/releasenotes/notes/next-link-for-instance-uuid-f46eafe5b575f3de.yaml @@ -0,0 +1,8 @@ +--- +fixes: + - | + Fixes a `bug <https://bugs.launchpad.net/ironic/+bug/1718683>`_ + with the response for a + ``GET /nodes?limit=1&instance_uuid=<uuid>`` request. If a node matched, + a ``next`` link was returned, even though there are no more nodes that + will match. That link is no longer returned.