12 de mai de 2018

YAML e JINJA2 - Parte I

Olá Pessoal Boa Noite, hoje vamos falar um pouco sobre templates e criação automática de configurações.

YAML são as iniciais de Yet Another Markup Language, o objetivo inicial de YAML foi o de poder transformar estruturas de dados em um formato que possa ser armazenado em arquivos, ou enviado via rede para outras máquinas; da mesma forma que XML.

A diferença de XML, YAML é mais intuitivo fazendo que sua escrita e leitura sejam mais fáceis de entender.

Devido à essa facilidade na leitura e escrita, YAML é amplamente utilizado na definição de configurações. Por exemplo se eu quiser definir um roteador que vai precisar executar "bgp", eu posso colocar todas essas definições em um arquivo, YAML. Esse arquivo posteriormente pode se utilizado por outro software como JINJA2, para gerar arquivos de configurações, podendo inclusive, com ajuda de templates JINJA2, gerar configurações para diferentes fabricantes.



Os arquivos YAML precisam ser processados por um "parser", esse parser se encarrega de ler o arquivo YAM e criar uma estrutura de dados a qual possamos acessar. Em Python esse parser é feito pela livraria PyYAML

Antes de continuar com YAML, vou lhes mostrar alguns conceitos sobre estruturas de dados aninhados em python, isso vai ajudar no entendimento da sintaxes YAML.

Diccionarios Aninhados


Até agora conhecemos os diccionarios em python, porém nada impede ter diccionarios dentro de diccionarios. Exemplo:

Roteadores={'R1':{'hostname':'R1SP','ip':'1.1.1.1'},'R2':{'hostname':'R1SP','ip':'1.1.1.1'}}

O diccionario acima "Roteadores", tem duas chaves, a primeira chave 'R1' e a segunda 'R2'. O detalhe é que o valor associado à chave 'R1' é um outro diccionario, o mesmo para 'R2'.

Vamos testar no interpretador de python:


>>> Roteadores={'R1':{'hostname':'R1SP','ip':'1.1.1.1'},'R2':{'hostname':'R1SP','ip':'1.1.1.1'}}
>>> Roteadores
{'R1': {'ip': '1.1.1.1', 'hostname': 'R1SP'}, 'R2': {'ip': '1.1.1.1', 'hostname': 'R1SP'}}
>>> Roteadores['R1']
{'ip': '1.1.1.1', 'hostname': 'R1SP'}
>>> Roteadores['R2']
{'ip': '1.1.1.1', 'hostname': 'R1SP'}
>>> Roteadores['R1']['ip']
'1.1.1.1'
>>> Roteadores['R2']['ip']
'1.1.1.1'
>>> 

Para poder ir digamos assim acessando aos valores de diccionarios mais baixos podemos utilizar a notação Diccionario_Pai[chave-1][chave-2]...[chave-n].


Listas de Diccionarios

Ao igual que existem diccionarios aninhados, nada impede ter por exemplo uma lista de diccionarios. Vejamos:

>>> Roteadores=[{'hostname':'R1SP','ip':'1.1.1.1'},{'hostname':'R1SP','ip':'1.1.1.1'}]
>>> Roteadores
[{'ip': '1.1.1.1', 'hostname': 'R1SP'}, {'ip': '1.1.1.1', 'hostname': 'R1SP'}]
>>> Roteadores[0]
{'ip': '1.1.1.1', 'hostname': 'R1SP'}
>>> Roteadores[1]
{'ip': '1.1.1.1', 'hostname': 'R1SP'}
>>> Roteadores[0]['ip']
'1.1.1.1'
>>> Roteadores[1]['ip']
'1.1.1.1'
>>> 

Agora o acesso aos elementos do diccionario é um pouco diferente, utilizamos uma combinação do index da lista e a chave do diccionario.

Ao momento de processar um arquivo YAML para poder utilizar ele em JINJA2 p.e, vamos utilizar bastante as estruturas acima mostradas.

Instalação do módulo PyYAML para parseamento


Para parsear os arquivos YAML é preciso instalar o módulo pyyaml.

sudo pip install pyyaml

E para utilizar basta importar o módulo em nosso interpretador python

import yaml



Agora sim ...Continuando com YAML.....


Sintaxes em YAML


Inicio de um Documento

Se utiliza o string '---' para indicar o inicio de um documento YAML.

Fim de um Documento

Se utiliza o string '...' para indicar o fim de um documento YAML.

Podem ser inseridos vários documentos em um único arquivo YAML.

Indentação

YAML utiliza indentação para definir hierarquias, similar a indentação em python. Exemplo:

R1:
  hostname: R1SP

No exemplo acima a chave "hostname", com valor "R1SP" esta embaixo da chave "R1". Existe uma hierarquia em YAML.

Em python a configuração acima pode ser traduzida para o seguinte diccionario:

{'R1':{'hostname':'R1SP'}}

Separador

Em YAML somente se utiliza "espaço" como separador, nada de TAB.


Escalares

YAML, permite a definição de diferentes tipos de variavéis, inteiro, float, string boolean. A forma como é definido é do tipo "chave:valor". O tipo de variavél é reconhecido automáticamente.

myInteiro: 10
myFloat: 3.14
myString: "Post de YAML"

Em python a configuração acima se traduz para:

{'myInteiro': 10, 'myFloat': 3.14, 'myString': 'Post de YAML'}

Strings podem estar entre aspas simples o duplas. Se utilizam duplas quando precisamos utilizar caracteres especiais nesse caso também utilizamos o caractere "\"

myString: "Primeira Linha\nSegunda Linha" 

As vezes precisamos armazenar um string de forma literal nesse caso podemos utilizar o operador '|':

myString: |
  "Post de YAML
  exemplo de string.

  Novo paragrafo"

Em python a configuração acima se traduz em:   

{'myString': '"Post de YAML\n exemplo de string.\n Novo paragrafo"\n'}

é possivél também indicar em YAML para que sejam trocados os ENTERs por espaços (quem vai fazer isso é o parser), nesse caso utilizamos o operador '>'

myString: >
  "Post de YAML
  exemplo de string.

  Novo paragrafo"

Em python a configuração acima se traduz em:   

