This discussion has been locked. The information referenced herein may be inaccurate due to age, software updates, or external references.
You can no longer post new replies to this discussion. If you have a similar question you can start a new discussion in this forum.

Get the next available subnet of a particular size within a supernet

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?

Parents
  • 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

  • Hi,

    Do we have any option available now ?

Reply Children
No Data