From 4854d7fbd9cd45febbc778b7766994b9770ff7c5 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 6 Jun 2024 14:28:18 +0000 Subject: [PATCH] Doc: add example of using kubectl connection plugin (#741) (#743) [PR #741/fb80d973 backport][stable-3] Doc: add example of using kubectl connection plugin This is a backport of PR #741 as merged into main (fb80d97). SUMMARY Currently documentation for collection don't include any examples of using kubenrenes.core.kubectl connection plugin and it's hard to start using that plugin. ISSUE TYPE Docs Pull Request COMPONENT NAME kubenrenes.core.kubectl connection plugin ADDITIONAL INFORMATION This PR was inspired by #288 and based on feedback on that PR and my own experience. Thanks @tpo for his try and @geerlingguy for his Ansible for DevOps book Reviewed-by: Yuriy Novostavskiy Reviewed-by: Mike Graves --- .ansible-lint-ignore | 2 + ...20240601-doc-example-of-using-kubectl.yaml | 3 + docs/kubernetes.core.kubectl_connection.rst | 76 +++++++++++++++++++ plugins/connection/kubectl.py | 75 ++++++++++++++++++ 4 files changed, 156 insertions(+) create mode 100644 .ansible-lint-ignore create mode 100644 changelogs/fragments/20240601-doc-example-of-using-kubectl.yaml diff --git a/.ansible-lint-ignore b/.ansible-lint-ignore new file mode 100644 index 0000000000..b089a5a252 --- /dev/null +++ b/.ansible-lint-ignore @@ -0,0 +1,2 @@ +# no-changed-when is not requried for examples +plugins/connection/kubectl.py no-changed-when diff --git a/changelogs/fragments/20240601-doc-example-of-using-kubectl.yaml b/changelogs/fragments/20240601-doc-example-of-using-kubectl.yaml new file mode 100644 index 0000000000..a242bfdfc2 --- /dev/null +++ b/changelogs/fragments/20240601-doc-example-of-using-kubectl.yaml @@ -0,0 +1,3 @@ +--- +minor_changes: + - connection/kubectl.py - Added an example of using the kubectl connection plugin to the documentation (https://github.com/ansible-collections/kubernetes.core/pull/741). diff --git a/docs/kubernetes.core.kubectl_connection.rst b/docs/kubernetes.core.kubectl_connection.rst index 48db359929..97e60f9cd8 100644 --- a/docs/kubernetes.core.kubectl_connection.rst +++ b/docs/kubernetes.core.kubectl_connection.rst @@ -365,6 +365,82 @@ Parameters +Examples +-------- + +.. code-block:: yaml + + - name: Run a command in a pod using local kubectl with kubeconfig file ~/.kube/config + hosts: localhost + gather_facts: no + vars: + ansible_connection: kubernetes.core.kubectl + ansible_kubectl_namespace: my-namespace + ansible_kubectl_pod: my-pod + ansible_kubectl_container: my-container + tasks: + # be aware that the command is executed as the user that started the container + # and requires python to be installed in the image + - name: Run a command in a pod + ansible.builtin.command: echo "Hello, World!" + + - name: Run a command in a pod using local kubectl with inventory variables + # Example inventory: + # k8s: + # hosts: + # foo.example.com: + # ansible_connection: kubernetes.core.kubectl + # ansible_kubectl_kubeconfig: /root/.kube/foo.example.com.config + # ansible_kubectl_pod: my-foo-pod + # ansible_kubectl_container: my-foo-container + # ansible_kubectl_namespace: my-foo-namespace + # bar.example.com: + # ansible_connection: kubernetes.core.kubectl + # ansible_kubectl_kubeconfig: /root/.kube/bar.example.com.config + # ansible_kubectl_pod: my-bar-pod + # ansible_kubectl_container: my-bar-container + # ansible_kubectl_namespace: my-bar-namespace + hosts: k8s + gather_facts: no + tasks: + # be aware that the command is executed as the user that started the container + # and requires python to be installed in the image + - name: Run a command in a pod + ansible.builtin.command: echo "Hello, World!" + + - name: Run a command in a pod using dynamic inventory + hosts: localhost + gather_facts: no + vars: + kubeconfig: /root/.kube/config + namespace: my-namespace + my_app: my-app + tasks: + - name: Get My App pod info based on label + kubernetes.core.k8s_info: + kubeconfig: "{{ kubeconfig }}" + namespace: "{{ namespace }}" + kind: Pod + label_selectors: app.kubernetes.io/name = "{{ my_app }}" + register: my_app_pod + + - name: Get My App pod name + ansible.builtin.set_fact: + my_app_pod_name: "{{ my_app_pod.resources[0].metadata.name }}" + + - name: Add My App pod to inventory + ansible.builtin.add_host: + name: "{{ my_app_pod_name }}" + ansible_connection: kubernetes.core.kubectl + ansible_kubectl_kubeconfig: "{{ kubeconfig }}" + ansible_kubectl_pod: "{{ my_app_pod_name }}" + ansible_kubectl_namespace: "{{ namespace }}" + + - name: Run a command in My App pod + # be aware that the command is executed as the user that started the container + # and requires python to be installed in the image + ansible.builtin.command: echo "Hello, World!" + delegate_to: "{{ my_app_pod_name }}" diff --git a/plugins/connection/kubectl.py b/plugins/connection/kubectl.py index 2a5e1b988f..47953845b1 100644 --- a/plugins/connection/kubectl.py +++ b/plugins/connection/kubectl.py @@ -181,6 +181,81 @@ aliases: [ kubectl_verify_ssl ] """ +EXAMPLES = r""" + +- name: Run a command in a pod using local kubectl with kubeconfig file ~/.kube/config + hosts: localhost + gather_facts: no + vars: + ansible_connection: kubernetes.core.kubectl + ansible_kubectl_namespace: my-namespace + ansible_kubectl_pod: my-pod + ansible_kubectl_container: my-container + tasks: + # be aware that the command is executed as the user that started the container + # and requires python to be installed in the image + - name: Run a command in a pod + ansible.builtin.command: echo "Hello, World!" + +- name: Run a command in a pod using local kubectl with inventory variables + # Example inventory: + # k8s: + # hosts: + # foo.example.com: + # ansible_connection: kubernetes.core.kubectl + # ansible_kubectl_kubeconfig: /root/.kube/foo.example.com.config + # ansible_kubectl_pod: my-foo-pod + # ansible_kubectl_container: my-foo-container + # ansible_kubectl_namespace: my-foo-namespace + # bar.example.com: + # ansible_connection: kubernetes.core.kubectl + # ansible_kubectl_kubeconfig: /root/.kube/bar.example.com.config + # ansible_kubectl_pod: my-bar-pod + # ansible_kubectl_container: my-bar-container + # ansible_kubectl_namespace: my-bar-namespace + hosts: k8s + gather_facts: no + tasks: + # be aware that the command is executed as the user that started the container + # and requires python to be installed in the image + - name: Run a command in a pod + ansible.builtin.command: echo "Hello, World!" + +- name: Run a command in a pod using dynamic inventory + hosts: localhost + gather_facts: no + vars: + kubeconfig: /root/.kube/config + namespace: my-namespace + my_app: my-app + tasks: + - name: Get My App pod info based on label + kubernetes.core.k8s_info: + kubeconfig: "{{ kubeconfig }}" + namespace: "{{ namespace }}" + kind: Pod + label_selectors: app.kubernetes.io/name = "{{ my_app }}" + register: my_app_pod + + - name: Get My App pod name + ansible.builtin.set_fact: + my_app_pod_name: "{{ my_app_pod.resources[0].metadata.name }}" + + - name: Add My App pod to inventory + ansible.builtin.add_host: + name: "{{ my_app_pod_name }}" + ansible_connection: kubernetes.core.kubectl + ansible_kubectl_kubeconfig: "{{ kubeconfig }}" + ansible_kubectl_pod: "{{ my_app_pod_name }}" + ansible_kubectl_namespace: "{{ namespace }}" + + - name: Run a command in My App pod + # be aware that the command is executed as the user that started the container + # and requires python to be installed in the image + ansible.builtin.command: echo "Hello, World!" + delegate_to: "{{ my_app_pod_name }}" +""" + import json import os import os.path