пятница, 15 января 2016 г.

сбор информации с маршрутизаторов cisco python paramiko

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

#!/usr/bin/python
#for work with SSH we need paramiko pip install paramiko
import paramiko
#hide password input 
import getpass
#build in library socket for with exception
import socket
list_bad_ip=[]
receive_buffer=""
client = paramiko.SSHClient()
#for connection via ssh you need to accept SSH keys
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#create function for send command and check answer
def send_string_and_wait_for_string(command, wait_string):
#send command
    shell.send(command)
#clear buffer
    receive_buffer = ""
#until receive WAIT_STRING - remote device ready
    while not wait_string in receive_buffer:
        receive_buffer += shell.recv(1024)
#return buffer with output of command 
 return receive_buffer
#read list of IPs from text file one by line
ips = [i.strip() for i in open("./1")]
username1 = raw_input("enter login :")
#hide password input 
password1 = getpass.getpass("enter password :")
#create loop for each IPs
for ip in ips:
#if we use try easy to work with expection
    try:
#connect to device
        client.connect(ip,port=22,username=username1,password=password1)
#check state
#        print "connect to ",ip
        shell = client.invoke_shell()
#wait for enable
        send_string_and_wait_for_string("", "#")
#enter command and wait for return to #
        receive_buffer = send_string_and_wait_for_string("sh int Vlan12 | i line protocol\n","#")
#first option not interesting 
        if "line protocol is up" in receive_buffer:
            print ip+" protocol is up"
#second possible answer interesting save in separate list 
        else:
            print ip+" line protocol is down"
            list_bad_ip.append(ip)
#close with this device
        shell.close()
        client.close()
#work with timeout error
    except socket.error:
        print ip + '=== Device unreachable'
#add ip with errors to list
        list_bad_ip.append(ip)
#save this list to file
with open('bad_ip', 'w') as f:
    for s in list_bad_ip:
        f.write(s + '\n')
#show list at the screen for lazy admin
print list_bad_ip
(END)

массовая настройка маршрутизаторов Cisco по ssh (mass configuring cisco router via ssh)

Написал небольшой скрипт как пример массовой настройки маршрутизаторов Cisco по ssh на python.
Использовал paramiko, а не модуль clogin из rancid, потому что было интересно уменьшить зависимости.

От других подобных скриптов мне кажется отличает такое
1) за счет ожидания wait for string работает и на каналах с большой латентностью (спутниках и наземных в перемешку)
2) в тоже время за счет выноса цикла отправки и ожидания ответа в функцию код получается более-менее компактным и добавлять команды довольно просто
3) за счет getpass получается скрытый ввод пароля
4) да и вообще в скрипте не храняться учетные данные
5) так как в моем списке ip могут попадаться и неактивные устройства, то используется try и  expect  для вывода адресов, до которых не удалось достучаться.
 
#!/usr/bin/python
#for work with SSH we need paramiko pip install paramiko
import paramiko
import getpass
#build in library socket for with exception
import socket
list_bad_ip=[]
client = paramiko.SSHClient()
#for connection via ssh you need to accept SSH keys
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#create function for send command and check answer
def send_string_and_wait_for_string(command, wait_string):
#send command
    shell.send(command)
#clear buffer
    receive_buffer = ""
#until receive WAIT_STRING - remote device ready
    while not wait_string in receive_buffer:
        receive_buffer += shell.recv(1024)
#read list of IPs from text file one by line
ips = [i.strip() for i in open("./1")]
username1 = raw_input("enter login :")
password1 = getpass.getpass("enter password :")
#create loop for each IPs
for ip in ips:
#if we use try easy to work with expection
    try:
#connect to device
        client.connect(ip,port=22,username=username1,password=password1)
#check state
        print "connect to ",ip
        shell = client.invoke_shell()
#wait for enable
        send_string_and_wait_for_string("", "#")
#enter conf t and wait for #
        send_string_and_wait_for_string("conf t\n", "(config)#")
#enter command and wait for return to #
        send_string_and_wait_for_string("login on-failure log\n","(config)#")
        send_string_and_wait_for_string("login on-success log\n","(config)#")
#end is important, exit worse in this case
        send_string_and_wait_for_string("end\n","#")
#don't forget store in flash
        send_string_and_wait_for_string("wr mem\n","#")
#we are near end with device
        print ip+" ok"
#close with this device
        shell.close()
        client.close()
#work with timeout error
    except socket.error:
        print ip + '=== Device unreachable'
#add ip with errors to list
        list_bad_ip.append(ip)
#save this list to file
with open('bad_ip', 'w') as f:
    for s in list_bad_ip:
        f.write(s + '\n')
#show list at the screen for lazy admin
print list_bad_ip

четверг, 22 октября 2015 г.

Скрипт в помощь поиска неуправляемых коммутаторов/hub на Python (seach unmanaged switch/hub connected to Cisco with python script)


#!/usr/bin/python
# version 0.1 Created Yevgenii Merezhko
# My assumptions:
# There are switches with many vlans. I select only "users switches"
# There are Cisco ip phones in voice vlan.
# Usually Po1 is uplink
# PC connected via IP Phones and somecase we have some hub/unmanaged switches after Cisco IP Phones
# Ip Phones have two mac address (one in voice vlan and second in data vlan)
#just for entering VoiceVlan number
VoiceVlan = str(input("Enter Voice Vlan number: "))
#put file in folder in put name of file
#may be better to work with all files in folder TBD
with open("/home/yevgenii/Downloads/test/test2/192.168.73.252.1.1") as textFile:
    lines = [line.split() for line in textFile]
