Search code examples
parsingansiblelinestdout

Ansible get a subset of items from a list


I have a list of output from an MQ command that shows the status of a channel, the stdout_lines of my registered variable is;

'stdout_lines': [u'CHANNEL(SVRCONN.CHL) CHLTYPE(SVRCONN) CONNAME(1.2.3.4) STATUS(RUNNING) SUBSTATE(RECEIVE)']}

This out worked OK for what I was intending on doing as I need to display the output of the CHANNEL and STATUS only and could find the values using a combinations of .split(')')[1].split('(')[1] and split(')')[4].split('(')[1] to get values SVRCONN.CHL and RUNNING

I have also been using this task for CLUSTER channel but found it was failing, the reason for this was that there is was an extra field,

'stdout_lines': [u'CHANNEL(CLUSTER_CHL) CHLTYPE(CLUSRCVR) CONNAME(2.3.4.5) RQMNAME(CLUS00) STATUS(RUNNING) SUBSTATE(RECEIVE)']}

now i could do a check to see if RQMNAME is in the output and then use a different split, but is there a way that this can be done using a string to find the location in output of STATUS?


Solution

  • Thanks to the work from Vladimir i have managed to code what i required by capturing all the fields, irrespective if the number of field in the output Taking the example of the two channel types above i now have a list of dicts using the code above but instead of debug out i have added it to a status list;

     - name: Set status
        set_fact:
          status: "{{status|default([]) + [cooked]}}" 
        with_items: "{{lines}}"
        vars:
          _items: "{{ item.split()|
                      map('regex_replace', '\\((.+)\\)$', ' \\1')|
                      list }}"
          _cooked: |
            {% for i in _items %}
            {% set arr = i.split() %}
            {{ arr.0 }}: {{ arr.1 }}
            {% endfor %}
          cooked: "{{ _cooked|from_yaml }}"
    

    This now gives... "status [{'CHLTYPE': u'SVRCONN', 'STATUS': u'RUNNING', 'CONNAME': u'1.2.3.4', 'SUBSTATE': u'RECEIVE', 'CHANNEL': u'SVRCONN.CHL'}, {'STATUS': u'RUNNING', 'CONNAME': u'2.3.4.5', 'SUBSTATE': u'RECEIVE', 'CHLTYPE': u'CLUSRCVR', 'RQMNAME': u'CLUS00', 'CHANNEL': u'CLUSTER_CHL'}]"

    now all i need to do is debug output the required field using a single statement

      - debug:
          msg: "CHANNEL = {{item.CHANNEL}} STATUS = {{item.STATUS}}{%if (item.RQMNAME is defined) %} QMGR = {{item.RQMNAME}}{%endif%}"
        with_items: "{{status}}"
    

    this outputs "CHANNEL = SVRCONN.CHL STATUS = RUNNING" "CHANNEL = CLUSTER_CHL STATUS = RUNNING QMGR = CLUS00"