{'myString': '"Post de YAML exemplo de string. Novo paragrafo"\n'}

Listas

Para definir uma lista se utiliza o carater '-' por cada item da lista.

roteadores:
  - R1
  - R2
  - R3

A estrutura de dados acima pode ser lida como: "A chave 'roteadores' tem como valor a lista de valores R1,R2 e R3'.

Em python ficaria:

{'roteadores': ['R1', 'R2', 'R3']}
Inclusive posso ter valores duplicados na lista, isso não é um problema.

roteadores:
  - router
  - router

A estrutura acima pode ser lida como: "A chave 'roteadores' tem como valor uma lista, que a sua vez contem dois itens; item-0=router e item-1=router"

Em python ficaria:

{'roteadores': ['router', 'router']}

Diccionarios

Dicionarios são estruturas de dados com um conjunto de mapeamentos do tipo chave:valor

R1:
  hostname: 'R1SP'
  ip: '1.1.1.1'
  user: 'cisco'
  pass: 'cisco'

A estrutura de dados acima pode ser lida como: "A chave 'R1', tem como valor um outro conjunto de pares chave:valor hostname:'R1SP', ip:'1.1.1.1' etc.

Em Python ficaria:

{'R1': 

   {'hostname': 'R1SP', 
    'ip': '1.1.1.1', 
    'pass': 'cisco', 
    'user': 'cisco'}
}

No caso de diccionarios não é possivél ter chaves duplicadas. Exemplo:

R1:
  hostname: 'R1SP'
  ip: '1.1.1.1'
  user: 'cisco'
  pass: 'cisco'
  ip: '11.11.11.11'

No exemplo acima o valor para a chave 'ip' será '11.11.11.11'. Ao colocar a mesma chave, o valor para essa chave será sobreescrito.

Em python ficaria:

{'R1': 
   {'hostname': 'R1SP', 
    'ip': '11.11.11.11', 
    'pass': 'cisco', 
    'user': 'cisco'}
}


Existe a possibilidade de combinar diccionarios e listas.

Exemplo, preciso definir uma configuração para dois roteadores e tenho os seguintes dados:

Roteador1: Nome R1SP, ip de acesso 1.1.1.1

Roteador2: Nome R2SP ip de acesso 2.2.2.2

A configuração YAML poderia ficar:

roteadores:
 - router:
     hostname: 'R1SP'
     ip: '1.1.1.1'
 - router:
     hostname: 'R2SP'
     ip: '2.2.2.2'


Em Python ficaria:


{'roteadores': 
   [{'router': {'hostname': 'R1SP', 'ip': '1.1.1.1'}}, 
    {'router': {'hostname': 'R2SP', 'ip': '2.2.2.2'}}
   ]
}

Vamos asignar o valor do diccionario acima para a variável MyRouters em python, e ir acessando aos valores da estrutura na medida que nos aprondufamos na hierarquia.

>>> import yaml

>>> MyRouters={'roteadores': 
...    [{'router': {'hostname': 'R1SP', 'ip': '1.1.1.1'}}, 
...     {'router': {'hostname': 'R2SP', 'ip': '2.2.2.2'}}
...    ]
... }
>>> MyRouters['roteadores']
[{'router': {'ip': '1.1.1.1', 'hostname': 'R1SP'}}, {'router': {'ip': '2.2.2.2', 'hostname': 'R2SP'}}]

>>> MyRouters['roteadores'][0]
{'router': {'ip': '1.1.1.1', 'hostname': 'R1SP'}}

>>> MyRouters['roteadores'][1]
{'router': {'ip': '2.2.2.2', 'hostname': 'R2SP'}}

>>> MyRouters['roteadores'][0]['router']
{'ip': '1.1.1.1', 'hostname': 'R1SP'}

>>> MyRouters['roteadores'][1]['router']
{'ip': '2.2.2.2', 'hostname': 'R2SP'}

>>> MyRouters['roteadores'][0]['router']['ip']
'1.1.1.1'

>>> MyRouters['roteadores'][1]['router']['ip']
'2.2.2.2'
>>> 


Existe um site de parseamento online, onde vocês podem praticar http://yaml-online-parser.appspot.com/. No site vocês colocam sua configuração YAML e escolhem como saída Python. Ele vai lhes mostrar qual será a estrutura em python do seu arquivo YAML.

Um outro exemplo, um switch para o qual precisa ser gerado uma configuração para 3 VLANs, e OSPF.


SW1:
 router-id: "1.1.1.1"
 vlans:
    - vlan: 
       id: 100
       desc: "Vlan da rede 192.168.100.0"
    - vlan: 
       id: 200
       desc: "Vlan da rede 192.168.200.0"
    - vlan: 
       id: 300
       desc: "Vlan da rede 10.10.10.0"
    
 ospf:
    networks:
     - network:
        net: 192.168.100.0 
        netmask: "255.255.255.0"
        area: 0
     - network:
        net: 192.168.200.0 
        netmask: "255.255.255.128"
        area: 1
     - network:
        net: 10.10.10.0 
        netmask: "255.255.255.0"
        area: 2


Por hoje é isso Pessoal!!... Um Feliz Dia das Mais!!

Abçs
Jose

Agora sou... CCNA CYBER OPS


Ontem, sexta-feira, 11/05/2018, conquistei o titulo de CCNA Cyber OPS. Após ter concluído os Exames 210-250 SECFND e 210-255 SECOPS. A Cisco tem bancado, através do programa Cisco Global Cyber Ops Scholarship, não só os cursos online preparatórios para esses Exames, como também os vouchers (100% na faixa) para que os interessados no tema possam tirar essa certificação, a custo zero.

Com o constante aumento dos Cyber ataques e ameaças eletrônicas, eu creio que todo profissional de TI deveria passar por estes treinamentos, de forma a ficar antenado com os temas relacionados a Tratamento de Incidentes de Segurança na Web.

Agradeço ao Bruno Nunes, que montou um grupo de estudos no WhatsApp para os interessados no CCNA Cyber, pelas dicas e compartilhamento de material.

Fica a Dica!

5 de mai de 2018

NAPALM - Parte III

Olá Pessoal Boa Tarde, hoje vamos utilizar NAPALM para mudar as configurações dos nossos roteadores.

