使用 with_nested 从 API 开始循环

ansible looping from API using with_nested

我有 ansible-playbook 可以从叶路由器循环 ping 到主干。 ansible任务执行成功,可以看到如下:

  - name: PING FROM LEAF TO SPINE
    shell: ping {{item[0]}} -c 2 -s {{item[2]}} | grep -i received | awk '{print "{{item[3]}} :\n"," {{item[1]}} :", }'
    register: p
    with_nested:
    - [ ['10.0.0.1','Spine-01'], ['10.0.0.2','Spine-02'] ]
    - [ ['10.0.0.3','Leaf-01'], ['10.0.0.6','Leaf-04'], ['10.0.0.9','Leaf-07'] ]

但我不想手动编写,而是想从一个保存所有数据的变量中调用设备名称和 ip。我拥有的变量称为“get_devices”,包含设备名称、设备 ip 和设备类型 (spine/leaf) 形式的数据。我是 Ansible 的新手,我正在考虑像这样创建 spine 和 leaf 变量:

 - name: DEFINE VARIABLE SPINE
   set_fact: spine = "{{ item }}"
   loop: "{{ get_devices.json.results }}"
   when: "item.device_role.name == 'Spine'"

 - name: DEFINE VARIABLE LEAF
   set_fact: leaf = "{{ item }}"
   loop: "{{ get_devices.json.results }}"
   when: "item.device_role.name == 'Leaf'"

 - name: PING FROM LEAF TO SPINE
   shell: ping {{item[0]}} -c 2 -s {{item[2]}} | grep -i received | awk '{print "{{item[3]}} :\n"," {{item[1]}} :", }'
   register: p
   with_nested:
   - [ ' {{ spine.ip_address}} ','{{ spine.name }}' ]
   - [ ' {{ leaf.ip_address}} ','{{ leaf.name }}' ]

但是,它导致了这样的错误:

fatal: [localhost]: FAILED! => {"msg": "'spine' is undefined"}

知道如何解决这个问题吗?或者如果还有其他方法可以做到这一点,请告诉我。谢谢。

编辑:这是 get_devices.json.results 的部分结果:

    {
        "name": "Leaf-Ganesha-CRCS-01",
        "ip_address": "10.0.0.3"
        "device_role": {
            "display": "Leaf",
            "name": "Leaf",
        }
    },
    {
        "name": "Leaf-02",
        "ip_address": "10.0.0.6"
        "device_role": {
            "display": "Leaf",
            "name": "Leaf",
        }
    },
    {
        "name": "Spine-01",
        "ip_address": "10.0.0.1"
        "device_role": {
            "display": "Spine",
            "name": "Spine",
        }
    },
    . . . 

给定列表

get_devices.json.results:
  - device_role:
      display: Leaf
      name: Leaf
    ip_address: 10.0.0.3
    name: Leaf-Ganesha-CRCS-01
  - device_role:
      display: Leaf
      name: Leaf
    ip_address: 10.0.0.6
    name: Leaf-02
  - device_role:
      display: Spine
      name: Spine
    ip_address: 10.0.0.1
    name: Spine-01

分组路由器并创建字典

routers: "{{ dict(get_devices.json.results|groupby('device_role.name')) }}"
spine: "{{ routers.Spine|items2dict(key_name='name', value_name='ip_address') }}"
leaf: "{{ routers.Leaf|items2dict(key_name='name', value_name='ip_address') }}"

给予

  routers:
    Leaf:
    - device_role:
        display: Leaf
        name: Leaf
      ip_address: 10.0.0.3
      name: Leaf-Ganesha-CRCS-01
    - device_role:
        display: Leaf
        name: Leaf
      ip_address: 10.0.0.6
      name: Leaf-02
    Spine:
    - device_role:
        display: Spine
        name: Spine
      ip_address: 10.0.0.1
      name: Spine-01

  spine:
    Spine-01: 10.0.0.1

  leaf:
    Leaf-02: 10.0.0.6
    Leaf-Ganesha-CRCS-01: 10.0.0.3

然后迭代 spineleaf 路由器的嵌套列表,例如

    - debug:
        msg: >-
          ping {{ item.0.value }} -c 2 -s {{ item.1.value }} |
          grep -i received |
          awk '{print "{{ item.1.key }} :\n"," {{ item.0.key }} :", }'
      with_nested:
        - "{{ spine|dict2items }}"
        - "{{ leaf|dict2items }}"

将创建命令

msg: ping 10.0.0.1 -c 2 -s 10.0.0.3 | grep -i received | awk '{print "Leaf-Ganesha-CRCS-01 :\n"," Spine-01 :", }'
msg: ping 10.0.0.1 -c 2 -s 10.0.0.6 | grep -i received | awk '{print "Leaf-02 :\n"," Spine-01 :", }'

按照您的逻辑并使用 product 的另一个答案:

  tasks:
    - name: DEFINE VARIABLE SPINE
      set_fact: 
        spine: "{{ spine | d([]) + [ {'name': item.name, 'ip': item.ip_address} ] }}"
      loop: "{{ get_devices.json.results }}"
      when: "item.device_role.name == 'Spine'"

    - name: DEFINE VARIABLE LEAF
      set_fact: 
        leaf: "{{ leaf | d([]) + [ {'name': item.name, 'ip': item.ip_address} ] }}"
      loop: "{{ get_devices.json.results }}"
      when: "item.device_role.name == 'Leaf'"

    - name: PING FROM LEAF TO SPINE
      debug:
        msg: ping {{item.0.ip}} -c 2 -s {{item.1.ip}} | grep -i received | awk '{print "{{item.1.name}} :\n"," {{item.0.name}} :", }'
      register: p
      loop: "{{ spine | product(leaf)|list }}"

结果:

"msg": "ping 10.0.0.1 -c 2 -s 10.0.0.3 | grep -i received | awk '{print \"Leaf-Ganesha-CRCS-01 :\n\",\" Spine-01 :\", }'"

"msg": "ping 10.0.0.1 -c 2 -s 10.0.0.6 | grep -i received | awk '{print \"Leaf-02 :\n\",\" Spine-01 :\", }'"