Tabelle e viste con Junos Pyez

(Nayan Gadre) (12 settembre 2020)

Queste sono note create mentre lavorare con la libreria Junos pyez per lautomazione di rete. Junos fornisce tabelle e viste per impostare ed estrarre dati di configurazione personalizzati. Tutto il codice pyez e ncclient è opensource con licenza Apache 2.0

Definisci una tabella e una vista in un file Yaml in lib / jnpr / junos / risorse
come “ user.yml ” e il corrispondente caricatore come “ user.py

user.yml
user.py

user.py ”viene utilizzato per convertire le definizioni Table e View del file yaml negli elementi del dizionario globale di Python. Qui \_\_file \_\_ punta a “ user.py ” che verrà. quindi essere convertito in “ user.yml ” nome file. loadyaml di Junos pyez convertirà quindi “ user.yml “in un dizionario per aggiungerlo al dizionario globals () .

Entrambe le definizioni di tabella e vista nello yaml vengono convertiti in classi in python. loadyaml è un metodo di fabbrica ed è esposto come API pubblica utilizzando \_\_ all \_\_ dichiarazione pitonica. Fornisce un dizionario delle definizioni nome-elemento e classe elemento come si può vedere nello snap di una riga.

Il file user.yml è suddiviso in 2 chiavi di livello superiore: “ UserTable ” e “ UserView ” quindi loadyaml restituirà 2 classi con questi nomi.

dizionario convertito da user.yml

Questo dizionario viene passato a FactoryLoader.load ( ) per generare classi:

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

Lo scopo della classe Factory Loader

Il metodo dizionari items () r restituisce un oggetto di visualizzazione che contiene un elenco di tuple contenenti coppie chiave-valore.

Il modo in cui il caricatore di fabbrica decide se la tabella e lo schema di visualizzazione forniti sono per la configurazione o per le operazioni è tramite le chiavi presenti nello schema . Ad esempio: “ set ” e “ get ” la renderebbero una tabella di configurazione,
rpc ” quindi è unoperazione tabella, “ comando ” o “ title ” quindi è una tabella di comandi, cè anche qualche combinazione confusa di “ item ” “ view “e” * “che indica anche se si tratta di una tabella di comandi.

Dato che ci stiamo concentrando su “ user.yml ” possiamo vedere che si tratta di “una tabella di configurazione, poiché ha una” imposta ” nella sua gerarchia. Quindi popoleremo \_item\_cfgtables con UserTable key.

Questa è la funzione di creazione classi per generare la classe table per le tabelle del tipo di configurazione.

La classe Table contiene un riferimento alla classe View, quindi se è presente una vista definita nella sezione tabella, creeremo una classe per quella vista utilizzando il metodo \_build\_view () e la classe come valore della chiave “ view “.

Il metodo del dizionario get () , permette di impostare un valore predefinito se la chiave non è presente , qui la chiave “ view\_name ” sarà assente, quindi la chiave \_build\_view ( view\_name ) creerà una classe e assocerà la classe come valore a view\_name chiave. Inoltre estrarrà i gruppi, eval, campi e li memorizzerà nei campi interni degli oggetti di visualizzazione.

Per prima cosa controlleremo come il contenitore CFGTABLE viene creato in \_CFGTBL
\_CFGTBL = FactoryCfgTable

Python ti consente per creare classi o tipi dinamici utilizzando il metodo “ type “.
Se “ type ”viene passato a un oggetto esistente, restituisce il suo tipo. Tuttavia, se a “ type ” vengono passati 3 argomenti, “ nome classe “,” tupla di base “,” dict “quindi restituisce una nuova classe. Esiste anche un metodo “ vars “, che restituisce \_\_dict\_\_ attributo, che memorizza gli attributi scrivibili degli oggetti. Python crea altre classi usando le metaclassi.

Possiamo passare il nome della classe da cui la nuova classe erediterà come una singola tupla: Ad esempio: new\_cls = type (table\_name, (CfgTable,), {})

