tripleo-ipa/tripleo_ipa/ansible_plugins/filter/dns_data.py

140 lines
4.1 KiB
Python

#!/usr/bin/python
#
# Copyright 2023 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from ipaddress import ip_address, IPv4Address
def _parse_host_entry(entry):
if len(entry.split()) >= 2:
value = entry.split()[0]
try:
ip = ip_address(value)
record_type = 'A' if (type(ip) is IPv4Address) else 'AAAA'
except ValueError:
return "", "", "Invalid", ""
host = entry.split()[1]
host_split = host.split('.', 1)
if (len(host_split) == 2):
name = host_split[0]
zone = host_split[1]
return value, name, record_type, zone
return "", "", "Invalid", ""
def _get_reverse_entry(name, zone, ip_str):
# this should follow ipa heuristics to get the reverse domain
ip = ip_address(ip_str)
prefix = 1 if (type(ip) is IPv4Address) else 16
zone_name = '.'.join(ip.reverse_pointer.split('.')[prefix:])
record_name = '.'.join(ip.reverse_pointer.split('.', prefix)[:-1])
record_value = '.'.join((name, zone)) + '.'
record = {"record_name": record_name,
"zone_name": zone_name,
"record_type": "PTR",
"record_value": record_value}
return zone_name, record
def _clean_hosts_entries(hosts_entries, cdomain):
entries = list()
for host_entry in hosts_entries:
value, name, record_type, zone = _parse_host_entry(host_entry)
if record_type == "Invalid":
continue
if not zone.endswith(cdomain):
continue
entries.append(host_entry)
return entries
def _parse_hosts_entries(hosts_entries_in, cdomain):
"""Extract parameters to add dns entries from hosts_data
---
:param hosts_data: is a list of strings, with each string being a line
in the /etc/hosts file.
:returns: two lists. a list of dicts containing the parameters needed for
ansible-freeipa dnsrecord to add, and a list of dicts containing
dnszones to add.
"""
zones = set()
records = list()
hosts_entries = _clean_hosts_entries(hosts_entries_in, cdomain)
# get forward entries
for host_entry in hosts_entries:
value, name, record_type, zone = _parse_host_entry(host_entry)
# add forward zone
if zone not in zones:
zones.add(zone)
# add forward record
record = {"record_name": name,
"zone_name": zone,
"record_type": record_type,
"record_value": value}
records.append(record)
# NOTE(alee) Create a set of reverse DNS records to be added. We need
# to process entries in the reverse order, because there may be duplicate
# entries and we only want the latest entry.
visited_ips = set()
for host_entry in reversed(hosts_entries):
value, name, record_type, zone = _parse_host_entry(host_entry)
if value in visited_ips:
continue
visited_ips.add(value)
zone, record = _get_reverse_entry(name, zone, value)
# add reverse zone
if zone not in zones:
zones.add(zone)
# add reverse record
records.append(record)
return [list(zones), records]
def get_dns_zones(hosts_entries, cdomain):
return _parse_hosts_entries(hosts_entries, cdomain)[0]
def get_dns_entries(hosts_entries, cdomain):
return _parse_hosts_entries(hosts_entries, cdomain)[1]
class FilterModule(object):
def filters(self):
return {
'get_dns_entries': get_dns_entries,
'get_dns_zones': get_dns_zones
}