Search code examples
ansiblemikrotikansible-template

How to extract the output from stdout.lines in ansible


---
- name: Mikrotik info
  hosts: mikrotik
  connection: network_cli
  remote_user: root
  gather_facts: false
  tasks:
  - name: show info
    routeros_command:
     commands: /system routerboard print
    register: rb_info

  - name: Debug info
    debug:
      msg: "{{ rb_info.stdout_lines }}"

Output:

 routerboard: yes
             model: 751G-2HnD
     serial-number: 3A6502B2A2E7
     firmware-type: ar7240
  factory-firmware: 3.0
  current-firmware: 6.42.3
  upgrade-firmware: 6.43.4

I need to filter it for "upgrade-firmware" string and get output like this:

upgrade-firmware: 6.43.4

I should use regex_replace? Or I can use grep or something like that?

Any thoughts are greatly appreciated.

Thank you


Solution

  • (update)

    Use from_yaml and combine a dictionary. For example

        - set_fact:
            minfo: "{{ minfo|default({})|combine(item|from_yaml) }}"
          loop: "{{ rb_info.stdout_lines }}"
        - debug:
            var: minfo['upgrade-firmware']
    

    give

      minfo['upgrade-firmware']: 6.43.4
    

    (for the record)

    1. Robust solution is to write the data to template and include_vars. The tasks below
        - tempfile:
          register: tempfile
        - template:
            src: minfo.j2
            dest: "{{ tempfile.path }}"
        - include_vars:
            file: "{{ tempfile.path }}"
            name: minfo
        - debug:
            var: minfo
    

    with the template

        shell> cat minfo.j2 
        {% for item in rb_info.stdout_lines %}
        {{ item }}
        {% endfor %}
    

    should give

        "minfo": {
            "current-firmware": "6.42.3", 
            "factory-firmware": 3.0, 
            "firmware-type": "ar7240", 
            "model": "751G-2HnD", 
            "routerboard": true, 
            "serial-number": "3A6502B2A2E7", 
            "upgrade-firmware": "6.43.4"
        }
    
    1. The tasks below creates variable upgrade_firmware
        - set_fact:
            upgrade_firmware: "{{ item.split(':').1|trim }}"
          loop: "{{ rb_info.stdout_lines|map('quote')|map('trim')|list }}"
          when: item is search('^upgrade-firmware')
        - debug:
            var: upgrade_firmware
    
    1. It is possible to put all the parameters into the dictionary
        - set_fact:
            minfo: "{{ minfo|default({})|
                       combine({item.split(':').0: item.split(':').1|trim}) }}"
          loop: "{{ rb_info.stdout_lines|map('quote')|map('trim')|list }}"
        - debug:
            var: minfo['upgrade-firmware']