diff options
author | Simo Sorce <simo@redhat.com> | 2015-10-02 21:30:35 -0400 |
---|---|---|
committer | Simo Sorce <simo@redhat.com> | 2015-10-19 12:18:26 -0400 |
commit | b20b47b100b2716273a5abfe2850e994c1d3e69d (patch) | |
tree | ae028008985d65ea2009ebc0d8871676b18593b6 /custodia | |
parent | 2380852ef8007cd9862d2db5f6af7e4e10bd6aad (diff) | |
download | custodia-b20b47b100b2716273a5abfe2850e994c1d3e69d.tar.gz custodia-b20b47b100b2716273a5abfe2850e994c1d3e69d.tar.xz custodia-b20b47b100b2716273a5abfe2850e994c1d3e69d.zip |
Add forwarder plugin
This pugin allows to mangle and forward requests to another custodia
server, locally or on the network.
Signed-off-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Christian Heimes <cheimes@redhat.com>
Diffstat (limited to 'custodia')
-rw-r--r-- | custodia/forwarder.py | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/custodia/forwarder.py b/custodia/forwarder.py new file mode 100644 index 0000000..03fcfef --- /dev/null +++ b/custodia/forwarder.py @@ -0,0 +1,72 @@ +# Copyright (C) 2015 Custodia Project Contributors - see LICENSE file + +import json +import uuid + +from custodia import log +from custodia.client import CustodiaHTTPClient +from custodia.httpd.consumer import HTTPConsumer +from custodia.httpd.server import HTTPError + + +class Forwarder(HTTPConsumer): + + def __init__(self, *args, **kwargs): + super(Forwarder, self).__init__(*args, **kwargs) + self._auditlog = log.AuditLog(self.config) + self.client = CustodiaHTTPClient(self.config['forward_uri']) + self.headers = json.loads(self.config.get('forward_headers', '{}')) + self.uuid = str(uuid.uuid4()) + self.headers['X-LOOP-CUSTODIA'] = self.uuid + + def _path(self, request): + trail = request.get('trail', []) + prefix = request.get('remote_user', 'guest') + return '/'.join([prefix.rstrip('/')] + trail) + + def _headers(self, request): + headers = {} + headers.update(self.headers) + loop = request['headers'].get('X-LOOP-CUSTODIA', None) + if loop is not None: + headers['X-LOOP-CUSTODIA'] += ',' + loop + return headers + + def _response(self, reply, response): + if reply.status_code < 200 or reply.status_code > 299: + raise HTTPError(reply.status_code) + response['code'] = reply.status_code + if reply.content: + response['output'] = reply.content + + def _request(self, cmd, request, response, path, **kwargs): + if self.uuid in request['headers'].get('X-LOOP-CUSTODIA', ''): + raise HTTPError(502, "Loop detected") + reply = cmd(path, **kwargs) + self._response(reply, response) + + def GET(self, request, response): + self._request(self.client.get, request, response, + self._path(request), + params=request.get('query', None), + headers=self._headers(request)) + + def PUT(self, request, response): + self._request(self.client.put, request, response, + self._path(request), + data=request.get('body', None), + params=request.get('query', None), + headers=self._headers(request)) + + def DELETE(self, request, response): + self._request(self.client.delete, request, response, + self._path(request), + params=request.get('query', None), + headers=self._headers(request)) + + def POST(self, request, response): + self._request(self.client.post, request, response, + self._path(request), + data=request.get('body', None), + params=request.get('query', None), + headers=self._headers(request)) |