def apply(self, domain, post_records): """ Apply record changes to domain """ deleted_records, new_records = self.compare(domain, post_records) records = [] for r in deleted_records: record = {"name": r["name"], "type": r["type"], "changetype": "DELETE", "records": []} records.append(record) postdata_for_delete = {"rrsets": records} records = [] for r in new_records: record = { "name": r["name"], "type": r["type"], "changetype": "REPLACE", "records": [ { "content": r["content"], "disabled": r["disabled"], "name": r["name"], "ttl": r["ttl"], "type": r["type"], } ], } records.append(record) postdata_for_new = {"rrsets": records} try: headers = {} headers["X-API-Key"] = PDNS_API_KEY jdata1 = utils.fetch_json( urlparse.urljoin(PDNS_STATS_URL, "/servers/localhost/zones/%s" % domain), headers=headers, method="PATCH", data=postdata_for_delete, ) # logging.debug(jdata1) jdata2 = utils.fetch_json( urlparse.urljoin(PDNS_STATS_URL, "/servers/localhost/zones/%s" % domain), headers=headers, method="PATCH", data=postdata_for_new, ) # logging.debug(jdata2) if "error" in jdata2.keys(): logging.error("Cannot apply record changes.") logging.debug(jdata2["error"]) return {"status": "error", "msg": jdata2["error"]} else: logging.info("Record was applied successfully.") return {"status": "ok", "msg": "Record was applied successfully"} except Exception, e: logging.error("Cannot apply record changes to domain %s. DETAIL: %s" % (str(e), domain)) return {"status": "error", "msg": "There was something wrong, please contact administrator"}
def update_from_master(self, domain_name): """ Update records from Master DNS server """ domain = Domain.query.filter(Domain.name == domain_name).first() if domain: headers = {} headers['X-API-Key'] = PDNS_API_KEY try: jdata = utils.fetch_json(urlparse.urljoin( PDNS_STATS_URL, '/servers/localhost/zones/%s/axfr-retrieve' % domain), headers=headers, method='PUT') return { 'status': 'ok', 'msg': 'Update from Master successfully' } except: return { 'status': 'error', 'msg': 'There was something wrong, please contact administrator' } else: return {'status': 'error', 'msg': 'This domain doesnot exist'}
def add(self, domain_name, domain_type, domain_ns=[], domain_master_ips=[]): """ Add a domain to power dns """ headers = {} headers['X-API-Key'] = PDNS_API_KEY post_data = { "name": domain_name, "kind": domain_type, "masters": domain_master_ips, "nameservers": domain_ns } try: jdata = utils.fetch_json(urlparse.urljoin( PDNS_STATS_URL, '/servers/localhost/zones'), headers=headers, method='POST', data=post_data) if 'error' in jdata.keys(): logging.error(jdata['error']) return {'status': 'error', 'msg': jdata['error']} else: logging.info('Added domain %s successfully' % domain_name) return {'status': 'ok', 'msg': 'Added domain successfully'} except Exception, e: print traceback.format_exc() logging.error('Cannot add domain %s' % domain_name) logging.debug(str(e)) return {'status': 'error', 'msg': 'Cannot add this domain.'}
def delete(self, domain): """ Delete a record from domain """ headers = {} headers['X-API-Key'] = PDNS_API_KEY data = {"rrsets": [ { "name": self.name, "type": self.type, "changetype": "DELETE", "records": [ { "name": self.name, "type": self.type } ] } ] } try: jdata = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, '/servers/localhost/zones/%s' % domain), headers=headers, method='PATCH', data=data) logging.debug(jdata) return {'status': 'ok', 'msg': 'Record was removed successfully'} except: logging.error("Cannot remove record %s/%s/%s from domain %s" % (self.name, self.type, self.data, domain)) return {'status': 'error', 'msg': 'There was something wrong, please contact administrator'}
def get_domains(self): """ Get all domains which has in PowerDNS jdata example: [ { "id": "example.org.", "url": "/servers/localhost/zones/example.org.", "name": "example.org", "kind": "Native", "dnssec": false, "account": "", "masters": [], "serial": 2015101501, "notified_serial": 0, "last_check": 0 } ] """ headers = {} headers['X-API-Key'] = PDNS_API_KEY jdata = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, '/servers/localhost/zones'), headers=headers) return jdata
def get_record_data(self, domain): """ Query domain's DNS records via API """ headers = {} headers['X-API-Key'] = PDNS_API_KEY try: jdata = utils.fetch_json(urlparse.urljoin( PDNS_STATS_URL, API_EXTENDED_URL + '/servers/localhost/zones/%s' % domain), headers=headers) except: logging.error( "Cannot fetch domain's record data from remote powerdns api") return False if NEW_SCHEMA: rrsets = jdata['rrsets'] for rrset in rrsets: r_name = rrset['name'].rstrip('.') if PRETTY_IPV6_PTR: # only if activated if rrset['type'] == 'PTR': # only ptr if 'ip6.arpa' in r_name: # only if v6-ptr r_name = dns.reversename.to_address( dns.name.from_text(r_name)) rrset['name'] = r_name rrset['content'] = rrset['records'][0]['content'] rrset['disabled'] = rrset['records'][0]['disabled'] return {'records': rrsets} return jdata
def add(self, domain_name, domain_type, domain_ns=[], domain_master_ips=[]): """ Add a domain to power dns """ headers = {} headers['X-API-Key'] = PDNS_API_KEY post_data = { "name": domain_name, "kind": domain_type, "masters": domain_master_ips, "nameservers": domain_ns } try: jdata = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, '/servers/localhost/zones'), headers=headers, method='POST', data=post_data) if 'error' in jdata.keys(): logging.error(jdata['error']) return {'status': 'error', 'msg': jdata['error']} else: logging.info('Added domain %s successfully' % domain_name) return {'status': 'ok', 'msg': 'Added domain successfully'} except Exception, e: print traceback.format_exc() logging.error('Cannot add domain %s' % domain_name) logging.debug(str(e)) return {'status': 'error', 'msg': 'Cannot add this domain.'}
def get_record_data(self, domain): """ Query domain's DNS records via API """ headers = {} headers['X-API-Key'] = PDNS_API_KEY try: jdata = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, API_EXTENDED_URL + '/servers/localhost/zones/%s' % domain), headers=headers) except: logging.error("Cannot fetch domain's record data from remote powerdns api") return False if NEW_SCHEMA: rrsets = jdata['rrsets'] for rrset in rrsets: r_name = rrset['name'].rstrip('.') if PRETTY_IPV6_PTR: # only if activated if rrset['type'] == 'PTR': # only ptr if 'ip6.arpa' in r_name: # only if v6-ptr r_name = dns.reversename.to_address(dns.name.from_text(r_name)) rrset['name'] = r_name rrset['content'] = rrset['records'][0]['content'] rrset['disabled'] = rrset['records'][0]['disabled'] return {'records': rrsets} return jdata
def delete(self, domain): """ Delete a record from domain """ headers = {} headers['X-API-Key'] = PDNS_API_KEY data = {"rrsets": [ { "name": self.name, "type": self.type, "changetype": "DELETE", "records": [ { "name": self.name, "type": self.type } ] } ] } try: jdata = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, API_EXTENDED_URL + '/servers/localhost/zones/%s' % domain), headers=headers, method='PATCH', data=data) logging.debug(jdata) return {'status': 'ok', 'msg': 'Record was removed successfully'} except: logging.error("Cannot remove record %s/%s/%s from domain %s" % (self.name, self.type, self.data, domain)) return {'status': 'error', 'msg': 'There was something wrong, please contact administrator'}
def add(self, domain_name, domain_type, domain_ns=[], domain_master_ips=[]): """ Add a domain to power dns """ headers = {} headers["X-API-Key"] = PDNS_API_KEY post_data = {"name": domain_name, "kind": domain_type, "masters": domain_master_ips, "nameservers": domain_ns} try: jdata = utils.fetch_json( urlparse.urljoin(PDNS_STATS_URL, "/servers/localhost/zones"), headers=headers, method="POST", data=post_data, ) if "error" in jdata.keys(): logging.error(jdata["error"]) return {"status": "error", "msg": jdata["error"]} else: logging.info("Added domain %s successfully" % domain_name) return {"status": "ok", "msg": "Added domain successfully"} except Exception, e: print traceback.format_exc() logging.error("Cannot add domain %s" % domain_name) logging.debug(str(e)) return {"status": "error", "msg": "Cannot add this domain."}
def get_domain_dnssec(self, domain_name): """ Get domain DNSSEC information """ domain = Domain.query.filter(Domain.name == domain_name).first() if domain: headers = {} headers['X-API-Key'] = PDNS_API_KEY try: jdata = utils.fetch_json(urlparse.urljoin( PDNS_STATS_URL, API_EXTENDED_URL + '/servers/localhost/zones/%s/cryptokeys' % domain.name), headers=headers, method='GET') if 'error' in jdata: return { 'status': 'error', 'msg': 'DNSSEC is not enabled for this domain' } else: return {'status': 'ok', 'dnssec': jdata} except: return { 'status': 'error', 'msg': 'There was something wrong, please contact administrator' } else: return {'status': 'error', 'msg': 'This domain doesnot exist'}
def update(self): """ Fetch zones (domains) from PowerDNS and update into DB """ db_domain = Domain.query.all() list_db_domain = [d.name for d in db_domain] headers = {} headers['X-API-Key'] = PDNS_API_KEY try: jdata = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, '/servers/localhost/zones'), headers=headers) list_jdomain = [d['name'] for d in jdata] try: # domains should remove from db since it doesn't exist in powerdns anymore should_removed_db_domain = list(set(list_db_domain).difference(list_jdomain)) for d in should_removed_db_domain: # revoke permission before delete domain domain = Domain.query.filter(Domain.name==d).first() domain_user = DomainUser.query.filter(DomainUser.domain_id==domain.id) if domain_user: domain_user.delete() db.session.commit() # then remove domain Domain.query.filter(Domain.name == d).delete() db.session.commit() except: logging.error('Can not delete domain from DB') logging.debug(traceback.format_exc()) db.session.rollback() # update/add new domain for data in jdata: d = Domain.query.filter(Domain.name == data['name']).first() if d: #update exist domain d.master = str(data['masters']) d.type = data['kind'] d.serial = data['serial'] d.notified_serial = data['notified_serial'] d.last_check = data['last_check'] else: # add new domain d = Domain() d.name = data['name'] d.master = str(data['masters']) d.type = data['kind'] d.serial = data['serial'] d.notified_serial = data['notified_serial'] d.last_check = data['last_check'] db.session.add(d) try: db.session.commit() except: db.session.rollback() return {'status': 'ok', 'msg': 'Domain table has been updated successfully'} except Exception, e: logging.error('Can not update domain table.' + str(e)) return {'status': 'error', 'msg': 'Can not update domain table'}
def add(self, domain): """ Add a record to domain """ # validate record first r = self.get_record_data(domain) records = r['records'] check = filter(lambda check: check['name'] == self.name, records) if check: r = check[0] if r['type'] in ('A', 'AAAA' ,'CNAME'): return {'status': 'error', 'msg': 'Record already exists with type "A", "AAAA" or "CNAME"'} # continue if the record is ready to be added headers = {} headers['X-API-Key'] = PDNS_API_KEY if NEW_SCHEMA: data = {"rrsets": [ { "name": self.name + '.', "type": self.type, "changetype": "REPLACE", "ttl": self.ttl, "records": [ { "content": self.data, "disabled": self.status, } ] } ] } else: data = {"rrsets": [ { "name": self.name, "type": self.type, "changetype": "REPLACE", "records": [ { "content": self.data, "disabled": self.status, "name": self.name, "ttl": self.ttl, "type": self.type, "set-ptr": self.auto_ptr } ] } ] } try: jdata = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, API_EXTENDED_URL + '/servers/localhost/zones/%s' % domain), headers=headers, method='PATCH', data=data) logging.debug(jdata) return {'status': 'ok', 'msg': 'Record was added successfully'} except Exception, e: logging.error("Cannot add record %s/%s/%s to domain %s. DETAIL: %s" % (self.name, self.type, self.data, domain, str(e))) return {'status': 'error', 'msg': 'There was something wrong, please contact administrator'}
def delete(self, domain): """ Delete a record from domain """ headers = {} headers["X-API-Key"] = PDNS_API_KEY data = { "rrsets": [ { "name": self.name, "type": self.type, "changetype": "DELETE", "records": [{"name": self.name, "type": self.type}], } ] } try: jdata = utils.fetch_json( urlparse.urljoin(PDNS_STATS_URL, "/servers/localhost/zones/%s" % domain), headers=headers, method="PATCH", data=data, ) logging.debug(jdata) return {"status": "ok", "msg": "Record was removed successfully"} except: logging.error("Cannot remove record %s/%s/%s from domain %s" % (self.name, self.type, self.data, domain)) return {"status": "error", "msg": "There was something wrong, please contact administrator"}
def add(self, domain): """ Add a record to domain """ # validate record first r = self.get_record_data(domain) records = r['records'] check = filter(lambda check: check['name'] == self.name, records) if check: r = check[0] if r['type'] in ('A', 'AAAA' ,'CNAME'): return {'status': 'error', 'msg': 'Record already exists with type "A", "AAAA" or "CNAME"'} # continue if the record is ready to be added headers = {} headers['X-API-Key'] = PDNS_API_KEY if NEW_SCHEMA: data = {"rrsets": [ { "name": self.name + '.', "type": self.type, "changetype": "REPLACE", "ttl": self.ttl, "records": [ { "content": self.data, "disabled": self.status, } ] } ] } else: data = {"rrsets": [ { "name": self.name, "type": self.type, "changetype": "REPLACE", "records": [ { "content": self.data, "disabled": self.status, "name": self.name, "ttl": self.ttl, "type": self.type } ] } ] } try: jdata = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, API_EXTENDED_URL + '/servers/localhost/zones/%s' % domain), headers=headers, method='PATCH', data=data) logging.debug(jdata) return {'status': 'ok', 'msg': 'Record was added successfully'} except Exception, e: logging.error("Cannot add record %s/%s/%s to domain %s. DETAIL: %s" % (self.name, self.type, self.data, domain, str(e))) return {'status': 'error', 'msg': 'There was something wrong, please contact administrator'}
def get_record_data(self, domain): """ Query domain's DNS records via API """ headers = {} headers['X-API-Key'] = PDNS_API_KEY try: jdata = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, '/servers/localhost/zones/%s' % domain), headers=headers) except: logging.error("Cannot fetch domain's record data from remote powerdns api") return False return jdata
def get_statistic(self): """ Get server statistics """ headers = {} headers['X-API-Key'] = PDNS_API_KEY try: jdata = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, API_EXTENDED_URL + '/servers/%s/statistics' % self.server_id), headers=headers, method='GET') return jdata except: logging.error("Can not get server statistics.") logging.debug(traceback.format_exc()) return []
def get_config(self): """ Get server config """ headers = {} headers['X-API-Key'] = PDNS_API_KEY try: jdata = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, API_EXTENDED_URL + '/servers/%s/config' % self.server_id), headers=headers, method='GET') return jdata except: logging.error("Can not get server configuration.") logging.debug(traceback.format_exc()) return []
def get_statistic(self): """ Get server statistics """ headers = {} headers['X-API-Key'] = PDNS_API_KEY try: jdata = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, '/servers/%s/statistics' % self.server_id), headers=headers, method='GET') return jdata except: logging.error("Can not get server statistics.") logging.debug(traceback.format_exc()) return []
def update(self, domain, content): """ Update single record """ headers = {} headers['X-API-Key'] = PDNS_API_KEY if NEW_SCHEMA: data = {"rrsets": [ { "name": self.name + '.', "type": self.type, "ttl": self.ttl, "changetype": "REPLACE", "records": [ { "content": content, "disabled": self.status, } ] } ] } else: data = {"rrsets": [ { "name": self.name, "type": self.type, "changetype": "REPLACE", "records": [ { "content": content, "disabled": self.status, "name": self.name, "ttl": self.ttl, "type": self.type, "priority": 10 } ] } ] } try: jdata = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, API_EXTENDED_URL + '/servers/localhost/zones/%s' % domain), headers=headers, method='PATCH', data=data) logging.debug("dyndns data: " % data) return {'status': 'ok', 'msg': 'Record was updated successfully'} except Exception, e: logging.error("Cannot add record %s/%s/%s to domain %s. DETAIL: %s" % (self.name, self.type, self.data, domain, str(e))) return {'status': 'error', 'msg': 'There was something wrong, please contact administrator'}
def add(self, domain): """ Add a record to domain """ # validate record first r = self.get_record_data(domain) records = r["records"] check = filter(lambda check: check["name"] == self.name, records) if check: r = check[0] if r["type"] in ("A", "AAAA", "CNAME"): return {"status": "error", "msg": 'Record might was already exist with type "A", "AAAA", "CNAME"'} # continue if the record is ready to be added headers = {} headers["X-API-Key"] = PDNS_API_KEY data = { "rrsets": [ { "name": self.name, "type": self.type, "changetype": "REPLACE", "records": [ { "content": self.data, "disabled": self.status, "name": self.name, "ttl": self.ttl, "type": self.type, } ], } ] } try: jdata = utils.fetch_json( urlparse.urljoin(PDNS_STATS_URL, "/servers/localhost/zones/%s" % domain), headers=headers, method="PATCH", data=data, ) logging.debug(jdata) return {"status": "ok", "msg": "Record was added successfully"} except Exception, e: logging.error( "Cannot add record %s/%s/%s to domain %s. DETAIL: %s" % (self.name, self.type, self.data, domain, str(e)) ) return {"status": "error", "msg": "There was something wrong, please contact administrator"}
def update_from_master(self, domain_name): """ Update records from Master DNS server """ domain = Domain.query.filter(Domain.name == domain_name).first() if domain: headers = {} headers['X-API-Key'] = PDNS_API_KEY try: jdata = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, '/servers/localhost/zones/%s/axfr-retrieve' % domain), headers=headers, method='PUT') return {'status': 'ok', 'msg': 'Update from Master successfully'} except: return {'status': 'error', 'msg': 'There was something wrong, please contact administrator'} else: return {'status': 'error', 'msg': 'This domain doesnot exist'}
def get_record_data(self, domain): """ Query domain's DNS records via API """ headers = {} headers['X-API-Key'] = PDNS_API_KEY try: jdata = utils.fetch_json(urlparse.urljoin( PDNS_STATS_URL, '/servers/localhost/zones/%s' % domain), headers=headers) except: logging.error( "Cannot fetch domain's record data from remote powerdns api") return False return jdata
def delete(self, domain_name): """ Delete a single domain name from powerdns """ headers = {} headers['X-API-Key'] = PDNS_API_KEY try: jdata = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, API_EXTENDED_URL + '/servers/localhost/zones/%s' % domain_name), headers=headers, method='DELETE') logging.info('Delete domain %s successfully' % domain_name) return {'status': 'ok', 'msg': 'Delete domain successfully'} except Exception, e: print traceback.format_exc() logging.error('Cannot delete domain %s' % domain_name) logging.debug(str(e)) return {'status': 'error', 'msg': 'Cannot delete domain'}
def delete(self, domain_name): """ Delete a single domain name from powerdns """ headers = {} headers['X-API-Key'] = PDNS_API_KEY try: jdata = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, '/servers/localhost/zones/%s' % domain_name), headers=headers, method='DELETE') logging.info('Delete domain %s successfully' % domain_name) return {'status': 'ok', 'msg': 'Delete domain successfully'} except Exception, e: print traceback.format_exc() logging.error('Cannot delete domain %s' % domain_name) logging.debug(str(e)) return {'status': 'error', 'msg': 'Cannot delete domain'}
def get_config(self): """ Get server config """ headers = {} headers['X-API-Key'] = PDNS_API_KEY try: jdata = utils.fetch_json(urlparse.urljoin( PDNS_STATS_URL, '/servers/%s/config' % self.server_id), headers=headers, method='GET') return jdata except: logging.error("Can not get server configuration.") logging.debug(traceback.format_exc()) return []
def get_domain_dnssec(self, domain_name): """ Get domain DNSSEC information """ domain = Domain.query.filter(Domain.name == domain_name).first() if domain: headers = {} headers['X-API-Key'] = PDNS_API_KEY try: jdata = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, API_EXTENDED_URL + '/servers/localhost/zones/%s/cryptokeys' % domain.name), headers=headers, method='GET') if 'error' in jdata: return {'status': 'error', 'msg': 'DNSSEC is not enabled for this domain'} else: return {'status': 'ok', 'dnssec': jdata} except: return {'status': 'error', 'msg': 'There was something wrong, please contact administrator'} else: return {'status': 'error', 'msg': 'This domain doesnot exist'}
def delete(self, domain_name): """ Delete a single domain name from powerdns """ headers = {} headers["X-API-Key"] = PDNS_API_KEY try: jdata = utils.fetch_json( urlparse.urljoin(PDNS_STATS_URL, "/servers/localhost/zones/%s" % domain_name), headers=headers, method="DELETE", ) logging.info("Delete domain %s successfully" % domain_name) return {"status": "ok", "msg": "Delete domain successfully"} except Exception, e: print traceback.format_exc() logging.error("Cannot delete domain %s" % domain_name) logging.debug(str(e)) return {"status": "error", "msg": "Cannot delete domain"}
def update_from_master(self, domain_name): """ Update records from Master DNS server """ domain = Domain.query.filter(Domain.name == domain_name).first() if domain: headers = {} headers["X-API-Key"] = PDNS_API_KEY try: jdata = utils.fetch_json( urlparse.urljoin(PDNS_STATS_URL, "/servers/localhost/zones/%s/axfr-retrieve" % domain), headers=headers, method="PUT", ) return {"status": "ok", "msg": "Update from Master successfully"} except: return {"status": "error", "msg": "There was something wrong, please contact administrator"} else: return {"status": "error", "msg": "This domain doesnot exist"}
def get_record_data(self, domain): """ Query domain's DNS records via API """ headers = {} headers['X-API-Key'] = PDNS_API_KEY try: jdata = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, API_EXTENDED_URL + '/servers/localhost/zones/%s' % domain), headers=headers) except: logging.error("Cannot fetch domain's record data from remote powerdns api") return False if NEW_SCHEMA: rrsets = jdata['rrsets'] for rrset in rrsets: rrset['name'] = rrset['name'].rstrip('.') rrset['content'] = rrset['records'][0]['content'] rrset['disabled'] = rrset['records'][0]['disabled'] return {'records': rrsets} return jdata
def apply(self, domain, post_records): """ Apply record changes to domain """ deleted_records, new_records = self.compare(domain, post_records) records = [] for r in deleted_records: record = { "name": r['name'], "type": r['type'], "changetype": "DELETE", "records": [] } records.append(record) postdata_for_delete = {"rrsets": records} records = [] for r in new_records: record = { "name": r['name'], "type": r['type'], "changetype": "REPLACE", "records": [{ "content": r['content'], "disabled": r['disabled'], "name": r['name'], "ttl": r['ttl'], "type": r['type'], }] } records.append(record) postdata_for_new = {"rrsets": records} try: headers = {} headers['X-API-Key'] = PDNS_API_KEY jdata1 = utils.fetch_json(urlparse.urljoin( PDNS_STATS_URL, '/servers/localhost/zones/%s' % domain), headers=headers, method='PATCH', data=postdata_for_delete) #logging.debug(jdata1) jdata2 = utils.fetch_json(urlparse.urljoin( PDNS_STATS_URL, '/servers/localhost/zones/%s' % domain), headers=headers, method='PATCH', data=postdata_for_new) #logging.debug(jdata2) if 'error' in jdata2.keys(): logging.error('Cannot apply record changes.') logging.debug(jdata2['error']) return {'status': 'error', 'msg': jdata2['error']} else: logging.info('Record was applied successfully.') return { 'status': 'ok', 'msg': 'Record was applied successfully' } except Exception, e: logging.error( "Cannot apply record changes to domain %s. DETAIL: %s" % (str(e), domain)) return { 'status': 'error', 'msg': 'There was something wrong, please contact administrator' }
def update(self): """ Fetch zones (domains) from PowerDNS and update into DB """ db_domain = Domain.query.all() list_db_domain = [d.name for d in db_domain] headers = {} headers['X-API-Key'] = PDNS_API_KEY try: jdata = utils.fetch_json(urlparse.urljoin( PDNS_STATS_URL, '/servers/localhost/zones'), headers=headers) list_jdomain = [d['name'] for d in jdata] try: # domains should remove from db since it doesn't exist in powerdns anymore should_removed_db_domain = list( set(list_db_domain).difference(list_jdomain)) for d in should_removed_db_domain: # revoke permission before delete domain domain = Domain.query.filter(Domain.name == d).first() domain_user = DomainUser.query.filter( DomainUser.domain_id == domain.id) if domain_user: domain_user.delete() db.session.commit() # then remove domain Domain.query.filter(Domain.name == d).delete() db.session.commit() except: logging.error('Can not delete domain from DB') logging.debug(traceback.format_exc()) db.session.rollback() # update/add new domain for data in jdata: d = Domain.query.filter(Domain.name == data['name']).first() if d: #update exist domain d.master = str(data['masters']) d.type = data['kind'] d.serial = data['serial'] d.notified_serial = data['notified_serial'] d.last_check = data['last_check'] else: # add new domain d = Domain() d.name = data['name'] d.master = str(data['masters']) d.type = data['kind'] d.serial = data['serial'] d.notified_serial = data['notified_serial'] d.last_check = data['last_check'] db.session.add(d) try: db.session.commit() except: db.session.rollback() return { 'status': 'ok', 'msg': 'Domain table has been updated successfully' } except Exception, e: logging.error('Can not update domain table.' + str(e)) return {'status': 'error', 'msg': 'Can not update domain table'}
def apply(self, domain, post_records): """ Apply record changes to domain """ deleted_records, new_records = self.compare(domain, post_records) records = [] for r in deleted_records: record = { "name": r['name'], "type": r['type'], "changetype": "DELETE", "records": [ ] } records.append(record) postdata_for_delete = {"rrsets": records} records = [] for r in new_records: record = { "name": r['name'], "type": r['type'], "changetype": "REPLACE", "records": [ { "content": r['content'], "disabled": r['disabled'], "name": r['name'], "ttl": r['ttl'], "type": r['type'], "priority": 10, # priority field for pdns 3.4.1. https://doc.powerdns.com/md/authoritative/upgrading/ } ] } records.append(record) # Adjustment to add multiple records which described in https://github.com/ngoduykhanh/PowerDNS-Admin/issues/5#issuecomment-181637576 final_records = [] records = sorted(records, key = lambda item: (item["name"], item["type"])) for key, group in itertools.groupby(records, lambda item: (item["name"], item["type"])): final_records.append({ "name": key[0], "type": key[1], "changetype": "REPLACE", "records": [ { "content": item['records'][0]['content'], "disabled": item['records'][0]['disabled'], "name": key[0], "ttl": item['records'][0]['ttl'], "type": key[1], "priority": 10, } for item in group ] }) postdata_for_new = {"rrsets": final_records} try: headers = {} headers['X-API-Key'] = PDNS_API_KEY jdata1 = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, '/servers/localhost/zones/%s' % domain), headers=headers, method='PATCH', data=postdata_for_delete) #logging.debug(jdata1) jdata2 = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, '/servers/localhost/zones/%s' % domain), headers=headers, method='PATCH', data=postdata_for_new) #logging.debug(jdata2) if 'error' in jdata2.keys(): logging.error('Cannot apply record changes.') logging.debug(jdata2['error']) return {'status': 'error', 'msg': jdata2['error']} else: logging.info('Record was applied successfully.') return {'status': 'ok', 'msg': 'Record was applied successfully'} except Exception, e: logging.error("Cannot apply record changes to domain %s. DETAIL: %s" % (str(e), domain)) return {'status': 'error', 'msg': 'There was something wrong, please contact administrator'}
def update(self): """ Fetch zones (domains) from PowerDNS and update into DB """ db_domain = Domain.query.all() list_db_domain = [d.name for d in db_domain] dict_db_domain = dict((x.name,x) for x in db_domain) headers = {} headers['X-API-Key'] = PDNS_API_KEY try: jdata = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, API_EXTENDED_URL + '/servers/localhost/zones'), headers=headers) list_jdomain = [d['name'].rstrip('.') for d in jdata] try: # domains should remove from db since it doesn't exist in powerdns anymore should_removed_db_domain = list(set(list_db_domain).difference(list_jdomain)) for d in should_removed_db_domain: # revoke permission before delete domain domain = Domain.query.filter(Domain.name==d).first() domain_user = DomainUser.query.filter(DomainUser.domain_id==domain.id) if domain_user: domain_user.delete() db.session.commit() # then remove domain Domain.query.filter(Domain.name == d).delete() db.session.commit() except: logging.error('Can not delete domain from DB') logging.debug(traceback.format_exc()) db.session.rollback() # update/add new domain for data in jdata: d = dict_db_domain.get(data['name'].rstrip('.'), None) changed = False if d: # existing domain, only update if something actually has changed if ( d.master != str(data['masters']) or d.type != data['kind'] or d.serial != data['serial'] or d.notified_serial != data['notified_serial'] or d.last_check != ( 1 if data['last_check'] else 0 ) or d.dnssec != data['dnssec'] ): d.master = str(data['masters']) d.type = data['kind'] d.serial = data['serial'] d.notified_serial = data['notified_serial'] d.last_check = 1 if data['last_check'] else 0 d.dnssec = 1 if data['dnssec'] else 0 changed = True else: # add new domain d = Domain() d.name = data['name'].rstrip('.') d.master = str(data['masters']) d.type = data['kind'] d.serial = data['serial'] d.notified_serial = data['notified_serial'] d.last_check = data['last_check'] d.dnssec = 1 if data['dnssec'] else 0 db.session.add(d) changed = True if changed: try: db.session.commit() except: db.session.rollback() return {'status': 'ok', 'msg': 'Domain table has been updated successfully'} except Exception, e: logging.error('Can not update domain table.' + str(e)) return {'status': 'error', 'msg': 'Can not update domain table'}
def apply(self, domain, post_records): """ Apply record changes to domain """ deleted_records, new_records = self.compare(domain, post_records) records = [] for r in deleted_records: record = { "name": r['name'] + '.' if NEW_SCHEMA else r['name'], "type": r['type'], "changetype": "DELETE", "records": [ ] } records.append(record) postdata_for_delete = {"rrsets": records} records = [] for r in new_records: if NEW_SCHEMA: record = { "name": r['name'] + '.', "type": r['type'], "changetype": "REPLACE", "ttl": r['ttl'], "records": [ { "content": r['content'], "disabled": r['disabled'], } ] } else: record = { "name": r['name'], "type": r['type'], "changetype": "REPLACE", "records": [ { "content": r['content'], "disabled": r['disabled'], "name": r['name'], "ttl": r['ttl'], "type": r['type'], "priority": 10, # priority field for pdns 3.4.1. https://doc.powerdns.com/md/authoritative/upgrading/ } ] } records.append(record) # Adjustment to add multiple records which described in https://github.com/ngoduykhanh/PowerDNS-Admin/issues/5#issuecomment-181637576 final_records = [] records = sorted(records, key = lambda item: (item["name"], item["type"], item["changetype"])) for key, group in itertools.groupby(records, lambda item: (item["name"], item["type"], item["changetype"])): if NEW_SCHEMA: new_record = { "name": key[0], "type": key[1], "changetype": key[2], "ttl": None, "records": [] } for item in group: temp_content = item['records'][0]['content'] temp_disabled = item['records'][0]['disabled'] if key[1] in ['MX', 'CNAME', 'SRV', 'NS']: if temp_content.strip()[-1:] != '.': temp_content += '.' if new_record['ttl'] is None: new_record['ttl'] = item['ttl'] new_record['records'].append({ "content": temp_content, "disabled": temp_disabled }) final_records.append(new_record) else: final_records.append({ "name": key[0], "type": key[1], "changetype": key[2], "records": [ { "content": item['records'][0]['content'], "disabled": item['records'][0]['disabled'], "name": key[0], "ttl": item['records'][0]['ttl'], "type": key[1], "priority": 10, } for item in group ] }) postdata_for_new = {"rrsets": final_records} try: headers = {} headers['X-API-Key'] = PDNS_API_KEY jdata1 = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, API_EXTENDED_URL + '/servers/localhost/zones/%s' % domain), headers=headers, method='PATCH', data=postdata_for_delete) jdata2 = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, API_EXTENDED_URL + '/servers/localhost/zones/%s' % domain), headers=headers, method='PATCH', data=postdata_for_new) if 'error' in jdata2.keys(): logging.error('Cannot apply record changes.') logging.debug(jdata2['error']) return {'status': 'error', 'msg': jdata2['error']} else: logging.info('Record was applied successfully.') return {'status': 'ok', 'msg': 'Record was applied successfully'} except Exception, e: logging.error("Cannot apply record changes to domain %s. DETAIL: %s" % (str(e), domain)) return {'status': 'error', 'msg': 'There was something wrong, please contact administrator'}
def apply(self, domain, post_records): """ Apply record changes to domain """ records = [] for r in post_records: r_name = domain if r['record_name'] in ['@', ''] else r['record_name'] + '.' + domain r_type = r['record_type'] if PRETTY_IPV6_PTR: # only if activated if NEW_SCHEMA: # only if new schema if r_type == 'PTR': # only ptr if ':' in r['record_name']: # dirty ipv6 check r_name = r['record_name'] record = { "name": r_name, "type": r_type, "content": r['record_data'], "disabled": True if r['record_status'] == 'Disabled' else False, "ttl": int(r['record_ttl']) if r['record_ttl'] else 3600, } records.append(record) deleted_records, new_records = self.compare(domain, records) records = [] for r in deleted_records: r_name = r['name'] + '.' if NEW_SCHEMA else r['name'] r_type = r['type'] if PRETTY_IPV6_PTR: # only if activated if NEW_SCHEMA: # only if new schema if r_type == 'PTR': # only ptr if ':' in r['name']: # dirty ipv6 check r_name = dns.reversename.from_address(r['name']).to_text() record = { "name": r_name, "type": r_type, "changetype": "DELETE", "records": [ ] } records.append(record) postdata_for_delete = {"rrsets": records} records = [] for r in new_records: if NEW_SCHEMA: r_name = r['name'] + '.' r_type = r['type'] if PRETTY_IPV6_PTR: # only if activated if r_type == 'PTR': # only ptr if ':' in r['name']: # dirty ipv6 check r_name = r['name'] record = { "name": r_name, "type": r_type, "changetype": "REPLACE", "ttl": r['ttl'], "records": [ { "content": r['content'], "disabled": r['disabled'], } ] } else: record = { "name": r['name'], "type": r['type'], "changetype": "REPLACE", "records": [ { "content": r['content'], "disabled": r['disabled'], "name": r['name'], "ttl": r['ttl'], "type": r['type'], "priority": 10, # priority field for pdns 3.4.1. https://doc.powerdns.com/md/authoritative/upgrading/ } ] } records.append(record) # Adjustment to add multiple records which described in https://github.com/ngoduykhanh/PowerDNS-Admin/issues/5#issuecomment-181637576 final_records = [] records = sorted(records, key = lambda item: (item["name"], item["type"], item["changetype"])) for key, group in itertools.groupby(records, lambda item: (item["name"], item["type"], item["changetype"])): if NEW_SCHEMA: r_name = key[0] r_type = key[1] r_changetype = key[2] if PRETTY_IPV6_PTR: # only if activated if r_type == 'PTR': # only ptr if ':' in r_name: # dirty ipv6 check r_name = dns.reversename.from_address(r_name).to_text() new_record = { "name": r_name, "type": r_type, "changetype": r_changetype, "ttl": None, "records": [] } for item in group: temp_content = item['records'][0]['content'] temp_disabled = item['records'][0]['disabled'] if key[1] in ['MX', 'CNAME', 'SRV', 'NS']: if temp_content.strip()[-1:] != '.': temp_content += '.' if new_record['ttl'] is None: new_record['ttl'] = item['ttl'] new_record['records'].append({ "content": temp_content, "disabled": temp_disabled }) final_records.append(new_record) else: final_records.append({ "name": key[0], "type": key[1], "changetype": key[2], "records": [ { "content": item['records'][0]['content'], "disabled": item['records'][0]['disabled'], "name": key[0], "ttl": item['records'][0]['ttl'], "type": key[1], "priority": 10, } for item in group ] }) postdata_for_new = {"rrsets": final_records} try: headers = {} headers['X-API-Key'] = PDNS_API_KEY jdata1 = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, API_EXTENDED_URL + '/servers/localhost/zones/%s' % domain), headers=headers, method='PATCH', data=postdata_for_delete) jdata2 = utils.fetch_json(urlparse.urljoin(PDNS_STATS_URL, API_EXTENDED_URL + '/servers/localhost/zones/%s' % domain), headers=headers, method='PATCH', data=postdata_for_new) if 'error' in jdata2.keys(): logging.error('Cannot apply record changes.') logging.debug(jdata2['error']) return {'status': 'error', 'msg': jdata2['error']} else: logging.info('Record was applied successfully.') return {'status': 'ok', 'msg': 'Record was applied successfully'} except Exception, e: logging.error("Cannot apply record changes to domain %s. DETAIL: %s" % (str(e), domain)) return {'status': 'error', 'msg': 'There was something wrong, please contact administrator'}