-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdyndns.py
executable file
·147 lines (106 loc) · 3.81 KB
/
dyndns.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#!/usr/bin/env python
# -*-coding: utf-8 -*-
"""
Usage: $ {1: program}.py
"""
import copy
import json
import os
import requests
from dotenv import load_dotenv
load_dotenv()
CF_EMAIL = os.getenv("CF_EMAIL")
CF_API_KEY = os.getenv("CF_API_KEY")
CF_API = os.getenv("CF_API", default="https://api.cloudflare.com/client/v4")
CF_ZONE_ID = os.getenv("CF_ZONE_ID")
ZONE = os.getenv("ZONE")
DOMAINS = [domain.strip() for domain in os.getenv("DOMAINS").split(",")]
# IP Address service url
IP_API = "http://ipinfo.io/ip"
# Cache values like zone_id that had to be collected first time this ran
try:
with open("CACHE.json", "r") as f:
CACHE = json.load(f)
except Exception:
CACHE = {}
# curl -X PUT "https://api.cloudflare.com/client/v4/zones/023e105f4ecef8ad9ca31a8372d0c353/dns_records/372e67954025e0ba6aaa6d586b9e0b59" \
# -H "X-Auth-Email: [email protected]" \
# -H "X-Auth-Key: c2547eb745079dac9320b638f5e225cf483cc5cfdda41" \
# -H "Content-Type: application/json" \
# --data '{"type":"A","name":"example.com","content":"127.0.0.1","ttl":{},"proxied":false}'
def get_zone_id():
headers = {
"X-AUTH-KEY": CF_API_KEY,
"X-AUTH-EMAIL": CF_EMAIL,
"CONTENT-TYPE": "application/json",
}
r = requests.get(f"{CF_API}/zones", headers=headers)
results = r.json()
zone_id = [zone["id"] for zone in results["result"] if zone["name"] == ZONE][0]
CACHE["zone_id"] = zone_id
def get_domain_ids():
headers = {
"X-AUTH-KEY": CF_API_KEY,
"X-AUTH-EMAIL": CF_EMAIL,
"CONTENT-TYPE": "application/json",
}
r = requests.get(f"{CF_API}/zones/{CACHE['zone_id']}/dns_records", headers=headers)
results = r.json()
# print("DumpVar:\n", json.dumps(results, indent=4))
identifiers = {
domain["name"]: domain["id"] for domain in results["result"] if domain["name"] in DOMAINS
}
CACHE["domain_ids"] = copy.copy(identifiers)
def get_public_ip():
"""Get public ip address for dynamic ip hosted service"""
r = requests.get(IP_API)
ip = r.text.strip()
return ip
def save_cache():
with open("CACHE.json", "w") as f:
json.dump(CACHE, f, indent=4)
def update_cloudflare(ip):
"""Update Cloudflare"""
for domain in DOMAINS:
zone_id = CACHE["zone_id"]
domain_id = CACHE["domain_ids"][domain]
url = f"{CF_API}/zones/{zone_id}/dns_records/{domain_id}"
headers = {
"X-AUTH-KEY": CF_API_KEY,
"X-AUTH-EMAIL": CF_EMAIL,
"CONTENT-TYPE": "application/json",
}
payload = {"type": "A", "name": domain, "content": ip}
print("Updating", domain, "Payload", payload, "URL", url)
print("Headers", headers)
r = requests.put(url, headers=headers, json=payload)
print("Results", r.status_code, r.json())
print("\n\n")
def main():
# Collect zone_id if not available in CACHE.json
cache_save_flag = False
if not CACHE.get("zone_id", False):
cache_save_flag = True
get_zone_id()
# Check if all domain_id's are found in CACHE.json
all_found = False
if CACHE.get("domain_ids", False):
all_found = all([CACHE["domain_ids"].get(domain, False) for domain in DOMAINS])
if not all_found:
cache_save_flag = True
get_domain_ids()
# print([CACHE["domain_ids"].get(domain, False) for domain in DOMAINS])
# print("DumpVar:\n", json.dumps(CACHE, indent=4))
# Update public ip in cloudflare
ip = get_public_ip()
if ip != CACHE.get("public_ip", ""):
update_cloudflare(ip)
CACHE["public_ip"] = ip
cache_save_flag = True
else:
print("Not updating Cloudflare - public IP hasn't changed.")
# Save collected ids in CACHE.json file
if cache_save_flag:
save_cache()
if __name__ == "__main__":
main()