Книга: PyNEng
Назад: Модуль sqlite3
Дальше: V. Работа с сетевым оборудованием

Дополнительные материалы

Дополнительные материалы

Документация:

  • - подробное описание SQLite

Статьи:

Задания

Задания

Все задания и вспомогательные файлы можно скачать в . Если в заданиях раздела есть задания с буквами (например, 5.2a), то лучше выполнить сначала задания без букв, а затем с буквами. Задания с буквами, как правило, немного сложнее заданий без букв и развивают или усложняют идею в соответствующем задании без буквы.

Например, в разделе есть задания 5.1, 5.2, 5.2a, 5.2b, 5.3, 5.3a. Сначала лучше выполнить задания 5.1, 5.2, 5.3, а затем 5.2a, 5.2b, 5.3a

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

Задание 18.1

На основе файла из примеров раздела, необходимо создать два скрипта:

  • create_db.py
    • сюда должна быть вынесена функциональность по созданию БД:
    • должна выполняться проверка наличия файла БД
    • если файла нет, согласно описанию схемы БД в файле dhcp_snooping_schema.sql, должна быть создана БД (БД отличается от примера в разделе)
  • add_data.py
    • с помощью этого скрипта, выполняется добавление данных в БД
    • добавлять надо не только данные из вывода sh ip dhcp snooping binding, но и информацию о коммутаторах

Код в скриптах должен быть разбит на функции. Какие именно функции и как разделить код, надо решить самостоятельно. Часть кода может быть глобальной.

В БД теперь две таблицы (схема описана в файле dhcp_snooping_schema.sql):

  • switches - в ней находятся данные о коммутаторах
  • dhcp - эта таблица осталась такой же как в примере, за исключением поля switch
    • это поле ссылается на поле hostname в таблице switches

Соответственно, в файле add_data.py две части:

  • информация о коммутаторах добавляется в таблицу switches
    • данные о коммутаторах, находятся в файле switches.yml
  • информация на основании вывода sh ip dhcp snooping binding добавляется в таблицу dhcp
    • вывод с трёх коммутаторов:
      • файлы sw1_dhcp_snooping.txt, sw2_dhcp_snooping.txt, sw3_dhcp_snooping.txt
    • так как таблица dhcp изменилась, и в ней теперь присутствует поле switch, его нужно также заполнять. Имя коммутатора определяется по имени файла с данными

На данном этапе, оба скрипта вызываются без аргументов.

Задание 18.1a

Скопировать скрипт add_data.py из задания 18.1.

Добавить в файл add_data.py, из задания 18.1, проверку на наличие БД:

  • если файл БД есть, записать данные
  • если файла БД нет, вывести сообщение, что БД нет и её необходимо сначала создать

Задание 18.2

На основе файла get_data_ver1.py из раздела, создать скрипт get_data.py.

Код в скрипте должен быть разбит на функции. Какие именно функции и как разделить код, надо решить самостоятельно. Часть кода может быть глобальной.

В примере из раздела, скрипту передавались два аргумента:

  • key - имя столбца, по которому надо найти информацию
  • value - значение

Теперь необходимо расширить функциональность таким образом:

  • если скрипт был вызван без аргументов, вывести всё содержимое таблицы dhcp
    • отформатировать вывод в виде столбцов
  • если скрипт был вызван с двумя аргументами, вывести информацию из таблицы dhcp, которая соответствует полю и значению
  • если скрипт был вызван с любым другим количеством аргументов, вывести сообщение, что скрипт поддерживает только два или ноль аргументов

Обработка некорректного ввода аргумента будет выполняться в следующем задании

Файл БД можно скопировать из прошлых заданий

В итоге, вывод должен выглядеть так:

