import time
import datetime
import textwrap
+import ipaddress
# Third party modules
import six
from .pidfile import PidFileError, InvalidPidFileError, PidFileInUseError, PidFile
-__version__ = '0.5.3'
+__version__ = '0.5.4'
LOG = logging.getLogger(__name__)
self.temp_log_cfg_file = None
self.temp_zones_cfg_file = None
+ self.acls = {
+ 'allow-notify': ['dnsmaster.pixelpark.com'],
+ 'allow-transfer': ['dnsmaster.pixelpark.com'],
+ }
+
description = textwrap.dedent('''\
Generation of configuration of named (the BIND 9 name daemon).
''').strip()
if section_name.lower() == 'named':
self.set_named_options(section, section_name)
+ if section_name.lower() == 'acl':
+ self.read_acl_lists(section, section_name)
+
self._perform_cmdline_opts()
# -------------------------------------------------------------------------
if masters:
self.zone_masters = masters
+ # -------------------------------------------------------------------------
+ def read_acl_lists(self, section, section_name):
+
+ if self.verbose > 2:
+ LOG.debug("Evaluating config section {n!r}:\n{s}".format(
+ n=section_name, s=pp(section)))
+
+ for acl_name in section.keys():
+
+ entries_str = section[acl_name].strip()
+ entries = self.re_split_addresses.split(entries_str)
+ self.acls[acl_name] = entries
+
# -------------------------------------------------------------------------
def post_init(self):
LOG.info("Generating all config files in a temporary directory ...")
+ self.generate_acl_file()
self.generate_named_conf()
time.sleep(2)
LOG.debug("Temporary LOG conf: {!r}".format(self.temp_log_cfg_file))
LOG.debug("Temporary zones conf: {!r}".format(self.temp_zones_cfg_file))
+ # -------------------------------------------------------------------------
+ def generate_acl_file(self):
+
+ LOG.info("Generating {} ...".format(self.default_named_acl_cfg_file))
+
+ cur_date = datetime.datetime.now().isoformat(' ')
+
+ lines = []
+ lines.append('###############################################################')
+ lines.append('')
+ lines.append(' Bind9 configuration file for ACLs')
+ lines.append(' {}'.format(self.named_acl_cfg_file))
+ lines.append('')
+ lines.append(' Generated at: {}'.format(cur_date))
+ lines.append('')
+ lines.append('###############################################################')
+ header = textwrap.indent('\n'.join(lines), '//', lambda line: True) + '\n'
+
+ content = header
+
+ for acl_name in sorted(self.acls.keys()):
+
+ lines = []
+ lines.append('')
+ lines.append('// ---------------------------------------------------------------')
+ lines.append('acl {} {{'.format(acl_name))
+ if acl_name in ('allow-notify', 'allow-transfer'):
+ lines.append('\t// Localhost')
+ lines.append('\t127.0.0.1;')
+ if self.named_listen_on_v6:
+ lines.append('\t::1;')
+
+ ips_done = []
+
+ for entry in self.acls[acl_name]:
+
+ hostname = entry
+ ip = None
+ ips = []
+ try:
+ ip = ipaddress.ip_address(entry)
+ ips.append(entry)
+ hostname = socket.getfqdn(entry)
+ except ValueError:
+ for info in socket.getaddrinfo(entry, 53):
+ if info[0] not in (socket.AF_INET, socket.AF_INET6):
+ continue
+ if info[0] == socket.AF_INET:
+ ips.append(info[4][0])
+ elif self.named_listen_on_v6:
+ ips.append(info[4][0])
+
+ if ips and hostname:
+ lines.append('\t// {}'.format(hostname))
+ for ip in sorted(ips):
+ if ip not in ips_done:
+ lines.append('\t{};'.format(ip))
+ ips_done.append(ip)
+ else:
+ msg = "Did not found IP address of {!r} for ACL {!r}.".format(
+ entry, acl_name)
+ LOG.error(msg)
+
+ lines.append('};')
+
+ content += '\n'.join(lines) + '\n'
+
+ content += '\n// vim: ts=8 filetype=named noet noai\n'
+
+ with open(self.temp_acl_cfg_file, 'w', **self.open_args) as fh:
+ fh.write(content)
+
+ if self.verbose > 2:
+ LOG.debug("Generated {!r}:\n{}".format(self.temp_acl_cfg_file, content.strip()))
+
+
# -------------------------------------------------------------------------
def generate_named_conf(self):