diff --git a/changelogs/fragments/358-k8s_exec.yml b/changelogs/fragments/358-k8s_exec.yml new file mode 100644 index 0000000000..cba731855c --- /dev/null +++ b/changelogs/fragments/358-k8s_exec.yml @@ -0,0 +1,3 @@ +--- +minor_changes: +- k8s_exec - select first container from the pod if none specified (https://github.com/ansible-collections/kubernetes.core/issues/358). diff --git a/molecule/default/tasks/exec.yml b/molecule/default/tasks/exec.yml index 1878f91e18..29bfd115dc 100644 --- a/molecule/default/tasks/exec.yml +++ b/molecule/default/tasks/exec.yml @@ -13,6 +13,21 @@ - name: sleeper image: busybox command: ["sleep", "infinity"] + multi_container_pod_name: pod-2 + multi_container_pod_definition: + apiVersion: v1 + kind: Pod + metadata: + name: "{{ multi_container_pod_name }}" + namespace: "{{ exec_namespace }}" + spec: + containers: + - name: sleeper-1 + image: busybox + command: ["sleep", "infinity"] + - name: sleeper-2 + image: busybox + command: ["sleep", "infinity"] block: - name: "Ensure that {{ exec_namespace }} namespace exists" @@ -57,6 +72,25 @@ - command_status.rc != 0 - command_status.return_code != 0 + - name: Create a multi container pod + k8s: + definition: "{{ multi_container_pod_definition }}" + wait: yes + wait_sleep: 1 + wait_timeout: 30 + + - name: Execute command on the first container of the pod + k8s_exec: + pod: "{{ multi_container_pod_name }}" + namespace: "{{ exec_namespace }}" + command: echo hello + register: output + + - name: Assert k8s_exec output is correct + assert: + that: + - "'hello' in output.stdout" + always: - name: "Cleanup namespace" k8s: diff --git a/plugins/modules/k8s_exec.py b/plugins/modules/k8s_exec.py index fb36a39b32..936fb2c494 100644 --- a/plugins/modules/k8s_exec.py +++ b/plugins/modules/k8s_exec.py @@ -40,27 +40,28 @@ description: - The URL of an HTTP proxy to use for the connection. - Can also be specified via I(K8S_AUTH_PROXY) environment variable. - - Please note that this module does not pick up typical proxy settings from the environment (e.g. HTTP_PROXY). + - Please note that this module does not pick up typical proxy settings from the environment (for example, HTTP_PROXY). type: str namespace: description: - - The pod namespace name + - The pod namespace name. type: str required: yes pod: description: - - The pod name + - The pod name. type: str required: yes container: description: - The name of the container in the pod to connect to. - Defaults to only container if there is only one container in the pod. + - If not specified, will choose the first container from the given pod as kubectl cmdline does. type: str required: no command: description: - - The command to execute + - The command to execute. type: str required: yes """ @@ -84,6 +85,13 @@ debug: msg: "cmd failed" when: command_status.rc != 0 + +- name: Specify a container name to execute the command on + kubernetes.core.k8s_exec: + namespace: myproject + pod: busybox-test + container: manager + command: echo "hello" """ RETURN = r""" @@ -134,6 +142,7 @@ try: from kubernetes.client.apis import core_v1_api from kubernetes.stream import stream + from kubernetes.client.rest import ApiException except ImportError: # ImportError are managed by the common module already. pass @@ -157,6 +166,19 @@ def execute_module(module, k8s_ansible_mixin): optional_kwargs = {} if module.params.get("container"): optional_kwargs["container"] = module.params["container"] + else: + # default to the first container available on pod + resp = None + try: + resp = api.read_namespaced_pod( + name=module.params["pod"], namespace=module.params["namespace"] + ) + except ApiException: + pass + + if resp and len(resp.spec.containers) >= 1: + optional_kwargs["container"] = resp.spec.containers[0].name + try: resp = stream( api.connect_get_namespaced_pod_exec,