2016-06-07 67 views
1

我在尋找建議。我有以下代碼動態創建一個列表,然後我可以稍後在模板中使用。在Ansible中創建動態列表的正確方法

這是我放在一起的測試代碼的副本 - 對於我剛添加admins | regex_replace變量到j2模板中的實際角色。

--- 

    - hosts: localhost 
    gather_facts: false 

    vars: 
     # define empty admins var first so ansible doesn't complain 
     admins: 

     admin_accounts: 
     - name: john 
     uid: 1000 
     group: sysadmin 
     shell: /bin/bash 
     comment: "Unix Administrator" 
     - name: paul 
     uid: 1001 
     group: sysadmin 
     shell: /bin/bash 
     comment: "Unix Administrator" 
     - name: george 
     uid: 1002 
     group: sysadmin 
     shell: /bin/bash 
     comment: "Unix Administrator" 
     - name: ringo 
     uid: 1003 
     group: sysadmin 
     shell: /bin/bash 
     comment: "Unix Administrator" 

    tasks: 

     - name: build array of admin user names 
     set_fact: admins="{{ admins}} {{ item.name }}" 
     with_items: "{{ admin_accounts }}" 

     # print out the fact piping through two jinja2 filters 
     # careful with word wrapping 
     - debug: msg={{ admins | regex_replace('\s+',', ') | regex_replace`(',\s(.*)','\\1') }}` 

這給了我以下內容:

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

TASK [build array of admin user names] ***************************************** 
ok: [localhost] => (item={u'comment': u'Unix Administrator', u'shell': u'/bin/bash', u'group': u'sysadmin', u'name': u'john', u'uid': 1000}) 
ok: [localhost] => (item={u'comment': u'Unix Administrator', u'shell': u'/bin/bash', u'group': u'sysadmin', u'name': u'paul', u'uid': 1001}) 
ok: [localhost] => (item={u'comment': u'Unix Administrator', u'shell': u'/bin/bash', u'group': u'sysadmin', u'name': u'george', u'uid': 1002}) 
ok: [localhost] => (item={u'comment': u'Unix Administrator', u'shell': u'/bin/bash', u'group': u'sysadmin', u'name': u'ringo', u'uid': 1003}) 

TASK [debug] ******************************************************************* 
ok: [localhost] => { 
    "msg": "john, paul, george, ringo" 
} 

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

所以......我得到了我所需要的,但我要對正確的方式?

在Centos 7.2上運行的Ansible版本是2.0.2.0。

在此先感謝。


編輯:得到的過濾器結束這樣看:

- name: build list of admin user names 
    set_fact: 
     admin_list: "{{ admin_accounts | selectattr('state', 'equalto', 'present') | map(attribute='name') | join(', ') }}" 
    - debug: msg={{ admin_list }} 

已經添加了另一個參數來YAML:

state: absent 

林戈被排除在外,如需要的話。

回答

2

過濾器將在列表上運行,所以with_items真的很浪費,而正則表達式對你所做的事情來說是非常愚蠢的。你真的想要一個逗號分隔的字符串,還是隻想要從admin_accounts列表中提取的用戶名列表?

如果你只是想列表,爲什麼不:

set_fact: 
    admin_usernames: "{{ admin_accounts | map(attribute='name') | list }}" 

...如果你真的想用逗號分隔的列表作爲扁帶,只需添加一個連接過濾器:

set_fact: 
    admin_usernames: "{{ admin_accounts | map(attribute='name') | join(', ') }}" 

但是,如果你的最終目標是一個模板,我會建議在模板內部這樣做,因爲這看起來相當格式化相關,而不是邏輯相關(除非你只是簡化堆棧溢出目的)。

+0

Exac tly我不知道我在找什麼,非常感謝你!該代碼示例是爲該帖子創建的,假設這是用於模板是正確的,但是我不知道如何獲得j2中需要的格式。 非常感謝,非常感謝! – Rowley

+0

不好意思問一下,但是關掉那個,有沒有可以過濾的條件,可以讓我有條件映射?我引用了一些用於創建用戶帳戶的json,並使用「state」屬性來計算sudoers的帳戶別名。使用with_items和一起實現期望的效果。我無法在無用的過濾器文檔中看到如何在沒有編寫自己的過濾器的情況下執行此操作。我剛剛有一種方法... – Rowley

+0

剛纔在過濾器[here](http://jinja.pocoo.org/docs/dev/templates/#builtin-filters)上找到了一個體面的頁面,並發現了selectattr和rejectattr。不幸的是,它看起來像我當前版本的使用jinja2.7,而不是2.8,因此我得到了「沒有測試命名爲'equalto'。 – Rowley