Pull to refresh

Python scirpt на службе сетевого администратора

Зачем

Многие представляют себе, что такое городская сеть и объемы работ, необходимые для её постройки и эксплуатации. Все мы люди, а все люди, как известно имеют свойство ошибаться. В больших сетях с парой сотен железок это приводит к простоям, недополученным прибылям и как следствие лишением премии системщика и/или бессонной ночи за моником, лошадиным дозам кофе и тихом проклинании самого себя за отсутствие должного внимания.
В один прекрасный момент это надоедает и приходит в голову затертые до дыр фразы «Do it, using less administrative effort», «Don't do it again, script it once!».
И вот этот один прекрасный день настал.

Что же произошло

А случилось так, что составили планы по строительству сети на новом районе, закупили железо, настроили и поставили. А через неделю начались звонки в сапорт с жалобами на регулярные обрывы, по их словам «где-то каждые час-полтора», а у кого-то и вообще не работает. Созвонились с одним грамотным клиентом и начали анализировть. В сети у нас работает dhcp relay + snooping + PPPoE. То есть пока клиент не авторизовался, ему дается серый IP адрес, после того как авторизовался — белый. Вроде бы всё красиво, но почему-то не подумав, я настроил клиентские свичи так, что на порту была разрешена только одна привязка MAC-IP-PORT, snooping в режиме strict, а клиенты иногда и аренду адресов не продляли или перетыкали в сеть то ноут, то свой комп, то SOHO мыльницу-роутер, после чего порт блокировался. И тут я понимаю, что придется мне сейчас взять и зайти на каждую железку хоть по вебе, хоть по телнету и поменять эти настройки, разрешив хотя бы по три привязки на порт. Прикинув объем и муторность работ, наконец сказал себе «с меня хватит, пора заняться автоматизацией!»

И занялся

Решая на чем писать скрипт, ориентировался на то, что, во-первых, биллинг у нас уже написан на python, есть с кем посоветоваться в случае чего, знаю что есть куча библиотек для упрощения работы, когда-то давно читал теорию по нему, есть опыт написания скриптов на bash'e и чутьем чую — запарюсь я эту задачу решать на нем.
Погуглив часок, составил список инструментов — telnetlib и ipaddr. Названия говорят сами за себя. Сел и начал писать:

#!/usr/bin/env python

# -*- coding: utf-8 -*-

# for telnettting
import telnetlib
# for passing/getting script arguments
from sys import argv
# thanks to google code for pretty lib
from ipaddr import *
# inputs
import sys
# secure password entering
import getpass

# hosts is a network in a.b.c.d/e format passed as first script param
hosts = IPv4Network(argv[1])
# ask user for username
user = raw_input("Enter username: ")
# ask user for password
password = getpass.getpass()
# command passed qouted "command to do" as second script param
command = argv[2]
# d-link switches have unconvinient paging for telnet/serial interaction
disclip = "disable clipaging"

# loop adresses inside given network
for host in IPv4Network(hosts).iterhosts():
print host
# try for not to fail the whole script on one error
try:
# host is ipaddr.IPv4Address but telnetlib.Telnet() requires first argument as string
tn = telnetlib.Telnet(str(host),23,1)
# "NeverMatches" because it really never matches with suggested output, don't know why, 1 is delay(timeout)
print tn.read_until("NeverMatches",1)
# passing username
tn.write(user + "\n")
# passing password
print tn.read_until("NeverMatches",1)
tn.write(password + "\n")
# disabling clipaging
print tn.read_until("NeverMatches",1)
tn.write(disclip + "\n")
# running actual command
print tn.read_until("NeverMatches",1)
tn.write(command + "\n")
# save changes
print tn.read_until("NeverMatches",1)
tn.write("save\n")
# logout, but wait a bit. becuase "save" command takes some time usually
print tn.read_until("NeverMatches",5)
tn.write("logout\n")
# look that logged out
print tn.read_until("NeverMatches",1)
except:
print "Error connecting to host", host


Скрипт запускается с двумя параметрами — подсеть (можно и отдельный хост) и команда, которую нужно выполнить, например:
/telnet.py 192.168.207.0/24 "config address_binding dhcp_snoop max_entry ports 1-24 limit 3"
Более подробно по ходу выполнения скрипта — в комментариях внутри кода.
Не забудьте, что библиотека ipaddr не идет в базовой поставке python'a, нужно доставить отдельно, по крайней мере в убунтовых и дебиановских репах она есть.
Я не профессиональный python-программист и поэтому не претендую на чистоту кода и правильность его оформления, мне было важно решить задачу — выполнение рутинных операций на множестве однотипных железок, так что буду только рад услышать все комментарии и ругательства по поводу (не)правильности чего-либо. Сам понимаю, что хорошо бы писать лог, добавить кучу исключений, да и управление вести пожалуй лучше по snmp. Надеюсь это творение сэкономит много времени и нервов собратьям по профессии.

При выполнении всего использовалась литература и источники:
  1. Книга «Язык программирования Python» — Сузи Роман Авриевич (чисто как справочник, новичку на мой взгляд будет тяжело с неё начать)
  2. Официальная документация на библиотеку telnetlib
  3. Всё, что удалось найти на гугло-коде про библиотеку ipaddr


PS: В коде почему-то пропали отступы при переносе сюда.
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.