2016-06-07 36 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