首页 > 解决方案 > 为某些键迭代字典 Ansible

问题描述

关于如何迭代某个字典的疑问

---
- name: main playbook
  hosts: localhost
  tasks:
    - name: Set fact
      var:
        tower_objects_organizations:
          security:
            org: ORG_I-SSO-ES-ADM-SSMM
            teams:
              - I-SSO-ES-ADM-SSMM
              - I-SSO-ES-ADM-SSMM2
          monit:
            org: ORG_I-SSO-ES-TS-MONIT
            teams:
              - I-SSO-ES-TS-MONIT

    - name: "[{{ productname }}][parallel set organization] Set organizations fact"
      debug:
        msg: "XXXXX"
      with_items: "{{ tower_objects_organizations| dict2items | subelements('value.teams') }}"

有谁知道我如何遍历每个子目录中的团队(安全,监控......)并以团队作为键并将其组织作为值填充字典,即 I-SSO-ES-ADM-SSMM: ORG_I-SSO-ES-ADM-SSMM, I-SSO-ES-ADM-SSMM2: ORG_I-SSO-ES-ADM-SSMM, I-SSO-ES-TS-MONIT:ORG_I-SSO-ES-TS-MONIT 使用子元素我能够到达团队列表,但是输出不是预期的

标签: ansiblejinja2

解决方案


有和没有自定义过滤器的解决方案:

当我必须对 dict 执行一些复杂操作时,我更喜欢使用自定义过滤器:

您在 playbook 文件夹中创建一个文件夹filter_plugins(我已将文件命名为myfilters.py和过滤器customfilter

#!/usr/bin/python
class FilterModule(object):
    def filters(self):
        return {
            'customfilter': self.customfilter
        }

    def customfilter(self, obj):
        result = {}

        for k in obj:
            org = obj[k]['org']
            for l in obj[k]['teams']:
                result[l] = org

        return result

剧本样本:

  tasks:
    - name: Set fact
      set_fact:
        result: "{{ tower_objects_organizations | customfilter}}"
      vars:
        tower_objects_organizations:
          security:
            org: ORG_I-SSO-ES-ADM-SSMM
            teams:
              - I-SSO-ES-ADM-SSMM
              - I-SSO-ES-ADM-SSMM2
          monit:
            org: ORG_I-SSO-ES-TS-MONIT
            teams:
              - I-SSO-ES-TS-MONIT
          others:
            org: ORG_I-SSO-ES-TS-OTHER
            teams:
              - I-SSO-ES-TS-OTHER0
              - I-SSO-ES-TS-OTHER1            

    - name: display result
      debug:
        var: result 

结果:

ok: [localhost] => 
  result:
    I-SSO-ES-ADM-SSMM: ORG_I-SSO-ES-ADM-SSMM
    I-SSO-ES-ADM-SSMM2: ORG_I-SSO-ES-ADM-SSMM
    I-SSO-ES-TS-MONIT: ORG_I-SSO-ES-TS-MONIT
    I-SSO-ES-TS-OTHER0: ORG_I-SSO-ES-TS-OTHER
    I-SSO-ES-TS-OTHER1: ORG_I-SSO-ES-TS-OTHER

编辑

我认为另一种没有自定义过滤器但可读性较差的解决方案:

- set_fact:
    result: "{{ result | d({}) | combine(dict(item.value.teams|product([item.value.org]))) }}"
  loop: "{{ tower_objects_organizations|dict2items }}"               

- name: debug result
  debug:      
    var: result 

推荐阅读