#python
#python
Вопрос:
Мне было интересно, есть ли хороший способ найти следующий доступный пробел для создания сетевого блока, учитывая список существующих?
Например, у меня есть эти сети в моем списке:
[
'10.0.0.0/24',
'10.0.0.0/20',
'10.10.0.0/20',
]
и затем кто-то приходит и спрашивает: «У вас достаточно места для 1/22 для меня?»
Я хотел бы иметь возможность предложить что-то вроде: «Вот пробел: x.x.x.x / 22» (x.x.x.x — это то, что предшествует 10.0.0.0)
или
«Вот пробел: x.x.x.x / 22» (x.x.x.x — это что-то среднее между 10.0.0.255 и 10.10.0.0)
или
«Вот пробел: x.x.x.x / 22» (x.x.x.x — это то, что появляется после 10.10.15.255)
Я был бы очень признателен за любые предложения.
Ответ №1:
ipaddress
Библиотека хороша для такого варианта использования. Вы можете использовать IPv4Network
класс для определения диапазонов подсетей, а IPv4Address
объекты, которые он может возвращать, могут быть преобразованы в целые числа для сравнения.
Что я делаю ниже:
- Установите заданный список как список
IPv4Network
s - Определите размер блока, который мы ищем
- Выполните итерацию по списку, вычисляя объем пространства между последовательными блоками и проверяя, подходит ли наш требуемый блок.
Вы также можете вернуть an IPv4Network
со встроенной в него подсетью вместо an IPv4Address
, но я оставлю это как упражнение для читателя.
from ipaddress import IPv4Network, IPv4Address
networks = [
IPv4Network('10.0.0.0/24')
IPv4Network('10.0.0.0/20')
IPv4Network('10.0.10.0/20')
]
wanted = 22
wanted_size = 2 ** (32 - wanted) # number of addresses in a /22
space_found = None
for i in range(1, len(networks):
previous_network_end = int(networks[i-1].network_address int(networks[i-1].hostmask))
next_network_start = int(networks[i].network_address)
free_space_size = next_network_start - previous_network_end
if free_space_size >= wanted_size:
return IPv4Address(networks[i-1] 1) # first available address
Комментарии:
1. Это действительно правильно. Могу ли я добавить сортировку и обрезку списка подсетей из списка перед циклом, было бы хорошей идеей. Очень признателен, парень в зеленом плаще.
2. еще 1 быстрый комментарий (не требующий от вас решения): если у меня есть этот список
[IPv4Network('10.0.0.0/8'), IPv4Network('100.0.0.0/26'), IPv4Network('191.0.0.0/8'), IPv4Network('191.1.0.0/24'), IPv4Network('192.0.0.0/24')]
, и я ищу пробелы / 22, я бы получил 11.0.0.0, 100.0.0.64, 191.1.1.0 в качестве следующих доступных начальных адресов разрыва. Но 100.0.0.64 и 191.1.1.0 не могут быть сетевыми адресами для / 22, поэтому вам все равно придется поработать, чтобы выяснить, можем ли мы выделить / 22 с этими пробелами. но это еще одна забавная проблема, которую нужно решить. та3. Да, для этого вам нужно будет ввести дополнительные проверки и «ускорить» до следующей возможной
/22
начальной точки. Все равно должно быть выполнимо — будет один вызов функции, когда вы определяетеprevious_network_end
, что вам нужно будет написать