Ansible Jinja2模板大小写不敏感匹配后如何保留原元素格式?
问题描述
我用Ansible Playbook结合Jinja2模板生成配置文件,现在遇到一个问题:实现大小写不敏感匹配配置项后,输出的是match_config里的小写键名,但我需要输出allowed_options列表中定义的原大小写格式。
原Playbook代码
--- - 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
原Jinja2模板(xa.j2)
{% 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 %}
当前输出
Match User user1 allowagent domaintoken rsatoken XXXXXZZZ0000000 Match Address 162.243.72.0/24,192.43.120.0/23 rsaauthentication enabled
期望输出
Match User user1 AllowAgent domaintoken RSATokeN XXXXXZZZ0000000 Match Address 162.243.72.0/24,192.43.120.0/23 RSAAuthentication enabled
解决方案
核心思路是提前把allowed_options转换成小写键对应原大小写值的字典,这样在模板里匹配到小写的optname后,就能直接取出对应的原格式选项名。
步骤1:修改Playbook,添加转换后的字典变量
在vars里新增allowed_options_map,通过dict和zip把小写后的选项名和原选项名配对:
--- - name: main hosts: localhost become: true vars: allowed_options: [AllowAgent,RSAAuthentication,RSATokeN] # 新增:生成小写键对应原大小写值的字典 allowed_options_map: "{{ dict(allowed_options | 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: - name: deploy template: src: xa.j2 dest: /tmp/xa.txt
步骤2:修改Jinja2模板,使用字典匹配并输出原格式
把模板里的判断和输出逻辑改成用allowed_options_map来匹配:
{% if (allowed_options_map is defined) and allowed_options_map %} {% 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_map %} {{ allowed_options_map[optname] }} {{ optval }} {% endif %} {% endfor %} {% endfor %} {% endif %}
这样模板会先检查optname是否在allowed_options_map的键(小写)里,匹配到后直接取字典对应的原大小写值输出,完美实现需求。
内容的提问来源于stack exchange,提问作者johnny bravo
相关产品推荐
相关产品推荐