$ python get_data.py  В таблице dhcp такие записи: ---------------------------------------------------------------------- 00:09:BB:3D:D6:58  10.1.10.2         10    FastEthernet0/1      sw1 00:04:A3:3E:5B:69  10.1.5.2          5     FastEthernet0/10     sw1 00:05:B3:7E:9B:60  10.1.5.4          5     FastEthernet0/9      sw1 00:07:BC:3F:A6:50  10.1.10.6         10    FastEthernet0/3      sw1 00:09:BC:3F:A6:50  192.168.1.100     100   FastEthernet0/5      sw1 00:A9:BB:3D:D6:58  10.1.10.20        10    FastEthernet0/7      sw2 00:B4:A3:3E:5B:69  10.1.5.20         5     FastEthernet0/5      sw2 00:C5:B3:7E:9B:60  10.1.5.40         5     FastEthernet0/9      sw2 00:A9:BC:3F:A6:50  100.1.1.6         3     FastEthernet0/20     sw3  $ python get_data.py ip 10.1.10.2  Detailed information for host(s) with ip 10.1.10.2 ---------------------------------------- mac         : 00:09:BB:3D:D6:58 vlan        : 10 interface   : FastEthernet0/1 switch      : sw1 ----------------------------------------   $ python get_data.py vlan 10  Detailed information for host(s) with vlan 10 ---------------------------------------- mac         : 00:09:BB:3D:D6:58 ip          : 10.1.10.2 interface   : FastEthernet0/1 switch      : sw1 ---------------------------------------- mac         : 00:07:BC:3F:A6:50 ip          : 10.1.10.6 interface   : FastEthernet0/3 switch      : sw1 ---------------------------------------- mac         : 00:A9:BB:3D:D6:58 ip          : 10.1.10.20 interface   : FastEthernet0/7 switch      : sw2 ----------------------------------------  $ python get_data.py vlan Пожалуйста, введите два или ноль аргументов 

Задание 18.2a

Дополнить скрипт get_data.py из задания 18.2

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

Файл БД можно скопировать из прошлых заданий

В итоге, вывод должен выглядеть так:

$ python get_data.py vln 10 Данный параметр не поддерживается. Допустимые значения параметров: mac, ip, vlan, interface, switch 

Задание 18.3

В прошлых заданиях информация добавлялась в пустую БД. В этом задании, разбирается ситуация, когда в БД уже есть информация.

Скопируйте скрипт add_data.py и попробуйте выполнить его повторно, на существующей БД. Должна возникнуть ошибка.

При создании схемы БД, было явно указано, что поле MAC-адрес, должно быть уникальным. Поэтому, при добавлении записи с таким же MAC-адресом, возникает ошибка.

Но, нужно каким-то образом обновлять БД, чтобы в ней хранилась актуальная информация.

Например, можно каждый раз, когда записывается информация, предварительно просто удалять всё из таблицы dhcp.

Но, в принципе, старая информация тоже может пригодиться.

Поэтому, мы будем делать немного по-другому. Создадим новое поле active, которое будет указывать является ли запись актуальной.

Поле active должно принимать такие значения:

  • 0 - означает False. И используется для того, чтобы отметить запись как неактивную
  • 1 - True. Используется чтобы указать, что запись активна

Каждый раз, когда информация из файлов с выводом DHCP snooping добавляется заново, надо пометить все существующие записи (для данного коммутатора), как неактивные (active = 0). Затем можно обновлять информацию и пометить новые записи, как активные (active = 1).

Таким образом, в БД останутся и старые записи, для MAC-адресов, которые сейчас не активны, и появится обновленная информация для активных адресов.

Новая схема БД находится в файле dhcp_snooping_schema.sql

Измените скрипт add_data.py таким образом, чтобы выполнялись новые условия и заполнялось поле active.

Код в скрипте должен быть разбит на функции. Какие именно функции и как разделить код, надо решить самостоятельно. Часть кода может быть глобальной.

Для проверки корректности запроса SQL, можно выполнить его в командной строке, с помощью утилиты sqlite3.

Для проверки задания и работы нового поля, попробуйте удалить пару строк из одного из файлов с выводом dhcp snooping. И после этого проверить, что удаление строки отображаются в таблице как неактивные.

Задание 18.4

Обновить файл get_data из задания 18.2 или 18.2a. Добавить поддержку столбца active, который мы добавили в задании 18.3.

Теперь, при запросе информации, сначала должны отображаться активные записи, а затем, неактивные.

Например:

$ python get_data.py ip 10.1.10.2  Detailed information for host(s) with ip 10.1.10.2 ---------------------------------------- mac         : 00:09:BB:3D:D6:58 vlan        : 10 interface   : FastEthernet0/1 switch      : sw1 ----------------------------------------  ======================================= Inactive values: ---------------------------------------- mac         : 00:09:23:34:16:18 vlan        : 10 interface   : FastEthernet0/4 switch      : sw1 ----------------------------------------  $ python get_data1.py -------------------------------------------------------------------------------- Active values: -------------------------------------------------------------------------------- 00:09:BB:3D:D6:58  10.1.10.2         10    FastEthernet0/1    sw1         1 00:04:A3:3E:5B:69  10.1.5.2          5     FastEthernet0/10   sw1         1 00:05:B3:7E:9B:60  10.1.5.4          5     FastEthernet0/9    sw1         1 00:07:BC:3F:A6:50  10.1.10.6         10    FastEthernet0/3    sw1         1 00:09:BC:3F:A6:50  192.168.100.100   1     FastEthernet0/7    sw1         1 00:B4:A3:3E:5B:69  10.1.5.20         5     FastEthernet0/5    sw2         1 00:C5:B3:7E:9B:60  10.1.5.40         5     FastEthernet0/9    sw2         1 00:A9:BC:3F:A6:50  10.1.10.60        20    FastEthernet0/2    sw2         1 -------------------------------------------------------------------------------- Inactive values: -------------------------------------------------------------------------------- 00:A9:BB:3D:D6:58  10.1.10.20        10    FastEthernet0/7    sw2         0 

Задание 18.5

Теперь в БД остается и старая информация. И, если какой-то MAC-адрес не появлялся в новых записях, запись с ним, может оставаться в БД очень долго.

И, хотя это может быть полезно, чтобы посмотреть, где MAC-адрес находился в последний раз, постоянно хранить эту информацию не очень полезно.

Например, если запись в БД уже больше месяца, то её можно удалить.

Для того, чтобы сделать такой критерий, нужно ввести новое поле, в которое будет записываться последнее время добавления записи.

Новое поле называется last_active и в нём должна находиться строка, в формате: YYYY-MM-DD HH:MM:SS.

В этом задании необходимо:

  • изменить, соответственно, таблицу dhcp и добавить новое поле.
    • таблицу можно поменять из cli sqlite, но файл dhcp_snooping_schema.sql тоже необходимо изменить
  • изменить скрипт add_data.py, чтобы он добавлял к каждой записи время

Как получить строку со временем и датой, в указанном формате, показано в задании. Раскомментируйте строку и посмотрите как она выглядит.

import datetime  now = str(datetime.datetime.today().replace(microsecond=0)) #print(now) 

Задание 18.5a

После выполнения задания 18.5, в таблице dhcp есть новое поле last_active.

Обновите скрипт add_data.py, таким образом, чтобы он удалял все записи, которые были активными более 7 дней назад.

Для того, чтобы получить такие записи, можно просто вручную обновить поле last_active.

В файле задания описан пример работы с объектами модуля datetime. Обратите внимание, что объекты, как и строки с датой, которые пишутся в БД, можно сравнивать между собой.

from datetime import timedelta, datetime  now = datetime.today().replace(microsecond=0) week_ago = now - timedelta(days = 7)  #print(now) #print(week_ago) #print(now > week_ago) #print(str(now) > str(week_ago)) 

Задание 18.6

В этом задании выложен файл parse_dhcp_snooping.py.

В файле созданы несколько функций и описаны аргументы командной строки, которые принимает файл.

В файле parse_dhcp_snooping.py нельзя ничего менять.

Есть поддержка аргументов для выполнения всех действий, которые, в предыдущих заданиях, выполнялись в файлах create_db.py, add_data.py и get_data.py.

В файле parse_dhcp_snooping.py есть такая строка:

import parse_dhcp_snooping_functions as pds 

И задача этого задания в том, чтобы создать все необходимые функции, в файле parse_dhcp_snooping_functions.py на основе информации в файле parse_dhcp_snooping.py.

Из файла parse_dhcp_snooping.py, необходимо определить:

  • какие функции должны быть в файле parse_dhcp_snooping_functions.py
  • какие параметры создать в этих функциях

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

Вся необходимая информация, присутствует в функциях create, add, get, в файле parse_dhcp_snooping.py.

В принципе, для выполнения задания, не обязательно разбираться с модулем argparse. Но, Вы можете почитать о нём в разделе .

Для того, чтобы было проще начать, попробуйте создать необходимые функции в файле parse_dhcp_snooping_functions.py и, например, просто выведите аргументы функций, используя print.

Потом, можно создать функции, которые запрашивают информацию из БД (базу данных можно скопировать из предыдущих заданий).

Можно создавать любые вспомогательные функции в файле parse_dhcp_snooping_functions.py, а не только те, которые вызываются из файла parse_dhcp_snooping.py.

