summaryrefslogtreecommitdiff
path: root/swift
diff options
context:
space:
mode:
authorMatthew Oliver <matt@oliver.net.au>2023-03-31 16:48:01 +1100
committerAlistair Coles <alistairncoles@gmail.com>2023-04-14 10:37:40 +0100
commite5105ffa09f7919cf27fa9f70aecbc98e53536aa (patch)
treee888587b69ca4b0c73f9002217fa074853f2bb18 /swift
parentd2153f5d5a05b70054399638f70e5383d9ccaf8e (diff)
downloadswift-e5105ffa09f7919cf27fa9f70aecbc98e53536aa.tar.gz
internal_client: Remove allow_modify_pipeline option
The internal client is suppose to be internal to the cluster, and as such we rely on it to not remove any headers we decide to send. However if the allow_modify_pipeline option is set the gatekeeper middleware is added to the internal client's proxy pipeline. So firstly, this patch removes the allow_modify_pipeline option from the internal client constructor. And when calling loadapp allow_modify_pipeline is always passed with a False. Further, an op could directly put the gatekeeper middleware into the internal client config. The internal client constructor will now check the pipeline and raise a ValueError if one has been placed in the pipeline. To do this, there is now a check_gatekeeper_loaded staticmethod that will walk the pipeline which called from the InternalClient.__init__ method. Enabling this walking through the pipeline, we are now stashing the wsgi pipeline in each filter so that we don't have to rely on 'app' naming conventions to iterate the pipeline. Co-Authored-By: Alistair Coles <alistairncoles@gmail.com> Change-Id: Idcca7ac0796935c8883de9084d612d64159d9f92
Diffstat (limited to 'swift')
-rw-r--r--swift/common/internal_client.py25
-rw-r--r--swift/common/wsgi.py8
-rw-r--r--swift/container/sharder.py1
3 files changed, 28 insertions, 6 deletions
diff --git a/swift/common/internal_client.py b/swift/common/internal_client.py
index 2c1c99cc0..d82035c39 100644
--- a/swift/common/internal_client.py
+++ b/swift/common/internal_client.py
@@ -28,6 +28,7 @@ from zlib import compressobj
from swift.common.exceptions import ClientException
from swift.common.http import (HTTP_NOT_FOUND, HTTP_MULTIPLE_CHOICES,
is_client_error, is_server_error)
+from swift.common.middleware.gatekeeper import GatekeeperMiddleware
from swift.common.request_helpers import USE_REPLICATION_NETWORK_HEADER
from swift.common.swob import Request, bytes_to_wsgi
from swift.common.utils import quote, close_if_possible, drain_and_close
@@ -144,6 +145,8 @@ class InternalClient(object):
:param user_agent: User agent to be sent to requests to Swift.
:param request_tries: Number of tries before InternalClient.make_request()
gives up.
+ :param use_replication_network: Force the client to use the replication
+ network over the cluster.
:param global_conf: a dict of options to update the loaded proxy config.
Options in ``global_conf`` will override those in ``conf_path`` except
where the ``conf_path`` option is preceded by ``set``.
@@ -151,12 +154,15 @@ class InternalClient(object):
"""
def __init__(self, conf_path, user_agent, request_tries,
- allow_modify_pipeline=False, use_replication_network=False,
- global_conf=None, app=None):
+ use_replication_network=False, global_conf=None, app=None,
+ **kwargs):
if request_tries < 1:
raise ValueError('request_tries must be positive')
+ # Internal clients don't use the gatekeeper and the pipeline remains
+ # static so we never allow anything to modify the proxy pipeline.
self.app = app or loadapp(conf_path, global_conf=global_conf,
- allow_modify_pipeline=allow_modify_pipeline,)
+ allow_modify_pipeline=False,)
+ self.check_gatekeeper_not_loaded(self.app)
self.user_agent = \
self.app._pipeline_final_app.backend_user_agent = user_agent
self.request_tries = request_tries
@@ -167,6 +173,19 @@ class InternalClient(object):
self.auto_create_account_prefix = \
self.app._pipeline_final_app.auto_create_account_prefix
+ @staticmethod
+ def check_gatekeeper_not_loaded(app):
+ # the Gatekeeper middleware would prevent an InternalClient passing
+ # X-Backend-* headers to the proxy app, so ensure it's not present
+ try:
+ for app in app._pipeline:
+ if isinstance(app, GatekeeperMiddleware):
+ raise ValueError(
+ "Gatekeeper middleware is not allowed in the "
+ "InternalClient proxy pipeline")
+ except AttributeError:
+ pass
+
def make_request(
self, method, path, headers, acceptable_statuses, body_file=None,
params=None):
diff --git a/swift/common/wsgi.py b/swift/common/wsgi.py
index 4fa4946dd..7c39a89e2 100644
--- a/swift/common/wsgi.py
+++ b/swift/common/wsgi.py
@@ -361,10 +361,14 @@ def loadapp(conf_file, global_conf=None, allow_modify_pipeline=True):
if func and allow_modify_pipeline:
func(PipelineWrapper(ctx))
filters = [c.create() for c in reversed(ctx.filter_contexts)]
+ pipeline = [ultimate_app]
+ ultimate_app._pipeline = pipeline
+ ultimate_app._pipeline_final_app = ultimate_app
app = ultimate_app
- app._pipeline_final_app = ultimate_app
for filter_app in filters:
- app = filter_app(app)
+ app = filter_app(pipeline[0])
+ pipeline.insert(0, app)
+ app._pipeline = pipeline
app._pipeline_final_app = ultimate_app
return app
return ctx.create()
diff --git a/swift/container/sharder.py b/swift/container/sharder.py
index 378bad7c9..ca6ee0566 100644
--- a/swift/container/sharder.py
+++ b/swift/container/sharder.py
@@ -895,7 +895,6 @@ class ContainerSharder(ContainerSharderConf, ContainerReplicator):
internal_client_conf_path,
'Swift Container Sharder',
request_tries,
- allow_modify_pipeline=False,
use_replication_network=True,
global_conf={'log_name': '%s-ic' % conf.get(
'log_name', self.log_route)})