Hello,
I’m working on a role for system SSSD daemon. I found this piece of code online:
https://github.com/picotrading/ansible-sssd/blob/master/templates/sssd.conf.j2
I have defined my own sssd_config variable in my role’s defaults directory, so I’d like to use that piece of code. That code is neat. However, I don’t understand what it is doing in line:
{% from “templates/encoder/macros/ini_encode_macro.j2” import ini_encode with context -%}
Also does current Ansible support templates macro like above?
If it doesn’t, then sssd_config variable is a large dictionary map, with INI-style different sections. What really needs to happen is based on that variable, change it to use = symbol as delimiter for each INI section. For example:
sssd_config:
sssd:
debug_level: 1
config_file_version: 2
…
Then the produced sssd.conf file would look like below:
[sssd]
debug_level=1
config_file_version=2
Thank you,
Xinhuan Zheng
vbotka
(Vladimir Botka)
January 14, 2020, 10:42pm
2
I still cannot figure out how to loop through my variable:
sssd_config:
sssd:
debug_level: 1
nss:
reconnection_retries: 3
pam:
**debug_level: 5**
Here is my template code:
{% for item in sssd_config %}
[{{ item }}]
{% set list = sssd_config[item] %}
{% for i in list %}
{{ i }} =
{% endfor %}
{% endfor %}
I cannot figure out what to put after {{ i }}. Please HELP!
Thank you,
- Xinhuan Zheng
vbotka
(Vladimir Botka)
January 15, 2020, 6:35pm
4
Variable 'sssd_config' is dictionary. It's not possible to iterate
dictionary. Try for example
{% for item in sssd_config.items() %}
{{ item }}
{% endfor %}
see the 'items' in the created file and fit the template to your needs.
HTH,
-vlado
Tried what you said. Here is what {{ item }} look like:
[(u’sssd’, {u’debug_level’: 5, u’reconnection_retries’: 3, u’config_file_version’: 2, u’sbus_timeout’: 30})]
[(u’services’, [u’nss’, u’pam’, u’ssh’])]
…
What should I do next?
Thanks again,
vbotka
(Vladimir Botka)
January 15, 2020, 6:47pm
6
Fit the template to your needs. For example the template
{% for item in sssd_config.items() %}
[{{ item.0 }}]
{{ item.1.keys().0 }}={{ item.1.values().0 }}
{% endfor %}
gives
[nss]
reconnection_retries=3
[pam]
debug_level=5
[sssd]
debug_level=1
HTH,
-vlado
vbotka
(Vladimir Botka)
January 15, 2020, 6:56pm
7
There might be more items in the configuration sections. The template
below gives the same result and would include other parameters if present
{% for item in sssd_config.items() %}
[{{ item.0 }}]
{% for iitem in item.1.items() %}
{{ iitem.0 }}={{ iitem.1 }}
{% endfor %}
{% endfor %}
I tested the solution, it doesn’t work. item.1 becomes:
{u’id_provider’: u’local’, u’auth_provider’: u’local’, u’enumerate’: True}
So I get error there is no keys on {{ item.1.keys().0 }}
Got this error:
"AnsibleUndefinedVariable: ‘list object’ has no attribute ‘items’ for item.1.items()
vbotka
(Vladimir Botka)
January 15, 2020, 8:45pm
10
Both versions works for me. Double-check the code. The playbook
- hosts: localhost
vars:
sssd_config:
sssd:
debug_level: 1
nss:
reconnection_retries: 3
pam:
debug_level: 5
tasks:
- template:
src: template.j2
dest: config.ini
with the template
% for item in sssd_config.items() %}
[{{ item.0 }}]
{{ item.1.keys().0 }}={{ item.1.values().0 }}
{% endfor %}
# ------------------------------------------
{% for item in sssd_config.items() %}
[{{ item.0 }}]
{% for iitem in item.1.items() %}
{{ iitem.0 }}={{ iitem.1 }}
{% endfor %}
{% endfor %}
gives
[nss]
reconnection_retries=3
[pam]
debug_level=5
[sssd]
debug_level=1
# ------------------------------------------
[nss]
reconnection_retries=3
[pam]
debug_level=5
[sssd]
debug_level=1
Hello,
Your testing looks fine in the test data model. However, the sssd_config real data model is like below:
sssd_config:
sssd:
debug_level: 1
additional_key: additional_value
another_addtional_key: another_additional_value
nss:
reconnection_retries: 3
additional_key: additional_value
another_addtional_key: another_additional_value
pam:
debug_level: 5
additional_key: additional_value
another_addtional_key: another_additional_value
The addtional_key and another_additional_key isn’t same per section (pam,nss,sssd), and number of additional_key per section isn’t identical either. So nss section may have 5 key/value pairs, pam may have 6 key/value pairs, and sssd may have only 3 key/value pairs. Each additional_key is pretty much unique to that section.
Because this is so difficult to manipulate in template (I spend most yesterday to figure it out), I think it is probably better just put INI-style content into template file, then fill in the values from variables that varies for that key/value pair. It makes the work more simpler.
Thank you for providing the test case. I’ll remember this lesson.
vbotka
(Vladimir Botka)
January 16, 2020, 3:49pm
12
It also possible to use module 'ini_file'
https://docs.ansible.com/ansible/latest/modules/ini_file_module.html
With the configuration data transformed to this list
sssd_config:
- params:
- additional_key: additional_value
- reconnection_retries: 3
- another_addtional_key: another_additional_value
section: nss
- params:
- debug_level: 5
- another_addtional_key: another_additional_value
- additional_key: additional_value
section: pam
- params:
- debug_level: 1
- another_addtional_key: another_additional_value
- additional_key: additional_value
section: sssd
the task below
- ini_file:
path: /scratch/tmp/config.ini
section: "{{ item.0.section }}"
option: "{{ item.1.keys()|list|first }}"
value: "{{ item.1.values()|list|first }}"
with_subelements:
- "{{ sssd_config }}"
- params
gives
$ cat /scratch/tmp/config.ini
[nss]
additional_key = additional_value
reconnection_retries = 3
another_addtional_key = another_additional_value
[pam]
debug_level = 5
another_addtional_key = another_additional_value
additional_key = additional_value
[sssd]
debug_level = 1
another_addtional_key = another_additional_value
additional_key = additional_value
Hello Mr. Botka,
This is exactly what I am looking for. It looks so neat with ini_file module instead of template. I’ll play with it in my tasks.
Thank you very much!