87 lines
2.8 KiB
Text
87 lines
2.8 KiB
Text
|
|
[ -f "$STATE_DIR/.env" ] && source "$STATE_DIR/.env"
|
||
|
|
|
||
|
|
{% if firewalls and firewalls | length > 0 %}
|
||
|
|
echo ""
|
||
|
|
echo "=== Firewall Reconciliation ==="
|
||
|
|
|
||
|
|
{% for fw in firewalls %}
|
||
|
|
FW_NAME="{{ fw.name }}"
|
||
|
|
|
||
|
|
# ── Create firewall if it doesn't exist ──────────────────────────────────────
|
||
|
|
if hcloud firewall describe "$FW_NAME" > /dev/null 2>&1; then
|
||
|
|
echo "✓ Firewall '$FW_NAME' exists"
|
||
|
|
else
|
||
|
|
echo "Creating firewall '$FW_NAME'..."
|
||
|
|
hcloud firewall create \
|
||
|
|
--name "$FW_NAME" \
|
||
|
|
{%- for key, val in fw.labels %}
|
||
|
|
--label "{{ key }}={{ val }}" \
|
||
|
|
{%- endfor %}
|
||
|
|
> /dev/null
|
||
|
|
echo "✓ Firewall '$FW_NAME' created"
|
||
|
|
fi
|
||
|
|
|
||
|
|
# ── Reconcile rules: add missing, leave existing untouched ───────────────────
|
||
|
|
# Strategy: try add-rule per desired rule; hcloud ignores if rule is duplicate
|
||
|
|
echo " Reconciling {{ fw.rules | length }} rule(s)..."
|
||
|
|
|
||
|
|
{% for rule in fw.rules %}
|
||
|
|
{%- if rule.direction == "in" %}
|
||
|
|
{%- if rule.protocol == "icmp" %}
|
||
|
|
hcloud firewall add-rule "$FW_NAME" \
|
||
|
|
--direction in --protocol icmp \
|
||
|
|
{%- for ip in rule.source_ips %}
|
||
|
|
--source-ips {{ ip }} \
|
||
|
|
{%- endfor %}
|
||
|
|
> /dev/null 2>&1 || true
|
||
|
|
{%- else %}
|
||
|
|
hcloud firewall add-rule "$FW_NAME" \
|
||
|
|
--direction in --protocol {{ rule.protocol }} --port {{ rule.port }} \
|
||
|
|
{%- for ip in rule.source_ips %}
|
||
|
|
--source-ips {{ ip }} \
|
||
|
|
{%- endfor %}
|
||
|
|
> /dev/null 2>&1 || true
|
||
|
|
{%- endif %}
|
||
|
|
{%- else %}
|
||
|
|
{%- if rule.protocol == "icmp" %}
|
||
|
|
hcloud firewall add-rule "$FW_NAME" \
|
||
|
|
--direction out --protocol icmp \
|
||
|
|
{%- for ip in rule.destination_ips %}
|
||
|
|
--destination-ips {{ ip }} \
|
||
|
|
{%- endfor %}
|
||
|
|
> /dev/null 2>&1 || true
|
||
|
|
{%- else %}
|
||
|
|
hcloud firewall add-rule "$FW_NAME" \
|
||
|
|
--direction out --protocol {{ rule.protocol }} --port {{ rule.port }} \
|
||
|
|
{%- for ip in rule.destination_ips %}
|
||
|
|
--destination-ips {{ ip }} \
|
||
|
|
{%- endfor %}
|
||
|
|
> /dev/null 2>&1 || true
|
||
|
|
{%- endif %}
|
||
|
|
{%- endif %}
|
||
|
|
{% endfor %}
|
||
|
|
echo " ✓ Rules reconciled for '$FW_NAME'"
|
||
|
|
|
||
|
|
# ── Apply firewall to this server ─────────────────────────────────────────────
|
||
|
|
{% if servers is defined %}
|
||
|
|
{%- for srv in servers %}
|
||
|
|
{%- if srv.firewall is defined and srv.firewall == fw.name %}
|
||
|
|
echo " Applying '$FW_NAME' to server '{{ srv.hostname }}'..."
|
||
|
|
hcloud firewall apply-to-resource "$FW_NAME" \
|
||
|
|
--type server \
|
||
|
|
--server "{{ srv.hostname }}" 2>/dev/null || true
|
||
|
|
echo " ✓ Firewall applied to '{{ srv.hostname }}'"
|
||
|
|
{%- endif %}
|
||
|
|
{%- endfor %}
|
||
|
|
{% endif %}
|
||
|
|
|
||
|
|
{% endfor %}
|
||
|
|
|
||
|
|
echo ""
|
||
|
|
echo "=== Firewall Reconciliation Complete ==="
|
||
|
|
echo "FIREWALL_NAMES={{ firewalls | map(attribute='name') | join(d=',') }}" >> "$STATE_DIR/.env"
|
||
|
|
|
||
|
|
{% else %}
|
||
|
|
{# Firewall config not in server-create context — reconciliation handled by bootstrap #}
|
||
|
|
{% endif %}
|