cancelar
Mostrar resultados para 
Pesquisar em vez de 
Queria dizer: 
cancel
576
Apresentações
7
Útil
6
Comentários
natanael0liveira
Spotlight
Spotlight

     Pouco tempo atrás, me deparei com uma demanda desafiadora que exigia uma automação rápida e confiável, na qual seria necessário acelerar ao máximo a convergência de rede, com foco na degradação de links. Sabemos, porém, que existem diversas variáveis que podem causar degradação da conectividade. Ainda assim, a tolerância deveria ser muito bem ajustada, pois, afinal, a diferença entre o remédio e o veneno está na dose. Uma convergência ativada de forma precoce pode gerar resultados indesejados, assim como uma tolerância exagerada pode acabar impactando negativamente a experiência do usuário.

     Seria capaz de apostar que você pensou no tradicional SD-WAN como solução. Em ambientes empresariais e com soluções prontas, bastariam alguns cliques para alcançar o resultado desejado. Entretanto, o cenário possuía algumas variáveis específicas, como sessões BGP com prefixos próprios e conexões entre sites ao redor do globo que exigiam alta performance. Além disso, tratava-se de um ambiente multivendor, no qual o SD-WAN tradicional não se encaixa. Bem sabemos que a convergência natural do BGP é lenta e que, mesmo utilizando BFD como suporte, ainda há espaço para melhorias em cenários onde não ocorrem quedas de sessão, mas sim degradações “silenciosas”.

     Na busca por automações performáticas e lineares, sempre partindo de um fluxo bem definido, compreendendo a lógica do que precisava ser alcançado e como, decidi testar, como solução alternativa, as funcionalidades de bash/shell disponibilizadas pelos fabricantes, que, diga-se de passagem, são pouco divulgadas.

     Por exemplo, a plataforma NX-OS apresenta um contêiner especializado, pré-construído e instalado no sistema. Esse ambiente de contêiner é chamado de guest shell e é baseado no CentOS 7

07fig03.jpg

     Ele possui diversas funções e oferece benefícios importantes que auxiliam desenvolvedores na criação e hospedagem de aplicativos em plataformas Nexus, como acesso à rede, à CLI do NX-OS, ao sistema de arquivos bootflash e, principalmente, a capacidade de instalar scripts Python e aplicativos Linux.

     Além disso, o switch Nexus conta com um interpretador Python diretamente acessível pela CLI, o que permite o uso de diversos módulos essenciais para a operação de dispositivos de rede, como interfaces, VLANs, VRFs, ACLs e rotas, conforme demonstrado a seguir.

