-
Notifications
You must be signed in to change notification settings - Fork 0
/
cloudflare_dns.py
123 lines (107 loc) · 3.35 KB
/
cloudflare_dns.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
#!/bin/python
import getopt
import sys
import socket
import CloudFlare
def main():
zone_name = 'example.com'
email = 'admin@example.com'
token = '<secret token>'
try:
opts, args = getopt.getopt(sys.argv[1:], "d:i", ["dns=", "ip=", "add", "delete"])
except getopt.GetoptError as err:
print str(err)
sys.exit(2)
dns_name = ''
ip_address = ''
action = ''
for o, a in opts:
if o == "--add":
action = 'add'
elif o == "--delete":
action = 'delete'
elif o == "--dns":
dns_name = a
elif o == "--ip":
ip_address = a
else:
assert False, "unhandled option"
if ip_address == '':
exit('ip empty')
elif is_valid_ipv4_address(ip_address) == False:
ip = socket.gethostbyname(ip_address)
if is_valid_ipv4_address(ip) == True:
ip_address = ip
else:
exit('wrong ip or dns')
if dns_name == '':
exit('dns empty')
cf = CloudFlare.CloudFlare(email=email,token=token)
# query for the zone name and expect only one value back
try:
zones = cf.zones.get(params = {'name':zone_name,'per_page':1})
except Exception as e:
exit('/zones.get - %s - api call failed' % (e))
# extract the zone_id which is needed to process that zone
zone = zones[0]
zone_id = zone['id']
if action == 'add':
add_record(cf, zone_id, dns_name, ip_address)
elif action == 'delete':
delete_record(cf, zone_id, dns_name, ip_address)
exit(0)
def add_record(cf, zone_id, dns_name, ip_address):
dns_data = {
'name':dns_name,
'type':'A',
'content':ip_address,
'proxied':True,
}
try:
res = cf.zones.dns_records.post(zone_id, data=dns_data)
except Exception as e:
exit('/zones.post - %s - api call failed' % (e))
print 'CREATED: %s %s' % (dns_name, ip_address)
exit(0)
def delete_record(cf, zone_id, dns_name, ip_address):
rec_id = ''
# request the DNS records from that zone
try:
dns_records = cf.zones.dns_records.get(zone_id)
except Exception as e:
exit('/zones/dns_records.get %d %s - api call failed' % (e, e))
# then all the DNS records for that zone
for dns_record in dns_records:
if dns_record['type'] not in ['A', 'AAAA']:
# we only deal with A / AAAA records
continue
if dns_record['name'] == dns_name and dns_record['content'] == ip_address:
rec_id = dns_record['id']
else:
continue
if rec_id != '':
dns_data = {
'name':dns_name,
'type':'A',
'content':ip_address,
}
try:
res = cf.zones.dns_records.delete(zone_id, rec_id, data=dns_data)
except Exception as e:
exit('/zones.delete - %s - api call failed' % (e))
print 'DELETED: %s %s' % (dns_name, ip_address)
exit(0)
def is_valid_ipv4_address(address):
try:
socket.inet_pton(socket.AF_INET, address)
except AttributeError: # no inet_pton here, sorry
try:
socket.inet_aton(address)
except socket.error:
return False
return address.count('.') == 3
except socket.error: # not a valid address
return False
return True
if __name__ == '__main__':
main()