from fb_pdnstools.server import PowerDNSServer
from fb_pdnstools.errors import PDNSApiNotFoundError
from fb_pdnstools.errors import PDNSApiValidationError
+from fb_tools.xlate import format_list
-from fb_tools.errors import FbCfgAppError
+from . import __version__ as GLOBAL_VERSION
-from fb_tools.cfg_app import FbConfigApplication
+from .argparse_actions import PortOptionAction, TimeoutOptionAction
+
+from .mail_app import MailAppError, BaseMailApplication
+
+from .pdns_config import PdnsConfigError, PdnsConfiguration, LIBRARY_NAME
from .xlate import XLATOR
-__version__ = '0.8.0'
+__version__ = '0.9.0'
LOG = logging.getLogger(__name__)
-_LIBRARY_NAME = "pp-pdns-api-client"
_ = XLATOR.gettext
# =============================================================================
-class PpPDNSAppError(FbCfgAppError):
+class PpPDNSAppError(MailAppError):
"""Base error class for all exceptions happened during
execution this configured application"""
pass
# =============================================================================
-class PpPDNSApplication(FbConfigApplication):
+class PpPDNSApplication(BaseMailApplication):
"""
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': "dnsmaster.pp-dns.com",
- 'public': "dnsmaster-public.pixelpark.com",
- 'local': "dnsmaster-local.pixelpark.com"
- }
-
- default_api_port = 8081
- default_api_servername = "localhost"
- default_timeout = 20
-
# -------------------------------------------------------------------------
def __init__(
- self, appname=None, verbose=0, version=__version__, base_dir=None,
- initialized=None, usage=None, description=None,
+ self, appname=None, verbose=0, version=GLOBAL_VERSION, base_dir=None,
+ cfg_class=PdnsConfiguration, initialized=False, 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,
- environment='global'):
+ instance=None):
+
+ if instance:
+ self._instance = instance
+ else:
+ self._instance = PdnsConfiguration.default_pdns_instance
- 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._api_key = None
+ self._api_host = None
+ self._api_port = None
+ self._api_servername = None
self._api_server_version = 'unknown'
- self._user_agent = '{}/{}'.format(_LIBRARY_NAME, self.version)
- self._timeout = self.default_timeout
self.local_addresses = []
self.pdns = None
- self._environment = 'global'
- if environment != 'global':
- self.environment = environment
-
- stems = []
- if cfg_stems:
- if isinstance(cfg_stems, list):
- for stem in cfg_stems:
- s = str(stem).strip()
- if not s:
- msg = _("Invalid configuration stem {!r} given.").format(stem)
- raise PpPDNSAppError(msg)
- stems.append(s)
- else:
- s = str(cfg_stems).strip()
- if not s:
- msg = _("Invalid configuration stem {!r} given.").format(cfg_stems)
- raise PpPDNSAppError(msg)
- stems.append(s)
- else:
- stems = [self.appname]
- if 'pdns-api' not in stems:
- stems.insert(0, 'pdns-api')
-
super(PpPDNSApplication, self).__init__(
appname=appname, verbose=verbose, version=version, base_dir=base_dir,
- initialized=False, usage=usage, description=description,
+ description=description, cfg_class=cfg_class, initialized=False,
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,
+ env_prefix=env_prefix,
)
for interface, snics in psutil.net_if_addrs().items():
if addr not in self.local_addresses:
self.local_addresses.append(addr)
- self._user_agent = '{}/{}'.format(_LIBRARY_NAME, self.version)
+ if not self.cfg:
+ msg=_("Configuration not available.")
+ raise PpPDNSAppError(msg)
+
+ self.eval_instance(instance)
# -----------------------------------------------------------
@property
# -----------------------------------------------------------
@property
- def user_agent(self):
- "The name of the user agent used in API calls."
- return self._user_agent
+ def instance(self):
+ "The name of the PowerDNS instance."
+ return self._instance
- @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()
+ @instance.setter
+ def instance(self, value):
+ if value is None:
+ raise PpPDNSAppError(_("Invalid instance {!r} given.").format(None))
+ v = str(value).strip().lower()
+ if v not in self.api_keys.keys():
+ raise PpPDNSAppError(_("Invalid instance {!r} given.").format(value))
- # -----------------------------------------------------------
- @property
- def timeout(self):
- "The timeout in seconds on requesting the PowerDNS API."
- return self._timeout
+ self.eval_instance(v)
- @timeout.setter
- def timeout(self, value):
- v = int(value)
- if v < 1:
- raise PpPDNSAppError(_("Invalid timeout {!r} given.").format(value))
- self._timeout = v
+ # -------------------------------------------------------------------------
+ def eval_instance(self, inst_name):
- # -----------------------------------------------------------
- @property
- def environment(self):
- "The name of the PowerDNS environment."
- return self._environment
+ if not self.cfg:
+ msg = _("Configuration not available.")
+ raise PpPDNSAppError(msg)
- @environment.setter
- def environment(self, value):
- if value is None:
- raise PpPDNSAppError(_("Invalid environment {!r} given.").format(None))
- 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]
+ if inst_name not in self.cfg.pdns_api_instances:
+ msg = _("PDNS instance {!r} is not configured.").format(inst_name)
+ raise PpPDNSAppError(msg)
+
+ inst = self.cfg.pdns_api_instances[inst_name]
+
+ self._instance = inst_name
+ self.api_host = inst['host']
+ self.api_port = inst['port']
+ self.api_key = inst['key']
+ self.api_servername = inst['servername']
# -------------------------------------------------------------------------
def as_dict(self, short=True):
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_port'] = self.default_api_port
- res['default_api_servername'] = self.default_api_servername
- res['default_timeout'] = self.default_timeout
- res['environment'] = self.environment
- res['timeout'] = self.timeout
- res['user_agent'] = self.user_agent
+ res['instance'] = self.instance
res['api_server_version'] = self.api_server_version
return res
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()
+ inst_group = pdns_group.add_mutually_exclusive_group()
- envs = []
- for env in self.api_keys.keys():
- envs.append(str(env))
- envs.sort()
+ insts = PdnsConfiguration.valid_pdns_api_instances
+ inst_list = format_list(insts, do_repr=True)
+ default_timeout = PdnsConfiguration.default_pdns_timeout
- env_group.add_argument(
- '-E', '--env', '--environment',
- metavar=_("ENVIRONMENT"), choices=envs, dest="env",
+ inst_group.add_argument(
+ '-I', '--inst', '--instance',
+ metavar=_("INSTANCE"), choices=envs, dest="inst",
help=_(
- "Select, which PowerDNS environment to use. "
- "Valid values: {v}, default: {d!r}.").format(
- v=', '.join(map(lambda x: repr(x), envs)), d='global')
+ "Select, which PowerDNS instance to use. Valid values: {v}, "
+ "default: {d!r}.").format(v=inst_list, d=self.instance),
)
- env_group.add_argument(
+ inst_group.add_argument(
'-G', '--global',
- action='store_true', dest="env_global",
- help=_("Using the {!r} PowerDNS environment.").format('global'),
+ action='store_true', dest="inst_global",
+ help=_("Using the {!r} PowerDNS instance.").format('global'),
)
- env_group.add_argument(
+ inst_group.add_argument(
'-L', '--local',
- action='store_true', dest="env_local",
- help=_("Using the {!r} PowerDNS environment.").format('local'),
+ action='store_true', dest="inst_local",
+ help=_("Using the {!r} PowerDNS instance.").format('local'),
)
- env_group.add_argument(
+ inst_group.add_argument(
'-P', '--public',
- action='store_true', dest="env_public",
- help=_("Using the {!r} PowerDNS environment.").format('public'),
+ action='store_true', dest="inst_public",
+ help=_("Using the {!r} PowerDNS instance.").format('public'),
)
pdns_group.add_argument(
'-p', '--port',
- metavar=_("PORT"), type=int, dest='api_port', default=self.default_api_port,
+ metavar=_("PORT"), type=int, dest='api_port',
+ default=PdnsConfiguration.default_pdns_api_port,
+ what="PowerDNS API", action=PortOptionAction,
help=_("Which port to connect to PowerDNS API, default: {}.").format(
- self.default_api_port),
+ PdnsConfiguration.default_pdns_api_port),
)
pdns_group.add_argument(
'-t', '--timeout',
- metavar=_("SECS"), type=int, dest='timeout', default=self.default_timeout,
+ metavar=_("SECS"), type=int, dest='timeout', default=default_timeout,
+ what=_("PowerDNS API access"), action=TimeoutOptionAction,
help=_("The timeout in seconds to request the PowerDNS API, default: {}.").format(
- self.default_timeout),
+ default_timeout),
)
# -------------------------------------------------------------------------
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
-
- if self.args.timeout:
- self.timeout = self.args.timeout
-
- # -------------------------------------------------------------------------
- def perform_config(self):
-
- super(PpPDNSApplication, self).perform_config()
-
- for section_name in self.cfg.keys():
-
- if self.verbose > 3:
- LOG.debug(_("Checking config section {!r} ...").format(section_name))
-
- section = self.cfg[section_name]
-
- if section_name.lower() in (
- 'powerdns-api', 'powerdns_api', 'powerdnsapi',
- 'pdns-api', 'pdns_api', 'pdnsapi'):
- self.set_cfg_api_options(section, section_name)
-
- # -------------------------------------------------------------------------
- def set_cfg_api_options(self, section, section_name):
-
- if self.verbose > 2:
- LOG.debug(
- _("Evaluating config section {!r}:").format(section_name) + '\n' + pp(section))
-
- if 'environment' in section:
- v = section['environment'].strip().lower()
- if v not in self.api_hosts:
- LOG.error(_("Wrong environment {!r} found in configuration.").format(
- section['environment']))
- self.config_has_errors = True
- else:
- self.environment = v
-
- if 'host' in section:
- v = section['host']
- host = v.lower().strip()
- if host:
- self.api_host = host
-
- if 'port' in section:
- try:
- port = int(section['port'])
- if port <= 0 or port > 2**16:
- raise ValueError(
- _("A port must be greater than 0 and less than {}.").format(2**16))
- except (TypeError, ValueError) as e:
- LOG.error(_("Wrong port number {p!r} in configuration section {s!r}: {e}").format(
- p=section['port'], s=section_name, e=e))
- self.config_has_errors = True
- else:
- self.api_port = port
-
- if 'server_id' in section and section['server_id'].strip():
- self.api_servername = section['server_id'].strip().lower()
-
- if 'key' in section:
- key = section['key'].strip()
- self.api_key = key
-
# -------------------------------------------------------------------------
def _check_path_config(self, section, section_name, key, class_prop, absolute=True, desc=None):
if self.verbose > 1:
LOG.debug(_("Executing {} ...").format('post_init()'))
+ super(PpPDNSApplication, self).post_init()
+
+ if self.args.inst:
+ self.instance = self.args.inst
+ elif self.args.inst_global:
+ self.instance = 'global'
+ elif self.args.inst_local:
+ self.instance = 'local'
+ elif self.args.inst_public:
+ self.instance = 'public'
+
+ if self.args.api_port:
+ self.api_port = self.args.api_port
+
+ if self.args.timeout:
+ self.cfg.pdns_timeout = self.args.timeout
+
self.pdns = PowerDNSServer(
appname=self.appname, verbose=self.verbose, base_dir=self.base_dir,
master_server=self.api_host, port=self.api_port,
)
self.pdns.initialized = True
- self.initialized = True
-
# -------------------------------------------------------------------------
def pre_run(self):
"""
if self.verbose > 1:
LOG.debug(_("Executing {} ...").format('post_run()'))
+ if self.pdns:
+ self.pdns = None
+
# -------------------------------------------------------------------------
def get_api_server_version(self):