Browse Source

Config for dns sync script

Sebastian Lohff 4 years ago
parent
commit
e35f89bc57
1 changed files with 55 additions and 20 deletions
  1. 55
    20
      bin/dns-sync

+ 55
- 20
bin/dns-sync View File

@@ -1,6 +1,7 @@
1 1
 #!/usr/bin/env python3
2 2
 # -*- coding: utf-8 -*-
3 3
 import argparse
4
+import configparser
4 5
 import os
5 6
 import sys
6 7
 import json
@@ -26,9 +27,10 @@ def _parser():
26 27
 	             #description='do some awesome foo',
27 28
 	)
28 29
 
29
-	#parser.add_argument("-p", "--port", default=2323, type=int, help="Your port")
30
-	#parser.add_argument("-v", "--verbose", default=False, action="store_true", help="Be more verbose")
31
-
30
+	parser.add_argument("--pdns-host", default="127.0.0.1", help="PDNS host")
31
+	parser.add_argument("--pdns-port", default=8081, help="PDNS port")
32
+	parser.add_argument("-c", "--config", default=None, type=argparse.FileType("r"), help="Path to config file (default path: ./dns-sync.conf, /etc/dns-sync.conf)")
33
+	parser.add_argument("--api-key", default=None, help="PDNS API key")
32 34
 	parser.add_argument("--version", action="version", version="%(prog)s " + __VERSION__)
33 35
 
34 36
 	return parser
@@ -61,6 +63,8 @@ def mergeDomains(zoneData, pdnsData):
61 63
 def removeOldDomains(zoneData, pdnsData):
62 64
 	rrDel = []
63 65
 
66
+	#print("zone data", zoneData)
67
+	#print("pdnsData", pdnsData)
64 68
 	for entry in pdnsData['rrsets']:
65 69
 		# search for name/type in domain dict. if non-existtant mark for deletion
66 70
 		# this could be much more efficient with a dict! name: [rrset...]
@@ -84,7 +88,7 @@ def handleNameserver(ns, servers, usedNameservers, domains):
84 88
 			domains.append((ns.name, "AAAA", [ns.glueIPv6]))
85 89
 
86 90
 
87
-def getDomainsFromQueryset(qs, zone, glueRecords, usedNameservers):
91
+def getDomainsFromQueryset(qs, zone, glueRecords, usedNameservers, v4reverse=False):
88 92
 	for domain in qs:
89 93
 		servers = []
90 94
 		for ns in domain.nameservers.all():
@@ -99,10 +103,30 @@ def getDomainsFromQueryset(qs, zone, glueRecords, usedNameservers):
99 103
 
100 104
 		zone.append((domain.getZone(), "NS", servers))
101 105
 
