em 12-15-2025 03:30 AM
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
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.
switch(config)# feature bash-shell
switch# run bash
bash-4.2# cd /bootflash/scripts
bash-4.2# vi ciscocommunity.py
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.
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
Cisco Press.
Programmability and Automation in Cisco Nexus Switches.
Disponível em:
https://www.ciscopress.com/articles/article.asp?p=3089355&seqNum=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
NetworkEvolution (YouTube).
NX-OS Programmability and Automation Overview.
Disponível em:
https://www.youtube.com/watch?v=BgNW6JRWmpM
Show de Bola, ótimo artigo!
Excelente post! Parabéns
obrigado por compartilhar ... adoro automações, principalmente em Python (ao qual tenho um carinho especial) !
Obrigado @Assis Teixeira e @rodrigo-freitas !
@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!
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.
Navegue pelos links rápidos da Comunidade e usufrua de um conteúdo personalizado e em seu idioma nativo: