kubernetes.core icon indicating copy to clipboard operation
kubernetes.core copied to clipboard

template parameter on `k8s` module fails with exception

Open profhase opened this issue 2 years ago • 14 comments

SUMMARY

When using template parameter

ISSUE TYPE
  • Bug Report
COMPONENT NAME
ANSIBLE VERSION
2.12.2
COLLECTION VERSION
2.2.3
OS / ENVIRONMENT

ubuntu 20.04

STEPS TO REPRODUCE
- name: assure configs
  k8s:
    namespace: default
    template: my_config.yml.j2

An exception occurred during task execution. To see the full traceback, use -vvv. The error was: TypeError: get() missing 1 required positional argument: 'body'

While the following works:

- name: assure configs
  k8s:
    namespace: default
    definition: "{{ lookup('template', 'my_config.yml.j2') }}"

profhase avatar Mar 02 '22 11:03 profhase

Hi @profhase

Thanks for taking the time to report the issue. I couldn't reproduce the issue using

ansible-playbook play.yaml -vvv

with

play.yaml

---
- hosts: localhost
  gather_facts: no

  collections:
    - kubernetes.core

  vars:
    namespace: "collection"
  
  tasks:
    - name: assure configs
      k8s:
        namespace: default
        template: namespace.yml.j2

namespace.yml.j2

apiVersion: v1
kind: Namespace
metadata:
  name: "{{ namespace }}"

could you please rerun your playbook using -vvv and also provide the content of my_config.yml.j2 ?

Thanks

abikouo avatar Mar 02 '22 14:03 abikouo

Hi thank you for the quick answer:

# my_config.yml.j2
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-config
  namespace: default
data:
  test.yaml: |
    my:
      app:
        registration: false
