Skip to content

Commit

Permalink
Add reverse_pointer filter.
Browse files Browse the repository at this point in the history
  • Loading branch information
felixfontein committed Nov 10, 2024
1 parent 4108826 commit 2da4a2e
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 0 deletions.
84 changes: 84 additions & 0 deletions plugins/filter/reverse_pointer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# -*- coding: utf-8 -*-

# Copyright (c) 2020-2021, Felix Fontein <felix@fontein.de>
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later

from __future__ import absolute_import, division, print_function
__metaclass__ = type


DOCUMENTATION = r"""
name: reverse_pointer
short_description: Convert an IP address into a DNS name for reverse lookup
version_added: 3.1.0
description:
- Given an IPv4 or IPv6 address, such as V(192.168.1.2), converts it to a DNS name to use for
reverse lookups, such as V(2.1.168.192.in-addr.arpa).
options:
_input:
description:
- The IP address.
type: string
required: true
author:
- Felix Fontein (@felixfontein)
seealso:
- name: RFC 1035, Section 3.5
link: https://www.rfc-editor.org/rfc/rfc1035.html#section-3.5
description: Describes C(in-addr.arpa).
- name: RFC 3152
link: https://www.rfc-editor.org/rfc/rfc3152.html
description: Describes C(ip6.arpa).
"""

EXAMPLES = r"""
- name: Convert IP address to DNS name for reverse lookup
ansible.builtin.set_fact:
dns_name: "{{ ip_address | community.dns.reverse_pointer }}"
# Should result in '2.1.168.192.in-addr.arpa.'
vars:
ip_address: 192.168.1.2
"""

RETURN = r"""
_value:
description: The DNS name.
type: string
"""


from ansible.errors import AnsibleFilterError
from ansible.module_utils.common.text.converters import to_text
from ansible.module_utils.six import string_types

from ansible_collections.community.dns.plugins.plugin_utils.ips import assert_requirements_present

try:
import ipaddress
except ImportError:
# handled by assert_requirements_present
pass


def reverse_pointer(ip):
assert_requirements_present('community.dns.reverse_pointer', 'filter')
if not isinstance(ip, string_types):
raise AnsibleFilterError('Input for community.dns.reverse_pointer must be a string')
try:
ipaddr = ipaddress.ip_address(to_text(ip))
except Exception as e:
raise AnsibleFilterError('Cannot parse IP address: {error}'.format(error=e))
res = ipaddr.reverse_pointer
if not res.endswith(u'.'):
res += u'.'
return res


class FilterModule(object):
'''Ansible jinja2 filters'''

def filters(self):
return {
'reverse_pointer': reverse_pointer,
}
5 changes: 5 additions & 0 deletions tests/integration/targets/filter_reverse_pointer/aliases
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later

shippable/posix/group1
41 changes: 41 additions & 0 deletions tests/integration/targets/filter_reverse_pointer/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later

- name: Compute reverse pointer
ansible.builtin.set_fact:
reverse_ipv4: >-
{{ '192.168.1.2' | community.dns.reverse_pointer }}
reverse_ipv6: >-
{{ 'a::B' | community.dns.reverse_pointer }}
- name: Check results
assert:
that:
- reverse_ipv4 == '2.1.168.192.in-addr.arpa.'
- reverse_ipv6 == 'b.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.a.0.0.0.ip6.arpa.'

- name: Process invalid IP address
ansible.builtin.set_fact:
reverse_nope: >-
{{ 'foo.com' | community.dns.reverse_pointer }}
ignore_errors: true
register: invalid_ip

- name: Process non-string
ansible.builtin.set_fact:
reverse_nope: >-
{{ 42 | community.dns.reverse_pointer }}
ignore_errors: true
register: non_string

- name: Check results
assert:
that:
- invalid_ip is failed
- >-
"Cannot parse IP address: 'foo.com' does not appear to be an IPv4 or IPv6 address" in invalid_ip.msg
- non_string is failed
- >-
"Input for community.dns.reverse_pointer must be a string" in non_string.msg

0 comments on commit 2da4a2e

Please sign in to comment.