From f6820276a018114b1042c8f559a13f0e4dfd7a30 Mon Sep 17 00:00:00 2001 From: Jake Cohen Date: Mon, 27 Feb 2023 09:44:30 -0800 Subject: [PATCH 1/9] initial commit --- contents/debug-ephemeral-container.py | 67 +++++++++++++++++++++++++++ plugin.yaml | 30 ++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 contents/debug-ephemeral-container.py diff --git a/contents/debug-ephemeral-container.py b/contents/debug-ephemeral-container.py new file mode 100644 index 0000000..b31d2f8 --- /dev/null +++ b/contents/debug-ephemeral-container.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python -u +import logging +import sys +import os +import common + +from kubernetes import client +from kubernetes.client.rest import ApiException +from kubernetes import watch + +logging.basicConfig(stream=sys.stdout, level=logging.INFO, + format='%(message)s') +log = logging.getLogger('kubernetes-model-source') + +if os.environ.get('RD_JOB_LOGLEVEL') == 'DEBUG': + log.setLevel(logging.DEBUG) + +def main(): + + common.connect() + + try: + v1 = client.CoreV1Api() + + [name, namespace, container] = common.get_core_node_parameter_list() + + if not container: + core_v1 = client.CoreV1Api() + response = core_v1.read_namespaced_pod_status( + name=name, + namespace=namespace, + pretty="True" + ) + container = response.spec.containers[0].name + + common.log_pod_parameters(log, {'name': name, 'namespace': namespace, 'container_name': container}) + common.verify_pod_exists(name, namespace) + + # add a debug container to it + spec = client.models.V1EphemeralContainer( + name="debugger", + image = "centos:7", + stdin=True, + tty=True) + body = { + "spec": { + "ephemeralContainers": [ + spec.to_dict() + ] + } + } + response = v1.patch_namespaced_pod_ephemeralcontainers( + name, + namespace, + body, + _preload_content=False) + + print(response.data) +# print("Read(): " + response.read()) + + + except ApiException: + log.exception("Exception error creating:") + sys.exit(1) + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/plugin.yaml b/plugin.yaml index 55930bc..ca35f07 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -2348,6 +2348,36 @@ providers: scope: Instance renderingOptions: groupName: Authentication + - name: Kubernetes-Ephemeral-Container + service: WorkflowNodeStep + title: Kubernetes / Pods / Debug Ephemeral Container + description: 'Add an ephemeral container to a pod for debugging.' + plugin-type: script + script-interpreter: python -u + script-file: debug-ephemeral-container.py + script-args: ${config.name} + config: + - name: name + type: String + title: "Pod Name" + required: true + description: "Name of the running pod that the ephemeral container will get attached to." + - name: namespace + type: String + title: "Namespace" + description: "Namespace where the job was created" + required: false + default: default + - name: container-name + type: String + title: "Name for Ephemeral Container" + description: "Name for the ephemeral container that will be added to the running pod." + required: false + - name: image + type: String + title: "Container Image" + description: "Image for the ephemeral container to be added to the running pod." + default: "busybox" - name: Kubernetes-InlineScript-Step service: WorkflowNodeStep title: Kubernetes / Pods / Execute Script From 6e486145692ed202a5720e2f718ec39cf22423cb Mon Sep 17 00:00:00 2001 From: Jake Cohen Date: Mon, 27 Feb 2023 10:27:56 -0800 Subject: [PATCH 2/9] removing hardcoded values --- contents/debug-ephemeral-container.py | 9 +++++++-- plugin.yaml | 7 ++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/contents/debug-ephemeral-container.py b/contents/debug-ephemeral-container.py index b31d2f8..a26ee63 100644 --- a/contents/debug-ephemeral-container.py +++ b/contents/debug-ephemeral-container.py @@ -19,6 +19,11 @@ def main(): common.connect() + print("Container image: " + os.environ.get("RD_CONFIG_CONTAINER_IMAGE")) + print("Container name: " + os.environ.get("RD_CONFIG_CONTAINER_NAME")) + container_name = os.environ.get("RD_CONFIG_CONTAINER_NAME") + container_image = os.environ.get("RD_CONFIG_CONTAINER_IMAGE") + try: v1 = client.CoreV1Api() @@ -38,8 +43,8 @@ def main(): # add a debug container to it spec = client.models.V1EphemeralContainer( - name="debugger", - image = "centos:7", + name = container_name, + image = container_image, stdin=True, tty=True) body = { diff --git a/plugin.yaml b/plugin.yaml index ca35f07..8f31525 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -2368,12 +2368,13 @@ providers: description: "Namespace where the job was created" required: false default: default - - name: container-name + - name: container_name type: String title: "Name for Ephemeral Container" description: "Name for the ephemeral container that will be added to the running pod." - required: false - - name: image + required: true + default: debugger + - name: container_image type: String title: "Container Image" description: "Image for the ephemeral container to be added to the running pod." From b4d8feeb6e0bde1bddc5c1442c382a88ee90c1d5 Mon Sep 17 00:00:00 2001 From: Jake Cohen Date: Mon, 27 Feb 2023 10:29:12 -0800 Subject: [PATCH 3/9] remove print statements --- contents/debug-ephemeral-container.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/contents/debug-ephemeral-container.py b/contents/debug-ephemeral-container.py index a26ee63..9534e7a 100644 --- a/contents/debug-ephemeral-container.py +++ b/contents/debug-ephemeral-container.py @@ -19,8 +19,6 @@ def main(): common.connect() - print("Container image: " + os.environ.get("RD_CONFIG_CONTAINER_IMAGE")) - print("Container name: " + os.environ.get("RD_CONFIG_CONTAINER_NAME")) container_name = os.environ.get("RD_CONFIG_CONTAINER_NAME") container_image = os.environ.get("RD_CONFIG_CONTAINER_IMAGE") From 66c313b6773cb6a5ab8f80a3a44befb0d1b7e766 Mon Sep 17 00:00:00 2001 From: Jake Cohen Date: Mon, 27 Feb 2023 15:18:22 -0800 Subject: [PATCH 4/9] add ability to set target container --- contents/debug-ephemeral-container.py | 23 ++++++++++++++++------- plugin.yaml | 5 +++++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/contents/debug-ephemeral-container.py b/contents/debug-ephemeral-container.py index 9534e7a..feac93a 100644 --- a/contents/debug-ephemeral-container.py +++ b/contents/debug-ephemeral-container.py @@ -22,6 +22,9 @@ def main(): container_name = os.environ.get("RD_CONFIG_CONTAINER_NAME") container_image = os.environ.get("RD_CONFIG_CONTAINER_IMAGE") + if os.environ.get("RD_CONFIG_TARGET_CONTAINER"): + target_container = os.environ.get("RD_CONFIG_TARGET_CONTAINER") + try: v1 = client.CoreV1Api() @@ -40,18 +43,25 @@ def main(): common.verify_pod_exists(name, namespace) # add a debug container to it - spec = client.models.V1EphemeralContainer( - name = container_name, - image = container_image, - stdin=True, - tty=True) body = { "spec": { "ephemeralContainers": [ - spec.to_dict() + { + "name": container_name, + "image": container_image, + "targetContainerName": target_container, + "stdin": True, + "tty": True, +# "volumeMounts": [{ +# "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", +# "name": "kube-api-access-qnhvv", +# "readOnly": true +# }] + } ] } } + response = v1.patch_namespaced_pod_ephemeralcontainers( name, namespace, @@ -59,7 +69,6 @@ def main(): _preload_content=False) print(response.data) -# print("Read(): " + response.read()) except ApiException: diff --git a/plugin.yaml b/plugin.yaml index 8f31525..15eb884 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -2379,6 +2379,11 @@ providers: title: "Container Image" description: "Image for the ephemeral container to be added to the running pod." default: "busybox" + - name: target_container + type: String + title: "Target Container" + description: "Name of a container within the running pod that the ephemeral container should target.\n The ephemeral container will be run in the namespaces (IPC, PID, etc) of the Target Container. If not set then the ephemeral container uses the namespaces configured in the Pod spec." + required: false - name: Kubernetes-InlineScript-Step service: WorkflowNodeStep title: Kubernetes / Pods / Execute Script From c17f3f2fedbcecebda809a8bc26fb89b033780f8 Mon Sep 17 00:00:00 2001 From: Jake Cohen Date: Mon, 27 Feb 2023 16:57:11 -0800 Subject: [PATCH 5/9] print simplified success message --- contents/debug-ephemeral-container.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/contents/debug-ephemeral-container.py b/contents/debug-ephemeral-container.py index feac93a..52dcd22 100644 --- a/contents/debug-ephemeral-container.py +++ b/contents/debug-ephemeral-container.py @@ -68,8 +68,7 @@ def main(): body, _preload_content=False) - print(response.data) - + print("Ephemeral container " + container_name + " successfully added to pod " + name) except ApiException: log.exception("Exception error creating:") From 64a11a22e16e3e3ddd5bfaa0b9f8ad94871693f0 Mon Sep 17 00:00:00 2001 From: Jake Cohen Date: Mon, 27 Feb 2023 16:59:35 -0800 Subject: [PATCH 6/9] add auth properties --- plugin.yaml | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/plugin.yaml b/plugin.yaml index 15eb884..2034b88 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -2384,6 +2384,49 @@ providers: title: "Target Container" description: "Name of a container within the running pod that the ephemeral container should target.\n The ephemeral container will be run in the namespaces (IPC, PID, etc) of the Target Container. If not set then the ephemeral container uses the namespaces configured in the Pod spec." required: false + - name: config_file + type: String + title: "Kubernetes Config File Path" + description: "Leave empty if you want to pass the connection parameters" + required: false + scope: Instance + renderingOptions: + groupName: Authentication + - name: url + type: String + title: "Cluster URL" + description: "Kubernetes Cluster URL" + required: false + scope: Instance + renderingOptions: + groupName: Authentication + - name: token + type: String + title: "Token" + required: false + scope: Instance + description: "Kubernetes API Token" + renderingOptions: + groupName: Authentication + selectionAccessor: "STORAGE_PATH" + valueConversion: "STORAGE_PATH_AUTOMATIC_READ" + storage-path-root: "keys" + - name: verify_ssl + type: Boolean + title: "Verify ssl" + description: "Verify ssl for SSL connections" + required: false + scope: Instance + renderingOptions: + groupName: Authentication + - name: ssl_ca_cert + type: String + title: "SSL Certificate Path" + description: "SSL Certificate Path for SSL connections" + required: false + scope: Instance + renderingOptions: + groupName: Authentication - name: Kubernetes-InlineScript-Step service: WorkflowNodeStep title: Kubernetes / Pods / Execute Script From 0c1e30c62c70b071b9df8e9f2079f635c12263d7 Mon Sep 17 00:00:00 2001 From: Jake Cohen Date: Mon, 27 Feb 2023 17:26:30 -0800 Subject: [PATCH 7/9] add option to print pod spec --- contents/debug-ephemeral-container.py | 7 ++++++- plugin.yaml | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/contents/debug-ephemeral-container.py b/contents/debug-ephemeral-container.py index 52dcd22..5300f79 100644 --- a/contents/debug-ephemeral-container.py +++ b/contents/debug-ephemeral-container.py @@ -3,6 +3,7 @@ import sys import os import common +import json from kubernetes import client from kubernetes.client.rest import ApiException @@ -68,7 +69,11 @@ def main(): body, _preload_content=False) - print("Ephemeral container " + container_name + " successfully added to pod " + name) + if os.environ.get("RD_CONFIG_PRINT_POD_SPEC") == "true": + json_data = json.loads(response.data.decode("utf-8")) + print(json.dumps(json_data, indent=2)) + else: + print("Ephemeral container " + container_name + " successfully added to pod " + name) except ApiException: log.exception("Exception error creating:") diff --git a/plugin.yaml b/plugin.yaml index 2034b88..193c6ad 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -2384,6 +2384,11 @@ providers: title: "Target Container" description: "Name of a container within the running pod that the ephemeral container should target.\n The ephemeral container will be run in the namespaces (IPC, PID, etc) of the Target Container. If not set then the ephemeral container uses the namespaces configured in the Pod spec." required: false + - name: print_pod_spec + type: Boolean + title: "Print Pod Spec" + description: "Optionally print the pod spec to the log output after the ephemeral container has been added." + default: "false" - name: config_file type: String title: "Kubernetes Config File Path" From 5bc947097918a9e2fa0b6aed6f2a13e898ef84d5 Mon Sep 17 00:00:00 2001 From: Jake Cohen Date: Tue, 28 Feb 2023 08:40:45 -0800 Subject: [PATCH 8/9] add link to docs in property description --- plugin.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin.yaml b/plugin.yaml index 193c6ad..20abb57 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -2350,7 +2350,7 @@ providers: groupName: Authentication - name: Kubernetes-Ephemeral-Container service: WorkflowNodeStep - title: Kubernetes / Pods / Debug Ephemeral Container + title: Kubernetes / Pods / Add Ephemeral Debug Container description: 'Add an ephemeral container to a pod for debugging.' plugin-type: script script-interpreter: python -u @@ -2382,7 +2382,7 @@ providers: - name: target_container type: String title: "Target Container" - description: "Name of a container within the running pod that the ephemeral container should target.\n The ephemeral container will be run in the namespaces (IPC, PID, etc) of the Target Container. If not set then the ephemeral container uses the namespaces configured in the Pod spec." + description: "Name of a container within the running pod that the ephemeral container should target.\n The ephemeral container will be run in the namespaces (IPC, PID, etc) of the Target Container. If not set then the ephemeral container uses the namespaces configured in the Pod spec. See the official Kubernetes documentation [here](https://kubernetes.io/docs/tasks/debug/debug-application/debug-running-pod/#ephemeral-container) for further details." required: false - name: print_pod_spec type: Boolean From 1a97a81a7bc92045955d191739ae837ffd87b6e3 Mon Sep 17 00:00:00 2001 From: Jake Cohen Date: Mon, 6 Mar 2023 08:04:52 -0800 Subject: [PATCH 9/9] cleaning up comments and changing title --- contents/debug-ephemeral-container.py | 7 +------ plugin.yaml | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/contents/debug-ephemeral-container.py b/contents/debug-ephemeral-container.py index 5300f79..813cda2 100644 --- a/contents/debug-ephemeral-container.py +++ b/contents/debug-ephemeral-container.py @@ -52,12 +52,7 @@ def main(): "image": container_image, "targetContainerName": target_container, "stdin": True, - "tty": True, -# "volumeMounts": [{ -# "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount", -# "name": "kube-api-access-qnhvv", -# "readOnly": true -# }] + "tty": True } ] } diff --git a/plugin.yaml b/plugin.yaml index 20abb57..b257265 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -2350,7 +2350,7 @@ providers: groupName: Authentication - name: Kubernetes-Ephemeral-Container service: WorkflowNodeStep - title: Kubernetes / Pods / Add Ephemeral Debug Container + title: Kubernetes / Debug / Ephemeral Container description: 'Add an ephemeral container to a pod for debugging.' plugin-type: script script-interpreter: python -u