TASK [py_t.kube_app : assure configs] ******************************************
task path: /home/me/py-t/roles/kube_app/tasks/main.yml:11
<65.108.152.134> ESTABLISH SSH CONNECTION FOR USER: root
<65.108.152.134> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/home/me/.cache/molecule/kube_app/default/ssh_key"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="root"' -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null -o ControlMaster=auto -o ControlPersist=60s -o ForwardX11=no -o LogLevel=ERROR -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o 'ControlPath="/home/me/.ansible/cp/%h-%p-%r"' 65.108.152.134 '/bin/sh -c '"'"'echo ~root && sleep 0'"'"''
<65.108.152.134> (0, b'/root\n', b'')
<65.108.152.134> ESTABLISH SSH CONNECTION FOR USER: root
<65.108.152.134> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/home/me/.cache/molecule/kube_app/default/ssh_key"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="root"' -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null -o ControlMaster=auto -o ControlPersist=60s -o ForwardX11=no -o LogLevel=ERROR -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o 'ControlPath="/home/me/.ansible/cp/%h-%p-%r"' 65.108.152.134 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo /root/.ansible/tmp `"&& mkdir "` echo /root/.ansible/tmp/ansible-tmp-1646298842.8390255-97011-158001910567681 `" && echo ansible-tmp-1646298842.8390255-97011-158001910567681="` echo /root/.ansible/tmp/ansible-tmp-1646298842.8390255-97011-158001910567681 `" ) && sleep 0'"'"''
<65.108.152.134> (0, b'ansible-tmp-1646298842.8390255-97011-158001910567681=/root/.ansible/tmp/ansible-tmp-1646298842.8390255-97011-158001910567681\n', b'')
redirecting (type: modules) ansible.builtin.k8s to kubernetes.core.k8s
Using module file /home/me/.ansible/collections/ansible_collections/kubernetes/core/plugins/modules/k8s.py
<65.108.152.134> PUT /home/me/.ansible/tmp/ansible-local-96977krb_z16v/tmpftop3ggk TO /root/.ansible/tmp/ansible-tmp-1646298842.8390255-97011-158001910567681/AnsiballZ_k8s.py
<65.108.152.134> SSH: EXEC scp -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/home/me/.cache/molecule/kube_app/default/ssh_key"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="root"' -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null -o ControlMaster=auto -o ControlPersist=60s -o ForwardX11=no -o LogLevel=ERROR -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o 'ControlPath="/home/me/.ansible/cp/%h-%p-%r"' /home/me/.ansible/tmp/ansible-local-96977krb_z16v/tmpftop3ggk '[65.108.152.134]:/root/.ansible/tmp/ansible-tmp-1646298842.8390255-97011-158001910567681/AnsiballZ_k8s.py'
<65.108.152.134> (0, b'', b'')
<65.108.152.134> ESTABLISH SSH CONNECTION FOR USER: root
<65.108.152.134> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/home/me/.cache/molecule/kube_app/default/ssh_key"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="root"' -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null -o ControlMaster=auto -o ControlPersist=60s -o ForwardX11=no -o LogLevel=ERROR -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o 'ControlPath="/home/me/.ansible/cp/%h-%p-%r"' 65.108.152.134 '/bin/sh -c '"'"'chmod u+x /root/.ansible/tmp/ansible-tmp-1646298842.8390255-97011-158001910567681/ /root/.ansible/tmp/ansible-tmp-1646298842.8390255-97011-158001910567681/AnsiballZ_k8s.py && sleep 0'"'"''
<65.108.152.134> (0, b'', b'')
<65.108.152.134> ESTABLISH SSH CONNECTION FOR USER: root
<65.108.152.134> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/home/me/.cache/molecule/kube_app/default/ssh_key"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="root"' -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null -o ControlMaster=auto -o ControlPersist=60s -o ForwardX11=no -o LogLevel=ERROR -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o 'ControlPath="/home/me/.ansible/cp/%h-%p-%r"' -tt 65.108.152.134 '/bin/sh -c '"'"'K8S_AUTH_KUBECONFIG=/etc/rancher/k3s/k3s.yaml /usr/libexec/platform-python /root/.ansible/tmp/ansible-tmp-1646298842.8390255-97011-158001910567681/AnsiballZ_k8s.py && sleep 0'"'"''
<65.108.152.134> (1, b'Traceback (most recent call last):\r\n  File "/root/.ansible/tmp/ansible-tmp-1646298842.8390255-97011-158001910567681/AnsiballZ_k8s.py", line 107, in <module>\r\n    _ansiballz_main()\r\n  File "/root/.ansible/tmp/ansible-tmp-1646298842.8390255-97011-158001910567681/AnsiballZ_k8s.py", line 99, in _ansiballz_main\r\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\r\n  File "/root/.ansible/tmp/ansible-tmp-1646298842.8390255-97011-158001910567681/AnsiballZ_k8s.py", line 48, in invoke_module\r\n    run_name=\'__main__\', alter_sys=True)\r\n  File "/usr/lib64/python3.6/runpy.py", line 205, in run_module\r\n    return _run_module_code(code, init_globals, run_name, mod_spec)\r\n  File "/usr/lib64/python3.6/runpy.py", line 96, in _run_module_code\r\n    mod_name, mod_spec, pkg_name, script_name)\r\n  File "/usr/lib64/python3.6/runpy.py", line 85, in _run_code\r\n    exec(code, run_globals)\r\n  File "/tmp/ansible_k8s_payload_2w5jsjq6/ansible_k8s_payload.zip/ansible_collections/kubernetes/core/plugins/modules/k8s.py", line 397, in <module>\r\n  File "/tmp/ansible_k8s_payload_2w5jsjq6/ansible_k8s_payload.zip/ansible_collections/kubernetes/core/plugins/modules/k8s.py", line 393, in main\r\n  File "/tmp/ansible_k8s_payload_2w5jsjq6/ansible_k8s_payload.zip/ansible_collections/kubernetes/core/plugins/modules/k8s.py", line 377, in execute_module\r\n  File "/tmp/ansible_k8s_payload_2w5jsjq6/ansible_k8s_payload.zip/ansible_collections/kubernetes/core/plugins/module_utils/common.py", line 559, in execute_module\r\n  File "/tmp/ansible_k8s_payload_2w5jsjq6/ansible_k8s_payload.zip/ansible_collections/kubernetes/core/plugins/module_utils/common.py", line 635, in perform_action\r\nTypeError: get() missing 1 required positional argument: \'body\'\r\n', b'Shared connection to 65.108.152.134 closed.\r\n')
<65.108.152.134> Failed to connect to the host via ssh: Shared connection to 65.108.152.134 closed.
<65.108.152.134> ESTABLISH SSH CONNECTION FOR USER: root
<65.108.152.134> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/home/me/.cache/molecule/kube_app/default/ssh_key"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="root"' -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null -o ControlMaster=auto -o ControlPersist=60s -o ForwardX11=no -o LogLevel=ERROR -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o 'ControlPath="/home/me/.ansible/cp/%h-%p-%r"' 65.108.152.134 '/bin/sh -c '"'"'rm -f -r /root/.ansible/tmp/ansible-tmp-1646298842.8390255-97011-158001910567681/ > /dev/null 2>&1 && sleep 0'"'"''
<65.108.152.134> (0, b'', b'')
The full traceback is:



















