vars:
openssh_match_config:
test:
matchkey: 'User'
matchvalue: 'XXX'
chrootdirectory: '/home/%u'
maxsessions: '2'
test2:
matchkey: 'Address'
matchvalue: '1.3.0.3.0/24,192.43.120.0/27'
maxsessions: '3'
x11forwarding: 'yes'
otheropt: VAL1
otheropt2: VAL2
I need to have it translated as:
Match User XXX
ChrootDirectory /home/%u
MaxSessions 2
Match Address 1.3.0.3.0/24,192.43.120.0/27
MaxSessions 3
X11Forwarding yes
otheropt VAL1
otheropt2 VAL2
I've updated the loop , seems to be on the right track but still can't figure out how to fix it...
{% for k,v in openssh_match_config.items() %}
Match {{ openssh_match_config[k]['matchkey'] }} {{ openssh_match_config[k]['matchvalue'] }}
{%for x in v.items() %}
{{x}}
{%endfor%}
{% endfor %}
Your loop is for x in v.items()
. The items()
method returns a list of (key, value)
tuples. That is, given the following dictionary in variable myvar
:
{"name": "bob"}
Writing myvar.items()
would return [("name", "bob")]
.
All this means that in your list, the value of x
is a tuple, so writing {{x}}
will get you the string representation of a tuple: something like ('matchkey', 'Address')
.
You could write something like this:
{% for k,v in openssh_match_config.items() %}
Match {{ v.matchkey }} {{ v.matchvalue }}
{% for optname, optval in v.items() %}
{{ optname }} {{ optval }}
{% endfor %}
{% endfor %}
Which gets you:
Match User XXX
matchkey User
matchvalue XXX
chrootdirectory /home/%u
maxsessions 2
Match Address 1.3.0.3.0/24,192.43.120.0/27
matchkey Address
matchvalue 1.3.0.3.0/24,192.43.120.0/27
maxsessions 3
x11forwarding yes
otheropt VAL1
otheropt2 VAL2
And that almost works, except for the erroneous conclusion of matchkey
and matchvalue
. You can avoid those by using appropriate conditionals:
{% for k,v in openssh_match_config.items() %}
Match {{ v.matchkey }} {{ v.matchvalue }}
{% for optname, optval in v.items() if optname not in ['matchkey', 'matchvalue'] %}
{{ optname }} {{ optval }}
{% endfor %}
{% endfor %}
Which produces:
Match User XXX
chrootdirectory /home/%u
maxsessions 2
Match Address 1.3.0.3.0/24,192.43.120.0/27
maxsessions 3
x11forwarding yes
otheropt VAL1
otheropt2 VAL2
Or you could redesign your data structure so that the ssh config values are kept separate from the metadata you use in your playbook:
- hosts: localhost
gather_facts: false
vars:
openssh_match_config:
- matchkey: 'User'
matchvalue: 'XXX'
config:
chrootdirectory: '/home/%u'
maxsessions: '2'
- matchkey: 'Address'
matchvalue: '1.3.0.3.0/24,192.43.120.0/27'
maxsessions: '3'
config:
x11forwarding: 'yes'
otheropt: VAL1
otheropt2: VAL2
tasks:
- copy:
dest: out.txt
content: |
{% for v in openssh_match_config %}
Match {{ v.matchkey }} {{ v.matchvalue }}
{% for optname, optval in v.config.items() %}
{{ optname }} {{ optval }}
{% endfor %}
{% endfor %}