ansible-collections / community.kubernetes

Kubernetes Collection for Ansible
https://galaxy.ansible.com/community/kubernetes
GNU General Public License v3.0
265 stars 104 forks source link

k8s create resource from template fails #278

Closed el-pako closed 4 years ago

el-pako commented 4 years ago
SUMMARY

Using k8s module with template parameter to generate kubernetes resources from template file fails with:

"Failed to retrieve requested object: get() missing 1 required positional argument: 'body'",

ISSUE TYPE
COMPONENT NAME

k8s

ANSIBLE VERSION
ansible 2.10.2
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/user/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /home/user/.local/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Mar 20 2020, 17:08:22) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
CONFIGURATION
None
OS / ENVIRONMENT

NAME="Red Hat Enterprise Linux Server" VERSION="7.9 (Maipo)"

STEPS TO REPRODUCE

Folder structure on ansible controller:

home
└── user/
    ├── resource.j2
    └── ansible/
        └── roles/
            └── test
                 └── tasks
                 │   └── main.yml
                 └── templates
                     └── resource.j2

Run the test role on a remote machine. main.yml contains the task:

- name: Create a kubernetes resource
  k8s:
    state: present
    template: '/home/user/resource.j2'
  failed_when: false

For template value, choose one of the following:

Content of resource.j2

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: image-registry-pvc
  namespace: openshift-image-registry
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 100Gi
  storageClassName: nfs01
  volumeMode: Filesystem
EXPECTED RESULTS

Kubernetes resource gets created.

ACTUAL RESULTS

All mentioned values for the template parameter fail with the same error message.

ok: [<REMOTE_IP>] => {
    "changed": false,
    "error": "",
    "failed_when_result": false,
    "invocation": {
        "module_args": {
            "api_key": null,
            "api_version": "v1",
            "append_hash": false,
            "apply": false,
            "ca_cert": null,
            "client_cert": null,
            "client_key": null,
            "context": null,
            "force": false,
            "host": null,
            "kind": null,
            "kubeconfig": null,
            "merge_type": null,
            "name": null,
            "namespace": null,
            "password": null,
            "persist_config": null,
            "proxy": null,
            "resource_definition": null,
            "src": null,
            "state": "present",
            "template": "/home/user/resource.j2",
            "username": null,
            "validate": null,
            "validate_certs": null,
            "wait": false,
            "wait_condition": null,
            "wait_sleep": 5,
            "wait_timeout": 120
        }
    },
    "msg": "Failed to retrieve requested object: get() missing 1 required positional argument: 'body'",
    "reason": "",
    "status": ""
}
Akasurde commented 4 years ago

@el-pako Thanks for reporting this issue. Could you please provide content of /home/user/resource.j2?

el-pako commented 4 years ago

@Akasurde I added it to my first comment.

Akasurde commented 4 years ago

@el-pako Thanks. I will try to reproduce this on setup.

Akasurde commented 4 years ago

@el-pako Could you please list the version openshift library used? Also, do you get same error while creating other objects as well? Thanks.

el-pako commented 4 years ago

@Akasurde

/bin/pip3 show openshift Name: openshift Version: 0.11.2 Summary: OpenShift python client

I get this error only when using the template parameter, no matter whats written in the resource.j2, also when it is empty.

tima commented 4 years ago

Thanks for the extra info @el-pako. @Akasurde was having trouble reproducing the error so far. That error seems to be coming from the openshift client library which is a bit puzzling. We're digging deeper and just wanted to make sure we're testing with the same versions.

tima commented 4 years ago

@el-pako: I was able to reproduce it. Could you try using the FQCN like so...

- name: Create a kubernetes resource
  community.kubernetes.k8s:
    state: present
    template: '/home/user/resource.j2'

Without prepending community.kubernetes the playbook runner assumes ansible.builtin, an older version of the k8s module which doesn't support the template param. What I'm still unclear on is why you didn't just get an unrecognized parameter "template" error from the module because it was using the builtin collection that have support for that. Going to have to take that one back to the engineers.

Let us know if adding an explicit namespace resolved your issue here.

el-pako commented 4 years ago

@tima Using the FQCN for the module, the error is gone and the resource was successfully created in the k8 environment. This time, I referenced the template file in the template folder (but it also works with a full qualified reference):


- name: Create a Kubernetes resource
  community.kubernetes.k8s:
    state: present
    template: resource.j2
el-pako commented 4 years ago

Here is the verbose output. Noticed that the template argument is null.

changed: [<REMOTE_IP>] => {
    "changed": true,
    "invocation": {
        "module_args": {
            "api_key": null,
            "api_version": "v1",
            "append_hash": false,
            "apply": false,
            "ca_cert": null,
            "client_cert": null,
            "client_key": null,
            "context": null,
            "force": false,
            "host": null,
            "kind": null,
            "kubeconfig": null,
            "merge_type": null,
            "name": null,
            "namespace": null,
            "password": null,
            "persist_config": null,
            "proxy": null,
            "resource_definition": "apiVersion: eventstreams.ibm.com/v1beta1\nkind: EventStreams\nmetadata:\n  name: light-secure\n  namespace: demo\nspec:\n  version: 10.0.0\n  license:\n    accept: true\n    use: IBMSupportingProgram\n  adminApi: {}\n  adminUI: {}\n  collector: {}\n  restProducer: {}\n  schemaRegistry:\n    storage:\n      type: ephemeral\n  strimziOverrides:\n    kafka:\n      replicas: 1\n      authorization:\n        type: runas\n      config:\n        interceptor.class.names: com.ibm.eventstreams.interceptors.metrics.ProducerMetricsInterceptor\n        offsets.topic.replication.factor: 1\n        transaction.state.log.min.isr: 1\n        transaction.state.log.replication.factor: 1\n      listeners:\n        external:\n          type: route\n          authentication:\n            type: scram-sha-512\n        tls:\n          authentication:\n            type: tls\n      metrics: {}\n      storage:\n        type: ephemeral\n    zookeeper:\n      replicas: 1\n      metrics: {}\n      storage:\n        type: ephemeral\n",
            "src": null,
            "state": "present",
            "template": null,
            "username": null,
            "validate": null,
            "validate_certs": null,
            "wait": false,
            "wait_condition": null,
            "wait_sleep": 5,
            "wait_timeout": 120
        }
    },
Akasurde commented 4 years ago

So, the problem is - when we do not specify FQCN for the module, it fails to find the respective action plugin. The template logic comes from k8s action plugin and resposible for populating required information such as name, kind. Thus OpenShift library fails to find the required parameter to search resource due to lack of info.

@tima I am talking to Ansible Core team to check if this is a collection or engine related issue. Depending upon that we will fix it.

For now, the workaround is to specify the FQCN of module in the given task.

Akasurde commented 4 years ago

resolved_by_pr #299

Akasurde commented 4 years ago

@el-pako Could you please try PR #299 and let me know if it works for you? Thanks.

el-pako commented 4 years ago

@Akasurde I am afraid I can not do that as I was using Ansible from a productive, shared environment at work (that also has been upgraded to a newer Ansible version since then).