Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

k8s_raw unicode_error when using jinja lookup templating #40185

Closed
tarlov opened this issue May 15, 2018 · 17 comments
Closed

k8s_raw unicode_error when using jinja lookup templating #40185

tarlov opened this issue May 15, 2018 · 17 comments
Labels
affects_2.5 This issue/PR affects Ansible v2.5 bug This issue/PR relates to a bug. clustering Clustering category k8s support:core This issue/PR relates to code supported by the Ansible Engineering Team. traceback This issue/PR includes a traceback.

Comments

@tarlov
Copy link

tarlov commented May 15, 2018

ISSUE TYPE
  • Bug Report
COMPONENT NAME

k8s_raw

ANSIBLE VERSION
nsible 2.5.2
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/etc/ansible/library']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /bin/ansible
  python version = 2.7.5 (default, Apr 11 2018, 07:36:10) [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)]

CONFIGURATION

DEFAULT_BECOME(/etc/ansible/ansible.cfg) = True
DEFAULT_BECOME_ASK_PASS(/etc/ansible/ansible.cfg) = False
DEFAULT_BECOME_METHOD(/etc/ansible/ansible.cfg) = sudo
DEFAULT_BECOME_USER(/etc/ansible/ansible.cfg) = root
DEFAULT_HASH_BEHAVIOUR(/etc/ansible/ansible.cfg) = merge
DEFAULT_MODULE_PATH(/etc/ansible/ansible.cfg) = [u'/etc/ansible/library']
DEFAULT_REMOTE_USER(/etc/ansible/ansible.cfg) = ansible
DEFAULT_ROLES_PATH(/etc/ansible/ansible.cfg) = [u'/etc/ansible/roles']
HOST_KEY_CHECKING(/etc/ansible/ansible.cfg) = False
PERSISTENT_CONNECT_TIMEOUT(/etc/ansible/ansible.cfg) = 30

OS / ENVIRONMENT

Centos

SUMMARY

We are trying to use the k8s_raw module with jinja template. The issue is that when we use the task like this:

  • name: Read definition file from the Ansible controller file system
    k8s_raw:
    state: present
    definition: "{{ lookup('file', '/testing/deployment.yml') | from_yaml }}"
    We are having exception:
    The full traceback is:
    Traceback (most recent call last):
    File "/tmp/ansible_bpILrC/ansible_module_k8s_raw.py", line 163, in
    main()
    File "/tmp/ansible_bpILrC/ansible_module_k8s_raw.py", line 159, in main
    KubernetesRawModule().execute_module()
    File "/tmp/ansible_bpILrC/ansible_modlib.zip/ansible/module_utils/k8s/raw.py", line 121, in execute_module
    File "/tmp/ansible_bpILrC/ansible_modlib.zip/ansible/module_utils/k8s/raw.py", line 170, in _create
    UnicodeEncodeError: 'ascii' codec can't encode character u'\ufffd' in position 171: ordinal not in range(128)