Проверьте все операции:

  • создание БД
  • добавление информации о коммутаторах
  • добавление информации на основании вывода sh ip dhcp snooping binding из файлов
  • выборку информации из БД (по параметру и всю информацию)

Чтобы было проще понять, как будет выглядеть вызов скрипта, ниже несколько примеров.

$ python parse_dhcp_snooping.py -h usage: parse_dhcp_snooping.py [-h] {create_db,add,get} ...  optional arguments:   -h, --help           show this help message and exit  subcommands:   valid subcommands    {create_db,add,get}  additional info     create_db          create new db     add                add data to db     get                get data from db  $ python parse_dhcp_snooping.py get -h usage: parse_dhcp_snooping.py get [-h] [--db DB_FILE]                                   [-k {mac,ip,vlan,interface,switch}]                                   [-v VALUE] [-a]  optional arguments:   -h, --help            show this help message and exit   --db DB_FILE          db name   -k {mac,ip,vlan,interface,switch}                         host key (parameter) to search   -v VALUE              value of key   -a                    show db content  $ python parse_dhcp_snooping.py add -h usage: parse_dhcp_snooping.py add [-h] [--db DB_FILE] [-s]                                   filename [filename ...]  positional arguments:   filename      file(s) to add to db  optional arguments:   -h, --help    show this help message and exit   --db DB_FILE  db name   -s            add switch data if set, else add normal data  $ python parse_dhcp_snooping.py create_db -h usage: parse_dhcp_snooping.py create_db [-h] [-n NAME] [-s SCHEMA]  optional arguments:   -h, --help  show this help message and exit   -n NAME     db filename   -s SCHEMA   db schema filename   $ python parse_dhcp_snooping.py create_db Creating DB dhcp_snooping.db with DB schema dhcp_snooping_schema.sql Creating schema... Done  $ python parse_dhcp_snooping.py add sw1_dhcp_snooping.txt sw2_dhcp_snooping.txt sw3_dhcp_snooping.txt Reading info from file(s) sw1_dhcp_snooping.txt, sw2_dhcp_snooping.txt, sw3_dhcp_snooping.txt  Adding data to db dhcp_snooping.db   $ python parse_dhcp_snooping.py add -s switches.yml Adding switch data to database   $ python parse_dhcp_snooping.py get Showing dhcp_snooping.db content... ---------------------------------------------------------------------- 00:09:BB:3D:D6:58  10.1.10.2         10    FastEthernet0/1      sw1 00:04:A3:3E:5B:69  10.1.5.2          5     FastEthernet0/10     sw1 00:05:B3:7E:9B:60  10.1.5.4          5     FastEthernet0/9      sw1 00:07:BC:3F:A6:50  10.1.10.6         10    FastEthernet0/3      sw1 00:09:BC:3F:A6:50  192.168.1.100     100   FastEthernet0/5      sw1 00:A9:BB:3D:D6:58  10.1.10.20        10    FastEthernet0/7      sw2 00:B4:A3:3E:5B:69  10.1.5.20         5     FastEthernet0/5      sw2 00:C5:B3:7E:9B:60  10.1.5.40         5     FastEthernet0/9      sw2 00:A9:BC:3F:A6:50  100.1.1.6         3     FastEthernet0/20     sw3  $ python parse_dhcp_snooping.py get -k vlan -v 10 Geting data from DB: dhcp_snooping.db Request data for host(s) with vlan 10  Detailed information for host(s) with vlan 10 ---------------------------------------- mac         : 00:09:BB:3D:D6:58 ip          : 10.1.10.2 interface   : FastEthernet0/1 switch      : sw1 ---------------------------------------- mac         : 00:07:BC:3F:A6:50 ip          : 10.1.10.6 interface   : FastEthernet0/3 switch      : sw1 ---------------------------------------- mac         : 00:A9:BB:3D:D6:58 ip          : 10.1.10.20 interface   : FastEthernet0/7 switch      : sw2 ----------------------------------------   $ python parse_dhcp_snooping.py get -k vln -v 10 usage: parse_dhcp_snooping.py get [-h] [--db DB_FILE]                                   [-k {mac,ip,vlan,interface,switch}]                                   [-v VALUE] [-a] parse_dhcp_snooping.py get: error: argument -k: invalid choice: 'vln' (choose from 'mac', 'ip', 'vlan', 'interface', 'switch') 
Назад: Модуль sqlite3
Дальше: V. Работа с сетевым оборудованием