fatal: [rocky-1]: FAILED! => {
    "changed": false,
    "module_stderr": "Shared connection to 65.108.152.134 closed.\r\n",
    "module_stdout": "Traceback (most recent call last):\r\n  File \"/root/.ansible/tmp/ansible-tmp-1646298842.8390255-97011-158001910567681/AnsiballZ_k8s.py\", line 107, in <module>\r\n    _ansiballz_main()\r\n  File \"/root/.ansible/tmp/ansible-tmp-1646298842.8390255-97011-158001910567681/AnsiballZ_k8s.py\", line 99, in _ansiballz_main\r\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\r\n  File \"/root/.ansible/tmp/ansible-tmp-1646298842.8390255-97011-158001910567681/AnsiballZ_k8s.py\", line 48, in invoke_module\r\n    run_name='__main__', alter_sys=True)\r\n  File \"/usr/lib64/python3.6/runpy.py\", line 205, in run_module\r\n    return _run_module_code(code, init_globals, run_name, mod_spec)\r\n  File \"/usr/lib64/python3.6/runpy.py\", line 96, in _run_module_code\r\n    mod_name, mod_spec, pkg_name, script_name)\r\n  File \"/usr/lib64/python3.6/runpy.py\", line 85, in _run_code\r\n    exec(code, run_globals)\r\n  File \"/tmp/ansible_k8s_payload_2w5jsjq6/ansible_k8s_payload.zip/ansible_collections/kubernetes/core/plugins/modules/k8s.py\", line 397, in <module>\r\n  File \"/tmp/ansible_k8s_payload_2w5jsjq6/ansible_k8s_payload.zip/ansible_collections/kubernetes/core/plugins/modules/k8s.py\", line 393, in main\r\n  File \"/tmp/ansible_k8s_payload_2w5jsjq6/ansible_k8s_payload.zip/ansible_collections/kubernetes/core/plugins/modules/k8s.py\", line 377, in execute_module\r\n  File \"/tmp/ansible_k8s_payload_2w5jsjq6/ansible_k8s_payload.zip/ansible_collections/kubernetes/core/plugins/module_utils/common.py\", line 559, in execute_module\r\n  File \"/tmp/ansible_k8s_payload_2w5jsjq6/ansible_k8s_payload.zip/ansible_collections/kubernetes/core/plugins/module_utils/common.py\", line 635, in perform_action\r\nTypeError: get() missing 1 required positional argument: 'body'\r\n",
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
    "rc": 1
}

profhase avatar Mar 03 '22 09:03 profhase

I was not able to reproduce using your definition, based on the backtrace this may be related to your Kubernetes python client version, could you please run pip freeze | grep kubernetes ? Thanks

abikouo avatar Mar 03 '22 10:03 abikouo

Hi, sure :)

kubernetes==23.3.0

profhase avatar Mar 03 '22 10:03 profhase

You are using a recent version so it is not!! @Akasurde could you please try and see if you can reproduce this issue?

abikouo avatar Mar 03 '22 10:03 abikouo

@abikouo

You are using a recent version so it is not!!

I do not understand what you mean

profhase avatar Mar 03 '22 10:03 profhase

@abikouo

You are using a recent version so it is not!!

I do not understand what you mean

Sorry I was not cleared. I meant the issue may not be related to Kubernetes python client version. The issue is located here

https://github.com/ansible-collections/kubernetes.core/blob/0d9c4d3459cfba655c0dbbdb3d22a5cb5def7f21/plugins/module_utils/common.py#L635

The module is checking if the resource already exists and to do so it used the Kubernetes client and it seems that there is a missing required parameter.

abikouo avatar Mar 03 '22 10:03 abikouo

I can reproduce on 2.2.3 branch, not on the latest devel.

Akasurde avatar Mar 03 '22 10:03 Akasurde

@abikouo If I am not mistaken, both possibilities

# 1
- name: assure configs
  k8s:
    namespace: default
    template: my_config.yml.j2

# 2
- name: assure configs
  k8s:
    namespace: default
    definition: "{{ lookup('template', 'my_config.yml.j2') }}"

