Redhat

使用 ansible 模板化防火牆區域 - xml 操作問題

  • February 2, 2021

在 RHEL7.6 上使用 ansible 2.9 我正在嘗試配置單個防火牆區域,其中還包括豐富規則的配置。一切正常,除非我嘗試在模板中添加豐富規則。在下面的範例中,我嘗試添加允許 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>

我需要改變什麼(模板和/或變數)來實現這一點?

謝謝!Ĵ

更改模板的一部分

...
{% 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>

引用自:https://serverfault.com/questions/1030073