Я решил поставить DHCP сервер на Linux, но была небольшая проблема, у нас не было текущего DHCP сервера (все ip были статическими), карты сети, списка ip и mac адресов. Я сканировал сеть получил список mac и ip, распечатал и мы с коллегой пошли записывать фамилии тех, у кого эти mac адреса. Потом я внес все это в таблицу excel (таблица 1).
Таблица 1 | ||||
Кабинет |
Имя ПК |
ФИО |
IP |
MAC |
1 |
1-1 |
Иванов |
192.168.0.10 |
00:00:00:00:00:00 |
Полгода спустя я все-таки решил заняться установкой DHCP сервера. Для резервирования ip надо было прописать это все в config. Но из-за того, что в таблице было примерно 75 строк с mac, ip, фамилиями, было как-то лень прописывать это все вручную и я решил создать python скрипт, который сам все это сделает.
Пример файла dhcp.conf:
host Lastname {
hardware ethernet 00:00:00:00:00:00;
fixed-address 192.168.0.1;
}
Lastname - Фамилия пользователя.
hardware ethernet - MAC адрес.
fixed-address - ip адрес для резервирования.
Текущая таблица не подходила из-за того, что ФИО в ней полно. Я создал новую таблицу (таблица 2) и переписал фамилии на латиницу.
Таблица 2 | ||
name |
mac |
ip |
Ivanov |
00:00:00:00:00:00 |
192.168.0.10 |
Далее я начал писать скрипт на python, получилось 3 варианта скрипта.
Библиотеки xlrd и pandas 1строчку в таблице excel не включают в список считая ее оглавлением столбцов.
Вариант 1
Хотел использовать библиотеку pandas но она не завелась и решил использовать списки. Для того что бы заключить все строки в скобки воспользовался инструментом excel. С протяжкой формулы.
="'"&A1&"'," - для столбца name
="'"&B1&"'," - для столбца mac
="'"&C1&"'," - для столбца ip
Получилось так (таблица 3).
Таблица 3 | ||
name |
mac |
ip |
'Ivanov' |
'00:00:00:00:00:00', |
'192.168.0.10' |
Далее внес это все в списки и просто пробегался циклом.
mac=['00:00:00:00:00:00', ...]
ip=['192.168.0.10', ...]
name=['Ivanov', ...]
def write():
with open("dhcp.conf", 'w') as f:
for i,j,k in zip(Config.name, Config.mac, Config.ip):
f.write(f"host {i}" + " {\n\thardware ethernet" + f" {j};" + "\n\tfixed-address " + f"{k};" + "\n}\n\n")
if __name__ == '__main__':
write()
Создаем 3 списка:
mac - для mac адресов
ip -для ip адресов
name - для фамилий пользователей
mac=['00:00:00:00:00:00', ...]
ip=['192.168.0.10', ...]
name=['Ivanov', ...]
Создаем функцию:
def write():
Открываем файл dhcp.conf в режиме записи:
with open("dhcp.conf", 'w') as f:
Проходимся циклом по спискам. zip - функция берёт на вход несколько списков и создаёт из них список (кортеж):
for i,j,k in zip(Config.name, Config.mac, Config.ip):
Записываем в файл:
f.write(f"host {i}" + " {\n\thardware ethernet" + f" {j};" + "\n\tfixed-address " + f"{k};" + "\n}\n\n")
Вызываем функцию:
if __name__ == '__main__':
write()
Вариант 2
Пользовался таблицей 2 и библиотекой xlrd.
Библиотека не поддерживает xlsx формат поэтому пришлось сохранить файл в формат xls.
import xlrd
def write():
loc = (r"C:\path\to\file\filename.xls")
sheet = xlrd.open_workbook(loc).sheet_by_index(0)
with open("dhcp.conf", 'w') as f:
for i in range(sheet.nrows):
f.write(f"host {sheet.cell_value(i, 0)}" + " {\n\thardware ethernet" + f" {sheet.cell_value(i,1)};" + "\n\tfixed-address " + f"{sheet.cell_value(i,2)};" + "\n}\n\n")
if __name__ == '__main__':
write()
Импортируем библиотеку для возможности ее использования:
import xlrd
Объявляем функцию:
def write():
Открываем excel и лист с индексом 0:
loc = (r"C:\path\to\file\filename.xls")
sheet = xlrd.open_workbook(loc).sheet_by_index(0)
Данный фрагмент можно записать во так:
sheet = xlrd.open_workbook(r"C:\path\to\file\filename.xls").sheet_by_index(0)
Открываем файл на запись:
with open("dhcp.conf", 'w') as f:
Пробегаемся циклом по количеству строк. Где 'sheet.nrows' показывает количество строк:
for i in range(sheet.nrows):
Записываем в файл. sheet.cell_value(i, 0) - считываем значение с поля где i - строка, 0 - столбец:
f.write(f"host {sheet.cell_value(i, 0)}" + " {\n\thardware ethernet" + f" {sheet.cell_value(i,1)};" + "\n\tfixed-address " + f"{sheet.cell_value(i,2)};" + "\n}\n\
Вызываем функцию:
if __name__ == '__main__':
write()
Вариант 3
Пользовался таблицей 2 и библиотекой pandas.
import pandas as pd
def write():
excel = pd.read_excel(r'C:\path\to\file\filename.xlsx')
with open("dhcp.conf", 'w') as f:
for i, j, k in zip(excel["Name"].tolist(), excel["MAC"].tolist(), excel["IP"].tolist()):
f.write(f"host {i}" + " {\n\thardware ethernet" + f" {j};" + "\n\tfixed-address " + f"{k};" + "\n}\n\n")
if __name__ == '__main__':
write()
Подключаем библиотеку. as - создание псевдонима:
import pandas as pd
Создаем функцию:
def write():
Считываем данные из excel:
excel = pd.read_excel(r'C:\path\to\file\filename.xlsx')
Открываем файл для чтения:
with open("dhcp.conf", 'w') as f:
Пробегаемся циклом по спискам:
for i, j, k in zip(excel["Name"].tolist(), excel["MAC"].tolist(), excel["IP"].tolist()):
Выбираем столбцы, у которого название 'Name', 'mac', 'ip'. Создаем из них список:
excel["Name"].tolist(), excel["MAC"].tolist(), excel["IP"].tolist
Что бы посмотреть, как pandas видит оглавление excel используется следующая строчка:
print (excel.columns.ravel())
Записываем в файл:
f.write(f"host {i}" + " {\n\thardware ethernet" + f" {j};" + "\n\tfixed-address " + f"{k};" + "\n}\n\n
Вызываем функцию:
if __name__ == '__main__':
write()
Вывод всех вариантов скриптов в dhcp.conf:
host Ivanov {
hardware ethernet 00:00:00:00:00:00;
fixed-address 192.168.0.10;
}
Надеюсь, кому-нибудь это будет полезно.
PS: это моя первая статья
Комментарии (8)
baldr
15.08.2022 14:10+6Большой минус. Смысла в статье мало, а неправильных решений - много. Я перечислю только часть.
xlrd устарела уже много лет назад, о чем пишут даже они сами в своих доках. Есть openpyxl, который может нормально работать с xlsx-файлами.
Смысла использовать именно Python в данном случае - немного. Проще было то же самое сделать на VBA в том же самом Excel-файлике. Плюсы - можно хранить на сетевом диске и обновлять всем, а не одному пользователю с правильно настроенным питоном.
pandas - это вообще оверкилл. Она тяжелая сама по себе, да еще и тянет зависимости. Выше верно заметили что даже csv справится.
Вы не знаете Python, но пишете статью с подробным комментированием каждой строчки, что выглядит как "тьюториал". Вот это что за дичь с конкатенацией вообще:
f"host {i}" + " {\n\thardware ethernet" + f" {j};"
Ну и вообще, я, хоть и не системный администратор, но предполагаю, что для подобных решений (ведение списка пользователей) есть более специализированные инструменты.
Заклочение: автоматизация - хорошо, самообразование - хорошо, идея поделиться получившимся решением - хорошо. Но сама статья - плохо.
iig
15.08.2022 14:47сама статья - плохо
Как одноразовое решение - сойдёт. Хотя на
bashawk это делается в одну строчку. Но показывать этот велосипед никому категорически нельзя ;)
Sergey-S-Kovalev
15.08.2022 20:44+2Включить DHCP на клиентский сегмент.
Всем выставить автоматическое получение IP адреса через любимую систему управления конфигурацией.
Понять, что на дворе 2022 год и ходить к хостам по IP, а не по именам не практично.
Статика в сегменте с клиентскими хостами не нужна. Если вы думаете, что нужна, то у вас все сделано не правильно.
AlexSyz
15.08.2022 23:55Полностью согласен с baldr - Excel позволяет обработать такую таблицу без Питона. Я бы даже VBA не использовал - просто concatenate в соседнем столбце.
Основное преимущество - можно после исправления одной строки сразу ее проапдейтить в конфиге.
net_racoon
16.08.2022 09:52-1В этой статье все плохо, даже не знаю с чего начать:
1) Зачем вы прибиваете ИПы к МАКу? Вы к пользователям ходите? Зачем вы к пользователям ходите? Почему не ходите по именам?
2) Зачем вы храните ФИО в конфиге. Это лишний источник информации, который через определенное время потеряет актуальность, когда Иванов уволится и на его место сядет Петров- в конфиге это править никто не будет;
3) Скрипт не нужен, склеить несколько ячеек можно на чистом Экселе;
4) Как писали выше, можно было перевести в CSV и все стало бы проще;
5) Я не виндоадмин, но что-то мне подсказывает что ваш нужно делать сеть на винде, с контроллерами домена и т.п.
iig
Таблицу можно сохранить в CSV - модуль для csv встроен в python.