
С ansible 2.9 на RHEL7.6 я пытаюсь настроить отдельные зоны firewalld, которые также включают конфигурацию расширенных правил. Все работает отлично, за исключением случаев, когда я пытаюсь добавить шаблонное правило. В примере ниже я пытаюсь добавить расширенное правило, разрешающее трафик VRRP.
Задача Ansible:
- name: Configure firewalld zones
template:
src: zone_template.xml.j2
dest: /etc/firewalld/zones/{{ item.name }}.xml
with_items: "{{ firewalld_zones }}"
notify: reload firewalld
loop_control:
label: "{{ item.name }}"
Переменная firewalld_zones
определена в моем defaults/main.yml следующим образом:
firewalld_zones:
- name: public
short: "Public"
description: "Public Zone"
port:
- { port: 300, protocol: tcp }
- { port: 300, protocol: udp }
rule:
- protocol:
- value: "vrrp"
- action: accept
Фрагмент моего шаблона zone_template.xml.j2
:
<?xml version="1.0" encoding="utf-8"?>
<zone{% if item.target is defined %} target="{{ item.target }}"{% endif %}>
<short>{{ item.short|default(item.name)|upper }}</short>
{% if item.description is defined %}
<description>{{ item.description }}</description>
{% endif %}
{% for tag in item %}
{# Settings which can be used several times #}
{% if tag in ['interface','source','service','port','protocol','icmp-block','forward-port','source-port'] %}
{% for subtag in item[tag] %}
<{{ tag }}{% for name,value in subtag.items() %} {{ name }}="{{ value }}"{% endfor %}/>
{% endfor %}
{# Settings which can be used once #}
{% elif tag in ['icmp-block-inversion','masquerade'] and item[tag] == True %}
<{{ tag }}/>
{% endif %}
{% endfor %}
{% for rule in item.rule|default([]) %}
<rule{% if rule.family is defined %} family="{{ rule.family }}"{% endif %}>
{% for tag in rule %}
{% if tag in ['source','destination','service','port','icmp-block','icmp-type','masquerade','forward-port','protocol'] %}
{% for subtag in rule[tag] %}
{% if subtag in ['action'] %}
<{% for name,value in subtag.items() %}{{ name }}{% endfor %}/>
{% endif %}
<{{ tag }}{% for name,value in subtag.items() %} {{ name }}="{{ value }}"{% endfor %}/>
{% endfor %}
{% endif %}
</rule>
{% endfor %}
{% endfor %}
</zone>
При этом я получаю:
<?xml version="1.0" encoding="utf-8"?>
<zone>
<short>PUBLIC</short>
<description>Public Zone</description>
<port protocol="tcp" port="300"/>
<port protocol="udp" port="300"/>
<rule>
<protocol value="vrrp"/>
<protocol action="accept"/>
</rule>
</zone>
Я пытаюсь добиться следующего:
<?xml version="1.0" encoding="utf-8"?>
<zone>
<short>PUBLIC</short>
<description>Public Zone</description>
<port protocol="tcp" port="300"/>
<port protocol="udp" port="300"/>
<rule>
<protocol value="vrrp"/>
<accept/>
</rule>
</zone>
Что мне нужно изменить (шаблон и/или переменные), чтобы добиться этого?
Спасибо! Дж.
решение1
Изменить часть шаблона
...
{% for subtag in rule[tag] %}
{% for name,value in subtag.items() %}
{% if name in ['action'] %}
<{{ value }}/>
{% else %}
<{{ tag }} {{ name }}="{{ value }}"/>
{% endif %}
{% endfor %}
{% endfor %}
{% endif %}
{% endfor %}
</rule>
{% endfor %}
</zone>