import ipaddress ## import netaddr from pyroute2 import IPRoute ## from . import utils from . import radvd class IP(object): type = None version = None _ip = ipaddress.ip_address _net = ipaddress.ip_network _net_ip = netaddr.IPAddress _net_net = netaddr.IPNetwork def __init__(self, ip, prefix, *args, **kwargs): self.str = ip self.prefix = int(prefix) self.net_ip = self._net_ip(self.str) self.net_net = self._net_net('{0}/{1}'.format(self.str, self.prefix)) def _ext_init(self): self.ip = self._ip(self.str) self.net = self._net('{0}/{1}'.format(self.str, self.prefix), strict = False) return(None) class IP4(IP): type = 'IPv4' version = 4 _ip = ipaddress.IPv4Address _net = ipaddress.IPv4Network def __init__(self, ip, prefix, *args, **kwargs): super().__init__(ip, prefix, *args, **kwargs) self._ext_init() class IP6(IP): type = 'IPv6' version = 6 _ip = ipaddress.IPv6Address _net = ipaddress.IPv6Network def __init__(self, ip, prefix, *args, **kwargs): super().__init__(ip, prefix, *args, **kwargs) self._ext_init() self.alloc_block = netaddr.SubnetSplitter(self.net_net) class Assignment(object): def __init__(self, assign_xml, radvd = False, dns = False): self.xml = assign_xml self.do_radvd = radvd self.radvd_dns = dns self.iface = None self.iface_idx = None self.iface_addrs = [] self.iface_blocks = [] self.alloc = None # This must be set externally to a mapped Allocation instance self.alloc_id = None self.prefix = None self.alloc_block = None self.parse() def _alloc(self): self.alloc_id = int(self.xml.attrib['alloc'].strip()) return(None) def _iface(self): _iface_txt = self.xml.attrib['iface'].strip() self.iface = _iface_txt.strip() ipr = IPRoute() self.iface_idx = ipr.link_lookup(ifname = self.iface)[0] ipr.close() return(None) def _prefix(self): self.prefix = int(self.xml.attrib.get('prefix', 64).strip()) return(None) def parse(self): self._iface() self._alloc() self._prefix() return(None) def parse_alloc(self): self.alloc_block = self.alloc.ip.alloc_block self.iface_blocks = self.alloc_block.extract_subnet(self.prefix, count = 1) for i in self.iface_blocks: self.iface_addrs.append(IP6(str(next(i.iter_hosts())), 128)) return(None) class Allocation(object): def __init__(self, alloc_net): _ip, _prefix = alloc_net.split('/') self.id = int(_prefix.strip()) self.prefix = self.id self.ip = IP6(_ip.strip(), self.prefix) class Tunnel(object): def __init__(self, tun_xml, he_tunnel, creds): self.xml = tun_xml self.creds = creds self.he = he_tunnel self.update_key = self.he.creds.password self.id = None self.client = None self.server = None self.endpoint = None self.radvd = None self.enable_radvd = None self.radvd_dns = None self.allocations = {} # This is a dict of {}[alloc.id] = Allocation obj self.assignments = [] # This is a list of Assignment objs self.parse() def _allocations(self): self.allocations = self.he.allocations return(None) def _assignments(self): _assigns_xml = self.xml.find('assignments') self.enable_radvd = utils.xml2bool(_assigns_xml.attrib.get('radvd', 'false')) self.radvd_dns = utils.xml2bool(_assigns_xml.attrib.get('radvdDns', 'false')) for _assign_xml in _assigns_xml.findall('assign'): assign = Assignment(_assign_xml, radvd = self.enable_radvd, dns = self.radvd_dns) assign.alloc = self.allocations[assign.alloc_id] assign.parse_alloc() self.assignments.append(assign) return(None) def _client(self): self.client = self.he.client return(None) def _creds(self): self.creds_id = self.xml.attrib['creds'].strip() return(None) def _endpoint(self): self.endpoint = self.he.endpoint return(None) def _id(self): self.id = int(self.xml.attrib['id'].strip()) return(None) def _radvd(self): self.radvd = radvd.RADVD() self.radvd.conf.generate(self.assignments) return(None) def _server(self): self.server = self.he.server return(None) def parse(self): self._id() self._creds() self._client() self._server() self._endpoint() self._allocations() self._assignments() self._radvd() return(None)