chiark / gitweb /
make-secnet-sites: Switch to `ipaddress' from `ipaddr'
[secnet.git] / make-secnet-sites
index 395066e8b5f2f07eaf6cc4e5a668d804b8d2a993..158f5b36c8229b170969fe966de4cb23d4c84731 100755 (executable)
@@ -46,12 +46,13 @@ no-suppress-args
 cd ~/secnet/sites-test/
 execute ~/secnet/make-secnet-sites.py -u vpnheader groupfiles sites
 
-This program is part of secnet. It relies on the "ipaddr" library from
-Cendio Systems AB.
+This program is part of secnet.
 
 """
 
 from __future__ import print_function
+from __future__ import unicode_literals
+from builtins import int
 
 import string
 import time
@@ -60,7 +61,7 @@ import os
 import getopt
 import re
 
-import ipaddr
+import ipaddress
 
 # entry 0 is "near the executable", or maybe from PYTHONPATH=.,
 # which we don't want to preempt
@@ -70,6 +71,14 @@ import ipaddrset
 
 VERSION="0.1.18"
 
+from sys import version_info
+if version_info.major == 2:  # for python2
+    import codecs
+    sys.stdin = codecs.getreader('utf-8')(sys.stdin)
+    sys.stdout = codecs.getwriter('utf-8')(sys.stdout)
+    import io
+    open=lambda f,m='r': io.open(f,m,encoding='utf-8')
+
 # Are we being invoked from userv?
 service=0
 # If we are, which group does the caller want to modify?
@@ -98,7 +107,7 @@ else:
                        sys.exit(1)
                ugs=os.environ["USERV_GROUP"]
                ok=0
-               for i in string.split(ugs):
+               for i in ugs.split():
                        if group==i: ok=1
                if not ok:
                        print("caller not in group %s"%group)
@@ -138,7 +147,7 @@ def listof(subtype):
 class single_ipaddr (basetype):
        "An IP address"
        def __init__(self,w):
-               self.addr=ipaddr.IPAddress(w[1])
+               self.addr=ipaddress.ip_address(w[1])
        def __str__(self):
                return '"%s"'%self.addr
 
@@ -147,7 +156,7 @@ class networks (basetype):
        def __init__(self,w):
                self.set=ipaddrset.IPAddressSet()
                for i in w[1:]:
-                       x=ipaddr.IPNetwork(i,strict=True)
+                       x=ipaddress.ip_network(i,strict=True)
                        self.set.append([x])
        def __str__(self):
                return ",".join(map((lambda n: '"%s"'%n), self.set.networks()))
@@ -191,7 +200,7 @@ class boolean (basetype):
 class num (basetype):
        "A decimal number"
        def __init__(self,w):
-               self.n=string.atol(w[1])
+               self.n=int(w[1])
        def __str__(self):
                return '%d'%(self.n)
 
@@ -199,7 +208,7 @@ class address (basetype):
        "A DNS name and UDP port number"
        def __init__(self,w):
                self.adr=w[1]
-               self.port=string.atoi(w[2])
+               self.port=int(w[2])
                if (self.port<1 or self.port>65535):
                        complain("invalid port number")
        def __str__(self):
@@ -208,7 +217,7 @@ class address (basetype):
 class rsakey (basetype):
        "An RSA public key"
        def __init__(self,w):
-               self.l=string.atoi(w[1])
+               self.l=int(w[1])
                self.e=w[2]
                self.n=w[3]
        def __str__(self):
@@ -256,6 +265,7 @@ class level:
        allow_properties={}
        require_properties={}
        def __init__(self,w):
+               self.type=w[0]
                self.name=w[1]
                self.properties={}
                self.children={}
@@ -299,7 +309,7 @@ class vpnlevel(level):
                w.write("\n")
                self.indent(w,ind+2)
                w.write("all-sites %s;\n"%
-                       string.join(self.children.keys(),','))
+                       ','.join(self.children.keys()))
                self.indent(w,ind)
                w.write("};\n")
 
@@ -319,9 +329,9 @@ class locationlevel(level):
                self.indent(w,ind)
                # The "h=h,self=self" abomination below exists because
                # Python didn't support nested_scopes until version 2.1
-               w.write("%s %s;\n"%(self.name,string.join(
+               w.write("%s %s;\n"%(self.name,','.join(
                        map(lambda x,h=h,self=self:
-                               h+"/"+x,self.children.keys()),',')))
+                               h+"/"+x,self.children.keys()))))
 
 class sitelevel(level):
        "Site level (i.e. a leafnode) in the configuration hierarchy"
@@ -398,7 +408,7 @@ def set_property(obj,w):
 def pline(i,allow_include=False):
        "Process a configuration file line"
        global allow_defs, obstack, root
-       w=string.split(i.rstrip('\n'))
+       w=i.rstrip('\n').split()
        if len(w)==0: return [i]
        keyword=w[0]
        current=obstack[len(obstack)-1]
@@ -482,7 +492,7 @@ def outputsites(w):
        w.write("# secnet sites file autogenerated by make-secnet-sites "
                +"version %s\n"%VERSION)
        w.write("# %s\n"%time.asctime(time.localtime(time.time())))
-       w.write("# Command line: %s\n\n"%string.join(sys.argv))
+       w.write("# Command line: %s\n\n"%' '.join(sys.argv))
 
        # Raw VPN data section of file
        w.write(prefix+"vpn-data {\n")
@@ -497,9 +507,9 @@ def outputsites(w):
        w.write("};\n")
 
        # Flattened list of sites
-       w.write(prefix+"all-sites %s;\n"%string.join(
+       w.write(prefix+"all-sites %s;\n"%",".join(
                map(lambda x:"%svpn/%s/all-sites"%(prefix,x),
-                       root.children.keys()),","))
+                       root.children.keys())))
 
 line=0
 file=None
@@ -516,7 +526,7 @@ def live(n):
        return 0
 def delempty(n):
        "Delete nodes that have no leafnode children"
-       for i in n.children.keys():
+       for i in list(n.children.keys()):
                delempty(n.children[i])
                if not live(n.children[i]):
                        del n.children[i]