SlideShare une entreprise Scribd logo
Python & Réseaux
Initiation à la programmation réseaux
Les Sockets
CC
Pro
Digit
Consulting
Chapitre I
Plan
1. Rappels
2. Les sockets
3. Exemple serveur-client
4. Le Threading
Rappels
Comment faire communiquer deux applications, sur la même machine ou à
distantes ?
 Par la connexion au réseau local ou à Internet !
 En précisant le protocole :
Le protocole TCP (Transmission Control Protocol) :
Pour connecter deux applications et de leur faire échanger des informations.
« Orienté connexion »
Le protocole UDP (User Datagram Protocol):
Envoie des informations au travers du réseau, en spécifiant une cible, sans
vérifier l’effectivité réception. Protocole non connecté.
Dans l'architecture que nous allons voir dans les exemples du cours on
trouve en général un serveur et plusieurs clients.
Le serveur, c'est une machine qui va traiter les requêtes du client.
Rappels
Dans les exemples que nous allons voir, nous allons créer deux applications
: l'application serveur et l'application client.
Le serveur écoute donc en attendant des connexions et les clients se
connectent au serveur.
Les différentes étapes
Nos applications vont fonctionner selon un schéma assez similaire.
Voici dans l'ordre les étapes du client et du serveur. Les étapes sont très
simplifiées, la plupart des serveurs peuvent communiquer avec plusieurs
clients mais nous ne verrons pas cela tout de suite.
Rappels
Le serveur :
- attend une connexion de la part du client ;
- accepte la connexion quand le client se connecte ;
- échange des informations avec le client ;
- ferme la connexion.
Le client :
- se connecte au serveur ;
- échange des informations avec le serveur ;
- ferme la connexion.
Comme on l'a vu, le serveur peut dialoguer avec plusieurs clients : c'est
tout l'intérêt.
Rappels
Établir une connexion
Pour que le client se connecte au serveur, il nous faut deux informations :
- Le nom d'hôte (host name), identifiant une machine sur Internet ou sur un
réseau local. Les noms d'hôtes permettent de représenter des adresses IP de
façon plus claire (on a un nom comme google.fr, plus facile à retenir que
l'adresse IP correspondante 74.125.224.84).
- Un numéro de port, qui est souvent propre au type d'information que l'on va
échanger. Si on demande une connexion web, le navigateur va en général
interroger le port 80 si c'est en http ou le port 443 si c'est en connexion
sécurisée (https). Le numéro de port est compris entre 0 et 65535 et les
numéros entre 0 et 1023 sont réservés par le système (ce n'est pas une très
bonne idée de les utilisées).
Les Sockets
Les sockets sont des objets qui permettent d'ouvrir une connexion avec une
machine locale ou distante et d'échanger avec elle.
Ces objets sont définis dans le module socket et nous allons maintenant
voir comment ils fonctionnent.
Commençons par importer notre module socket.
>>> import socket
Nous allons d'abord créer notre serveur puis, en parallèle, un client.
Nous allons faire communiquer les deux. Pour l'instant, nous nous occupons
du serveur.
Les Sockets
Construire notre socket
Nous allons pour cela faire appel au constructeur socket. Dans le cas d'une
connexion TCP, il prend les deux paramètres suivants, dans l'ordre :
socket.AF_INET : la famille d'adresses, ici ce sont des adresses Internet ;
socket.SOCK_STREAM : le type du socket, SOCK_STREAM pour le protocole TCP.
>>> connexion_principale = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Les Sockets
Connecter le socket
Pour une connexion serveur, qui va attendre des connexions de clients, on
utilise la méthode bind. Elle prend un paramètre : le tuple (nom_hote,
port).
Question C‘est notre client qui se connectait à notre serveur ou
l'inverse…
Oui mais c‘est notre client qui se connecte à notre serveur , pour que
notre serveur écoute sur un port, il faut le configurer en conséquence.
Donc, dans notre cas, le nom de l'hôte sera vide et le port sera celui que
vous voulez, entre 1024 et 65535.
>>> connexion_principale.bind(('', 12800))
Les Sockets
Faire écouter notre socket
Notre socket est prêt à écouter sur le port 12800 mais il n'écoute pas
encore. On va avant tout lui préciser le nombre maximum de connexions
qu'il peut recevoir sur ce port sans les accepter. On utilise pour
cela la méthode listen. On lui passe généralement 5 en paramètre.
Cela veut dire que notre serveur ne pourra dialoguer qu'avec 5 clients
maximum ?
Non. Cela veut dire que si 5 clients se connectent et que le serveur
n'accepte aucune de ces connexions, aucun autre client ne pourra se
connecter. Mais généralement, très peu de temps après que le client
ait demandé la connexion, le serveur l'accepte. Vous pouvez donc avoir
bien plus de clients connectés, ne vous en faites pas.
Les Sockets
Accepter une connexion venant du client
Enfin, dernière étape, on va accepter une connexion. Aucune connexion ne
s'est encore présentée mais la méthode accept que nous allons utiliser va
bloquer le programme tant qu'aucun client ne s'est connecté.
Il est important de noter que la méthode accept renvoie deux informations :
le socket connecté qui vient de se créer, celui qui va nous permettre de
dialoguer avec notre client tout juste connecté ;
un tuple représentant l'adresse IP et le port de connexion du client.
Les Sockets
Le port de connexion du client… ce n'est pas le même que celui du
serveur ?
Non car votre client, en ouvrant une connexion, passe par un port dit «
de sortie » qui va être choisi par le système parmi les ports
disponibles. Pour schématiser, quand un client se connecte à un
serveur, il emprunte un port puis établit la connexion sur le port du
serveur. Il y a donc deux ports dans notre histoire mais celui
qu'utilise le client pour ouvrir sa connexion ne va pas nous
intéresser.
>>> connexion_avec_client, infos_connexion =
connexion_principale.accept()
Les Sockets
Création du client
Commencez par construire votre socket de la même façon :
>>> import socket
>>> connexion_avec_serveur = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Connecter le client
Pour se connecter à un serveur, on va utiliser la méthode connect. Elle prend
en paramètre un tuple, comme bind, contenant le nom d'hôte et le numéro du
port identifiant le serveur auquel on veut se connecter.
Le numéro du port sur lequel on veut se connecter, vous le connaissez : c'est
12800. Vu que nos deux applications Python sont sur la même machine, le nom
d'hôte va être localhost.
>>> connexion_avec_serveur.connect(('localhost', 12800))
Maintenant notre serveur et notre client sont connectés !
Les Sockets
Création du client (suite)
Si vous retournez dans la console Python abritant le serveur, vous pouvez
constater que la méthode accept ne bloque plus, puisqu'elle vient
d'accepter la connexion demandée par le client. Vous pouvez donc de
nouveau saisir du code côté serveur :
>>> print(infos_connexion)
('127.0.0.1', 2901)
La première information, c'est l'adresse IP du client. Ici, elle vaut
127.0.0.1 c'est-à-dire l'IP de l'ordinateur local. Dites-vous que l'hôte
localhost redirige vers l'IP 127.0.0.1.
Les Sockets
Faire communiquer nos sockets
Comment faire communiquer nos sockets ? En utilisant les méthodes send pour
envoyer et recv pour recevoir.
Les informations transmises seront des chaînes de bytes, pas des str !
Donc côté serveur :
>>> connexion_avec_client.send(b"Je viens d'accepter la connexion")
32
La méthode send vous renvoie le nombre de caractères envoyés.
Maintenant, côté client, on va réceptionner le message que l'on vient d'envoyer.
La méthode recv prend en paramètre le nombre de caractères à lire. Généralement,
on lui passe la valeur 1024. Si le message est plus grand que 1024 caractères,
on récupérera le reste après.
Les Sockets
Dans la fenêtre Python côté client, donc :
>>> msg_recu = connexion_avec_serveur.recv(1024)
>>> msg_recu
b"Je viens d'accepter la connexion"
Songez que ce petit mécanisme peut servir à faire communiquer des
applications entre elles non seulement sur la machine locale, mais aussi
sur des machines distantes et reliées par Internet.
Le client peut également envoyer des informations au serveur et le serveur
peut les réceptionner, tout cela grâce aux méthodes send et recv que nous
venons de voir.
Les Sockets
Fermer la connexion
Pour fermer la connexion, il faut appeler la méthode close de notre
socket.
Côté serveur :
>>> connexion_avec_client.close()
Et du côté client :
>>> connexion_avec_serveur.close()
On va récapituler en présentant dans l'ordre un petit serveur et un client
que nous pouvons utiliser.
Et pour finir, nous allons optimiser un peu notre serveur en lui
permettant de gérer plusieurs clients à la fois.
Les Sockets
import socket
hote = ''
port = 12800
connexion_principale = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connexion_principale.bind((hote, port))
connexion_principale.listen(5)
print("Le serveur écoute à présent sur le port {}".format(port))
connexion_avec_client, infos_connexion = connexion_principale.accept()
msg_recu = b""
while msg_recu != b"fin":
msg_recu = connexion_avec_client.recv(1024)
# L'instruction ci-dessous peut lever une exception si le message
# Réceptionné comporte des accents
print(msg_recu.decode())
connexion_avec_client.send(b"5 / 5")
print("Fermeture de la connexion")
connexion_avec_client.close()
connexion_principale.close()
Le code pour le serveur
Voici le code du serveur,
légèrement amélioré. Il
n'accepte qu'un seul
client (nous verrons plus
bas comment en accepter
plusieurs) et il tourne
jusqu'à recevoir du client
le message fin.
À chaque fois que le
serveur reçoit un message,
il envoie en retour le
message '5 / 5'
Les Sockets
import socket
hote = "localhost"
port = 12800
connexion_avec_serveur = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connexion_avec_serveur.connect((hote, port))
print("Connexion établie avec le serveur sur le port {}".format(port))
msg_a_envoyer = b""
while msg_a_envoyer != b"fin":
msg_a_envoyer = input("> ")
# Peut planter si vous tapez des caractères spéciaux
msg_a_envoyer = msg_a_envoyer.encode()
# On envoie le message
connexion_avec_serveur.send(msg_a_envoyer)
msg_recu = connexion_avec_serveur.recv(1024)
print(msg_recu.decode())
# Là encore, peut planter s'il y a des accents
print("Fermeture de la connexion")
connexion_avec_serveur.close()
Le code pour le
client
Voici le code du
client pouvant
interagir avec notre
serveur.
Il va tenter de se
connecter sur le port
12800 de la machine
locale. Il demande à
l'utilisateur de
saisir quelque chose
au clavier et envoie
ce quelque chose au
serveur, puis attend
sa réponse.
Les Sockets
Que font les méthodes encode et décode ?
encode est une méthode de str. Elle peut prendre en paramètre un nom
d'encodage et permet de passer un str en chaîne bytes : le type de chaîne
que send accepte. En fait, encode encode la chaîne str en fonction d'un
encodage précis (par défaut, Utf-8).
decode, à l'inverse, est une méthode de bytes. Elle aussi peut prendre en
paramètre un encodage et elle renvoie une chaîne str décodée grâce à
l'encodage (par défaut Utf-8).
Si l'encodage de votre console est différent d'Utf-8 (ce sera souvent le
cas sur Windows), des erreurs peuvent se produire si les messages que vous
encodez ou décodez comportent des accents.
Le Threading
Un serveur plus élaboré
Quel sont les problèmes de notre serveur ?
 N'accepter qu'un seul client. Si d'autres clients veulent se connecter,
ils ne peuvent pas.
 Attend le message d'un client et qu‘il renvoie immédiatement après
réception. Mais ce n'est pas toujours le cas : parfois vous envoyez un
message au client alors qu'il ne vous a rien envoyé et vis versa.
 Les erreurs sont assez mal gérées.
Le Threading
Le module select
Permet d’interroger plusieurs clients dans l'attente d'un message à
réceptionner, sans paralyser notre programme.
Pour schématiser, select va écouter sur une liste de clients et retourner
au bout d'un temps précisé. Ce que renvoie select, c'est la liste des
clients qui ont un message à réceptionner. Il suffit de parcourir ces
clients, de lire les messages en attente (grâce à recv).
Sur Linux, select peut être utilisé sur autre chose que des sockets mais,
cette fonctionnalité n'étant pas portable.
Le Threading
Comment marche la fonction select
La fonction qui nous intéresse porte le même nom que le module associé,
select. Elle prend trois ou quatre arguments et en renvoie trois. :
rlist : la liste des sockets en attente d'être lus ;
wlist : la liste des sockets en attente d'être écrits ;
xlist : la liste des sockets en attente d'une erreur ;
timeout : le délai pendant lequel la fonction attend avant de retourner. Si
vous précisez en timeout 0, la fonction retourne immédiatement. Si ce
paramètre n'est pas précisé, la fonction retourne dès qu'un des sockets
change d'état (est prêt à être lu s'il est dans rlist par exemple) mais pas
avant.
Le Threading
Comment marche la fonction select
Ce qu'on veut, c'est mettre des sockets dans une liste et que select les
surveille, en retournant dès qu'un socket est prêt à être lu. Comme cela
notre programme ne bloque pas et il peut recevoir des messages de plusieurs
clients dans un ordre complètement inconnu.
Maintenant, concernant le timeout : si on ne le précise pas, select bloque
jusqu'au moment où l'un des sockets que nous écoutons est prêt à être lu,
dans notre cas. Si vous précisez un timeout de 0, select retournera tout de
suite. Sinon, select retournera au bout du temps que vous indiquez en
secondes, ou plus tôt si un socket est prêt à être lu.
Donc si on précise un timeout de 1, la fonction va bloquer pendant une
seconde maximum. Mais si un des sockets en écoute est prêt à être lu dans
l'intervalle (c'est-à-dire si un des clients envoie un message au serveur),
Le Threading
Considérez cette ligne :
>>> rlist, wlist, xlist = select.select(clients_connectes, [], [], 2)
Cette instruction va écouter les sockets contenus dans la liste
clients_connectes.
Elle retournera au plus tard dans 2 secondes. Mais elle retournera plus
tôt si un client envoie un message. La liste des clients ayant envoyé un
message se retrouve dans notre variable rlist.
On la parcourt ensuite et on peut appeler recv sur chacun des sockets.
Le Threading
Le but va être de créer un serveur pouvant accepter plusieurs clients,
réceptionner leurs messages et leur envoyer une confirmation à chaque
réception.
L'exercice ne change pas beaucoup mais on va utiliser select pour
travailler avec plusieurs clients.
La fonction select permet d’écouter plusieurs clients connectés mais va
également nous permettre de savoir si un (ou plusieurs) clients sont
connectés au serveur.
Souvenez que la méthode accept est aussi une fonction bloquante. On va du
reste l'utiliser de la même façon qu'un peu plus haut.
Le Threading
Maintenant notre serveur peut accepter des connexions de plus d'un client,
vous pouvez faire le test. En outre, il ne se bloque pas dans l'attente d'un
message, du moins pas plus de 50 millisecondes.
Les commentaires sont assez précis pour vous permettre d'aller plus loin.
Ceci n'est pas encore une version complète mais, grâce à cette base, vous
devriez pouvoir facilement arriver à quelque chose.
Projet : Faire un mini serveur de tchat ?
Les déconnexions fortuites ne sont pas gérées non plus.
Mais vous avez assez d'éléments pour faire des tests et améliorer notre
serveur.
Le Threading
Pour aller plus loin
Pour plus de documentation du module socket, de select et de socketserver
aller au niveau de leur page officielle.
Le module socketserver propose une alternative pour monter vos
applications serveur. Il en existe d'autres, dans tous les cas : vous
pouvez utiliser des sockets non bloquants (c'est-à-dire qui ne bloquent
pas le programme quand vous utilisez leur méthode accept ou recv) ou des
threads pour exécuter différentes portions de votre programme en
parallèle.
Conclusion
Dans la structure réseau vue, on trouve un serveur pouvant dialoguer avec
plusieurs clients.
Pour créer une connexion côté serveur ou client, on utilise le module
socket et la classe socket de ce module.
Pour se connecter à un serveur, le socket client utilise la méthode
connect.
Pour écouter sur un port précis, le serveur utilise d'abord la méthode
bind puis la méthode listen.
Pour s'échanger des informations, les sockets client et serveur utilisent
les méthodes send et recv..
Conclusion
Pour fermer une connexion, le socket serveur ou client utilise la méthode
close.
Le module select peut être utile si l'on souhaite créer un serveur pouvant
gérer plusieurs connexions simultanément ; toutefois, il en existe
d'autres.
Les méthodes de l'objet socket
accept() accepte une connexion, retourne un nouveau socket et une adresse client
bind(addr) associe le socket à une adresse locale
close() ferme le socket
connect(addr) connecte le socket à une adresse distante
connect_ex(addr) connect, retourne un code erreur au lieu d'une exception
dup() retourne un nouveau objet socket identique à celui en cours
fileno() retourne une description du fichier
getpeername() retourne l'adresse distante
getsockname() retourne l'adresse locale
getsockopt(level, optname[, buflen]) : retourne les options du socket
gettimeout() retourne le timeout ou none
listen(n) commence à écouter les connexions entrantes
Les méthodes de l'objet socket
makefile([mode, [bufsize]]) : retourne un fichier objet pour le
socket
recv(buflen[, flags]) : recoit des données
recv_into(buffer[, nbytes[, flags]]) : recoit des données (dans un buffer)
recvfrom(buflen[, flags]) : reçoit des données et l'adresse de
l'envoyeur
recvfrom_into(buffer[,nbytes,[,flags]) : reçoit des données et l'adresse de
l'envoyeur (dans un buffer)
sendall(data[, flags]) : envoye toutes les données
send(data[, flags]) : envoye des données mais il se peut
que pas toutes le soit
sendto(data[, flags], addr) : envoye des données à une adresse
donnée
Python & Réseaux
Initiation à la programmation réseaux
Configuration Réseaux à Distance
avec Netmiko
CC
Pro
Digit
Consulting
Chapitre II
Plan
1. Présentation de la Bibliothèque Netmiko
2. Copie sécurisée
3. Netmiko via SSH Proxy
4. Netmiko et TextFSMRappels
Pourquoi Netmiko ?
Certain types de problèmes peuvent prendre beaucoup de temps de développement et
de dépannage :
 Problèmes similaires avec Python-SSH et les périphériques réseau
 les commutateurs HP ProCurve ont des codes d'échappement ANSI dans la sortie
 Cisco WLC a un message supplémentaire «connexion en tant que:»
Netmiko a donc été créé pour simplifier cette gestion SSH de niveau inférieur sur
un large éventail de fournisseurs de réseaux et de plates-formes.
Depuis la fin de 2014, Kirk Byers travaille sur une bibliothèque Python open source
qui simplifie la gestion SSH pour les périphériques réseau.
Pourquoi Netmiko ?
La bibliothèque est basée sur la bibliothèque Paramiko SSH et s'appelle Netmiko.
Vous pouvez trouver la bibliothèque sur https://github.com/ktbyers/netmiko et la
dernière version publiée du logiciel peut être téléchargée
https://github.com/ktbyers/netmiko/releases .
Les objectifs de cette bibliothèque sont les suivants:
 Établir avec succès une connexion SSH à un appareil réseau,
 Exécution des commandes show et la récupération des données de sortie,
 Simplifiez l'exécution des commandes de configuration,
 Simplifiez des actions de validation,
 Sur un large éventail de fournisseurs de réseaux et de plates-formes.
Pourquoi Netmiko ?
Depuis janvier 2019, Netmiko prend en charge les plates-formes suivantes avec 3
niveaux de test indiqué.
Testé régulièrement:
Arista EOS - Cisco ASA - Cisco IOS / IOS-XE - Cisco IOS-XR - Cisco NX-OS
Cisco SG300 - HP Comware7 - HP ProCurve - Juniper Junos - Linux
Tests limités:
Alcatel AOS6 / AOS8 - Apresia Systems AEOS - Calix B6 - Cisco AireOS (contrôleurs
LAN sans fil) - Dell OS9 (Force10) - Dell OS10 - Dell PowerConnect - Extreme ERS
(Avaya) - VSP extrême (Avaya) - Extreme VDX (Brocade) - Extreme MLX / NetIron
(brocart / fonderie) – Huawei - Infusion IP OcNOS – Mellanox - NetApp cDOT
OneAccess - Palo Alto PAN-OS – Pluribus - Ruckus ICX / FastIron
Ubiquiti EdgeSwitch - Vyatta VyOS
Pourquoi Netmiko ?
Expérimental:
A10 – Accedian – Aruba - Ciena SAOS - Citrix Netscaler - Cisco Telepresence
Check Point GAiA – Coriant - Dell OS6 - Dell EMC Isilon – Eltex - Enterasys
EXOS extrêmes - Aile extrême - Extreme SLX (Brocade) - F5 TMSH - F5 Linux
Fortinet - MRV Communications OptiSwitch - Nokia / Alcatel SR-OS - QuantaMesh
Rad ETX
TP 1
TP 1: Session SSH simple vers un routeur Cisco
Exécutez et renvoyez la commande 'show ip int brief'.
Tout d'abord, importer la fonction ConnectHandler du module Netmiko.
ConnectHandler sélectionne la classe Netmiko correcte en fonction du type
d'appareil.
>>> from netmiko import ConnectHandler
Définir ensuite un dictionnaire de périphériques réseau composé d'un type de
périphérique, d'une adresse IP, d'un nom d'utilisateur et d'un mot de passe.
>>> cisco = {
...: 'device_type': 'cisco_ios',
...: 'host': 'cisco.domain.com',
...: 'username': 'admin',
...: 'password': 'cisco123',
...: }
TP 1
À ce stade, on peut se connecter à l'appareil.
Notez ci-dessus que j'ai spécifié le device_type comme 'cisco_ios'. Tous les
device_types ne sont pas pris en charge.
Pour se connecter, on appelle ConnectHandler et en passant mon dictionnaire de
périphérique défini précédemment:
>>> net_connect = ConnectHandler(**cisco)
Alternativement, je pourrais simplement appeler la fonction ConnectHandler
directement et ne pas utiliser de dictionnaire (comme suit):
>>> net_connect2 = ConnectHandler(device_type='cisco_ios',
host='cisco.domain.com', username='admin', password='cisco123')
TP 1
A ce stade, nous devrions avoir une connexion SSH établie.
On peut vérifier cela en exécutant la méthode find_prompt ()
>>> net_connect.find_prompt()
'cisco3#'
On peut également envoyer des commandes sur le canal SSH et recevoir la sortie.
On utilise la méthode .send_command () pour envoyer une commande :
>>> output = net_connect.send_command("show ip int brief")
TP 1
>>> print(output)
Interface IP-Address OK? Method Status Protocol
GigabitEthernet0/0/0 10.10.10.22 YES manual up up
GigabitEthernet0/0/1 unassigned YES NVRAM administratively down down
GigabitEthernet0/1/0 unassigned YES unset down down
GigabitEthernet0/1/1 unassigned YES unset down down
GigabitEthernet0/1/2 unassigned YES unset down down
GigabitEthernet0/1/3 unassigned YES unset down down
Vlan1 unassigned YES unset up down
Essayons également de modifier la configuration de ce routeur.
Tout d'abord, regardons la configuration de journalisation actuelle:
>>> output = net_connect.send_command("show run | inc logging")
TP 1
>>> print(output)
logging synchronous
Maintenant, afin de faire des changements de configuration, on peut créer une
liste de commandes de configuration que l’on veut exécuter. Il peut s'agir d'une
seule commande ou de plusieurs commandes.
>>> config_commands = ['logging buffered 19999']
J'exécute ensuite la méthode send_config_set (). Cette méthode entrera en mode de
configuration, exécutera les commandes, puis quittera le mode de configuration
(notez qu'il y aura quelques exceptions à ce comportement en fonction de la
plate-forme - par exemple, IOS-XR ne quittera pas le mode de configuration en
raison de modifications en attente).
>>> output = net_connect.send_config_set(config_commands)
TP 1
>>> output = net_connect.send_config_set(config_commands)
>>> print(output)
config term
Enter configuration commands, one per line. End with CNTL/Z.
cisco3(config)#logging buffered 19999
cisco3(config)#end
cisco3#
Vérifier la modification:
>>> output = net_connect.send_command("show run | inc logging")
>>> print(output)
logging buffered 19999
logging synchronous
TP 2
TP 2: Exécution de «show arp» sur un ensemble de périphériques réseau composés de
différents fournisseurs et plates-formes.
Tout d'abord, on doit définir
les périphériques réseau
(les adresses IP et les mots de passe réels
ont été masqués):
>>> from netmiko import ConnectHandler
>>> from datetime import datetime
TP 2
>>> cisco3 = {
...: 'device_type': 'cisco_ios',
...: 'host': 'cisco3.domain.com',
...: 'username': 'admin',
...: 'password': 'cisco123',
...: }
...:
>>> cisco_asa = {
...: 'device_type': 'cisco_asa',
...: 'host': '10.10.10.88',
...: 'username': 'admin',
...: 'password': 'cisco123',
...: 'secret': 'cisco123',
...: }
...:
TP 2
>>> cisco_xrv = {
...: 'device_type': 'cisco_xr',
...: 'host': '10.10.10.77',
...: 'username': 'admin',
...: 'password': 'cisco123',
...: }
>>> arista8 = {
...: 'device_type': 'arista_eos',
...: 'host': 'arista8.domain.com',
...: 'username': 'admin',
...: 'password': '!cisco123',
...: }
...:
TP 2
>>> hp_procurve = {
...: 'device_type': 'hp_procurve',
...: 'host': '10.10.10.68',
...: 'username': 'admin',
...: 'password': '!cisco123',
...: }
...:
>>> juniper_srx = {
...: 'device_type': 'juniper',
...: 'host': 'srx1.domain.com',
...: 'username': 'admin',
...: 'password': '!cisco123',
...: }
TP 2
Ensuite, créer une liste Python qui inclut tous ces appareils:
>>> all_devices = [cisco3, cisco_asa, cisco_xrv, arista8, hp_procurve,
juniper_srx]
Maintenant, on va créer une boucle for qui itère sur tous ces appareils. Chaque
fois dans la boucle: le code se connecte à l'appareil, exécute 'show arp', puis
affiche la sortie. On gardera également la trace du temps nécessaire à
l'exécution du code.
TP 2
>>> start_time = datetime.now()
...: for a_device in all_devices:
...: net_connect = ConnectHandler(**a_device)
...: output = net_connect.send_command("show arp")
...: print(f"nn--------- Device {a_device['device_type']} ---------")
...: print(output)
...: print("--------- End ---------")
...:
...: end_time = datetime.now()
...: total_time = end_time - start_time
TP 2
Voici la sortie de la boucle for (c'est-à-dire toute la sortie "show arp"):
--------- Device cisco_ios ---------
Protocol Address Age (min) Hardware Addr Type Interface
Internet 10.10.10.1 32 0062.ec29.70fe ARPA GigabitEthernet0/0/0
Internet 10.10.10.20 156 c89c.1dea.0eb6 ARPA GigabitEthernet0/0/0
Internet 10.10.10.22 - a093.5141.b780 ARPA GigabitEthernet0/0/0
Internet 10.10.10.37 178 0001.00ff.0001 ARPA GigabitEthernet0/0/0
Internet 10.10.10.38 15 0002.00ff.0001 ARPA GigabitEthernet0/0/0
--------- End ---------
--------- Device cisco_asa ---------
outside 10.10.10.1 0062.ec29.70fe 1949
outside 10.10.10.20 c89c.1dea.0eb6 10226
outside 10.10.10.37 0001.00ff.0001 11606
outside 10.10.10.38 0002.00ff.0001 11636
--------- End ---------
TP 2
Voici la sortie de la boucle for (c'est-à-dire toute la sortie "show arp"):
--------- Device cisco_xr ---------
Thu Jan 30 10:45:44.240 UTC
-------------------------------------------------------------------------------
0/0/CPU0
-------------------------------------------------------------------------------
Address Age Hardware Addr State Type Interface
10.10.10.1 00:32:36 0062.ec29.70fe Dynamic ARPA GigabitEthernet0/0/0/0
10.10.10.19 02:50:35 0024.c4e9.48ae Dynamic ARPA GigabitEthernet0/0/0/0
10.10.10.20 00:30:26 c89c.1dea.0eb6 Dynamic ARPA GigabitEthernet0/0/0/0
10.10.10.21 03:09:20 1c6a.7aaf.576c Dynamic ARPA GigabitEthernet0/0/0/0
10.10.10.22 02:58:54 a093.5141.b780 Dynamic ARPA GigabitEthernet0/0/0/0
10.10.10.23 01:37:37 502f.a8b1.6900 Dynamic ARPA GigabitEthernet0/0/0/0
10.10.10.32 02:56:30 5254.abc7.26aa Dynamic ARPA GigabitEthernet0/0/0/0
10.10.10.37 - 0001.00ff.0001 Interface ARPA GigabitEthernet0/0/0/0
10.10.10.38 01:55:33 0002.00ff.0001 Dynamic ARPA GigabitEthernet0/0/0/0
10.10.10.39 00:11:32 6464.9be8.08c8 Dynamic ARPA GigabitEthernet0/0/0/0
10.10.10.42 00:00:46 ec38.739e.2f08 Dynamic ARPA GigabitEthernet0/0/0/0
10.10.10.43 00:22:35 5254.abda.5495 Dynamic ARPA GigabitEthernet0/0/0/0
--------- End ---------
TP 2
--------- Device arista_eos ---------
Address Age (min) Hardware Addr Interface
10.10.10.1 0 0062.ec29.70fe Vlan1, Ethernet1
10.10.10.20 0 c89c.1dea.0eb6 Vlan1, not learned
10.10.10.43 0 5254.abda.5495 Vlan1, not learned
--------- End ---------
--------- Device hp_procurve ---------
IP ARP table
IP Address MAC Address Type Port
--------------- ----------------- ------- ----
10.10.19.1 0062ec-2970fd dynamic 26
10.10.19.20 c07bbc-65272e dynamic 26
--------- End ---------
TP 2
--------- Device juniper ---------
MAC Address Address Name Interface Flags
00:62:ec:29:70:fe 10.10.10.1 10.10.10.1 vlan.0 none
c8:9c:1d:ea:0e:b6 10.10.10.20 10.10.10.20 vlan.0 none
Total entries: 2
--------- End ---------
>>> print(total_time)
0:00:42.062773
Comme vous pouvez le voir, l'exécution du code a pris un peu plus de 42 secondes.
Cela pourrait être considérablement amélioré en créant les sessions SSH
simultanément voir le code ici pour quelques exemples utilisant la concurrence.
TP 2
Méthodes Netmiko couramment utilisées:
net_connect.send_command () - Envoie la commande sur le canal, retourne la sortie (basée sur le
modèle)
net_connect.send_command_timing () - Envoie une commande sur le canal, retourne la sortie (en
fonction du timing)
net_connect.send_config_set () - Envoie des commandes de configuration au périphérique distant
net_connect.send_config_from_file () - Envoie des commandes de configuration chargées à partir d'un
fichier
net_connect.save_config () - Enregistrez la configuration en cours d'exécution dans la
configuration de démarrage
net_connect.enable () - Entrer en mode d'activation
net_connect.find_prompt () - Retourne l'invite actuelle du routeur
net_connect.commit () - Exécute une action de validation sur Juniper et IOS-XR
net_connect.disconnect () - Ferme la connexion
net_connect.write_channel () - Écriture de bas niveau du canal
net_connect.read_channel () - Écriture de bas niveau du canal
Prise en charge de la copie sécurisée
L'extension des capacités de transfert de fichiers Secure Copy incluses dans
Netmiko devrait faciliter les mises à niveau du système d'exploitation et
d'autres opérations de transfert de fichiers.
Code tester sur Cisco IOS, IOS-XE, NX-OS, IOS-XR, Juniper Junos et Arista EOS.
Il s'agit à la fois des opérations de copie sécurisée «get» et «put» et comprend
également des méthodes associées qui vérifient si le fichier existe, qui
vérifient que l'espace disque est disponible et qui effectuent une comparaison
MD5 sur le fichier transféré.
Remarque: Le pilote Netmiko nécessite généralement l'activation d'un serveur SCP
sur le périphérique réseau distant.
Prise en charge de la copie sécurisée
En plus d'ajouter la prise en charge de la copie sécurisée pour des plates-formes
supplémentaires, une fonction «file_transfer» de niveau supérieur effectue un
transfert_fichier fiable. Cela devrait maintenant être l'interface principale
pour utiliser la copie sécurisée de Netmiko.
Voici les principaux arguments de la fonction file_transfer dans Netmiko :
def file_transfer(ssh_conn, source_file, dest_file,
file_system = None, direction='put',
disable_md5=False, overwrite_file=False):
En regardant les arguments, nous pouvons voir que 'file_transfer' prend une
connexion Netmiko SSH (ssh_conn), un fichier source et un fichier de destination.
Prise en charge de la copie sécurisée
Nous pouvons également voir qui ont un argument facultatif pour spécifier le
système de fichiers. De plus, il existe des systèmes de fichiers par défaut
inclus dans le code Netmiko. Les systèmes de fichiers par défaut sont les
suivants:
Cisco IOS/IOS-XE/IOS-XR Auto detects the file-system
Cisco NX-OS bootflash:
Arista EOS /mnt/flash
Juniper Junos /var/tmp
Prise en charge de la copie sécurisée
Le comportement par défaut de la fonction file_transfer est un transfert de
fichier idempotent.
En d'autres termes, Netmiko vérifiera d'abord si le fichier existe déjà, puis
calculera et comparera le MD5 du fichier. Si le fichier existe déjà et a le bon
MD5, alors Netmiko ne transférera pas le fichier.
Par défaut, 'file_transfer' a l'argument overwrite_file défini sur False, donc si
le fichier existe déjà (et que le MD5 ne correspond pas), il n'écrasera pas le
fichier.
On peut modifier ce comportement en spécifiant overwrite_file = True.
On peut également désactiver le calcul MD5. Vous pouvez éventuellement choisir de
le faire car le calcul MD5 sur les gros fichiers est très lent sur certains
périphériques réseau.
Prise en charge de la copie sécurisée
La fonction 'file_transfer' retournera un dictionnaire avec la structure
suivante:
{
'file_exists': True,
'file_transferred': True,
'file_verified': True
}
La clé 'file_verified' indiquera si la vérification MD5 a réussi. En général,
cela doit toujours être True ou une exception Python doit être déclenchée (sauf
si vous désactivez explicitement la vérification MD5 à l'aide de disable_md5 =
True).
$ python test_file_transfer.py
Prise en charge de la copie sécurisée
La clé 'file_exists' indique que le fichier transféré existe maintenant. Dans le
cas d'une opération «put», cela signifie que le fichier se trouve sur le système
distant. Dans le cas d'une opération «get», cela signifie que le fichier est
maintenant sur le système local (le système qui exécute le script Python).
La clé 'file_transferred' indique si le fichier devait être transféré ou était
déjà correct.
Voici le résultat de l'exécution de ce script. Remarque, j'ai ajouté quelques
commentaires et espacement pour plus de clarté:
Prise en charge de la copie sécurisée
Execution test_file_transfer.py
Password:
# Cisco IOS Device
{'file_exists': True, 'file_transferred': True, 'file_verified': True}
Hit enter to continue:
# Arista Device
{'file_exists': True, 'file_transferred': True, 'file_verified': True}
Hit enter to continue:
# Juniper Device
{'file_exists': True, 'file_transferred': True, 'file_verified': True}
Hit enter to continue:
Prise en charge de la copie sécurisée
Execution test_file_transfer.py
Password:
# Cisco IOS Device
{'file_exists': True, 'file_transferred': True, 'file_verified': True}
Hit enter to continue:
# Arista Device
{'file_exists': True, 'file_transferred': True, 'file_verified': True}
Hit enter to continue:
# Juniper Device
{'file_exists': True, 'file_transferred': True, 'file_verified': True}
Hit enter to continue:
# NX-OS Device
{'file_exists': True, 'file_transferred': True, 'file_verified': True}
Hit enter to continue:
Prise en charge de la copie sécurisée
Voici l'avant et l'après sur chacun de ces appareils:
# Cisco IOS Before
pynet-rtr1#dir flash:/testa.txt
%Error opening flash:/testa.txt (File not found)
# Cisco IOS After
pynet-rtr1#dir flash:/testa.txt
Directory of flash:/testa.txt
67 -rw- 12 Ven 31 2020 11:45:10 -08:00 testa.txt
# Arista Before
pynet-sw1#dir flash:/testa.txt
Directory of flash:/testa.txt

Contenu connexe

Similaire à Support Cours de Python et Réseaux.pptx

Rapport application chat
Rapport application chatRapport application chat
Rapport application chat
Tbatou sanae
 
Le Réseau et Java
Le Réseau et JavaLe Réseau et Java
Le Réseau et Java
Korteby Farouk
 
application SSL_TLS.pptx
application SSL_TLS.pptxapplication SSL_TLS.pptx
application SSL_TLS.pptx
kohay75604
 
Formation1 sockets
Formation1 socketsFormation1 sockets
Formation1 sockets
Mariem SOMRANI
 
Le service dhcp
Le service dhcpLe service dhcp
Le service dhcpDGMALY
 
réseaux
réseauxréseaux
réseaux
SaraElMendili
 
module_I6_Sockets.pdf
module_I6_Sockets.pdfmodule_I6_Sockets.pdf
module_I6_Sockets.pdf
Patiento Del Mar
 
Les mécanismes de base du procotole IP
Les mécanismes de base du procotole IPLes mécanismes de base du procotole IP
Les mécanismes de base du procotole IP
Pascal GUENOT
 
RAPPORT DU PREMIER MINI PROJET «FORUM DE CHAT» Novembre 2005.pdf
RAPPORT DU PREMIER MINI PROJET «FORUM DE CHAT» Novembre 2005.pdfRAPPORT DU PREMIER MINI PROJET «FORUM DE CHAT» Novembre 2005.pdf
RAPPORT DU PREMIER MINI PROJET «FORUM DE CHAT» Novembre 2005.pdf
Souf212
 
Développement informatique : Programmation réseau
Développement informatique : Programmation réseauDéveloppement informatique : Programmation réseau
Développement informatique : Programmation réseau
ECAM Brussels Engineering School
 
Rapport TME_semaine_7_KAID_NHEK
Rapport TME_semaine_7_KAID_NHEKRapport TME_semaine_7_KAID_NHEK
Rapport TME_semaine_7_KAID_NHEKBelkacem KAID
 
Weos tunnel ssl hôte à site
Weos   tunnel ssl hôte à siteWeos   tunnel ssl hôte à site
Weos tunnel ssl hôte à site
Fabian Vandendyck
 
Chapitre 6 - Protocoles TCP/IP, UDP/IP
Chapitre 6  - Protocoles TCP/IP, UDP/IPChapitre 6  - Protocoles TCP/IP, UDP/IP
Chapitre 6 - Protocoles TCP/IP, UDP/IP
Tarik Zakaria Benmerar
 
Advanced html5
Advanced html5Advanced html5
Advanced html5
Arrow Group
 
SERVICES RESEAUX AVANCES
SERVICES RESEAUX AVANCESSERVICES RESEAUX AVANCES
SERVICES RESEAUX AVANCES
Manassé Achim kpaya
 
Etude de la WIFI sur NS2
Etude de la WIFI sur NS2Etude de la WIFI sur NS2
Etude de la WIFI sur NS2
Chiheb Ouaghlani
 
Chap7_JavaNet.pdf
Chap7_JavaNet.pdfChap7_JavaNet.pdf
Chap7_JavaNet.pdf
Patiento Del Mar
 
Rapport sécurité
Rapport sécuritéRapport sécurité
Rapport sécurité
dihiaselma
 
radius
radiusradius

Similaire à Support Cours de Python et Réseaux.pptx (20)

Rapport application chat
Rapport application chatRapport application chat
Rapport application chat
 
Le Réseau et Java
Le Réseau et JavaLe Réseau et Java
Le Réseau et Java
 
application SSL_TLS.pptx
application SSL_TLS.pptxapplication SSL_TLS.pptx
application SSL_TLS.pptx
 
Formation1 sockets
Formation1 socketsFormation1 sockets
Formation1 sockets
 
Le service dhcp
Le service dhcpLe service dhcp
Le service dhcp
 
réseaux
réseauxréseaux
réseaux
 
module_I6_Sockets.pdf
module_I6_Sockets.pdfmodule_I6_Sockets.pdf
module_I6_Sockets.pdf
 
Les mécanismes de base du procotole IP
Les mécanismes de base du procotole IPLes mécanismes de base du procotole IP
Les mécanismes de base du procotole IP
 
RAPPORT DU PREMIER MINI PROJET «FORUM DE CHAT» Novembre 2005.pdf
RAPPORT DU PREMIER MINI PROJET «FORUM DE CHAT» Novembre 2005.pdfRAPPORT DU PREMIER MINI PROJET «FORUM DE CHAT» Novembre 2005.pdf
RAPPORT DU PREMIER MINI PROJET «FORUM DE CHAT» Novembre 2005.pdf
 
Développement informatique : Programmation réseau
Développement informatique : Programmation réseauDéveloppement informatique : Programmation réseau
Développement informatique : Programmation réseau
 
Rapport TME_semaine_7_KAID_NHEK
Rapport TME_semaine_7_KAID_NHEKRapport TME_semaine_7_KAID_NHEK
Rapport TME_semaine_7_KAID_NHEK
 
Weos tunnel ssl hôte à site
Weos   tunnel ssl hôte à siteWeos   tunnel ssl hôte à site
Weos tunnel ssl hôte à site
 
Chapitre 6 - Protocoles TCP/IP, UDP/IP
Chapitre 6  - Protocoles TCP/IP, UDP/IPChapitre 6  - Protocoles TCP/IP, UDP/IP
Chapitre 6 - Protocoles TCP/IP, UDP/IP
 
Advanced html5
Advanced html5Advanced html5
Advanced html5
 
SERVICES RESEAUX AVANCES
SERVICES RESEAUX AVANCESSERVICES RESEAUX AVANCES
SERVICES RESEAUX AVANCES
 
Etude de la WIFI sur NS2
Etude de la WIFI sur NS2Etude de la WIFI sur NS2
Etude de la WIFI sur NS2
 
Chap7_JavaNet.pdf
Chap7_JavaNet.pdfChap7_JavaNet.pdf
Chap7_JavaNet.pdf
 
.NET DotNet CF - 3
.NET DotNet CF - 3.NET DotNet CF - 3
.NET DotNet CF - 3
 
Rapport sécurité
Rapport sécuritéRapport sécurité
Rapport sécurité
 
radius
radiusradius
radius
 

Dernier

JTC 2024 - Approche collective de la santé
JTC 2024 - Approche collective de la santéJTC 2024 - Approche collective de la santé
JTC 2024 - Approche collective de la santé
Institut de l'Elevage - Idele
 
2024 03 27 JTC actualités C Perrot (idele).pdf
2024 03 27 JTC actualités C Perrot (idele).pdf2024 03 27 JTC actualités C Perrot (idele).pdf
2024 03 27 JTC actualités C Perrot (idele).pdf
idelewebmestre
 
Reconquête de l’engraissement du chevreau à la ferme
Reconquête de l’engraissement du chevreau à la fermeReconquête de l’engraissement du chevreau à la ferme
Reconquête de l’engraissement du chevreau à la ferme
Institut de l'Elevage - Idele
 
COUPROD Une méthode nationale commune à l’ensemble des filières herbivores
COUPROD Une méthode nationale commune à l’ensemble des filières herbivoresCOUPROD Une méthode nationale commune à l’ensemble des filières herbivores
COUPROD Une méthode nationale commune à l’ensemble des filières herbivores
Institut de l'Elevage - Idele
 
Leviers d’adaptation au changement climatique, qualité du lait et des produit...
Leviers d’adaptation au changement climatique, qualité du lait et des produit...Leviers d’adaptation au changement climatique, qualité du lait et des produit...
Leviers d’adaptation au changement climatique, qualité du lait et des produit...
Institut de l'Elevage - Idele
 
JTC_2024_TC Bâtiment et bien-être estival.pdf
JTC_2024_TC Bâtiment et bien-être estival.pdfJTC_2024_TC Bâtiment et bien-être estival.pdf
JTC_2024_TC Bâtiment et bien-être estival.pdf
idelewebmestre
 
Accompagner les éleveurs dans l'analyse de leurs coûts de production
Accompagner les éleveurs dans l'analyse de leurs coûts de productionAccompagner les éleveurs dans l'analyse de leurs coûts de production
Accompagner les éleveurs dans l'analyse de leurs coûts de production
Institut de l'Elevage - Idele
 
05-La génétique, un levier majeur pour les enjeux à venir
05-La génétique, un levier majeur pour les enjeux à venir05-La génétique, un levier majeur pour les enjeux à venir
05-La génétique, un levier majeur pour les enjeux à venir
Institut de l'Elevage - Idele
 
Accompagner les porteurs de projets en transformation fermière
Accompagner les porteurs de projets en transformation fermièreAccompagner les porteurs de projets en transformation fermière
Accompagner les porteurs de projets en transformation fermière
Institut de l'Elevage - Idele
 
BeeBOP diaporama webinaire : Et si l’IA permettait de compléter l’observatio...
BeeBOP diaporama webinaire : Et si l’IA permettait de compléter l’observatio...BeeBOP diaporama webinaire : Et si l’IA permettait de compléter l’observatio...
BeeBOP diaporama webinaire : Et si l’IA permettait de compléter l’observatio...
Institut de l'Elevage - Idele
 
JTC 2024 - Actualités sur le bien-être animal
JTC 2024 - Actualités sur le bien-être animalJTC 2024 - Actualités sur le bien-être animal
JTC 2024 - Actualités sur le bien-être animal
Institut de l'Elevage - Idele
 
JTC 2024 - Pour une traite de qualité, mieux comprendre l’interface trayon-ma...
JTC 2024 - Pour une traite de qualité, mieux comprendre l’interface trayon-ma...JTC 2024 - Pour une traite de qualité, mieux comprendre l’interface trayon-ma...
JTC 2024 - Pour une traite de qualité, mieux comprendre l’interface trayon-ma...
Institut de l'Elevage - Idele
 
RAPPORT DE STAGE sur CHANTIER BTP (by BR Engineering ) (1) (1).pdf
RAPPORT DE STAGE  sur CHANTIER  BTP (by BR Engineering ) (1) (1).pdfRAPPORT DE STAGE  sur CHANTIER  BTP (by BR Engineering ) (1) (1).pdf
RAPPORT DE STAGE sur CHANTIER BTP (by BR Engineering ) (1) (1).pdf
fatima413951
 
JTC 2024 - Atelier APaChe-Pâturage des arbres par les chèvres
JTC 2024 - Atelier APaChe-Pâturage des arbres par les chèvresJTC 2024 - Atelier APaChe-Pâturage des arbres par les chèvres
JTC 2024 - Atelier APaChe-Pâturage des arbres par les chèvres
Institut de l'Elevage - Idele
 

Dernier (14)

JTC 2024 - Approche collective de la santé
JTC 2024 - Approche collective de la santéJTC 2024 - Approche collective de la santé
JTC 2024 - Approche collective de la santé
 
2024 03 27 JTC actualités C Perrot (idele).pdf
2024 03 27 JTC actualités C Perrot (idele).pdf2024 03 27 JTC actualités C Perrot (idele).pdf
2024 03 27 JTC actualités C Perrot (idele).pdf
 
Reconquête de l’engraissement du chevreau à la ferme
Reconquête de l’engraissement du chevreau à la fermeReconquête de l’engraissement du chevreau à la ferme
Reconquête de l’engraissement du chevreau à la ferme
 
COUPROD Une méthode nationale commune à l’ensemble des filières herbivores
COUPROD Une méthode nationale commune à l’ensemble des filières herbivoresCOUPROD Une méthode nationale commune à l’ensemble des filières herbivores
COUPROD Une méthode nationale commune à l’ensemble des filières herbivores
 
Leviers d’adaptation au changement climatique, qualité du lait et des produit...
Leviers d’adaptation au changement climatique, qualité du lait et des produit...Leviers d’adaptation au changement climatique, qualité du lait et des produit...
Leviers d’adaptation au changement climatique, qualité du lait et des produit...
 
JTC_2024_TC Bâtiment et bien-être estival.pdf
JTC_2024_TC Bâtiment et bien-être estival.pdfJTC_2024_TC Bâtiment et bien-être estival.pdf
JTC_2024_TC Bâtiment et bien-être estival.pdf
 
Accompagner les éleveurs dans l'analyse de leurs coûts de production
Accompagner les éleveurs dans l'analyse de leurs coûts de productionAccompagner les éleveurs dans l'analyse de leurs coûts de production
Accompagner les éleveurs dans l'analyse de leurs coûts de production
 
05-La génétique, un levier majeur pour les enjeux à venir
05-La génétique, un levier majeur pour les enjeux à venir05-La génétique, un levier majeur pour les enjeux à venir
05-La génétique, un levier majeur pour les enjeux à venir
 
Accompagner les porteurs de projets en transformation fermière
Accompagner les porteurs de projets en transformation fermièreAccompagner les porteurs de projets en transformation fermière
Accompagner les porteurs de projets en transformation fermière
 
BeeBOP diaporama webinaire : Et si l’IA permettait de compléter l’observatio...
BeeBOP diaporama webinaire : Et si l’IA permettait de compléter l’observatio...BeeBOP diaporama webinaire : Et si l’IA permettait de compléter l’observatio...
BeeBOP diaporama webinaire : Et si l’IA permettait de compléter l’observatio...
 
JTC 2024 - Actualités sur le bien-être animal
JTC 2024 - Actualités sur le bien-être animalJTC 2024 - Actualités sur le bien-être animal
JTC 2024 - Actualités sur le bien-être animal
 
JTC 2024 - Pour une traite de qualité, mieux comprendre l’interface trayon-ma...
JTC 2024 - Pour une traite de qualité, mieux comprendre l’interface trayon-ma...JTC 2024 - Pour une traite de qualité, mieux comprendre l’interface trayon-ma...
JTC 2024 - Pour une traite de qualité, mieux comprendre l’interface trayon-ma...
 
RAPPORT DE STAGE sur CHANTIER BTP (by BR Engineering ) (1) (1).pdf
RAPPORT DE STAGE  sur CHANTIER  BTP (by BR Engineering ) (1) (1).pdfRAPPORT DE STAGE  sur CHANTIER  BTP (by BR Engineering ) (1) (1).pdf
RAPPORT DE STAGE sur CHANTIER BTP (by BR Engineering ) (1) (1).pdf
 
JTC 2024 - Atelier APaChe-Pâturage des arbres par les chèvres
JTC 2024 - Atelier APaChe-Pâturage des arbres par les chèvresJTC 2024 - Atelier APaChe-Pâturage des arbres par les chèvres
JTC 2024 - Atelier APaChe-Pâturage des arbres par les chèvres
 

Support Cours de Python et Réseaux.pptx

  • 1. Python & Réseaux Initiation à la programmation réseaux Les Sockets CC Pro Digit Consulting Chapitre I
  • 2. Plan 1. Rappels 2. Les sockets 3. Exemple serveur-client 4. Le Threading
  • 3. Rappels Comment faire communiquer deux applications, sur la même machine ou à distantes ?  Par la connexion au réseau local ou à Internet !  En précisant le protocole : Le protocole TCP (Transmission Control Protocol) : Pour connecter deux applications et de leur faire échanger des informations. « Orienté connexion » Le protocole UDP (User Datagram Protocol): Envoie des informations au travers du réseau, en spécifiant une cible, sans vérifier l’effectivité réception. Protocole non connecté. Dans l'architecture que nous allons voir dans les exemples du cours on trouve en général un serveur et plusieurs clients. Le serveur, c'est une machine qui va traiter les requêtes du client.
  • 4. Rappels Dans les exemples que nous allons voir, nous allons créer deux applications : l'application serveur et l'application client. Le serveur écoute donc en attendant des connexions et les clients se connectent au serveur. Les différentes étapes Nos applications vont fonctionner selon un schéma assez similaire. Voici dans l'ordre les étapes du client et du serveur. Les étapes sont très simplifiées, la plupart des serveurs peuvent communiquer avec plusieurs clients mais nous ne verrons pas cela tout de suite.
  • 5. Rappels Le serveur : - attend une connexion de la part du client ; - accepte la connexion quand le client se connecte ; - échange des informations avec le client ; - ferme la connexion. Le client : - se connecte au serveur ; - échange des informations avec le serveur ; - ferme la connexion. Comme on l'a vu, le serveur peut dialoguer avec plusieurs clients : c'est tout l'intérêt.
  • 6. Rappels Établir une connexion Pour que le client se connecte au serveur, il nous faut deux informations : - Le nom d'hôte (host name), identifiant une machine sur Internet ou sur un réseau local. Les noms d'hôtes permettent de représenter des adresses IP de façon plus claire (on a un nom comme google.fr, plus facile à retenir que l'adresse IP correspondante 74.125.224.84). - Un numéro de port, qui est souvent propre au type d'information que l'on va échanger. Si on demande une connexion web, le navigateur va en général interroger le port 80 si c'est en http ou le port 443 si c'est en connexion sécurisée (https). Le numéro de port est compris entre 0 et 65535 et les numéros entre 0 et 1023 sont réservés par le système (ce n'est pas une très bonne idée de les utilisées).
  • 7. Les Sockets Les sockets sont des objets qui permettent d'ouvrir une connexion avec une machine locale ou distante et d'échanger avec elle. Ces objets sont définis dans le module socket et nous allons maintenant voir comment ils fonctionnent. Commençons par importer notre module socket. >>> import socket Nous allons d'abord créer notre serveur puis, en parallèle, un client. Nous allons faire communiquer les deux. Pour l'instant, nous nous occupons du serveur.
  • 8. Les Sockets Construire notre socket Nous allons pour cela faire appel au constructeur socket. Dans le cas d'une connexion TCP, il prend les deux paramètres suivants, dans l'ordre : socket.AF_INET : la famille d'adresses, ici ce sont des adresses Internet ; socket.SOCK_STREAM : le type du socket, SOCK_STREAM pour le protocole TCP. >>> connexion_principale = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  • 9. Les Sockets Connecter le socket Pour une connexion serveur, qui va attendre des connexions de clients, on utilise la méthode bind. Elle prend un paramètre : le tuple (nom_hote, port). Question C‘est notre client qui se connectait à notre serveur ou l'inverse… Oui mais c‘est notre client qui se connecte à notre serveur , pour que notre serveur écoute sur un port, il faut le configurer en conséquence. Donc, dans notre cas, le nom de l'hôte sera vide et le port sera celui que vous voulez, entre 1024 et 65535. >>> connexion_principale.bind(('', 12800))
  • 10. Les Sockets Faire écouter notre socket Notre socket est prêt à écouter sur le port 12800 mais il n'écoute pas encore. On va avant tout lui préciser le nombre maximum de connexions qu'il peut recevoir sur ce port sans les accepter. On utilise pour cela la méthode listen. On lui passe généralement 5 en paramètre. Cela veut dire que notre serveur ne pourra dialoguer qu'avec 5 clients maximum ? Non. Cela veut dire que si 5 clients se connectent et que le serveur n'accepte aucune de ces connexions, aucun autre client ne pourra se connecter. Mais généralement, très peu de temps après que le client ait demandé la connexion, le serveur l'accepte. Vous pouvez donc avoir bien plus de clients connectés, ne vous en faites pas.
  • 11. Les Sockets Accepter une connexion venant du client Enfin, dernière étape, on va accepter une connexion. Aucune connexion ne s'est encore présentée mais la méthode accept que nous allons utiliser va bloquer le programme tant qu'aucun client ne s'est connecté. Il est important de noter que la méthode accept renvoie deux informations : le socket connecté qui vient de se créer, celui qui va nous permettre de dialoguer avec notre client tout juste connecté ; un tuple représentant l'adresse IP et le port de connexion du client.
  • 12. Les Sockets Le port de connexion du client… ce n'est pas le même que celui du serveur ? Non car votre client, en ouvrant une connexion, passe par un port dit « de sortie » qui va être choisi par le système parmi les ports disponibles. Pour schématiser, quand un client se connecte à un serveur, il emprunte un port puis établit la connexion sur le port du serveur. Il y a donc deux ports dans notre histoire mais celui qu'utilise le client pour ouvrir sa connexion ne va pas nous intéresser. >>> connexion_avec_client, infos_connexion = connexion_principale.accept()
  • 13. Les Sockets Création du client Commencez par construire votre socket de la même façon : >>> import socket >>> connexion_avec_serveur = socket.socket(socket.AF_INET, socket.SOCK_STREAM) Connecter le client Pour se connecter à un serveur, on va utiliser la méthode connect. Elle prend en paramètre un tuple, comme bind, contenant le nom d'hôte et le numéro du port identifiant le serveur auquel on veut se connecter. Le numéro du port sur lequel on veut se connecter, vous le connaissez : c'est 12800. Vu que nos deux applications Python sont sur la même machine, le nom d'hôte va être localhost. >>> connexion_avec_serveur.connect(('localhost', 12800)) Maintenant notre serveur et notre client sont connectés !
  • 14. Les Sockets Création du client (suite) Si vous retournez dans la console Python abritant le serveur, vous pouvez constater que la méthode accept ne bloque plus, puisqu'elle vient d'accepter la connexion demandée par le client. Vous pouvez donc de nouveau saisir du code côté serveur : >>> print(infos_connexion) ('127.0.0.1', 2901) La première information, c'est l'adresse IP du client. Ici, elle vaut 127.0.0.1 c'est-à-dire l'IP de l'ordinateur local. Dites-vous que l'hôte localhost redirige vers l'IP 127.0.0.1.
  • 15. Les Sockets Faire communiquer nos sockets Comment faire communiquer nos sockets ? En utilisant les méthodes send pour envoyer et recv pour recevoir. Les informations transmises seront des chaînes de bytes, pas des str ! Donc côté serveur : >>> connexion_avec_client.send(b"Je viens d'accepter la connexion") 32 La méthode send vous renvoie le nombre de caractères envoyés. Maintenant, côté client, on va réceptionner le message que l'on vient d'envoyer. La méthode recv prend en paramètre le nombre de caractères à lire. Généralement, on lui passe la valeur 1024. Si le message est plus grand que 1024 caractères, on récupérera le reste après.
  • 16. Les Sockets Dans la fenêtre Python côté client, donc : >>> msg_recu = connexion_avec_serveur.recv(1024) >>> msg_recu b"Je viens d'accepter la connexion" Songez que ce petit mécanisme peut servir à faire communiquer des applications entre elles non seulement sur la machine locale, mais aussi sur des machines distantes et reliées par Internet. Le client peut également envoyer des informations au serveur et le serveur peut les réceptionner, tout cela grâce aux méthodes send et recv que nous venons de voir.
  • 17. Les Sockets Fermer la connexion Pour fermer la connexion, il faut appeler la méthode close de notre socket. Côté serveur : >>> connexion_avec_client.close() Et du côté client : >>> connexion_avec_serveur.close() On va récapituler en présentant dans l'ordre un petit serveur et un client que nous pouvons utiliser. Et pour finir, nous allons optimiser un peu notre serveur en lui permettant de gérer plusieurs clients à la fois.
  • 18. Les Sockets import socket hote = '' port = 12800 connexion_principale = socket.socket(socket.AF_INET, socket.SOCK_STREAM) connexion_principale.bind((hote, port)) connexion_principale.listen(5) print("Le serveur écoute à présent sur le port {}".format(port)) connexion_avec_client, infos_connexion = connexion_principale.accept() msg_recu = b"" while msg_recu != b"fin": msg_recu = connexion_avec_client.recv(1024) # L'instruction ci-dessous peut lever une exception si le message # Réceptionné comporte des accents print(msg_recu.decode()) connexion_avec_client.send(b"5 / 5") print("Fermeture de la connexion") connexion_avec_client.close() connexion_principale.close() Le code pour le serveur Voici le code du serveur, légèrement amélioré. Il n'accepte qu'un seul client (nous verrons plus bas comment en accepter plusieurs) et il tourne jusqu'à recevoir du client le message fin. À chaque fois que le serveur reçoit un message, il envoie en retour le message '5 / 5'
  • 19. Les Sockets import socket hote = "localhost" port = 12800 connexion_avec_serveur = socket.socket(socket.AF_INET, socket.SOCK_STREAM) connexion_avec_serveur.connect((hote, port)) print("Connexion établie avec le serveur sur le port {}".format(port)) msg_a_envoyer = b"" while msg_a_envoyer != b"fin": msg_a_envoyer = input("> ") # Peut planter si vous tapez des caractères spéciaux msg_a_envoyer = msg_a_envoyer.encode() # On envoie le message connexion_avec_serveur.send(msg_a_envoyer) msg_recu = connexion_avec_serveur.recv(1024) print(msg_recu.decode()) # Là encore, peut planter s'il y a des accents print("Fermeture de la connexion") connexion_avec_serveur.close() Le code pour le client Voici le code du client pouvant interagir avec notre serveur. Il va tenter de se connecter sur le port 12800 de la machine locale. Il demande à l'utilisateur de saisir quelque chose au clavier et envoie ce quelque chose au serveur, puis attend sa réponse.
  • 20. Les Sockets Que font les méthodes encode et décode ? encode est une méthode de str. Elle peut prendre en paramètre un nom d'encodage et permet de passer un str en chaîne bytes : le type de chaîne que send accepte. En fait, encode encode la chaîne str en fonction d'un encodage précis (par défaut, Utf-8). decode, à l'inverse, est une méthode de bytes. Elle aussi peut prendre en paramètre un encodage et elle renvoie une chaîne str décodée grâce à l'encodage (par défaut Utf-8). Si l'encodage de votre console est différent d'Utf-8 (ce sera souvent le cas sur Windows), des erreurs peuvent se produire si les messages que vous encodez ou décodez comportent des accents.
  • 21. Le Threading Un serveur plus élaboré Quel sont les problèmes de notre serveur ?  N'accepter qu'un seul client. Si d'autres clients veulent se connecter, ils ne peuvent pas.  Attend le message d'un client et qu‘il renvoie immédiatement après réception. Mais ce n'est pas toujours le cas : parfois vous envoyez un message au client alors qu'il ne vous a rien envoyé et vis versa.  Les erreurs sont assez mal gérées.
  • 22. Le Threading Le module select Permet d’interroger plusieurs clients dans l'attente d'un message à réceptionner, sans paralyser notre programme. Pour schématiser, select va écouter sur une liste de clients et retourner au bout d'un temps précisé. Ce que renvoie select, c'est la liste des clients qui ont un message à réceptionner. Il suffit de parcourir ces clients, de lire les messages en attente (grâce à recv). Sur Linux, select peut être utilisé sur autre chose que des sockets mais, cette fonctionnalité n'étant pas portable.
  • 23. Le Threading Comment marche la fonction select La fonction qui nous intéresse porte le même nom que le module associé, select. Elle prend trois ou quatre arguments et en renvoie trois. : rlist : la liste des sockets en attente d'être lus ; wlist : la liste des sockets en attente d'être écrits ; xlist : la liste des sockets en attente d'une erreur ; timeout : le délai pendant lequel la fonction attend avant de retourner. Si vous précisez en timeout 0, la fonction retourne immédiatement. Si ce paramètre n'est pas précisé, la fonction retourne dès qu'un des sockets change d'état (est prêt à être lu s'il est dans rlist par exemple) mais pas avant.
  • 24. Le Threading Comment marche la fonction select Ce qu'on veut, c'est mettre des sockets dans une liste et que select les surveille, en retournant dès qu'un socket est prêt à être lu. Comme cela notre programme ne bloque pas et il peut recevoir des messages de plusieurs clients dans un ordre complètement inconnu. Maintenant, concernant le timeout : si on ne le précise pas, select bloque jusqu'au moment où l'un des sockets que nous écoutons est prêt à être lu, dans notre cas. Si vous précisez un timeout de 0, select retournera tout de suite. Sinon, select retournera au bout du temps que vous indiquez en secondes, ou plus tôt si un socket est prêt à être lu. Donc si on précise un timeout de 1, la fonction va bloquer pendant une seconde maximum. Mais si un des sockets en écoute est prêt à être lu dans l'intervalle (c'est-à-dire si un des clients envoie un message au serveur),
  • 25. Le Threading Considérez cette ligne : >>> rlist, wlist, xlist = select.select(clients_connectes, [], [], 2) Cette instruction va écouter les sockets contenus dans la liste clients_connectes. Elle retournera au plus tard dans 2 secondes. Mais elle retournera plus tôt si un client envoie un message. La liste des clients ayant envoyé un message se retrouve dans notre variable rlist. On la parcourt ensuite et on peut appeler recv sur chacun des sockets.
  • 26. Le Threading Le but va être de créer un serveur pouvant accepter plusieurs clients, réceptionner leurs messages et leur envoyer une confirmation à chaque réception. L'exercice ne change pas beaucoup mais on va utiliser select pour travailler avec plusieurs clients. La fonction select permet d’écouter plusieurs clients connectés mais va également nous permettre de savoir si un (ou plusieurs) clients sont connectés au serveur. Souvenez que la méthode accept est aussi une fonction bloquante. On va du reste l'utiliser de la même façon qu'un peu plus haut.
  • 27. Le Threading Maintenant notre serveur peut accepter des connexions de plus d'un client, vous pouvez faire le test. En outre, il ne se bloque pas dans l'attente d'un message, du moins pas plus de 50 millisecondes. Les commentaires sont assez précis pour vous permettre d'aller plus loin. Ceci n'est pas encore une version complète mais, grâce à cette base, vous devriez pouvoir facilement arriver à quelque chose. Projet : Faire un mini serveur de tchat ? Les déconnexions fortuites ne sont pas gérées non plus. Mais vous avez assez d'éléments pour faire des tests et améliorer notre serveur.
  • 28. Le Threading Pour aller plus loin Pour plus de documentation du module socket, de select et de socketserver aller au niveau de leur page officielle. Le module socketserver propose une alternative pour monter vos applications serveur. Il en existe d'autres, dans tous les cas : vous pouvez utiliser des sockets non bloquants (c'est-à-dire qui ne bloquent pas le programme quand vous utilisez leur méthode accept ou recv) ou des threads pour exécuter différentes portions de votre programme en parallèle.
  • 29. Conclusion Dans la structure réseau vue, on trouve un serveur pouvant dialoguer avec plusieurs clients. Pour créer une connexion côté serveur ou client, on utilise le module socket et la classe socket de ce module. Pour se connecter à un serveur, le socket client utilise la méthode connect. Pour écouter sur un port précis, le serveur utilise d'abord la méthode bind puis la méthode listen. Pour s'échanger des informations, les sockets client et serveur utilisent les méthodes send et recv..
  • 30. Conclusion Pour fermer une connexion, le socket serveur ou client utilise la méthode close. Le module select peut être utile si l'on souhaite créer un serveur pouvant gérer plusieurs connexions simultanément ; toutefois, il en existe d'autres.
  • 31. Les méthodes de l'objet socket accept() accepte une connexion, retourne un nouveau socket et une adresse client bind(addr) associe le socket à une adresse locale close() ferme le socket connect(addr) connecte le socket à une adresse distante connect_ex(addr) connect, retourne un code erreur au lieu d'une exception dup() retourne un nouveau objet socket identique à celui en cours fileno() retourne une description du fichier getpeername() retourne l'adresse distante getsockname() retourne l'adresse locale getsockopt(level, optname[, buflen]) : retourne les options du socket gettimeout() retourne le timeout ou none listen(n) commence à écouter les connexions entrantes
  • 32. Les méthodes de l'objet socket makefile([mode, [bufsize]]) : retourne un fichier objet pour le socket recv(buflen[, flags]) : recoit des données recv_into(buffer[, nbytes[, flags]]) : recoit des données (dans un buffer) recvfrom(buflen[, flags]) : reçoit des données et l'adresse de l'envoyeur recvfrom_into(buffer[,nbytes,[,flags]) : reçoit des données et l'adresse de l'envoyeur (dans un buffer) sendall(data[, flags]) : envoye toutes les données send(data[, flags]) : envoye des données mais il se peut que pas toutes le soit sendto(data[, flags], addr) : envoye des données à une adresse donnée
  • 33. Python & Réseaux Initiation à la programmation réseaux Configuration Réseaux à Distance avec Netmiko CC Pro Digit Consulting Chapitre II
  • 34. Plan 1. Présentation de la Bibliothèque Netmiko 2. Copie sécurisée 3. Netmiko via SSH Proxy 4. Netmiko et TextFSMRappels
  • 35. Pourquoi Netmiko ? Certain types de problèmes peuvent prendre beaucoup de temps de développement et de dépannage :  Problèmes similaires avec Python-SSH et les périphériques réseau  les commutateurs HP ProCurve ont des codes d'échappement ANSI dans la sortie  Cisco WLC a un message supplémentaire «connexion en tant que:» Netmiko a donc été créé pour simplifier cette gestion SSH de niveau inférieur sur un large éventail de fournisseurs de réseaux et de plates-formes. Depuis la fin de 2014, Kirk Byers travaille sur une bibliothèque Python open source qui simplifie la gestion SSH pour les périphériques réseau.
  • 36. Pourquoi Netmiko ? La bibliothèque est basée sur la bibliothèque Paramiko SSH et s'appelle Netmiko. Vous pouvez trouver la bibliothèque sur https://github.com/ktbyers/netmiko et la dernière version publiée du logiciel peut être téléchargée https://github.com/ktbyers/netmiko/releases . Les objectifs de cette bibliothèque sont les suivants:  Établir avec succès une connexion SSH à un appareil réseau,  Exécution des commandes show et la récupération des données de sortie,  Simplifiez l'exécution des commandes de configuration,  Simplifiez des actions de validation,  Sur un large éventail de fournisseurs de réseaux et de plates-formes.
  • 37. Pourquoi Netmiko ? Depuis janvier 2019, Netmiko prend en charge les plates-formes suivantes avec 3 niveaux de test indiqué. Testé régulièrement: Arista EOS - Cisco ASA - Cisco IOS / IOS-XE - Cisco IOS-XR - Cisco NX-OS Cisco SG300 - HP Comware7 - HP ProCurve - Juniper Junos - Linux Tests limités: Alcatel AOS6 / AOS8 - Apresia Systems AEOS - Calix B6 - Cisco AireOS (contrôleurs LAN sans fil) - Dell OS9 (Force10) - Dell OS10 - Dell PowerConnect - Extreme ERS (Avaya) - VSP extrême (Avaya) - Extreme VDX (Brocade) - Extreme MLX / NetIron (brocart / fonderie) – Huawei - Infusion IP OcNOS – Mellanox - NetApp cDOT OneAccess - Palo Alto PAN-OS – Pluribus - Ruckus ICX / FastIron Ubiquiti EdgeSwitch - Vyatta VyOS
  • 38. Pourquoi Netmiko ? Expérimental: A10 – Accedian – Aruba - Ciena SAOS - Citrix Netscaler - Cisco Telepresence Check Point GAiA – Coriant - Dell OS6 - Dell EMC Isilon – Eltex - Enterasys EXOS extrêmes - Aile extrême - Extreme SLX (Brocade) - F5 TMSH - F5 Linux Fortinet - MRV Communications OptiSwitch - Nokia / Alcatel SR-OS - QuantaMesh Rad ETX
  • 39. TP 1 TP 1: Session SSH simple vers un routeur Cisco Exécutez et renvoyez la commande 'show ip int brief'. Tout d'abord, importer la fonction ConnectHandler du module Netmiko. ConnectHandler sélectionne la classe Netmiko correcte en fonction du type d'appareil. >>> from netmiko import ConnectHandler Définir ensuite un dictionnaire de périphériques réseau composé d'un type de périphérique, d'une adresse IP, d'un nom d'utilisateur et d'un mot de passe. >>> cisco = { ...: 'device_type': 'cisco_ios', ...: 'host': 'cisco.domain.com', ...: 'username': 'admin', ...: 'password': 'cisco123', ...: }
  • 40. TP 1 À ce stade, on peut se connecter à l'appareil. Notez ci-dessus que j'ai spécifié le device_type comme 'cisco_ios'. Tous les device_types ne sont pas pris en charge. Pour se connecter, on appelle ConnectHandler et en passant mon dictionnaire de périphérique défini précédemment: >>> net_connect = ConnectHandler(**cisco) Alternativement, je pourrais simplement appeler la fonction ConnectHandler directement et ne pas utiliser de dictionnaire (comme suit): >>> net_connect2 = ConnectHandler(device_type='cisco_ios', host='cisco.domain.com', username='admin', password='cisco123')
  • 41. TP 1 A ce stade, nous devrions avoir une connexion SSH établie. On peut vérifier cela en exécutant la méthode find_prompt () >>> net_connect.find_prompt() 'cisco3#' On peut également envoyer des commandes sur le canal SSH et recevoir la sortie. On utilise la méthode .send_command () pour envoyer une commande : >>> output = net_connect.send_command("show ip int brief")
  • 42. TP 1 >>> print(output) Interface IP-Address OK? Method Status Protocol GigabitEthernet0/0/0 10.10.10.22 YES manual up up GigabitEthernet0/0/1 unassigned YES NVRAM administratively down down GigabitEthernet0/1/0 unassigned YES unset down down GigabitEthernet0/1/1 unassigned YES unset down down GigabitEthernet0/1/2 unassigned YES unset down down GigabitEthernet0/1/3 unassigned YES unset down down Vlan1 unassigned YES unset up down Essayons également de modifier la configuration de ce routeur. Tout d'abord, regardons la configuration de journalisation actuelle: >>> output = net_connect.send_command("show run | inc logging")
  • 43. TP 1 >>> print(output) logging synchronous Maintenant, afin de faire des changements de configuration, on peut créer une liste de commandes de configuration que l’on veut exécuter. Il peut s'agir d'une seule commande ou de plusieurs commandes. >>> config_commands = ['logging buffered 19999'] J'exécute ensuite la méthode send_config_set (). Cette méthode entrera en mode de configuration, exécutera les commandes, puis quittera le mode de configuration (notez qu'il y aura quelques exceptions à ce comportement en fonction de la plate-forme - par exemple, IOS-XR ne quittera pas le mode de configuration en raison de modifications en attente). >>> output = net_connect.send_config_set(config_commands)
  • 44. TP 1 >>> output = net_connect.send_config_set(config_commands) >>> print(output) config term Enter configuration commands, one per line. End with CNTL/Z. cisco3(config)#logging buffered 19999 cisco3(config)#end cisco3# Vérifier la modification: >>> output = net_connect.send_command("show run | inc logging") >>> print(output) logging buffered 19999 logging synchronous
  • 45. TP 2 TP 2: Exécution de «show arp» sur un ensemble de périphériques réseau composés de différents fournisseurs et plates-formes. Tout d'abord, on doit définir les périphériques réseau (les adresses IP et les mots de passe réels ont été masqués): >>> from netmiko import ConnectHandler >>> from datetime import datetime
  • 46. TP 2 >>> cisco3 = { ...: 'device_type': 'cisco_ios', ...: 'host': 'cisco3.domain.com', ...: 'username': 'admin', ...: 'password': 'cisco123', ...: } ...: >>> cisco_asa = { ...: 'device_type': 'cisco_asa', ...: 'host': '10.10.10.88', ...: 'username': 'admin', ...: 'password': 'cisco123', ...: 'secret': 'cisco123', ...: } ...:
  • 47. TP 2 >>> cisco_xrv = { ...: 'device_type': 'cisco_xr', ...: 'host': '10.10.10.77', ...: 'username': 'admin', ...: 'password': 'cisco123', ...: } >>> arista8 = { ...: 'device_type': 'arista_eos', ...: 'host': 'arista8.domain.com', ...: 'username': 'admin', ...: 'password': '!cisco123', ...: } ...:
  • 48. TP 2 >>> hp_procurve = { ...: 'device_type': 'hp_procurve', ...: 'host': '10.10.10.68', ...: 'username': 'admin', ...: 'password': '!cisco123', ...: } ...: >>> juniper_srx = { ...: 'device_type': 'juniper', ...: 'host': 'srx1.domain.com', ...: 'username': 'admin', ...: 'password': '!cisco123', ...: }
  • 49. TP 2 Ensuite, créer une liste Python qui inclut tous ces appareils: >>> all_devices = [cisco3, cisco_asa, cisco_xrv, arista8, hp_procurve, juniper_srx] Maintenant, on va créer une boucle for qui itère sur tous ces appareils. Chaque fois dans la boucle: le code se connecte à l'appareil, exécute 'show arp', puis affiche la sortie. On gardera également la trace du temps nécessaire à l'exécution du code.
  • 50. TP 2 >>> start_time = datetime.now() ...: for a_device in all_devices: ...: net_connect = ConnectHandler(**a_device) ...: output = net_connect.send_command("show arp") ...: print(f"nn--------- Device {a_device['device_type']} ---------") ...: print(output) ...: print("--------- End ---------") ...: ...: end_time = datetime.now() ...: total_time = end_time - start_time
  • 51. TP 2 Voici la sortie de la boucle for (c'est-à-dire toute la sortie "show arp"): --------- Device cisco_ios --------- Protocol Address Age (min) Hardware Addr Type Interface Internet 10.10.10.1 32 0062.ec29.70fe ARPA GigabitEthernet0/0/0 Internet 10.10.10.20 156 c89c.1dea.0eb6 ARPA GigabitEthernet0/0/0 Internet 10.10.10.22 - a093.5141.b780 ARPA GigabitEthernet0/0/0 Internet 10.10.10.37 178 0001.00ff.0001 ARPA GigabitEthernet0/0/0 Internet 10.10.10.38 15 0002.00ff.0001 ARPA GigabitEthernet0/0/0 --------- End --------- --------- Device cisco_asa --------- outside 10.10.10.1 0062.ec29.70fe 1949 outside 10.10.10.20 c89c.1dea.0eb6 10226 outside 10.10.10.37 0001.00ff.0001 11606 outside 10.10.10.38 0002.00ff.0001 11636 --------- End ---------
  • 52. TP 2 Voici la sortie de la boucle for (c'est-à-dire toute la sortie "show arp"): --------- Device cisco_xr --------- Thu Jan 30 10:45:44.240 UTC ------------------------------------------------------------------------------- 0/0/CPU0 ------------------------------------------------------------------------------- Address Age Hardware Addr State Type Interface 10.10.10.1 00:32:36 0062.ec29.70fe Dynamic ARPA GigabitEthernet0/0/0/0 10.10.10.19 02:50:35 0024.c4e9.48ae Dynamic ARPA GigabitEthernet0/0/0/0 10.10.10.20 00:30:26 c89c.1dea.0eb6 Dynamic ARPA GigabitEthernet0/0/0/0 10.10.10.21 03:09:20 1c6a.7aaf.576c Dynamic ARPA GigabitEthernet0/0/0/0 10.10.10.22 02:58:54 a093.5141.b780 Dynamic ARPA GigabitEthernet0/0/0/0 10.10.10.23 01:37:37 502f.a8b1.6900 Dynamic ARPA GigabitEthernet0/0/0/0 10.10.10.32 02:56:30 5254.abc7.26aa Dynamic ARPA GigabitEthernet0/0/0/0 10.10.10.37 - 0001.00ff.0001 Interface ARPA GigabitEthernet0/0/0/0 10.10.10.38 01:55:33 0002.00ff.0001 Dynamic ARPA GigabitEthernet0/0/0/0 10.10.10.39 00:11:32 6464.9be8.08c8 Dynamic ARPA GigabitEthernet0/0/0/0 10.10.10.42 00:00:46 ec38.739e.2f08 Dynamic ARPA GigabitEthernet0/0/0/0 10.10.10.43 00:22:35 5254.abda.5495 Dynamic ARPA GigabitEthernet0/0/0/0 --------- End ---------
  • 53. TP 2 --------- Device arista_eos --------- Address Age (min) Hardware Addr Interface 10.10.10.1 0 0062.ec29.70fe Vlan1, Ethernet1 10.10.10.20 0 c89c.1dea.0eb6 Vlan1, not learned 10.10.10.43 0 5254.abda.5495 Vlan1, not learned --------- End --------- --------- Device hp_procurve --------- IP ARP table IP Address MAC Address Type Port --------------- ----------------- ------- ---- 10.10.19.1 0062ec-2970fd dynamic 26 10.10.19.20 c07bbc-65272e dynamic 26 --------- End ---------
  • 54. TP 2 --------- Device juniper --------- MAC Address Address Name Interface Flags 00:62:ec:29:70:fe 10.10.10.1 10.10.10.1 vlan.0 none c8:9c:1d:ea:0e:b6 10.10.10.20 10.10.10.20 vlan.0 none Total entries: 2 --------- End --------- >>> print(total_time) 0:00:42.062773 Comme vous pouvez le voir, l'exécution du code a pris un peu plus de 42 secondes. Cela pourrait être considérablement amélioré en créant les sessions SSH simultanément voir le code ici pour quelques exemples utilisant la concurrence.
  • 55. TP 2 Méthodes Netmiko couramment utilisées: net_connect.send_command () - Envoie la commande sur le canal, retourne la sortie (basée sur le modèle) net_connect.send_command_timing () - Envoie une commande sur le canal, retourne la sortie (en fonction du timing) net_connect.send_config_set () - Envoie des commandes de configuration au périphérique distant net_connect.send_config_from_file () - Envoie des commandes de configuration chargées à partir d'un fichier net_connect.save_config () - Enregistrez la configuration en cours d'exécution dans la configuration de démarrage net_connect.enable () - Entrer en mode d'activation net_connect.find_prompt () - Retourne l'invite actuelle du routeur net_connect.commit () - Exécute une action de validation sur Juniper et IOS-XR net_connect.disconnect () - Ferme la connexion net_connect.write_channel () - Écriture de bas niveau du canal net_connect.read_channel () - Écriture de bas niveau du canal
  • 56. Prise en charge de la copie sécurisée L'extension des capacités de transfert de fichiers Secure Copy incluses dans Netmiko devrait faciliter les mises à niveau du système d'exploitation et d'autres opérations de transfert de fichiers. Code tester sur Cisco IOS, IOS-XE, NX-OS, IOS-XR, Juniper Junos et Arista EOS. Il s'agit à la fois des opérations de copie sécurisée «get» et «put» et comprend également des méthodes associées qui vérifient si le fichier existe, qui vérifient que l'espace disque est disponible et qui effectuent une comparaison MD5 sur le fichier transféré. Remarque: Le pilote Netmiko nécessite généralement l'activation d'un serveur SCP sur le périphérique réseau distant.
  • 57. Prise en charge de la copie sécurisée En plus d'ajouter la prise en charge de la copie sécurisée pour des plates-formes supplémentaires, une fonction «file_transfer» de niveau supérieur effectue un transfert_fichier fiable. Cela devrait maintenant être l'interface principale pour utiliser la copie sécurisée de Netmiko. Voici les principaux arguments de la fonction file_transfer dans Netmiko : def file_transfer(ssh_conn, source_file, dest_file, file_system = None, direction='put', disable_md5=False, overwrite_file=False): En regardant les arguments, nous pouvons voir que 'file_transfer' prend une connexion Netmiko SSH (ssh_conn), un fichier source et un fichier de destination.
  • 58. Prise en charge de la copie sécurisée Nous pouvons également voir qui ont un argument facultatif pour spécifier le système de fichiers. De plus, il existe des systèmes de fichiers par défaut inclus dans le code Netmiko. Les systèmes de fichiers par défaut sont les suivants: Cisco IOS/IOS-XE/IOS-XR Auto detects the file-system Cisco NX-OS bootflash: Arista EOS /mnt/flash Juniper Junos /var/tmp
  • 59. Prise en charge de la copie sécurisée Le comportement par défaut de la fonction file_transfer est un transfert de fichier idempotent. En d'autres termes, Netmiko vérifiera d'abord si le fichier existe déjà, puis calculera et comparera le MD5 du fichier. Si le fichier existe déjà et a le bon MD5, alors Netmiko ne transférera pas le fichier. Par défaut, 'file_transfer' a l'argument overwrite_file défini sur False, donc si le fichier existe déjà (et que le MD5 ne correspond pas), il n'écrasera pas le fichier. On peut modifier ce comportement en spécifiant overwrite_file = True. On peut également désactiver le calcul MD5. Vous pouvez éventuellement choisir de le faire car le calcul MD5 sur les gros fichiers est très lent sur certains périphériques réseau.
  • 60. Prise en charge de la copie sécurisée La fonction 'file_transfer' retournera un dictionnaire avec la structure suivante: { 'file_exists': True, 'file_transferred': True, 'file_verified': True } La clé 'file_verified' indiquera si la vérification MD5 a réussi. En général, cela doit toujours être True ou une exception Python doit être déclenchée (sauf si vous désactivez explicitement la vérification MD5 à l'aide de disable_md5 = True). $ python test_file_transfer.py
  • 61. Prise en charge de la copie sécurisée La clé 'file_exists' indique que le fichier transféré existe maintenant. Dans le cas d'une opération «put», cela signifie que le fichier se trouve sur le système distant. Dans le cas d'une opération «get», cela signifie que le fichier est maintenant sur le système local (le système qui exécute le script Python). La clé 'file_transferred' indique si le fichier devait être transféré ou était déjà correct. Voici le résultat de l'exécution de ce script. Remarque, j'ai ajouté quelques commentaires et espacement pour plus de clarté:
  • 62. Prise en charge de la copie sécurisée Execution test_file_transfer.py Password: # Cisco IOS Device {'file_exists': True, 'file_transferred': True, 'file_verified': True} Hit enter to continue: # Arista Device {'file_exists': True, 'file_transferred': True, 'file_verified': True} Hit enter to continue: # Juniper Device {'file_exists': True, 'file_transferred': True, 'file_verified': True} Hit enter to continue:
  • 63. Prise en charge de la copie sécurisée Execution test_file_transfer.py Password: # Cisco IOS Device {'file_exists': True, 'file_transferred': True, 'file_verified': True} Hit enter to continue: # Arista Device {'file_exists': True, 'file_transferred': True, 'file_verified': True} Hit enter to continue: # Juniper Device {'file_exists': True, 'file_transferred': True, 'file_verified': True} Hit enter to continue: # NX-OS Device {'file_exists': True, 'file_transferred': True, 'file_verified': True} Hit enter to continue:
  • 64. Prise en charge de la copie sécurisée Voici l'avant et l'après sur chacun de ces appareils: # Cisco IOS Before pynet-rtr1#dir flash:/testa.txt %Error opening flash:/testa.txt (File not found) # Cisco IOS After pynet-rtr1#dir flash:/testa.txt Directory of flash:/testa.txt 67 -rw- 12 Ven 31 2020 11:45:10 -08:00 testa.txt # Arista Before pynet-sw1#dir flash:/testa.txt Directory of flash:/testa.txt