Index: tools/gformat.py
===================================================================
--- tools/gformat.py	(revision 14335)
+++ tools/gformat.py	(revision 14374)
@@ -1,3 +1,3 @@
-#!/usr/local/bin/python
+#!/usr/bin/env python3
 #
 # vim:ts=2:et:sw=2:ai
@@ -32,10 +32,11 @@
 sys.path.append(os.path.dirname(__file__))
 
-SVN = filter(os.path.isfile, ('/usr/local/bin/svn', '/usr/bin/svn'))[0]
-SVNVERSION = filter(os.path.isfile, ('/usr/local/bin/svnversion', '/usr/bin/svnversion'))[0]
+SVN = next(filter(os.path.isfile, ('/usr/local/bin/svn', '/usr/bin/svn')))
+SVNVERSION = next(filter(os.path.isfile, ('/usr/local/bin/svnversion', '/usr/bin/svnversion')))
 
 import argparse
 import cgi
 import cgitb
+import codecs
 import copy
 import glob
@@ -51,14 +52,15 @@
 import time
 import traceback
-import urlparse
+import urllib
 
 from pprint import pprint
 from collections import defaultdict, OrderedDict
+from operator import itemgetter, attrgetter
 from sys import stderr
 try:
   import yaml
-except ImportError, e:
-  print e
-  print "[ERROR] Please install the python-yaml or devel/py-yaml package"
+except ImportError as e:
+  print(e)
+  print("[ERROR] Please install the python-yaml or devel/py-yaml package")
   exit(1)
 
@@ -92,5 +94,5 @@
 
 
-if os.environ.has_key('CONFIGROOT'):
+if os.environ.get('CONFIGROOT', None):
   NODE_DIR = os.environ['CONFIGROOT']
 else:
@@ -131,5 +133,5 @@
 DHCP_SERVER = 20
 def dhcp_type(item):
-  if not item.has_key('dhcp'):
+  if not 'dhcp' in item:
     return NO_DHCP
   elif not item['dhcp']:
@@ -159,5 +161,5 @@
   try:
     """ Get configuration yaml for 'item'"""
-    if datadump_cache.has_key(item):
+    if item in datadump_cache:
       return datadump_cache[item].copy()
 
@@ -178,5 +180,5 @@
     if datadump['nodetype'] == 'Hybrid':
       # Some values are defined implicitly
-      if datadump.has_key('rdr_host') and datadump['rdr_host'] and not datadump.has_key('service_incoming_rdr'):
+      if 'rdr_host' in datadump and datadump['rdr_host'] and not 'service_incoming_rdr' in datadump:
         datadump['service_incoming_rdr'] = True
       # Use some boring defaults
@@ -188,6 +190,6 @@
         'monitoring_group' : 'wleiden',
       }
-      for (key,value) in defaults.iteritems():
-        if not datadump.has_key(key):
+      for (key,value) in defaults.items():
+        if not key in datadump:
           datadump[key] = value
     f.close()
@@ -195,5 +197,5 @@
     # Sometimes getting version information is useless or harmfull, like in the pre-commit hooks
     if add_version_info:
-      p = subprocess.Popen([SVN, 'info', datadump['autogen_gfile']], stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
+      p = subprocess.Popen([SVN, 'info', datadump['autogen_gfile']], stderr=subprocess.STDOUT, stdout=subprocess.PIPE, universal_newlines=True)
       lines = p.communicate()[0].split('\n')
       if p.returncode == 0:
@@ -213,15 +215,15 @@
         datadump[key]['autogen_vlan_alias'] = False
 
-        datadump[key]['autogen_bridge_member'] = datadump[key].has_key('parent')
+        datadump[key]['autogen_bridge_member'] = 'parent' in datadump[key]
         datadump[key]['autogen_bridge'] = datadump[key]['autogen_ifbase'].startswith('bridge')
         datadump[key]['autogen_bridge_alias'] = datadump[key]['autogen_ifbase'].startswith('bridge') and '_alias' in key
 
-        if datadump[key].has_key('parent'):
-            if datadump[key].has_key('ip'):
+        if 'parent' in datadump[key]:
+            if 'ip' in datadump[key]:
                 raise ValueError("Interface bridge member cannot have IP assigned")
-            if datadump[key].has_key('dhcp') and datadump[key]['dhcp'] != False:
+            if 'dhcp' in datadump[key] and datadump[key]['dhcp'] != False:
                 raise ValueError("Interface bridge member cannot have DHCP set")
 
-        if datadump[key].has_key('ip'):
+        if 'ip' in datadump[key]:
           datadump[key]['autogen_gateway'] = datadump[key]['ip'].split('/')[0]
 
@@ -252,5 +254,5 @@
     datadump['autogen_item'] = item
 
-    datadump['autogen_domain'] = datadump['domain'] if datadump.has_key('domain') else 'wleiden.net.'
+    datadump['autogen_domain'] = datadump['domain'] if 'domain' in datadump else 'wleiden.net.'
     datadump['autogen_fqdn'] = datadump['nodename'] + '.' + datadump['autogen_domain']
     datadump_cache[item] = datadump.copy()
@@ -445,5 +447,5 @@
   output += "<h2>Connected To:</h2><ul>"
   (poel, errors) = make_relations()
-  for network, hosts in poel.iteritems():
+  for network, hosts in poel.items():
     if host in [x[0] for x in hosts]:
       if len(hosts) == 1:
@@ -474,9 +476,6 @@
 def parseaddr(s):
   """ Process IPv4 CIDR notation addr to a (binary) number """
-  f = s.split('.')
-  return (long(f[0]) << 24L) + \
-    (long(f[1]) << 16L) + \
-    (long(f[2]) << 8L) + \
-    long(f[3])
+  f = list(map(int, s.split('.')))
+  return ((f[0] << 24) +  (f[1] << 16) + (f[2] << 8) + (f[3]))
 
 
@@ -554,8 +553,8 @@
     ifname = datadump[iface_key]['autogen_ifbase']
     groupif = datadump[iface_key]['autogen_if_dhcp']
-    if not datadump[iface_key].has_key('comment'):
+    if not 'comment' in datadump[iface_key]:
       datadump[iface_key]['comment'] = None
 
-    if not datadump[iface_key].has_key('ip'):
+    if not 'ip' in datadump[iface_key]:
       continue
 
@@ -613,5 +612,5 @@
 
   # Output the blocks in groups
-  for ifname,value in sorted(dhcp_out.iteritems()):
+  for ifname,value in sorted(dhcp_out.items()):
       output += ("shared-network \"%s\" {\n" % ifname) + indent(''.join(value), 2).rstrip()  + '\n}\n\n'
   return output
@@ -637,5 +636,5 @@
 
   for iface_key in get_interface_keys(datadump):
-    if not datadump[iface_key].has_key('comment'):
+    if not 'comment' in datadump[iface_key]:
       datadump[iface_key]['comment'] = None
     output += "## %(autogen_ifname)s - %(comment)s\n" % datadump[iface_key]
@@ -667,5 +666,5 @@
 
 def make_interface_list(datadump):
-  if interface_list_cache.has_key(datadump['autogen_item']):
+  if datadump['autogen_item'] in interface_list_cache:
     return (interface_list_cache[datadump['autogen_item']])
   # lo0 configuration:
@@ -684,5 +683,5 @@
   masterip_used = False
   for iface_key in get_interface_keys(datadump):
-    if datadump[iface_key].has_key('ip') and datadump[iface_key]['ip'].startswith(datadump['masterip']):
+    if 'ip' in datadump[iface_key] and datadump[iface_key]['ip'].startswith(datadump['masterip']):
       masterip_used = True
       break
@@ -710,9 +709,9 @@
 
     # Flag dhclient is possible
-    if not dhclient_if.has_key(ifname) or dhclient_if[ifname] == False:
+    if not ifname in dhclient_if or dhclient_if[ifname] == False:
       dhclient_if[ifname] = dhcp_type(ifacedump) == DHCP_CLIENT
 
     # Ethernet address
-    if ifacedump.has_key('ether'):
+    if 'ether' in ifacedump:
         flags_if[ifname]['ether'] = ifacedump['ether']
 
@@ -721,7 +720,7 @@
 
     # Add interface IP to list
-    if ifacedump.has_key('ip'):
+    if 'ip' in ifacedump:
       item = (ifacedump['ip'], ifacedump['comment'])
-      if addrs_list.has_key(ifname):
+      if ifname in addrs_list:
         addrs_list[ifname].append(item)
       else:
@@ -740,5 +739,5 @@
         ifacedump['autogen_wlanmode'] = "ap"
 
-      if not ifacedump.has_key('channel'):
+      if not 'channel' in ifacedump:
         if ifacedump['type'] == '11a':
           ifacedump['channel'] = 36
@@ -747,10 +746,10 @@
 
       # Allow special hacks at the back like wds and stuff
-      if not ifacedump.has_key('extra'):
+      if not 'extra' in ifacedump:
         ifacedump['autogen_extra'] = 'regdomain ETSI country NL'
       else:
         ifacedump['autogen_extra'] = ifacedump['extra']
-        
-      ifacedump['autogen_ssid_hex'] = '0x' + ''.join(x.encode('hex') for x in ifacedump['ssid'])
+
+      ifacedump['autogen_ssid_hex'] = '0x' + codecs.encode(ifacedump['ssid'].encode('ascii'), 'hex').decode('ascii')
 
       output += "wlans_%(autogen_ifbase)s='%(autogen_ifname)s'\n" % ifacedump
@@ -797,8 +796,8 @@
   """ Generate configuration file '/etc/rc.conf.local' """
   item = datadump['autogen_item']
-  if rc_conf_local_cache.has_key(item):
+  if item in rc_conf_local_cache:
     return rc_conf_local_cache[item]
 
-  if not datadump.has_key('ileiden'):
+  if not 'ileiden' in datadump:
     datadump['autogen_ileiden_enable'] = False
   else:
@@ -856,5 +855,5 @@
   #
   list_ileiden_proxies="
-  {% for serviceid,item in autogen_ileiden_proxies.iteritems() -%}
+  {% for serviceid,item in autogen_ileiden_proxies.items() -%}
     {{ "%-16s"|format(serviceid) }} # {{ item.nodename }}
   {% endfor -%}
@@ -997,5 +996,5 @@
   # Print IP address which needs to be assigned over here
   output += "\n"
-  for iface,addrs in sorted(addrs_list.iteritems()):
+  for iface,addrs in sorted(addrs_list.items()):
     for addr, comment in sorted(addrs,key=lambda x: parseaddr(x[0].split('/')[0])):
       output += "# %s || %s || %s\n" % (iface, addr, comment)
@@ -1013,14 +1012,15 @@
     # Make sure the external address is always first as this is needed in the
     # firewall setup
-    addrs = sorted(
-        [x for x in addrs if not '0.0.0.0' in x[0]],
-        key=lambda x: x[0].split('.')[0], 
-        cmp=lambda x,y: cmp(1 if x == '172' else 0, 1 if y == '172' else 0)
-      )
-
+    addrs_tmp = []
+    for addr in addrs:
+        if addr[0].startswith('172'):
+            addrs_tmp.insert(0, addr)
+        else:
+            addrs_tmp.append(addr)
+    addrs = addrs_tmp
 
     idx_offset = 0
     # Set MAC is required
-    if flags_if[iface].has_key('ether'):
+    if 'ether' in flags_if[iface]:
       output += prefix + "ifconfig_%s='link %s'\n" % (iface, flags_if[iface]['ether'])
       output += prefix + "ifconfig_%s_alias0='inet %s'\n" % (iface, addrs[0][0])
@@ -1096,5 +1096,5 @@
   (poel, errors) = make_relations()
   table = []
-  for iface,addrs in sorted(addrs_list.iteritems()):
+  for iface,addrs in sorted(addrs_list.items()):
     if iface in ['lo0']:
       continue
@@ -1115,5 +1115,5 @@
     ifacedump = datadump[iface_key]
 
-    if not ifacedump.has_key('ns_ip'):
+    if not 'ns_ip' in ifacedump:
       continue
 
@@ -1230,5 +1230,5 @@
   autogen_ips = []
   (addrs_list, _, _, dhclient_if, _, extra_ouput) = make_interface_list(datadump)
-  for iface,addrs in sorted(addrs_list.iteritems()):
+  for iface,addrs in sorted(addrs_list.items()):
     for addr, comment in sorted(addrs,key=lambda x: parseaddr(x[0].split('/')[0])):
       if addr.startswith('172'):
@@ -1258,5 +1258,5 @@
     forward-addr: 208.67.220.220 # OpenDNS DNS B
 {% else -%}
-{%- for serviceid,item in autogen_ileiden_proxies.iteritems() %}
+{%- for serviceid,item in autogen_ileiden_proxies.items() %}
   {%- if loop.index <= 5 %}
     forward-addr: {{ "%-16s"|format(serviceid) }} # {{ item.nodename }}
@@ -1306,5 +1306,5 @@
   (addrs_list, vlan_list, bridge_list, dhclient_if, flags_if, extra_ouput) = make_interface_list(datadump)
   table = []
-  for iface,addrs in sorted(addrs_list.iteritems()):
+  for iface,addrs in sorted(addrs_list.items()):
     if iface in ['lo0']:
       continue
@@ -1391,5 +1391,5 @@
       output += "%s:\n" % iface_key
       for key,required in key_order:
-        if datadump[iface_key].has_key(key):
+        if key in datadump[iface_key]:
           output += "  %-11s: %s\n" % (key, format_yaml_value(datadump[iface_key][key]))
       output += "\n\n"
@@ -1406,10 +1406,10 @@
   output = generate_header(datadump, "#") if header else ''
 
-  for key in datadump.keys():
+  for key in list(datadump.keys()):
     if key.startswith('autogen_'):
       del datadump[key]
     # Interface autogen cleanups
     elif type(datadump[key]) == dict:
-      for key2 in datadump[key].keys():
+      for key2 in list(datadump[key].keys()):
         if key2.startswith('autogen_'):
           del datadump[key][key2]
@@ -1470,5 +1470,5 @@
     else:
       assert False, "Config not found!"
-  except IOError, e:
+  except IOError as e:
     output += "[ERROR] Config file not found"
   return output
@@ -1502,6 +1502,6 @@
 
   # Update repository if requested
-  form = urlparse.parse_qs(environ['QUERY_STRING']) if environ.has_key('QUERY_STRING') else None
-  if form and form.has_key("action") and "update" in form["action"]:
+  form = urllib.parse.urlparse.parse_qs(environ['QUERY_STRING']) if QUERY_STRING in environ else None
+  if form and 'action' in form and 'update' in form['action']:
     refresh_rate = 5
     output = "[INFO] Updating subverion, please wait...\n"
@@ -1510,5 +1510,5 @@
     output += subprocess.Popen([SVN, 'up', "%s/.." % NODE_DIR], stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate()[0]
     new_version = subprocess.Popen([SVNVERSION, '-c', "%s/.." % NODE_DIR], stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate()[0]
-    if old_version != new_version or (environ.has_key('QUERY_STRING') and 'force' in environ['QUERY_STRING']):
+    if old_version != new_version or ('QUERY_STRING' in environ and 'force' in environ['QUERY_STRING']):
         try:
             generate_static(CACHE_DIR, False)
@@ -1575,7 +1575,7 @@
     fqdn = datadump['nodename']
  
-    if datadump.has_key('rdr_host'):
+    if 'rdr_host' in datadump:
       remote_target = datadump['rdr_host']
-    elif datadump.has_key('remote_access') and datadump['remote_access']:
+    elif 'remote_access' in datadump and datadump['remote_access']:
       remote_target = datadump['remote_access'].split(':')[0]
     else:
@@ -1610,5 +1610,5 @@
         cidr = int(cidr)
         addr = addr & ~((1 << (32 - cidr)) - 1)
-        if pool.has_key(addr):
+        if addr in pool:
           pool[addr] += [(iface_name, fqdn, ip)]
         else:
@@ -1624,5 +1624,5 @@
 
   # Automatic naming convention of interlinks namely 2 + remote.lower()
-  for (key,value) in pool.iteritems():
+  for (key,value) in pool.items():
     # Make sure they are sorted from low-ip to high-ip
     value = sorted(value, key=lambda x: parseaddr(x[2]))
@@ -1674,5 +1674,5 @@
     k, items = line.items()[0]
     if type(items) == dict:
-      if items.has_key('reverse'):
+      if 'reverse' in items:
         reverse = items['reverse']
         items = items['a']
@@ -1724,12 +1724,12 @@
   f.write(dns_header % details)
 
-  for host,items in wleiden_zone.iteritems():
+  for host,items in wleiden_zone.items():
     for ip,reverse in items:
       if ip not in ['0.0.0.0']:
         f.write("%s.wleiden.net. IN A %s\n" % (host.lower(), ip))
-  for source,dest in wleiden_cname.iteritems():
+  for source,dest in wleiden_cname.items():
     dest = dest if dest.endswith('.') else dest + ".wleiden.net."
     f.write("%s.wleiden.net. IN CNAME %s\n" % (source.lower(), dest.lower()))
-  for source, dest in wleiden_raw.iteritems():
+  for source, dest in wleiden_raw.items():
     f.write("%s.wleiden.net. %s\n" % (source, dest))
   f.close()
@@ -1743,5 +1743,5 @@
     #XXX: Not effient, fix to proper data structure and do checks at other
     # stages
-    for host,items in wleiden_zone.iteritems():
+    for host,items in wleiden_zone.items():
       for ip,reverse in items:
         if not reverse:
@@ -1756,5 +1756,5 @@
 
 def usage():
-  print """Usage: %(prog)s <argument>
+  print("""Usage: %(prog)s <argument>
 Argument:
 \tcleanup                      =  Cleanup all YAML files to specified format
@@ -1783,5 +1783,5 @@
   VIEW differences and VERIFY all are OK:
   $ diff -urI 'Generated' -r /tmp/pre /tmp/post
-""" % { 'prog' : sys.argv[0], 'files'  : '|'.join(files) }
+""" % { 'prog' : sys.argv[0], 'files'  : '|'.join(files) })
   exit(0)
 
@@ -1814,5 +1814,5 @@
 def fix_conflict(left, right, default='i'):
   while True:
-    print "## %-30s | %-30s" % (left, right)
+    print("## %-30s | %-30s" % (left, right))
     c = raw_input("## Solve Conflict (h for help) <l|r|e|i|> [%s]: " % default)
     if not c:
@@ -1828,5 +1828,5 @@
       return None
     else:
-      print "#ERROR: '%s' is invalid input (left, right, edit or ignore)!" % c
+      print("#ERROR: '%s' is invalid input (left, right, edit or ignore)!" % c)
 
 
@@ -1834,7 +1834,7 @@
 def print_cgi_response(response_headers, output):
   for header in response_headers:
-     print "%s: %s" % header
-  print
-  print output
+     print("%s: %s" % header)
+  print("")
+  print(output)
 
 
@@ -1843,5 +1843,5 @@
   """Hard working sub"""
   # Allow easy hacking using the CLI
-  if not os.environ.has_key('REQUEST_URI'):
+  if not os.environ.get('REQUEST_URI', None):
     if len(sys.argv) < 2:
       usage()
@@ -1883,8 +1883,8 @@
         node = sys.argv[2]
       except IndexError:
-        print "Invalid argument"
+        print("Invalid argument")
         exit(1)
       except IOError as e:
-        print e
+        print(e)
         exit(1)
 
@@ -1898,5 +1898,5 @@
       for config in gen_files:
          logger.info("## Generating %s %s", node, config)
-         print generate_config(node, config, datadump)
+         print(generate_config(node, config, datadump))
     elif sys.argv[1] == "test-cgi":
       os.environ['REQUEST_URI'] = "/".join(['config'] + sys.argv[2:])
@@ -1927,7 +1927,7 @@
         for iface_key in sorted([elem for elem in datadump.keys() if elem.startswith('iface_')]):
           ifacedump = datadump[iface_key]
-          if ifacedump.has_key('mode') and ifacedump['mode'] == 'ap-wds':
+          if 'mode' in ifacedump and ifacedump['mode'] == 'ap-wds':
             ifacedump['nodename'] = datadump['nodename']
-            if not ifacedump.has_key('channel') or not ifacedump['channel']:
+            if not 'channel' in ifacedump or not ifacedump['channel']:
               ifacedump['channel'] = 0
             sql = """INSERT INTO links (node_id, type, ssid, protocol, channel, status)
@@ -1938,10 +1938,10 @@
             datadump = get_yaml(host)
             if datadump.get('service_proxy_normal', False) or datadump.get('service_proxy_ileiden', False):
-                print textwrap.dedent("""\
+                print(textwrap.dedent("""\
                     ++ wleiden-gw-%(nodename)s
                     menu = %(nodename)s.gw
                     title = Wireless Leiden gateway %(nodename)s.gw.wleiden.net.
                     host = %(nodename)s.gw.wleiden.net.
-                    """ % datadump)
+                    """ % datadump))
     elif sys.argv[1] == "nagios-export":
       try:
@@ -1963,5 +1963,5 @@
         ip2host[datadump['masterip']] = datadump['autogen_fqdn']
         for iface in get_interface_keys(datadump):
-          if datadump[iface].has_key('autogen_gateway'):
+          if 'autogen_gateway' in datadump[iface]:
             ip2host[datadump[iface]['autogen_gateway']] = datadump['autogen_fqdn']
 
@@ -1979,5 +1979,5 @@
               parents[ip2host[ip]].append(ip2host[stack[-1]])
             except KeyError as e:
-              print >> stderr, "# Unable to find %s in configuration files" % e.args[0]
+              print("# Unable to find %s in configuration files" % e.args[0])
             stack.append(ip)
           elif prev_depth > depth:
@@ -1987,5 +1987,5 @@
               parents[ip2host[ip]].append(ip2host[stack[-1]])
             except KeyError as e:
-              print >> stderr, "# Unable to find %s in configuration files" % e.args[0]
+              print("# Unable to find %s in configuration files" % e.args[0])
 
 
@@ -2003,5 +2003,5 @@
       }  
 
-      print '''\
+      print('''\
 define host {
         name                  wleiden-node           ; Default Node Template
@@ -2075,7 +2075,7 @@
 # TDB: Advanced local passive checks
 # /usr/local/libexec/nagios/check_by_ssh
-''' % params
-
-      print '''\
+''' % params)
+
+      print('''\
 # Service Group, not displayed by default        
 define hostgroup {
@@ -2105,8 +2105,8 @@
         check_command         check_dns_wl!"www.wirelessleiden.nl"
 }
-'''
+''')
 
       if heavy_load:
-        print '''\
+        print('''\
 define service {
         use                   wleiden-service
@@ -2143,12 +2143,12 @@
         check_command         check_snmp_disk
 }
-'''
+''')
       for node in get_hostlist():
         datadump = get_yaml(node)
         if not datadump['status'] == 'up':
           continue
-        if not hostgroup_details.has_key(datadump['monitoring_group']):
+        if not datadump['monitoring_group'] in hostgroup_details:
            hostgroup_details[datadump['monitoring_group']] = datadump['monitoring_group']
-        print '''\
+        print('''\
 define host {
         use                   wleiden-node,host-pnp
@@ -2157,20 +2157,20 @@
         address               %(masterip)s
         hostgroups            srv_hybrid,%(monitoring_group)s\
-''' % datadump
+''' % datadump)
         if (len(parents[datadump['autogen_fqdn']]) > 0) and parents[datadump['autogen_fqdn']][0] != 'root':
-          print '''\
+          print('''\
         parents               %(parents)s\
-''' % { 'parents' : parents[datadump['autogen_fqdn']][0] }
-        print '''\
+''' % { 'parents' : parents[datadump['autogen_fqdn']][0] })
+        print('''\
 }
-'''
-
-
-      for name,alias in hostgroup_details.iteritems(): 
-        print '''\
+''')
+
+
+      for name,alias in hostgroup_details.items(): 
+        print('''\
 define hostgroup {
        hostgroup_name         %s
        alias                  %s
-} ''' % (name, alias)      
+} ''' % (name, alias))
 
 
@@ -2180,5 +2180,5 @@
         datadump = get_yaml(node)
         hosts[datadump['nodename']] = datadump
-      print yaml.dump(hosts)
+      print(yaml.dump(hosts))
 
     elif sys.argv[1] == "dns":
@@ -2196,7 +2196,7 @@
 
       (poel, errors) = make_relations()
-      print "\n".join(["# WARNING: %s" % x for x in errors])
-
-      for host,datadump in datadumps.iteritems():
+      print("\n".join(["# WARNING: %s" % x for x in errors]))
+
+      for host,datadump in datadumps.items():
         try:
           # Convert all yes and no to boolean values
@@ -2230,18 +2230,18 @@
                 datadump[iface_key]['mode'] = 'ap'
               # Wireless Leiden SSID have an consistent lowercase/uppercase
-              if datadump[iface_key].has_key('ssid'):
+              if 'ssid' in datadump[iface_key]:
                 ssid = datadump[iface_key]['ssid']
                 prefix = 'ap-WirelessLeiden-'
                 if ssid.lower().startswith(prefix.lower()):
                   datadump[iface_key]['ssid'] = prefix + ssid[len(prefix)].upper() + ssid[len(prefix) + 1:] 
-              if datadump[iface_key].has_key('ns_ip') and not datadump[iface_key].has_key('mode'):
+              if 'ns_ip' in datadump[iface_key] and not 'mode' in  datadump[iface_key]:
                 datadump[iface_key]['mode'] = 'autogen-FIXME'
-              if not datadump[iface_key].has_key('comment'):
+              if not 'comment' in datadump[iface_key]:
                 datadump[iface_key]['comment'] = 'autogen-FIXME'
 
-              if datadump[iface_key].has_key('ns_mac'):
+              if 'ns_mac' in datadump[iface_key]:
                 datadump[iface_key]['ns_mac'] = datadump[iface_key]['ns_mac'].lower()
 
-              if datadump[iface_key]['comment'].startswith('autogen-') and datadump[iface_key].has_key('comment'):
+              if 'comment' in datadump[iface_key] and datadump[iface_key]['comment'].startswith('autogen-'):
                 datadump[iface_key] = datadump[iface_key]['desc']
 
@@ -2261,5 +2261,5 @@
               # See: https://en.wikipedia.org/wiki/List_of_WLAN_channels
               channels_at_2400Mhz = (1,6,11)
-              if datadump[iface_key]['type'] == '11g' and datadump[iface_key].has_key('channel'):
+              if datadump[iface_key]['type'] == '11g' and 'channel' in datadump[iface_key]:
                 datadump[iface_key]['channel'] = int(datadump[iface_key]['channel'])
                 if datadump[iface_key]['channel'] not in channels_at_2400Mhz:
@@ -2267,5 +2267,5 @@
 
               # Mandatory interface keys
-              if not datadump[iface_key].has_key('status'):
+              if not 'status' in datadump[iface_key]:
                 datadump[iface_key]['status'] = 'planned'
 
@@ -2279,9 +2279,9 @@
 
               # Making sure description works
-              if datadump[iface_key].has_key('desc'):
+              if 'desc' in datadump[iface_key]:
                 if datadump[iface_key]['comment'].lower() == datadump[iface_key]['desc'].lower():
                   del datadump[iface_key]['desc']
                 else:
-                  print "# ERROR: At %s - %s" % (datadump['nodename'], iface_key)
+                  print("# ERROR: At %s - %s" % (datadump['nodename'], iface_key))
                   response = fix_conflict(datadump[iface_key]['comment'], datadump[iface_key]['desc'])
                   if response:
@@ -2334,10 +2334,10 @@
        output = datadump['autogen_fqdn'] if use_fqdn else system
        if sys.argv[2] == "all":
-         print output
+         print(output)
        elif datadump['status'] == sys.argv[2]:
-         print output
+         print(output)
     elif sys.argv[1] == "create":
       if sys.argv[2] == "network.kml":
-        print make_network_kml.make_graph()
+        print(make_network_kml.make_graph())
       elif sys.argv[2] == "host-ips.txt":
         for system in get_hostlist():
@@ -2346,13 +2346,13 @@
           for ifkey in get_interface_keys(datadump):
             ips.append(datadump[ifkey]['ip'].split('/')[0])
-          print system, ' '.join(ips)
+          print(system, ' '.join(ips))
       elif sys.argv[2] == "host-pos.txt":
         for system in get_hostlist():
           datadump = get_yaml(system)
-          print system, datadump['rdnap_x'], datadump['rdnap_y']
+          print(system, datadump['rdnap_x'], datadump['rdnap_y'])
       elif sys.argv[2] == "nodeplanner.json":
-        print make_network_kml.make_nodeplanner_json()
+        print(make_network_kml.make_nodeplanner_json())
       elif sys.argv[2] == 'ssh_config':
-        print  '''
+        print('''
 Host *.wleiden.net
   User root
@@ -2360,8 +2360,8 @@
 Host 172.16.*.*
   User root
-'''
+''')
         for system in get_hostlist():
           datadump = get_yaml(system)
-          print '''\
+          print('''\
 Host %s
   User root
@@ -2375,5 +2375,5 @@
 Host %s
   User root
-''' % (system, system.lower(), datadump['nodename'], datadump['nodename'].lower())
+''' % (system, system.lower(), datadump['nodename'], datadump['nodename'].lower()))
       else:
         usage()
@@ -2388,6 +2388,6 @@
       response_headers, output = process_cgi_request()
     except:
-      print ''
-      print ''
+      print('')
+      print('')
       raise
 
