96 lines
5.7 KiB
Django/Jinja
96 lines
5.7 KiB
Django/Jinja
#jinja2: trim_blocks: True, lstrip_blocks: True
|
|
{% set ip_to_host = {} %}
|
|
{% for host in groups['all'] | default([]) %}
|
|
{% set hv = hostvars[host] | default({}) %}
|
|
{% if hv.ansible_host is defined and (hv.ansible_connection | default('')) != 'community.proxmox.proxmox_pct_remote' %}
|
|
{% set _ = ip_to_host.update({(hv.ansible_host | string): host}) %}
|
|
{% endif %}
|
|
{% if hv.container_ip is defined and hv.container_ip %}
|
|
{% set _ = ip_to_host.update({(hv.container_ip | string): host}) %}
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% macro render_rule(service_name, iif, saddr, oif, daddr, protos, ports, dest_name) %}
|
|
{% set lines = [] %}
|
|
{% set iifs = iif if (iif is iterable and iif is not string) else [iif] %}
|
|
{% set oifs = oif if (oif is iterable and oif is not string) else [oif] %}
|
|
{% set active_protos = protos | sort if protos | length > 0 else [none] %}
|
|
{% set active_ports = ports if ports | length > 0 else [none] %}
|
|
{% for current_iif in iifs %}
|
|
{% for current_oif in oifs %}
|
|
{% for p in active_protos %}
|
|
{% for port in active_ports %}
|
|
{% set proto_rule = '' %}
|
|
{% if p and port %}
|
|
{% set proto_rule = p ~ ' dport ' ~ port %}
|
|
{% elif p %}
|
|
{% set proto_rule = 'meta l4proto ' ~ p %}
|
|
{% endif %}
|
|
{# Resolve source name: prefer an explicit host resolved via saddr, otherwise fall back
|
|
to the current interface for this specific line (not the whole iif list/service_name) #}
|
|
{% set resolved_service_name = service_name if service_name else current_iif %}
|
|
{% if saddr and ip_to_host[saddr | string] is defined %}
|
|
{% set resolved_service_name = ip_to_host[saddr | string] %}
|
|
{% endif %}
|
|
{# Resolve destination IP to inventory hostname only for comment #}
|
|
{% set resolved_dest_name = dest_name %}
|
|
{% if daddr and ip_to_host[daddr | string] is defined %}
|
|
{% set resolved_dest_name = ip_to_host[daddr | string] %}
|
|
{% endif %}
|
|
{% set comment_text = resolved_service_name ~ ' -> ' ~ resolved_dest_name %}
|
|
{% set comment_str = ' comment "' ~ comment_text ~ '"' %}
|
|
{% set parts = ['iifname "' ~ current_iif ~ '"'] %}
|
|
{% if saddr %}
|
|
{% set _ = parts.append('ip saddr ' ~ saddr) %}
|
|
{% endif %}
|
|
{% if current_oif %}
|
|
{% set _ = parts.append('oifname "' ~ current_oif ~ '"') %}
|
|
{% endif %}
|
|
{% if daddr %}
|
|
{% set _ = parts.append('ip daddr ' ~ daddr) %}
|
|
{% endif %}
|
|
{% if proto_rule %}
|
|
{% set _ = parts.append(proto_rule) %}
|
|
{% endif %}
|
|
{% set _ = parts.append('counter accept' ~ comment_str) %}
|
|
{% set _ = lines.append(parts | join(' ')) %}
|
|
{% endfor %}
|
|
{% endfor %}
|
|
{% endfor %}
|
|
{% endfor %}
|
|
{{ lines | join('\n') }}
|
|
{% endmacro %}
|
|
{% filter regex_replace('\n[ \t]*\n+', '\n') %}
|
|
{# === Managed Hosts Forward Rules === #}
|
|
{% for item in groups[nft_managed_group] | sort %}
|
|
{% set client = hostvars[item] %}
|
|
{% if client.nft_to is defined and client.nft_to is not none %}
|
|
{% set raw_rules = client.nft_to if (client.nft_to is iterable and client.nft_to is not string and client.nft_to is not mapping) else [client.nft_to] %}
|
|
{% for r in raw_rules %}
|
|
{% set rule_dict = r if (r is mapping) else {'to': r} %}
|
|
{% set raw_dests = rule_dict.to if (rule_dict.to is iterable and rule_dict.to is not string) else [rule_dict.to] %}
|
|
{% set protos = rule_dict.proto if (rule_dict.proto is defined and rule_dict.proto is iterable and rule_dict.proto is not string) else ([rule_dict.proto] if rule_dict.proto is defined else []) %}
|
|
{% set ports = rule_dict.port if (rule_dict.port is defined and rule_dict.port is iterable and rule_dict.port is not string) else ([rule_dict.port] if rule_dict.port is defined else []) %}
|
|
{% for dest in raw_dests %}
|
|
{% set dest_name = dest | regex_replace('^zone:', '') %}
|
|
{% if dest.startswith('zone:') %}
|
|
{{ render_rule(item, client.zone_iface, client.container_ip, dest.split(':')[1], none, protos, ports, dest_name) }}
|
|
{% else %}
|
|
{{ render_rule(item, client.zone_iface, client.container_ip, hostvars[dest].zone_iface, hostvars[dest].container_ip, protos, ports, dest_name) }}
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% endfor %}
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% for item in groups[nft_managed_group] | sort %}
|
|
{% set client = hostvars[item] %}
|
|
{% if client.nft_from is defined and client.nft_from is not none %}
|
|
{% set raw_from_rules = client.nft_from if (client.nft_from is iterable and client.nft_from is not string and client.nft_from is not mapping) else [client.nft_from] %}
|
|
{% for r in raw_from_rules %}
|
|
{% set protos = r.proto if (r.proto is defined and r.proto is iterable and r.proto is not string) else ([r.proto] if r.proto is defined else []) %}
|
|
{% set ports = r.port if (r.port is defined and r.port is iterable and r.port is not string) else ([r.port] if r.port is defined else []) %}
|
|
{{ render_rule(none, r.iface, none, client.zone_iface, client.container_ip, protos, ports, item) }}
|
|
{% endfor %}
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% endfilter %}
|