diff --git a/.github/workflows/build_and_test.yaml b/.github/workflows/build_and_test.yaml index b402f42..7751414 100644 --- a/.github/workflows/build_and_test.yaml +++ b/.github/workflows/build_and_test.yaml @@ -97,6 +97,8 @@ jobs: kubectl cp sidecar:/tmp/absolute/absolute.txt /tmp/absolute.txt kubectl cp sidecar:/tmp/relative/relative.txt /tmp/relative.txt kubectl cp sidecar:/tmp/500.txt /tmp/500.txt || true + kubectl cp sidecar:/tmp/command-output.txt /tmp/command-output.txt + kubectl cp sidecar:/tmp/hostname.txt /tmp/hostname.txt echo "Downloading resource files from sidecar-5xx..." kubectl cp sidecar-5xx:/tmp-5xx/hello.world /tmp/5xx/hello.world @@ -119,6 +121,8 @@ jobs: echo -n "This absolutely exists" | diff - /tmp/absolute.txt && echo -n "This relatively exists" | diff - /tmp/relative.txt && [ ! -f /tmp/500.txt ] && echo "No 5xx file created" && + echo -n "This generated by script" | diff - /tmp/command-output.txt && + echo "sidecar" | diff - /tmp/hostname.txt && ls /tmp/script_result && echo -n "Hello World!" | diff - /tmp/5xx/hello.world && diff test/kubelogo.png /tmp/5xx/cm-kubelogo.png && diff --git a/README.md b/README.md index fdf4dcd..faf7a6a 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Both are identical multi-arch images built for `amd64`, `arm64`, `arm/v7`, `ppc6 - Update/Delete on change of configmap or secret - Enforce unique filenames -# Usage +# Usage Example for a simple deployment can be found in [`example.yaml`](./example.yaml). Depending on the cluster setup you have to grant yourself admin rights first: ```shell @@ -48,6 +48,7 @@ metadata: ``` 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 `.command` suffix, the content will be processed as a shell command which will be executed. Stdout of the command will be stored in the file. ## Configuration Environment Variables diff --git a/example.yaml b/example.yaml index 278c782..21410e5 100644 --- a/example.yaml +++ b/example.yaml @@ -71,6 +71,19 @@ data: # base64 encoded: my super cool \n multiline \ secret secret.world: bXkgc3VwZXIgY29vbAptdWx0aWxpbmUKc2VjcmV0 --- +apiVersion: v1 +kind: ConfigMap +metadata: + name: output-of-command + labels: + findme: "yup" +data: + rand.sh: | + #!/bin/sh + dd if=/dev/random bs=4 count=1 | hexdump -v -e '/1 "%02X"' + random.txt.command: '/tmp/rand.sh' + hostname.txt.command: '/bin/hostname' +--- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -97,4 +110,3 @@ subjects: - kind: ServiceAccount name: sample-acc namespace: default - diff --git a/src/helpers.py b/src/helpers.py index 4155dbf..78adb44 100755 --- a/src/helpers.py +++ b/src/helpers.py @@ -158,11 +158,13 @@ def unique_filename(filename, namespace, resource, resource_name): def execute(script_path): logger.debug(f"Executing script from {script_path}") try: - result = subprocess.run(["sh", script_path], + result = subprocess.run(script_path, shell=True, capture_output=True, - check=True) + check=True, + text=True) logger.debug(f"Script stdout: {result.stdout}") logger.debug(f"Script stderr: {result.stderr}") logger.debug(f"Script exit code: {result.returncode}") except subprocess.CalledProcessError as e: logger.error(f"Script failed with error: {e}") + return result diff --git a/src/resources.py b/src/resources.py index 3da08ac..da2945d 100755 --- a/src/resources.py +++ b/src/resources.py @@ -43,15 +43,18 @@ def signal_handler(signum, frame): signal.signal(signal.SIGTERM, signal_handler) -def _get_file_data_and_name(full_filename, content, enable_5xx, content_type=CONTENT_TYPE_TEXT): +def _get_file_data_and_name(full_filename, content, enable_5xx, content_type=CONTENT_TYPE_TEXT, remove=False): if content_type == CONTENT_TYPE_BASE64_BINARY: file_data = base64.b64decode(content) else: file_data = content - if full_filename.endswith(".url"): + if full_filename.endswith(".url") and not remove: filename = full_filename[:-4] file_data = request(file_data, "GET", enable_5xx).text + elif full_filename.endswith(".command") and not remove: + filename = full_filename[:-8] + file_data = execute(file_data).stdout else: filename = full_filename @@ -187,7 +190,8 @@ def _update_file(data_key, data_content, dest_folder, metadata, resource, filename, file_data = _get_file_data_and_name(data_key, data_content, enable_5xx, - content_type) + content_type, + remove) if unique_filenames: filename = unique_filename(filename=filename, namespace=metadata.namespace, diff --git a/test/resources/resources.yaml b/test/resources/resources.yaml index ee621cc..241f185 100644 --- a/test/resources/resources.yaml +++ b/test/resources/resources.yaml @@ -51,3 +51,16 @@ metadata: findme: "yup" data: 500.txt.url: "http://dummy-server/500" +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: command-configmap + labels: + findme: "yup" +data: + script.sh: |- + #!/bin/sh + echo -n "This generated by script" + command-output.txt.command: '/tmp/script.sh' + hostname.txt.command: '/bin/hostname'