A topologia física vai ser a mesma utilizada até agora. Dois roteadores R1-IOS e R2-JunOS, e um host representando pela nuvem Cloud1.



Ambos os roteadores estão rodando OSPF, e todas as suas interfaces estão na área 0.

O objetivo será, trocar de OSPF para BGP. Ficando R1 no AS100 e R2 no AS200.

Os novos arquivos de configuração podem ser baixados de:

https://github.com/JoseBalbuena/BlogNetFinders/blob/master/NAPALM_PARTEIII_R2.conf

https://github.com/JoseBalbuena/BlogNetFinders/blob/master/NAPALM_PARTEIII_R1.conf


Dessa vez vamos utilizar o método load_replace_candidate() da livraria NAPALM.

O único detalhe a ter em consideração é que eu preciso começar a configurar pelo roteador R2, isso porque quando faça a troca de configuração eu vou perder a conetividade com R2, porém quando configure R1 e o peer BGP fechar a conexão irá voltar.

Se eu começar por R1, vou perder conetividade com R2 e nunca mais vou ter acesso.

O meu script ficaria assim:


#!/usr/bin/python

import napalm

#Router diccionario
R1={'so':'ios','hostname':'R1','ip':'1.1.1.1','username':'napalm','password':'napalm','secret':'cisco','newfile':'/home/jose/Automatizacao/R1_new.conf'}
R2={'so':'junos','hostname':'R2','ip':'2.2.2.2','username':'napalm','password':'napalm123','newfile':'/home/jose/Automatizacao/R2_new.conf'}

#Listado dos meus roteadores
routers=[R2,R1] #R2 primeiro na lista


#BEGIN


#Loop para fazer varredura
for router in routers:
 #Caso seja um roteador IOS, utilizar o parametro optional_args com a senha de enable
 if router['so'] == 'ios':
  optional_args={'secret':router['secret']}
 else:
  optional_args={}
 #Selecctiona o driver
 driver = napalm.get_network_driver(router['so'])
 #Coneta ao roteador, dentro de um try..execpt, caso de algum erro o erro eh printado
 try:
  device = driver (hostname=router['ip'], username=router['username'], password=router['password'],optional_args=optional_args)
  device.open()
  #Carrega o arquivo das atualizacoes a serem feitas
  device.load_replace_candidate(filename=router['newfile'])
  #Faz o commit
  device.commit_config()
  #Fecha a conexao
  device.close()
 except Exception as error:
  print "Problemas com driver/sessao do roteador %s" % router['ip']
  print error

#FIM


Quando executamos o script:

jose@rejane:~/Automatizacao$ ./napalm_newconf_ex3.py 
Problemas com driver/sessao do roteador 2.2.2.2
RpcTimeoutError(host: 2.2.2.2, cmd: commit-configuration, timeout: 60)
jose@rejane:~/Automatizacao$ 

Podemos apreciar que ao executar o script,  NAPALM atacha um erro no "commit_config()" para R2, esse erro acontece pelo fato de que quando o commit é executado em R2, automaticamente a nossa conexão ao roteador é perdida. O NAPALM não recebe a resposta do "commit" em R2 e atacha o erro acima. Mas a configuração foi aplicada em R2, a única coisa que falto foi o NAPALM receber a resposta. Resumindo o erro é na livraria do NAPALM e não no "commit" em R2.

O ideal é não perder a conetividade, quem sabe manter o OSPF rodando, mas para própositos de testes e de saber como funcionam as coisas, esta tudo OK.

Verificando em R1:

R1#sh ip bgp summary 
BGP router identifier 1.1.1.1, local AS number 100
BGP table version is 5, main routing table version 5
4 network entries using 592 bytes of memory
4 path entries using 256 bytes of memory
2/2 BGP path/bestpath attribute entries using 272 bytes of memory
1 BGP AS-PATH entries using 24 bytes of memory
0 BGP route-map cache entries using 0 bytes of memory
0 BGP filter-list cache entries using 0 bytes of memory
BGP using 1144 total bytes of memory
BGP activity 4/0 prefixes, 4/0 paths, scan interval 60 secs

Neighbor        V           AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
10.10.10.2      4          200      45      45        5    0    0 00:18:38        2
R1#sh ip bgp
BGP table version is 5, local router ID is 1.1.1.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal, 
              r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter, 
              x best-external, a additional-path, c RIB-compressed, 
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found

     Network          Next Hop            Metric LocPrf Weight Path
 *>  1.1.1.0/24       0.0.0.0                  0         32768 i
 *>  2.2.2.0/24       10.10.10.2                             0 200 i
 r>  10.10.10.0/24    10.10.10.2                             0 200 i
 *>  192.168.200.0    0.0.0.0                  0         32768 i
R1#



Verificando em R2:

napalm@JunOS-R2> show bgp summary 
Groups: 1 Peers: 1 Down peers: 0
Table          Tot Paths  Act Paths Suppressed    History Damp State    Pending
inet.0                 2          2          0          0          0          0
Peer                     AS      InPkt     OutPkt    OutQ   Flaps Last Up/Dwn State|#Active/Received/Accepted/Damped...
10.10.10.1              100         43         43       0       0       17:57 2/2/2/0              0/0/0/0

napalm@JunOS-R2> 

napalm@JunOS-R2> show route          

