---
- name: main
hosts: localhost
become: true
vars:
allowed_options: [AllowAgent,RSAAuthentication,RSATokeN]
match_config:
test:
matchkey: 'User'
matchvalue: 'user1'
allowagent: 'domaintoken'
rsatoken: 'XXXXXZZZ0000000'
test2:
matchkey: 'Address'
matchvalue: '162.243.72.0/24,192.43.120.0/23'
rsaauthentication: 'enabled'
invalidkey: invalidvalue
tasks:
- name: deploy
template:
src: xa.j2
dest: /tmp/xa.txt
{% if (allowed_options is defined) and allowed_options %}
{% for k,v in match_config.items() %}
Match {{ v.matchkey }} {{ v.matchvalue }}
{% for optname, optval in v.items() if optname not in ['matchkey', 'matchvalue'] %}
{% if optname in allowed_options|lower %}
{{ optname }} {{ optval }}
{% endif %}
{% endfor %}
{% endfor %}
{% endif %}
I get the right output:
Match User user1
allowagent domaintoken
rsatoken XXXXXZZZ0000000
Match Address 162.243.72.0/24,192.43.120.0/23
rsaauthentication enabled
But, I would prefer
Match User user1
AllowAgent domaintoken
RSATokeN XXXXXZZZ0000000
Match Address 162.243.72.0/24,192.43.120.0/23
RSAAuthentication enabled
I just plain and simple can't figure out...
So I just compare case insensitive in jinja2 template and if it match just to use list[element]
Declare the below dictionary
allowed_dict: "{{ dict(allowed_options|map('lower')|zip(allowed_options)) }}"
gives
allowed_dict:
allowagent: AllowAgent
rsaauthentication: RSAAuthentication
rsatoken: RSATokeN
and use it in the template
{% for k,v in match_config.items() %}
Match {{ v.matchkey }} {{ v.matchvalue }}
{% for optname, optval in v.items() %}
{% if optname in allowed_dict %}
{{ allowed_dict[optname] }} {{ optval }}
{% endif %}
{% endfor %}
{% endfor %}
gives
Match User user1
AllowAgent domaintoken
RSATokeN XXXXXZZZ0000000
Match Address 162.243.72.0/24,192.43.120.0/23
RSAAuthentication enabled
Example of a complete playbook for testing
- hosts: localhost
vars:
allowed_options: [AllowAgent, RSAAuthentication, RSATokeN]
allowed_dict: "{{ dict(allowed_options|map('lower')|zip(allowed_options)) }}"
match_config:
test:
matchkey: 'User'
matchvalue: 'user1'
allowagent: 'domaintoken'
rsatoken: 'XXXXXZZZ0000000'
test2:
matchkey: 'Address'
matchvalue: '162.243.72.0/24,192.43.120.0/23'
rsaauthentication: 'enabled'
invalidkey: invalidvalue
tasks:
- debug:
var: allowed_dict
- debug:
msg: |
{% for k,v in match_config.items() %}
Match {{ v.matchkey }} {{ v.matchvalue }}
{% for optname, optval in v.items() %}
{% if optname in allowed_dict %}
{{ allowed_dict[optname] }} {{ optval }}
{% endif %}
{% endfor %}
{% endfor %}
If the variable allowed_options might be undefined set it to an empty list
allowed_dict: "{{ dict(allowed_options|d([])|map('lower')|
zip(allowed_options|d([]))) }}"
This would result in an empty dictionary
allowed_dict: {}
Q: Explain the construct zip(allowed_options)
A: Take a look at the intermediate results
- debug:
msg: |
allowed_options|map('lower'):
{{ allowed_options|map('lower')|to_yaml }}
allowed_options|map('lower')|zip(allowed_options):
{{ allowed_options|map('lower')|zip(allowed_options)|to_yaml }}
dict(allowed_options|map('lower')|zip(allowed_options)):
{{ dict(allowed_options|map('lower')|zip(allowed_options))|to_nice_yaml }}
gives
msg: |-
allowed_options|map('lower'):
[allowagent, rsaauthentication, rsatoken]
allowed_options|map('lower')|zip(allowed_options):
- [allowagent, AllowAgent]
- [rsaauthentication, RSAAuthentication]
- [rsatoken, RSATokeN]
dict(allowed_options|map('lower')|zip(allowed_options)):
allowagent: AllowAgent
rsaauthentication: RSAAuthentication
rsatoken: RSATokeN