def choose_ip_addr(request): if 'network' not in request.GET: servers = list( Query( {'servertype': 'route_network'}, ['hostname', 'intern_ip'], ['hostname'], )) return TemplateResponse(request, 'servershell/choose_ip_addr.html', {'servers': servers}) network = request.GET['network'] servers = list( Query( { 'servertype': Any(*(s.servertype_id for s in Servertype.objects.filter( ip_addr_type='network'))), 'intern_ip': ContainedOnlyBy(network), }, ['hostname', 'intern_ip'], ['hostname'], )) if servers: return TemplateResponse(request, 'servershell/choose_ip_addr.html', {'servers': servers}) network_query = Query({'intern_ip': network}, ['intern_ip']) return TemplateResponse( request, 'servershell/choose_ip_addr.html', {'ip_addrs': islice(network_query.get_free_ip_addrs(), 1000)})
def get_free_ip_addrs(self): networks = list(self.get_network_ip_addrs()) if not networks: raise DatasetError('No networks') # Index host and network addresses separately used_hosts = set() used_networks = list() for obj in type(self)( { 'intern_ip': Any(*(ContainedOnlyBy(n) for n in networks)), }, ['intern_ip']): addr = obj['intern_ip'] if isinstance(addr, (IPv4Address, IPv6Address)): used_hosts.add(addr) else: assert isinstance(addr, (IPv4Network, IPv6Network)) used_networks.append(addr) # Now, we are ready to return. for network in networks: for host in network.hosts(): for other_network in used_networks: if host in other_network: break else: if host not in used_hosts: yield host