Se “ set “è presente nella sezione Tabella:
ad esempio: set: system / login / user
Quindi dovremmo anche passare la classe base di configurazione per creare la nostra classe UserTable:
Ad esempio: new\_cls = type (table\_name, (CfgTable, Config), {})

campi che vengono popolati automaticamente nella classe

Una volta che la classe viene creato, lo aggiungeremo al catalogo delle classi factoryLoader: self.catalog [table\_name] = cls

Ora passiamo alla costruzione della classe di visualizzazione:

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

view\_name definito nel file “ user.yml ” è “ userView “.

Infine,” load “Restituirà un catalogo di classi create dalla classe FactoryLoader .

Quindi riassumendo il percorso:

Questo completa solo una parte in cui il file yml viene convertito in Classi che possono essere utilizzate per operare. Quindi, iniziamo creando un oggetto della nostra classe UserTable.

user\_table = UserTable (dev)

Poiché il UserTable eredita da CfgTable e le classi base Config, erediteremo il costruttore e tutti i metodi definiti in quelle classi base. Non appena creiamo un nuovo oggetto UserTable , chiama \_\_init\_\_ delle classi principali. Poiché “ set ” è menzionato nel file yml, chiameremo anche il costruttore di config classe base.

Dopodiché, chiama il metodo get () per recuperare i dati di configurazione per sistema / login / utente gerarchia.
Controlliamo prima lopzione namesonly = false .

Ricorda che la gerarchia per lespressione xpath era già stata impostata tramite set: system / login / user ” user.yml “. Una funzione \_build\_xml lo traduce in un file. XML come di seguito:

Se lutente ha specificato un nome utente specifico, denominato “ namekey “, allora abbiamo bisogno per inserirlo nellxml generato sopra. Ad esempio: get (user = “regress”) inserisce lelemento name con il valore regress:

regress

tutto viene impacchettato in get\_cmd e inviato a self.RPC.get\_config (get\_cmd)
Un tipico XML- RPC è simile al seguente:

formato di XML chiamata metodo RPC XML

Il nostro XML per ottenere informazioni sullutente ha il seguente aspetto:

Questo XML-RPC viene convertito in una richiesta HTTP POST e inviato al server: esegue un XML RPC e restituisce i risultati come XML o python nativo

La chiamata rpc effettiva viene eseguita tramite il metodo rpc di ncclient su ssh in modo che i dati vengano crittografati.

La gestione RPC di il rpc\_cmd\_e è. fatto da ncclient che fornisce limplementazione per netconf su ssh. Diventerà difficile capire dove sia effettivamente definito il metodo rpc nelloggetto Manager () dal pacchetto ncclient. Dopo aver studiato la libreria ncclient, ho scoperto che è definita come un dizionario di metodi con “rpc” = ExecuteRpc e questo dizionario è specifico del fornitore. Fare clic qui per saperne di più .

Lintera operazione di denominazione del dizionario viene creata per ogni richiesta di connessione basata sul fornitore e restituita.

LRPC XML finale inviato anche sul server netconf ssh sul dispositivo Junos

Un rapido riepilogo dellinizio e dello scambio della sessione netconf:

Il client deve avviare una connessione netconf alla porta 830 su ssh. Il server dovrebbe inviare immediatamente il suo messaggio HELLO e anche il client dovrebbe fare lo stesso. Lintero messaggio hello > specifica le capacità del client e del server. Il server dovrebbe quindi attendere di elaborare qualsiasi richiesta rpc > e dovrebbe inviare un rpc-reply >. Il client può aggiungere tutti gli attributi XML desiderati allelemento rpc > e il il server restituirà tutti questi attributi nellelemento rpc-reply >.

La risposta viene analizzata, per ok > e rpc-error > che indicano nessun / qualsiasi errore. Quindi viene trasformato in un formato dipendente dal dispositivo / fornitore, rimuove i tag dello spazio dei nomi ecc.

La risposta viene infine ricevuta come di seguito:

[(regress, [(user, regress), (uid, 928), (class\_name, superuser), (password, abc123 @ # $ # $ ^)])]