From 1cd5b63efd9456860b9d8f13792a8ad49f8d0354 Mon Sep 17 00:00:00 2001 From: Fredrik Wahlberg Date: Thu, 15 Jan 2004 23:16:56 +0000 Subject: [PATCH] Added simple error message handling More sanity checks Restructured code --- TODO | 2 + dnsupdate.py | 111 +++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 84 insertions(+), 29 deletions(-) diff --git a/TODO b/TODO index f11500d..21bf97d 100644 --- a/TODO +++ b/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!! diff --git a/dnsupdate.py b/dnsupdate.py index 03a9a38..c11cd5c 100644 --- a/dnsupdate.py +++ b/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) \ No newline at end of file + msg['error'] = [] + + getparams(msg) + validate(msg) + err = checkerror(msg) + if err == 0: + update(msg) + checkerror(msg)