AUF DIESER SEITE
Beispiel: Anpassen der Ausgabe des Befehls show interfaces knappe mithilfe eines Op-Skripts
In diesem Beispiel wird ein op-Skript verwendet, um die Ausgabe des show interfaces terse
Befehls anzupassen. Das XSLT-Skript wird Zeile für Zeile erläutert.
Anforderungen
In diesem Beispiel wird ein Gerät verwendet, auf dem Junos OS ausgeführt wird.
Übersicht und Op-Skript
Standardmäßig sieht das Layout des show interfaces terse
Befehls wie folgt aus:
user@host> show interfaces terse Interface Admin Link Proto Local Remote dsc up up fxp0 up up fxp0.0 up up inet 192.168.71.246/21 fxp1 up up fxp1.0 up up inet 10.0.0.4/8 inet6 fe80::200:ff:fe00:4/64 fc00::10:0:0:4/64 tnp 4 gre up up ipip up up lo0 up up lo0.0 up up inet 127.0.0.1 --> 0/0 lo0.16385 up up inet inet6 fe80::2a0:a5ff:fe12:2f04 lsi up up mtun up up pimd up up pime up up tap up up
In Junos XML werden die Ausgabefelder wie folgt dargestellt:
user@host> show interfaces terse | display xml <rpc-reply xmlns:junos="http://xml.juniper.net/junos/10.0R1/junos"> <interface-information xmlns="http://xml.juniper.net/junos/10.0R1/junos-interface" junos:style="terse"> <physical-interface> <name>dsc</name> <admin-status>up</admin-status> <oper-status>up</oper-status> </physical-interface> <physical-interface> <name>fxp0</name> <admin-status>up</admin-status> <oper-status>up</oper-status> <logical-interface> <name>fxp0.0</name> <admin-status>up</admin-status> <oper-status>up</oper-status> ... Remainder of output omitted for brevity ...
XSLT-Syntax
Mit dem show interfaces terse
folgenden Skript wird die Ausgabe des Befehls angepasst. Das Skript wird Zeile für Zeile erläutert.
1 <?xml version="1.0" standalone="yes"?> 2 <xsl:stylesheet version="1.0" 3 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 4 xmlns:junos="http://xml.juniper.net/junos/*/junos" 5 xmlns:xnm="http://xml.juniper.net/xnm/1.1/xnm" 6 xmlns:jcs="http://xml.juniper.net/junos/commit-scripts/1.0"> 7 <xsl:import href="../import/junos.xsl"/> 8 <xsl:variable name="arguments"> 9 <argument> 10 <name>interface</name> 11 <description>Name of interface to display</description> 12 </argument> 13 <argument> 14 <name>protocol</name> 15 <description>Protocol to display (inet, inet6)</description> 16 </argument> 17 </xsl:variable> 18 <xsl:param name="interface"/> 19 <xsl:param name="protocol"/> 20 <xsl:template match="/"> 21 <op-script-results> 22 <xsl:variable name="rpc"> 23 <get-interface-information> 24 <terse/> 25 <xsl:if test="$interface"> 26 <interface-name> 27 <xsl:value-of select="$interface"/> 28 </interface-name> 29 </xsl:if> 30 </get-interface-information> 31 </xsl:variable> 32 <xsl:variable name="out" select="jcs:invoke($rpc)"/> 33 <interface-information junos:style="terse"> 34 <xsl:choose> 35 <xsl:when test="$protocol='inet' or $protocol='inet6' or $protocol='mpls' or $protocol='tnp'"> 36 <xsl:for-each select="$out/physical-interface/ logical-interface[address-family/address-family-name = $protocol]"> 37 <xsl:call-template name="intf"/> 38 </xsl:for-each> 39 </xsl:when> 40 <xsl:when test="$protocol"> 41 <xnm:error> 42 <message> 43 <xsl:text>invalid protocol: </xsl:text> 44 <xsl:value-of select="$protocol"/> 45 </message> 46 </xnm:error> 47 </xsl:when> 48 <xsl:otherwise> 49 <xsl:for-each select="$out/physical-interface/logical-interface"> 50 <xsl:call-template name="intf"/> 51 </xsl:for-each> 52 </xsl:otherwise> 53 </xsl:choose> 54 </interface-information> 55 </op-script-results> 56 </xsl:template> 57 <xsl:template name="intf"> 58 <xsl:variable name="status"> 59 <xsl:choose> 60 <xsl:when test="admin-status='up' and oper-status='up'"> 61 <xsl:text> </xsl:text> 62 </xsl:when> 63 <xsl:when test="admin-status='down'"> 64 <xsl:text>offline</xsl:text> 65 </xsl:when> 66 <xsl:when test="oper-status='down' and ../admin-status='down'"> 67 <xsl:text>p-offline</xsl:text> 68 </xsl:when> 69 <xsl:when test="oper-status='down' and ../oper-status='down'"> 70 <xsl:text>p-down</xsl:text> 71 </xsl:when> 72 <xsl:when test="oper-status='down'"> 73 <xsl:text>down</xsl:text> 74 </xsl:when> 75 <xsl:otherwise> 76 <xsl:value-of select="concat(oper-status, '/', admin-status)"/> 77 </xsl:otherwise> 78 </xsl:choose> 79 </xsl:variable> 80 <xsl:variable name="desc"> 81 <xsl:choose> 82 <xsl:when test="description"> 83 <xsl:value-of select="description"/> 84 </xsl:when> 85 <xsl:when test="../description"> 86 <xsl:value-of select="../description"/> 87 </xsl:when> 88 </xsl:choose> 89 </xsl:variable> 90 <logical-interface> 91 <name><xsl:value-of select="name"/></name> 92 <xsl:if test="string-length($desc)"> 93 <admin-status><xsl:value-of select="$desc"/></admin-status> 94 </xsl:if> 95 <admin-status><xsl:value-of select="$status"/></admin-status> 96 <xsl:choose> 97 <xsl:when test="$protocol"> 98 <xsl:copy-of select="address-family[address-family-name = $protocol]"/> 99 </xsl:when> 100 <xsl:otherwise> 101 <xsl:copy-of select="address-family"/> 102 </xsl:otherwise> 103 </xsl:choose> 104 </logical-interface> 105 </xsl:template> 106 </xsl:stylesheet>
Zeilenweise Erklärung
Die Zeilen 1 bis 7, Zeile 20 sowie die Zeilen 105 und 106 sind die Textbausteine, die Sie in jedes Op-Skript aufnehmen. Weitere Informationen finden Sie unter Erforderliche Boilerplate für Op-Skripte.
1 <?xml version="1.0" standalone="yes"?> 2 <xsl:stylesheet version="1.0" 3 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 4 xmlns:junos="http://xml.juniper.net/junos/*/junos" 5 xmlns:xnm="http://xml.juniper.net/xnm/1.1/xnm" 6 xmlns:jcs="http://xml.juniper.net/junos/commit-scripts/1.0"> 7 <xsl:import href="../import/junos.xsl"/> ... 20 <xsl:template match="/"> ... 105 </xsl:template> 106 </xsl:stylesheet>
In den Zeilen 8 bis 17 wird eine Variable namens arguments
deklariert, die zwei Argumente für das Skript enthält: interface
und protocol
. Diese Variablendeklaration bewirkt, dass interface
und protocol
in der Befehlszeilenschnittstelle (CLI) als verfügbare Argumente für das Skript angezeigt wird.
8 <xsl:variable name="arguments"> 9 <argument> 10 <name>interface</name> 11 <description>Name of interface to display</description> 12 </argument> 13 <argument> 14 <name>protocol</name> 15 <description>Protocol to display (inet, inet6)</description> 16 </argument> 17 </xsl:variable>
In den Zeilen 18 und 19 werden dem Skript zwei Parameter deklariert, die den in den Zeilen 8 bis 17 erstellten Argumenten entsprechen. Die Parameternamen müssen exakt mit den Argumentnamen übereinstimmen.
18 <xsl:param name="interface"/> 19 <xsl:param name="protocol"/>
In den Zeilen 20 bis 31 wird eine Variable mit dem Namen rpc
deklariert. Der show interfaces terse
Befehl wird der rpc
Variablen zugewiesen. Wenn Sie das Argument beim Ausführen des Skripts einschließen, wird der Wert des Arguments (der Schnittstellenname) an das interface
Skript übergeben.
20 <xsl:template match="/"> 21 <op-script-results> 22 <xsl:variable name="rpc"> 23 <get-interface-information> 24 <terse/> 25 <xsl:if test="$interface"> 26 <interface-name> 27 <xsl:value-of select="$interface"/> 28 </interface-name> 29 </xsl:if> 30 </get-interface-information> 31 </xsl:variable>
Zeile 32 deklariert eine Variable named out
und wendet auf sie die Ausführung der rpc
Variablen an (show interfaces terse
Befehl).
32 <xsl:variable name="out" select="jcs:invoke($rpc)"/>
Zeile 33 gibt an, dass der Ausgabepegel des show interfaces
zu ändernden Befehls (im Gegensatz zu extensive
, , detail
usw.) ist terse
.
33 <interface-information junos:style="terse">
In den Zeilen 34 bis 39 wird angegeben, dass die intf
Vorlage auf jede Instanz dieses Protokolltyps in der Ausgabe angewendet wird, wenn Sie das protocol
Argument beim Ausführen des Skripts einschließen und wenn der von Ihnen angegebene inet
Protokollwert , inet6
mpls
, oder tnp
ist.
34 <xsl:choose> 35 <xsl:when test="$protocol='inet' or $protocol='inet6' or $protocol='mpls' or $protocol='tnp'"> 36 <xsl:for-each select="$out/physical-interface/ logical-interface[address-family/address-family-name = $protocol]"> 37 <xsl:call-template name="intf"/> 38 </xsl:for-each> 39 </xsl:when>
In den Zeilen 40 bis 47 wird angegeben, dass eine Fehlermeldung generiert wird, wenn Sie das protocol
Argument beim Ausführen des Skripts einschließen und wenn der von Ihnen angegebene Protokollwert ein anderer Wert als inet
, , inet6
mpls
oder tnp
ist.
40 <xsl:when test="$protocol"> 41 <xnm:error> 42 <message> 43 <xsl:text>invalid protocol: </xsl:text> 44 <xsl:value-of select="$protocol"/> 45 </message> 46 </xnm:error> 47 </xsl:when>
In den Zeilen 48 bis 52 wird angegeben, dass die intf
Vorlage auf jede logische Schnittstelle in der Ausgabe angewendet wird, wenn Sie das protocol
Argument beim Ausführen des Skripts nicht einschließen.
48 <xsl:otherwise> 49 <xsl:for-each select="$out/physical-interface/logical-interface"> 50 <xsl:call-template name="intf"/> 51 </xsl:for-each> 52 </xsl:otherwise>
Die Zeilen 53 bis 56 sind schließende Tags.
53 </xsl:choose> 54 </interface-information> 55 </op-script-results> 56 </xsl:template>
Zeile 57 öffnet die intf
Vorlage. Mit dieser Vorlage wird die Ausgabe des show interfaces terse
Befehls angepasst.
57 <xsl:template name="intf">
Zeile 58 deklariert eine Variable mit dem Namen status
, die angeben soll, wie der Schnittstellenstatus gemeldet wird. Die Zeilen 59 bis 78 enthalten eine <xsl:choose>
Anweisung, die die status
Variable unter Berücksichtigung aller möglichen Zustände auffüllt. Wie immer in XSLT wird die erste <xsl:when>
Anweisung ausgeführt, die als TRUE ausgewertet wird, und der Rest wird ignoriert. Jede <xsl:when>
Anweisung wird separat erklärt.
58 <xsl:variable name="status"> 59 <xsl:choose>
In den Zeilen 60 bis 62 wird angegeben, dass keine Ausgabe generiert wird, wenn 'up' und oper-status
'up' admin-status
ist. In diesem Fall bleibt die Variable status
leer.
60 <xsl:when test="admin-status='up' and oper-status='up'"> 61 <xsl:text> </xsl:text> 62 </xsl:when>
In den Zeilen 63 bis 65 wird angegeben, dass die Variable den status
Text offline
enthält, wenn admin-status
'down' ist.
63 <xsl:when test="admin-status='down'"> 64 <xsl:text>offline</xsl:text> 65 </xsl:when>
In den Zeilen 66 bis 68 wird angegeben, dass die Variable den Text p-offline
enthält, wenn oper-status
'down' und die status
physische Schnittstelle admin-status
'down' ist. ../
( Wählt die physische Schnittstelle aus.)
66 <xsl:when test="oper-status='down' and ../admin-status='down'"> 67 <xsl:text>p-offline</xsl:text> 68 </xsl:when>
In den Zeilen 69 bis 71 wird angegeben, dass die Variable den Text p-down
enthält, wenn oper-status
'down' und die status
physische Schnittstelle oper-status
'down' ist. ../
( Wählt die physische Schnittstelle aus.)
69 <xsl:when test="oper-status='down' and ../oper-status='down'"> 70 <xsl:text>p-down</xsl:text> 71 </xsl:when>
In den Zeilen 72 bis 74 wird angegeben, dass die Variable den status
Text down
enthält, wenn oper-status
'down' ist.
72 <xsl:when test="oper-status='down'"> 73 <xsl:text>down</xsl:text> 74 </xsl:when>
In den Zeilen 75 bis 77 wird angegeben, dass, wenn keiner der Testfälle wahr ist, die status
Variable einen Schrägstrich als Trennzeichen enthält oper-status
und admin-status
verkettet.
75 <xsl:otherwise> 76 <xsl:value-of select="concat(oper-status, '/', admin-status)"/> 77 </xsl:otherwise>
Die Zeilen 78 und 79 sind schließende Tags.
78 </xsl:choose> 79 </xsl:variable>
In den Zeilen 80 bis 89 wird eine Variable namens definiert desc
. Eine <xsl:choose>
Anweisung füllt die Variable aus, indem sie die spezifischste verfügbare Schnittstellenbeschreibung auswählt. Wenn eine logische Schnittstellenbeschreibung in der Konfiguration enthalten ist, wird sie zum Auffüllen der Variablen desc
verwendet. Ist dies nicht der Fall, wird die Beschreibung der physikalischen Schnittstelle verwendet. Wenn keine Beschreibung der physikalischen Schnittstelle in der Konfiguration enthalten ist, bleibt die Variable leer. Wie immer in XSLT wird die erste <xsl:when>
Anweisung ausgeführt, die als TRUE ausgewertet wird, und der Rest wird ignoriert.
80 <xsl:variable name="desc"> 81 <xsl:choose> 82 <xsl:when test="description"> 83 <xsl:value-of select="description"/> 84 </xsl:when> 85 <xsl:when test="../description"> 86 <xsl:value-of select="../description"/> 87 </xsl:when> 88 </xsl:choose> 89 </xsl:variable>
Der Rest des Skripts gibt an, wie die Ausgabe des Betriebsmodus angezeigt wird.
In den Zeilen 90 und 91 wird festgelegt, dass der Name der logischen Schnittstelle zuerst in der Ausgabe angezeigt wird.
90 <logical-interface> 91 <name><xsl:value-of select="name"/></name>
In den Zeilen 92 bis 94 wird getestet, ob die desc
Variable eine Anzahl von Zeichen ungleich Null hat. Wenn die Anzahl der Zeichen größer als Null ist, wird die Schnittstellenbeschreibung an der Standardposition des admin-status
Feldes angezeigt. (In der Standardausgabe wird das Feld in der admin-status
zweiten Zeile angezeigt.)
92 <xsl:if test="string-length($desc)"> 93 <admin-status><xsl:value-of select="$desc"/></admin-status> 94 </xsl:if>
Zeile 95 gibt an, dass als nächstes der in der Variablen status
definierte Schnittstellenstatus angezeigt wird.
95 <admin-status><xsl:value-of select="$status"/></admin-status>
In den Zeilen 96 bis 103 wird angegeben, dass nur Schnittstellen mit diesem konfigurierten Protokoll angezeigt werden, wenn Sie das protocol
Argument beim Ausführen des Skripts einschließen. Wenn Sie das Argument protocol
nicht angeben, werden alle Schnittstellen angezeigt.
96 <xsl:choose> 97 <xsl:when test="$protocol"> 98 <xsl:copy-of select="address-family[address-family-name = $protocol]"/> 99 </xsl:when> 100 <xsl:otherwise> 101 <xsl:copy-of select="address-family"/> 102 </xsl:otherwise> 103 </xsl:choose>
Die Zeilen 104 bis 106 sind schließende Tags.
104 </logical-interface> 105 </xsl:template> 106 </xsl:stylesheet>
SLAX-Syntax
Die SLAX-Version des Skripts lautet wie folgt:
version 1.0; ns junos = "http://xml.juniper.net/junos/*/junos"; ns xnm = "http://xml.juniper.net/xnm/1.1/xnm"; ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0"; import "../import/junos.xsl"; var $arguments = { <argument> { <name> "interface"; <description> "Name of interface to display"; } <argument> { <name> "protocol"; <description> "Protocol to display (inet, inet6)"; } } param $interface; param $protocol; match / { <op-script-results> { var $rpc = { <get-interface-information> { <terse>; if ($interface) { <interface-name> $interface; } } } var $out = jcs:invoke($rpc); <interface-information junos:style="terse"> { if ($protocol='inet' or $protocol='inet6' or $protocol='mpls' or $protocol='tnp') { for-each ($out/physical-interface/ logical-interface[address-family/address-family-name = $protocol]) { call intf(); } } else if ($protocol) { <xnm:error> { <message> { expr "invalid protocol: "; expr $protocol; } } } else { for-each ($out/physical-interface/logical-interface) { call intf(); } } } } } intf () { var $status = { if (admin-status='up' and oper-status='up') { } else if (admin-status='down') { expr "offline"; } else if (oper-status='down' and ../admin-status='down') { expr "p-offline"; } else if (oper-status='down' and ../oper-status='down') { expr "p-down"; } else if (oper-status='down') { expr "down"; } else { expr oper-status _ '/' _ admin-status; } } var $desc = { if (description) { expr description; } else if (../description) { expr ../description; } } <logical-interface> { <name> name; if (string-length($desc)) { <admin-status> $desc; } <admin-status> $status; if ($protocol) { copy-of address-family[address-family-name = $protocol]; } else { copy-of address-family; } } }
Konfiguration
Verfahren
Schritt-für-Schritt-Anleitung
So laden Sie das Skript herunter, aktivieren und testen es:
Kopieren Sie das XSLT- oder SLAX-Skript in eine Textdatei, nennen Sie die Datei interface.xsl oder interface.slax und kopieren Sie sie in das Verzeichnis / var/db/scripts/op/ auf dem Gerät.
Fügen Sie im Konfigurationsmodus die
file
Anweisung auf Hierarchieebene[edit system scripts op]
und ggf. interface.xsl oder interface.slax ein.[edit system scripts op] user@host# set file interface.(slax | xsl)
Geben Sie den Befehl ein, um die Konfiguration zu bestätigen und in den
commit and-quit
Betriebsmodus zurückzukehren.[edit] user@host# commit and-quit
Führen Sie das Op-Skript aus, indem Sie den
op interface
Befehl operational mode eingeben.
Überprüfung
Überprüfen der Commit-Skriptausgabe
Zweck
Stellen Sie sicher, dass sich das Skript wie erwartet verhält.
Aktion
Geben Sie die Betriebsbefehle aus und op interface
vergleichen Sie die show interfaces terse
Ausgabe. Der show interfaces terse
Befehl zeigt die Standardausgabe an. Der op interface
Befehl zeigt die benutzerdefinierte Ausgabe an.
user@host> show interfaces terse Interface Admin Link Proto Local Remote dsc up up fxp0 up up fxp0.0 up up inet 192.168.71.246/21 fxp1 up up fxp1.0 up up inet 10.0.0.4/8 inet6 fe80::200:ff:fe00:4/64 fc00::10:0:0:4/64 tnp 4 gre up up ipip up up lo0 up up lo0.0 up up inet 127.0.0.1 --> 0/0 lo0.16385 up up inet inet6 fe80::2a0:a5ff:fe12:2f04 lsi up up mtun up up pimd up up pime up up tap up up user@host> op interface Interface Admin Link Proto Local Remote fxp0.0 This is the Ethernet Management interface. inet 192.168.71.246/21 fxp1.0 inet 10.0.0.4/8 inet6 fe80::200:ff:fe00:4/64 fc00::10:0:0:4/64 tnp 4 lo0.0 inet 127.0.0.1 --> 0/0 lo0.16385 inet inet6 fe80::2a0:a5ff:fe12:2f04-->
Geben Sie den op interface
Betriebsbefehl für verschiedene Hierarchieebenen und überprüfen Sie die Ausgabe. Zum Beispiel:
user@host> op interface interface fxp0 Interface Admin Link Proto Local Remote fxp0.0 This is the Ethernet Management interface. inet 192.168.71.246/21 user@host> op interface protocol inet Interface Admin Link Proto Local Remote fxp0.0 This is the Ethernet Management interface. inet 192.168.71.246/21 fxp1.0 inet 10.0.0.4/8 lo0.0 inet 127.0.0.1 --> 0/0 lo0.16385 inet