Добавляем IP телефоны в отдельный Pool IP адресов по Mac адресу

Всем привет!
Этот топик о том, как я использовал Python для написания скрипта, который производит следующие действия:

  1. Выгружает список активных мак адресов с Микротика
  2. Выбирает мак адреса IP телефонов
  3. Помещает их в отдельный pool IP адресов

Кому интересно прошу пожаловать под кат.

Для начала я определился какие инструменты я буду для этого использовать. Так как я как раз начал учить Python(как первый ЯП), то и решил применить его на практике. Далее буду приводить пример кода с его комментированием.

import telnetlib
import time
import ftplib
import logging


class MacToPool():
    def get_export_file_from_mikrotik(self):
        host = "IP адрес микротика"
        user = "ваш_логин"
        password = "ваш_пароль"
        command_1 = '/ip dhcp-server lease print file=lease_file'
        command_2 = 'quit'
        tn = telnetlib.Telnet(host)
        tn.read_until(b"Login: ")
        tn.write(user.encode('UTF-8') + b"\n")
        tn.read_until(b"Password: ")
        tn.write(password.encode('UTF-8') + b"\n")
        tn.read_until(b'>')
        ftp = ftplib.FTP('IP адрес микротика')
        ftp.login('ваш_логин', 'ваш_пароль')
        try:
            ftp.delete('lease_file.txt')
            ftp.delete('script_mac_phone.rsc')
            logging.basicConfig(filename='log.txt', level=logging.INFO,
                            format='%(asctime)s - %(levelname)s - %(message)s')
            logging.info("Файлы удалены: lease_file.txt, script_mac_phone.rsc")
        except Exception:
            logging.basicConfig(filename='log.txt', level=logging.INFO,
                            format='%(asctime)s - %(levelname)s - %(message)s')
            logging.info("Файлы для удаления не найдены. Продолжаем работу.")
        time.sleep(1)
        tn.write(command_1.encode('UTF-8') + b"\r\n")
        time.sleep(1)
        logging.basicConfig(filename='log.txt', level=logging.INFO,
                            format='%(asctime)s - %(levelname)s - %(message)s')
        logging.info("Файл конфигурации создан.")
        tn.read_until(b'>')
        tn.write(command_2.encode('UTF-8') + b"\r\n")
        time.sleep(1)
        f = open('lease_file.txt', "wb")
        ftp.retrbinary("RETR lease_file.txt", f.write)
        logging.basicConfig(filename='log.txt', level=logging.INFO,
                            format='%(asctime)s - %(levelname)s - %(message)s')
        logging.info("Файл конфигурации скопирован на сервер")

    lst_mac_phone = []


В функции get_export_file_from_mikrotik() я подключаюсь к микротику, и с помощью команды /ip dhcp-server lease print file=lease_file записываю все активные мак адреса в файл lease_ftp и далее уже с помощью FTP скачиваю его к себе в рабочую папку скрипта для дальнейшей работы.

Так же здесь создаю пустой список для мак адресов телефонов. Далее идет следующий код

def get_all_mac(self):
        self.get_export_file_from_mikrotik(MacToPool)
        text = open('lease_file.txt').readlines()
        self.all_mac = []
        for line in text:
            lst_value = line.split(" ")
            for symbol in lst_value:
                if len(symbol) == 17:
                    self.all_mac.append(symbol)
        return self.all_mac


В файле lease_ftp у нас очень много лишней информации, и поэтому я с помощью функции get_all_mac получил список содержащий только мак адреса всех активных устройств. Следующим скриптом я выдергиваю из всех мак адресов, только нужные(в моем случае это мак адреса телефонов):

def find_mac_phone(self):
        self.get_all_mac(MacToPool)
        mac_phone = open("macphone.txt", "w")
        for mac_address in self.all_mac:
            if mac_address[0:8] == "00:15:65":
                mac_phone.write(mac_address + "\n")
                self.lst_mac_phone.append(mac_address)
        logging.basicConfig(filename='log.txt', level=logging.INFO,
                            format='%(asctime)s - %(levelname)s - %(message)s')
        logging.info("Файл с MAC адресами телефонов создан")


