diff --git a/docs/docsite/rst/user_guide/playbooks_filters_ipaddr.rst b/docs/docsite/rst/user_guide/playbooks_filters_ipaddr.rst index 95950023128..8570b91309e 100644 --- a/docs/docsite/rst/user_guide/playbooks_filters_ipaddr.rst +++ b/docs/docsite/rst/user_guide/playbooks_filters_ipaddr.rst @@ -448,6 +448,15 @@ Here are a few simple examples:: # {{ '192.168.0.5' | ipmath(-10) }} 192.167.255.251 + # {{ '192.168.1.1/24' | ipmath(5) }} + 192.168.1.6 + + # {{ '192.168.1.6/24' | ipmath(-5) }} + 192.168.1.1 + + # {{ '192.168.2.6/24' | ipmath(-10) }} + 192.168.1.252 + # {{ '2001::1' | ipmath(10) }} 2001::b diff --git a/lib/ansible/plugins/filter/ipaddr.py b/lib/ansible/plugins/filter/ipaddr.py index ad5edd62e58..d2d1c74b907 100644 --- a/lib/ansible/plugins/filter/ipaddr.py +++ b/lib/ansible/plugins/filter/ipaddr.py @@ -673,8 +673,11 @@ def ipaddr(value, query='', version=False, alias='ipaddr'): def ipmath(value, amount): try: - ip = netaddr.IPAddress(value) - except netaddr.AddrFormatError: + if '/' in value: + ip = netaddr.IPNetwork(value).ip + else: + ip = netaddr.IPAddress(value) + except (netaddr.AddrFormatError, ValueError): msg = 'You must pass a valid IP address; {0} is invalid'.format(value) raise errors.AnsibleFilterError(msg) diff --git a/test/units/plugins/filter/test_ipaddr.py b/test/units/plugins/filter/test_ipaddr.py index 1fe4e1fec58..e7dd89ab11f 100644 --- a/test/units/plugins/filter/test_ipaddr.py +++ b/test/units/plugins/filter/test_ipaddr.py @@ -481,6 +481,10 @@ class TestIpFilter(unittest.TestCase): self.assertEqual(ipmath('192.168.1.5', -5), '192.168.1.0') self.assertEqual(ipmath('192.168.0.5', -10), '192.167.255.251') + self.assertEqual(ipmath('192.168.1.1/24', 5), '192.168.1.6') + self.assertEqual(ipmath('192.168.1.6/24', -5), '192.168.1.1') + self.assertEqual(ipmath('192.168.2.6/24', -10), '192.168.1.252') + self.assertEqual(ipmath('2001::1', 8), '2001::9') self.assertEqual(ipmath('2001::1', 9), '2001::a') self.assertEqual(ipmath('2001::1', 10), '2001::b')