Added simple error message handling
More sanity checks Restructured code
This commit is contained in:
2
TODO
2
TODO
@@ -9,6 +9,8 @@ TODO for dnsupdate
|
||||
|
||||
|
||||
Done:
|
||||
- Validate data, check for cfg files existance
|
||||
- Re-structure the code
|
||||
- Add a config-file for hostname, domain and password. Option to select
|
||||
All options should be configurable, ttl and force as well.
|
||||
- Fix the global variabel mess!!
|
||||
|
||||
111
dnsupdate.py
111
dnsupdate.py
@@ -2,16 +2,31 @@
|
||||
# dnsupdate.py
|
||||
# Updates a dynamic dns-record using a TSIG key.
|
||||
|
||||
def checkerror(msg):
|
||||
if len(msg['error']) > 0:
|
||||
for error in msg['error']:
|
||||
print "Error: %s" % error
|
||||
print "Use -h for help"
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
def get_ipaddress():
|
||||
# Connects to the dns server to determine which ip address
|
||||
# Connect to the dns server to determine which ip address
|
||||
# this host connects from
|
||||
import urllib
|
||||
remote = opener = urllib.FancyURLopener({})
|
||||
f = opener.open("http://www.wahlberg.se/~fredrik/ip.php")
|
||||
ip = f.read().strip()
|
||||
return ip
|
||||
try:
|
||||
f = opener.open("http://www.wahlberg.se/~fredrik/ip.php")
|
||||
ip = f.read().strip()
|
||||
return ip
|
||||
except:
|
||||
msg['error'].append("Could not determine ip address automatically,\nuse -i switch to enter manually")
|
||||
|
||||
def main(msg):
|
||||
|
||||
|
||||
def getparams(msg):
|
||||
from optparse import OptionParser
|
||||
import sys
|
||||
# Define option parameters
|
||||
@@ -19,10 +34,10 @@ def main(msg):
|
||||
parser = OptionParser(usage)
|
||||
parser.add_option("-c", "--config",
|
||||
type="string",
|
||||
help="File containing configuration data")
|
||||
help="Alternate config file")
|
||||
parser.add_option("-d", "--domain",
|
||||
type="string",
|
||||
help="Name of the domain to update")
|
||||
help="Domain to update")
|
||||
parser.add_option("-i", "--ipaddress",
|
||||
type="string",
|
||||
help="IP-address of the host [auto detected]")
|
||||
@@ -31,13 +46,14 @@ def main(msg):
|
||||
help="Name of the TSIG key")
|
||||
parser.add_option("-n", "--name",
|
||||
type="string",
|
||||
help="Name of the host to update")
|
||||
help="Hostname of local machine")
|
||||
parser.add_option("-p", "--password",
|
||||
type="string",
|
||||
help="The TSIG key")
|
||||
help="TSIG key")
|
||||
parser.add_option("-t", "--ttl",
|
||||
type="int",
|
||||
help="TTL in seconds")
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
if options.config:
|
||||
@@ -45,12 +61,15 @@ def main(msg):
|
||||
|
||||
msg = readcfg(msg)
|
||||
|
||||
if options.domain:
|
||||
msg['domain'] = options.domain
|
||||
if options.ipaddress:
|
||||
msg['ipaddress'] = options.ipaddress
|
||||
else:
|
||||
msg['ipaddress'] = get_ipaddress()
|
||||
ip = get_ipaddress()
|
||||
if ip:
|
||||
msg['ipaddress'] = ip
|
||||
|
||||
if options.domain:
|
||||
msg['domain'] = options.domain
|
||||
if options.keyname:
|
||||
msg['keyname'] = options.keyname
|
||||
if options.name:
|
||||
@@ -60,13 +79,23 @@ def main(msg):
|
||||
if options.ttl:
|
||||
msg['ttl'] = options.ttl
|
||||
|
||||
#print msg
|
||||
update(msg)
|
||||
return msg
|
||||
|
||||
|
||||
|
||||
def readcfg(msg):
|
||||
import os.path
|
||||
# Reads the config file for default info
|
||||
cfgfile = open(msg['cfgfile'], 'r')
|
||||
if not msg.has_key('cfgfile'):
|
||||
if os.path.exists(os.path.expanduser("~/.dnsupdaterc")):
|
||||
cfgfile = open(os.path.expanduser("~/.dnsupdaterc"), 'r')
|
||||
else:
|
||||
return msg
|
||||
else:
|
||||
if not os.path.exists(msg['cfgfile']):
|
||||
msg['error'].append("No such file: %s" % msg['cfgfile'])
|
||||
return msg
|
||||
cfgfile = open(msg['cfgfile'], 'r')
|
||||
|
||||
for line in cfgfile.readlines():
|
||||
(key, value) = line.split('\t', 1)
|
||||
@@ -75,22 +104,14 @@ def readcfg(msg):
|
||||
cfgfile.close()
|
||||
return msg
|
||||
|
||||
|
||||
|
||||
def update(msg):
|
||||
import dns.query
|
||||
import dns.tsigkeyring
|
||||
import dns.update
|
||||
import re
|
||||
import string
|
||||
# The update function connects to the dns server
|
||||
|
||||
# Sanity check incoming data
|
||||
#global hostname, ipaddress, ttl
|
||||
msg['hostname'] = string.replace(msg['hostname'], "." + msg['domain'], '')
|
||||
if not re.search('^[12]?[0-9]?[0-9](\.[12]?[0-9]?[0-9]){3}$', msg['ipaddress']):
|
||||
print "Invalid ip address '%s'" % msg['ipaddress']
|
||||
return
|
||||
|
||||
|
||||
# The name of the key and the secret
|
||||
keyring = dns.tsigkeyring.from_text({
|
||||
msg['keyname']: msg['keysecret']
|
||||
@@ -103,7 +124,11 @@ def update(msg):
|
||||
update.replace(msg['hostname'], msg['ttl'], 'a', msg['ipaddress'])
|
||||
|
||||
# doit, servername
|
||||
response = dns.query.tcp(update, 'nic.wahlberg.se')
|
||||
try:
|
||||
response = dns.query.tcp(update, '217.78.32.198')
|
||||
except:
|
||||
msg['error'].append("An error has occurred, check your keyname and password.")
|
||||
return
|
||||
|
||||
# Verify response
|
||||
if response.rcode() == 0:
|
||||
@@ -111,8 +136,36 @@ def update(msg):
|
||||
else:
|
||||
print "An error has occurred, the server returned:\n%s" % response
|
||||
|
||||
|
||||
|
||||
def validate(msg):
|
||||
import re
|
||||
import string
|
||||
# Verify all required data is present and sanity check incoming data
|
||||
req_vals = ['domain', 'hostname', 'ipaddress', 'keyname', 'keysecret']
|
||||
for value in req_vals:
|
||||
if not msg.has_key(value):
|
||||
msg['error'].append('Missing "%s" parameter' % value)
|
||||
|
||||
#global hostname, ipaddress, ttl
|
||||
if msg.has_key('hostname') and msg.has_key('domain'):
|
||||
msg['hostname'] = string.replace(msg['hostname'], "." + msg['domain'], '')
|
||||
|
||||
if msg.has_key('ipaddress'):
|
||||
if not re.search('^[12]?[0-9]?[0-9](\.[12]?[0-9]?[0-9]){3}$', msg['ipaddress']):
|
||||
msg['error'].append("Invalid ip address '%s'" % msg['ipaddress'])
|
||||
|
||||
return msg
|
||||
|
||||
|
||||
|
||||
if __name__=="__main__":
|
||||
import os.path
|
||||
msg = {}
|
||||
msg['cfgfile'] = os.path.expanduser("~/.dnsupdaterc")
|
||||
main(msg)
|
||||
msg['error'] = []
|
||||
|
||||
getparams(msg)
|
||||
validate(msg)
|
||||
err = checkerror(msg)
|
||||
if err == 0:
|
||||
update(msg)
|
||||
checkerror(msg)
|
||||
|
||||
Reference in New Issue
Block a user