From b993f3c9a20cfd2208db07fcda8c46d6a8843bac Mon Sep 17 00:00:00 2001 From: Rodolfo Alonso Hernandez Date: Thu, 10 Apr 2025 09:02:55 +0000 Subject: [PATCH] Return a HTTP404 message when the Metadata instance is not present If the Metadata instance (network, router) is not present, now the Metadata proxy handler writes a HTTP 404 error message in the socket file that is received by the client (virtual machine) that requests the metadata. Closes-Bug: #2106713 Change-Id: Ic717de94f2c483c08e2aa8fe688fe2e88d17d035 --- neutron/agent/metadata/agent.py | 20 ++++++++++++++++---- neutron/agent/metadata/proxy_base.py | 9 +++++++-- neutron/agent/ovn/metadata/server_socket.py | 20 ++++++++++++++++---- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/neutron/agent/metadata/agent.py b/neutron/agent/metadata/agent.py index 0868f32034a..34488517807 100644 --- a/neutron/agent/metadata/agent.py +++ b/neutron/agent/metadata/agent.py @@ -24,7 +24,6 @@ from oslo_log import log as logging from oslo_service import loopingcall import requests import webob -from webob import exc as webob_exc from neutron._i18n import _ from neutron.agent.common import base_agent_rpc @@ -169,9 +168,22 @@ class MetadataProxyHandler(MetadataProxyHandlerBaseSocketServer, res = self._proxy_request(instance_id, project_id, req) self.wfile.write(res) return - # TODO(ralonsoh): change this return to be a formatted Request - # and added to self.wfile - return webob_exc.HTTPNotFound() + + network_id, router_id = self._get_instance_id(req) + if network_id and router_id: + title = '400 Bad Request' + msg = _(f'Both network {network_id} and router {router_id} ' + f'defined.') + elif network_id: + title = '404 Not Found' + msg = _(f'Instance was not found on network {network_id}.') + LOG.warning(msg) + else: + title = '404 Not Found' + msg = _(f'Instance was not found on router {router_id}.') + LOG.warning(msg) + res = common_metadata.encode_http_reponse(title, title, msg) + self.wfile.write(res) except Exception as exc: LOG.exception('Error while receiving data.') raise exc diff --git a/neutron/agent/metadata/proxy_base.py b/neutron/agent/metadata/proxy_base.py index 11f0af06ccc..29ba0f03fce 100644 --- a/neutron/agent/metadata/proxy_base.py +++ b/neutron/agent/metadata/proxy_base.py @@ -91,11 +91,16 @@ class MetadataProxyHandlerBase(metaclass=abc.ABCMeta): explanation = str(msg) return webob.exc.HTTPInternalServerError(explanation=explanation) - def _get_instance_and_project_id(self, req, skip_cache=False): - forwarded_for = req.headers.get('X-Forwarded-For') + def _get_instance_id(self, req): + """Returns the network ID and the router ID from the request""" network_id = req.headers.get(self.NETWORK_ID_HEADER) router_id = (req.headers.get(self.ROUTER_ID_HEADER) if self.ROUTER_ID_HEADER else None) + return network_id, router_id + + def _get_instance_and_project_id(self, req, skip_cache=False): + forwarded_for = req.headers.get('X-Forwarded-For') + network_id, router_id = self._get_instance_id(req) # Only one should be given, drop since it could be spoofed if network_id and router_id: diff --git a/neutron/agent/ovn/metadata/server_socket.py b/neutron/agent/ovn/metadata/server_socket.py index 3d10e833e48..2445c4e3677 100644 --- a/neutron/agent/ovn/metadata/server_socket.py +++ b/neutron/agent/ovn/metadata/server_socket.py @@ -21,7 +21,6 @@ from oslo_config import cfg from oslo_log import log as logging import requests import webob -from webob import exc as webob_exc from neutron._i18n import _ from neutron.agent.linux import utils as agent_utils @@ -145,9 +144,22 @@ class MetadataProxyHandler(MetadataProxyHandlerBaseSocketServer, res = self._proxy_request(instance_id, project_id, req) self.wfile.write(res) return - # TODO(ralonsoh): change this return to be a formatted Request - # and added to self.wfile - return webob_exc.HTTPNotFound() + + network_id, router_id = self._get_instance_id(req) + if network_id and router_id: + title = '400 Bad Request' + msg = _(f'Both network {network_id} and router {router_id} ' + f'defined.') + elif network_id: + title = '404 Not Found' + msg = _(f'Instance was not found on network {network_id}.') + LOG.warning(msg) + else: + title = '404 Not Found' + msg = _(f'Instance was not found on router {router_id}.') + LOG.warning(msg) + res = common_metadata.encode_http_reponse(title, title, msg) + self.wfile.write(res) except Exception as exc: LOG.exception('Error while receiving data.') raise exc