are equivalent. Would it be suitable just to drop the template option, if it just increases complexity? (Also due to the zen of python: "There should be one-- and preferably only one --obvious way to do it.")

profhase avatar Mar 03 '22 11:03 profhase

I agree with what you are saying, we added those to cater to different requirements. So I don't think we can drop template.

Akasurde avatar Mar 03 '22 11:03 Akasurde

I can reproduce on 2.2.3 branch, not on the latest devel.

I can reproduce only if the template file is empty. Otherwise, I get correct results.

Akasurde avatar Mar 04 '22 08:03 Akasurde

@abikouo

You are using a recent version so it is not!!

I do not understand what you mean

Sorry I was not cleared. I meant the issue may not be related to Kubernetes python client version. The issue is located here

https://github.com/ansible-collections/kubernetes.core/blob/0d9c4d3459cfba655c0dbbdb3d22a5cb5def7f21/plugins/module_utils/common.py#L635

The module is checking if the resource already exists and to do so it used the Kubernetes client and it seems that there is a missing required parameter.

Got the same error on that same line (the line number changed but the code is the same) with a different task. k8s core version 2.3.2

Task:

    - name: Delete previous language-update job pods
      kubernetes.core.k8s:
        state: absent
        namespace: "app-develop"
        label_selectors:
          - job-name=language-update
Ansible error outout
Traceback (most recent call last):
  File \"/home/ubuntu/.ansible/tmp/ansible-tmp-1658741258.3613455-1652-132517230211849/AnsiballZ_k8s.py\", line 107, in 
    _ansiballz_main()
  File \"/home/ubuntu/.ansible/tmp/ansible-tmp-1658741258.3613455-1652-132517230211849/AnsiballZ_k8s.py\", line 99, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File \"/home/ubuntu/.ansible/tmp/ansible-tmp-1658741258.3613455-1652-132517230211849/AnsiballZ_k8s.py\", line 47, in invoke_module
    runpy.run_module(mod_name='ansible_collections.kubernetes.core.plugins.modules.k8s', init_globals=dict(_module_fqn='ansible_collections.kubernetes.core.plugins.modules.k8s', _modlib_path=modlib_path),
  File \"/usr/lib/python3.8/runpy.py\", line 207, in run_module
    return _run_module_code(code, init_globals, run_name, mod_spec)
  File \"/usr/lib/python3.8/runpy.py\", line 97, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File \"/usr/lib/python3.8/runpy.py\", line 87, in _run_code
    exec(code, run_globals)
  File \"/tmp/ansible_kubernetes.core.k8s_payload_qm06753o/ansible_kubernetes.core.k8s_payload.zip/ansible_collections/kubernetes/core/plugins/modules/k8s.py\", line 486, in 
  File \"/tmp/ansible_kubernetes.core.k8s_payload_qm06753o/ansible_kubernetes.core.k8s_payload.zip/ansible_collections/kubernetes/core/plugins/modules/k8s.py\", line 482, in main
  File \"/tmp/ansible_kubernetes.core.k8s_payload_qm06753o/ansible_kubernetes.core.k8s_payload.zip/ansible_collections/kubernetes/core/plugins/modules/k8s.py\", line 459, in execute_module
  File \"/tmp/ansible_kubernetes.core.k8s_payload_qm06753o/ansible_kubernetes.core.k8s_payload.zip/ansible_collections/kubernetes/core/plugins/module_utils/common.py\", line 807, in execute_module
  File \"/tmp/ansible_kubernetes.core.k8s_payload_qm06753o/ansible_kubernetes.core.k8s_payload.zip/ansible_collections/kubernetes/core/plugins/module_utils/common.py\", line 905, in perform_action
TypeError: get() missing 1 required positional argument: 'body'

https://github.com/ansible-collections/kubernetes.core/blob/2.3.2/plugins/module_utils/common.py#L905

vertexvaar avatar Jul 25 '22 09:07 vertexvaar

@vertexvaar I found the issue. The module is trying to list all resources using the label, as the kind parameter is not defined, the ResourceList class is used to do that and requires the body parameter to be defined. I will check if this is possible with the Kubernetes client or reject on Ansible side when the kind parameter is not defined.

abikouo avatar Jul 25 '22 16:07 abikouo

Hi, I've had the exact same issue (fixed when I explicitly added a kind: Pod in my config block

Does that mean you should document kind as being mandatory?

daladim avatar Oct 27 '23 08:10 daladim