106
+		if v4reverse:
107
+			# for ipv4 reverse we have to do some extra work in case of classless delegations
108
+			# see RFC2317
109
+			net = domain.parentNet.getNetwork()
110
+			if net.prefixlen % 8 != 0:
111
+				revZone = domain.getZone()
112
+				parts = str(net.network_address).split(".")
113
+				baseZone = ".".join(reversed(parts[:net.prefixlen // 8])) + ".in-addr.arpa."
114
+				startNo = int(parts[net.prefixlen // 8])
115
+				lenExp = 8 - (net.prefixlen % 8)
116
+
117
+				for i in range(2 ** lenExp):
118
+					no = startNo + i
119
+					zone.append(("%d.%s" % (no, baseZone), "CNAME", ["%d.%s" % (no, revZone)]))
120
+
102 121
 def mergeDomainsWithPdns(s, args, zone, zoneData, protectedRecords=[]):
103
-	url = "http://potatos.portal.dn:8081/api/v1/servers/localhost/zones/%s" % (zone,)
122
+	url = "http://%s:%s/api/v1/servers/localhost/zones/%s" % (args.pdns_host, args.pdns_port, zone,)
104 123
 	pdnsData = s.get(url).json()
105 124
 
125
+	baseProtectedRecords = [
126
+		(zone, "NS", []),
127
+		(zone, "SOA", []),
128
+	]
129
+
106 130
 	# add dn. (NS + glue Nameservers)
107 131
 	newDomains = mergeDomains(zoneData, pdnsData)
108 132
 	print("Add/replace", newDomains)
@@ -110,22 +134,38 @@ def mergeDomainsWithPdns(s, args, zone, zoneData, protectedRecords=[]):
110 134
 	if len(newDomains) > 0:
111 135
 		r = s.patch(url, data=json.dumps({'rrsets': newDomains}))
112 136
 		if r.status_code != 204:
113
-			raise RuntimeError("Could not update records in powerdns")
137
+			raise RuntimeError("Could not update records in powerdns, API returned %d" % r.status_code)
114 138
 
115
-	delDomains = removeOldDomains(zoneData, zoneData + protectedRecords)
139
+	delDomains = removeOldDomains(zoneData + protectedRecords + baseProtectedRecords, pdnsData)
116 140
 	print("Del", delDomains)
117 141
 	r = s.patch(url, data=json.dumps({'rrsets': delDomains}))
118 142
 	if r.status_code != 204:
119
-		raise RuntimeError("Could not update records in powerdns")
143
+		raise RuntimeError("Could not update records in powerdns, API returned %d" % r.status_code)
120 144
 
121 145
 
122 146
 def main():
123 147
 	parser = _parser()
124 148
 	args = parser.parse_args()
125 149
 
150
+	config = configparser.ConfigParser()
151
+	if args.config:
152
+		config.read_file(args.config)
153
+	else:
154
+		config.read([os.path.join(os.path.abspath(__file__), "dns-sync.conf"), "/etc/dns-sync.conf"])
155
+		#print(config)
156
+		#print(config.get("DEFAULT", "api-key"))
157
+		#print(config.has_section("DEFAULT"), config.has_option("DEFAULT", "api-key"))
158
+
159
+	if args.api_key:
160
+		config["DEFAULT"]["api-key"] = args.api_key
161
+
162
+	if not config.has_option("DEFAULT", "api-key"):
163
+		print("Error: Could not find api-key (not present in config under [DEFAULT]; not given via command line)", file=sys.stderr)
164
+		sys.exit(2)
165
+
126 166
 	s = requests.Session()
127 167
 	s.headers = {
128
-		'X-API-Key': 'bei2aequ2OBi',
168
+		'X-API-Key': config.get("DEFAULT", "api-key"),
129 169
 		'Accept': 'application/json'
130 170
 	}
131 171
 
@@ -143,21 +183,16 @@ def main():
143 183
 	qs = ReverseZone.objects.annotate(nsCount=Count('nameservers')).filter(nsCount__gt=0).order_by("parentNet__address")
144 184
 	qs4 = filter(lambda _revz: _revz.getNetwork().version == 4, qs)
145 185
 	qs6 = filter(lambda _revz: _revz.getNetwork().version == 6, qs)
146
-	getDomainsFromQueryset(qs4, rzone4, domains, usedNameservers)
186
+	getDomainsFromQueryset(qs4, rzone4, domains, usedNameservers, v4reverse=True)
147 187
 	getDomainsFromQueryset(qs6, rzone6, domains, usedNameservers)
148 188
 
149
-	print("dn.", domains)
150
-	print("v4", rzone4)
151
-	print("v6", rzone6)
152
-
153
-	protectedRecords = [
154
-		("dn.", "NS", []),
155
-		("dn.", "SOA", []),
156
-	]
189
+	#print("dn.", domains)
190
+	#print("v4", rzone4)
191
+	#print("v6", rzone6)
157 192
 
158
-	mergeDomainsWithPdns(s, args, "dn.", domains, protectedRecords)
193
+	mergeDomainsWithPdns(s, args, "dn.", domains)
159 194
 	mergeDomainsWithPdns(s, args, "10.in-addr.arpa.", rzone4)
160
-	mergeDomainsWithPdns(s, args, "3.2.7.c.3.a.d.f.ip6.arpa.")
195
+	mergeDomainsWithPdns(s, args, "3.2.7.c.3.a.d.f.ip6.arpa.", rzone6)
161 196
 
162 197
 
163 198
 

Loading…
Cancel
Save