Tabelas e visualizações com Junos Pyez

(Nayan Gadre) (12 de setembro de 2020)

Estas são notas criadas durante trabalhando com a biblioteca Junos pyez para automação de rede. Junos fornece tabelas e visualizações para definir e extrair dados de configuração personalizados. Todo o código pyez e ncclient é código aberto sob a licença Apache 2.0

Você define uma Tabela e uma Visualização em um arquivo Yaml em lib / jnpr / junos / recursos
como “ user.yml ” e seus correspondentes arquivo carregador como “ user.py

user.yml
user.py

O“ user.py ”é usado para converter as definições de Tabela e Visualização do arquivo yaml em elementos de dicionário global do python. Aqui \_\_file \_\_ aponta para o “ user.py ” que irá. em seguida, ser convertido para o nome de arquivo “ user.yml ”. O loadyaml do junos pyez converterá então o “ user.yml ”em um dicionário para anexá-lo ao dicionário globals () .

Ambas as definições de Tabela e Visualização no yaml são convertidos em classes em python. O loadyaml é um método de fábrica e é exposto como API pública usando o \_\_ all \_\_ declaração pythônica. Ele fornece um dicionário de definições de nome de item e classe de item como pode ser visto em um snap de linha.

O arquivo user.yml é dividido em 2 chaves de nível superior: “ UserTable ” e “ UserView ” para que o loadyaml retornará 2 classes com esses nomes.

dicionário convertido do user.yml

Este dicionário é passado para o FactoryLoader.load ( ) método para gerar classes:

FactoryLoader (). load (yaml.load (open (path, “r”), Loader = yaml.FullLoader))

O objetivo da Factory Loader Class

Os itens do dicionário () método r retorna um objeto de visualização que contém uma lista de tuplas contendo pares de valores-chave.

A maneira como o carregador de fábrica decide se a tabela fornecida e o esquema de visualização são para configuração ou para operações é por meio das chaves presentes no esquema . Por exemplo: “ set ” e “ get ” as chaves o tornariam uma tabela de configuração,
rpc ” então é uma operação tabela, “ comando ” ou “ título ” então é uma tabela de comando, também há alguma combinação confusa de “ item ” “ view ”e“ * ”que também determina se é uma tabela de comando.

Já que estamos nos concentrando em o “ user.yml ” podemos ver que é “uma tabela de configuração, uma vez que tem um“ set ” em sua hierarquia. Portanto, devemos preencher o \_item\_cfgtables com o UserTable chave.

Esta é a função de construtor de classe para gerar a classe de tabela para tabelas de tipo de configuração.

A classe Table contém uma referência à classe View, portanto se houver uma visão definida na seção da tabela, devemos criar uma classe para essa visão usando o método \_build\_view () e definir a classe como o valor da chave “ view ”.

O método de dicionário get () permite definir um valor padrão se a chave não estiver presente , aqui a chave “ view\_name ” estará ausente, então a \_build\_view ( view\_name ) criará uma classe e associará a classe como valor a view\_name chave. Ele também extrairá os grupos, eval, campos e os armazenará nos campos internos dos objetos de visualização.

Primeiro verificaremos como o contêiner CFGTABLE é criado em \_CFGTBL
\_CFGTBL = FactoryCfgTable

Python permite que você para criar classes ou tipos dinâmicos usando o método “ type ”.
Se “ type ”é passado um objeto existente, ele retorna seu tipo. No entanto, se “ type ” receber 3 argumentos, “ nome da classe ”,“ baseia a tupla ”,“ dict ”e então retorna uma nova classe. Também existe um método “ vars ”, que retorna \_\_dict\_\_ atributo, que armazena os atributos graváveis ​​dos objetos. Python cria outras classes usando metaclasses.

Podemos passar o nome da classe da qual nossa nova classe herdará como uma única tupla: Por exemplo: new\_cls = type (table\_name, (CfgTable,), {})

