diff --git a/ironic/api/controllers/v1/node.py b/ironic/api/controllers/v1/node.py index 1eb03fd7e0..f9531cad2d 100644 --- a/ironic/api/controllers/v1/node.py +++ b/ironic/api/controllers/v1/node.py @@ -1766,6 +1766,11 @@ class NodesController(rest.RestController): continue if patch_val == wtypes.Unset: patch_val = None + # conductor_group is case-insensitive, and we use it to calculate + # the conductor to send an update too. lowercase it here instead + # of just before saving so we calculate correctly. + if field == 'conductor_group': + patch_val = patch_val.lower() if rpc_node[field] != patch_val: rpc_node[field] = patch_val diff --git a/ironic/tests/unit/api/controllers/v1/test_node.py b/ironic/tests/unit/api/controllers/v1/test_node.py index 15e01ddd50..c76c11e699 100644 --- a/ironic/tests/unit/api/controllers/v1/test_node.py +++ b/ironic/tests/unit/api/controllers/v1/test_node.py @@ -2324,6 +2324,19 @@ class TestPatch(test_api_base.BaseApiTest): self.assertEqual(http_client.NOT_ACCEPTABLE, response.status_code) self.assertTrue(response.json['error_message']) + @mock.patch('pecan.request') + def test__update_changed_fields_lowers_conductor_group(self, + mock_pecan_req): + mock_pecan_req.version.minor = versions.MINOR_MAX_VERSION + controller = api_node.NodesController() + + node_dict = self.node.as_dict() + node_dict['conductor_group'] = 'NEW-GROUP' + node_obj = api_node.Node(**node_dict) + + controller._update_changed_fields(node_obj, self.node) + self.assertEqual('new-group', self.node.conductor_group) + @mock.patch("pecan.request") def test__update_changed_fields_remove_chassis_uuid(self, mock_pecan_req): mock_pecan_req.version.minor = versions.MINOR_MAX_VERSION diff --git a/releasenotes/notes/bug-2004947-e5f27e11b8f9c96d.yaml b/releasenotes/notes/bug-2004947-e5f27e11b8f9c96d.yaml new file mode 100644 index 0000000000..4af981224d --- /dev/null +++ b/releasenotes/notes/bug-2004947-e5f27e11b8f9c96d.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + Fixes an issue where setting the ``conductor_group`` for a node was not + entirely case-sensitive, in that this could fail if case-sensitivity did + not match between the conductor configuration and the API request.