From 19fcf6906e3afcaafe1ee801782eff3d48b3069e Mon Sep 17 00:00:00 2001 From: Yuriy Novostavskiy Date: Thu, 6 Jun 2024 16:48:15 +0300 Subject: [PATCH] Doc: add example of using kubectl connection plugin (#741) Doc: add example of using kubectl connection plugin 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: Bikouo Aubin Reviewed-by: Sandra McCann Reviewed-by: Mike Graves Reviewed-by: Yuriy Novostavskiy Reviewed-by: purdzan (cherry picked from commit fb80d973c446d6626aa00a0f55a8ae53e3e517c4) --- .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