2

I am using this in an Ansible playbook:

- 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

I loop through a csv which has a list of VMs and their Vcenters. The json output from the Ansible task is this:

{
  "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",
        },

Now I need to query this output for the VMs in my csv (guest_name matches vmname) and use set_fact to indicate whether the VMs in the csv are poweredOff or poweredOn. Next I can use it as a conditional on whether to power off the VM or not based on its current status.

I can't seem to get the json_query to work when matching to the VM name in the csv to the json output and then getting the corresponding power status. Any ideas?

CSV file:

vmname    vcenter  
Server1   Vcenter1  
Server2   Vcenter1
β.εηοιτ.βε
  • 33,893
  • 13
  • 69
  • 83
Julia L
  • 57
  • 6

2 Answers2

1

Q: "set_fact to indicate whether the VMs in the CSV are powered off or powered on."

A: For example

    - 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

gives

  virtual_machines:
  - Server1: poweredOn
    Server2: poweredOn

Servers missing in the vminfo.results will be silently ignored.


Q: "Use it as a conditional on whether to power off the VM or not."

A: For example Server1 in the first host

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

gives

  msg: Host=0 VM=Server1 is poweredOn
Vladimir Botka
  • 58,131
  • 4
  • 32
  • 63
0

I suppose, from your your example that you do have a TSV, so a tab separated values and not a CSV, which stands for comma separated values.

Based on this, the read_csv module, along with the dialect: excel-tab will help you read your TSV.

Then, you will need to use a filter projection to query the JSON based on the data in your TSV file.

You could also need to flatten the projection to get rid of the doubles list created by both the list in results and in virtual_machines.

An example of the resulting JMESPath query, for the Server1 ends up being:

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

Then with all this in a playbook we do end up with:

- 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

Which yields the recap:

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    
β.εηοιτ.βε
  • 33,893
  • 13
  • 69
  • 83