from .pdns_zone import PdnsApiZone
from .pdns_record import PdnsApiRecord, PdnsSoaData, PdnsApiRrset
-__version__ = '0.6.1'
+__version__ = '0.6.2'
LOG = logging.getLogger(__name__)
_LIBRARY_NAME = "pp-pdns-api-client"
'ttl': ttl,
'changetype': 'REPLACE',
'records': [],
+ 'comments': [],
}
- if comment:
- comment_rec = {
- 'content': comment,
- 'account': getpass.getuser(),
- 'modified_at': time.time(),
- }
- rrset['comments'] = [comment_rec]
+# if comment:
+# comment_rec = {
+# 'content': comment,
+# 'account': getpass.getuser(),
+# 'modified_at': int(time.time() + 0.5),
+# }
+# rrset['comments'] = [comment_rec]
record = {
'content': new_soa.data,
self.patch_zone(zone, payload)
+ # -------------------------------------------------------------------------
+ def increase_serial(self, zone_name, comment=None):
+
+ zone = self.get_api_zone(zone_name)
+ if not zone:
+ raise PpPDNSAppError("Did not found zone for {!r}.".format(zone_name))
+
+ LOG.info("Increasing serial in SOA of zone {!r} ....".format(zone_name))
+
+ api_host_address = None
+ for addr_info in socket.getaddrinfo(self.api_host, 53, family=socket.AF_INET):
+ api_host_address = addr_info[4][0]
+ break
+
+ api_soa = zone.get_soa()
+ if not api_soa:
+ raise PpPDNSAppError("Could not find SOA for zone {!r}.".format(zone_name))
+ if self.verbose > 2:
+ LOG.debug("Got SOA for zone {z!r} by API:\n{s}".format(
+ z=zone_name, s=api_soa))
+
+ dns_soa = zone.get_soa_by_dns(api_host_address)
+ if self.verbose > 2:
+ LOG.debug("Got SOA for zone {z!r} from DNS by {h!r}:\n{s}".format(
+ h=self.api_host, z=zone_name, s=dns_soa))
+
+ new_serial = zone.get_new_serial(dns_soa.serial)
+ LOG.debug("Got new serial number for zone {z!r}: {s}.".format(
+ z=zone_name, s=new_serial))
+
+ api_soa.serial = new_serial
+ return self.update_soa(zone, api_soa, comment)
+
+ # -------------------------------------------------------------------------
+ def set_nameservers(
+ self, zone, new_nameservers, for_zone=None, comment=None, new_ttl=None,
+ do_serial=True, do_notify=True):
+
+ current_nameservers = zone.get_zone_nameservers(for_zone=for_zone)
+ if for_zone:
+ LOG.debug("Current nameservers of {f!r} in zone {z!r}:\n{ns}".format(
+ f=for_zone, z=zone.name, ns=pp(current_nameservers)))
+ else:
+ LOG.debug("Current nameservers of zone {z!r}:\n{ns}".format(
+ z=zone.name, ns=pp(current_nameservers)))
+
+ ns2remove = []
+ ns2add = []
+
+ for ns in current_nameservers:
+ if ns not in new_nameservers:
+ ns2remove.append(ns)
+ for ns in new_nameservers:
+ if ns not in current_nameservers:
+ ns2add.append(ns)
+
+ if not ns2remove and not ns2add:
+ if for_zone:
+ msg = "Subzone {f!r} has already the expected nameservers in zone {z!r}."
+ else:
+ msg = "Zone {z!r} has already the expected nameservers."
+ LOG.info(msg.format(f=for_zone, z=zone.name))
+ return False
+
+ LOG.debug("Nameservers to remove from zone {z!r}:\n{ns}".format(
+ z=zone.name, ns=pp(ns2remove)))
+ LOG.debug("Nameservers to add to zone {z!r}:\n{ns}".format(
+ z=zone.name, ns=pp(ns2add)))
+
+ ns_ttl = None
+ if not new_ttl:
+ cur_rrset = zone.get_ns_rrset(for_zone=for_zone)
+ ns_ttl = cur_rrset.ttl
+ else:
+ ns_ttl = int(new_ttl)
+ LOG.debug("TTL for NS records: {}.".format(ns_ttl))
+
+ rrset_name = zone.name.lower()
+ if for_zone:
+ rrset_name = for_zone.lower()
+
+ records = []
+ for ns in new_nameservers:
+ record = {
+ "name": rrset_name,
+ "type": "NS",
+ "content": ns,
+ "disabled": False,
+ "set-ptr": False,
+ }
+ records.append(record)
+ rrset = {
+ "name": rrset_name,
+ "type": "NS",
+ "ttl": ns_ttl,
+ "changetype": "REPLACE",
+ "records": records,
+ }
+
+ if comment:
+ comment_rec = {
+ 'content': comment,
+ 'account': getpass.getuser(),
+ 'modified_at': int(time.time() + 0.5),
+ }
+ rrset['comments'] = [comment_rec]
+
+ payload = {"rrsets": [rrset]}
+
+ self.patch_zone(zone, payload)
+
+ if do_serial:
+ self.increase_serial(zone.name)
+
+ if do_notify:
+ self.notify_zone(zone)
+
+ return True
+
+ # -------------------------------------------------------------------------
+ def notify_zone(self, zone):
+
+ LOG.info("Notifying slaves of zone {!r} ...".format(zone.name))
+
+ path = "/servers/{}/zones/{}/notify".format(self.api_servername, zone.name)
+ return self.perform_request(path, 'PUT', '', may_simulate=True)
# =============================================================================