微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Ansible 读取嵌套的 json 值和匹配变量

如何解决Ansible 读取嵌套的 json 值和匹配变量

我在 Ansible 剧本中使用它:

- name: Gather info from Vcenter
  vmware_vm_info:
    hostname: "{{ result_item.vcenter }}"
    username: "{{ ansible_username }}"
    password: "{{ ansible_password }}"
    validate_certs: no
  register: vminfo
  loop: "{{ result.list }}"
  loop_control:
    loop_var: result_item

我遍历了一个包含 VM 及其 Vcenter 列表的 csv。 Ansible 任务的 json 输出是这样的:

{
  "results": [
    {
      "changed": false,"virtual_machines": [
        {
          "guest_name": "Server1","guest_fullname": "SUSE Linux Enterprise 11 (64-bit)","power_state": "poweredOn",},{
          "guest_name": "Server2","guest_fullname": "FreeBSD Pre-11 versions (64-bit)",

现在我需要为我的 csv 中的 VM 查询输出(guest_name 匹配 vmname)并使用 set_fact 来指示 csv 中的 VM 是 powerOff 还是 powerOn。接下来,我可以将其用作是否根据当前状态关闭 VM 电源的条件。

在将 csv 中的 VM 名称匹配到 json 输出然后获取相应的电源状态时,我似乎无法让 json_query 工作。有什么想法吗?

CSV 文件

vmname    vcenter  
Server1   Vcenter1  
Server2   Vcenter1

解决方法

问:set_fact 以指示 CSV 中的 VM 是关闭还是打开。

答:例如

    - read_csv:
        path: servers.csv
        dialect: excel-tab
      register: result
    - set_fact:
        servers: "{{ result.list|map(attribute='vmname')|list }}"
    - set_fact:
        virtual_machines: "{{ virtual_machines|default([]) +
                              [dict(_servers|zip(_values))] }}"
      loop: "{{ vminfo.results }}"
      vars:
        _servers: "{{ servers|intersect(_dict.keys()|list) }}"
        _values: "{{ _servers|map('extract',_dict)|list }}"
        _dict: "{{ item.virtual_machines|
                   items2dict(key_name='guest_name',value_name='power_state') }}"
    - debug:
        var: virtual_machines

给予

  virtual_machines:
  - Server1: poweredOn
    Server2: poweredOn

vminfo.results 中缺少的服务器将被静默忽略。


问:"将其用作是否关闭虚拟机电源的条件。"

A:例如第一台主机中的Server1

    - debug:
        msg: "Host={{ _host }} VM={{ _vm }} is poweredOn"
      when: virtual_machines[_host][_vm] == 'poweredOn'
      vars:
        _host: 0
        _vm: Server1

给予

  msg: Host=0 VM=Server1 is poweredOn
,

我想,根据您的示例,您确实有一个 TSV,因此是制表符分隔值而不是 CSV,它代表 逗号 分隔值。

基于此,read_csv 模块以及 dialect: excel-tab 将帮助您阅读 TSV。

然后,您将需要使用 filter projection 根据 TSV 文件中的数据查询 JSON。

您可能还需要 flatten the projection 删除由 resultsvirtual_machines 中的列表创建的双打列表。

结果 JMESPath 查询的示例,对于 Server1 最终是:

results[].virtual_machines[?
  guest_name == `Server1`
]|[]|[0].power_state

然后将所有这些都放在一个剧本中,我们最终得到:

- hosts: localhost
  gather_facts: no

  tasks:
    - read_csv:
        path: servers.csv
        dialect: excel-tab
      register: servers
   
    - debug:
        msg: >-
          For {{ item.vmname }},the state is {{ 
            vminfo | 
            json_query(
              'results[].virtual_machines[?
                guest_name == `' ~ item.vmname ~ '`
              ]|[]|[0].power_state'
            ) 
          }}
      loop: "{{ servers.list }}"
      loop_control:
        label: "{{ item.vmname }}"
      vars:
        vminfo:
          results:
            - changed: false
              virtual_machines:
              - guest_name: Server1
                guest_fullname: SUSE Linux Enterprise 11 (64-bit)
                power_state: poweredOn
              - guest_name: Server2
                guest_fullname: FreeBSD Pre-11 versions (64-bit)
                power_state: poweredOn

总结如下:

PLAY [localhost] **************************************************************************************************

TASK [read_csv] ***************************************************************************************************
ok: [localhost]

TASK [debug] ******************************************************************************************************
ok: [localhost] => (item=Server1) => 
  msg: For Server1,the state is poweredOn
ok: [localhost] => (item=Server2) => 
  msg: For Server2,the state is poweredOn

PLAY RECAP ********************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0    

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。