2

With ansible 2.9 on RHEL7.6 I'm trying to configure individual firewalld zones which also includes configuration of rich rules. It all works fine, except when I'm trying to template adding a rich rule in. In the example below, I'm attempting to add a rich rule allowing VRRP traffic.

Ansible task:

    - 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 }}"

The variable firewalld_zones is defined in my defaults/main.yml as the following:

firewalld_zones:
  - name: public
    short: "Public"
    description: "Public Zone"
    port:
      - { port: 300, protocol: tcp }
      - { port: 300, protocol: udp }
    rule:
      - protocol:
          - value: "vrrp"
          - action: accept

Snippet of my template 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>

With this I get :

<?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>

What I'm trying to get is this:

<?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>

What do I need to change (template and/or variables) to achieve this?

Thanks! J

JaneD
  • 65
  • 4
  • You can't get "". The value in the data is Boolean "accept: yes". Because yes is not quoted you get "". But, what is the purpose of the value when you want the key only? Does it mean: yes, put accept into the rule, or no, do not put accept into the rule? Why not omit or include accept on the list? You might want to 1) change the structure or 2) confirm the value in "accept: yes" shall be evaluated as a condition to omit or include the key in the rule or 3) confirm the value in "accept: yes" shall be ignored. – Vladimir Botka Aug 14 '20 at 04:51

1 Answers1

1

Change the part of the template

...
{% 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>
JaneD
  • 65
  • 4
Vladimir Botka
  • 5,138
  • 8
  • 20
  • Thanks so very much for that. I know the accept:yes thing didnt make sense. But your code worked perfectly and I changed it slightly to `{% for name,value in subtag.items() %} {% if name in ['action'] %} <{{ value }}/>` so that it makes more sense (eg I can accept, deny, reject, etc with the action definition). Again, many tahnks for your excellent advice. – JaneD Aug 14 '20 at 08:40
  • It's up to you. You're welcome. I've accepted your edit. But, now, my answer doesn't produce what you expect. Are you going to edit the question too? – Vladimir Botka Aug 14 '20 at 08:50
  • I have edited the question. It makes much more sense now :) thanks again – JaneD Aug 14 '20 at 08:58