inet.0: 6 destinations, 6 routes (6 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

1.1.1.0/24         *[BGP/170] 00:18:18, MED 0, localpref 100
                      AS path: 100 I
                    > to 10.10.10.1 via em0.0
2.2.2.0/24         *[Direct/0] 01:00:02
                    > via lo0.0
2.2.2.2/32         *[Local/0] 01:00:02
                      Local via lo0.0
10.10.10.0/24      *[Direct/0] 01:00:03
                    > via em0.0
10.10.10.2/32      *[Local/0] 01:00:03
                      Local via em0.0
192.168.200.0/24   *[BGP/170] 00:05:38, MED 0, localpref 100
                      AS path: 100 I
                    > to 10.10.10.1 via em0.0

napalm@JunOS-R2> 


Podemos ver que o BGP foi estabelecido e as rotas tb estão OK.

Desde o host conseguimos pingar tanto para R1 e R2.

jose@rejane:~$ ping 1.1.1.1
PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
64 bytes from 1.1.1.1: icmp_seq=1 ttl=255 time=11.4 ms
64 bytes from 1.1.1.1: icmp_seq=2 ttl=255 time=9.09 ms
^C
--- 1.1.1.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 9.090/10.258/11.427/1.172 ms
jose@rejane:~$ ping 2.2.2.2
PING 2.2.2.2 (2.2.2.2) 56(84) bytes of data.
64 bytes from 2.2.2.2: icmp_seq=1 ttl=63 time=11.6 ms
64 bytes from 2.2.2.2: icmp_seq=2 ttl=63 time=20.1 ms
^C
--- 2.2.2.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 11.603/15.891/20.180/4.290 ms
jose@rejane:~$ 


Bom é isso ai pessoal, nesse três últimos post aprendimos como "coletar informação", "Atualizar a configuração" e "Reemplazar a configuração", utilizando a livraria NAPALM.

Os script são simples, visto que o próposito deles é o ensino, mas vocês podem incluir muitas coisas neles, como logs, entrada de teclado quem sabe ler as configurações dos roteadores de algum banco de dados etc etc..

O próximo post iremos falar de YAML e JINJA2..

Abçs e um ótimo final de semana!!
Jose



2 de mai de 2018

ISP Express - Produtos e Serviços Cisco com até 70% de desconto e Financiado em 60 X


O NetfindersBrasil, em parceria com a AINET - Associação dos Instrutores do NetAcad - passa agora a oferecer Produtos e Serviços da Cisco Syste para Provedores de Acesso Internet interessados.

Conheça o QuickSupport:

“O QuickSupport foi idealizado para oferecer com exclusividade aos Provedores de Serviços de Internet regionais (iSPs) uma série de serviços executados remotamente ou em loco por especialistas certificados pela Cisco, proporcionando recursos de suporte e manutenção durante a vida útil operacional dos equipamentos CISCO ”


• Através do contrato QuickSupport a AINET , Fornece:
• Monitoramento on-line ( snmp – noc) itens básicos do roteador e ou customizados em conjunto com o cliente
• Acesso por parte do Cliente de nossas ferramentas de monitoração (opcional)
• Cisco TotalCare proporciona recursos de suporte técnico premiados com qualificação para recursos inteligentes. Ele soluciona problemas com mais rapidez, aprimora a eficiência operacional e reduz seu risco de período de inatividade, aumentar a eficiência operacional
• Através de gerenciamento proativo
• Ferramentas e automatizadas
• Gerenciamento SmartNet (*)
• Suporte para Softwares de sistemas autorizados, Cisco IOS , incluindo manutenção e novos lançamentos.
• Gerenciamento ao TAC L3 24 horas por dia, 7 dias por semana
• Substituição avançada de hardware, 24 x 7 x 2 – com ou sem um engenheiro de campo ou – Próximo dia útil (NBD - Next Business Day)
• Equipe de suporte técnico para consultas e soluções de problemas
• Treinamento através de cursos presenciais ou on line a seus colaboradores para toda linha de roteadores CISCO ASR .
• Configuração e/ou acompanhamento das ativações das features e serviços agregados as plataformas ASR
• Administração , supervisão e manutenção
• Relatórios periódicos ou de Alerta de performance e Segurança de seu equipamento
A) Gerenciamento de Incidentes
B) Alertas de segurança de produto
C) Ciclo de vida dos produtos
D) Recomendações para correção de problemas
E) Vulnerabilidades de segurança associadas ao dispositivo
F) Registros de ameaças exibe a identificação da ameaça, a aplicação e a data e a hora e a origem
G) Localizações e IP de host de origem de ameaças
H) Tipo de ameaça por gravidade. Descreve o número de ameaças, classificado por gravidade
I) Consumo de largura de banda (bytes) . Exibe a largura de banda dos sistemas tornando fácil ver quais sistemas estão consumindo a maior largura de banda.

• Ações proativas por nossa equipe técnica
• Suporte remoto e local L1 –L2 –L3
• Aplicação de atualizações sempre que necessário


Quer adquirir Produtos e Soluções Cisco com os melhores preços do Mercado? Consulte-nos: isp.express@ainet.com.br





30 de abr de 2018

Curso de Python para Engenheiros de Redes


Foram-se os tempos em que um engenheiro de redes somente precisava conhecer o sistema operacional dos equipamentos de networking, seja ele Cisco IOS, JunOS, etc. Com a chegada das novas tendências de mercado, chegou o paradigma de DevOps, no qual os mundos de Desenvolvimento e Operações se fundiram a fim de obter uma melhor comunicação, colaboração e coesão entre estas áreas.

Descrição:

Segundo https://newrelic.com/devops/what-is- devops “Em vez de ter duas áreas diferentes, trabalhando digamos que de forma independente
uma da outra executando tarefas específicas; a metodologia DevOps reconhece uma interdependência de ambas as áreas. Dessa forma DevOps ajuda a desenvolver um software com maior agilidade, mantendo o serviço estavél, e ganhando a velocidade necessária para uma maior inovação.”

Um dos itens no paradigma de DevOps é o chamado “Infraestructure as Code IAC”, no qual um tem a capacidade de administrar e configurar toda uma infraestrutura de TI via código, em vez de ser um processo manual. O IAC se aplica ao mundo do Networking, onde temos por exemplo o conceito de SDN, no qual a camada de controle é desacoplada da camada de fordwarding. Dessa forma o controle é feito no chamado SDN Controller, e é ele que se encarrega de configurar as caixas de fordwarding, switches. Dessa forma toda à programação da sua rede você faz no SDN controller. Sendo assim, se faz necessário o aprendizado de alguma linguagem de programação afim de poder estar atualizados com as novas necessidades.

Porque python?

Não existe uma regra na linguagem de programação a ser utilizada no IAC, mas sendo python uma linguagem de fácil aprendizado, gratuito, com muitas livrarias, e com uma comunidade de desenvolvimento da linguagem sempre ativa; digamos que é a linguagem perfeita para nosso propósito, que é o de programar a nossa rede.


