1
0
Fork 0
mirror of https://github.com/ansible-collections/hetzner.hcloud.git synced 2026-02-03 23:51:48 +00:00

fix: firewall idempotency with ipv6 addresses (#722)

##### SUMMARY

Always use the canonical address representation when checking if rules
changed.


Fixes #708
This commit is contained in:
Jonas L. 2025-10-31 14:45:06 +01:00 committed by GitHub
parent 7ac361a9cc
commit 907a7fd73c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 73 additions and 17 deletions

View file

@ -0,0 +1,7 @@
from __future__ import annotations
from ipaddress import ip_interface
def normalize_ip(value: str) -> str:
return str(ip_interface(value))

View file

@ -221,6 +221,7 @@ import time
from ansible.module_utils.basic import AnsibleModule
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.ipaddress import normalize_ip
from ..module_utils.vendor.hcloud import APIException, HCloudException
from ..module_utils.vendor.hcloud.firewalls import (
BoundFirewall,
@ -229,6 +230,14 @@ from ..module_utils.vendor.hcloud.firewalls import (
)
def normalize_rules(rules: list[dict]) -> list[dict]:
for rule in rules:
# Ensure ip addresses canonical representation
rule["source_ips"] = [normalize_ip(o) for o in rule["source_ips"]]
rule["destination_ips"] = [normalize_ip(o) for o in rule["destination_ips"]]
return rules
class AnsibleHCloudFirewall(AnsibleHCloud):
represent = "hcloud_firewall"
@ -287,6 +296,7 @@ class AnsibleHCloudFirewall(AnsibleHCloud):
}
rules = self.module.params.get("rules")
if rules is not None:
rules = normalize_rules(rules)
params["rules"] = [
FirewallRule(
direction=rule["direction"],
@ -323,21 +333,24 @@ class AnsibleHCloudFirewall(AnsibleHCloud):
self._mark_as_changed()
rules = self.module.params.get("rules")
if rules is not None and rules != [self._prepare_result_rule(rule) for rule in self.hcloud_firewall.rules]:
if not self.module.check_mode:
new_rules = [
FirewallRule(
direction=rule["direction"],
protocol=rule["protocol"],
source_ips=rule["source_ips"] if rule["source_ips"] is not None else [],
destination_ips=rule["destination_ips"] if rule["destination_ips"] is not None else [],
port=rule["port"],
description=rule["description"],
)
for rule in rules
]
self.hcloud_firewall.set_rules(new_rules)
self._mark_as_changed()
if rules is not None:
rules = normalize_rules(rules)
if rules != [self._prepare_result_rule(rule) for rule in self.hcloud_firewall.rules]:
if not self.module.check_mode:
new_rules = [
FirewallRule(
direction=rule["direction"],
protocol=rule["protocol"],
source_ips=rule["source_ips"] if rule["source_ips"] is not None else [],
destination_ips=rule["destination_ips"] if rule["destination_ips"] is not None else [],
port=rule["port"],
description=rule["description"],
)
for rule in rules
]
self.hcloud_firewall.set_rules(new_rules)
self._mark_as_changed()
self._get_firewall()