fatal: [k8s -> localhost]: FAILED! => {
"changed": false,
"module_stderr": "Traceback (most recent call last):\n File "/tmp/ansible_bpILrC/ansible_module_k8s_raw.py", line 163, in \n main()\n File "/tmp/ansible_bpILrC/ansible_module_k8s_raw.py", line 159, in main\n KubernetesRawModule().execute_module()\n File "/tmp/ansible_bpILrC/ansible_modlib.zip/ansible/module_utils/k8s/raw.py", line 121, in execute_module\n File "/tmp/ansible_bpILrC/ansible_modlib.zip/ansible/module_utils/k8s/raw.py", line 170, in _create\nUnicodeEncodeError: 'ascii' codec can't encode character u'\ufffd' in position 171: ordinal not in range(128)\n",
"module_stdout": "",
"msg": "MODULE FAILURE",
"rc": 1

STEPS TO REPRODUCE
  1 - name: Create a Service object from an inline definition
  2   k8s_raw:
  3     host: "{{k8s_host}}"
  4     kubeconfig: "{{k8s_config}}"
  5     namespace: "{{namespace}}-{{env}}"
  6     state: present
  7     resource_definition: "{{ lookup('template', 'service.yml') | from_yaml }}"
  8   delegate_to: "localhost"
EXPECTED RESULTS
ACTUAL RESULTS

TASK [devops-k8s-service : Create a Service object from an inline definition] *************************************************************************************************************************************
task path: /etc/ansible/roles/devops-k8s-service/tasks/main.yml:1
looking for "service.yml" at "/etc/ansible/roles/devops-k8s-service/templates/service.yml"
File lookup using /etc/ansible/roles/devops-k8s-service/templates/service.yml as file
Using module file /usr/lib/python2.7/site-packages/ansible/modules/clustering/k8s/k8s_raw.py
ESTABLISH LOCAL CONNECTION FOR USER: ansible
EXEC /bin/sh -c 'echo ~ && sleep 0'
EXEC /bin/sh -c '( umask 77 && mkdir -p "echo /home/ansible/.ansible/tmp/ansible-tmp-1526406851.13-36098482327457" && echo ansible-tmp-1526406851.13-36098482327457="echo /home/ansible/.ansible/tmp/ansible-tmp-1526406851.13-36098482327457" ) && sleep 0'
PUT /home/ansible/.ansible/tmp/ansible-local-281449WIXrE/tmpr4OG3F TO /home/ansible/.ansible/tmp/ansible-tmp-1526406851.13-36098482327457/k8s_raw.py
EXEC /bin/sh -c 'chmod u+x /home/ansible/.ansible/tmp/ansible-tmp-1526406851.13-36098482327457/ /home/ansible/.ansible/tmp/ansible-tmp-1526406851.13-36098482327457/k8s_raw.py && sleep 0'
EXEC /bin/sh -c 'sudo -H -S -n -u root /bin/sh -c '"'"'echo BECOME-SUCCESS-sdpatlhciheqdvbadkknmlopegvqibfl; /usr/bin/python2 /home/ansible/.ansible/tmp/ansible-tmp-1526406851.13-36098482327457/k8s_raw.py'"'"' && sleep 0'
EXEC /bin/sh -c 'rm -f -r /home/ansible/.ansible/tmp/ansible-tmp-1526406851.13-36098482327457/ > /dev/null 2>&1 && sleep 0'
The full traceback is:
Traceback (most recent call last):
File "/tmp/ansible_bpILrC/ansible_module_k8s_raw.py", line 163, in
main()
File "/tmp/ansible_bpILrC/ansible_module_k8s_raw.py", line 159, in main
KubernetesRawModule().execute_module()
File "/tmp/ansible_bpILrC/ansible_modlib.zip/ansible/module_utils/k8s/raw.py", line 121, in execute_module
File "/tmp/ansible_bpILrC/ansible_modlib.zip/ansible/module_utils/k8s/raw.py", line 170, in _create
UnicodeEncodeError: 'ascii' codec can't encode character u'\ufffd' in position 171: ordinal not in range(128)

fatal: [k8s -> localhost]: FAILED! => {
"changed": false,
"module_stderr": "Traceback (most recent call last):\n File "/tmp/ansible_bpILrC/ansible_module_k8s_raw.py", line 163, in \n main()\n File "/tmp/ansible_bpILrC/ansible_module_k8s_raw.py", line 159, in main\n KubernetesRawModule().execute_module()\n File "/tmp/ansible_bpILrC/ansible_modlib.zip/ansible/module_utils/k8s/raw.py", line 121, in execute_module\n File "/tmp/ansible_bpILrC/ansible_modlib.zip/ansible/module_utils/k8s/raw.py", line 170, in _create\nUnicodeEncodeError: 'ascii' codec can't encode character u'\ufffd' in position 171: ordinal not in range(128)\n",
"module_stdout": "",
"msg": "MODULE FAILURE",
"rc": 1
}

tarea
@ansibot
Copy link
Contributor

ansibot commented May 15, 2018

Files identified in the description:

If these files are inaccurate, please update the component name section of the description or use the !component bot command.

click here for bot help

@ansibot
Copy link
Contributor

ansibot commented May 15, 2018

@ansibot ansibot added affects_2.5 This issue/PR affects Ansible v2.5 bug This issue/PR relates to a bug. module This issue/PR relates to a module. needs_triage Needs a first human triage before being processed. support:community This issue/PR relates to code supported by the Ansible community. labels May 15, 2018
@fabianvf
Copy link
Contributor

Could you post an example of your service.yml? I'm able to use the template lookup in my environment so I wonder if there's something in the file itself we're handling oddly.

@ansibot ansibot removed the needs_triage Needs a first human triage before being processed. label May 15, 2018
@ansibot
Copy link
Contributor

ansibot commented May 23, 2018

Files identified in the description:

If these files are inaccurate, please update the component name section of the description or use the !component bot command.

click here for bot help

@ansibot ansibot added deprecated This issue/PR relates to a deprecated module. traceback This issue/PR includes a traceback. labels May 23, 2018
@infernix
Copy link

I am getting this exact error even without a lookup.

Here's how to reproduce.

- name: Set working fact
   set_fact: 
     testreplicas: 4

- name: Test breaking  fact
  set_fact:
    test:
      replicas: 4

- name: Create test deployment
  k8s_raw:
    state: present
    name: test
    namespace: test
    definition:
      apiVersion: extensions/v1beta1
      kind: Deployment
      metadata:
        labels:
          app: test
      spec:
        replicas: "{{ test.replicas }}"
        template:
...

It fails on {{ test.replicas }} but using {{ testreplicas }} instead works fine.

@ehelms
Copy link
Contributor

ehelms commented Jun 27, 2018

I see the same issue and it can be simplified down to the following. If you try to set replicas: to a string (e.g. replicas: "2") this error will appear. If you use a variable, jinja2 will resolve that to a string causing the same issue.

@fabianvf
Copy link
Contributor

so if you use "{{ test.replicas | int }}" does it behave properly? I'm not sure what the difference between the testreplicas vs test.replicas case is though, @maxamillion do you have any thoughts on what might cause that?

@ehelms
Copy link
Contributor

ehelms commented Jun 28, 2018

@fabianvf Using Ansible 2.6 stable and latest openshift and kubernetes clients I get the following even with the cast to int:

The full traceback is:
  File "/tmp/ansible_qzoFPI/ansible_modlib.zip/ansible/module_utils/k8s/raw.py", line 171, in perform_action
    k8s_obj = resource.patch(definition, name=name, namespace=namespace).to_dict()
  File "/usr/lib/python2.7/site-packages/openshift/dynamic/client.py", line 33, in inner
    raise api_exception(e)

failed: [localhost] (item=candlepin) => changed=false 
  error: 500
  invocation:
    module_args:
      api_key: null
      cert_file: null
      context: null
      host: null
      key_file: null
      kubeconfig: null
      password: null
      ssl_ca_cert: null
      username: null
      verify_ssl: null
  item: candlepin
  msg: |-
    Failed to patch object: {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"unrecognized type: int32","code":500}
  reason: Internal Server Error
  status: 500

@fabianvf
Copy link
Contributor

it seems that doing test.replicas | int makes no difference. This issue is independent of the k8s modules though, seems to be a function of the templating system. Here's a playbook to reproduce it with just the debug module:

---

- name: K8s
  hosts: localhost
  gather_facts: no
  vars:
    test:
      replicas: 4
    testreplicas: 4
  tasks:
  - name: Create test deployment
    debug: var=numreplicas
    vars:
      numreplicas:
        replicas: "{{ test.replicas }}"

  - name: Create test deployment
    debug: var=numreplicas
    vars:
      numreplicas:
        replicas: "{{ testreplicas }}"
PLAY [K8s] ****************************************************************************************************************************************************

TASK [Create test deployment] *********************************************************************************************************************************
ok: [localhost] => {
    "numreplicas": {
        "replicas": "4"
    }
}

TASK [Create test deployment] *********************************************************************************************************************************
ok: [localhost] => {
    "numreplicas": {
        "replicas": 4
    }
}

PLAY RECAP ****************************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0

Bizarrely, if I add cast testreplicas (the one that is properly an int) to int, it will turn into a string.

---

- name: K8s
  hosts: localhost
  gather_facts: no
  vars:
    testreplicas: 4
  tasks:
  - name: Create test deployment
    debug: var=numreplicas
    vars:
      numreplicas:
        replicas: "{{ testreplicas }}"
  - name: Create test deployment
    debug: var=numreplicas
    vars:
      numreplicas:
        replicas: "{{ testreplicas|int }}"
PLAY [K8s] ****************************************************************************************************************************************************

TASK [Create test deployment] *********************************************************************************************************************************
ok: [localhost] => {
    "numreplicas": {
        "replicas": 4
    }
}

TASK [Create test deployment] *********************************************************************************************************************************
ok: [localhost] => {
    "numreplicas": {
        "replicas": "4"
    }
}

PLAY RECAP ****************************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0

@sivel
Copy link
Member

sivel commented Jun 28, 2018

Yes, this is a side effect of the interactions between Ansible and Jinja2. The new jinja2 native types functionality coming in Ansible 2.7 solves this (#32738)

Unfortunately, with a module such as k8s_raw that does not define a strict argument_spec that can validate and specify strict types for arguments, there isn't really a way to use a variable to supply an integer without jinja2 native types functionality.

fabianvf added a commit to fabianvf/forklift that referenced this issue Jun 28, 2018
fabianvf added a commit to fabianvf/forklift that referenced this issue Jun 29, 2018
ehelms pushed a commit to theforeman/forklift that referenced this issue Jun 29, 2018
* workaround ansible/ansible#40185

* Create rolebinding with Ansible module

* remove unnecessary oc command

* explicitly define project with annotations

* _exec -> exec

* {openshift|k8s}_raw -> k8s

* Update required ansible version

* use oc command until ansible/ansible#42116 is fixed
@ansibot
Copy link
Contributor

ansibot commented Jul 14, 2018

@willthames
Copy link
Contributor

I strongly recommend using a template

  k8s:
    definition: "{{ lookup('template', 'deployment.yml') | from_yaml }}"

and then you can do things like replicas: {{ replica_count }} in the template safely.

@ansibot
Copy link
Contributor

ansibot commented Jul 15, 2018

Files identified in the description:
None

If these files are inaccurate, please update the component name section of the description or use the !component bot command.

click here for bot help

@ansibot ansibot added support:core This issue/PR relates to code supported by the Ansible Engineering Team. and removed module This issue/PR relates to a module. support:community This issue/PR relates to code supported by the Ansible community. labels Jul 15, 2018
@ansibot
Copy link
Contributor

ansibot commented Jul 15, 2018

Files identified in the description:

If these files are inaccurate, please update the component name section of the description or use the !component bot command.

click here for bot help

@ansibot ansibot added module This issue/PR relates to a module. and removed support:core This issue/PR relates to code supported by the Ansible Engineering Team. labels Jul 15, 2018
@ansibot ansibot added the support:community This issue/PR relates to code supported by the Ansible community. label Jul 15, 2018
@ansibot ansibot added support:core This issue/PR relates to code supported by the Ansible Engineering Team. and removed support:community This issue/PR relates to code supported by the Ansible community. labels Sep 17, 2018
@ansibot ansibot added support:community This issue/PR relates to code supported by the Ansible community. and removed support:core This issue/PR relates to code supported by the Ansible Engineering Team. labels Oct 3, 2018
@ansibot ansibot added the k8s label Oct 11, 2018
@ansibot ansibot added the clustering Clustering category label Mar 5, 2019
@ansibot
Copy link
Contributor

ansibot commented Apr 14, 2019

Files identified in the description:
None

If these files are inaccurate, please update the component name section of the description or use the !component bot command.

click here for bot help

@ansibot ansibot added support:core This issue/PR relates to code supported by the Ansible Engineering Team. and removed deprecated This issue/PR relates to a deprecated module. module This issue/PR relates to a module. support:community This issue/PR relates to code supported by the Ansible community. labels Apr 14, 2019
johnpmitsch pushed a commit to johnpmitsch/forklift that referenced this issue Jun 27, 2019
* workaround ansible/ansible#40185

* Create rolebinding with Ansible module

* remove unnecessary oc command

* explicitly define project with annotations

* _exec -> exec

* {openshift|k8s}_raw -> k8s

* Update required ansible version

* use oc command until ansible/ansible#42116 is fixed
@fabianvf
Copy link
Contributor

close_me

I think the proper resolution if you're hitting this issue is to put your definition into a template instead of inline, which will allow you to not add the quotes and will allow the yaml loader to properly recognize the type.

@ansibot
Copy link
Contributor

ansibot commented Mar 26, 2020

Files identified in the description:

If these files are incorrect, please update the component name section of the description or use the !component bot command.

click here for bot help

@ansibot ansibot closed this as completed Mar 26, 2020
@ansible ansible locked and limited conversation to collaborators Apr 23, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
affects_2.5 This issue/PR affects Ansible v2.5 bug This issue/PR relates to a bug. clustering Clustering category k8s support:core This issue/PR relates to code supported by the Ansible Engineering Team. traceback This issue/PR includes a traceback.
Projects
None yet
Development

No branches or pull requests

7 participants