Я решил поставить 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)


  1. iig
    15.08.2022 13:55
    +2

    Таблицу можно сохранить в CSV - модуль для csv встроен в python.


  1. baldr
    15.08.2022 14:10
    +6

    Большой минус. Смысла в статье мало, а неправильных решений - много. Я перечислю только часть.

    xlrd устарела уже много лет назад, о чем пишут даже они сами в своих доках. Есть openpyxl, который может нормально работать с xlsx-файлами.

    Смысла использовать именно Python в данном случае - немного. Проще было то же самое сделать на VBA в том же самом Excel-файлике. Плюсы - можно хранить на сетевом диске и обновлять всем, а не одному пользователю с правильно настроенным питоном.

    pandas - это вообще оверкилл. Она тяжелая сама по себе, да еще и тянет зависимости. Выше верно заметили что даже csv справится.

    Вы не знаете Python, но пишете статью с подробным комментированием каждой строчки, что выглядит как "тьюториал". Вот это что за дичь с конкатенацией вообще: f"host {i}" + " {\n\thardware ethernet" + f" {j};"

    Ну и вообще, я, хоть и не системный администратор, но предполагаю, что для подобных решений (ведение списка пользователей) есть более специализированные инструменты.

    Заклочение: автоматизация - хорошо, самообразование - хорошо, идея поделиться получившимся решением - хорошо. Но сама статья - плохо.


    1. iig
      15.08.2022 14:47

      сама статья - плохо

      Как одноразовое решение - сойдёт. Хотя на bash awk это делается в одну строчку. Но показывать этот велосипед никому категорически нельзя ;)


      1. net_racoon
        16.08.2022 09:46

        Да можно было вообще чистым Экселем обойтись.


  1. Sergey-S-Kovalev
    15.08.2022 20:44
    +2

    1. Включить DHCP на клиентский сегмент.

    2. Всем выставить автоматическое получение IP адреса через любимую систему управления конфигурацией.

    3. Понять, что на дворе 2022 год и ходить к хостам по IP, а не по именам не практично.

    4. Статика в сегменте с клиентскими хостами не нужна. Если вы думаете, что нужна, то у вас все сделано не правильно.


    1. iig
      16.08.2022 11:48

      все сделано не правильно

      Возможно, но если работает - не нужно трогать же :)


  1. AlexSyz
    15.08.2022 23:55

    Полностью согласен с baldr - Excel позволяет обработать такую таблицу без Питона. Я бы даже VBA не использовал - просто concatenate в соседнем столбце.

    Основное преимущество - можно после исправления одной строки сразу ее проапдейтить в конфиге.


  1. net_racoon
    16.08.2022 09:52
    -1

    В этой статье все плохо, даже не знаю с чего начать:

    1) Зачем вы прибиваете ИПы к МАКу? Вы к пользователям ходите? Зачем вы к пользователям ходите? Почему не ходите по именам?

    2) Зачем вы храните ФИО в конфиге. Это лишний источник информации, который через определенное время потеряет актуальность, когда Иванов уволится и на его место сядет Петров- в конфиге это править никто не будет;

    3) Скрипт не нужен, склеить несколько ячеек можно на чистом Экселе;

    4) Как писали выше, можно было перевести в CSV и все стало бы проще;

    5) Я не виндоадмин, но что-то мне подсказывает что ваш нужно делать сеть на винде, с контроллерами домена и т.п.