Se “ set ”a palavra-chave está presente na seção Tabela:
por exemplo: set: sistema / login / usuário
Portanto, também devemos passar a classe base de configuração para criar nossa classe UserTable:
Por exemplo: new\_cls = type (table\_name, (CfgTable, Config), {})

campos que são preenchidos automaticamente na classe

Assim que a classe for criado, nós o adicionaremos ao catálogo de classes factoryLoader: self.catalog [table\_name] = cls

Agora avançando para a construção da classe de visualização:

view\_name = tbl\_dict [“ view ”]
tbl\_dict [“ view ”] = self.catalog.get (view\_name, self.\_build\_view (view\_name))

O view\_name definido no arquivo “ user.yml ” é “ userView ”.

Finalmente,“ load ”Retornará um catálogo de classes criadas pela classe FactoryLoader .

Resumindo o caminho:

Isso apenas completa uma parte em que o yml é convertido em classes que podem ser usadas para operar. Em seguida, começamos criando um objeto de nossa classe UserTable.

user\_table = UserTable (dev)

Desde o recém-criado UserTable herda de CfgTable e classes base do Config, herdaremos o construtor e todos os métodos definidos nessas classes base. Assim que criamos um novo objeto UserTable , ele chama o objeto \_\_init\_\_ das classes pai. Como “ set ” é mencionado no arquivo yml, também chamaremos o construtor de config classe base.

Depois disso, ligue o método get () para buscar os dados de configuração de sistema / login / usuário hierarquia.
Verificaremos a opção namesonly = false primeiro.

Lembre-se de que a hierarquia para a expressão xpath já foi definida por meio de set: system / login / user declaração“ user.yml ”. Uma função \_build\_xml traduz isso em um. XML como abaixo:

Se o usuário especificou um nome de usuário específico, referido como “ namekey ”, então precisamos para inserir isso no xml gerado acima. Por exemplo: get (user = ”regress”) iria inserir o elemento de nome com o valor regress:

regress

tudo é compactado em get\_cmd e enviado para self.RPC.get\_config (get\_cmd)
Um XML- típico RPC se parece com o seguinte:

formato de XML de chamada de método RPC XML

Nosso XML para obter informações do usuário é semelhante a:

Este XML-RPC é convertido em uma solicitação HTTP POST e enviado ao servidor: executa um XML RPC e retorna resultados como XML ou python nativo

A chamada de rpc real é feita pelo método rpc do ncclient sobre ssh para que os dados sejam criptografados.

O tratamento RPC de o rpc\_cmd\_e é. feito por ncclient que fornece implementação para netconf sobre ssh. Será difícil entender onde o método rpc no objeto Manager () do pacote ncclient está realmente definido. Depois de estudar a biblioteca ncclient, descobri que ela é definida como um dicionário de métodos com “rpc” = ExecuteRpc , e este dicionário é específico do fornecedor. Clique aqui para ler mais .

Toda essa operação para nomear o dicionário é criada para cada solicitação de conexão com base no fornecedor e retornada.

O XML RPC final enviado por ssh para o servidor netconf no dispositivo Junos

Uma rápida resumo da iniciação e troca da sessão netconf:

O cliente deve iniciar uma conexão netconf à porta 830 sobre ssh. O servidor deve enviar sua mensagem OLÁ imediatamente, e o cliente também deve fazer o mesmo. Toda a mensagem hello > especifica os recursos do cliente e do servidor. O servidor deve então esperar para processar quaisquer pedidos rpc > e deve enviar um rpc-reply >. O cliente pode adicionar quantos atributos XML ao elemento rpc > desejar, e o o servidor retornará todos os atributos no elemento rpc-reply >.

A resposta é analisada, para ok > e rpc-error > tags que indicam nenhum / quaisquer erros. Em seguida, ele é transformado em um formato dependente de dispositivo / fornecedor, remova as tags de namespace etc.

A resposta é finalmente recebida como abaixo:

[(regressar, [(usuário, regressar), (uid, 928), (nome\_classe, superusuário), (senha, abc123 @ # $ # $ ^)])]