0

Im trying to filter ansible-playbook output to a valid json output so i can work with it. The output im getting is:

ok: [r-sw01] => {
    "configlets | selectattr(\"name\", \"eq\", \"r-sw01\")": [
        {
            "config": "hostname r-sw01\n\ninterface Management1\n   ip address 10.10.24.10/24\n\ninterface Port-Channel20\n   description USR\n   switchport mode trunk\n\ninterface Ethernet99-100\n   description  USR_Po20\n   speed forced 25gfull\n",
            "containerCount": 0,
            "containers": [],
            "dateTimeInLongFormat": 1615984781483,
            "devices": [
                "r-sw01"
            ],
            "editable": true,
            "isAutoBuilder": "",
            "isDefault": "no",
            "isDraft": false,
            "key": "configlet_71ef71",
            "name": "r-sw01",
            "netElementCount": 0,
            "note": "",
            "reconciled": false,
            "sslConfig": false,
            "type": "Static",
            "typeStudioConfiglet": false,
            "user": "chal",
            "visible": true
        }
    ]
}

From this playbook:

---
- name: Playbook to demonstrate cv_container module.
  hosts: cvp_servers
  connection: local
  gather_facts: no
  collections:
    - arista.cvp
  tasks:
    - name: "Gather CVP facts from {{inventory_hostname}}"
      arista.cvp.cv_facts:
        facts:
          configlets
    - debug:
        var: configlets | selectattr("name", "eq", "{{ tag }}")

Have tried filtering it using python :

configlet_settings = subprocess.Popen(["ansible-playbook", "configlets.yml", "-e", tag ,"-i", "inventory.ini"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = configlet_settings.communicate()
out = out.decode()
out = out.split('\n')
r = re.search(r"configlets.*\[(.*?)\]", str(out))
r = r.group(1)
my_lst = re.findall(r"\w+", r)

But im only getting (['r', 'sw01'],)

Or "None" when i try to change the regex, how can i get a valid json of this output ? i dont need the | selectattr(\"name\", \"eq\", \"r-sw01\")" only what comes after

EDIT- Trying to redirect output to file :

  ---
- name: Playbook to demonstrate cv_container module.
  hosts: cvp_servers
  connection: local
  gather_facts: no
  collections:
    - arista.cvp
  vars:
    var: var
    vars_files:
            - vars.yml
  tasks:
    - name: "Gather CVP facts from {{inventory_hostname}}"
      arista.cvp.cv_facts:
        facts:
          configlets
    - debug:
        var: configlets | selectattr("name", "eq", "{{ tag }}")

    - name: write JSON to a file
      copy:
         content: "{{ var|to_nice_json }}"
         dest: somefile.json

Got an error:

FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'var' is undefined
Batchen Regev
  • 685
  • 1
  • 7
  • 28
  • 1
    Trying to parse the output from Ansible seems like a waste of time. If you want JSON output from Ansible, *just write JSON to a file*, using a `template` or `copy` task, then simply read the file into your code. No manual parsing necessary. Ansible has filters for serializing data to JSON/YAML/etc. – larsks Mar 21 '21 at 12:39
  • how do i redirect var? I added this after debug`- local_action: copy content=var dest=somelog.log` tried also with `content={{var}}` – Batchen Regev Mar 21 '21 at 12:45

1 Answers1

1

If you want to write the JSON serialization of an Ansible variable to a file, you can do something like this:

- name: write JSON to a file
  copy:
    content: "{{ var|to_nice_json }}"
    dest: somelog.json

Then just import that in your Python code:

import json

with open('somelog.json') as fd:
  data = json.load(fd)
larsks
  • 277,717
  • 41
  • 399
  • 399
  • Playbook returns an error : `FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'var' is undefined` - edited question with playbook changes – Batchen Regev Mar 21 '21 at 13:23
  • Have you defined a variable named `var`? If not, use the name of the variable you're trying to dump. – larsks Mar 21 '21 at 13:44
  • where do i need to defined it ? the full playbook is here in the question please let me know what i should do – Batchen Regev Mar 21 '21 at 13:52
  • This actually requires you to know what you're trying to do. What is the name of the variable you want to dump to JSON? Is it `configlets`? Whatever it is, replace `var` in that `content` expression with the name of the variable. – larsks Mar 21 '21 at 14:07
  • the var created to filter the output on `configlets` and giving me only the relevant info by name, as configlets has LOTS of info, after it filters it i want only the json it is filtering . if i put the configulets it content instead of var i get the full info, if there isnt a way to put the filtered info on `var` to log file this is good enough :) – Batchen Regev Mar 21 '21 at 14:19
  • Ended up doing ` content: "{{ configlets |to_nice_json }}"` and filtered on python, thanks! – Batchen Regev Mar 21 '21 at 14:41