switch# python3
Python 3.7.3 (default, Nov 20 2019, 14:38:01)
[GCC 5.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cisco
>>> help(cisco)
Help on package cisco:

NAME
cisco

PACKAGE CONTENTS
acl
bgp
buffer_depth_monitor
check_port_discards
cisco_secret
feature
historys
interface
ipaddress
key
line_parser
mac_address_table
md5sum
nxcli
nxos_cli
ospf
routemap
routes
section_parser
ssh
system
tacacs
transfer
vlan
vrf

CLASSES
builtins.dict(builtins.object)
cisco.history.History
builtins.object
cisco.cisco_secret.CiscoSecret
cisco.interface.Interface
cisco.key.Key

     Isso possibilita uma expansão significativa da usabilidade do dispositivo, pois o leque de possibilidades torna-se muito mais amplo. Dessa forma, é possível tomar decisões diretamente no equipamento, baseadas em lógicas que fazem sentido para a organização, sem a dependência de sistemas fechados ou soluções proprietárias.

     No meu caso de uso, esse formato permitiu manter coerência entre diferentes fabricantes, utilizando a mesma lógica padrão para alcançar o que denominei de path adaptativo. Para isso, foram empregadas funcionalidades como comunidades, expressões regulares e outras manipulações de atributos de roteamento, sempre orientadas por intenção e inteligência, com foco na remediação baseada em degradação de performance.

     A seguir, apresento um pequeno exemplo, sem grande complexidade, de como utilizar essa funcionalidade em um switch Cisco Nexus.

  • Verificar se o bash está ativado:
switch(config)# feature bash-shell
  •  Acessar o bash:
switch# run bash 
  • Acessar o diretório ( aqui você esta no linux do sistema então pode explorar o que bem entender
bash-4.2# cd /bootflash/scripts 
  • Caso deseje, pode listar os arquivos com ls -l;
  • Criar seu arquivo python:
bash-4.2# vi ciscocommunity.py
  1. Defina o localizador do interpretador que o CLI irá chamar: #!/isan/bin/python3
  2. Defina módulos e funções, ex: from cli import *

      Agora vamos a um código de fictício que executa o comando "show bgp ipv4 unicast summary" e retorna apenas o ASN e a quantidade de prefixos, em formato JSON, filtrando exclusivamente sessões eBGP e excluindo sessões iBGP.

#!/isan/bin/python3
from cli import cli
import json
import re
from collections import defaultdict

# Ajuste o AFI/SAFI conforme seu caso:
CMD = "show bgp ipv4 unicast summary | json"

def to_int_maybe(v):
    """Converte '123', 123 -> 123. Se for 'Idle', 'Active', etc -> None."""
    if v is None:
        return None
    if isinstance(v, int):
        return v
    if isinstance(v, str) and re.fullmatch(r"\d+", v.strip()):
        return int(v.strip())
    return None

def main():
    raw = cli(CMD)
    data = json.loads(raw)

    # Estrutura varia um pouco por release.
    # Vamos achar uma lista/dict de neighbors de forma tolerante.
    neighbors = None

    # Alguns NX-OS usam algo como: TABLE_vrf -> ROW_vrf -> TABLE_neighbor -> ROW_neighbor
    # Outros: "neighbors" direto.
    if "neighbors" in data:
        neighbors = data["neighbors"]
    else:
        # tentativa comum no estilo NX-OS JSON
        try:
            vrf = data.get("TABLE_vrf", {}).get("ROW_vrf", data.get("vrf", {}))
            tbl = vrf.get("TABLE_neighbor") or vrf.get("TABLE_neigh") or {}
            neighbors = tbl.get("ROW_neighbor") or tbl.get("ROW_neigh")
        except Exception:
            neighbors = None

    if neighbors is None:
        raise SystemExit("Não consegui localizar neighbors no JSON. Rode o comando e ajuste o path no parser.")

    # Quando tem 1 neighbor, às vezes vem dict; com vários, vem list
    if isinstance(neighbors, dict):
        neighbors = [neighbors]

    routes_by_asn = defaultdict(int)

    for n in neighbors:
        # campos típicos (podem variar por versão):
        # - remoteAs / remote_as
        # - localAs / local_as
        # - statePfxRcd / state_pfxrcd / pfxrcd
        remote_as = n.get("remoteAs") or n.get("remote_as") or n.get("remoteas")
        local_as  = n.get("localAs")  or n.get("local_as")  or n.get("localas")

        # Se não tiver local_as no JSON, dá pra setar manualmente (seu AS) aqui.
        # local_as = local_as or 52580

        if remote_as is None or local_as is None:
            continue

        # Filtra somente NÃO-iBGP (eBGP): remote-as != local-as
        if int(remote_as) == int(local_as):
            continue

        # Em "summary", o campo "State/PfxRcd" vira número quando Established.
        pfx = (
            n.get("statePfxRcd") or n.get("state_pfxrcd") or n.get("pfxRcd") or
            n.get("pfxrcd") or n.get("prefixReceived") or n.get("prefix_received")
        )
        pfx_int = to_int_maybe(pfx)
        if pfx_int is None:
            # Não Established / sem prefixos numéricos
            continue

        routes_by_asn[int(remote_as)] += pfx_int

    # Saída: "ASN: numero_de_rotas"
    for asn in sorted(routes_by_asn):
        print(f"{asn}: {routes_by_asn[asn]}")

if __name__ == "__main__":
    main()

     Salve o arquivo e retorne ao CLI, com isso, já é possível definir gatilhos ou simplesmente executar o código manualmente diretamente. Nesse caso, a execução seria feita da seguinte forma:

switch# source ciscocommunity.py 

     Alternativamente, pode-se configurar uma rotina EEM para executar o script automaticamente sempre que uma sessão BGP cair ou voltar a se estabelecer. De qualquer maneira, conforme o proposto, supomos que neste equipamento temos 3 sessões eBGP com os ASNs 65101, 65102 e 65103 onde o ASN local ( iBGP ) seria o 65410 e todas estão estabelecidas. O output esperado seria algo semelhante a:

65101: 240325
65102: 908500
65103: 135590

      Indo muito além disso, comandos de configuração podem ser utilizados para construir soluções personalizadas, adaptadas às particularidades de cada ambiente. Espero que este artigo tenha ajudado você a descobrir mais uma opção extremamente poderosa para o seu dia a dia como engenheiro de redes !

As referências a seguir foram utilizadas como base para compreender e validar os conceitos de programabilidade, automação e execução de scripts Python on-box em plataformas Cisco Nexus.

Referências

  1. Cisco Systems, Inc.
    Cisco Nexus 7000 Series NX-OS Programmability Guide.
    Disponível em:
    https://www.cisco.com/c/en/us/td/docs/switches/datacenter/nexus7000/sw/programmability/guide/b_Cisco_Nexus_7000_Series_NX-OS_Programmability_Guide/b_Cisco_Nexus_7000_Series_NX-OS_Programmability_Guide_chapter_0100.html

  2. Cisco Press.
    Programmability and Automation in Cisco Nexus Switches.
    Disponível em:
    https://www.ciscopress.com/articles/article.asp?p=3089355&seqNum=3

  3. Cisco Systems, Inc.
    Cisco Nexus 9000 Series NX-OS Programmability Guide (Release 9.3x).
    Disponível em:
    https://www.cisco.com/c/en/us/td/docs/switches/datacenter/nexus9000/sw/93x/progammability/guide/b-cisco-nexus-9000-series-nx-os-programmability-guide-93x/b-cisco-nexus-9000-series-nx-os-programmability-guide-93x_chapter_0101100.html

  4. NetworkEvolution (YouTube).
    NX-OS Programmability and Automation Overview.
    Disponível em:
    https://www.youtube.com/watch?v=BgNW6JRWmpM

Comentários
Assis Teixeira
Spotlight
Spotlight

Show de Bola, ótimo artigo!

rodrigo-freitas
Level 1
Level 1

Excelente post! Parabéns

@natanael0liveira ,

 obrigado por compartilhar ... adoro automações, principalmente em Python (ao qual tenho um carinho especial) !

 

natanael0liveira
Spotlight
Spotlight
natanael0liveira
Spotlight
Spotlight

@Marcelo Morais a possibilidade de usar o bash aumenta em muito os use cases possíveis do equipamento e realmente adicionando o python nesse jogo fica bom demais! Obrigado pela leitura.

Baita artigo! Obrigado por compartilhar, ficou bem explicativo e compreensível!

Primeiros Passos

Encontre respostas, faça perguntas e conecte-se com nossa comunidade de especialistas da Cisco de todo o mundo.

Estamos felizes por você estar aqui! Participe de conversas e conecte-se com sua comunidade.