Skip to content

Instantly share code, notes, and snippets.

@falz
Last active July 31, 2025 18:17
Show Gist options
  • Save falz/b0f07945b5196a585d0fb1462467a8ea to your computer and use it in GitHub Desktop.
Save falz/b0f07945b5196a585d0fb1462467a8ea to your computer and use it in GitHub Desktop.
Example script to create Knot DNS config file for Secondaries (slaves) from PowerDNS
#! /usr/bin/env python3
#
#
# description:
# An attempt to build a knot style zone file for secondary servers to overcome
# DNS Catalog Zone restrictions with secondaries
#
import powerdns # https://github.com/outini/python-powerdns
import sys
import datetime
##############################
# config
config = {}
# (ns0-test)
config['powerdns_api_url'] = "http://ns0-test.mydomain.net:8081/api/v1"
config['powerdns_api_token'] = "<redacted>"
config['sep'] = "####################################"
##############################
## functions
def pdns_connect(config):
api_client = powerdns.PDNSApiClient(api_endpoint=config['powerdns_api_url'], api_key=config['powerdns_api_token'])
api = powerdns.PDNSEndpoint(api_client)
return(api)
def get_pdns_zones(config, pdns_api):
#print("Connecting to PowerDNS PowerDNS updates..")
# get list of all zones
pdns_zones = pdns_api.servers[0].zones
return(pdns_zones)
def print_knot_config(config, zones, pdns_api):
timestamp = datetime.datetime.now()
print("# File created on: " + str(timestamp))
print("")
for zone in zones:
myzone = ""
myzone_primaries = []
if zone._api_data['kind'] == "Slave":
myzone = zone.name.rstrip(".")
myzone_account = zone._api_data['account']
myzone_dnssec = zone._api_data['dnssec']
myzone_primaries = zone._api_data['masters']
myzone_primaries_str = ', '.join(myzone_primaries)
myzone_primary_name = myzone + "_primary"
print(config['sep'])
print("# zone:", myzone)
print("# account:", myzone_account)
print("# dnssec:", myzone_dnssec)
print("remote:")
print(" - id: " + myzone_primary_name)
print(" address: [" + myzone_primaries_str + "]")
print("zone:")
print(" - domain: " + myzone)
print(" master: " + myzone_primary_name)
print("")
print("")
##############################
## main
if __name__ == "__main__":
try:
pdns_api = pdns_connect(config)
except:
print("Cannot connect to PowerDNS API")
sys.exit(1)
try:
zones = get_pdns_zones(config, pdns_api)
except:
print("Cannot get list of zones from PowerDNS")
sys.exit(1)
print_knot_config(config, zones, pdns_api)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment