SUR CETTE PAGE
Exemple : Personnaliser la sortie des interfaces show terse Command à l’aide d’un script Op
Cet exemple utilise un script op pour personnaliser la sortie de la show interfaces terse
commande. Une explication ligne par ligne du script XSLT est fournie.
Exigences
Cet exemple utilise un équipement exécutant Junos OS.
Présentation et script op
Par défaut, la configuration de la show interfaces terse
commande ressemble à ceci :
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
Dans Junos XML, les champs de sortie sont représentés comme suit :
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 ...
Syntaxe XSLT
Le script suivant personnalise la sortie de la show interfaces terse
commande. Une explication ligne par ligne du script est fournie.
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>
Explication ligne par ligne
Les lignes 1 à 7, les lignes 20 et les lignes 105 et 106 sont la plaque de chaudron que vous incluez dans chaque script op. Pour plus d’informations, consultez la plaque de chaudron requise pour les scripts op.
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>
Les lignes 8 à 17 déclarent une variable appelée arguments
, contenant deux arguments au script : interface
et protocol
. Cette déclaration de variable génère interface
et protocol
doit apparaître dans l’interface de ligne de commande (CLI) comme arguments disponibles pour le script.
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>
Les lignes 18 et 19 déclarent deux paramètres au script, correspondant aux arguments créés dans les lignes 8 à 17. Les noms des paramètres doivent correspondre exactement aux noms des arguments.
18 <xsl:param name="interface"/> 19 <xsl:param name="protocol"/>
Les lignes 20 à 31 déclarent une variable nommée rpc
. La show interfaces terse
commande est affectée à la rpc
variable. Si vous incluez l’argument interface
lors de l’exécution du script, la valeur de l’argument (le nom de l’interface) est transmise au script.
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>
La ligne 32 déclare une variable nommée out
et lui applique l’exécution de la rpc
variable (show interfaces terse
commande).
32 <xsl:variable name="out" select="jcs:invoke($rpc)"/>
La ligne 33 spécifie que le niveau de sortie de la show interfaces
commande en cours de modification est terse
(par opposition à extensive
, detail
et ainsi de suite).
33 <interface-information junos:style="terse">
Les lignes 34 à 39 spécifient que si vous incluez l’argument protocol
lorsque vous exécutez le script et si la valeur de protocole que vous spécifiez est inet
, inet6
ou mpls
tnp
, le intf
modèle est appliqué à chaque instance de ce type de protocole dans la sortie.
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>
Les lignes 40 à 47 spécifient que si vous incluez l’argument protocol
lors de l’exécution du script et si la valeur de protocole que vous spécifiez est autre que inet
, inet6
, mpls
ou tnp
, un message d’erreur est généré.
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>
Les lignes 48 à 52 spécifient que si vous n’incluez pas l’argument protocol
lors de l’exécution du script, le intf
modèle est appliqué à chaque interface logique de la sortie.
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>
Les lignes 53 à 56 ferment les balises.
53 </xsl:choose> 54 </interface-information> 55 </op-script-results> 56 </xsl:template>
La ligne 57 ouvre le intf
modèle. Ce modèle personnalise la sortie de la show interfaces terse
commande.
57 <xsl:template name="intf">
La ligne 58 déclare une variable appelée status
, dont l’objectif est de spécifier comment l’état de l’interface est signalé. Les lignes 59 à 78 contiennent une <xsl:choose>
instruction qui remplit la status
variable en tenant compte de tous les états possibles. Comme toujours dans XSLT, la première <xsl:when>
instruction qui s’évalue comme VRAIE est exécutée, et les autres sont ignorées. Chaque <xsl:when>
instruction est expliquée séparément.
58 <xsl:variable name="status"> 59 <xsl:choose>
Les lignes 60 à 62 spécifient qu’aucune sortie n’est générée si admin-status
elle est « up » et oper-status
« up ». Dans ce cas, la status
variable reste vide.
60 <xsl:when test="admin-status='up' and oper-status='up'"> 61 <xsl:text> </xsl:text> 62 </xsl:when>
Les lignes 63 à 65 spécifient que si admin-status
elle est « down », la status
variable contient le texte offline
.
63 <xsl:when test="admin-status='down'"> 64 <xsl:text>offline</xsl:text> 65 </xsl:when>
Les lignes 66 à 68 spécifient que si oper-status
l’interface admin-status
physique est « down », la status
variable contient le texte p-offline
. (../
sélectionne l’interface physique.)
66 <xsl:when test="oper-status='down' and ../admin-status='down'"> 67 <xsl:text>p-offline</xsl:text> 68 </xsl:when>
Les lignes 69 à 71 spécifient que si oper-status
elle est « down » et l’interface oper-status
physique est « down », la status
variable contient le texte p-down
. (../
sélectionne l’interface physique.)
69 <xsl:when test="oper-status='down' and ../oper-status='down'"> 70 <xsl:text>p-down</xsl:text> 71 </xsl:when>
Les lignes 72 à 74 spécifient que si oper-status
elle est « down », la status
variable contient le texte down
.
72 <xsl:when test="oper-status='down'"> 73 <xsl:text>down</xsl:text> 74 </xsl:when>
Les lignes 75 à 77 spécifient que si aucun des cas de test n’est vrai, la status
variable contient oper-status
et admin-status
concaténée avec une barre de barre en tant que séparateur.
75 <xsl:otherwise> 76 <xsl:value-of select="concat(oper-status, '/', admin-status)"/> 77 </xsl:otherwise>
Les lignes 78 et 79 ferment des balises.
78 </xsl:choose> 79 </xsl:variable>
Les lignes 80 à 89 définissent une variable appelée desc
. Une <xsl:choose>
instruction remplit la variable en sélectionnant la description d’interface la plus spécifique disponible. Si une description d’interface logique est incluse dans la configuration, elle est utilisée pour remplir la desc
variable. Si ce n’est pas le cas, la description de l’interface physique est utilisée. Si aucune description d’interface physique n’est incluse dans la configuration, la variable reste vide. Comme toujours dans XSLT, la première <xsl:when>
instruction qui s’évalue comme VRAIE est exécutée, et les autres sont ignorées.
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>
Le reste du script spécifie la façon dont la sortie du mode opérationnel est affichée.
Les lignes 90 et 91 spécifient que le nom de l’interface logique est affiché en premier dans la sortie.
90 <logical-interface> 91 <name><xsl:value-of select="name"/></name>
Les lignes 92 à 94 testent si la desc
variable a un nombre de caractères non nul. Si le nombre de caractères est supérieur à zéro, la description de l’interface est affichée dans l’emplacement standard du admin-status
champ. (Dans la sortie standard, le admin-status
champ est affiché sur la deuxième ligne.)
92 <xsl:if test="string-length($desc)"> 93 <admin-status><xsl:value-of select="$desc"/></admin-status> 94 </xsl:if>
La ligne 95 spécifie que l’état de l’interface défini dans la status
variable s’affiche ensuite.
95 <admin-status><xsl:value-of select="$status"/></admin-status>
Les lignes 96 à 103 spécifient que si vous incluez l’argument lors de l’exécution protocol
du script, seules les interfaces avec ce protocole configuré sont affichées. Si vous n’incluez pas l’argument protocol
, toutes les interfaces s’affichent.
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>
Les lignes 104 à 106 ferment les balises.
104 </logical-interface> 105 </xsl:template> 106 </xsl:stylesheet>
Syntaxe SLAX
La version SLAX du script est la suivante :
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; } } }
Configuration
Procédure
Procédure étape par étape
Pour télécharger, activer et tester le script :
Copiez le script XSLT ou SLAX dans un fichier texte, nommez le fichier interface.xsl ou interface.slax le cas échéant et copiez-le dans le répertoire /var/db/scripts/op/ sur l’équipement.
En mode configuration, incluez l’instruction
file
au niveau de la[edit system scripts op]
hiérarchie et interface.xsl ou interface.slax , le cas échéant.[edit system scripts op] user@host# set file interface.(slax | xsl)
Émettez la
commit and-quit
commande pour valider la configuration et revenir en mode opérationnel.[edit] user@host# commit and-quit
Exécutez le script opérationnel en publiant la commande du
op interface
mode opérationnel.
Vérification
Vérification de la sortie du script de validation
But
Vérifiez que le script se comporte comme prévu.
Action
Émettez les show interfaces terse
commandes et op interface
les commandes opérationnelles et comparez les résultats. La show interfaces terse
commande affiche la sortie standard. La op interface
commande affiche la sortie personnalisée.
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-->
Émettez le op interface
commandement opérationnel pour différents niveaux hiérarchiques et examinez les résultats. Par exemple :
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