Skip to content

Commit

Permalink
k8s_exec: Select first container from the pod
Browse files Browse the repository at this point in the history
kubectl command select first container from the pod in order
to execute commands on. We replicate the same behavior in k8s_exec
module.

Fixes: ansible-collections#358

Signed-off-by: Abhijeet Kasurde <[email protected]>
  • Loading branch information
Akasurde committed Feb 7, 2022
1 parent a122bad commit 852d9d0
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 4 deletions.
3 changes: 3 additions & 0 deletions changelogs/fragments/358-k8s_exec.yml
Original file line number Diff line number Diff line change
@@ -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).
34 changes: 34 additions & 0 deletions molecule/default/tasks/exec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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:
Expand Down
30 changes: 26 additions & 4 deletions plugins/modules/k8s_exec.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
"""
Expand All @@ -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"""
Expand Down Expand Up @@ -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
Expand All @@ -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,
Expand Down

0 comments on commit 852d9d0

Please sign in to comment.