Utiliser Junos PyEZ pour exécuter des bacs réutilisables sur des équipements Junos
RÉSUMÉ Utilisez la Device
rpc
propriété pour exécuter des bacs réutilisables opérationnels sur des équipements Junos.
Vous pouvez utiliser Junos PyEZ pour exécuter des appels de procédure à distance (RPC) à la demande sur les équipements Junos. Après avoir créé une instance de la Device
classe, vous pouvez exécuter des RPC en tant que propriété de l’instance Device
. Vous pouvez exécuter la plupart des commandes opérationnelles à l’aide de Junos PyEZ que celles que vous pouvez exécuter dans l’interface de ligne de commande.
L’API Junos XML est une représentation XML des instructions de configuration et des commandes en mode opérationnel de Junos OS. Il définit un équivalent XML pour toutes les instructions de la hiérarchie de configuration de Junos OS et de nombreuses commandes que vous émettez en mode opérationnel CLI. Chaque commande de mode opérationnel avec un équivalent XML Junos est mappée à un élément de balise de requête et, si nécessaire, à un élément de balise de réponse. Les balises de requête sont utilisées dans les RPC au sein de sessions de protocole NETCONF ou Junos XML pour demander des informations à un périphérique Junos. Le serveur renvoie la réponse à l’aide d’éléments XML Junos inclus dans l’élément de balise de réponse.
Lorsque vous utilisez Junos PyEZ pour exécuter des RPC, vous mappez le nom de la balise de requête à un nom de méthode. Cette rubrique explique comment mapper des commandes CLI aux RPC Junos PyEZ, comment exécuter des RPC à l’aide de Junos PyEZ et comment personnaliser les données renvoyées dans la réponse RPC.
Mapper des commandes Junos OS aux RPC Junos PyEZ
Toutes les commandes opérationnelles ayant des équivalents XML Junos sont répertoriées dans l’Explorateur d’API XML Junos. Vous pouvez également afficher l’élément de balise de requête XML Junos pour n’importe quelle commande en mode opérationnel ayant un équivalent XML Junos, soit sur l’interface de ligne de commande, soit à l’aide de Junos PyEZ. Une fois que vous avez obtenu la balise request, vous pouvez la mapper au nom de la méthode RPC Junos PyEZ.
Pour afficher la balise de requête XML Junos d’une commande dans l’interface de ligne de commande, incluez l’option | display xml rpc
après la commande. L’exemple suivant affiche la balise de requête de la show route
commande :
user@router> show route | display xml rpc <rpc-reply xmlns:junos="http://xml.juniper.net/junos/15.1R1/junos"> <rpc> <get-route-information> </get-route-information> </rpc> </rpc-reply>
Vous pouvez également afficher la balise de requête XML Junos d’une commande à l’aide de Junos PyEZ. Pour afficher la balise request, appelez la méthode d’instance Device
display_xml_rpc()
et incluez la chaîne de commande et format='text'
les arguments as. Par exemple :
from jnpr.junos import Device with Device(host='router.example.com') as dev: print (dev.display_xml_rpc('show route', format='text'))
L’exécution du programme renvoie la balise de requête pour la show route
commande.
<get-route-information> </get-route-information>
Vous pouvez mapper les balises de requête d’une commande opérationnelle à un nom de méthode RPC Junos PyEZ. Pour dériver le nom de la méthode RPC, remplacez les traits d’union de la balise de requête par des traits de soulignement (_) et supprimez les chevrons qui les entourent. Par exemple, la <get-route-information>
balise request correspond au nom de la get_route_information()
méthode.
Exécuter des RPC en tant que propriété de l’instance d’appareil
Chaque instance de Device
possède une rpc
propriété qui vous permet d’exécuter n’importe quel RPC disponible via l’API Junos XML. Dans une application Junos PyEZ, après avoir établi une connexion avec le périphérique, vous pouvez exécuter le RPC en ajoutant la propriété et le rpc
nom de la méthode RPC à l’instance de périphérique, comme illustré dans l’exemple suivant :
from jnpr.junos import Device from lxml import etree with Device(host='dc1a.example.com') as dev: #invoke the RPC equivalent to "show version" sw = dev.rpc.get_software_information() print(etree.tostring(sw, encoding='unicode'))
La valeur de retour est un objet XML commençant au premier élément sous la <rpc-reply>
balise. Dans ce cas, le get_software_information()
RPC renvoie l’élément <software-information>
.
<software-information> <host-name>dc1a</host-name> ... </software-information>
Les commandes Junos OS peuvent avoir des options de forme fixe qui n’ont pas de valeur. Par exemple, l’équivalent XML Junos de la show interfaces terse
commande indique qu’il s’agit terse
d’un élément vide.
user@router> show interfaces terse | display xml rpc <rpc-reply xmlns:junos="http://xml.juniper.net/junos/14.1R1/junos"> <rpc> <get-interface-information> <terse/> </get-interface-information> </rpc> </rpc-reply>
Pour exécuter un RPC et inclure une option de commande qui ne prend pas de valeur, ajoutez l’option à la liste d’arguments de la méthode RPC, remplacez les tirets dans le nom de l’option par des traits de soulignement et définissez-le sur True. Le code suivant exécute l’équivalent RPC Junos PyEZ de la show interfaces terse
commande :
rsp = dev.rpc.get_interface_information(terse=True)
Les commandes Junos OS peuvent également avoir des options qui nécessitent une valeur. Par exemple, dans la sortie suivante, l’élément interface-name
requiert une valeur, qui est le nom de l’interface pour laquelle vous souhaitez renvoyer des informations :
user@router> show interfaces ge-0/0/0 | display xml rpc <rpc-reply xmlns:junos="http://xml.juniper.net/junos/14.1R1/junos"> <rpc> <get-interface-information> <interface-name>ge-0/0/0</interface-name> </get-interface-information> </rpc> </rpc-reply>
Pour exécuter un RPC et inclure une option de commande qui nécessite une valeur, ajoutez l’option à la liste d’arguments de la méthode RPC, remplacez les tirets dans le nom de l’option par des traits de soulignement, puis définissez-la sur la valeur appropriée. L’exemple suivant exécute l’équivalent RPC Junos PyEZ de la show interfaces ge-0/0/0
commande :
rsp = dev.rpc.get_interface_information(interface_name='ge-0/0/0')
Spécifiez le format de la sortie RPC
Par défaut, la valeur de retour RPC est un objet XML commençant au premier élément sous la <rpc-reply>
balise. Vous pouvez également renvoyer la sortie RPC au format texte ou JSON (JavaScript Object Notation) en incluant le {'format':'text'}
dictionnaire ou {'format':'json'}
comme premier argument de la méthode RPC.
La sortie RPC au format JSON est prise en charge à partir de Junos OS version 14.2R1.
L’exemple suivant renvoie la sortie du get_software_information()
RPC au format texte, qui est identique à la sortie émise pour la show version
commande dans l’interface de ligne de commande, sauf que la sortie RPC est incluse dans un <output>
élément.
from jnpr.junos import Device from lxml import etree with Device(host='router1.example.com') as dev: sw_info_text = dev.rpc.get_software_information({'format':'text'}) print(etree.tostring(sw_info_text))
user@server:~$ python3 junos-pyez-rpc-text-format.py <output> Hostname: router1 Model: mx104 Junos: 18.3R1.9 JUNOS Base OS boot [18.3R1.9] JUNOS Base OS Software Suite [18.3R1.9] JUNOS Crypto Software Suite [18.3R1.9] JUNOS Packet Forwarding Engine Support (TRIO) [18.3R1.9] JUNOS Web Management [18.3R1.9] JUNOS Online Documentation [18.3R1.9] JUNOS SDN Software Suite [18.3R1.9] JUNOS Services Application Level Gateways [18.3R1.9] JUNOS Services COS [18.3R1.9] JUNOS Services Jflow Container package [18.3R1.9] JUNOS Services Stateful Firewall [18.3R1.9] JUNOS Services NAT [18.3R1.9] JUNOS Services RPM [18.3R1.9] JUNOS Services Captive Portal and Content Delivery Container package [18.3R1.9] JUNOS Macsec Software Suite [18.3R1.9] JUNOS Services Crypto [18.3R1.9] JUNOS Services IPSec [18.3R1.9] JUNOS DP Crypto Software Software Suite [18.3R1.9] JUNOS py-base-powerpc [18.3R1.9] JUNOS py-extensions-powerpc [18.3R1.9] JUNOS jsd [powerpc-18.3R1.9-jet-1] JUNOS Kernel Software Suite [18.3R1.9] JUNOS Routing Software Suite [18.3R1.9] <output>
L’exemple suivant renvoie la sortie du get_software_information()
RPC au format JSON.
from jnpr.junos import Device from pprint import pprint with Device(host='router1.example.com') as dev: sw_info_json = dev.rpc.get_software_information({'format':'json'}) pprint(sw_info_json)
user@server:~$ python3 junos-pyez-rpc-json-format.py {u'software-information': [{u'host-name': [{u'data': u'router1'}], u'junos-version': [{u'data': u'18.3R1.9'}], u'package-information': [{u'comment': [{u'data': u'JUNOS Base OS boot [18.3R1.9]'}], u'name': [{u'data': u'junos'}]}, {u'comment': [{u'data': u'JUNOS Base OS Software Suite [18.3R1.9]'}], u'name': [{u'data': u'jbase'}]}, ...
Spécifier l’étendue des données à renvoyer
Vous pouvez utiliser Junos PyEZ pour exécuter un RPC afin de récupérer des informations opérationnelles à partir d’équipements Junos. À partir de la version 2.3.0 de Junos PyEZ, lorsque vous demandez une sortie XML, vous pouvez filtrer la réponse pour ne renvoyer que des éléments spécifiques. Le filtrage de la sortie est avantageux lorsque vous disposez d’une sortie opérationnelle importante, mais que vous n’avez besoin de travailler qu’avec un sous-ensemble de données.
Pour filtrer la réponse RPC afin de ne renvoyer que des balises spécifiques, incluez l’argument de filter_xml
la méthode RPC. Le filter_xml
paramètre prend une chaîne contenant le filtre de sous-arborescence qui sélectionne les éléments à renvoyer. Le filtre de sous-arborescence renvoie les données qui correspondent aux critères de sélection.
L’exemple Junos PyEZ suivant exécute le <get-interface-information>
RPC et filtre la sortie pour récupérer uniquement l’élément <name>
de chaque <physical-interface>
élément de la réponse :
from jnpr.junos import Device from lxml import etree with Device(host='router.example.com', use_filter=True) as dev: filter = '<interface-information><physical-interface><name/></physical-interface></interface-information>' result = dev.rpc.get_interface_information(filter_xml=filter) print (etree.tostring(result, encoding='unicode'))
Lorsque vous exécutez le script, il affiche l’élément name de chaque interface physique.
user@server:~$ python3 junos-pyez-get-interface-names.py <interface-information style="normal"><physical-interface><name> lc-0/0/0 </name></physical-interface><physical-interface><name> pfe-0/0/0 </name></physical-interface><physical-interface><name> pfh-0/0/0 </name></physical-interface><physical-interface><name> xe-0/0/0 </name></physical-interface><physical-interface><name> xe-0/1/0 </name></physical-interface><physical-interface><name> ge-1/0/0 </name></physical-interface> ... </interface-information>
Spécifier le délai d’expiration RPC
Le temps d’exécution du RPC peut varier considérablement en fonction du RPC et de l’appareil. Par défaut, les RPC NETCONF expirent au bout de 30 secondes. Vous pouvez prolonger la valeur du délai d’expiration en incluant l’argument lors de l’exécution dev_timeout=seconds
du RPC pour vous assurer que le RPC n’expire pas pendant l’exécution. dev_timeout
ajuste le délai d’expiration de l’appareil uniquement pour cette seule opération RPC.
dev.rpc.get_route_information(table='inet.0', dev_timeout=55)
Normaliser la réponse RPC XML
Lorsque vous exécutez un RPC, la réponse RPC peut inclure des données qui sont entourées de sauts de ligne ou qui contiennent d’autres espaces superflus. Des espaces inutiles peuvent rendre difficile l’analyse du code XML et la recherche d’informations à l’aide de recherches textuelles. Vous pouvez normaliser une réponse RPC, qui supprime tous les espaces de début et de fin et remplace les séquences d’espaces internes par un seul espace.
Le Tableau 1 compare une réponse RPC par défaut à la version normalisée. La réponse RPC par défaut inclut de nombreux sauts de ligne qui ne sont pas présents dans la réponse normalisée.
Réponse RPC par défaut |
Réponse RPC normalisée |
---|---|
<interface-information style="terse"> <logical-interface> <name>\nge-0/0/0.0\n</name> <admin-status>\nup\n</admin-status> <oper-status>\nup\n</oper-status> <filter-information>\n</filter-information> <address-family> <address-family-name>\ninet\n</address-family-name> <interface-address> <ifa-local emit="emit">\n198.51.100.1/24\n</ifa-local> </interface-address> </address-family> </logical-interface> </interface-information> |
<interface-information style="terse"> <logical-interface> <name>ge-0/0/0.0</name> <admin-status>up</admin-status> <oper-status>up</oper-status> <filter-information/> <address-family> <address-family-name>inet</address-family-name> <interface-address> <ifa-local emit="emit">198.51.100.1/24</ifa-local> </interface-address> </address-family> </logical-interface> </interface-information> |
Vous pouvez activer la normalisation pour la durée d’une session avec un périphérique, ou vous pouvez normaliser une réponse RPC individuelle lorsque vous exécutez le RPC. Pour activer la normalisation de l’ensemble de la session de périphérique, incluez-la normalize=True
dans la liste d’arguments lorsque vous créez l’instance de périphérique ou lorsque vous vous connectez à l’appareil à l’aide de la open()
méthode.
dev = Device(host='router1.example.com', user='root', normalize=True) # or dev.open(normalize=True)
Pour normaliser une réponse RPC individuelle, incluez-la normalize=True
dans la liste des arguments de cette méthode RPC.
dev.rpc.rpc_method(normalize=True)
Par exemple :
rsp = dev.rpc.get_interface_information(interface_name='ge-0/0/0.0', terse=True, normalize=True)
Si vous ne normalisez pas la réponse RPC, vous devez tenir compte des espaces lorsque vous utilisez des expressions XPath qui font référence à un nœud ou à une valeur spécifique. L’exemple suivant sélectionne l’adresse IPv4 d’une interface logique. Dans l’expression XPath, le prédicat spécifiant la inet
famille doit tenir compte des espaces supplémentaires pour que la recherche réussisse. La valeur résultante inclut les sauts de ligne de début et de fin.
rsp = dev.rpc.get_interface_information(interface_name='ge-0/0/0.0', terse=True) print (rsp.xpath('.// \ address-family[normalize-space(address-family-name)="inet"]/ \ interface-address/ifa-local')[0].text)
'\n198.51.100.1/24\n'
Lorsque vous normalisez la réponse RPC, les espaces de début et de fin sont supprimés, ce qui facilite grandement les recherches textuelles.
rsp = dev.rpc.get_interface_information(interface_name='ge-0/0/0.0', terse=True, normalize=True) print (rsp.xpath('.//address-family[address-family-name="inet"]/ \ interface-address/ifa-local')[0].text)
'198.51.100.1/24'