How to parse a map?
I'm trying to create a list in ansible which consists of some docker container information. First, I'm running a command module which returns this in stdout:
"map[key1:value1 key2:value2 key3:value3]"
How can I parse this further to get the values based on the key that I provide? When I use a map
filter, I get this:
"msg": "<generator object do_map at 0x7f3845b8a740>"
If I run the list
filter, I just get output as every single character in the map, so ["m", "a", "p", "[", "k", ...]
What filter should I use?
Solution 1:
For example
- set_fact:
x: "{{ _dict|from_yaml }}"
vars:
_regex: '^(.*)\[(.*)\](.*)$'
_key: "{{ stdout|regex_replace(_regex, '\\1') }}"
_val: "{{ stdout|regex_replace(_regex, '\\2') }}"
_dict: |
{{ _key }}:
{% for i in _val.split() %}
{{ i|regex_replace(':', ': ') }}
{% endfor %}
gives
x:
map:
key1: value1
key2: value2
key3: value3
If there were more lines, e.g.
stdout_lines:
- "map1[key1:value1 key2:value2 key3:value3]"
- "map2[key1:value1 key2:value2 key3:value3]"
- "map3[key1:value1 key2:value2 key3:value3]"
it would be possible to combine the dictionary, e.g.
- set_fact:
x: "{{ x|d({})|combine(_dict|from_yaml) }}"
loop: "{{ stdout_lines }}"
vars:
_regex: '^(.*)\[(.*)\](.*)$'
_key: "{{ item|regex_replace(_regex, '\\1') }}"
_val: "{{ item|regex_replace(_regex, '\\2') }}"
_dict: |
{{ _key }}:
{% for i in _val.split() %}
{{ i|regex_replace(':', ': ') }}
{% endfor %}
gives
x:
map1:
key1: value1
key2: value2
key3: value3
map2:
key1: value1
key2: value2
key3: value3
map3:
key1: value1
key2: value2
key3: value3
If the keys were repeating, e.g.
stdout_lines:
- "map[key1:value1 key2:value2 key3:value3]"
- "map[key1:value1 key2:value2 key3:value3]"
- "map[key1:value1 key2:value2 key3:value3]"
it would be possible to concatenate a list, e.g.
- set_fact:
x: "{{ x|d([]) + [_dict|from_yaml] }}"
loop: "{{ stdout_lines }}"
vars:
_regex: '^(.*)\[(.*)\](.*)$'
_key: "{{ item|regex_replace(_regex, '\\1') }}"
_val: "{{ item|regex_replace(_regex, '\\2') }}"
_dict: |
{{ _key }}:
{% for i in _val.split() %}
{{ i|regex_replace(':', ': ') }}
{% endfor %}
gives
x:
- map:
key1: value1
key2: value2
key3: value3
- map:
key1: value1
key2: value2
key3: value3
- map:
key1: value1
key2: value2
key3: value3