From 03a98b512eb8961522a7c79a72776b896b8cfc46 Mon Sep 17 00:00:00 2001 From: Frank Brehm Date: Tue, 7 Nov 2017 19:27:24 +0100 Subject: [PATCH] Adding pp_lib/pdns_zone.py --- pp_lib/pdns_zone.py | 292 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 292 insertions(+) create mode 100644 pp_lib/pdns_zone.py diff --git a/pp_lib/pdns_zone.py b/pp_lib/pdns_zone.py new file mode 100644 index 0000000..4a83d4a --- /dev/null +++ b/pp_lib/pdns_zone.py @@ -0,0 +1,292 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +@author: Frank Brehm +@contact: frank.brehm@pixelpark.com +@copyright: © 2010 - 2017 by Frank Brehm, Publicies Pixelpark GmbH, Berlin +@summary: An encapsulation class for zone objects by PowerDNS API +""" +from __future__ import absolute_import + +# Standard modules +import sys +import os +import logging +import copy + +# Third party modules + +# Own modules +from .common import pp, to_bytes + +from .errors import PpError +from .obj import PpBaseObjectError, PpBaseObject + +__version__ = '0.1.2' + +LOG = logging.getLogger(__name__) + +# ============================================================================= +class PdnsApiZoneError(PpBaseObjectError): + pass + + +# ============================================================================= +class PdnsApiZone(PpBaseObject): + + # ------------------------------------------------------------------------- + def __init__( + self, appname=None, verbose=0, version=__version__, base_dir=None, initialized=None, + account=None, dnssec=False, id=None, kind=None, last_check=None, + masters=None, name=None, notified_serial=None, serial=None, url=None): + +# { 'account': 'local', +# 'dnssec': False, +# 'id': 'bla.ai.', +# 'kind': 'Master', +# 'last_check': 0, +# 'masters': [], +# 'name': 'bla.ai.', +# 'notified_serial': 2017080404, +# 'serial': 2017080404, +# 'url': 'api/v1/servers/localhost/zones/bla.ai.'}, + self._account = account + self._dnssec = dnssec + self._id = id + self._kind = kind + self._last_check = last_check + self.masters = [] + if masters: + self.masters = copy.copy(masters) + self._name = name + self._notified_serial = notified_serial + self._serial = serial + self._url = url + + self.records = [] + + super(PdnsApiZone, self).__init__( + appname=appname, verbose=verbose, version=version, base_dir=base_dir) + + if initialized is not None: + self.initialized = initialized + + # ----------------------------------------------------------- + @classmethod + def init_from_dict( + cls, data, appname=None, verbose=0, version=__version__, base_dir=None, initialized=None): + + if not isinstance(data, dict): + raise PdnsApiZoneError("Given data {!r} is not a dict object.".format(data)) + + params = { + 'appname': appname, + 'verbose': verbose, + 'version': version, + 'base_dir': base_dir + } + if initialized is not None: + params['initialized'] = initialized + + params.update(data) + zone = cls(**params) + zone.initialized = True + + return zone + + # ----------------------------------------------------------- + @property + def account(self): + """The name of the owning account of the zone, internal used + to differ local visible zones from all other zones.""" + return getattr(self, '_account', None) + + @account.setter + def account(self, value): + if value: + v = str(value).strip() + if v: + self._account = v + else: + self._account = None + else: + self._account = None + + # ----------------------------------------------------------- + @property + def dnssec(self): + """Is the zone under control of DNSSEC.""" + return getattr(self, '_dnssec', False) + + @dnssec.setter + def dnssec(self, value): + self._dnssec = bool(value) + + # ----------------------------------------------------------- + @property + def id(self): + """The unique idendity of the zone.""" + return getattr(self, '_id', None) + + @id.setter + def id(self, value): + if value: + v = str(value).strip() + if v: + self._id = v + else: + self._id = None + else: + self._id = None + + # ----------------------------------------------------------- + @property + def kind(self): + """The kind or type of the zone.""" + return getattr(self, '_kind', None) + + @kind.setter + def kind(self, value): + if value: + v = str(value).strip() + if v: + self._kind = v + else: + self._kind = None + else: + self._kind = None + + # ----------------------------------------------------------- + @property + def last_check(self): + """The timestamp of the last check of the zone""" + return getattr(self, '_last_check', None) + + # ----------------------------------------------------------- + @property + def name(self): + """The kname of the zone.""" + return getattr(self, '_name', None) + + @name.setter + def name(self, value): + if value: + v = str(value).strip() + if v: + self._name = v + else: + self._name = None + else: + self._name = None + + # ----------------------------------------------------------- + @property + def notified_serial(self): + """The notified serial number of the zone""" + return getattr(self, '_notified_serial', None) + + # ----------------------------------------------------------- + @property + def serial(self): + """The serial number of the zone""" + return getattr(self, '_serial', None) + + # ----------------------------------------------------------- + @property + def url(self): + """The URL in the API to get the zone object.""" + return getattr(self, '_url', None) + + # ------------------------------------------------------------------------- + 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(PdnsApiZone, self).as_dict(short=short) + res['account'] = self.account + res['dnssec'] = copy.copy(self.dnssec) + res['id'] = self.id + res['kind'] = self.kind + res['last_check'] = self.last_check + res['masters'] = copy.copy(self.masters) + res['name'] = self.name + res['notified_serial'] = self.notified_serial + res['serial'] = self.serial + res['url'] = self.url + res['records'] = copy.copy(self.records) + + return res + + # ------------------------------------------------------------------------- + def __str__(self): + """ + Typecasting function for translating object structure + into a string + + @return: structure as string + @rtype: str + """ + + return pp(self.as_dict(short=True)) + + # ------------------------------------------------------------------------- + def __repr__(self): + """Typecasting into a string for reproduction.""" + + out = "<%s(" % (self.__class__.__name__) + + fields = [] + fields.append("name={!r}".format(self.name)) + fields.append("kind={!r}".format(self.kind)) + fields.append("serial={!r}".format(self.serial)) + fields.append("dnssec={!r}".format(self.dnssec)) + fields.append("account={!r}".format(self.account)) + fields.append("appname={!r}".format(self.appname)) + fields.append("verbose={!r}".format(self.verbose)) + fields.append("version={!r}".format(self.version)) + + out += ", ".join(fields) + ")>" + return out + + # ------------------------------------------------------------------------- + @classmethod + def get_list_template(cls): + + return "{name:<{len_zone}} {kind:<8} {serial:>10} {dnssec:<6} {account}" + + # ------------------------------------------------------------------------- + def get_line(self, len_zone=20): + + tpl = self.get_list_template() + + params = { + 'name': self.name, + 'len_zone': len_zone, + 'kind': self.kind, + 'serial': self.serial, + 'dnssec': 'no', + 'account': '', + } + if self.dnssec: + params['dnssec'] = 'yes' + if self.account: + params['account'] = self.account + + return tpl.format(**params) + +# ============================================================================= + +if __name__ == "__main__": + + pass + +# ============================================================================= + +# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 -- 2.39.5