From ec94d5880667526c5251c0269a64be455cd42636 Mon Sep 17 00:00:00 2001 From: Frank Brehm Date: Mon, 7 Aug 2017 13:01:45 +0200 Subject: [PATCH] Starting with generation of named.conf --- pp_lib/config_named_app.py | 118 +++++++++++++++++++++++++++++++++++-- pp_lib/pidfile.py | 5 +- 2 files changed, 116 insertions(+), 7 deletions(-) diff --git a/pp_lib/config_named_app.py b/pp_lib/config_named_app.py index 20fa72e..0c961d8 100644 --- a/pp_lib/config_named_app.py +++ b/pp_lib/config_named_app.py @@ -21,6 +21,9 @@ import socket import pwd import grp import tempfile +import time +import datetime +import textwrap # Third party modules import six @@ -35,7 +38,7 @@ from .cfg_app import PpCfgAppError, PpConfigApplication from .pidfile import PidFileError, InvalidPidFileError, PidFileInUseError, PidFile -__version__ = '0.4.3' +__version__ = '0.5.1' LOG = logging.getLogger(__name__) @@ -115,7 +118,7 @@ class PpConfigNamedApp(PpConfigApplication): # Configuration files and directories self.named_conf_dir = self.default_named_conf_dir - self.named_conf = self.default_named_conf + self._named_conf = self.default_named_conf self.named_bindkeys_file = self.default_named_bindkeys_file self.named_rootkeys_file = self.default_named_rootkeys_file self.named_def_zones_file = self.default_named_def_zones_file @@ -172,6 +175,12 @@ class PpConfigNamedApp(PpConfigApplication): self.post_init() + # ------------------------------------------- + @property + def named_conf(self): + """The named.conf as an absolute pathname.""" + return os.path.join(self.named_conf_dir, self._named_conf) + # ------------------------------------------------------------------------- def as_dict(self, short=True): """ @@ -185,6 +194,7 @@ class PpConfigNamedApp(PpConfigApplication): """ res = super(PpConfigNamedApp, self).as_dict(short=short) + res['named_conf'] = self.named_conf res['default_pidfile'] = self.default_pidfile res['default_pdns_api_host'] = self.default_pdns_api_host res['default_pdns_api_port'] = self.default_pdns_api_port @@ -340,7 +350,7 @@ class PpConfigNamedApp(PpConfigApplication): # Configuration files and directories self._check_path_config(section, section_name, 'config_dir', 'named_conf_dir', True) - self._check_path_config(section, section_name, 'named_conf', 'named_conf', False) + self._check_path_config(section, section_name, 'named_conf', '_named_conf', False) self._check_path_config( section, section_name, 'bindkeys_file', 'named_bindkeys_file', False) self._check_path_config( @@ -495,8 +505,13 @@ class PpConfigNamedApp(PpConfigApplication): def _run(self): if os.geteuid(): - LOG.error("You must be root to execute this script.") - self.exit(1) + if self.simulate: + LOG.warn("You must be root to execute this script.") + LOG.warn("But hey - this is simulation mode ...") + time.sleep(1) + else: + LOG.error("You must be root to execute this script.") + self.exit(1) try: self.pidfile.create() @@ -509,6 +524,7 @@ class PpConfigNamedApp(PpConfigApplication): self.get_api_zones() self.init_temp_objects() + self.create_temp_files() finally: if self.tempdir: @@ -517,6 +533,15 @@ class PpConfigNamedApp(PpConfigApplication): self.tempdir = None self.pidfile = None + # ------------------------------------------------------------------------- + def create_temp_files(self): + + LOG.info("Generating all config files in a temporary directory ...") + + self.generate_named_conf() + + time.sleep(2) + # ------------------------------------------------------------------------- def init_temp_objects(self): """Init temporary objects and properties.""" @@ -541,6 +566,89 @@ class PpConfigNamedApp(PpConfigApplication): 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_named_conf(self): + + LOG.info("Generating {} ...".format(self.default_named_conf)) + + cur_date = datetime.datetime.now().isoformat(' ') + + acl_file = os.path.join(self.named_conf_dir, self.named_acl_cfg_file) + named_pidfile = os.path.join(self.named_rundir, self.named_pidfile) + dump_dir = os.path.join(self.named_basedir, 'dump') + dump_file = os.path.join(dump_dir, 'named_dump.db') + stats_dir = os.path.join(self.named_basedir, 'stats') + stats_file = os.path.join(stats_dir, 'named.stats') + + lines = [] + lines.append('###############################################################') + lines.append('') + lines.append(' Main Bind9 configuration file') + lines.append(' {}'.format(self.named_conf)) + lines.append('') + lines.append(' Provided by Red Hat bind package to configure the ISC BIND named(8) DNS') + lines.append('') + lines.append(' See /usr/share/doc/bind*/sample/ for example named configuration files.') + lines.append('') + lines.append(' See the BIND Administrator\'s Reference Manual (ARM) for details about the') + lines.append(' configuration located in /usr/share/doc/bind-{version}/Bv9ARM.html') + 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 + + content += '\n// access control lists\n' + content += 'include "{}";\n'.format(acl_file) + + option_lines = [] + option_lines.append('options {') + option_lines.append('\tlisten-on { any; };') + if self.named_listen_on_v6: + option_lines.append('\tlisten-on-v6 { any; };') + else: + option_lines.append('\tlisten-on-v6 { ::1; };') + option_lines.append('') + option_lines.append('\trecursion no;') + option_lines.append('') + option_lines.append('\tdirectory "{}";'.format(self.named_basedir)) + option_lines.append('\tpid-file "{}";'.format(named_pidfile)) + option_lines.append('\tdump-file "{}";'.format(dump_file)) + option_lines.append('\tstatistics-file "{}";'.format(stats_file)) + + option_lines.append('') + option_lines.append('\t// DNSSEC') + option_lines.append('\tdnssec-enable yes;') + option_lines.append('\tdnssec-validation yes;') + + option_lines.append('') + option_lines.append('\tallow-transfer {') + option_lines.append('\t\tallow-transfer;') + option_lines.append('\t};') + + option_lines.append('') + option_lines.append('\tallow-notify {') + option_lines.append('\t\tallow-notify;') + option_lines.append('\t};') + + if not self.named_show_bind_version: + option_lines.append('') + option_lines.append('\tversion "{}";'.format(self.named_version2show)) + + option_lines.append('') + option_lines.append('};') + content += '\n' + '\n'.join(option_lines) + '\n' + + content += '\n// vim: ts=8 filetype=named noet noai\n' + + with open(self.temp_named_conf, 'w', **self.open_args) as fh: + fh.write(content) + + if self.verbose > 2: + LOG.debug("Generated {!r}:\n{}".format(self.temp_named_conf, content.strip())) + # ------------------------------------------------------------------------- def get_api_zones(self): diff --git a/pp_lib/pidfile.py b/pp_lib/pidfile.py index ddb67ea..ab6432a 100644 --- a/pp_lib/pidfile.py +++ b/pp_lib/pidfile.py @@ -32,7 +32,7 @@ from .obj import PpBaseObject from .common import to_utf8 -__version__ = '0.2.2' +__version__ = '0.2.3' LOG = logging.getLogger(__name__) @@ -253,6 +253,7 @@ class PidFile(PpBaseObject): res['created'] = self.created res['timeout'] = self.timeout res['parent_dir'] = self.parent_dir + res['open_args'] = self.open_args return res @@ -396,7 +397,7 @@ class PidFile(PpBaseObject): fh = None try: - fh = open(self.filename, 'w', self.open_args) + fh = open(self.filename, 'w', **self.open_args) except OSError as e: error_tuple = sys.exc_info() msg = "Error on recreating pidfile {!r}: {}".format(self.filename, e) -- 2.39.5