Unify `MetadataProxyHandlerBaseSocketServer` class (2)

The base class now implements the method ``handle``, that is shared
in all local implementations.

This patch adds a missing warning message when the HTTP request has
both the network and the router ID; only one must be provided only.

Partial-Bug: #2100585
Signed-off-by: Rodolfo Alonso Hernandez <ralonsoh@redhat.com>
Change-Id: Ie6b9695be1ac457526edaec95bb6600890090b92
This commit is contained in:
Rodolfo Alonso Hernandez
2025-09-05 08:57:22 +00:00
committed by Rodolfo Alonso
parent c031b59ec1
commit ca323d9052
3 changed files with 37 additions and 71 deletions

View File

@@ -12,7 +12,6 @@
# License for the specific language governing permissions and limitations
# under the License.
import io
import socketserver
from neutron_lib.agent import topics
@@ -21,7 +20,6 @@ from neutron_lib import context
from oslo_config import cfg
from oslo_log import log as logging
from oslo_service import loopingcall
import webob
from neutron._i18n import _
from neutron.agent.common import base_agent_rpc
@@ -55,8 +53,7 @@ class MetadataPluginAPI(base_agent_rpc.BasePluginApi):
class MetadataProxyHandler(
common_metadata.MetadataProxyHandlerBaseSocketServer,
socketserver.StreamRequestHandler):
common_metadata.MetadataProxyHandlerBaseSocketServer):
NETWORK_ID_HEADER = 'X-Neutron-Network-ID'
ROUTER_ID_HEADER = 'X-Neutron-Router-ID'
_conf = None
@@ -67,37 +64,6 @@ class MetadataProxyHandler(
super().__init__(self._conf, has_cache=False, request=request,
client_address=client_address, server=server)
def handle(self):
try:
request = self.request.recv(4096)
LOG.debug('Request: %s', request.decode('utf-8'))
f_request = io.BytesIO(request)
req = webob.Request.from_file(f_request)
instance_id, project_id = self._get_instance_and_project_id(req)
if instance_id:
res = self._proxy_request(instance_id, project_id, req)
self.wfile.write(res)
return
network_id, router_id = self._get_instance_id(req)
if network_id and router_id:
title = '400 Bad Request'
msg = _('Both network %s and router %s '
'defined.') % (network_id, router_id)
elif network_id:
title = '404 Not Found'
msg = _('Instance was not found on network %s.') % network_id
LOG.warning(msg)
else:
title = '404 Not Found'
msg = _('Instance was not found on router %s.') % 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
@staticmethod
def _get_port_filters(router_id=None, ip_address=None,
networks=None, mac_address=None):

View File

@@ -12,14 +12,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import io
import socketserver
from oslo_config import cfg
from oslo_log import log as logging
import webob
from neutron._i18n import _
from neutron.agent.linux import utils as agent_utils
from neutron.agent.metadata import proxy_base
from neutron.common import metadata as common_metadata
@@ -30,8 +27,7 @@ LOG = logging.getLogger(__name__)
class MetadataProxyHandler(
common_metadata.MetadataProxyHandlerBaseSocketServer,
socketserver.StreamRequestHandler):
common_metadata.MetadataProxyHandlerBaseSocketServer):
NETWORK_ID_HEADER = 'X-OVN-Network-ID'
ROUTER_ID_HEADER = ''
_conf = None
@@ -42,37 +38,6 @@ class MetadataProxyHandler(
super().__init__(self._conf, has_cache=False, request=request,
client_address=client_address, server=server)
def handle(self):
try:
request = self.request.recv(4096)
LOG.debug('Request: %s', request.decode('utf-8'))
f_request = io.BytesIO(request)
req = webob.Request.from_file(f_request)
instance_id, project_id = self._get_instance_and_project_id(req)
if instance_id:
res = self._proxy_request(instance_id, project_id, req)
self.wfile.write(res)
return
network_id, router_id = self._get_instance_id(req)
if network_id and router_id:
title = '400 Bad Request'
msg = _('Both network %s and router %s '
'defined.') % (network_id, router_id)
elif network_id:
title = '404 Not Found'
msg = _('Instance was not found on network %s.') % network_id
LOG.warning(msg)
else:
title = '404 Not Found'
msg = _('Instance was not found on router %s.') % 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
@property
def sb_idl(self):
return self._sb_idl

View File

@@ -12,6 +12,8 @@
# under the License.
import abc
import io
import socketserver
from urllib import parse
import jinja2
@@ -157,6 +159,7 @@ def encode_http_reponse(http_code, title, message):
class MetadataProxyHandlerBaseSocketServer(
proxy_base.MetadataProxyHandlerBase,
socketserver.StreamRequestHandler,
metaclass=abc.ABCMeta):
@staticmethod
def _http_response(http_response, request):
@@ -247,3 +250,35 @@ class MetadataProxyHandlerBaseSocketServer(
# TODO(ralonsoh): add info in the returned HTTP message to the VM.
return self._http_response(resp, req)
raise Exception(_('Unexpected response code: %s') % resp.status_code)
def handle(self):
try:
request = self.request.recv(4096)
LOG.debug('Request: %s', request.decode('utf-8'))
f_request = io.BytesIO(request)
req = webob.Request.from_file(f_request)
instance_id, project_id = self._get_instance_and_project_id(req)
if instance_id:
res = self._proxy_request(instance_id, project_id, req)
self.wfile.write(res)
return
network_id, router_id = self._get_instance_id(req)
if network_id and router_id:
title = '400 Bad Request'
msg = _('Both network %s and router %s '
'defined.') % (network_id, router_id)
LOG.warning(msg)
elif network_id:
title = '404 Not Found'
msg = _('Instance was not found on network %s.') % network_id
LOG.warning(msg)
else:
title = '404 Not Found'
msg = _('Instance was not found on router %s.') % router_id
LOG.warning(msg)
res = encode_http_reponse(title, title, msg)
self.wfile.write(res)
except Exception as exc:
LOG.exception('Error while receiving data.')
raise exc