From dee9e8d3021ee5f825ae98fc8eb1c2f4256994dc Mon Sep 17 00:00:00 2001 From: Frank Brehm Date: Tue, 7 Nov 2017 16:56:18 +0100 Subject: [PATCH] Adding pp_lib/pdns_app.py --- pp_lib/pdns_app.py | 296 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 296 insertions(+) create mode 100644 pp_lib/pdns_app.py diff --git a/pp_lib/pdns_app.py b/pp_lib/pdns_app.py new file mode 100644 index 0000000..2b5b63f --- /dev/null +++ b/pp_lib/pdns_app.py @@ -0,0 +1,296 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +@author: Frank Brehm +@contact: frank.brehm@pixelpark.com +@copyright: © 2017 by Frank Brehm, Berlin +@summary: The module for a application object related to PowerDNS. +""" +from __future__ import absolute_import + +# Standard modules +import logging +import logging.config +import re +import copy +import json + +# Third party modules +import requests +import six + +# Own modules +from .common import pp, to_bool + +from .cfg_app import PpCfgAppError, PpConfigApplication + +__version__ = '0.1.0' +LOG = logging.getLogger(__name__) + + +# ============================================================================= +class PpPDNSAppError(PpCfgAppError): + """Base error class for all exceptions happened during + execution this configured application""" + + pass + + +# ============================================================================= +class PpPDNSApplication(PpConfigApplication): + """ + Class for configured application objects related to PowerDNS. + """ + + api_keys = { + 'global': "6d1b08e2-59c6-49e7-9e48-039ade102016", + 'public': "cf0fb928-2a73-49ec-86c2-36e85c9672ff", + 'local': "d94b183a-c50d-47f7-b338-496090af1577" + } + + api_hosts = { + 'global': "systemshare.pixelpark.com", + 'public': "dnsmaster-public.pixelpark.com", + 'local': "dnsmaster-local.pixelpark.com" + } + + default_api_port = 8081 + default_api_servername = "localhost" + + # ------------------------------------------------------------------------- + def __init__( + self, appname=None, verbose=0, version=__version__, base_dir=None, + initialized=None, usage=None, description=None, + argparse_epilog=None, argparse_prefix_chars='-', env_prefix=None, + cfg_dir=None, cfg_stems=None, cfg_encoding='utf-8', need_config_file=False): + + self._api_key = self.api_keys['global'] + self._api_host = self.api_hosts['global'] + self._api_port = self.default_api_port + self._api_servername = self.default_api_servername + self._user_agent = '{}/{}'.format(_LIBRARY_NAME, __version__) + self._environment = 'global' + + super(PpPDNSApplication, self).__init__( + appname=appname, verbose=verbose, version=version, base_dir=base_dir, + initialized=False, usage=usage, description=description, + argparse_epilog=argparse_epilog, argparse_prefix_chars=argparse_prefix_chars, + env_prefix=env_prefix, cfg_dir=cfg_dir, cfg_stems=stems, + cfg_encoding=cfg_encoding, need_config_file=need_config_file, + ) + + # ----------------------------------------------------------- + @property + def api_key(self): + "The API key to use the PowerDNS API" + return self._api_key + + @api_key.setter + def api_key(self, value): + if value is None or str(value).strip() == '': + raise PpPDNSAppError("Invalid API key {!r} given.".format(value)) + self._api_key = str(value).strip() + + # ----------------------------------------------------------- + @property + def api_host(self): + "The host name or address providing the PowerDNS API." + return self._api_host + + @api_host.setter + def api_host(self, value): + if value is None or str(value).strip() == '': + raise PpPDNSAppError("Invalid API host {!r} given.".format(value)) + self._api_host = str(value).strip().lower() + + # ----------------------------------------------------------- + @property + def api_port(self): + "The TCP port number of the PowerDNS API." + return self._api_port + + @api_port.setter + def api_port(self, value): + v = int(value) + if v < 1: + raise PpPDNSAppError("Invalid API port {!r} given.".format(value)) + self._api_port = v + + # ----------------------------------------------------------- + @property + def api_servername(self): + "The (virtual) name of the PowerDNS server used in API calls." + return self._api_servername + + @api_servername.setter + def api_servername(self.value): + if value is None or str(value).strip() == '': + raise PpPDNSAppError("Invalid API server name {!r} given.".format(value)) + self._api_servername = str(value).strip() + + # ----------------------------------------------------------- + @property + def user_agent(self): + "The name of the user agent used in API calls." + return self._user_agent + + @user_agent.setter + def user_agent(self.value): + if value is None or str(value).strip() == '': + raise PpPDNSAppError("Invalid user agent {!r} given.".format(value)) + self._user_agent = str(value).strip() + + # ----------------------------------------------------------- + @property + def environment(self): + "The name of the PowerDNS environment." + return self._environment + + @environment.setter + def environment(self, value): + if value is None: + raise PpPDNSAppError("Invalid environment None given.") + v = str(value).strip().lower() + if v not in self.api_keys.keys(): + raise PpPDNSAppError("Invalid environment {!r} given.".format(value)) + self._environment = v + self._api_host = self.api_hosts[v] + self._api_key = self.api_keys[v] + + # ------------------------------------------------------------------------- + def as_dict(self, short=True): + """ + Transforms the elements of the object into a dict + + @param short: don't include local properties in resulting dict. + @type short: bool + + @return: structure as dict + @rtype: dict + """ + + res = super(PpPDNSApplication, self).as_dict(short=short) + res['api_host'] = self.api_host + res['api_hosts'] = copy.copy(self.api_hosts) + res['api_key'] = self.api_key + res['api_keys'] = copy.copy(self.api_keys) + res['api_port'] = self.api_port + res['api_servername'] = self.api_servername + res['default_api_servername'] = self.default_api_servername + res['default_api_port'] = self.default_api_port + res['environment'] = self.environment + res['user_agent'] = self.user_agent + + return res + + # ------------------------------------------------------------------------- + def init_arg_parser(self): + """ + Method to initiate the argument parser. + + This method should be explicitely called by all init_arg_parser() + methods in descendant classes. + """ + + super(PpPDNSApplication, self).init_arg_parser() + + pdns_group = self.arg_parser.add_argument_group('PowerDNS API options') + env_group = pdns_group.add_mutually_exclusive_group() + + env_group.add_argument( + '-E', '--env', '--environment', + metavar="ENVIRONMENT", choices=self.api_keys.keys().sort(), dest="env", + help=( + "Select, which PowerDNS environment to use. " + "Valid values: {v}, default: {d!r}.".format( + v=', '.join(map(lambda x: repr(x), self.api_keys.keys().sort())), + d='global')) + ) + + env_group.add_argument( + '-G', '--global', + action='store_true', dest="env_global", + help=("Using the 'global' PowerDNS environment."), + ) + + env_group.add_argument( + '-L', '--local', + action='store_true', dest="env_local", + help=("Using the 'local' PowerDNS environment."), + ) + + env_group.add_argument( + '-P', '--public', + action='store_true', dest="env_public", + help=("Using the 'public' PowerDNS environment."), + ) + + pdns_group.add_argument( + '-p', '--port', + metavar="PORT", type=int, dest='api_port', default=self.default_api_port, + help=("Which port to connect to PowerDNS API, default: {}.".format(self.default_api_port)), + ) + + # ------------------------------------------------------------------------- + def perform_arg_parser(self): + """ + Public available method to execute some actions after parsing + the command line parameters. + """ + + if self.args.env: + self.environment = self.args.env + elif self.args.env_global: + self.environment = 'global' + elif self.args.env_local: + self.environment = 'local' + elif self.args.env_public: + self.environment = 'public' + + if self.args.api_port: + self.api_port = self.args.api_port + + # ------------------------------------------------------------------------- + def pre_run(self): + """ + Dummy function to run before the main routine. + Could be overwritten by descendant classes. + + """ + + if self.verbose > 1: + LOG.debug("executing pre_run() ...") + + super(PpPDNSApplication, self).pre_run() + + # ------------------------------------------------------------------------- + def _run(self): + """ + Dummy function as main routine. + + MUST be overwritten by descendant classes. + + """ + LOG.debug("Executing nothing ...") + + # ------------------------------------------------------------------------- + def post_run(self): + """ + Dummy function to run after the main routine. + Could be overwritten by descendant classes. + + """ + + if self.verbose > 1: + LOG.debug("executing post_run() ...") + + +# ============================================================================= + +if __name__ == "__main__": + + pass + +# ============================================================================= + +# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 list -- 2.39.5