O dia de hoje vou criar um script em python que se coneta a vários roteadores Cisco IOS executa o comando "sh run", e armazena o resultado em um diretório de backups.
A Topologia que vou utilizar é a seguinte:
O roteador IOU1, IOU2 e IOU4 rodam OSPF entre eles. Eu tenho conetividade SSH a eles via interfaces de Loopback:
IOU1: 1.1.1.1
IOU2: 2.2.2.2
IOU4: 4.4.4.4
Todos eles tem configurado um usuário e senha padrão cisco/cisco e um enable também de cisco.
A configuração dos roteadores não é importante para esse post. O que é do nosso interesse é como armazenar a saída do comando "sh run" em um arquivo de texto.
O primeiro passo é definir os roteadores, cada roteador tem uma ip, usuário, senha, nome de host etc. Para isso vamos utilizar um dicciónario por cada roteador:
cisco_iou1={'device_type':'cisco_ios','ip':'1.1.1.1','username':'cisco','password':'cisco','secret':'cisco','timeout':10}
cisco_iou2={'device_type':'cisco_ios','ip':'2.2.2.2','username':'cisco','password':'cisco','secret':'cisco','timeout':10}
cisco_iou3={'device_type':'cisco_ios','ip':'3.3.3.3','username':'cisco','password':'cisco','secret':'cisco','timeout':10}
cisco_iou4={'device_type':'cisco_ios','ip':'4.4.4.4','username':'cisco','password':'cisco','secret':'cisco','timeout':10}
Vocês podem ver que eu adicionei um roteador a mais o IOU3, no decorrer do post vocês iram ver o porque de eu fazer isso.
Logo eu vou definir uma lista contendo cada um dos roteadores:
cisco_routers=[cisco_iou1,cisco_iou2,cisco_iou3,cisco_iou4]
Agora que temos definido quais elementos queremos coletar informação, o seguinte passo é fazer uma varredura em todos esses elementos, para isso utilizamos um laço "for".
for cisco_router in cisco_routers:
net_connect=ConnectHandler(**cisco_router)
net_connect.enable()
output=net_connect.send_command('sh run')
print output
net_connect.exit_enable_mode()
net_connect.disconnect()
O script completo ficaria:
#!/usr/bin/python
from netmiko import ConnectHandler
cisco_iou1={'device_type':'cisco_ios','ip':'1.1.1.1','username':'cisco','password':'cisco','secret':'cisco','timeout':10}
cisco_iou2={'device_type':'cisco_ios','ip':'2.2.2.2','username':'cisco','password':'cisco','secret':'cisco','timeout':10}
cisco_iou3={'device_type':'cisco_ios','ip':'3.3.3.3','username':'cisco','password':'cisco','secret':'cisco','timeout':10}
cisco_iou4={'device_type':'cisco_ios','ip':'4.4.4.4','username':'cisco','password':'cisco','secret':'cisco','timeout':10}
cisco_routers=[cisco_iou1,cisco_iou2,cisco_iou3,cisco_iou4]
for cisco_router in cisco_routers:
net_connect=ConnectHandler(**cisco_router)
net_connect.enable()
output=net_connect.send_command('sh run')
print output
net_connect.exit_enable_mode()
net_connect.disconnect()
jose@rejane:~/Automatizacao$ ./backup.py
Building configuration...
Current configuration : 2199 bytes
!
! Last configuration change at 11:44:14 -03 Mon Apr 16 2018
version 15.2
service timestamps debug datetime msec
service timestamps log datetime msec
no service password-encryption
!
hostname IOU1
......
......
line vty 0 4
login local
transport input ssh
!
!
end
Traceback (most recent call last):
File "./backup.py", line 15, in <module>
net_connect=ConnectHandler(**cisco_router)
File "/usr/local/lib/python2.7/dist-packages/netmiko/ssh_dispatcher.py", line 173, in ConnectHandler
return ConnectionClass(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/netmiko/base_connection.py", line 187, in __init__
self.establish_connection()
File "/usr/local/lib/python2.7/dist-packages/netmiko/base_connection.py", line 654, in establish_connection
raise NetMikoTimeoutException(msg)
netmiko.ssh_exception.NetMikoTimeoutException: Connection to device timed-out: cisco_ios 3.3.3.3:22
jose@rejane:~/Automatizacao$
Hummm...o script começou a rodar, ele printou o "sh run" do IOU1, IOU2 e parou em IOU3, o qual esta certo, visto que IOU3 não existe, mas nós queriamos o print de IOU4 que sabemos é um roteador ativo...o que fazer???.........Lembram da sentença "try...except"... ela é uma sentença que tenta fazer alguma coisa e se der erro executa um código de exceção e depois continua com o código normal...
Vamos modificar o nosso código para uma nova versão "backupv2.py", dessa vez com a sentença "try..except":
Script backupv2.py
#!/usr/bin/python
from netmiko import ConnectHandler
cisco_iou1={'device_type':'cisco_ios','ip':'1.1.1.1','username':'cisco','password':'cisco','secret':'cisco','timeout':10}
cisco_iou2={'device_type':'cisco_ios','ip':'2.2.2.2','username':'cisco','password':'cisco','secret':'cisco','timeout':10}
cisco_iou3={'device_type':'cisco_ios','ip':'3.3.3.3','username':'cisco','password':'cisco','secret':'cisco','timeout':10}
cisco_iou4={'device_type':'cisco_ios','ip':'4.4.4.4','username':'cisco','password':'cisco','secret':'cisco','timeout':10}
cisco_routers=[cisco_iou1,cisco_iou2,cisco_iou3,cisco_iou4]
for cisco_router in cisco_routers:
try:
net_connect=ConnectHandler(**cisco_router)
net_connect.enable()
output=net_connect.send_command('sh run')
print output
net_connect.exit_enable_mode()
net_connect.disconnect()
except:
print("Erro de conexao ao roteador %s" % cisco_router['ip'])
Executando o mesmo temos:
jose@rejane:~/Automatizacao$ ./backupv2.py
Building configuration...
Current configuration : 2199 bytes
!
! Last configuration change at 11:44:14 -03 Mon Apr 16 2018
version 15.2
service timestamps debug datetime msec
service timestamps log datetime msec
no service password-encryption
!
hostname IOU1
!
.....
.....
Erro de conexao ao roteador 3.3.3.3
Building configuration...
....
.....
Beleza!..agora nosso script funciona, e quando da algum erro em algum elemento, o script printa uma mensagem de erro.
Agora que o "core" do nosso script funciona, precisamos lhe adicionar algumas coisas, como por exemplo um arquivo log, de forma a que tudo o que seja feito por nosso script seja armazenado logeado, dessa forma é possivél detetar e corrigir falhas. Também precisamos que os "sh run" dos roteadores sejam armazenados em arquivos e não somente que sejam printados na tela.
Primeiro vou criar dois diretorios no home da minha máquina Linux:
mkdir /home/jose/backupciscorouters
mkdir /home/jose/backupciscorouters/logs
No primeiro diretório seram armazenados os "sh run", e no segundo o arquivo log, um arquivo log por dia.
O arquivos de "sh run", assim como o arquivo log precisam ter uma extensão que nos diga a data que foram criados. Para isso vamos utilizar as funções dos módulos "time" e "datetime". Para a criação do arquivo log, utilizamos o módulo "logging".
O script completo fico assim:
#!/usr/bin/python
from netmiko import ConnectHandler
import time
import datetime
import logging
#Diretorio de Backup
BackupDir='/home/jose/backupciscorouters'
#Data que sera concatenada no nome do arquivo log: backup.YYYYMMDD.log , um arquivo log por dia
LogData=datetime.datetime.now().strftime("%Y%m%d")
Log = BackupDir + "/logs/backup." + LogData + ".log"
#Configuracao basica do logging, o nivel de logging vai ser INFO, caso seja preciso mais informacao podemos colocar DEBUG
logging.basicConfig(filename=Log,
filemode='a',
format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s',
datefmt='%H:%M:%S',
level=logging.INFO)
#Inicio do Script, escrevo no arquivo log
logging.info('Inicio')
logging.info(datetime.datetime.now().strftime("%Y-%m-%d %H%M%S"))
#Definicao dos nossos roteadores
cisco_iou1={'device_type':'cisco_ios','ip':'1.1.1.1','host':'IOU1','username':'cisco','password':'cisco','secret':'cisco','timeout':10}
cisco_iou2={'device_type':'cisco_ios','ip':'2.2.2.2','host':'IOU2','username':'cisco','password':'cisco','secret':'cisco','timeout':10}
cisco_iou3={'device_type':'cisco_ios','ip':'3.3.3.3','host':'IOU3','username':'cisco','password':'cisco','secret':'cisco','timeout':10}
cisco_iou4={'device_type':'cisco_ios','ip':'4.4.4.4','host':'IOU4','username':'cisco','password':'cisco','secret':'cisco','timeout':10}
#Lista com os nossos roteadores
cisco_routers=[cisco_iou1,cisco_iou2,cisco_iou3,cisco_iou4]
#Laco para executar o comando sh run roteador por roteador
for cisco_router in cisco_routers:
try:
#Abrindo uma conexao SSH
net_connect=ConnectHandler(**cisco_router)
#Trocando para enable
net_connect.enable()
#Executando o comando sh run
output=net_connect.send_command('sh run')
#Nome do arquivo de backup no formato hostname.YYYY-MM-DD-HH:MM:SS
BackupNameOfFile=BackupDir + "/" + cisco_router['host'] + "." + datetime.datetime.now().strftime("%Y-%m-%d-%H:%M:%S")
#Escrevendo no arquivo a saida do comando sh run
with open(BackupNameOfFile,'w') as fh:
fh.write(output)
#Saindo do enable
net_connect.exit_enable_mode()
#Fechando a sessao SSH
net_connect.disconnect()
except:
logging.info("Erro de conexao ao roteador %s" % cisco_router['ip'])
#Escrevendo lo log a palavra Fim e colocando a hora que finalizou
logging.info('Fim')
logging.info(datetime.datetime.now().strftime("%Y-%m-%d %H%M%S"))
Ao rodar o mesmo obtemos como resultado:
jose@rejane:~/Automatizacao$ ./backupv3.py
jose@rejane:~/Automatizacao$
jose@rejane:~/backupciscorouters$ ls -ltrah
total 40K
drwxr-xr-x 82 jose jose 20K Abr 16 12:27 ..
drwxrwxr-x 2 jose jose 4,0K Abr 16 21:07 logs
-rw-rw-r-- 1 jose jose 2,3K Abr 16 21:07 IOU1.2018-04-16-21:07:37
-rw-rw-r-- 1 jose jose 2,1K Abr 16 21:07 IOU2.2018-04-16-21:07:42
-rw-rw-r-- 1 jose jose 2,1K Abr 16 21:07 IOU4.2018-04-16-21:07:48
drwxrwxr-x 3 jose jose 4,0K Abr 16 21:07 .
jose@rejane:~/backupciscorouters$
Show!..os arquivos com o conteúdo do "sh run" foram criados e eles tem a data que foram criados.
E o arquivo log como será que fico?..Vejamos:
jose@rejane:~/backupciscorouters/logs$ ls -ltrah
total 12K
drwxrwxr-x 2 jose jose 4,0K Abr 16 21:07 .
drwxrwxr-x 3 jose jose 4,0K Abr 16 21:07 ..
-rw-rw-r-- 1 jose jose 662 Abr 16 21:07 backup.20180416.log
jose@rejane:~/backupciscorouters/logs$
jose@rejane:~/backupciscorouters/logs$ more backup.20180416.log
21:07:32,282 root INFO Inicio
21:07:32,283 root INFO 2018-04-16 210732
21:07:32,331 paramiko.transport INFO Connected (version 2.0, client Cisco-1.25)
21:07:32,623 paramiko.transport INFO Authentication (password) successful!
21:07:37,800 paramiko.transport INFO Connected (version 2.0, client Cisco-1.25)
21:07:38,75 paramiko.transport INFO Authentication (password) successful!
21:07:43,194 root INFO Erro de conexao ao roteador 3.3.3.3
21:07:43,221 paramiko.transport INFO Connected (version 2.0, client Cisco-1.25)
21:07:43,490 paramiko.transport INFO Authentication (password) successful!
21:07:48,620 root INFO Fim
21:07:48,621 root INFO 2018-04-16 210748
jose@rejane:~/backupciscorouters/logs$
Podemos utilizar multiprocess para executar várias sessões SSH em paralelo, ou se por exemplo se minha rede tiver 20 roteadores, posso utilizar 4 scripts cada um rodando para 5 roteadores, e fazer o agendamento na cron do Linux.
Por hoje é isso pessoal, próximos posts vamos continuar com mais automatização e exemplos.
Abcs
Jose
Nenhum comentário:
Postar um comentário