nneedofhelp
nneedofhelp

Reputation: 1

how to query json objects in ansible

When I query a json object I need to limit it to a top level object. Please excuse my ignorance as I am new to this.

I have read several post and reviewed the JMESPath tutorial and examples and I feel I'm close but not quit there yet.


  - name: cluster vms
    hosts: localhosts
    connection: local
    gather_facts: no
    vars:
      - username: me
      - password: mypassword
      - host: host1
    tasks:
      - shell: python getvmsbycluster.py -s myvcenter -u '{{ username }}' -p '{{ password }}'
        delegate_to: localhost
        register: cluster_facts

      - set_facts:
          clusters: "{{ cluster_facts.stdout|from_json }}"
      - debug:
          msg: "{{ clusters |json_query('mydatacenter.*.*') }}

Sample output ...

ok: [localhost] => {
     "msg": [
         [],
         [
             {
                "virtualmachine1": {
                "annotation": "", 
                "cpu": "2", 
                "diskGB": "204.00", 
                "folder": "folder1", 
                "mem": "4", 
                "net": {
                    "00:00:00:00:00:01": {
                        "connected": true, 
                        "ip": "X.X.X.X", 
                        "netlabel": "vlan1", 
                        "prefix": 23
                    }
                }, 
                "ostype": "Microsoft Windows Server 2012 (64-bit)", 
                "path": "[datastore1] virtualmachine1/virtualmachine1.vmx", 
                "state": "poweredOn"
            }, 
            "virtualmachine2": {
                "annotation": "", 
                "cpu": "2", 
                "diskGB": "170.00", 
                "folder": "folder2", 
                "mem": "10", 
                "net": {
                    "00:00:00:00:00:02": {
                        "connected": true, 
                        "ip": "X.X.X.X", 
                        "netlabel": "vlan2", 
                        "prefix": 24
                    }
                }, 
                "ostype": "Red Hat Enterprise Linux 6 (64-bit)", 
                "path": "[datastore2] virtualmachine2/virtualmachine2.vmx", 
                "state": "poweredOn" 

I would like to get a to point where I only see: "virtualmachine1" "virtualmachine2"

Here is a sample of "clusters"
ok: [localhost] => {
"msg": {
    “mydatacenter”: {
        “mycluster”: {
            “myesxhost”: {
                "virtualmachine1”: {
                    "annotation": "", 
                    "cpu": "2", 
                    "diskGB": "38.00", 
                    "folder": “folder1”, 
                    "mem": "4", 
                    "net": {}, 
                    "ostype": "Red Hat Enterprise Linux 6 (64-bit)", 
                    "path": “[datastore1] virtualmachines1/virtualmachine1.vmtx", 
                    "state": "poweredOff

Upvotes: 0

Views: 700

Answers (1)

mdaniel
mdaniel

Reputation: 33231

Based solely on the output you provided, it would be this:

- debug:
    msg: >-
     {{ clusters | json_query("mydatacenter.*.*") | first | first |
        dict2items | map(attribute="key") | list }}

Since each .* in the JMESPath seems to produce a list of the matching children, so we need to "de-list" them, which is what the two first filters do. Then, you have the {"virtualmachine1: {}, "virtualmachine2": {}} structure, but you don't care about its value, only the keys, so dict2items transforms that structure into:

[{"key": "virtualmachine1", "value": {etcetc}},
 {"key": "virtualmachine2", "value": {whatever}}]

then we extract the value of the key field, and voila, a list of the keys of that bottom-most structure

Upvotes: 1

Related Questions