3

I am trying to configure a Mikrotik router using Ansible - as part of that task, I need to generate the actual command that is sent to the router. And somehow, some of the quotes simply... disappear from my string after Ansible parses it.

[ Edit - this seems to be related to jinja2_native. See the end of the question for the details ]

The minimum example I was able to build that showcases the problem is this:

- hosts: localhost
  gather_facts: false
  tasks:
  - vars:
      port: 20200
      cmd: >
        add chain=dstnat && dst-port="{{port}}"
        comment="%TR% - {{ansible_host}} - SSH for {{inventory_hostname}}" 
        dst-port="{{ port }}" protocol=tcp 
        }'
    debug:
      msg: "{{cmd}}"

When running this playbook, here is the result:

# ansible-playbook test.yml 
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [localhost] *****************************************************************************************************************

TASK [debug] *********************************************************************************************************************
Wednesday 29 April 2020  23:07:52 +0300 (0:00:00.052)       0:00:00.052 ******* 
ok: [localhost] => {
    "msg": "add chain=dstnat && dst-port=\"20200\" comment=\"%TR% - 127.0.0.1 - SSH for localhost  dst-port=20200\" protocol=tcp  }'\n"
}

Notice how some of the quotes are gone, and as a result the number of arguments in the command has totally changed. (and, of course, I noticed this only after spending several hours troubleshooting and wondering why the command was failing...)

Interestingly enough, if I change the text a bit, other quotes disappear:

- hosts: localhost
  gather_facts: false
  tasks:
  - vars:
      port: 20200
      cmd: >
        add chain=dstnat && dst-port="{{port}}"
        comment="{{ansible_host}} - SSH for {{inventory_hostname}}" 
        dst-port="{{ port }}" protocol=tcp 
        }'
    debug:
      msg: "{{cmd}}"
    tags: 
    - networking

# ansible-playbook test.yml 
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [localhost] *****************************************************************************************************************

TASK [debug] *********************************************************************************************************************
Wednesday 29 April 2020  23:12:12 +0300 (0:00:00.031)       0:00:00.031 ******* 
ok: [localhost] => {
    "msg": "add chain=dstnat && dst-port=\"20200 comment=127.0.0.1 - SSH for localhost  dst-port=20200\" protocol=tcp  }'\n"
}

It seems that whenever I have a sequence like }}" text_here "{{, the quotes are gone...

My questions are:

  1. Can anyone tell me why this happens?
  2. Can someone advise me on how I can avoid this issue? I have tried multiline strings (with double quotes, single quotes, > folding, etc) - same result...

[ Edit: when going through all the recent changes that might have caused this, I remembered enabling jinja2_native . And true enough, after setting jinja2_native back to False in ansible.cfg, the problem goes away...

# ansible-playbook test.yml 
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [localhost] *****************************************************************************************************************

TASK [debug] *********************************************************************************************************************
Wednesday 29 April 2020  23:55:29 +0300 (0:00:00.029)       0:00:00.029 ******* 
ok: [localhost] => {
    "msg": "add chain=dstnat && dst-port=\"20200\" comment=\"127.0.0.1 - SSH for localhost \"  dst-port=\"20200\" protocol=tcp  }'\n"
}

]

Bogd
  • 673
  • 9
  • 16
  • 1
    ansible v2.9.5 / python 3.6.9 => I can't reproduce your problem. Strings are outputted exactly as expected. – Zeitounator Apr 29 '20 at 20:38
  • @Zeitounator - I have one more configuration change that might be relevant. See my later edit regarding `jinja2_native` – Bogd Apr 29 '20 at 21:10

1 Answers1

2

I was able to get an answer on github - a big thanks to sivel for that!

I am also posting it here, for reference.

"The[re] was an issue with upstream jinja2, that was resolved in jinja2 2.11."

Some more links relevant to the issue: see here and here.

Bogd
  • 673
  • 9
  • 16
  • 1
    Thanks for that because I was going to post: "I still can't reproduce the issue" :) – Zeitounator Apr 29 '20 at 21:37
  • @Zeitounator - I should have mentioned this in the question, but I am using ansible installed via apt on Ubuntu 18.04 . And jinja2 from the Ubuntu repos seems to still be on v1.10. Could you share some info about your environment? Maybe it's time for me to switch... :) – Bogd Apr 30 '20 at 07:19
  • 1
    I always installl ansible via pip, never through the system packages, whatever the distribution. This is much more convenient and with virtualenvs and user installs, you can manage as many versions and library dependency layout as you want for any user on the system. This is [how I do it](https://github.com/ansible-ThoTeam/nexus3-oss/blob/ce458dc05b8292ac8012071c7760be17e7dd5709/.travis.yml#L17) for one for my role's CI with the following [requirements.txt](https://github.com/ansible-ThoTeam/nexus3-oss/blob/master/requirements.txt) – Zeitounator Apr 30 '20 at 08:14
  • Looks like I definitely should look into changing my environment :) . Thank you so much for all the details! – Bogd Apr 30 '20 at 08:38