Skip to content

Commit a56b5b8

Browse files
authored
Merge pull request #21 from MoralCode/exportZonefile
Export zonefile
2 parents 17880a5 + 64ce36f commit a56b5b8

1 file changed

Lines changed: 55 additions & 3 deletions

File tree

nfsn-ddns.py

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from ipaddress import IPv4Address, IPv6Address, ip_address
88
from typing import Union, NewType, Dict
99
from urllib.parse import urlencode
10+
from pathlib import Path
1011

1112
import requests
1213
from dotenv import load_dotenv
@@ -146,6 +147,46 @@ def createNFSNAuthHeader(nfsn_username, nfsn_apikey, url_path, body) -> Dict[str
146147
return {"X-NFSN-Authentication": f"{uts};{full_hash}"}
147148

148149

150+
def getAllDNSRecords(domain, nfsn_username, nfsn_apikey):
151+
action = "listRRs"
152+
153+
path = f"/dns/{domain}/{action}"
154+
155+
response_data = makeNFSNHTTPRequest(path, None, nfsn_username, nfsn_apikey)
156+
157+
return response_data
158+
159+
def NFSNDnsToZoneFile(dnsRecords):
160+
161+
def sortKey(record):
162+
host = record.get("name")
163+
return ("@" if host == "" else host) \
164+
+ record.get("data")
165+
166+
167+
dnsRecords = sorted(dnsRecords, key=sortKey )
168+
169+
outputList = []
170+
for record in dnsRecords:
171+
host = record.get("name")
172+
host = "@" if host == "" else host
173+
record_type = record.get("type")
174+
data = record.get("data")
175+
if record_type == "TXT":
176+
data = f'"{data}"'
177+
elif record_type == "MX":
178+
data = f'{record.get("aux")} {data}'
179+
outputList.append(
180+
'\t'.join([
181+
host,
182+
str(record.get("ttl")),
183+
"IN",
184+
record_type,
185+
data
186+
])
187+
)
188+
outputList.append("")
189+
return outputList
149190

150191
def updateIPs(domain, subdomain, domain_ip, current_ip, nfsn_username, nfsn_apikey, v6=False, create_if_not_exists=False):
151192
# When there's no existing record for a domain name, the
@@ -190,6 +231,7 @@ def check_ips(nfsn_domain, nfsn_subdomain, nfsn_username, nfsn_apikey, v6=False,
190231
parser = argparse.ArgumentParser(description='automate the updating of domain records to create Dynamic DNS for domains registered with NearlyFreeSpeech.net')
191232
parser.add_argument('--ipv6', '-6', action='store_true', help='also check and update the AAAA (IPv6) records')
192233
parser.add_argument('--useDig', '-d', action='store_true', help='use the dig command to query dns')
234+
parser.add_argument('--export-to', help='the filename to export the zone file to')
193235
args = parser.parse_args()
194236

195237
nfsn_username = os.getenv('USERNAME')
@@ -201,7 +243,17 @@ def check_ips(nfsn_domain, nfsn_subdomain, nfsn_username, nfsn_apikey, v6=False,
201243
ensure_present(nfsn_apikey, "API_KEY")
202244
ensure_present(nfsn_domain, "DOMAIN")
203245

204-
use_dig_command = os.getenv('IP_USE_DIG', args.useDig)
205-
v6_enabled = os.getenv('ENABLE_IPV6', args.ipv6)
246+
if args.export_to:
247+
248+
dns = getAllDNSRecords(nfsn_domain, nfsn_username, nfsn_apikey)
249+
250+
zonedata = NFSNDnsToZoneFile(dns)
206251

207-
check_ips(nfsn_domain, nfsn_subdomain, nfsn_username, nfsn_apikey, v6=v6_enabled, dig=use_dig_command, create_if_not_exists=False)
252+
Path(args.export_to).write_text('\n'.join(zonedata), encoding='utf-8')
253+
else:
254+
use_dig_command = os.getenv('IP_USE_DIG', args.useDig)
255+
v6_enabled = os.getenv('ENABLE_IPV6', args.ipv6)
256+
257+
check_ips(nfsn_domain, nfsn_subdomain, nfsn_username, nfsn_apikey, v6=v6_enabled, dig=use_dig_command, create_if_not_exists=False)
258+
259+

0 commit comments

Comments
 (0)