Add quotes to elemens of the list in jinja2 (ansib

2020-04-02 06:56发布

I have very simple line in the template:

ip={{ip|join(', ')}}

And I have list for ip:

ip:
 - 1.1.1.1
 - 2.2.2.2
 - 3.3.3.3

But application wants IPs with quotes (ip='1.1.1.1', '2.2.2.2').

I can do it like this:

ip:
 - "'1.1.1.1'"
 - "'2.2.2.2'"
 - "'3.3.3.3'"

But it is very ugly. Is any nice way to add quotes on each element of the list in ansible?

Thanks!

8条回答
We Are One
2楼-- · 2020-04-02 07:08

Actually there is a very simple method to achieve this:

{{ mylist | map('quote') | join(', ') }}

The filter map iterates over every item and let quote process it. Afterwards you can easily join them together.

查看更多
兄弟一词,经得起流年.
3楼-- · 2020-04-02 07:13

NOTE This is similar to Kashyap's answer, but i needed a slightly different version: Using it to double quote each items in a bash array), eg. result should be:

SOME_LIST=( "Johnny" "Joey" "Dee Dee" "Tommy" )

projects/ansible/expand_list.yml

---
- hosts: localhost
  connection: local

  vars:
    some_list:
      - Johnny
      - Joey
      - Dee Dee
      - Tommy

  tasks:
    - name: "Expand the ramones band members list."
      template:
        src: "templates/expand_list.conf.j2"
        dest: "/var/tmp/ramones.conf"

projects/ansible/templates/expand_list.conf.j2

SOME_LIST=( "{{ '" "'.join(some_list) }}" )
查看更多
不美不萌又怎样
4楼-- · 2020-04-02 07:14

You can use regex_replace, f.e. in a j2 template file:

(ip={{ip | map('regex_replace', '(.*)', "'\\1'") | join(',')}})

If you do this inline in a play, do not forget to escape the double quotes. Here is a full example:

- hosts: localhost
  gather_facts: no
  vars:
    ip:
    - 1.1.1.1
    - 2.2.2.2
    - 3.3.3.3
    ip_result: "{{ip | map('regex_replace', '(.*)', \"'\\1'\") | join(',')}}"
  tasks:
  - debug: msg="(ip={{ip_result}})"
  - copy: content="(ip={{ip_result}})" dest=./ip_result.txt

Content of ip_result.txt:

$ cat ip_result.txt
(ip='1.1.1.1','2.2.2.2','3.3.3.3')
查看更多
放荡不羁爱自由
5楼-- · 2020-04-02 07:15

I've developed a custom wrap filter

def wrap(value, wrapper = '"'):
  return wrapper + value + wrapper

class FilterModule(object):
  def filters(self):
    return {
      'wrap': wrap
    }

As you can see wrapper is customizable and defaults to "

You can use it this way

ip={{ ip | map('wrap') | join(', ') }}

Disclaimer: I'm a python and ansible newbie

查看更多
淡お忘
6楼-- · 2020-04-02 07:28

try:

- hosts: localhost
  tags: s20
  gather_facts: no
  vars:
    ip:
      - 1.1.1.1
      - 2.2.2.2
      - 3.3.3.3
    joined_ip: "'{{ \"', '\".join(ip)}}'"
  tasks:
  - debug: msg="(ip={{joined_ip}})"

PS: ansible supports a bit of python code execution within {{}}, which is what i'm misusing here.

查看更多
做自己的国王
7楼-- · 2020-04-02 07:28

I found the simplest way to do this with an existing Ansible filter is using regex_replace.

{{ ip | map("regex_replace","(.+)","\'\\1\'") | join(',')}}
查看更多
登录 后发表回答