-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathinit.py
More file actions
86 lines (71 loc) · 2.96 KB
/
init.py
File metadata and controls
86 lines (71 loc) · 2.96 KB
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
#!/usr/bin/env python3
import os; import sys; import requests; import logging
# Load Cloudflare API token
from dotenv import load_dotenv
load_dotenv()
type = logging.INFO
logging.basicConfig(level=type, format='%(message)s')
def get_env(var, required=True):
value = os.getenv(var)
if required and not value:
logging.error(f"Environment variable '{var}' is required.")
sys.exit(1)
return value
def get_external_ip():
url = 'http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip'
resp = requests.get(url, headers={'Metadata-Flavor': 'Google'})
resp.raise_for_status()
ip = resp.text.strip()
logging.info(f"Current external IP: {ip}")
return ip
def get_zone_id(domain, headers):
url = 'https://api.cloudflare.com/client/v4/zones'
params = {'name': domain}
resp = requests.get(url, headers=headers, params=params)
resp.raise_for_status()
result = resp.json()
if not result.get('success') or not result['result']:
logging.error(f"Could not find Zone ID for domain '{domain}'")
sys.exit(1)
zone_id = result['result'][0]['id']
logging.info(f"Zone ID for {domain}: {zone_id}")
return zone_id
def get_record(zone_id, full_name, headers):
url = f'https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records'
params = {'type': 'A', 'name': full_name}
resp = requests.get(url, headers=headers, params=params)
resp.raise_for_status()
data = resp.json()
if data.get('result'):
record = data['result'][0]
return record['id'], record['content']
return None, None
def update_record(zone_id, record_id, full_name, ip, headers):
url = f'https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records/{record_id}'
payload = { 'type': 'A', 'name': full_name, 'content': ip, 'ttl': 1, 'proxied': False }
resp = requests.put(url, headers=headers, json=payload)
resp.raise_for_status()
result = resp.json()
if result.get('success'):
logging.info(f"Updated {full_name} to {ip}")
else:
logging.error(f"Failed to update {full_name}: {result.get('errors')}")
def main():
domain = 'tjctgrader.org'
record_names = ['@', 'www']
token = get_env('CF_API_TOKEN')
headers = { 'Authorization': f'Bearer {token}', 'Content-Type': 'application/json' }
ip = get_external_ip()
zone_id = get_zone_id(domain, headers)
for name in record_names:
full_name = domain if name == '@' else f"{name}.{domain}"
record_id, old_ip = get_record(zone_id, full_name, headers)
if not record_id:
logging.warning(f"No A record found for {full_name}, skipping.")
continue
logging.info(f"{full_name} currently points to {old_ip}")
if old_ip == ip:
logging.info(f"No update needed for {full_name}")
else:
update_record(zone_id, record_id, full_name, ip, headers)
if __name__ == '__main__': main()