Следующие команды выполнят следующие действия:
Функция make_mikrotik_script() создает файл скрипта, который сможет обработать Mikrotik для добавления маков в пул.
Функция upload_to_ftp() выгружает готовый скрипт на FTP сервер микротика.
И последняя функция выполняет непосредственный запуск скрипта на роутере.

    def make_mikrotik_script(self):
        ###выполнив функцию, получаем скрипт для микротика для добавления маков телефонов в пул IP-Phones###
        script_mac_phone = open("script_mac_phone.txt", "w")
        script_mac_phone.write("/ip dhcp-server lease \n")
        self.find_mac_phone(MacToPool)
        for mac_address in self.lst_mac_phone:
            script_mac_phone.write("add address=IP-Phones mac-address=" + mac_address + " server=server1" + '\n')
        self.upload_to_ftp(MacToPool)
        logging.basicConfig(filename='log.txt', level=logging.INFO,
                            format='%(asctime)s - %(levelname)s - %(message)s')
        logging.info("Создан скрипт script_mac_phone.rsc")

    def upload_to_ftp(self):
        ftp = ftplib.FTP('IP адрес микротика')
        ftp.login('ваш_логин', 'ваш_пароль')
        f = open("script_mac_phone.txt", "rb")
        ftp.storbinary("STOR script_mac_phone.rsc", f)
        f.close()
        logging.basicConfig(filename='log.txt', level=logging.INFO,
                            format='%(asctime)s - %(levelname)s - %(message)s')
        logging.info("script_mac_phone.rsc перемещен на микротик")

    def load_script_to_mikrotik(self):
        self.make_mikrotik_script(MacToPool)
        host = "IP адрес микротика"
        user = "ваш_логин"
        password = "ваш_пароль"
        command_1 = '/import file-name=script_mac_phone.rsc'
        command_2 = 'quit'
        tn = telnetlib.Telnet(host)
        tn.read_until(b"Login: ")
        tn.write(user.encode('UTF-8') + b"\n")
        tn.read_until(b"Password: ")
        tn.write(password.encode('UTF-8') + b"\n")
        tn.read_until(b'>')
        tn.write(command_1.encode('UTF-8') + b"\r\n")
        time.sleep(1)
        logging.basicConfig(filename='log.txt', level=logging.INFO,
                            format='%(asctime)s - %(levelname)s - %(message)s')
        logging.info("Конфигурация загружена. Done!")
        tn.read_until(b'>')
        tn.write(command_2.encode('UTF-8') + b"\r\n")
        time.sleep(1)


Так же как вы могли заметить ведется логирование.
В результате таких нехитрых действий все телефоны у меня в отдельном пуле и теперь при необходимости мне так же удобно работать отдельно с ними.

P.S. Использовался Python версии 3.3
Share post
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 6

    0
    Чего только люди не выдумают, чтобы не использовать VLAN.
      0
      А мне интересно как вообще работать с айпи телефонией без влан? QoS как делать тогда?
        0
        Скажу тебе по секрету — огромное число так называемы администраторов о QoS только слышали и/или читали. До дела дошло далеко не у всех.Тем более, что в IPv4 с QoS всё весьма убого, хотя если речь идёт только о писюках юзеров и телефонах, то как бы и достаточно…
          0
          У меня все входящие и исходящие пакеты на сервер телефонии идут в самом высоком приоритете.
          По поводу VLAN, у меня есть не только хардварные телефоны, но и программные, при чем и тех и тех примерно поровну. Поэтому проблему приоритета трафика и решали именно путем приоритета пакетов, как написал выше.
        0
        Если честно, то совсем не понял зачем тут Python. Основная задача: по шаблону МАС адреса указывать определенный IP пул?
        Возможное решение
        # script-name: mac2pool
        # before use this script run command each DHCP-SERVER:
        # /ip dhcp-server set lease-script=mac2pool numbers=dhcpd-home
        # where DHCPD-HOME your DHCP-SERVER name
        # Also avaliable global variables: leaseBound, leaseServerName, leaseActMAC, leaseActIP
        # or add task to system scheduler:
        # /system scheduler add name=mac2pool interval=5m on-event=mac2pool
        
        :local poolName "br-v015-pool";
        :local macTpl "F0:27:65";
        
        if ( [:tonum ($leaseBound)] = 1 || [:tostr ($leaseActMAC)] = "" ) do={
          :foreach i in=[ /ip dhcp-server lease find where mac-address ~"$macTpl" disabled=no ] do={
            :local mac [ /ip dhcp-server lease get number=$i mac-address ];
        
            :log info "Work for MAC: $mac";
        
            if ( [ /ip dhcp-server lease get number=$i dynamic ] ) do={
              /ip dhcp-server lease make-static numbers=$i;
            }
            /ip dhcp-server lease set address=$poolName numbers=$i;
          };
        };
        


        Из недостатков следует выделить момент, что сперва назначается динамический адрес и только по прошествии времени аренды этого адреса будет выдан новый адрес из указанного пула. Но для наколенного решения за 5 минут — вполне себе рабочий вариант.

        Кто не хочет вешать скрипт на событие DHCP сервера можно добавить во встроенный планировщик. Вот как-то так… Проверил — работает. Жалобы и предложения только приветствуются…
          0
          Python использовал потому что именно его сейчас изучаю. Так же написал скрипт и в планировщик добавил его его.
          Так что в этом скрипте был еще и чисто академический интерес такой как разбор вывода конфигурации микротика.
          А ваш вариант очень интересен. Тоже думал насчет скрипта на самом микротике, но не было времени изучать синтаксис.

        Only users with full accounts can post comments. Log in, please.