From 85e09db061273003640567e7236a5067f1fd1c2b Mon Sep 17 00:00:00 2001 From: Syed Nihal Date: Mon, 18 Mar 2024 17:16:26 +0530 Subject: [PATCH] adding support for client certificates. See: https://github.com/kiwigrid/k8s-sidecar/issues/334 Signed-off-by: Syed Nihal --- README.md | 2 ++ src/helpers.py | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9008c529..346eeea9 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,8 @@ If the filename ends with `.url` suffix, the content will be processed as a URL | `REQ_USERNAME` | Username to use for basic authentication for requests to `REQ_URL` and for `*.url` triggered requests | false | - | string | | `REQ_PASSWORD` | Password to use for basic authentication for requests to `REQ_URL` and for `*.url` triggered requests | false | - | string | | `REQ_BASIC_AUTH_ENCODING` | Which encoding to use for username and password as [by default it's undefined](https://datatracker.ietf.org/doc/html/rfc7617) (e.g. `utf-8`). | false | `latin1` | string | +| `REQ_CLIENT_CERT` | [PATH] Client Certificate to be used by k8s-sidecar when communicating with the `REQ_URL` | false | - | string | +| `REQ_CLIENT_KEY` | [PATH] Client Key to be used by k8s-sidecar when communicating with the `REQ_URL` | false | - | string | | `SCRIPT` | Absolute path to a script to execute after a configmap got reloaded. It runs before calls to `REQ_URI`. If the file is not executable it will be passed to `sh`. Otherwise it's executed as is. [Shebangs](https://en.wikipedia.org/wiki/Shebang_(Unix)) known to work are `#!/bin/sh` and `#!/usr/bin/env python` | false | - | string | | `ERROR_THROTTLE_SLEEP` | How many seconds to wait before watching resources again when an error occurs | false | `5` | integer | | `SKIP_TLS_VERIFY` | Set to `true` to skip tls verification for kube api calls | false | - | boolean | diff --git a/src/helpers.py b/src/helpers.py index e2829632..f6081570 100755 --- a/src/helpers.py +++ b/src/helpers.py @@ -134,12 +134,16 @@ def request(url, method, enable_5xx=False, payload=None): if url is None: logger.warning(f"No url provided. Doing nothing.") return - + client_cert, client_key = get_client_cert_and_key_paths() + if client_cert and client_key: + cert = (client_cert, client_key) + else: + cert = None # If method is not provided use GET as default if method == "GET" or not method: - res = r.get("%s" % url, auth=auth, timeout=REQ_TIMEOUT, verify=REQ_TLS_VERIFY) + res = r.get("%s" % url, cert=cert, auth=auth, timeout=REQ_TIMEOUT, verify=REQ_TLS_VERIFY) elif method == "POST": - res = r.post("%s" % url, auth=auth, json=payload, timeout=REQ_TIMEOUT, verify=REQ_TLS_VERIFY) + res = r.post("%s" % url, cert=cert, auth=auth, json=payload, timeout=REQ_TIMEOUT, verify=REQ_TLS_VERIFY) else: logger.warning(f"Invalid REQ_METHOD: '{method}', please use 'GET' or 'POST'. Doing nothing.") return @@ -185,3 +189,9 @@ def execute(script_path): logger.debug(f"Script exit code: {result.returncode}") except subprocess.CalledProcessError as e: logger.error(f"Script failed with error: {e}") + + +def get_client_cert_and_key_paths(): + client_cert = os.getenv("REQ_CLIENT_CERT") + client_key = os.getenv("REQ_CLIENT_KEY") + return client_cert, client_key