ansible-collections / kubernetes.core

The collection includes a variety of Ansible content to help automate the management of applications in Kubernetes and OpenShift clusters, as well as the provisioning and maintenance of clusters themselves.
Other
216 stars 135 forks source link

k8s_json_patch module AttributeError: 'K8sAnsibleMixin' object has no attribute 'fail_json' #499

Open branic opened 2 years ago

branic commented 2 years ago
SUMMARY

The k8s_json_patch module is failing with the error: AttributeError: 'K8sAnsibleMixin' object has no attribute 'fail_json'

I found issue #433 which has the same error with the k8s_info module which was fixed in version 2.3.0. However, I'm using version 2.3.1 of the collection.

ISSUE TYPE
COMPONENT NAME

k8s_json_patch

ANSIBLE VERSION
ansible [core 2.13.0]
  config file = None
  configured module search path = ['/home/runner/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.8/site-packages/ansible
  ansible collection location = /home/runner/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.8.13 (default, Jun 24 2022, 15:27:57) [GCC 8.5.0 20210514 (Red Hat 8.5.0-13)]
  jinja version = 3.1.2
  libyaml = True
COLLECTION VERSION
# /usr/share/ansible/collections/ansible_collections
Collection      Version
--------------- -------
kubernetes.core 2.3.1  
CONFIGURATION
CACHE_PLUGIN(env: ANSIBLE_CACHE_PLUGIN) = jsonfile
CACHE_PLUGIN_CONNECTION(env: ANSIBLE_CACHE_PLUGIN_CONNECTION) = /runner/artifacts/a0a3d95e-2111-4f06-b3d9-1c1bc5ea22a3/fact_cache
DEFAULT_CALLBACK_PLUGIN_PATH(env: ANSIBLE_CALLBACK_PLUGINS) = ['/usr/local/lib/python3.8/site-packages/ansible_runner/callbacks']
DEFAULT_STDOUT_CALLBACK(env: ANSIBLE_STDOUT_CALLBACK) = awx_display
HOST_KEY_CHECKING(env: ANSIBLE_HOST_KEY_CHECKING) = False
RETRY_FILES_ENABLED(env: ANSIBLE_RETRY_FILES_ENABLED) = False
OS / ENVIRONMENT

The playbook is targeting localhost as the host and is running inside an execution environment. The target is a Red Hat OpenShift cluster.

STEPS TO REPRODUCE

When the below task is run against an OpenShift cluster with the namespace created and the ansible-automation-platform operator installed it will fail (its missing setting the apiversion). Although there is a failure to find the object to patch due to the missing apiversion setting the module fails with the `no attribute 'fail_json' which is unexpected.

- name: Update install plan
  kubernetes.core.k8s_json_patch:
    host: <REDACTED>
    api_key: <REDACTED>
    kind: Subscription
    namespace: aap
    name: ansible-automation-platform-operator
    patch:
      - op: replace
        path: /spec/installPlanApproval
        value: Manual
EXPECTED RESULTS

The task fails but without the module failing with the traceback. The No matches found for {'prefix': None, 'api_version': 'v1', 'short_names': ['Subscription']} message should be reported for the task.

ACTUAL RESULTS

Module fails with a traceback.

TASK [redhat_cop.aap_utilities.aap_ocp_install : Update install plan] **********************************************************************************************
task path: /home/runner/.ansible/collections/ansible_collections/redhat_cop/aap_utilities/roles/aap_ocp_install/tasks/install-operator.yml:34
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: root
<127.0.0.1> EXEC /bin/sh -c 'echo ~root && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp `"&& mkdir "` echo /root/.ansible/tmp/ansible-tmp-1660064438.7171547-176-132998062341796 `" && echo ansible-tmp-1660064438.7171547-176-132998062341796="` echo /root/.ansible/tmp/ansible-tmp-1660064438.7171547-176-132998062341796 `" ) && sleep 0'
Using module file /usr/share/ansible/collections/ansible_collections/kubernetes/core/plugins/modules/k8s_json_patch.py
<127.0.0.1> PUT /home/runner/.ansible/tmp/ansible-local-64bu1g3mwc/tmpvkm_6gg4 TO /root/.ansible/tmp/ansible-tmp-1660064438.7171547-176-132998062341796/AnsiballZ_k8s_json_patch.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1660064438.7171547-176-132998062341796/ /root/.ansible/tmp/ansible-tmp-1660064438.7171547-176-132998062341796/AnsiballZ_k8s_json_patch.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python3 /root/.ansible/tmp/ansible-tmp-1660064438.7171547-176-132998062341796/AnsiballZ_k8s_json_patch.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-tmp-1660064438.7171547-176-132998062341796/ > /dev/null 2>&1 && sleep 0'
The full traceback is:
Traceback (most recent call last):
  File "/tmp/ansible_kubernetes.core.k8s_json_patch_payload_otle065i/ansible_kubernetes.core.k8s_json_patch_payload.zip/ansible_collections/kubernetes/core/plugins/module_utils/common.py", line 388, in find_resource
  File "/tmp/ansible_kubernetes.core.k8s_json_patch_payload_otle065i/ansible_kubernetes.core.k8s_json_patch_payload.zip/ansible_collections/kubernetes/core/plugins/module_utils/common.py", line 365, in _find_resource_with_prefix
  File "/tmp/ansible_kubernetes.core.k8s_json_patch_payload_otle065i/ansible_kubernetes.core.k8s_json_patch_payload.zip/ansible_collections/kubernetes/core/plugins/module_utils/client/discovery.py", line 182, in get
kubernetes.dynamic.exceptions.ResourceNotFoundError: No matches found for {'prefix': None, 'api_version': 'v1', 'short_names': ['Subscription']}

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/root/.ansible/tmp/ansible-tmp-1660064438.7171547-176-132998062341796/AnsiballZ_k8s_json_patch.py", line 107, in <module>
    _ansiballz_main()
  File "/root/.ansible/tmp/ansible-tmp-1660064438.7171547-176-132998062341796/AnsiballZ_k8s_json_patch.py", line 99, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/root/.ansible/tmp/ansible-tmp-1660064438.7171547-176-132998062341796/AnsiballZ_k8s_json_patch.py", line 47, in invoke_module
    runpy.run_module(mod_name='ansible_collections.kubernetes.core.plugins.modules.k8s_json_patch', init_globals=dict(_module_fqn='ansible_collections.kubernetes.core.plugins.modules.k8s_json_patch', _modlib_path=modlib_path),
  File "/usr/lib64/python3.8/runpy.py", line 207, in run_module
    return _run_module_code(code, init_globals, run_name, mod_spec)
  File "/usr/lib64/python3.8/runpy.py", line 97, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "/usr/lib64/python3.8/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/tmp/ansible_kubernetes.core.k8s_json_patch_payload_otle065i/ansible_kubernetes.core.k8s_json_patch_payload.zip/ansible_collections/kubernetes/core/plugins/modules/k8s_json_patch.py", line 287, in <module>
  File "/tmp/ansible_kubernetes.core.k8s_json_patch_payload_otle065i/ansible_kubernetes.core.k8s_json_patch_payload.zip/ansible_collections/kubernetes/core/plugins/modules/k8s_json_patch.py", line 283, in main
  File "/tmp/ansible_kubernetes.core.k8s_json_patch_payload_otle065i/ansible_kubernetes.core.k8s_json_patch_payload.zip/ansible_collections/kubernetes/core/plugins/modules/k8s_json_patch.py", line 212, in execute_module
  File "/tmp/ansible_kubernetes.core.k8s_json_patch_payload_otle065i/ansible_kubernetes.core.k8s_json_patch_payload.zip/ansible_collections/kubernetes/core/plugins/module_utils/common.py", line 391, in find_resource
  File "/tmp/ansible_kubernetes.core.k8s_json_patch_payload_otle065i/ansible_kubernetes.core.k8s_json_patch_payload.zip/ansible_collections/kubernetes/core/plugins/module_utils/common.py", line 566, in fail
AttributeError: 'K8sAnsibleMixin' object has no attribute 'fail_json'
fatal: [localhost]: FAILED! => {
    "changed": false,
    "module_stderr": "Traceback (most recent call last):\n  File \"/tmp/ansible_kubernetes.core.k8s_json_patch_payload_otle065i/ansible_kubernetes.core.k8s_json_patch_payload.zip/ansible_collections/kubernetes/core/plugins/module_utils/common.py\", line 388, in find_resource\n  File \"/tmp/ansible_kubernetes.core.k8s_json_patch_payload_otle065i/ansible_kubernetes.core.k8s_json_patch_payload.zip/ansible_collections/kubernetes/core/plugins/module_utils/common.py\", line 365, in _find_resource_with_prefix\n  File \"/tmp/ansible_kubernetes.core.k8s_json_patch_payload_otle065i/ansible_kubernetes.core.k8s_json_patch_payload.zip/ansible_collections/kubernetes/core/plugins/module_utils/client/discovery.py\", line 182, in get\nkubernetes.dynamic.exceptions.ResourceNotFoundError: No matches found for {'prefix': None, 'api_version': 'v1', 'short_names': ['Subscription']}\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n  File \"/root/.ansible/tmp/ansible-tmp-1660064438.7171547-176-132998062341796/AnsiballZ_k8s_json_patch.py\", line 107, in <module>\n    _ansiballz_main()\n  File \"/root/.ansible/tmp/ansible-tmp-1660064438.7171547-176-132998062341796/AnsiballZ_k8s_json_patch.py\", line 99, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/root/.ansible/tmp/ansible-tmp-1660064438.7171547-176-132998062341796/AnsiballZ_k8s_json_patch.py\", line 47, in invoke_module\n    runpy.run_module(mod_name='ansible_collections.kubernetes.core.plugins.modules.k8s_json_patch', init_globals=dict(_module_fqn='ansible_collections.kubernetes.core.plugins.modules.k8s_json_patch', _modlib_path=modlib_path),\n  File \"/usr/lib64/python3.8/runpy.py\", line 207, in run_module\n    return _run_module_code(code, init_globals, run_name, mod_spec)\n  File \"/usr/lib64/python3.8/runpy.py\", line 97, in _run_module_code\n    _run_code(code, mod_globals, init_globals,\n  File \"/usr/lib64/python3.8/runpy.py\", line 87, in _run_code\n    exec(code, run_globals)\n  File \"/tmp/ansible_kubernetes.core.k8s_json_patch_payload_otle065i/ansible_kubernetes.core.k8s_json_patch_payload.zip/ansible_collections/kubernetes/core/plugins/modules/k8s_json_patch.py\", line 287, in <module>\n  File \"/tmp/ansible_kubernetes.core.k8s_json_patch_payload_otle065i/ansible_kubernetes.core.k8s_json_patch_payload.zip/ansible_collections/kubernetes/core/plugins/modules/k8s_json_patch.py\", line 283, in main\n  File \"/tmp/ansible_kubernetes.core.k8s_json_patch_payload_otle065i/ansible_kubernetes.core.k8s_json_patch_payload.zip/ansible_collections/kubernetes/core/plugins/modules/k8s_json_patch.py\", line 212, in execute_module\n  File \"/tmp/ansible_kubernetes.core.k8s_json_patch_payload_otle065i/ansible_kubernetes.core.k8s_json_patch_payload.zip/ansible_collections/kubernetes/core/plugins/module_utils/common.py\", line 391, in find_resource\n  File \"/tmp/ansible_kubernetes.core.k8s_json_patch_payload_otle065i/ansible_kubernetes.core.k8s_json_patch_payload.zip/ansible_collections/kubernetes/core/plugins/module_utils/common.py\", line 566, in fail\nAttributeError: 'K8sAnsibleMixin' object has no attribute 'fail_json'\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
    "rc": 1
}
branic commented 2 years ago

The module isn't always returning a module error. I did another test where I set the apiversion, kind, namespace, and name, but the name was not the name of an existing object and the task correctly failed, but the module did not.

fatal: [localhost]: FAILED! => {"changed": false, "error": 404, "msg": "Subscription ansible-automation-platform-operator: Failed to retrieve requested object: b'{\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"subscriptions.operators.coreos.com \\\\\"ansible-automation-platform-operator\\\\\" not found\",\"reason\":\"NotFound\",\"details\":{\"name\":\"ansible-automation-platform-operator\",\"group\":\"operators.coreos.com\",\"kind\":\"subscriptions\"},\"code\":404}\\n'", "reason": "Not Found", "status": 404}
gravesm commented 2 years ago

@branic Thanks for the bug report. This problem should already be fixed on the main branch, but we will look into porting a fix to older branches.

Muscule commented 1 year ago

I have the same problem. Version 2.3.2