在一个ansible剧本中合并两个复杂的词典

时间:2017-05-10 11:49:11

标签: ansible jinja2

我找不到合并两个变量变量的方法。 由于它们在我的剧本的几个部分中使用,他们必须留在这个结构中。

我想要做的是在主机属于特定组时设置特殊的ssh公钥。

主机:

...
[special-bla]
blahost1
blahost2
...

乏:

user_list:
  - user:     root
    uid:      0
    # ... other A settings ...
    keys:
      - {
          file: files/ssh/pubkeys/admin1.pub,
          options: 'from="10.28.89.0/24"',
        }
      - {
          file: files/ssh/pubkeys/admin2.pub,
          options: 'from="10.28.89.0/24"',
        }
      - {
          file: files/ssh/pubkeys/admin3.pub,
          options: 'from="10.28.10.32,10.28.89.0/24"',
        }

special_users:
  special_bla_users:
    - user:     root
      # ... other B settings ...
      keys:
        - {
            file: files/ssh/pubkeys/bla/bla_admin.pub,
            options: 'from="10.0.0.1"',
          }

在我的ansible playbook中,我根据主机是否在特定组中创建了一个special_local_users列表:

  - name: Create special_local_users list
    set_fact:
      special_local_user_list: |
        {%  for item in special_host_groups -%}
        {%    set section= item ~ '_users' %}
        {%    if special_users[section] is defined -%}
        {%      for user in special_users[section] -%}
        {{ user | to_json }},
        {%-     endfor %}
        {%-   endif %}
        {%- endfor %}

现在我想合并两个列表的设置。哪个应该导致

user_list:
  - user:     root
    uid:      0
    # ... other A settings ...
    # ... other B settings ...
    keys:
      - {
          file: files/ssh/pubkeys/admin1.pub,
          options: 'from="10.28.89.0/24"',
        }
      - {
          file: files/ssh/pubkeys/admin2.pub,
          options: 'from="10.28.89.0/24"',
        }
      - {
          file: files/ssh/pubkeys/admin3.pub,
          options: 'from="10.28.10.32,10.28.89.0/24"',
        }
      - {
          file: files/ssh/pubkeys/bla/bla_admin.pub,
          options: 'from="10.0.0.1"',
        }

我对jinja2的了解非常有限,所以我找不到方法。

有什么想法吗? 提前致谢!    拉斯

1 个答案:

答案 0 :(得分:0)

很抱歉...... 我自己找到了一个解决方案:

  - name: Merge user_list with special_local_user_list
    set_fact:
      user_list: |
        {%  set user_list_users=user_list | map(attribute='user') | list %}
        {%  set special_local_user_list_users=special_local_user_list | map(attribute='user') | list %}
        {%  set _users=user_list | map(attribute='user') | list %}
        {%  for item1 in special_local_user_list -%}
        {%    if item1['user'] in user_list_users %}
        {%      for item2 in user_list if item2['user'] == item1['user'] -%}
        {{
                item1.update(keys = item1['keys'] + item2['keys'])
        }}{{ item2 | combine(item1) }},
        {%-     endfor %}
        {%-   else %}
        {{ item1 }},
        {%-   endif %}
        {%- endfor %}
        {%  for item2 in user_list if item2['user'] not in special_local_user_list_users -%}
        {{ item2 }},
        {%- endfor %}

它看起来不太酷,但它确实有效。

它结合了除添加的键之外的所有值。