Fixed purgeUnknownRecords behavior
This commit is contained in:
parent
a9d25c743a
commit
464d2792b1
38
.vscode/settings.json
vendored
38
.vscode/settings.json
vendored
@ -1,19 +1,21 @@
|
|||||||
{
|
{
|
||||||
"files.exclude": {
|
"files.exclude": {
|
||||||
"**/.git": true,
|
"**/.git": true,
|
||||||
"**/.svn": true,
|
"**/.svn": true,
|
||||||
"**/.hg": true,
|
"**/.hg": true,
|
||||||
"**/CVS": true,
|
"**/CVS": true,
|
||||||
"**/.DS_Store": true,
|
"**/.DS_Store": true,
|
||||||
".github": true,
|
"**/Thumbs.db": true,
|
||||||
".gitignore": true,
|
".github": true,
|
||||||
".vscode": true,
|
".gitignore": true,
|
||||||
"Dockerfile": true,
|
".vscode": true,
|
||||||
"LICENSE": true,
|
"Dockerfile": true,
|
||||||
"requirements.txt": true,
|
"LICENSE": true,
|
||||||
"venv": true
|
"requirements.txt": true,
|
||||||
},
|
"venv": true
|
||||||
"explorerExclude.backup": null,
|
},
|
||||||
"python.linting.pylintEnabled": true,
|
"explorerExclude.backup": null,
|
||||||
"python.linting.enabled": true
|
"python.linting.pylintEnabled": true,
|
||||||
}
|
"python.linting.enabled": true,
|
||||||
|
"python.formatting.provider": "autopep8"
|
||||||
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
# Summary: Access your home network remotely via a custom domain name without a static IP!
|
# Summary: Access your home network remotely via a custom domain name without a static IP!
|
||||||
# Description: Access your home network remotely via a custom domain
|
# Description: Access your home network remotely via a custom domain
|
||||||
# Access your home network remotely via a custom domain
|
# Access your home network remotely via a custom domain
|
||||||
# A small, 🕵️ privacy centric, and ⚡
|
# A small, 🕵️ privacy centric, and ⚡
|
||||||
# lightning fast multi-architecture Docker image for self hosting projects.
|
# lightning fast multi-architecture Docker image for self hosting projects.
|
||||||
|
|
||||||
__version__ = "1.0.1"
|
__version__ = "1.0.1"
|
||||||
@ -18,15 +18,17 @@ import requests
|
|||||||
|
|
||||||
CONFIG_PATH = os.environ.get('CONFIG_PATH', os.getcwd() + "/")
|
CONFIG_PATH = os.environ.get('CONFIG_PATH', os.getcwd() + "/")
|
||||||
|
|
||||||
class GracefulExit:
|
|
||||||
def __init__(self):
|
|
||||||
self.kill_now = threading.Event()
|
|
||||||
signal.signal(signal.SIGINT, self.exit_gracefully)
|
|
||||||
signal.signal(signal.SIGTERM, self.exit_gracefully)
|
|
||||||
|
|
||||||
def exit_gracefully(self, signum, frame):
|
class GracefulExit:
|
||||||
print("🛑 Stopping main thread...")
|
def __init__(self):
|
||||||
self.kill_now.set()
|
self.kill_now = threading.Event()
|
||||||
|
signal.signal(signal.SIGINT, self.exit_gracefully)
|
||||||
|
signal.signal(signal.SIGTERM, self.exit_gracefully)
|
||||||
|
|
||||||
|
def exit_gracefully(self, signum, frame):
|
||||||
|
print("🛑 Stopping main thread...")
|
||||||
|
self.kill_now.set()
|
||||||
|
|
||||||
|
|
||||||
def deleteEntries(type):
|
def deleteEntries(type):
|
||||||
# Helper function for deleting A or AAAA records
|
# Helper function for deleting A or AAAA records
|
||||||
@ -34,17 +36,19 @@ def deleteEntries(type):
|
|||||||
# existing A or AAAA records are found.
|
# existing A or AAAA records are found.
|
||||||
for option in config["cloudflare"]:
|
for option in config["cloudflare"]:
|
||||||
answer = cf_api(
|
answer = cf_api(
|
||||||
"zones/" + option['zone_id'] + "/dns_records?per_page=100&type=" + type,
|
"zones/" + option['zone_id'] +
|
||||||
|
"/dns_records?per_page=100&type=" + type,
|
||||||
"GET", option)
|
"GET", option)
|
||||||
if answer is None or answer["result"] is None:
|
if answer is None or answer["result"] is None:
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
return
|
return
|
||||||
for record in answer["result"]:
|
for record in answer["result"]:
|
||||||
identifier = str(record["id"])
|
identifier = str(record["id"])
|
||||||
cf_api(
|
cf_api(
|
||||||
"zones/" + option['zone_id'] + "/dns_records/" + identifier,
|
"zones/" + option['zone_id'] + "/dns_records/" + identifier,
|
||||||
"DELETE", option)
|
"DELETE", option)
|
||||||
print("🗑️ Deleted stale record " + identifier)
|
print("🗑️ Deleted stale record " + identifier)
|
||||||
|
|
||||||
|
|
||||||
def getIPs():
|
def getIPs():
|
||||||
a = None
|
a = None
|
||||||
@ -66,7 +70,8 @@ def getIPs():
|
|||||||
deleteEntries("A")
|
deleteEntries("A")
|
||||||
if ipv6_enabled:
|
if ipv6_enabled:
|
||||||
try:
|
try:
|
||||||
aaaa = requests.get("https://[2606:4700:4700::1111]/cdn-cgi/trace").text.split("\n")
|
aaaa = requests.get(
|
||||||
|
"https://[2606:4700:4700::1111]/cdn-cgi/trace").text.split("\n")
|
||||||
aaaa.pop()
|
aaaa.pop()
|
||||||
aaaa = dict(s.split("=") for s in aaaa)["ip"]
|
aaaa = dict(s.split("=") for s in aaaa)["ip"]
|
||||||
except Exception:
|
except Exception:
|
||||||
@ -89,6 +94,7 @@ def getIPs():
|
|||||||
}
|
}
|
||||||
return ips
|
return ips
|
||||||
|
|
||||||
|
|
||||||
def commitRecord(ip):
|
def commitRecord(ip):
|
||||||
for option in config["cloudflare"]:
|
for option in config["cloudflare"]:
|
||||||
subdomains = option["subdomains"]
|
subdomains = option["subdomains"]
|
||||||
@ -97,7 +103,7 @@ def commitRecord(ip):
|
|||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
return
|
return
|
||||||
base_domain_name = response["result"]["name"]
|
base_domain_name = response["result"]["name"]
|
||||||
ttl = 300 # default Cloudflare TTL
|
ttl = 300 # default Cloudflare TTL
|
||||||
for subdomain in subdomains:
|
for subdomain in subdomains:
|
||||||
subdomain = subdomain.lower().strip()
|
subdomain = subdomain.lower().strip()
|
||||||
record = {
|
record = {
|
||||||
@ -108,7 +114,8 @@ def commitRecord(ip):
|
|||||||
"ttl": ttl
|
"ttl": ttl
|
||||||
}
|
}
|
||||||
dns_records = cf_api(
|
dns_records = cf_api(
|
||||||
"zones/" + option['zone_id'] + "/dns_records?per_page=100&type=" + ip["type"],
|
"zones/" + option['zone_id'] +
|
||||||
|
"/dns_records?per_page=100&type=" + ip["type"],
|
||||||
"GET", option)
|
"GET", option)
|
||||||
fqdn = base_domain_name
|
fqdn = base_domain_name
|
||||||
if subdomain:
|
if subdomain:
|
||||||
@ -133,7 +140,8 @@ def commitRecord(ip):
|
|||||||
if modified:
|
if modified:
|
||||||
print("📡 Updating record " + str(record))
|
print("📡 Updating record " + str(record))
|
||||||
response = cf_api(
|
response = cf_api(
|
||||||
"zones/" + option['zone_id'] + "/dns_records/" + identifier,
|
"zones/" + option['zone_id'] +
|
||||||
|
"/dns_records/" + identifier,
|
||||||
"PUT", option, {}, record)
|
"PUT", option, {}, record)
|
||||||
else:
|
else:
|
||||||
print("➕ Adding new record " + str(record))
|
print("➕ Adding new record " + str(record))
|
||||||
@ -144,16 +152,17 @@ def commitRecord(ip):
|
|||||||
identifier = str(identifier)
|
identifier = str(identifier)
|
||||||
print("🗑️ Deleting stale record " + identifier)
|
print("🗑️ Deleting stale record " + identifier)
|
||||||
response = cf_api(
|
response = cf_api(
|
||||||
"zones/" + option['zone_id'] + "/dns_records/" + identifier,
|
"zones/" + option['zone_id'] +
|
||||||
|
"/dns_records/" + identifier,
|
||||||
"DELETE", option)
|
"DELETE", option)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def cf_api(endpoint, method, config, headers={}, data=False):
|
def cf_api(endpoint, method, config, headers={}, data=False):
|
||||||
api_token = config['authentication']['api_token']
|
api_token = config['authentication']['api_token']
|
||||||
if api_token != '' and api_token != 'api_token_here':
|
if api_token != '' and api_token != 'api_token_here':
|
||||||
headers = {
|
headers = {
|
||||||
"Authorization": "Bearer " + api_token,
|
"Authorization": "Bearer " + api_token, **headers
|
||||||
**headers
|
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
headers = {
|
headers = {
|
||||||
@ -172,14 +181,17 @@ def cf_api(endpoint, method, config, headers={}, data=False):
|
|||||||
if response.ok:
|
if response.ok:
|
||||||
return response.json()
|
return response.json()
|
||||||
else:
|
else:
|
||||||
print("📈 Error sending '" + method + "' request to '" + response.url + "':")
|
print("📈 Error sending '" + method +
|
||||||
|
"' request to '" + response.url + "':")
|
||||||
print(response.text)
|
print(response.text)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def updateIPs(ips):
|
def updateIPs(ips):
|
||||||
for ip in ips.values():
|
for ip in ips.values():
|
||||||
commitRecord(ip)
|
commitRecord(ip)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
shown_ipv4_warning = False
|
shown_ipv4_warning = False
|
||||||
shown_ipv6_warning = False
|
shown_ipv6_warning = False
|
||||||
@ -196,7 +208,8 @@ if __name__ == '__main__':
|
|||||||
config = json.loads(config_file.read())
|
config = json.loads(config_file.read())
|
||||||
except:
|
except:
|
||||||
print("😡 Error reading config.json")
|
print("😡 Error reading config.json")
|
||||||
time.sleep(60) # wait 60 seconds to prevent excessive logging on docker auto restart
|
# wait 60 seconds to prevent excessive logging on docker auto restart
|
||||||
|
time.sleep(60)
|
||||||
|
|
||||||
if config is not None:
|
if config is not None:
|
||||||
try:
|
try:
|
||||||
@ -223,11 +236,12 @@ if __name__ == '__main__':
|
|||||||
next_time = time.time()
|
next_time = time.time()
|
||||||
killer = GracefulExit()
|
killer = GracefulExit()
|
||||||
prev_ips = None
|
prev_ips = None
|
||||||
while True:
|
while True:
|
||||||
updateIPs(getIPs())
|
updateIPs(getIPs())
|
||||||
if killer.kill_now.wait(delay):
|
if killer.kill_now.wait(delay):
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
print("❓ Unrecognized parameter '" + sys.argv[1] + "'. Stopping now.")
|
print("❓ Unrecognized parameter '" +
|
||||||
|
sys.argv[1] + "'. Stopping now.")
|
||||||
else:
|
else:
|
||||||
updateIPs(getIPs())
|
updateIPs(getIPs())
|
||||||
|
|||||||
Reference in New Issue
Block a user