Metodologia E-Doing (Aprenda Fazendo):

Os alunos irão construindo exemplos práticos de Scripts em Sala de Aula para automatizar tarefas nos Ambientes Cisco, Juniper e Arista

Público-Alvo: Profissionais de TI que desejam dominar os fundamentos da Programação em Python voltada para a Carreira de Routing & Switching.

Local:

Rua Marquês de Itu, 408 - Conjunto 24
Vila Buarque - São Paulo - SP (Próximo a Estação República do Metrô)


Obs: Os alunos poderão optar por participar de forma presencial (apenas 10 vagas) ou remotamente, em Tempo Real, deste curso via Plataforma Wiziq (limitado a 50 vagas)


Conteúdo Programático:

1. Linux para Sobrevivientes.
- Tipos de Usuários.
- Navegando nos diretórios Linux.
- Aprendendo a lidar com arquivos, permissões de arquivos.
- Aprendendo a lidar com processos.
- Instalação de pacotes em Ubuntu.
- Ferramentas de networking, ping trace, netstat, ifconfig etc

2. Python
- Porque Python?
- Qual versão de python utilizar?
- Linux ou Windows?
- Paradigmas da programação
- O interpretador de python, variáveis e estrutura de dados.
- Python em modo scripting, Indentação.
- Sentenças de Programação
+"if"
+"for"
+"while"
+"break"
- Funções.
- Tratamento de Exceções.
- Utilizando módulos, instalando módulos com "pip".
- Operações em Arquivos, sentença with.
- operações em Banco de Dados, exemplo MySql.

3. Aprendendo a Utilizar PARAMIKO.

4. APIs,REST,JSON,YAML e JINJA2. Exemplo utilizando Arista eAPI.

5. NetMiko, coleta de informação e modificação de configurações. Lab com Cisco IOS e IOS-XR.

6. NAPALM, coleta de informação e modificação de configurações. Lab Com Cisco IOS e JunOS.

Periodo:

Turma em Horário Comercial: De 04/06/2018 até 08/06/2018 - das 09:00 as 18:00 - com intervalo de 01 hora para almoço e coffee-breaks nos períodos da manhã e tarde

Turma no período Noturno: De 04/06/2018 até 08/06/2018 e de 11/06/2018 até 15/06/2018 - das 19:00 as 23:00 horas

Carga Horária: 40 horas

Investimento:

R$ 1.190,00 - Podendo ser parcelado em até 12X via PagSeguro


Mini-Curriculum do Instrutor:

José Balbuena - CCIE R&S #35681 - profissional com muitos anos de experiência na área de Redes de Computadores e que nos últimos anos tem trabalhado como sysadmin com diversas tecnologias emergentes, especialmente Big Data, Virtualização e DevOps.

Está longe de SP ? Acompanhe o curso remotamente em Tempo Real!!!

Garanta já a sua vaga comprando este curso pelo botão abaixo:









Dúvidas ? Envie- e-mail para adilson.aflorentino@eamsoft.com.br

NAPALM - Parte II

Olá Pessoal Boa Tarde, hoje vamos continuar com o nosso segundo post sobre NAPALM. Dessa vez vamos utilizar o NAPALM, para alterar configurações em nossos dispositivos de redes.

O nosso LAB vai ser o mesmo do post anterior:


O Roteador R1, é um Cisco IOS, e  R2 um JunOS. Para o NAPALM trabalhar corretamente em Cisco IOS, precisamos que o dispositivo tenha um lugar onde sejam armazenados os arquivos de configuração. Para o caso de Cisco IOS vamos utilizar a funcionalidade de "archive" e vou adicionar um disco "PCMCIA disk0:" no meu roteador 7200 emulado via GNS3. Podem também ser utilizados o "flash:", "bootflasg:" p.e

R1#sh disk0:
Unformatted Partition, please format it.
R1#format disk0:
Format operation may take a while. Continue? [confirm]
Format operation will destroy all data in "disk0:".  Continue? [confirm]

Primary Partition created...Size 10 MB

Drive communication & 1st Sector Write OK...
Writing Monlib sectors....
Monlib write complete 

Format: All system sectors written. OK...

Format: Total sectors in formatted partition: 20448
Format: Total bytes in formatted partition: 10469376
Format: Operation completed successfully.

Format of disk0: complete
R1#sh disk0:    
No files on device

8380416 bytes available (1794048 bytes used)

R1#conf t
R1(config)#archive 
R1(config-archive)#path disk0:
R1(config)#ip scp server enable 

Além disso precisamos ter um usuário com privilege=15, para poder copiar os arquivos via SCP.

username napalm privilege 15 password 0 napalm

No caso de JunOS a única configuração necessária é ter habilitado os serviços SSH, NETCONF-SSH e ter um usuário da classe "super-user".

set system host-name R2
set system login user napalm class super-user
set system login user napalm authentication plain-text napalm
set system services ssh
set system services netconf ssh
set system domain-name R2.com

As configurações completas encontran-se em :

https://github.com/JoseBalbuena/BlogNetFinders

Alterando Configurações:

Imaginemos que nós é solicitado configurar o SNMP de ambos os roteadores de forma que eles enviem seus traps para o servidor de gerenciamento NMS com ip 3.3.3.3.

O primeiro passo é criar os arquivos de configuração. Vou criar "R1_snmp.conf" e "R2_snmp.conf"

R1:
jose@rejane:~/Automatizacao$ more R1_snmp.conf 
snmp-server community NAPALM RO
snmp-server host 3.3.3.3 version 2c NAPALM 
snmp-server enable traps
jose@rejane:~/Automatizacao$

R2:
jose@rejane:~/Automatizacao$ more R2_snmp.conf 
set snmp description "R2 - SNMP Configurado via NAPALM"
set snmp community NAPALM
set snmp trap-group NAPALM targets 3.3.3.3
jose@rejane:~/Automatizacao$ 


Vamos mostrar o que NAPALM faz por trâs dos panos para o caso de Cisco IOS. Para isso vamos iniciar o python em modo interativo e abrir uma sessão em R1:

