From 1f7655dd03243d48de309a1d2d38ef1e093b2aba Mon Sep 17 00:00:00 2001 From: Jan Salapatek Date: Thu, 2 Jun 2022 20:27:06 +0200 Subject: [PATCH 01/13] initial untested commit for token based auth --- README.md | 7 ++++--- src/helpers.py | 17 ++++++++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index fdf4dcd3..42ebd5a2 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ metadata: k8s-sidecar-target-directory: "/path/to/target/directory" ``` -If the filename ends with `.url` suffix, the content will be processed as a URL which the target file contents will be downloaded from. +If the filename ends with `.url` suffix, the content will be processed as a URL which the target file contents will be downloaded from. If the source requires authentication, currently http basic-auth and header based token authentication are supported. Please see the variables below for details. ## Configuration Environment Variables @@ -69,9 +69,10 @@ If the filename ends with `.url` suffix, the content will be processed as a URL | `REQ_RETRY_READ` | How many times to retry on read errors for any http request (`.url` triggered requests, requests to `REQ_URI` and k8s api requests) | false | `5` | integer | | `REQ_RETRY_BACKOFF_FACTOR` | A backoff factor to apply between attempts after the second try for any http request (`.url` triggered requests, requests to `REQ_URI` and k8s api requests) | false | `1.1` | float | | `REQ_TIMEOUT` | How many seconds to wait for the server to send data before giving up for `.url` triggered requests or requests to `REQ_URI` (does not apply to k8s api requests) | false | `10` | float | +| `REQ_TOKEN_KEY` | Key of the header key/value pair presented in the http header for token based authentication for requests to `REQ_URL` and for `*.url` triggered requests. If `REQ_TOKEN_VALUE` is set and `REQ_TOKEN_KEY` is not, it defaults to `private-token`. | false | - | string | +| `REQ_TOKEN_VALUE` | Value of the key/value pair presented in the header pair for token based authentication for requests to `REQ_URL` and for `*.url` triggered requests. If configured it takes precedence over eventually also configured basic-auth credentials (`REQ_USERNAME`/`REQ_PASSWORD`) | false | - | string | | `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 | -| `SCRIPT` | Absolute path to shell script to execute after a configmap got reloaded. It runs before calls to `REQ_URI` | false | - | string | +| `REQ_PASSWORD` | Password to use for basic authentication for requests to `REQ_URL` and for `*.url` triggered requests | false | - | string || `SCRIPT` | Absolute path to shell script to execute after a configmap got reloaded. It runs before calls to `REQ_URI` | 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 | | `UNIQUE_FILENAMES` | Set to true to produce unique filenames where duplicate data keys exist between ConfigMaps and/or Secrets within the same or multiple Namespaces. | false | `false` | boolean | diff --git a/src/helpers.py b/src/helpers.py index 4155dbf3..58ed73d9 100755 --- a/src/helpers.py +++ b/src/helpers.py @@ -102,10 +102,21 @@ def request(url, method, enable_5xx=False, payload=None): username = os.getenv("REQ_USERNAME") password = os.getenv("REQ_PASSWORD") - if username and password: + req_token_name = os.getenv("REQ_TOKEN_KEY") + req_token_value = os.getenv("REQ_TOKEN_VALUE") + + if req_token_value and not req_token_name: + req_token_name = "private-token" + + if req_token_name and req_token_value: + auth = None + headers= { req_token_name, req_token_value } + elif username and password: auth = (username, password) + headers= None else: auth = None + headers= None r = requests.Session() @@ -123,9 +134,9 @@ def request(url, method, enable_5xx=False, payload=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) + res = r.get("%s" % url, auth=auth, headers=headers, timeout=REQ_TIMEOUT) elif method == "POST": - res = r.post("%s" % url, auth=auth, json=payload, timeout=REQ_TIMEOUT) + res = r.post("%s" % url, auth=auth, headers=headers, json=payload, timeout=REQ_TIMEOUT) else: logger.warning(f"Invalid REQ_METHOD: '{method}', please use 'GET' or 'POST'. Doing nothing.") return From 6a278b8584c14ba6060abc1b35e73a9ad9c98d53 Mon Sep 17 00:00:00 2001 From: Jan Salapatek Date: Tue, 7 Jun 2022 17:36:06 +0200 Subject: [PATCH 02/13] Switched from headers to params approach. Cleanup. --- .gitignore | 2 ++ README.md | 4 ++-- example.yaml | 16 ++++++++++++++++ src/helpers.py | 30 +++++++++++++++++++++--------- 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index f10a4fa5..299c2a0c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ *.iml .idea/ venv +.vscode/ +__pycache__ \ No newline at end of file diff --git a/README.md b/README.md index 42ebd5a2..eaacf96d 100644 --- a/README.md +++ b/README.md @@ -69,8 +69,8 @@ If the filename ends with `.url` suffix, the content will be processed as a URL | `REQ_RETRY_READ` | How many times to retry on read errors for any http request (`.url` triggered requests, requests to `REQ_URI` and k8s api requests) | false | `5` | integer | | `REQ_RETRY_BACKOFF_FACTOR` | A backoff factor to apply between attempts after the second try for any http request (`.url` triggered requests, requests to `REQ_URI` and k8s api requests) | false | `1.1` | float | | `REQ_TIMEOUT` | How many seconds to wait for the server to send data before giving up for `.url` triggered requests or requests to `REQ_URI` (does not apply to k8s api requests) | false | `10` | float | -| `REQ_TOKEN_KEY` | Key of the header key/value pair presented in the http header for token based authentication for requests to `REQ_URL` and for `*.url` triggered requests. If `REQ_TOKEN_VALUE` is set and `REQ_TOKEN_KEY` is not, it defaults to `private-token`. | false | - | string | -| `REQ_TOKEN_VALUE` | Value of the key/value pair presented in the header pair for token based authentication for requests to `REQ_URL` and for `*.url` triggered requests. If configured it takes precedence over eventually also configured basic-auth credentials (`REQ_USERNAME`/`REQ_PASSWORD`) | false | - | string | +| `REQ_TOKEN_KEY` | Key of the key/value pair passed as parameter within the url for token based authentication for requests to `REQ_URL` and for `*.url` triggered requests. If `REQ_TOKEN_VALUE` is set and `REQ_TOKEN_KEY` is not, it defaults to "`private_token`". | false | - | string | +| `REQ_TOKEN_VALUE` | Value of the key/value pair passed as parameter within the url for token based authentication for requests to `REQ_URL` and for `*.url` triggered requests. If configured it takes precedence over eventually also configured basic-auth credentials (`REQ_USERNAME`/`REQ_PASSWORD`) | false | - | string | | `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 || `SCRIPT` | Absolute path to shell script to execute after a configmap got reloaded. It runs before calls to `REQ_URI` | false | - | string | | `ERROR_THROTTLE_SLEEP` | How many seconds to wait before watching resources again when an error occurs | false | `5` | integer | diff --git a/example.yaml b/example.yaml index 278c7828..560c492f 100644 --- a/example.yaml +++ b/example.yaml @@ -28,6 +28,10 @@ spec: volumeMounts: - name: shared-volume mountPath: /tmp/ + # Only relevant for token based auth (like with git) +# envFrom: +# - secretRef: +# name: token-auth-sample-secret env: - name: LABEL value: "findme" @@ -71,6 +75,18 @@ data: # base64 encoded: my super cool \n multiline \ secret secret.world: bXkgc3VwZXIgY29vbAptdWx0aWxpbmUKc2VjcmV0 --- +# This secret is only necessary for token based authentication of http requests. +# Refer to README.md for details on the two parameters REQ_TOKEN_KEY and REQ_TOKEN_VALUE +apiVersion: v1 +kind: Secret +metadata: + name: token-auth-sample-secret +type: Opaque +data: + #REQ_TOKEN_KEY: private_token + # base64 encoded super-duper-secret authentication token + REQ_TOKEN_VALUE: c3VwZXItZHVwZXItc2VjcmV0 +--- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/src/helpers.py b/src/helpers.py index 58ed73d9..9027dbe4 100755 --- a/src/helpers.py +++ b/src/helpers.py @@ -102,21 +102,33 @@ def request(url, method, enable_5xx=False, payload=None): username = os.getenv("REQ_USERNAME") password = os.getenv("REQ_PASSWORD") - req_token_name = os.getenv("REQ_TOKEN_KEY") + req_token_key = os.getenv("REQ_TOKEN_KEY") req_token_value = os.getenv("REQ_TOKEN_VALUE") + params=dict() - if req_token_value and not req_token_name: - req_token_name = "private-token" + if req_token_value and not req_token_key: + req_token_key = "private_token" + logger.info(f"Request token value is set, but key is not. Setting request token key to default value {req_token_key}.") - if req_token_name and req_token_value: + if req_token_key and req_token_value: auth = None - headers= { req_token_name, req_token_value } + params[ str(req_token_key) ] = req_token_value + logger.info(f"Token based authorization configured. Token key: {req_token_key}.") + logger.debug(f"Token value {params[str(req_token_key)]}.") elif username and password: auth = (username, password) - headers= None + params = None + logger.info(f"Basic-auth configured. username: {username}.") + logger.debug(f"Basic-auth configured. password: {password}.") else: + logger.info(f"No authorization tokens set (no basic-auth and no private token).") auth = None - headers= None + params = None + + if params: + logger.debug(f"Request params are set as follows: {params}") + else: + logger.info(f"No request params are set.") r = requests.Session() @@ -134,9 +146,9 @@ def request(url, method, enable_5xx=False, payload=None): # If method is not provided use GET as default if method == "GET" or not method: - res = r.get("%s" % url, auth=auth, headers=headers, timeout=REQ_TIMEOUT) + res = r.get("%s" % url, auth=auth, params=params, timeout=REQ_TIMEOUT) elif method == "POST": - res = r.post("%s" % url, auth=auth, headers=headers, json=payload, timeout=REQ_TIMEOUT) + res = r.post("%s" % url, auth=auth, params=params, json=payload, timeout=REQ_TIMEOUT) else: logger.warning(f"Invalid REQ_METHOD: '{method}', please use 'GET' or 'POST'. Doing nothing.") return From 77ba05ff4a7feaf91b3fd8969f544b5543f88b75 Mon Sep 17 00:00:00 2001 From: Jan Salapatek <86241291+jansalapatek@users.noreply.github.com> Date: Fri, 10 Jun 2022 09:17:47 +0200 Subject: [PATCH 03/13] Update README.md Fixed description on auth mechanism --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eaacf96d..c087e73b 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ metadata: k8s-sidecar-target-directory: "/path/to/target/directory" ``` -If the filename ends with `.url` suffix, the content will be processed as a URL which the target file contents will be downloaded from. If the source requires authentication, currently http basic-auth and header based token authentication are supported. Please see the variables below for details. +If the filename ends with `.url` suffix, the content will be processed as a URL which the target file contents will be downloaded from. If the source requires authentication, currently http basic-auth and token based authentication via query param are supported. Please see the variables below for details. ## Configuration Environment Variables From 29e34113742feee82ccdb490a129737d04bb9f02 Mon Sep 17 00:00:00 2001 From: Jan Salapatek <86241291+jansalapatek@users.noreply.github.com> Date: Fri, 10 Jun 2022 09:20:32 +0200 Subject: [PATCH 04/13] Update README.md fixed linebreak --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c087e73b..38d3a560 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,8 @@ If the filename ends with `.url` suffix, the content will be processed as a URL | `REQ_TOKEN_KEY` | Key of the key/value pair passed as parameter within the url for token based authentication for requests to `REQ_URL` and for `*.url` triggered requests. If `REQ_TOKEN_VALUE` is set and `REQ_TOKEN_KEY` is not, it defaults to "`private_token`". | false | - | string | | `REQ_TOKEN_VALUE` | Value of the key/value pair passed as parameter within the url for token based authentication for requests to `REQ_URL` and for `*.url` triggered requests. If configured it takes precedence over eventually also configured basic-auth credentials (`REQ_USERNAME`/`REQ_PASSWORD`) | false | - | string | | `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 || `SCRIPT` | Absolute path to shell script to execute after a configmap got reloaded. It runs before calls to `REQ_URI` | false | - | string | +| `REQ_PASSWORD` | Password to use for basic authentication for requests to `REQ_URL` and for `*.url` triggered requests | false | - | string | +| `SCRIPT` | Absolute path to shell script to execute after a configmap got reloaded. It runs before calls to `REQ_URI` | 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 | | `UNIQUE_FILENAMES` | Set to true to produce unique filenames where duplicate data keys exist between ConfigMaps and/or Secrets within the same or multiple Namespaces. | false | `false` | boolean | From 702670e8418fc0163b3bc404acb4b86c38d9932b Mon Sep 17 00:00:00 2001 From: Jan Salapatek Date: Mon, 13 Jun 2022 16:01:44 +0200 Subject: [PATCH 05/13] minor adjustments on logging. --- src/helpers.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/helpers.py b/src/helpers.py index 9027dbe4..331bbe75 100755 --- a/src/helpers.py +++ b/src/helpers.py @@ -113,23 +113,16 @@ def request(url, method, enable_5xx=False, payload=None): if req_token_key and req_token_value: auth = None params[ str(req_token_key) ] = req_token_value - logger.info(f"Token based authorization configured. Token key: {req_token_key}.") - logger.debug(f"Token value {params[str(req_token_key)]}.") + logger.debug(f"Token based authorization configured. Token key: {req_token_key}.") elif username and password: auth = (username, password) params = None - logger.info(f"Basic-auth configured. username: {username}.") - logger.debug(f"Basic-auth configured. password: {password}.") + logger.debug(f"Basic-auth configured. username: {username}.") else: - logger.info(f"No authorization tokens set (no basic-auth and no private token).") + logger.debug(f"No authorization tokens set (no basic-auth and no private token).") auth = None params = None - if params: - logger.debug(f"Request params are set as follows: {params}") - else: - logger.info(f"No request params are set.") - r = requests.Session() retries = Retry(total=REQ_RETRY_TOTAL, From d1da522fd8dac2617f0364f95c26f82bff9d6421 Mon Sep 17 00:00:00 2001 From: Jan Salapatek Date: Mon, 13 Jun 2022 22:55:25 +0200 Subject: [PATCH 06/13] first commit for test wit api key. --- .github/workflows/build_and_test.yaml | 9 +++++- test/resources/resources.yaml | 9 ++++++ test/resources/sidecar.yaml | 45 +++++++++++++++++++++++++++ test/server/server.py | 21 +++++++++++-- 4 files changed, 81 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml index cda2e8ff..313d51d6 100644 --- a/.github/workflows/build_and_test.yaml +++ b/.github/workflows/build_and_test.yaml @@ -68,6 +68,7 @@ jobs: wait_for_pod_ready "sidecar" wait_for_pod_ready "sidecar-5xx" + wait_for_pod_ready "sidecar-api_key" wait_for_pod_ready "dummy-server-pod" - name: Install Configmaps and Secrets @@ -80,6 +81,7 @@ jobs: - name: Retrieve pod logs run: | kubectl logs sidecar > /tmp/sidecar.log + kubectl logs sidecar > /tmp/sidecar-api_key.log kubectl logs sidecar-5xx > /tmp/sidecar-5xx.log kubectl logs dummy-server-pod > /tmp/dummy-server.log - name: Upload artifacts @@ -109,6 +111,9 @@ jobs: kubectl cp sidecar-5xx:/tmp-5xx/relative/relative.txt /tmp/5xx/relative.txt kubectl cp sidecar-5xx:/tmp-5xx/500.txt /tmp/5xx/500.txt + echo "Downloading resource files from sidecar-api_key..." + kubectl cp sidecar-api_key:/tmp/api_key.txt /tmp/api-key/api_key.txt || true + - name: Verify files run: | echo "Verifying file content from sidecar and sidecar-5xx ..." @@ -126,4 +131,6 @@ jobs: echo -n "This absolutely exists" | diff - /tmp/5xx/absolute.txt && echo -n "This relatively exists" | diff - /tmp/5xx/relative.txt && echo -n "500" | diff - /tmp/5xx/500.txt && - ls /tmp/5xx/script_result + ls /tmp/5xx/script_result && + [ -f /tmp/api-key/api_key.txt ] && echo "api_key used for aouthentication" + diff --git a/test/resources/resources.yaml b/test/resources/resources.yaml index ee621ccf..0f39bb01 100644 --- a/test/resources/resources.yaml +++ b/test/resources/resources.yaml @@ -51,3 +51,12 @@ metadata: findme: "yup" data: 500.txt.url: "http://dummy-server/500" +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: url-configmap-api_key + labels: + findme: "sure" +data: + api_key.txt.url: "http://dummy-server/200/api_key" diff --git a/test/resources/sidecar.yaml b/test/resources/sidecar.yaml index f2f75430..35fc7b2a 100644 --- a/test/resources/sidecar.yaml +++ b/test/resources/sidecar.yaml @@ -105,6 +105,51 @@ spec: defaultMode: 0777 --- apiVersion: v1 +kind: Secret +metadata: + name: token-auth-sample-secret +type: Opaque +data: + REQ_TOKEN_KEY: private_token + REQ_TOKEN_VALUE: c3VwZXItZHVwZXItc2VjcmV0 +--- +apiVersion: v1 +kind: Pod +metadata: + name: sidecar-api_key + namespace: default +spec: + serviceAccountName: sample-acc + containers: + - name: sidecar + image: kiwigrid/k8s-sidecar:testing + volumeMounts: + - name: shared-volume + mountPath: /tmp/ + - name: script-volume + mountPath: /opt/script.sh + subPath: script.sh + envFrom: + - secretRef: + name: token-auth-sample-secret + env: + - name: LABEL + value: "findme" + - name: FOLDER + value: /tmp/ + - name: RESOURCE + value: both + - name: SCRIPT + value: "/opt/script.sh" + volumes: + - name: shared-volume + emptyDir: {} + - name: script-volume + configMap: + name: script-configmap + defaultMode: 0777 +--- +apiVersion: v1 kind: Pod metadata: name: dummy-server-pod diff --git a/test/server/server.py b/test/server/server.py index 29f198e6..eb033061 100644 --- a/test/server/server.py +++ b/test/server/server.py @@ -1,8 +1,19 @@ -from fastapi import FastAPI -import uvicorn +#from http.client import HTTPException, HTTPResponse +from fastapi import FastAPI, Security, Depends, HTTPException +from fastapi.security.api_key import APIKeyQuery, APIKey +#import uvicorn + +API_KEY_NAME="private_token" +API_KEY="super-duper-secret" +api_key_query = APIKeyQuery(name=API_KEY_NAME, auto_error=True) app = FastAPI() +def get_api_key (api_key_query: str = Security(api_key_query)): + if api_key_query == API_KEY: + return api_key_query + else: + raise HTTPException(403) @app.get("/", status_code=200) def read_root(): @@ -27,3 +38,9 @@ async def read_item(): @app.post("/503", status_code=503) async def read_item(): return 503 + + +@app.get("/200/api_key") +def read_root(api_key: APIKey = Depends(get_api_key)): + return 200 + \ No newline at end of file From 347808abce50bf6628e5ca1cef9c1381046cf0ec Mon Sep 17 00:00:00 2001 From: Jan Salapatek Date: Tue, 14 Jun 2022 11:43:21 +0200 Subject: [PATCH 07/13] fixed resource naming, added negative test. --- .github/workflows/build_and_test.yaml | 20 +++++++---- test/resources/resources.yaml | 4 +-- test/resources/sidecar.yaml | 51 +++++++++++++++++++++------ test/server/server.py | 3 +- 4 files changed, 56 insertions(+), 22 deletions(-) diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml index 313d51d6..394f2524 100644 --- a/.github/workflows/build_and_test.yaml +++ b/.github/workflows/build_and_test.yaml @@ -68,7 +68,8 @@ jobs: wait_for_pod_ready "sidecar" wait_for_pod_ready "sidecar-5xx" - wait_for_pod_ready "sidecar-api_key" + wait_for_pod_ready "sidecar-api-key" + wait_for_pod_ready "sidecar-api-key-fails" wait_for_pod_ready "dummy-server-pod" - name: Install Configmaps and Secrets @@ -81,8 +82,9 @@ jobs: - name: Retrieve pod logs run: | kubectl logs sidecar > /tmp/sidecar.log - kubectl logs sidecar > /tmp/sidecar-api_key.log kubectl logs sidecar-5xx > /tmp/sidecar-5xx.log + kubectl logs sidecar-api-key > /tmp/sidecar-api-key.log + kubectl logs sidecar-api-key-fails > /tmp/sidecar-api-key-fails.log kubectl logs dummy-server-pod > /tmp/dummy-server.log - name: Upload artifacts uses: actions/upload-artifact@v3 @@ -111,12 +113,15 @@ jobs: kubectl cp sidecar-5xx:/tmp-5xx/relative/relative.txt /tmp/5xx/relative.txt kubectl cp sidecar-5xx:/tmp-5xx/500.txt /tmp/5xx/500.txt - echo "Downloading resource files from sidecar-api_key..." - kubectl cp sidecar-api_key:/tmp/api_key.txt /tmp/api-key/api_key.txt || true + echo "Downloading resource files from sidecar-api-key..." + kubectl cp sidecar-api-key:/tmp/api-key.txt /tmp/api-key/api-key.txt || true + + echo "Downloading resource files from sidecar-api-key-fails..." + kubectl cp sidecar-api-key-fails:/tmp/api-key.txt /tmp/api-key-fails/api-key.txt || true - name: Verify files run: | - echo "Verifying file content from sidecar and sidecar-5xx ..." + echo "Verifying file content from different sidecar pods ..." # this needs to be the last statement so that it defines the script exit code echo -n "Hello World!" | diff - /tmp/hello.world && diff test/kubelogo.png /tmp/cm-kubelogo.png && @@ -132,5 +137,6 @@ jobs: echo -n "This relatively exists" | diff - /tmp/5xx/relative.txt && echo -n "500" | diff - /tmp/5xx/500.txt && ls /tmp/5xx/script_result && - [ -f /tmp/api-key/api_key.txt ] && echo "api_key used for aouthentication" - + grep "200" /tmp/api-key/api-key.txt && echo "api-key used successfully for authentication" && + grep "Forbidden" /tmp/api-key-fails/api-key.txt && echo "api-key-fails expectedly with wrong credentials" + \ No newline at end of file diff --git a/test/resources/resources.yaml b/test/resources/resources.yaml index 0f39bb01..6c1080e2 100644 --- a/test/resources/resources.yaml +++ b/test/resources/resources.yaml @@ -55,8 +55,8 @@ data: apiVersion: v1 kind: ConfigMap metadata: - name: url-configmap-api_key + name: url-configmap-api-key labels: findme: "sure" data: - api_key.txt.url: "http://dummy-server/200/api_key" + api-key.txt.url: "http://dummy-server/200/api-key" \ No newline at end of file diff --git a/test/resources/sidecar.yaml b/test/resources/sidecar.yaml index 35fc7b2a..f0b2af89 100644 --- a/test/resources/sidecar.yaml +++ b/test/resources/sidecar.yaml @@ -111,12 +111,13 @@ metadata: type: Opaque data: REQ_TOKEN_KEY: private_token + #REQ_TOKEN_VALUE: base64 enc "super-duper-secret" REQ_TOKEN_VALUE: c3VwZXItZHVwZXItc2VjcmV0 --- apiVersion: v1 kind: Pod metadata: - name: sidecar-api_key + name: sidecar-api-key namespace: default spec: serviceAccountName: sample-acc @@ -126,9 +127,6 @@ spec: volumeMounts: - name: shared-volume mountPath: /tmp/ - - name: script-volume - mountPath: /opt/script.sh - subPath: script.sh envFrom: - secretRef: name: token-auth-sample-secret @@ -138,16 +136,47 @@ spec: - name: FOLDER value: /tmp/ - name: RESOURCE - value: both - - name: SCRIPT - value: "/opt/script.sh" + value: configmap + volumes: + - name: shared-volume + emptyDir: {} +--- +apiVersion: v1 +kind: Secret +metadata: + name: token-auth-sample-secret-fails +type: Opaque +data: + REQ_TOKEN_KEY: private_token + #REQ_TOKEN_VALUE base64 enc "I-will-fail" + REQ_TOKEN_VALUE: SS13aWxsLWZhaWw= +--- +apiVersion: v1 +kind: Pod +metadata: + name: sidecar-api-key-fails + namespace: default +spec: + serviceAccountName: sample-acc + containers: + - name: sidecar + image: kiwigrid/k8s-sidecar:testing + volumeMounts: + - name: shared-volume + mountPath: /tmp/ + envFrom: + - secretRef: + name: token-auth-sample-secret-fails + env: + - name: LABEL + value: "findme" + - name: FOLDER + value: /tmp/ + - name: RESOURCE + value: configmap volumes: - name: shared-volume emptyDir: {} - - name: script-volume - configMap: - name: script-configmap - defaultMode: 0777 --- apiVersion: v1 kind: Pod diff --git a/test/server/server.py b/test/server/server.py index eb033061..cfb02556 100644 --- a/test/server/server.py +++ b/test/server/server.py @@ -40,7 +40,6 @@ async def read_item(): return 503 -@app.get("/200/api_key") +@app.get("/200/api-key") def read_root(api_key: APIKey = Depends(get_api_key)): return 200 - \ No newline at end of file From 8335cedb1af0123ea9a5a3c6bd8b269fc5ead9e1 Mon Sep 17 00:00:00 2001 From: Jan Salapatek Date: Tue, 14 Jun 2022 13:14:07 +0200 Subject: [PATCH 08/13] fixed secret base enc. rem. superfl. imports. --- test/resources/sidecar.yaml | 4 ++-- test/server/server.py | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/test/resources/sidecar.yaml b/test/resources/sidecar.yaml index f0b2af89..602fdcfd 100644 --- a/test/resources/sidecar.yaml +++ b/test/resources/sidecar.yaml @@ -110,7 +110,7 @@ metadata: name: token-auth-sample-secret type: Opaque data: - REQ_TOKEN_KEY: private_token + REQ_TOKEN_KEY: cHJpdmF0ZV90b2tlbg== #REQ_TOKEN_VALUE: base64 enc "super-duper-secret" REQ_TOKEN_VALUE: c3VwZXItZHVwZXItc2VjcmV0 --- @@ -147,7 +147,7 @@ metadata: name: token-auth-sample-secret-fails type: Opaque data: - REQ_TOKEN_KEY: private_token + REQ_TOKEN_KEY: cHJpdmF0ZV90b2tlbg== #REQ_TOKEN_VALUE base64 enc "I-will-fail" REQ_TOKEN_VALUE: SS13aWxsLWZhaWw= --- diff --git a/test/server/server.py b/test/server/server.py index cfb02556..22b9a77d 100644 --- a/test/server/server.py +++ b/test/server/server.py @@ -1,7 +1,5 @@ -#from http.client import HTTPException, HTTPResponse from fastapi import FastAPI, Security, Depends, HTTPException from fastapi.security.api_key import APIKeyQuery, APIKey -#import uvicorn API_KEY_NAME="private_token" API_KEY="super-duper-secret" From 953483a7389619cb9c555743096cbaf80943820b Mon Sep 17 00:00:00 2001 From: Jan Salapatek Date: Tue, 14 Jun 2022 13:43:17 +0200 Subject: [PATCH 09/13] added api-key.txt file to server for download. --- .github/workflows/build_and_test.yaml | 4 ++-- test/resources/resources.yaml | 2 +- test/server/Dockerfile | 1 + test/server/api-key.txt | 1 + test/server/server.py | 6 ++++-- 5 files changed, 9 insertions(+), 5 deletions(-) create mode 100644 test/server/api-key.txt diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml index 394f2524..4037e831 100644 --- a/.github/workflows/build_and_test.yaml +++ b/.github/workflows/build_and_test.yaml @@ -137,6 +137,6 @@ jobs: echo -n "This relatively exists" | diff - /tmp/5xx/relative.txt && echo -n "500" | diff - /tmp/5xx/500.txt && ls /tmp/5xx/script_result && - grep "200" /tmp/api-key/api-key.txt && echo "api-key used successfully for authentication" && - grep "Forbidden" /tmp/api-key-fails/api-key.txt && echo "api-key-fails expectedly with wrong credentials" + grep -i "success" /tmp/api-key/api-key.txt && echo "api-key used successfully for authentication" && + [ ! -f /tmp/api-key-fails/api-key.txt ] && echo "api-key-fails expectedly with wrong credentials" \ No newline at end of file diff --git a/test/resources/resources.yaml b/test/resources/resources.yaml index 6c1080e2..608804f4 100644 --- a/test/resources/resources.yaml +++ b/test/resources/resources.yaml @@ -59,4 +59,4 @@ metadata: labels: findme: "sure" data: - api-key.txt.url: "http://dummy-server/200/api-key" \ No newline at end of file + api-key.txt.url: "http://dummy-server/200/api-key.txt" \ No newline at end of file diff --git a/test/server/Dockerfile b/test/server/Dockerfile index 1992415a..b1f9e8f5 100644 --- a/test/server/Dockerfile +++ b/test/server/Dockerfile @@ -2,4 +2,5 @@ FROM python:3.9-alpine RUN pip install fastapi uvicorn EXPOSE 80 COPY server.py /server.py +COPY api-key.txt /api-key.txt CMD ["uvicorn", "server:app", "--host", "0.0.0.0", "--port", "80"] diff --git a/test/server/api-key.txt b/test/server/api-key.txt new file mode 100644 index 00000000..caaa5e19 --- /dev/null +++ b/test/server/api-key.txt @@ -0,0 +1 @@ +Success! I can only be downloaded with the correct combination of API Key and password! \ No newline at end of file diff --git a/test/server/server.py b/test/server/server.py index 22b9a77d..60903f5f 100644 --- a/test/server/server.py +++ b/test/server/server.py @@ -1,5 +1,7 @@ from fastapi import FastAPI, Security, Depends, HTTPException from fastapi.security.api_key import APIKeyQuery, APIKey +from fastapi.responses import FileResponse + API_KEY_NAME="private_token" API_KEY="super-duper-secret" @@ -38,6 +40,6 @@ async def read_item(): return 503 -@app.get("/200/api-key") +@app.get("/200/api-key.txt", response_class=FileResponse) def read_root(api_key: APIKey = Depends(get_api_key)): - return 200 + return "api-key.txt" From 77de590c7f15b1058344c1dbc96aa9d192cd5919 Mon Sep 17 00:00:00 2001 From: Jan Salapatek Date: Mon, 4 Jul 2022 15:05:21 +0200 Subject: [PATCH 10/13] added debug --- .github/workflows/build_and_test.yaml | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml index 4037e831..2e0c6ff9 100644 --- a/.github/workflows/build_and_test.yaml +++ b/.github/workflows/build_and_test.yaml @@ -114,11 +114,21 @@ jobs: kubectl cp sidecar-5xx:/tmp-5xx/500.txt /tmp/5xx/500.txt echo "Downloading resource files from sidecar-api-key..." - kubectl cp sidecar-api-key:/tmp/api-key.txt /tmp/api-key/api-key.txt || true + kubectl cp sidecar-api-key:/tmp/api-key.txt /tmp/sidecar-api-key/api-key.txt || true echo "Downloading resource files from sidecar-api-key-fails..." - kubectl cp sidecar-api-key-fails:/tmp/api-key.txt /tmp/api-key-fails/api-key.txt || true - + kubectl cp sidecar-api-key-fails:/tmp/api-key.txt /tmp/sidecar-api-key-fails/api-key.txt || true + - name: DEBUG + run: | + echo "#############################################################" + echo "#############################################################" + echo "#############################################################" + kubectl logs sidecar-api-key + ls -la /tmp/ + ls -la /tmp/api-key/ + echo "#############################################################" + echo "#############################################################" + echo "#############################################################" - name: Verify files run: | echo "Verifying file content from different sidecar pods ..." @@ -137,6 +147,6 @@ jobs: echo -n "This relatively exists" | diff - /tmp/5xx/relative.txt && echo -n "500" | diff - /tmp/5xx/500.txt && ls /tmp/5xx/script_result && - grep -i "success" /tmp/api-key/api-key.txt && echo "api-key used successfully for authentication" && - [ ! -f /tmp/api-key-fails/api-key.txt ] && echo "api-key-fails expectedly with wrong credentials" + grep -i "success" /tmp/sidecar-api-key/api-key.txt && echo "api-key used successfully for authentication" && + [ ! -f /tmp/sidecar-api-key-fails/api-key.txt ] && echo "api-key fails expectedly with wrong credentials" \ No newline at end of file From 41e907ca67f41cafa2403f26ef691758e6c036d1 Mon Sep 17 00:00:00 2001 From: Jan Salapatek Date: Mon, 4 Jul 2022 15:15:40 +0200 Subject: [PATCH 11/13] . --- .github/workflows/build_and_test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml index 2e0c6ff9..0c882e0c 100644 --- a/.github/workflows/build_and_test.yaml +++ b/.github/workflows/build_and_test.yaml @@ -125,7 +125,7 @@ jobs: echo "#############################################################" kubectl logs sidecar-api-key ls -la /tmp/ - ls -la /tmp/api-key/ + ls -la /tmp/*api-key*/ echo "#############################################################" echo "#############################################################" echo "#############################################################" From 27488a90b037f2e6295bc7fc84dbeaff5b17fce2 Mon Sep 17 00:00:00 2001 From: Jan Salapatek Date: Tue, 5 Jul 2022 10:12:30 +0200 Subject: [PATCH 12/13] minor changes to directories of test. --- .github/workflows/build_and_test.yaml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml index 0c882e0c..0d5604af 100644 --- a/.github/workflows/build_and_test.yaml +++ b/.github/workflows/build_and_test.yaml @@ -114,10 +114,10 @@ jobs: kubectl cp sidecar-5xx:/tmp-5xx/500.txt /tmp/5xx/500.txt echo "Downloading resource files from sidecar-api-key..." - kubectl cp sidecar-api-key:/tmp/api-key.txt /tmp/sidecar-api-key/api-key.txt || true + kubectl cp sidecar-api-key:/tmp/api-key.txt /tmp/sidecar-api-key.txt || true echo "Downloading resource files from sidecar-api-key-fails..." - kubectl cp sidecar-api-key-fails:/tmp/api-key.txt /tmp/sidecar-api-key-fails/api-key.txt || true + kubectl cp sidecar-api-key-fails:/tmp/api-key.txt /tmp/sidecar-api-key-fails.txt || true - name: DEBUG run: | echo "#############################################################" @@ -125,7 +125,6 @@ jobs: echo "#############################################################" kubectl logs sidecar-api-key ls -la /tmp/ - ls -la /tmp/*api-key*/ echo "#############################################################" echo "#############################################################" echo "#############################################################" @@ -147,6 +146,6 @@ jobs: echo -n "This relatively exists" | diff - /tmp/5xx/relative.txt && echo -n "500" | diff - /tmp/5xx/500.txt && ls /tmp/5xx/script_result && - grep -i "success" /tmp/sidecar-api-key/api-key.txt && echo "api-key used successfully for authentication" && - [ ! -f /tmp/sidecar-api-key-fails/api-key.txt ] && echo "api-key fails expectedly with wrong credentials" + grep -i "success" /tmp/sidecar-api-key.txt && echo "api-key used successfully for authentication." && + [ ! -f /tmp/sidecar-api-key-fails.txt ] && echo "api-key fails expectedly with wrong credentials." \ No newline at end of file From 8cb975415a9805c24a3164b8bfe603beb1667c69 Mon Sep 17 00:00:00 2001 From: Jan Salapatek Date: Wed, 19 Oct 2022 15:03:51 +0200 Subject: [PATCH 13/13] minor improvements to check variable assignments --- src/helpers.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/helpers.py b/src/helpers.py index 331bbe75..ab41a2e4 100755 --- a/src/helpers.py +++ b/src/helpers.py @@ -100,10 +100,10 @@ def remove_file(folder, filename): def request(url, method, enable_5xx=False, payload=None): enforce_status_codes = list() if enable_5xx else [500, 502, 503, 504] - username = os.getenv("REQ_USERNAME") - password = os.getenv("REQ_PASSWORD") - req_token_key = os.getenv("REQ_TOKEN_KEY") - req_token_value = os.getenv("REQ_TOKEN_VALUE") + username = {} if os.getenv("REQ_USERNAME") is None else os.getenv("REQ_USERNAME") + password = {} if os.getenv("REQ_PASSWORD") is None else os.getenv("REQ_PASSWORD") + req_token_key = {} if os.getenv("REQ_TOKEN_KEY") is None else os.getenv("REQ_TOKEN_KEY") + req_token_value = {} if os.getenv("REQ_TOKEN_VALUE") is None else os.getenv("REQ_TOKEN_VALUE") params=dict() if req_token_value and not req_token_key: