Tabele i widoki z Junosem Pyezem

(Nayan Gadre) (12 września 2020 r.)

To są notatki utworzone w praca z biblioteką Junos pyez do automatyzacji sieci. Junos udostępnia tabele i widoki do ustawiania i wyodrębniania niestandardowych danych konfiguracyjnych. Cały kod pyez i ncclient to opensource na licencji Apache 2.0

Definiujesz tabelę i widok w pliku Yaml w lib / jnpr / junos / zasoby
, takie jak „ user.yml ” i odpowiadające im plik ładujący jako „ user.py

user.yml
user.py

user.py ”służy do konwersji definicji tabeli i widoku pliku yaml na elementy globalnego słownika języka Python. Tutaj \_\_file \_\_ wskazuje na „ user.py ”, który będzie. następnie przekonwertować na nazwę pliku „ user.yml ”. loadyaml junosa pyeza skonwertuje następnie plik „ user.yml ”do słownika, aby dołączyć go do słownika globals () .

Zarówno definicje tabeli, jak i widoku w yamlu są konwertowane na klasy w Pythonie. loadyaml to metoda fabryczna, która jest udostępniana jako publiczny interfejs API za pomocą \_\_ all \_\_ deklaracja Pythona. Udostępnia słownik definicji pozycji-nazw i klas pozycji, co można zobaczyć w jednym wierszu.

Plik user.yml jest podzielony na 2 klucze najwyższego poziomu: „ UserTable ” i „ UserView ”, więc loadyaml zwróci 2 klasy o tych nazwach.

słownik przekonwertowany ze słownika user.yml

Ten słownik jest przekazywany do FactoryLoader.load ( ) do generowania klas:

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

Cel klasy Factory Loader

Słowniki items () metoda r zwraca obiekt widoku, który zawiera listę krotek zawierających pary klucz-wartość.

Sposób, w jaki program ładujący fabrykę decyduje, czy podana tabela i schemat widoku służy do konfiguracji, czy do operacji, odbywa się za pomocą kluczy obecnych w schemacie . Na przykład: „ set ” i „ get ” uczyniłoby z niej tabelę konfiguracji,
rpc ” to operacja table, „ command ” lub „ tytuł ” to jest to tabela poleceń, jest też pewna myląca kombinacja „ item ” „ view ”i„ * ”, który również określa, czy jest to tabela poleceń.

Ponieważ skupiamy się na „ user.yml ” widzimy, że jest to tabela konfiguracyjna, ponieważ zawiera „ ustaw ” w swojej hierarchii. Dlatego zapełnimy \_item\_cfgtables z UserTable klucz.

To jest funkcja konstruktora klas służąca do generowania klasy tabeli dla tabel typu konfiguracji.

Klasa Table zawiera odniesienie do klasy View, stąd jeśli istnieje widok zdefiniowany w sekcji tabeli, utworzymy klasę dla tego widoku za pomocą metody \_build\_view () i ustaw klasa jako wartość klucza „ view ”.

Słownik get () pozwala ustawić domyślną wartość, jeśli nie ma klucza , tutaj „ nazwa\_widoku ” będzie nieobecny, więc \_build\_view ( nazwa\_widoku ) utworzy klasę i powiąże ją jako wartość z nazwa\_widoku klawisz. Wyodrębni również grupy, eval, pola i zapisze je w wewnętrznych polach obiektów widoku.

Najpierw sprawdzimy, jak kontener CFGTABLE w \_CFGTBL
\_CFGTBL = FactoryCfgTable

Python umożliwia aby tworzyć dynamiczne klasy lub typy za pomocą metody „ type ”.
Jeśli „ type ”przekazuje istniejący obiekt, zwraca jego typ. Jeśli jednak „ typ ” otrzyma 3 argumenty, „ nazwa klasy ”,„ krotka podstaw ”,„ dict ”, a następnie zwraca nową klasę. Istnieje również metoda „ vars ”, która zwraca \_\_dict\_\_ , który przechowuje atrybuty obiektów z możliwością zapisu. Python tworzy inne klasy przy użyciu metaklas.

Możemy przekazać nazwę klasy, z której nowa klasa będzie dziedziczyć jako pojedynczą krotkę: Na przykład: new\_cls = type (nazwa\_tabeli, (CfgTable,), {})

Jeśli „ set ”jest obecne w sekcji Tabela:
na przykład: set: system / login / użytkownik
Powinniśmy więc przekazać również klasę bazową konfiguracji, aby utworzyć klasę UserTable:
Na przykład: new\_cls = type (nazwa\_tabeli, (CfgTable, Config), {})

pola, które są automatycznie wypełniane w klasie

Gdy klasa zostanie utworzony, dodamy go do katalogu klas factoryLoader: self.catalog [table\_name] = cls

Teraz przejdźmy do tworzenia klasy widoku:

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

view\_name zdefiniowany w pliku „ user.yml ” to „ userView ”.

Na koniec„ load ”Zwróci katalog klas utworzonych przez klasę FactoryLoader .

Podsumowując ścieżkę:

To tylko kończy jedną część, w której yml jest konwertowany na klasy, które można następnie wykorzystać do operacji. Następnie zaczynamy od utworzenia obiektu naszej klasy UserTable.

user\_table = UserTable (dev)

Ponieważ nowo utworzona UserTable dziedziczy po CfgTable i Config, odziedziczymy konstruktora i wszystkie metody zdefiniowane w tych klasach bazowych. Gdy tylko utworzymy nowy obiekt UserTable , wywołuje on \_\_init\_\_ klas nadrzędnych. Ponieważ „ set ” jest wspomniane w pliku yml, będziemy również wywoływać konstruktora konfiguracji klasa bazowa.

Następnie zadzwoń metoda get () do pobierania danych konfiguracyjnych dla system / login / użytkownik hierarchia.
Najpierw sprawdzimy opcję namesonly = false .

Pamiętaj, że hierarchia wyrażenia xpath została już ustawiona przez set: system / login / user „ user.yml ”. Funkcja \_build\_xml tłumaczy to na plik. XML jak poniżej:

Jeśli użytkownik podał konkretną nazwę użytkownika, określaną jako „ namekey ”, potrzebujemy aby wstawić to do powyższego wygenerowanego pliku xml. Na przykład: get (user = ”regress”) wstawiłoby element name z wartością regress:

regress

wszystko jest pakowane do get\_cmd i wysyłane do self.RPC.get\_config (get\_cmd)
Typowy XML- RPC wygląda następująco:

format XML wywołanie metody RPC w XML

Nasz kod XML do pobierania informacji o użytkowniku wygląda następująco:

Ten XML-RPC jest konwertowany na żądanie HTTP POST i wysyłany do serwera: wykonuje XML RPC i zwraca wyniki jako XML lub natywny Python

Faktyczne wywołanie RPC odbywa się za pomocą metody RPC ncclienta przez ssh, więc dane są szyfrowane.

Obsługa RPC rpc\_cmd\_e jest. wykonane przez ncclient, który zapewnia implementację netconf przez ssh. Trudno będzie zrozumieć, gdzie w rzeczywistości zdefiniowana jest metoda rpc w obiekcie Manager () z pakietu ncclient. Po przestudiowaniu biblioteki ncclient odkryłem, że jest zdefiniowana jako słownik metod z „rpc” = ExecuteRpc , a ten słownik jest specyficzny dla dostawcy. Kliknij tutaj, aby przeczytać więcej .

Cała operacja nazewnictwa słownika jest tworzona dla każdego żądania połączenia na podstawie dostawcy i zwracana.

Ostateczna wersja RPC XML wysłana przez ssh do serwera netconf na urządzeniu Junos

Szybka podsumowanie inicjacji i wymiany sesji netconf:

Klient musi zainicjować połączenie netconf z portem 830 przez ssh. Serwer powinien od razu wysłać wiadomość HELLO , a klient też powinien zrobić to samo. Cała wiadomość witaj > określa możliwości klienta i serwera. Serwer powinien wtedy poczekać na przetworzenie wszelkich żądań rpc > i wysłać rpc-response >. Klient może dodać dowolną liczbę atrybutów XML do elementu rpc >, a serwer zwróci wszystkie te atrybuty w elemencie rpc-response >.

Odpowiedź jest analizowana, dla ok > i rpc-error > tagi wskazujące brak błędów. Następnie jest przekształcany w format zależny od urządzenia / dostawcy, usuwa znaczniki przestrzeni nazw itp.

Ostatecznie otrzymujemy odpowiedź, jak poniżej:

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