Is there any way in the API or through SQL queries to retrieve the next available subnet in a supernet? For example, if I want to know the next free /28 subnet in a 10.10.10.0/24, how would I do that?
Anyone? tdanner ?
This is my really, really nasty way of coming up with an aswer for now, in case anyone else is interested. It takes the entire supernet's worth of IP address entries into memory in order to accomplish the task, so don't try this with a big subnet (I'm using /16's and it taking a little bit.) I'm really hoping for an elegant solution from Solarwinds for this though!
def getNextAvailableSubnet(supernet: ip.IPv4Network, size: int, numSubnets: int = 1): """Retrieves the next available subnet of a particular size within a given supernet. Keyword Args: supernet (ip.IPv4Network): The address of the supernet size (int): The CIDR size of the new network numSubnets (int): The number of subnets to find Raises: LookupError: If the supernet doesn't exist LookupError: If no valid subnet exists ValueError: If an incorrect size or numSubnets was supplied Returns: List: A list of IPv4Network objects representing the next free subnets """ if numSubnets <= 0: raise ValueError('An unusable number of networks was supplied ({})'.format(numSubnets)) if size <= supernet.prefixlen: raise ValueError('A new network CIDR was supplied that is larger than the parent CIDR') # Make sure the supernet exists and get its internal ID number try: supernetID = getSubnetAttributes(net=supernet) except LookupError as err: # The supernet doesn't exist print(err) raise def getNextNetwork(addrs): newNet = None # Iterate over the list of possible subnets and check if each one has been used yet. for net in supernet.subnets(new_prefix=size): if not net.network_address in supernetAddresses: # We found a potential candidate, now check if it really is fully available validatedAddr = True for addr in net: addr = addr.compressed # print('{} in supernetAddresses: {}'.format(addr, addr in supernetAddresses)) if addr in supernetAddresses: # Check all addresses to see if they are used validatedAddr = False break if validatedAddr: # A valid address was found # print('A valid address was found') newNet = net break # Error out if nothing was found if not newNet: raise LookupError('No valid subnet was found') # print('Subnet Found: ' + newNet.exploded) return newNet # This query gets a list of all IP addresses within the supernet # For performance reasons, please don't try this on something bigger # than a /16 supernetAddresses = swis.query( "SELECT IPAddress "\ "FROM IPAM.IPNode "\ "WHERE "\ " IPAddressN >= '{}' AND "\ " IPAddressN <= '{}' ".format( IPtoGUID(supernet.network_address), IPtoGUID(supernet.broadcast_address), ) )['results'] supernetAddresses = [i['IPAddress'] for i in supernetAddresses] results = [] # Find the next available networks for x in range(numSubnets): nextNet = getNextNetwork(supernetAddresses) # Mark the found network as used in our result set supernetAddresses.append(nextNet.network_address.compressed) print('Got ' + nextNet.exploded) results.append(nextNet) return results
I passed your message to an IPAM expert. He's out of the office until Tuesday though.
Hi, wyko.ter.haar,
Currently, there is no API to do this easily. However, it should be possible with a single SWQL query - I will investigate more deeply if this is possible this week