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, detailet 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, inet6ou mplstnp, 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, mplsou 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
fileau 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-quitcommande 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 interfacemode 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