From 32ddf5e58edfaf537aa407da05d8f50f2608c91b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miha=20Frange=C5=BE?= Date: Fri, 9 Jan 2026 11:32:58 +0100 Subject: [PATCH 1/3] ipaddr was moved to ansible.utils --- roles/alpine/templates/interfaces.j2 | 6 +++--- roles/collector/templates/snmp.conf.j2 | 2 +- roles/dnsmasq/templates/10-ranges.conf.j2 | 8 ++++---- roles/proxmox-backup/templates/hosts.j2 | 2 +- roles/proxmox/templates/loopback.intf.j2 | 2 +- roles/radvd/templates/radvd.conf.j2 | 2 +- roles/windows/tasks/interface_address.yml | 4 ++-- templates/ansible.intf.j2 | 4 ++-- templates/hosts.j2 | 2 +- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/roles/alpine/templates/interfaces.j2 b/roles/alpine/templates/interfaces.j2 index 882e93e..7aef1a4 100644 --- a/roles/alpine/templates/interfaces.j2 +++ b/roles/alpine/templates/interfaces.j2 @@ -33,14 +33,14 @@ iface {{ iface.name }} {% for address in iface.ip_addresses %} address {{ address.address }} {% if address.family.value == 4 %} -{% set subnet = address.address | ipaddr('subnet') %} +{% set subnet = address.address | ansible.utils.ipaddr('subnet') %} {% set prefix = prefixes | selectattr('prefix', '==', subnet) | first %} {% set gateway = prefix.custom_fields.gateway.address %} {% if gateway is defined and gateway != address.address %} {% if iface.vrf %} - up ip route add default via {{ gateway | ipaddr('address') }} {% if iface.vrf.name %}vrf {{ iface.vrf.name }}{% endif +%} + up ip route add default via {{ gateway | ansible.utils.ipaddr('address') }} {% if iface.vrf.name %}vrf {{ iface.vrf.name }}{% endif +%} {% else %} - gateway {{ gateway | ipaddr('address') }} + gateway {{ gateway | ansible.utils.ipaddr('address') }} {% endif %} {% endif %} {% endif %} diff --git a/roles/collector/templates/snmp.conf.j2 b/roles/collector/templates/snmp.conf.j2 index ec9aedb..98b43b8 100644 --- a/roles/collector/templates/snmp.conf.j2 +++ b/roles/collector/templates/snmp.conf.j2 @@ -6,7 +6,7 @@ agents = [ {% for address in query("netbox.netbox.nb_lookup", "devices", api_filter=snmp_hosts, raw_data=true) | selectattr("primary_ip4") | map(attribute="primary_ip4.address") - | ipaddr("int") | sort | ipaddr("address") %} + | ansible.utils.ipaddr("int") | sort | ansible.utils.ipaddr("address") %} "{{ address }}", {% endfor %} ] diff --git a/roles/dnsmasq/templates/10-ranges.conf.j2 b/roles/dnsmasq/templates/10-ranges.conf.j2 index 2d64db4..bc55b0e 100644 --- a/roles/dnsmasq/templates/10-ranges.conf.j2 +++ b/roles/dnsmasq/templates/10-ranges.conf.j2 @@ -1,11 +1,11 @@ {% for prefix in prefixes | selectattr('custom_fields.dhcp_server') | sort(attribute='vlan.name') %} -{% if prefix.custom_fields.dhcp_server.address | ipaddr('address') == primary_ip4 %} +{% if prefix.custom_fields.dhcp_server.address | ansible.utils.ipaddr('address') == primary_ip4 %} # {{ prefix.vlan.name }} {% for range in prefix.custom_fields.dhcp_ranges | default([], true) %} -dhcp-range = set:{{ prefix.vlan.name }},{{ range.start_address | ipaddr('address') }},{{ range.end_address | ipaddr('address') }},{{ prefix.prefix | ipaddr('netmask') }} +dhcp-range = set:{{ prefix.vlan.name }},{{ range.start_address | ansible.utils.ipaddr('address') }},{{ range.end_address | ansible.utils.ipaddr('address') }},{{ prefix.prefix | ansible.utils.ipaddr('netmask') }} {% endfor %} {% if prefix.custom_fields.gateway %} -dhcp-option = tag:{{ prefix.vlan.name }},option:router,{{ prefix.custom_fields.gateway.address | ipaddr('address') }} +dhcp-option = tag:{{ prefix.vlan.name }},option:router,{{ prefix.custom_fields.gateway.address | ansible.utils.ipaddr('address') }} {% endif -%} {% for host in hostvars.values() | selectattr('interfaces', 'defined') %} @@ -24,5 +24,5 @@ dhcp-host = {{ interface.mac_address | lower }},{{ address }},{{ interface.devic # custom reservations {% for reservation in reservations | default([]) %} -dhcp-host = {{ reservation.mac | lower }},{{ reservation.ip | ipaddr('address') }},{{ reservation.host | lower }} +dhcp-host = {{ reservation.mac | lower }},{{ reservation.ip | ansible.utils.ipaddr('address') }},{{ reservation.host | lower }} {% endfor %} diff --git a/roles/proxmox-backup/templates/hosts.j2 b/roles/proxmox-backup/templates/hosts.j2 index a4ac92f..0869ec3 100644 --- a/roles/proxmox-backup/templates/hosts.j2 +++ b/roles/proxmox-backup/templates/hosts.j2 @@ -8,5 +8,5 @@ ff02::2 ip6-allrouters ff02::3 ip6-allhosts {% for address in interfaces | selectattr('name', '==', 'lo') | map(attribute='ip_addresses') | first %} -{{ address.address | ipaddr('address') }} {{ address.dns_name }} {{ inventory_hostname }} +{{ address.address | ansible.utils.ipaddr('address') }} {{ address.dns_name }} {{ inventory_hostname }} {% endfor %} diff --git a/roles/proxmox/templates/loopback.intf.j2 b/roles/proxmox/templates/loopback.intf.j2 index 81c428c..26fc0c4 100644 --- a/roles/proxmox/templates/loopback.intf.j2 +++ b/roles/proxmox/templates/loopback.intf.j2 @@ -1,7 +1,7 @@ {% set lo = hostvars[inventory_hostname].interfaces | selectattr('name', '==', 'lo') | first %} {% set vxlan_ip = lo.ip_addresses | selectattr('family.value', '==', 4) | map(attribute='address') | first - | ipaddr('address') %} + | ansible.utils.ipaddr('address') %} iface lo # without this the local tunnel IP is sometimes advertised as 0.0.0.0 on boot vxlan-local-tunnelip {{ vxlan_ip }} diff --git a/roles/radvd/templates/radvd.conf.j2 b/roles/radvd/templates/radvd.conf.j2 index 2fd4723..bab538d 100644 --- a/roles/radvd/templates/radvd.conf.j2 +++ b/roles/radvd/templates/radvd.conf.j2 @@ -3,7 +3,7 @@ | selectattr('enabled') %} {% for address in iface.ip_addresses | selectattr("family.value", "==", 6) %} {# get the gateway for this subnet #} -{% set subnet = address.address | ipaddr('subnet') %} +{% set subnet = address.address | ansible.utils.ipaddr('subnet') %} {% set prefix = prefixes | selectattr('prefix', '==', subnet) | first %} {% set gateway = prefix.custom_fields.gateway.address %} {# if we are gateway, send RAs on this interface #} diff --git a/roles/windows/tasks/interface_address.yml b/roles/windows/tasks/interface_address.yml index cce3528..5e31b1a 100644 --- a/roles/windows/tasks/interface_address.yml +++ b/roles/windows/tasks/interface_address.yml @@ -2,7 +2,7 @@ win_shell: > New-NetIPAddress -InterfaceAlias {{ interface.name }} -AddressFamily IPv{{ address.family.value }} - -IPAddress "{{ address.address | ipaddr("address") }}" -PrefixLength {{ address.address | ipaddr("prefix") }} + -IPAddress "{{ address.address | ansible.utils.ipaddr("address") }}" -PrefixLength {{ address.address | ansible.utils.ipaddr("prefix") }} register: result changed_when: "not result.stderr or 'Instance MSFT_NetIPAddress already exists' not in result.stderr" failed_when: false @@ -17,7 +17,7 @@ New-NetRoute -InterfaceAlias {{ interface.name }} -AddressFamily IPv{{ address.family.value }} -DestinationPrefix {{ "0.0.0.0/0" if address.family.value == 4 else "::/0" }} - -NextHop {{ prefix.custom_fields.gateway.address | ipaddr("address") }} + -NextHop {{ prefix.custom_fields.gateway.address | ansible.utils.ipaddr("address") }} register: result changed_when: "not result.stderr or 'Instance MSFT_NetRoute already exists' not in result.stderr" failed_when: false diff --git a/templates/ansible.intf.j2 b/templates/ansible.intf.j2 index cd0bb29..465e03d 100644 --- a/templates/ansible.intf.j2 +++ b/templates/ansible.intf.j2 @@ -19,11 +19,11 @@ iface {{ iface.name }}{% if iface.name == 'lo' %} inet loopback{% endif +%} {% endif %} {% for ip in iface.ip_addresses %} address {{ ip.address }} -{% set subnet = ip.address | ipaddr('subnet') %} +{% set subnet = ip.address | ansible.utils.ipaddr('subnet') %} {% set prefix = prefixes | selectattr('prefix', '==', subnet) | first %} {% set gateway = prefix.custom_fields.gateway.address %} {% if gateway is defined %} - gateway {{ gateway | ipaddr('address') }} + gateway {{ gateway | ansible.utils.ipaddr('address') }} {% endif %} {% endfor %} diff --git a/templates/hosts.j2 b/templates/hosts.j2 index 8864201..5bf6d9d 100644 --- a/templates/hosts.j2 +++ b/templates/hosts.j2 @@ -11,5 +11,5 @@ ff02::3 ip6-allhosts | map(attribute='interfaces') | flatten | map(attribute='ip_addresses') | flatten | selectattr('dns_name') %} -{{ address.address | ipaddr('address') }} {{ address.dns_name }} {{ address.dns_name | split('.') | first }} +{{ address.address | ansible.utils.ipaddr('address') }} {{ address.dns_name }} {{ address.dns_name | split('.') | first }} {% endfor %} -- 2.49.1 From 0ae9d0592187ed26bf0a101253be824cb514970d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miha=20Frange=C5=BE?= Date: Fri, 9 Jan 2026 11:34:36 +0100 Subject: [PATCH 2/3] New ansible is more strict about types See https://docs.ansible.com/projects/ansible/latest/porting_guides/porting_guide_core_2.19.html#broken-conditionals --- filter_plugins/util.py | 7 +++++++ roles/debian/tasks/main.yml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/filter_plugins/util.py b/filter_plugins/util.py index af5d1b7..e0b34e3 100644 --- a/filter_plugins/util.py +++ b/filter_plugins/util.py @@ -6,6 +6,7 @@ class FilterModule(object): return { 'defaultattr': self.defaultattr, 'list2dict': self.list2dict, + 'any': self.any, } def defaultattr(self, objects, attr, val=None): @@ -19,3 +20,9 @@ class FilterModule(object): Like items2dict but keep entire dictionaries as values. ''' return {item[key]: item for item in items} + + def any(self, items): + ''' + Return True if any item in the list is True. + ''' + return any(items) diff --git a/roles/debian/tasks/main.yml b/roles/debian/tasks/main.yml index 66b0761..b0606d1 100644 --- a/roles/debian/tasks/main.yml +++ b/roles/debian/tasks/main.yml @@ -92,7 +92,7 @@ when: not is_proxmox # proxmox has its own firewall configuration - name: Run SSH instance in management VRF - when: interfaces | selectattr('vrf') | selectattr('vrf.name', '==', 'mgmt') + when: interfaces | selectattr('vrf') | selectattr('vrf.name', '==', 'mgmt') | any block: - name: Configure SSH instance in management VRF copy: -- 2.49.1 From c280703a189033751afcace8c7b0b8958c1753e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miha=20Frange=C5=BE?= Date: Fri, 9 Jan 2026 11:35:17 +0100 Subject: [PATCH 3/3] New ansible being strict about types part 2 --- roles/facts/tasks/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/facts/tasks/main.yml b/roles/facts/tasks/main.yml index bf6e0e3..c900b27 100644 --- a/roles/facts/tasks/main.yml +++ b/roles/facts/tasks/main.yml @@ -48,7 +48,7 @@ set_fact: services: '{{ query("netbox.netbox.nb_lookup", "services", raw_data=true, - api_filter=("virtual_machine_id" if is_virtual else "device_id")+"="+id) }}' + api_filter=("virtual_machine_id" if is_virtual else "device_id")~"="~id) }}' - when: 'cluster is defined and not is_virtual' block: -- 2.49.1