# I expect some thing like 
# 73    0004.23e7.d793    DYNAMIC     Fa0/22
# 73    0005.1e35.de56    DYNAMIC     Fa0/15
# 
# for example  it could be extracted from "sh mac add" 
# My colleague collect it for me with bash+clogin (module from Rancid)
# and separate file with like this bash script
# #!/bin/sh
# for i in $(ls 1*);
# do 
# cat $i| grep "^\ "| grep -v "Po1" > $i.1
# done
row = 0
MacAddressPhones = []
ListWithoutPhones = []
macaddress = 0
macaddress1 = 0
macaddress2 = 0
mac1phones = 0
mac2phonesswitch = 0
Vlan = 0
x = 0
y = 0
B = 0
port = []
PortNumber = 0
result = {}
#create list with mac in voice vlan
while row < len(lines):
    Vlan = lines[row][0]
    macaddress = lines[row][1]
    if Vlan == VoiceVlan:
        MacAddressPhones.append(macaddress)
        del lines[row][:]
    row += 1
#for easy loop filtering 
ListWithoutPhones = lines
#remove empty from list
lines = filter(None, lines)
#compare Mac in voice vlan with mac in data vlan)
for mac1phones in range(len(MacAddressPhones)):
    macaddress1 = MacAddressPhones[mac1phones]
    mac2phonesswitch = 0
    while mac2phonesswitch < len(lines):
        macaddress2 = lines[mac2phonesswitch][1]
        if macaddress1 == macaddress2:
            del ListWithoutPhones[mac2phonesswitch][:]
        lines = filter(None, lines)
        ListWithoutPhones = filter(None,ListWithoutPhones)
        mac2phonesswitch += 1
    mac1phones += 1
#create only list of port
while x < len(ListWithoutPhones):
    port.append(ListWithoutPhones[x][3])
    x += 1
print("port",port)
#calucate how many times port in list if more then 1, put in interesting list
while y     PortNumber = port[y]
    print("PortNumber",PortNumber)
    B = port.count(PortNumber)
    print("B",B)
    if B >1:
        result[PortNumber]=B
        print("result len:",len(result))
    y += 1
print ("List of Ports: ",result)
# after this it need to be filter uplink port in most case it will be easy

среда, 14 октября 2015 г.

Идея для очистки Cisco ACL IOS на маршрутизаторах

Условия:
  • Есть большое количество маршрутизаторов
  • ACL большого размера
  • ACL более менее похожи
  • ACL используют локальные адреса в качесте source
Идея:
Удалить неиспользуемые правила хотя бы более менее массово, чтобы сделать acl читаемыми человеком

Вариант решения:

  • Зайти на маршрутизатор, выбрать из ACL одного типа все destination у которых счетчики равны 0. 
  • Зайти на следующий маршрутизатор выбрать  destination у которых счетчики равны 0, сравнить с предыдущим, оставить только одинаковые
  • Зайти на следующий маршрутизатор.
В моем случае процент кандидатов на удаление очень приличный



четверг, 16 июля 2015 г.

Cisco NX OS кое что полезное

На устройстве nx/os можно хранить версии конфигов чуть удобнее чем раньше
http://www.cisco.com/c/en/us/td/docs/switches/datacenter/sw/5_x/nx-os/system_management/configuration/guide/sm_nx_os_cg/sm_7rollback.html

Раньше для этого применяли просто копирование
 copy run file (были особенности на разных устройствах, но можно было иметь под рукой конфиг

Разницу между сохраненным конфигом (checkpoint) и например текущим конфигом можно посмотреть так
http://www.cisco.com/web/techdoc/dc/reference/cli/nxos/commands/sec/show_diff_rollback-patch_running-config.html

Разницу в состоянии интерфейсов например так

show interface port-channel 10 | diff

только ввести команду надо пару раз
во втором увидим разницу

список всех комманд вводимых на устройстве с NX OS за последнее время

show accounting log | i нужные слова для поиска

быстрый обзор трафика на всех интерфейсах при выводе
show interfac | egrep eth|rate  (обращаю внимание на "или"= |)

очень полезная команда, чтобы найти нужный nexus (нужное шасси) включив индикацию на модуле

locator-led дальше по ?




среда, 18 марта 2015 г.

CDR Cisco Callmanager (CUCM) в легкочитаемый человеком вид

Для анализа CDR от Cisco CallManager нашел три более-менее удобных способа
Для любого из них нужно сначала
1) Залогиниться в CUCM CAR
2) выгрузить в csv CDR (при выгрузке отключите CMR будет немного меньше избыточных для простых задач данных)

Обработка
1)  открыть в excel и убрать вручную избыточные столбцы, привести формат даты и времени из unix формата timestamp в человекочитаемый формат, например с помощью двух формул. То есть добавил два столбца, вставил формулу и протянул мышкой вниз.

=(((C1/60)/60)/24)+ДАТА(1970; 1; 1) - дата
=(((C1/60)/60)/24)                                     - время

2) просмотреть с помощью небольшой утилиты с форума supportforum.cisco.com 
cisco 
https://learningnetwork.cisco.com/thread/50029?start=15&tstart=0
 прямая ссылка на всякий случай
https://dl.dropboxusercontent.com/u/53426117/PermLinks/UCMcdr.exe

3) красивый способ 

Взято здесь http://yurisk.info/2014/05/12/cisco-cucm-cdr-report-call-duration-and-called-numbers-extraction-script/

 awk -F,'BEGIN {OFS=","} {print strftime("%c",$5),$9,$31,$56}'report_cdr
Вместо report_cdr использовать ваше имя файла с отчетами
Такую строку удобно использовать в других, более сложных скриптах
Если просто обработать, то не забываем в конце добавить например
awk-F, 'BEGIN {OFS=","} {print strftime("%c",$5),$9,$31,$56}' report_cdr  перенаправляем в report.csv