From c3074524da97517bad4e1aaa5efc1f2cd09152cb Mon Sep 17 00:00:00 2001 From: Julia Kreger Date: Mon, 8 Jan 2024 10:15:06 -0800 Subject: [PATCH] Fix system scoped manageable node network failure Before this change, if a user requested a node to be cleaned or "managed" with cleaning enabled when the user is in the system scope, Ironic would attempt to user's token to make the request to Neutron. This, unfortunately, does not work, as the neutron client explicitly requires a project ID to make the request to Neutron. As a result, Ironic now falls back to it's internal credential configuration to make the forward request, which matches the behavior if a node has been unprovisioned and the cleaning has been started automatically. Closes-Bug: 2048416 Change-Id: Id91ec6afcf89642fb3069918e768016b8b657a31 --- ironic/common/neutron.py | 6 +++++- ironic/tests/unit/common/test_neutron.py | 1 + ...ystem-scope-triggered-clean-22ada9b920c08365.yaml | 12 ++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/fix-system-scope-triggered-clean-22ada9b920c08365.yaml diff --git a/ironic/common/neutron.py b/ironic/common/neutron.py index 7a5d92dd85..d3a9ae574d 100644 --- a/ironic/common/neutron.py +++ b/ironic/common/neutron.py @@ -70,7 +70,11 @@ def get_client(token=None, context=None, auth_from_config=False): user_auth = None if (not auth_from_config and CONF.neutron.auth_type != 'none' - and context.auth_token): + and context.auth_token and not context.system_scope): + # If we have a token, we *should* use the user's auth, however we + # can only do so *if* it is a project scoped request. If it is + # system scoped, we cannot leverage user auth data to make the next + # request. user_auth = keystone.get_service_auth(context, endpoint, service_auth) sess = keystone.get_session('neutron', timeout=CONF.neutron.timeout, diff --git a/ironic/tests/unit/common/test_neutron.py b/ironic/tests/unit/common/test_neutron.py index fe238df48c..15918b25fd 100644 --- a/ironic/tests/unit/common/test_neutron.py +++ b/ironic/tests/unit/common/test_neutron.py @@ -75,6 +75,7 @@ class TestNeutronClient(base.TestCase): mock_auth, mock_sauth): mock_ctxt.return_value = ctxt = mock.Mock() ctxt.auth_token = 'test-token-123' + ctxt.system_scope = None neutron.get_client(token='test-token-123') mock_ctxt.assert_called_once_with(auth_token='test-token-123') mock_client_init.assert_called_once_with(oslo_conf=mock.ANY, diff --git a/releasenotes/notes/fix-system-scope-triggered-clean-22ada9b920c08365.yaml b/releasenotes/notes/fix-system-scope-triggered-clean-22ada9b920c08365.yaml new file mode 100644 index 0000000000..325d615eff --- /dev/null +++ b/releasenotes/notes/fix-system-scope-triggered-clean-22ada9b920c08365.yaml @@ -0,0 +1,12 @@ +--- +fixes: + - | + Fixes an issue where a System Scoped user could not trigger a node into + a ``manageable`` state with cleaning enabled, as the Neutron client would + attempt to utilize their user's token to create the Neutron port for the + cleaning operation, as designed. This is because with requests made in the + ``system`` scope, there is no associated project and the request fails. + + Ironic now checks if the request has been made with a ``system`` scope, + and if so it utilizes the internal credential configuration to communicate + with Neutron.