jose@rejane:~/Automatizacao$ python
Python 2.7.6 (default, Oct 26 2016, 20:30:19) 
[GCC 4.8.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import napalm
>>> driver = napalm.get_network_driver('ios')
>>> device = driver('1.1.1.1','napalm','napalm',optional_args={'secret':'cisco'})
>>> device.open()
>>> device.load_merge_candidate(filename='R1_snmp.conf')


O método utilizado é o load_merge_candidate(), o método load_merge_candidate irá juntar a configuração atual com a nossa nova configuração.

Quando enviamos o load_merge_candidate(), em R1 foi criado um arquivo chamado merge_config.txt

R1#sh disk0: 
-#- --length-- -----date/time------ path
1          101 Apr 30 2018 14:18:22 +00:00 merge_config.txt

8376320 bytes available (1798144 bytes used)

R1#


Até agora somente temos feito um upload do arquivo de configuração. Vamos colocar ele em operaçao:

>>> device.commit_config()

Em R1 vamos ver que apareceu um arquivo chamado rollback_config.txt

R1#sh disk0: 
-#- --length-- -----date/time------ path
1          101 Apr 30 2018 14:18:22 +00:00 merge_config.txt
2         1344 Apr 30 2018 14:22:14 +00:00 rollback_config.txt

8372224 bytes available (1802240 bytes used)

R1#


Verificando R1, podemos apreciar que a nova configuração foi aplicada:

R1#sh run | inc snmp
snmp-server community NAPALM RO
snmp-server enable traps snmp authentication linkdown linkup coldstart warmstart
snmp-server enable traps vrrp
snmp-server enable traps flowmon
.....
.....
snmp-server enable traps vrfmib vrf-up vrf-down vnet-trunk-up vnet-trunk-down
snmp-server host 3.3.3.3 version 2c NAPALM 
R1#

Agora se quisernos fazer rollback, voltar a configuração anterior:

>>> device.rollback()
>>> 

E R1 voltará a configuração anterior:

R1#sh run | inc snmp
R1#

Em R2 podemos fazer a mesma coisa, lembrando que NAPALM utiliza para JunOS o driver pyEZ que se comunica com os roteadores via protocolo NETCONF. 

>>> driver = napalm.get_network_driver('junos')
>>> device = driver('2.2.2.2','napalm','napalm123')
>>> device.open()
>>> device.load_merge_candidate(filename='R2_snmp.conf')
>>> 
>>> device.commit_config()
>>>

Em R2:

....
....
snmp {
    description "R2 - SNMP Configurado via NAPALM";
    community NAPALM;
    trap-group NAPALM {
        targets {
            3.3.3.3;
        }
    }
}
....
....


O nosso script final ficaria(esse é um script básico, da para melhorar colocando alguns prints para saber o que ele esta fazendo, algum arquivo de logging etc) :

jose@rejane:~/Automatizacao$ more napalm_alterconf_ex2.py 
#!/usr/bin/python

import napalm

#Router diccionario
R1={'so':'ios','hostname':'R1','ip':'1.1.1.1','username':'napalm','password':'napalm','secret':'cisco','alterfile':'/home/jose/Automatizacao/R1_snmp.c
onf'}
R2={'so':'junos','hostname':'R2','ip':'2.2.2.2','username':'napalm','password':'napalm123','alterfile':'/home/jose/Automatizacao/R2_snmp.conf'}

#Listado dos meus roteadores
routers=[R1,R2]


#BEGIN


#Loop para fazer varredura
for router in routers:
 #Caso seja um roteador IOS, utilizar o parametro optional_args com a senha de enable
 if router['so'] == 'ios':
  optional_args={'secret':router['secret']}
 else:
  optional_args={}
 #Selecctiona o driver
 driver = napalm.get_network_driver(router['so'])
 #Coneta ao roteador, dentro de um try..execpt, caso de algum erro o erro eh printado
 try:
  device = driver (hostname=router['ip'], username=router['username'], password=router['password'],optional_args=optional_args)
  device.open()
  #Carrega o arquivo das atualizacoes a serem feitas
  device.load_merge_candidate(filename=router['alterfile'])
  #Fecha a conexao
  device.close()
 except Exception as error:
  print "Problemas com driver/sessao do roteador %s" % router['ip']
  print error

#FIM

Executando o script não recebemos nenhum erro:

jose@rejane:~/Automatizacao$ ./napalm_alterconf_ex2.py 
jose@rejane:~/Automatizacao$ 

E verificando R1 e R2, as configurações foram aplicadas com sucesso:

R1#sh run | inc snmp
snmp-server community NAPALM RO
snmp-server enable traps snmp authentication linkdown linkup coldstart warmstart
snmp-server enable traps vrrp
snmp-server enable traps flowmon
.....
.....
snmp-server enable traps vrfmib vrf-up vrf-down vnet-trunk-up vnet-trunk-down
snmp-server host 3.3.3.3 version 2c NAPALM 
R1#



....
....
snmp {
    description "R2 - SNMP Configurado via NAPALM";
    community NAPALM;
    trap-group NAPALM {
        targets {
            3.3.3.3;
        }
    }
}
....
....


Por hoje é isso pessoal...semana que vem vamos utilizar NAPALM, para carregar toda uma configuração nova em nosos dispositivos.

Abçs e Bom Feriado
Jose

22 de abr de 2018

Oficina de MPLS e VPN L3 - Lab 100% Hands-On


Curso voltado a criação de Redes MPLS e VPN L3 em Roteadores Cisco - Assista de Forma Remota ou Presencial!!!

Descrição:

O MPLS (Multiprotocol Label Switching) é uma técnica de Comutação baseada em LAbels muito utilizada no Ambiente de Service Providers. Este curso se propõe a realizar, de forma prática, a configuração e o Troubleshooting de Redes MPLS em Ambiente Cisco de forma 100% prática através de um Estudo de Caso.

Metodologia E-Doing (Aprenda Fazendo):

Os alunos irão construir um cenário a partir do zero, levantando todas as configurações, de modo a ter um exemplo de um Core MPLS, com roteadores PE e P, interligados a Roteadores de Cliente (CE) configurando todos os protocolos necessários para tornar a Rede estável e segura.

Público-Alvo: Profissionais de TI que desejam dominar os fundamentos de MPLS para prestar Exames Cisco da Carreira de Routing & Switching e Service Provider ou para melhorar suas capacidades de configuração e troubleshooting em Roteadores Cisco de forma a melhor atuar no Mundo Corporativo.

Local:

Rua Marquês de Itu, 408 - Conjunto 24
Vila Buarque - São Paulo - SP (Próximo a Estação República do Metrô)
Obs: Os alunos poderão optar por participar de forma presencial (apenas 10 vagas) ou remotamente, em Tempo Real, desta Oficina via Plataforma Wiziq (limitado a 50 vagas)


Conteúdo Programático:

Dia 01
Fundamentos de MPLS:
- Arquitetura IP MPLS
- Surgimento da tecnologia
- Roteamento convencional X baseado em rótulos
- O cabeçalho MPLS
- Estrutura MPLS
- Componentes da arquitetura
- Funcionamento
- vantagens e desvantagens do MPLS

Implementação pura de MPLS no backbone IP:
- Topologia de teste utilizada
- Configurações IP da topologia de teste
- endereços nas interfaces
- protocolo de roteamento interno
- testes de conectividade
- Configurações de MPLS na topologia de teste
- testes de conectividade relativos ao MPLS

MPLS e VPN de camada 3
- VPN's - Conceito
- Tipos de VPN
- Arquitetura IP VPN MPLS
- Configurações relativas a criação das VPN's
- BGP e MPBGP
- Testes de conectividade das VPN's criadas
- Configurando VRFs para servir o lado cliente
- Integração com protocolos de roteamento OSPF, IS-IS
- Uso de rotas estáticas


Dia 02
QOS com MPLS:
- Conceitos de QoS
- Modelo de Serviços Integrados
- Modelo de Serviços Diferenciados
- Como prover Eficiência no Link
- Uso de DSCP com labels MPLS

Engenharia de tráfego com MPLS
- Conceitos fundamentais
- A engenharia de tráfego sobre MPLS
- Extensões do OSPF para engenharia de tráfego
- Extensões do IS IS para engenharia de tráfego
- Protocolo RSVP TE
- Operação do MPLS TE
- Atributos de túneis MPLS TE
- Proteção e restauração FRR GMPLS

Pseudowire:
- AToM - Any Transport over MPLS
- Ethernet
- Frame Relay
- ATM—AAL5, cell mode
- PPP
- Cisco HDLC

IPV6 sobre MPLS:
- O protocolo IPv6
- Endereçamento IPv6
- Técnica 6PE
- Técnica 6VPE

Diferenciais:

Uso do Emulador EVE (Emulated Virtual Environment) que permite a criação de cenários Multivendor com soluções de dezenas de fabricantes. Os alunos poderão baixar e criar seu próprio servidor local, de modo a utiliza-lo para testes e homologação de cenários de Redes Reais.
120 dias de acesso a Plataforma NetFindersBrasil, onde o aluno poderá interagir via Fóruns de Aula para sanar suas dúvidas após a realização do Treinamento

Periodo:

Dias 12/05/2018 e 19/05/2018 - das 09:00 as 18:00 - com intervalo de 01 hora para almoço e coffee-breaks nos períodos da manhã e tarde

Carga Horária: 16 horas

Investimento:

R$ 590,00 - Podendo ser parcelado em até 12X via PagSeguro

Mini-Curriculum do Instrutor:
·Adilson Aparecido Florentino é Tecnólogo em Processamento de Dados pela Universidade Mackenzie e Especialista em Redes de Computadores pela FASP - Faculades Associadas de São Paulo. Atua como Instrutor Cisco desde 2001, primeiro no Programa Cisco Network Academy e atualmente como Instrutor Cisco CCSI # 33706.Possui as Certificações CCNA RS, CCNA Voice, CCNA Security, CCNA Wireless, CCDA, CCDP e CCNP RS.
·Fundador e CEO da EAMSOFT Consultoria e Treinamento em Informática Ltda. Atuou como Professor Universitário em diversas Instituições de Ensino tais como FATEC, IFSP, UNICID, FIAP e IBTA. Prestador de SErviços para o NIC.br nos cursos de IPv6 e Boas Práticas em BGP
·Autor do Livro IPv6 na Prática - primeiro livro em português sobre o tema. Consultor independente atuando em várias empresas em Projetos de Rede e treinamento utilizando roteadores Cisco, Juniper e Mikrotik

Está longe de SP ? Acompanhe o curso remotamente em Tempo Real!!! Garanta já a sua vaga comprando esta Oficina Hand-On pelo botão abaixo:








Maiores Informações, envie e-mail para adilson.aflorentino@eamsoft.com.br




NAPALM - Parte 1



Como já sabemos utilizar o Netmiko, hoje vou lhes apresentar uma ferramenta chamada de NAPALM (Network Automation and Programmability Abstraction Layer with Multivendor support).

NAPALM nasceu como o objetivo de ser uma livraria única de comunicação com dispositivos de diferentes sistemas operacionais e diferentes fabricantes, IOS, IOS-XR, NX-OS, JunOS etc.

NAPALM é um 'wrapper' em linguagem de programação, é dizer é uma função que chama a outra função, no caso de NAPALM ele chama as livrarias de conexão como Netmiko para IOS, pyeapi para EOS etc. Segue o link onde mostra quais livrarias o NAPALM utiliza:

https://napalm.readthedocs.io/en/latest/support/index.html

NAPALM, executa operações em arquivos dentro dos dispositivos, com o objetivo de mudar configuração, adicionar alguma configuração nova a uma já existente, ou simplesmente executar operações de comparação entre configurações. NAPALM também tem algumas operações de coleta de informação, via funções "get". O listado completo das funções get também encontra-se no link anterior.

Instalando NAPALM

Para instalar o NAPALM basta enviar o comando:

jose@rejane:~$ sudo pip install napalm


Utilizando o NAPALM

Para utilizar o NAPALM via python, precisamos chamar a livraria via comando import:

import napalm

Com a livraria carregada, precisamos escolher qual driver utilizar, isso depende do dispositivo com o qual queremos trabalhar:

driver = napalm.get_network_driver('Nome_do_driver')

Por exemplo se desejamos nós conetar a um dispositivo EOS, colocamos:

driver = napalm.get_network_driver('eos')

Uma vez escolhido o driver, precisamos utilizar o mesmo para abrir uma conexão ao dispositivo, lembrando que o metodo de transporte utilizado depende do driver a ser utilizado p.e para Cisco IOS o transporte é via SSH, para NXOS é via NX-OS API ou seja HTTP/HTTPS e por ai vai.

device = driver(hostname, username, password, timeout=60, optional_args=None)

Exemplo:

device = driver (hostname='1.1.1.1', username='cisco', password='cisco', timeout=60,optional_args={'secret': cisco}


Depois é somente abrir a conexão e começar a trabalhar :) 

device.open()

Exemplo

Nesse post vamos utilizar NAPALM para coletar informação dos nossos dispositivos.

Eu vou utilizar a seguinte topologia:



Dessa vez vou utilizar um roteador Cisco IOS, R1 e um JunOS R2. Ambos rodam OSPF, tem SSH configurado e o acesso a eles é via interfaces de Loopback:

R1: Lo0 1.1.1.1
R2: Lo0 2.2.2.2

Eu vou utilizar NAPALM com o próposito de coletar informação sobre os roteadores.

Carregando a livraria NAPALM no meu script python:

#!/usr/bin/python

import napalm

Criando um diccionário para cada roteador, e logo uma lista com ambos os roteadores:

R1={'so':'ios','hostname':'R1','ip':'1.1.1.1','username':'napalm','password':'napalm','secret':'cisco'}
R2={'so':'junos','hostname':'R2','ip':'2.2.2.2','username':'napalm','password':'napalm123'}

routers=[R1,R2]

Agora preciso fazer um loop para varrer todos os roteadores da minha lista. Existe um detalhe os roteadores Cisco IOS foram configurados com uma senha de enable, então preciso ter isso em consideração:

for router in routers:
 if router['so'] == 'ios':
  optional_args={'secret':router['secret']}
 else:
  optional_args={}


O código acima diz: "faz uma varredura para todos os meus roteadores na lista routers, caso sejam IOS coloca como argumento adicional a senha de enable

Dentro do loop, eu vou abrir  a conexão remota ao roteador e executar o método get_facts(). Tudo isso dentro de um "try...except" caso de algum problema na conexão para algum dos roteadores.

 driver = napalm.get_network_driver(router['so'])
 try:
  device = driver (hostname=router['ip'], username=router['username'], password=router['password'],optional_args=optional_args)
  device.open()
  router_facts = device.get_facts()
  print router_facts
  device.close()
 except Exception as error:
  print "Problemas com driver/sessao do roteador %s" % router['ip']
  print error 

O código completo ficaria:

#!/usr/bin/python

import napalm

#Router diccionario
R1={'so':'ios','hostname':'R1','ip':'1.1.1.1','username':'napalm','password':'napalm','secret':'cisco'}
R2={'so':'junos','hostname':'R2','ip':'2.2.2.2','username':'napalm','password':'napalm123'}

#Listado dos meus roteadores
routers=[R1,R2]


#BEGIN
#Loop para fazer varredura
for router in routers:
 #Caso seja um roteador IOS, utilizar o parametro optional_args com a senha de enable
 if router['so'] == 'ios':
  optional_args={'secret':router['secret']}
 else:
  optional_args={}
 #Selecctiona o driver
 driver = napalm.get_network_driver(router['so'])
 #Coneta ao roteador, dentro de um try..execpt, caso de algum erro o erro eh printado
 try:
  device = driver (hostname=router['ip'], username=router['username'], password=router['password'],optional_args=optional_args)
  device.open()
  #Executa o metodo get_facts
  router_facts = device.get_facts()
  #Imprime o resultado do get_facts, o resultado eh uma variavel do tipo diccionario
  print ("---------------- %s ---------------------" % router['hostname'])
  print router_facts
  #Fecha a conexao
  device.close()
 except Exception as error:
  print "Problemas com driver/sessao do roteador %s" % router['ip']
  print error

#FIM

Ao executar o script, obtenho como resultado:

jose@rejane:~/Automatizacao$ ./napalm_ex1.py 
---------------- R1 ---------------------
{u'os_version': u'7200 Software (C7200-ADVENTERPRISEK9-M), Version 15.2(4)M9, RELEASE SOFTWARE (fc2)', u'uptime': 14040, u'interface_list': [u'FastEthernet0/0', u'FastEthernet1/0', u'Loopback0'], u'vendor': u'Cisco', u'serial_number': u'4279256517', u'model': u'7206VXR', u'hostname': u'R1', u'fqdn': u'R1.R1.com'}
---------------- R2 ---------------------
{u'os_version': u'12.1R1.9', u'uptime': 21092, u'interface_list': ['.local.', 'cbp0', 'demux0', 'dsc', 'em0', 'em1', 'gre', 'ipip', 'irb', 'lo0', 'lsi', 'mtun', 'pimd', 'pime', 'pip0', 'pp0', 'tap'], u'vendor': u'Juniper', u'serial_number': u'None', u'model': u'OLIVE', u'hostname': u'JunOS-R2', u'fqdn': u'JunOS-R2.R2.com'}
jose@rejane:~/Automatizacao$ 


Bom Pessoal por hoje é isso, de momento temos utilizado o NAPALM somente para coletar informação. O próximo post vamos utilizar ele para operações de configuração.

Abcs e Obrigado!!
Jose

16 de abr de 2018

Fazendo Backup de Routers Cisco IOS utilizando Netmiko

Olá Pessoal Boa Tarde, depois de um tempo sumido por problemas diversos vamos continuar com nossos posts de automatização.

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 código acima pode ser explicado como: "para cada roteador, abre uma sessão SSH, troca para o modo enable,executa o comando "sh run", printa na tela o resultado ...logo sai do enable, e fecha a conexão"....Simples verdad!!..

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()

Vamos rodar ele e ver o que acontece:

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$ 

Ele nao mostra nada na tela, isso esta ok. Vejamos o diretório de backup:

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$ 

O arquivo log ficou OK também. E ele nos informa da falha na conexão ao roteador 3.3.3.3.

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

LinkWithin

Related Posts with Thumbnails