-
Notifications
You must be signed in to change notification settings - Fork 1
/
check-ip-change
executable file
·156 lines (137 loc) · 5.42 KB
/
check-ip-change
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
148
149
150
151
152
153
154
155
156
#!/usr/bin/env python3
"""
Copyright 2016 Matthew Aguirre
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import argparse
import dns.resolver
import jsonpickle
import os.path
import re
import sys
import urllib.parse
import urllib.request
import xdg.BaseDirectory
class GoogleDomainsConfig(object):
"""Houses all information for connecting to Google Domains for changing Synthetic records."""
def __init__(self, domainname, username, password, email):
"""Constructor, set all values"""
self.domainname = domainname
self.username = username
self.password = password
self.email = email
def getServerIP(self):
"""Gets the DNS Specified IP of the requested name."""
answers = dns.resolver.query(self.domainname, 'A')
return str(answers[0])
def updateDns(self, newIp):
"""Performs a GET which will update the Synthetic DNS record hosted through Google Domains."""
params = urllib.parse.urlencode({'hostname': self.domainname, 'myip': newIp})
update_url = "https://" + self.username + ":" + self.password + "@domains.google.com/nic/update?" + str(params)
opener = urllib.request.FancyURLopener()
opener.version = "Chrome/41.0 " + self.email
f = opener.open(update_url)
def getLocalIP():
"""Get the public IP of the current network (works behind firewall)."""
url = "http://checkip.dyndns.org"
request = urllib.request.urlopen(url, timeout=10).read()
theIP = re.findall(r"\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}", str(request))
if len(theIP) > 0 :
return theIP[0]
def loadConfigs(cfg_path):
"""Load the JSON file into an object list"""
if os.path.isfile(cfg_path):
fp = open(cfg_path)
gdc_list = jsonpickle.decode(fp.read())
fp.close()
return gdc_list
else:
return []
if __name__ == "__main__":
# TODO: be able to pass in all add/remove arguments on the command line instead of being interactive.
parser = argparse.ArgumentParser(description='Update Google Domains DyDNS Records.')
parser.add_argument('--list', action='store_true', help='list configured records')
parser.add_argument('--add', action='store_true', help='add a new configuration')
parser.add_argument('--remove', action='store_true', help='remove a configuration')
parser.add_argument('--local', action='store_true', help='print out the local IP')
#parser.add_argument('--edit', action='store_true', help='edit a configuration')
cfg_dir = xdg.BaseDirectory.xdg_config_home
cfg_file = "check-ip-change.json"
cfg_path = os.path.join(cfg_dir, cfg_file)
if not os.path.isdir(cfg_dir):
os.makedirs(cfg_dir)
# this is going to be ~/.config/check-ip-change.json
gdc_list = loadConfigs(cfg_path)
args = parser.parse_args()
if args.local:
local = getLocalIP()
print("Local IP: " + local)
sys.exit(0)
elif args.list:
counter = 1
for gdc in gdc_list:
print("[ " + str(counter) + " ] " + gdc.domainname)
print("--------------------------")
print("username: " + gdc.username)
print("password: " + gdc.password)
print("email: " + gdc.email)
print()
counter += 1
if counter == 1:
print (cfg_path + ": does not exist or is not configured.")
sys.exit(0)
elif args.add:
domain = input("Domain: ")
user = input("User: ")
password = input("Password: ")
email = input("E-Mail: ")
gdc = GoogleDomainsConfig(domain, user, password, email)
gdc_list.append(gdc)
fp = open(cfg_path, 'w')
fp.write(jsonpickle.encode(gdc_list))
fp.close()
sys.exit(0)
elif args.remove:
domain = input("Domain to Remove (Index or Name): ")
if(str.isdigit(domain)):
index = int(domain) - 1
del gdc_list[index]
else:
index = -1
counter = 0;
for gdc in gdc_list:
if gdc.domainname == domain:
index = counter
counter += 1
if index >= 0:
del gdc_list[index]
fp = open(cfg_path, 'w')
fp.write(jsonpickle.encode(gdc_list))
fp.close()
sys.exit(0)
# if args.edit:
# sys.exit(0)
if (len(gdc_list) > 0):
local = getLocalIP()
print ("Local IP: " + local)
for gdc in gdc_list:
server = gdc.getServerIP()
print ("DNS Specified IP: " + server)
if local != server:
#TODO: maybe have a y/n for updating?
print ("Updating DNS Record: " + gdc.domainname + " to " + local)
gdc.updateDns(local);
pass
else:
print ("No change in DNS record: " + gdc.domainname)
pass
else:
print (cfg_path + ": does not exist or is not configured.")