Verwenden von RPCs und Befehlen für den Betriebsmodus in Ereignisskripts
Die meisten Befehle im Betriebsmodus von Junos OS verfügen über XML-Entsprechungen. Ereignisskripts können diese XML-Befehle auf einem lokalen oder Remote-Gerät mithilfe des Remote Procedure Call (RPC)-Protokolls ausführen. Alle Befehle im Betriebsmodus, für die XML-Entsprechungen gelten, sind in der Junos XML API Operational Developer Reference aufgeführt.
SLAX- und XSLT-Skripte führen RPCs auf einem lokalen oder Remote-Gerät aus, indem sie die jcs:invoke()
Erweiterungsfunktionen oder jcs:execute()
verwenden. In Python-Skripts lassen sich RPCs mithilfe von Junos PyEZ-APIs einfach ausführen. Jede Instanz der Junos PyEZ-Klasse Device
verfügt über eine rpc
Eigenschaft, mit der Sie jeden RPC ausführen können, der über die Junos XML-API verfügbar ist. Nachdem Sie eine Sitzung mit einem lokalen oder Remotegerät eingerichtet haben, können Sie den RPC ausführen, indem Sie die Eigenschaft und den rpc
RPC-Methodennamen an die Geräteinstanz anfügen. Der Rückgabewert ist ein XML-Objekt, das mit dem ersten Element unter dem <rpc-reply>
Tag beginnt.
Die Verwendung von RPCs und Betriebsmodusbefehlen in Ereignisskripts wird in den folgenden Abschnitten ausführlicher erläutert:
Ausführen von RPCs auf einem lokalen Gerät
Um in einem SLAX- oder XSLT-Ereignisskript einen RPC auf dem lokalen Gerät auszuführen, schließen Sie den RPC in eine Variablendeklaration ein, und rufen Sie die jcs:invoke()
Erweiterungsfunktion mit der RPC-Variablen als Argument auf. Der folgende Codeausschnitt ruft einen RPC auf dem lokalen Gerät auf:
XSLT-Syntax
<xsl:variable name="rpc"> <get-interface-information/> # Junos RPC for the show interfaces command </xsl:variable> <xsl:variable name="out" select="jcs:invoke($rpc)"/> ...
SLAX-Syntax
var $rpc = <get-interface-information>; var $out = jcs:invoke($rpc);
Um in einem Python-Ereignisskript einen RPC auf dem lokalen Gerät auszuführen, erstellen Sie die Device
Instanz mit einer leeren Argumentliste, und fügen Sie die rpc
Eigenschaft sowie den RPC-Methodennamen und die Argumentliste an die Geräteinstanz an.
Python-Syntax
from jnpr.junos import Device with Device() as jdev: rsp = jdev.rpc.get_interface_information()
Wenn Sie die Instanz mit einer leeren Argumentliste erstellen, um eine Device
Verbindung mit dem lokalen Gerät herzustellen, verwendet Junos OS die Zugriffsrechte des Benutzers, der auf Hierarchieebene [edit event-options event-script file filename python-script-user]
konfiguriert ist. Wenn die python-script-user
Anweisung weggelassen wird, verwendet Junos OS die Zugriffsrechte des generischen, nicht privilegierten Benutzers und der Gruppe nobody
.
Ausführen von RPCs auf einem Remotegerät
Um in einem SLAX- oder XSLT-Ereignisskript einen RPC auf einem Remotegerät auszuführen, schließen Sie zuerst den RPC in eine Variablendeklaration ein und erstellen Sie mithilfe der jcs:open()
Erweiterungsfunktion ein Verbindungshandle mit den Argumenten, die zum Herstellen einer Verbindung mit dem Remotegerät erforderlich sind. Rufen Sie dann die jcs:execute()
Erweiterungsfunktion auf, und schließen Sie das Verbindungshandle und die RPC-Variable als Argumente ein. Zum Beispiel:
XSLT-Syntax
<xsl:variable name="rpc"> <get-interface-information/> </xsl:variable> <xsl:variable name="connection" select="jcs:open('198.51.100.1', 'bsmith', 'test123')"/> <xsl:variable name="out" select="jcs:execute($connection, $rpc)"/> <xsl:value-of select="jcs:close($connection)"/> ...
SLAX-Syntax
var $rpc = <get-interface-information>; var $connection = jcs:open("198.51.100.1", "bsmith","test123"); var $out = jcs:execute($connection, $rpc); expr jcs:close($connection); ...
Erstellen Sie in einem Python-Ereignisskript zum Ausführen eines RPC auf einem Remotegerät zunächst eine Instanz mit Device
den Argumenten, die zum Herstellen einer Verbindung mit dem Remotegerät erforderlich sind. Führen Sie dann den RPC aus, indem Sie die Eigenschaft sowie den rpc
RPC-Methodennamen und die Argumentliste an die Geräteinstanz anfügen.
Python-Syntax
from jnpr.junos import Device with Device(host='198.51.100.1', user='bsmith', passwd='test123') as jdev: rsp = jdev.rpc.get_interface_information()
Junos OS stellt eine Verbindung mit dem Remote-Gerät her und führt Vorgänge auf dem Remote-Gerät mithilfe der Zugriffsrechte des in der Argumentliste Device()
angegebenen Benutzers aus, auch wenn auf Hierarchieebene [edit event-options event-script file filename]
ein anderer Benutzer für die python-script-user
Anweisung konfiguriert ist.
Um zu vermeiden, dass die Remoteverbindungsdetails direkt in ein Ereignisskript eingefügt werden, können Sie Remoteausführungsdetails für jedes Ereignisskript angeben, das RPCs auf einem Remotegerät auf Hierarchieebene [edit event-options event-script file filename remote-execution]
ausführt. Es wird empfohlen, die Details zur Remoteausführung zur Konfiguration und nicht direkt im Ereignisskript hinzuzufügen, da alle Informationen an einem einzigen Ort verfügbar sind und die Passphrase in der Konfiguration verschlüsselt ist.
Konfigurieren Sie für jedes Remotegerät, auf dem ein RPC ausgeführt wird, den Gerätehostnamen sowie den entsprechenden Benutzernamen und die Passphrase.
[edit event-options event-script file filename] remote-execution { remote-hostname { username username; passphrase passphrase; } }
Die Remote-Hostnamen und der entsprechende Benutzername und die Passphrase werden zusätzlich zu den Ereignisdetails als Eingabe an das Ereignisskript übergeben, wenn es von einer Ereignisrichtlinie ausgeführt wird. Weitere Informationen zu den Details, die an das Ereignisskript weitergeleitet werden, finden Sie unter Verwenden von Ereignis- und Remoteausführungsdetails in Ereignisskripts.
Ein Ereignisskript verweist auf die Remote-Ausführungsdetails in der Argumentliste der Funktion, die zum Erstellen der Verbindung zum Remote-Host verwendet wird. Sobald die Verbindung hergestellt wurde, kann das Skript RPCs auf diesem Gerät ausführen.
In Python-Ereignisskripten verweisen Sie auf die Remote-Ausführungsdetails in der Argumentliste der Junos PyEZ-Instanz Device()
. Der folgende Code durchläuft die Remoteausführungsdetails für alle Hosts, die für dieses Ereignisskript konfiguriert sind, stellt eine Verbindung zu jedem Host her und führt denselben RPC aus.
Python-Syntax
from junos import Junos_Remote_Execution_Details from jnpr.junos import Device def main() for remote in Junos_Remote_Execution_Details(): hostname = remote.host username = remote.user passphrase = remote.passwd with Device(host=hostname, user=username, passwd=passphrase) as jdev: inv = jdev.rpc.get_interface_information() #process RPC information... if __name__ == "__main__": main()
Stellen Sie in SLAX- oder XSLT-Skripten mithilfe der jcs:open()
Funktion eine Verbindung zum fernen Host her, und verweisen Sie in der Argumentliste auf die Details zur Remoteausführung. Zum Beispiel:
XSLT-Syntax
<xsl:variable name="rpc"> <get-interface-information/> </xsl:variable> <xsl:for-each select="event-script-input/remote-execution-details"> <xsl:variable name="d" select="remote-execution-detail"/> <xsl:variable name="connection" select="jcs:open($d/remote-hostname,$d/username,$d/passphrase)"/> <xsl:variable name="out" select="jcs:execute($connection, $rpc)"/> <xsl:value-of select="jcs:close($connection)"/> ... </xsl:for-each>
SLAX-Syntax
var $rpc = <get-interface-information>; for-each (event-script-input/remote-execution-details) { var $d = remote-execution-detail; var $connection = jcs:open($d/remote-hostname,$d/username,$d/passphrase); var $out = jcs:execute($connection, $rpc); expr jcs:close($connection); ... }
Um einen RPC auf einem Remotegerät auszuführen, muss eine SSH-Sitzung aufgebaut werden. Damit das Skript die Verbindung herstellen kann, müssen Sie entweder die SSH-Hostschlüsselinformationen für das Remotegerät auf dem lokalen Gerät konfigurieren, auf dem das Skript ausgeführt wird, oder die SSH-Hostschlüsselinformationen für das Remotegerät müssen in der bekannten Hostdatei des Benutzers vorhanden sein, der das Skript ausführt. Konfigurieren Sie für jedes Remotegerät, auf dem der RPC ausgeführt wird, die SSH-Hostschlüsselinformationen mit einer der folgenden Methoden:
Um bekannte SSH-Hosts auf dem lokalen Gerät zu konfigurieren, schließen Sie die
host
Anweisung ein, und geben Sie Hostname- und Hostschlüsseloptionen für das Remotegerät auf der[edit security ssh-known-hosts]
Hierarchieebene der Konfiguration an.Um SSH-Hostschlüsselinformationen manuell abzurufen, geben Sie den
set security ssh-known-hosts fetch-from-server hostname
Befehl configuration mode ein, um Junos OS anzuweisen, eine Verbindung mit dem Remote-Gerät herzustellen und den Schlüssel hinzuzufügen.user@host# set security ssh-known-hosts fetch-from-server router2 The authenticity of host 'router2 (198.51.100.1)' can't be established. RSA key fingerprint is 30:18:99:7a:3c:ed:40:04:0f:fd:c1:57:7e:6b:f3:90. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'router2,198.51.100.1' (RSA) to the list of known hosts.
Um SSH-Hostschlüsselinformationen manuell aus einer Datei zu importieren, verwenden Sie den
set security ssh-known- hosts load-key-file filename
Befehl configuration mode und geben Sie die Datei known-hosts an.user@host# set security ssh-known-hosts load-key-file /var/tmp/known_hosts Import SSH host keys from trusted source /var/tmp/known_hosts ? [yes,no] (no) yes
Alternativ kann sich der Benutzer, der das Skript ausführt, beim lokalen Gerät anmelden, eine SSH-Verbindung zum Remotegerät herstellen und dann manuell den Hostschlüssel akzeptieren, der der bekannten Hostdatei dieses Benutzers hinzugefügt wird. Im folgenden Beispiel ist root bei router1 angemeldet. Um einen Remote-RPC auf router2 auszuführen, fügt root den Hostschlüssel von router2 hinzu, indem er den Befehl für den
ssh router2
Betriebsmodus ausgibt und den Schlüssel manuell akzeptiert.root@router1> ssh router2 The authenticity of host 'router2 (198.51.100.1)' can't be established. RSA key fingerprint is 30:18:99:7a:3c:ed:40:04:0f:fd:c1:57:7e:6b:f3:90. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'router2,198.51.100.1' (RSA) to the list of known hosts.
Nach der Konfiguration des erforderlichen SSH-Hostschlüssels und dem Abrufen eines Verbindungshandles für das Remote-Gerät kann das Ereignisskript RPCs mit der jcs:execute()
Erweiterungsfunktion auf diesem Remote-Gerät ausführen.
Anzeigen der RPC-Tags für einen Befehl
Sie können die RPC-XML-Tags für Betriebsmodusbefehle in der CLI des Geräts anzeigen. Um die RPC-XML-Tags für einen Befehl anzuzeigen, geben Sie nach dem Pipe-Symbol ( | ) ein display xml rpc
.
Im folgenden Beispiel werden die RPC-Tags für den show route
Befehl angezeigt:
user@host> show route | display xml rpc <rpc-reply xmlns:junos="http://xml.juniper.net/junos/10.1I0/junos"> <rpc> <get-route-information> </get-route-information> </rpc> <cli> <banner></banner> </cli> </rpc-reply>
SLAX- und XSLT-Skripte können RPCs mithilfe der RPC-XML-Tags ausführen. Python-Skripte müssen die RPC-Tags und Befehlsoptionen in ein für Python geeignetes Format konvertieren. Weitere Informationen zur Verwendung von Junos PyEZ zum Ausführen von RPCs und zum Zuordnen von RPC-Tags zu den entsprechenden Python-Methoden und Methodenargumenten finden Sie unter Verwenden von Junos PyEZ zum Ausführen von RPCs auf Geräten mit Junos OS.
Verwenden von Befehlen für den Betriebsmodus in Ereignisskripten
Für einige Befehle im Betriebsmodus gibt es keine XML-Entsprechungen. SLAX- und XSLT-Skripte können mithilfe des <command>
Elements Befehle ausführen, für die es keine XML-Entsprechung gibt. Python-Skripts können diese Befehle mithilfe der in der Device
Klasse definierten Junos PyEZ-Methode cli()
ausführen.
Wenn ein Befehl nicht in der Junos XML API Operational Developer Reference aufgeführt ist, verfügt der Befehl nicht über eine XML-Entsprechung. Eine andere Möglichkeit, um zu bestimmen, ob ein Befehl über eine XML-Entsprechung verfügt, besteht darin, den Befehl gefolgt vom | display xml
Befehl auszugeben.
user@host> operational-mode-command | display xml
Wenn die Ausgabe nur Tag-Elemente wie <output>
, <cli>
und <banner>
enthält, verfügt der Befehl möglicherweise nicht über eine XML-Entsprechung. Im folgenden Beispiel gibt die Ausgabe an, dass der show host
Befehl keine XML-Entsprechung hat:
user@host> show host hostname | display xml <rpc-reply xmlns:junos="http://xml.juniper.net/junos/10.0R1/junos"> <output> ... </output> <cli> <banner></banner> </cli> </rpc-reply>
Bei einigen Befehlen, die über eine XML-Entsprechung verfügen, enthält die Ausgabe des Befehls über die Pipeline | display xml
keine anderen Tag-Elemente als <output>
, <cli>
und <banner>
auch nur, weil die entsprechende Funktion nicht konfiguriert ist. Der show services cos statistics forwarding-class
Befehl verfügt z. B. über eine XML-Entsprechung, die <service-cos-forwarding-class-statistics>
eine Ausgabe im Antwort-Tag zurückgibt, aber wenn die Konfiguration keine Anweisungen auf der [edit class-of-service]
Hierarchieebene enthält, gibt es keine tatsächlichen Daten, die der show services cos statistics forwarding-class | display xml
Befehl anzeigen könnte. Die Ausgabe sieht in etwa so aus:
user@host> show services cos statistics forwarding-class | display xml <rpc-reply xmlns:junos="http://xml.juniper.net/junos/8.3I0/junos"> <cli> <banner></banner> </cli> </rpc-reply>
Aus diesem Grund sind die Informationen in der Junos XML API Operational Developer Reference in der Regel zuverlässiger.
SLAX- und XSLT-Ereignisskripte können Befehle ausführen, für die es keine XML-Entsprechung gibt. Verwenden Sie die <command>
Elemente , <xsl:value-of>
und <output>
das im Skript, wie im folgenden Codeausschnitt gezeigt. Dieser Codeausschnitt wird unter Beispiel: Anzeigen von DNS-Hostnameninformationen mithilfe eines Op-Skripts erweitert und ausführlich beschrieben.
<xsl:variable name="query"> <command> <xsl:value-of select="concat('show host ', $hostname)"/> </command> </xsl:variable> <xsl:variable name="result" select="jcs:invoke($query)"/> <xsl:variable name="host" select="$result"/> <output> <xsl:value-of select="concat('Name: ', $host)"/> </output> ...
Python-Ereignisskripts können mithilfe von Junos PyEZ-APIs Befehle ausführen, für die es keine XML-Entsprechung gibt. Die cli()
in der Device
Klasse definierte Methode führt einen Betriebsmodusbefehl aus und gibt die Ausgabe im Textformat zurück. Zum Beispiel:
from jnpr.junos import Device def main(): with Device() as jdev: res = jdev.cli('show host hostname', warning=False) print (res) if __name__ == "__main__": main()
Sie können auch angeben format='xml'
, dass die Ausgabe als Junos OS-XML-Elemente formatiert zurückgegeben werden soll. Weitere Informationen zur Junos PyEZ-Methode cli
finden Sie unter http://junos-pyez.readthedocs.org/en/latest/_modules/jnpr/junos/device.html#Device.cli .