-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathvultr-dns.py
executable file
·100 lines (73 loc) · 2.79 KB
/
vultr-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
#!/usr/bin/env python
import requests
import sys
import os
import string
from time import sleep
# Configure here
VULTR_API_KEY = "put your api key here"
VULTR_BIND_DELAY = 30
def vultr_request(method, path, data=None):
url = "https://api.vultr.com/v1{}".format(path)
resp = requests.request(method, url, data=data, headers={
"API-Key": VULTR_API_KEY})
resp.raise_for_status()
if resp.headers['Content-Type'] == 'application/json':
return resp.json()
return resp.text
def normalize_fqdn(fqdn):
fqdn = string.lower(fqdn)
return fqdn
def find_zone_for_name(domain):
resp = vultr_request("GET", "/dns/list")
zones = [entry['domain'] for entry in resp]
# api doesn't have a trailing . on its zones
if domain[-1:] == '.':
domain = domain[:-1]
domain_split = domain.split('.')
while len(domain_split) > 0:
search = string.join(domain_split, ".")
if search in zones:
return search
domain_split = domain_split[1:]
raise Exception("Could not identify existing zone for {}".format(domain))
def list_records(zone):
return vultr_request("GET", "/dns/records?domain={}".format(zone))
def create_record(domain, txt_value):
to_add = normalize_fqdn('_acme-challenge.{}'.format(domain))
print("Creating {} TXT: {}".format(to_add, txt_value))
zone = find_zone_for_name(domain)
create_params = {'domain': zone, 'name': to_add, 'type': 'TXT',
'data': '"{}"'.format(txt_value)}
vultr_request("POST", "/dns/create_record", create_params)
print("Will sleep {} seconds to wait for DNS cluster to reload".
format(VULTR_BIND_DELAY))
sleep(VULTR_BIND_DELAY)
def remove_record(domain, txt_value):
to_remove = normalize_fqdn("_acme-challenge.{}".format(domain))
zone = find_zone_for_name(to_remove)
recs = list_records(zone)
print "Removing {} TXT: {}".format(to_remove, txt_value)
to_remove = to_remove[:-len(zone)-1]
found = filter(
lambda rec:
'name' in rec and rec['name'] == to_remove and
'type' in rec and rec['type'] == 'TXT' and
rec['data'] == '"{}"'.format(txt_value),
recs)
if len(found) == 0:
print("Could not find record to remove: {} with value {}".
format(to_remove, txt_value))
return
delete_params = {'domain': zone, 'RECORDID': found[0]['RECORDID']}
vultr_request("POST", "/dns/delete_record", delete_params)
act = sys.argv[1]
if act == "create":
create_record(os.environ["CERTBOT_DOMAIN"],
os.environ["CERTBOT_VALIDATION"])
elif act == "delete":
remove_record(os.environ["CERTBOT_DOMAIN"],
os.environ["CERTBOT_VALIDATION"])
else:
print("Unknown action: {}".format(act))
exit(1)