ipaddr: add an option to return peer of a point-to-point link (#59144)

* ipaddr: add an option to return peer of a point-to-point link

Signed-off-by: Vincent Bernat <vincent@bernat.ch>

* ipaddr: extend "peer" to also work with /30
This commit is contained in:
Vincent Bernat 2019-11-13 19:47:05 +01:00 committed by ansibot
parent bb72b8f1d9
commit bf19060683
3 changed files with 49 additions and 0 deletions

View file

@ -434,6 +434,13 @@ To find the next nth usable IP address within a range, use ``next_nth_usable``::
In this example, ``next_nth_usable`` returns the second usable IP address for the given IP range.
To find the peer IP address for a point to point link, use ``peer``::
# {{ '192.168.122.1/31' | ipaddr('peer') }}
192.168.122.0
# {{ '192.168.122.1/30' | ipaddr('peer') }}
192.168.122.2
IP Math
^^^^^^^

View file

@ -277,6 +277,21 @@ def _next_usable_query(v, vtype):
return str(netaddr.IPAddress(int(v.ip) + 1))
def _peer_query(v, vtype):
if vtype == 'address':
raise errors.AnsibleFilterError("Not a network address")
elif vtype == 'network':
if v.size == 2:
return str(netaddr.IPAddress(int(v.ip) ^ 1))
if v.size == 4:
if int(v.ip) % 4 == 0:
raise errors.AnsibleFilterError("Network address of /30 has no peer")
if int(v.ip) % 4 == 3:
raise errors.AnsibleFilterError("Broadcast address of /30 has no peer")
return str(netaddr.IPAddress(int(v.ip) ^ 3))
raise errors.AnsibleFilterError("Not a point-to-point network")
def _prefix_query(v):
return int(v.prefixlen)
@ -463,6 +478,7 @@ def ipaddr(value, query='', version=False, alias='ipaddr'):
'lo': ('value',),
'multicast': ('value',),
'next_usable': ('vtype',),
'peer': ('vtype',),
'previous_usable': ('vtype',),
'private': ('value',),
'public': ('value',),
@ -507,6 +523,7 @@ def ipaddr(value, query='', version=False, alias='ipaddr'):
'network/prefix': _subnet_query,
'network_netmask': _network_netmask_query,
'network_wildcard': _network_wildcard_query,
'peer': _peer_query,
'prefix': _prefix_query,
'previous_usable': _previous_usable_query,
'private': _private_query,

View file

@ -336,6 +336,31 @@ class TestIpFilter(unittest.TestCase):
address = '1.12.1.254/24'
self.assertEqual(ipaddr(address, 'next_usable'), None)
def test_peer(self):
address = '1.12.1.0/31'
self.assertEqual(ipaddr(address, 'peer'), '1.12.1.1')
address = '1.12.1.1/31'
self.assertEqual(ipaddr(address, 'peer'), '1.12.1.0')
address = '1.12.1.1/30'
self.assertEqual(ipaddr(address, 'peer'), '1.12.1.2')
address = '1.12.1.2/30'
self.assertEqual(ipaddr(address, 'peer'), '1.12.1.1')
with self.assertRaises(AnsibleFilterError):
address = '1.12.1.34'
ipaddr(address, 'peer')
with self.assertRaises(AnsibleFilterError):
address = '1.12.1.33/29'
ipaddr(address, 'peer')
with self.assertRaises(AnsibleFilterError):
address = '1.12.1.32/30'
ipaddr(address, 'peer')
with self.assertRaises(AnsibleFilterError):
address = '1.12.1.35/30'
ipaddr(address, 'peer')
with self.assertRaises(AnsibleFilterError):
address = '1.12.1.34/32'
ipaddr(address, 'peer')
def test_previous_usable(self):
address = '1.12.1.0/24'
self.assertEqual(ipaddr(address, 'previous_usable'), None)