I am working on a project where I have to perform multiple queries to the system and the steps that follow it depend on the results of the query (there are 2 to 3 different ways each query can branch out).
The results from the queries are stored in a string variable using the register module. For instance, for one of the queries I have to check if there are multiple standby servers configured and the expected output can look like this:
database role = PRIMARY
host name = random_name
service name = service1
target list = server1:10201|server4:40704|server8:52125
timeout value = 120
Where the only needed part is the target list and I need to extract each server (they are separated by the “|” and I wont know how many servers will be on the target list). So essentially I need a way to scan the string until it finds the word “target list” and then extract whatever comes after the “=” and before the new-line, each one of those values could be stored in an array I guess.
I don’t even know where to start, anyone know any modules or how I can go about extracting the needed parts of the strings?
Here is the sample playbook, only the last line with regex_search
is relevant here. Rest is for illustration purpose. regex_search
can be used for extracting the desired part from the text:
regex_search('target list\s+=\s+(.*)','\1')
above regex would capture everything after =
on the line containing target list
and back-referenced using 1
.
- name: Sample playbook
connection: local
# gather_facts: false
hosts: localhost
vars:
data: "{{ lookup('env', 'x') }}"
tasks:
- debug:
msg: "{{ data }}"
- debug:
msg: "{{ data |regex_search('target list\s+=\s+(.*)','\1')}}"
Output of the above playbook:
PLAY [Sample playbook] **********************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************
ok: [localhost]
TASK [debug] ********************************************************************************************************************************************************
ok: [localhost] => {}
MSG:
database role = PRIMARY
host name = random_name
service name = service1
target list = server1:10201|server4:40704|server8:52125
timeout value = 120
TASK [debug] ********************************************************************************************************************************************************
ok: [localhost] => {}
MSG:
['server1:10201|server4:40704|server8:52125']
PLAY RECAP **********************************************************************************************************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0
Given the data registered in the variable results
result:
stdout_lines:
- database role = PRIMARY
- host name = random_name
- service name = service1
- target list = server1:10201|server4:40704|server8:52125
- timeout value = 120
use the attribute stdout_lines, e.g.
- set_fact:
servers: "{{ _val.split('|') }}"
vars:
_line: "{{ result.stdout_lines|select( 'match', '^target list.*$') }}"
_arr: "{{ _line.0.split('=')|map('trim') }}"
_val: "{{ _arr.1 }}"
gives
servers:
- server1:10201
- server4:40704
- server8:52125
Use cli_parse if you have to repeatedly parse the same structures.