-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathupdater.py
125 lines (96 loc) · 3.66 KB
/
updater.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
#/usr/bin/python
from boto import route53
import httplib
import socket
import re
class r53dd:
def __init__(self, hosted_zone, aws_key, aws_secret, ip_source, ttl = 300, hostname = None):
"""
Init Route53 DynDns Client
:type hosted_zone: str
:param hosted_zone: The domain name managed by Route53
:type aws_key: str
:param aws_key: AWS key from security credentials
:type aws_secret: str
:param aws_secret: AWS secret from security credentials
:type ttl: int
:param ttl: domain time to live in seconds, defaults to 300
"""
if hosted_zone[-1] != ".":
hosted_zone = hosted_zone + "."
self.hosted_zone = hosted_zone
self.aws_key = aws_key
self.aws_secret = aws_secret
self.ip_source = ip_source
self.ttl = ttl
self.hostname = hostname
def getR53Connection(self):
""" Opens a connection to Amazon's Route53 service """
return route53.Route53Connection(self.aws_key, self.aws_secret)
def getHostedZone(self):
""" get hosted_zone object by name """
r53 = self.getR53Connection()
zone = r53.get_hosted_zone_by_name(self.hosted_zone)
if zone == None:
print "Zone with name " + self.hosted_zone + " not found. Aborting."
exit(1)
"""
fix for current bug in boto library
see https://github.com/boto/boto/issues/448
"""
if zone.Id[0:12] == '/hostedzone/':
zone.Id = zone.Id.replace('/hostedzone/', '')
return zone
def getRecords(self):
""" get all records from configured zone """
zone = self.getHostedZone()
return self.getR53Connection().get_all_rrsets(zone.Id)
def updateIp(self):
"""
check if record exists. if no record exists create a record.
if a record exists and ip address has changed delete it before
new record being is created
"""
records = self.getRecords()
ip = self.getExternalIp()
fqdn = self.getHostname() + '.' + self.hosted_zone
for r in records:
if (r.type == "A"):
if (r.name == self.getHostname()+'.'+self.hosted_zone):
""" record exists """
""" return and do nothing if IP did not change """
old_ip = r.resource_records[0]
if old_ip == ip:
return
"""if IP changed remove old record"""
change = records.add_change('DELETE', fqdn, 'A', self.ttl)
change.add_value(old_ip)
""" create a a new record """
change = records.add_change('CREATE', fqdn, 'A', self.ttl)
change.add_value(ip)
records.commit()
def getExternalIp(self):
"""
Retrieve external IP Address from service
"""
ip = ''
request_parts = self.ip_source.split("/", 1)
request_parts +=['']*(2-len(request_parts))
(host, path) = request_parts
iptest = httplib.HTTPConnection(host)
iptest.request('GET', "/%s" % path)
response = iptest.getresponse()
if (response.status == 200):
ip = re.search('((\d+\.){3}(\d+))', response.read()).group(0)
iptest.close()
""" if ip check worked run update record """
if (len(ip) > 0):
return ip
return None
def getHostname(self):
"""
get configured hostname, if empty get hostname from sys
"""
if self.hostname != None:
return self.hostname
return socket.gethostname().split('.')[0]