Ansible通过一组dict循环,注册该列表,然后打印特定的输出

Ansible通过一组dict循环,注册该列表,然后打印特定的输出,ansible,Ansible,这就是我要做的 使用内置网络模块登录到网络交换机并发送命令 将该命令注册为var 打印该变量或在剧本中的其他地方使用该变量 这似乎很简单,对吗?但以下是我面临的问题 首先,我登录到一个设备(当前),然后在一个循环中发出一个简单的命令(这将变成两个命令和两个输出) 我想把这两个命令的输出放入一个列表中。 接下来,我将遍历这个列表,并检查每个命令返回的值(记住这是2个输出) 以下是当前的剧本: - name: Checking for free ports nxos_command:

这就是我要做的

  • 使用内置网络模块登录到网络交换机并发送命令
  • 将该命令注册为var
  • 打印该变量或在剧本中的其他地方使用该变量
  • 这似乎很简单,对吗?但以下是我面临的问题

    首先,我登录到一个设备(当前),然后在一个循环中发出一个简单的命令(这将变成两个命令和两个输出)

    我想把这两个命令的输出放入一个列表中。 接下来,我将遍历这个列表,并检查每个命令返回的值(记住这是2个输出)

    以下是当前的剧本:

    - name: Checking for free ports
      nxos_command: 
        provider: 
          host: "{{inventory_hostname}}" 
          username: "{{user.stdout}}"
        commands: "show run interface {{ item.interface }}"
      when: device.ansible_facts.ansible_device_os == 'nxos' 
      loop: "{{ device_vars[inventory_hostname] }}"
      register: ports
    
    然后,当我使用debug时,我会得到一堆数据:

    - debug: 
        var: item.stdout
      loop: "{{ports.results}}"
      register: ports_output
    
    然后我设置事实,然后再次调试(打印):

    - name: Setting var
      set_fact: 
        port_list: "{{item.stdout}}"
      loop: "{{ports.results}}"
    
    - debug: var=port_list
    
    我遇到的问题是,即使端口列表是一个列表,ansible只返回该列表的一个值。这是初始播放的最后一个值/命令。所以我假设它正在某个地方被覆盖

    以下是我想要的输出:

    ok: [device1] => {
        "port_list": [
            "1st output from the device",
            "2nd output from the device"
        ]
    }
    
    但我能得到的只是:

    ok: [device1] => {
        "port_list": [
            "2nd output from the device"
        ]
    }
    
    以下是我在
    网站中声明的变量。yml

      vars:
        device_vars:
          device1:                                                                 
          - interface: Ethernet1/1
            description: "some description
            vlan: 1
          - interface: Ethernet1/2
            description: "some description"
            vlan: 1
        port_list: []
    
    我想我的问题是,我正在处理一份清单清单清单等清单清单,而Ansible似乎对此并不友好。 我已设法将数据转换成这种格式(省略):


    我花了3天时间在这上面,似乎找不到解决方案。

    将元素添加到列表中

    port_list: "{{ port_list + [item.stdout] }}"
    

    在循环过程中,
    set\u fact
    覆盖变量,因此您只看到最后一个变量正在被设置。但是,您也可以使用
    set\u fact
    将变量附加到先前指定的值,并包括所有变量,如下所示:

    - name: Setting var
      set_fact: 
        port_list: "{{ port_list|default([]) + [item.stdout] }}"
      loop: "{{ports.results}}"
    

    default([])
    上面的过滤器是给
    port\u list
    变量分配一个初始值。

    我最后使用了这个:
    port\u list:“{{{port\u list | default([])+item.stdout}”
    因为我不想要列表列表,所以只有一个列表-谢谢大家!编辑:这与dupe不同,因为我使用_列表管理
    ,而不是使用_项管理
    ,这是不同的。此外,数据来自ansible输出,而不是用户定义的。如果数据不同,那么为什么重复目标包含您接受的数据?如果你认为这是完全不同的,那么为什么你一开始就接受了这个错误的答案? 重复目标问题与您的问题完全相同,它还包含更好的解决方案,您只需使用
    map(attribute='stdout.0')
    - name: Setting var
      set_fact: 
        port_list: "{{ port_list|default([]) + [item.stdout] }}"
      loop: "{{ports.results}}"