scripts/gestion/hptools2/snmp.py
Pierre-Elliott Bécue a0f0c80ead Version plus pythonesque de HPTools. Pleinement fonctionnelle sous jessie.
* Les requêtes de type lecture seule marchent très bien tout court ;
 * Celles de type écriture sont sans effet sous wheezy. C'est a priori
 un bug dans python-netsnmp
2015-04-24 01:55:52 +02:00

124 lines
4.3 KiB
Python

#!/bin/bash /usr/scripts/python.sh
# -*- coding: utf-8 -*-
"""Ce fichier propose un client snmp basique"""
import netsnmp
import socket
import gestion.secrets_new as secrets_new
class SNMPClient(object):
"""Classe de base définissant un client SNMP."""
def __init__(self, host):
"""Crée une session pointant vers le serveur SNMP, et
peuple les variables utiles."""
# Le fait se gérer si c'est .adm.crans.org, .crans.org, ou
# si le nom est un fqdn ou pas est du ressort du DNS (dans la
# mesure où de toute façon, si on a pas de dns, contacter les
# switches dont on doit résoudre l'IP va être tendu).
try:
self.host = socket.gethostbyname_ex(host)[0]
except socket.gaierror:
self.host = host
self.__session = None
self.__version3 = False
self.__snmp_community = None
self.__snmp_version = None
self.__snmp_seclevel = None
self.__snmp_authprotocol = None
self.__snmp_authpassword = None
self.__snmp_secname = None
self.__snmp_privprotocol = None
self.__snmp_privpassword = None
def __get_session(self, version3=False):
"""Crée une session en cas de besoin, en vérifiant qu'une
session répondant aux besoins n'existe pas déjà."""
if version3 and self.__version3 and self.__session:
return self.__session
if not version3 and not self.__version3 and self.__session:
return self.__session
if version3 and (not self.__version3 or not self.__session):
self.__snmp_community = 'private'
self.__snmp_version = 3
self.__snmp_seclevel = 'authPriv'
self.__snmp_authprotocol = 'SHA'
self.__snmp_authpassword = secrets_new.get('snmp_authentication_pass')
self.__snmp_secname = 'crans'
self.__snmp_privprotocol = 'DES'
self.__snmp_privpassword = secrets_new.get('snmp_privacy_pass')
if not version3 and (self.__version3 or not self.__session):
self.__snmp_community = 'public'
self.__snmp_version = 1
self.__snmp_seclevel = 'noAuthNoPriv'
self.__snmp_authprotocol = 'DEFAULT'
self.__snmp_authpassword = ''
self.__snmp_secname = 'initial'
self.__snmp_privprotocol = 'DEFAULT'
self.__snmp_privpassword = ''
self.__version3 = version3
session = netsnmp.Session(Version=self.__snmp_version, DestHost=self.host,
Community=self.__snmp_community, SecLevel=self.__snmp_seclevel,
SecName=self.__snmp_secname, PrivProto=self.__snmp_privprotocol,
PrivPass=self.__snmp_privpassword, AuthProto=self.__snmp_authprotocol,
AuthPass=self.__snmp_authpassword)
return session
def walk(self, attribute):
"""Fait un walk.
Exemple:
Si je demande hpSwitchPortFdbAddress, le retour contiendra
des entrées ayant pour tag hpSwitchPortFdbAddress, pour iid
une éventuelle valeur (si pertinent), et pour val la valeur
associée."""
self.__session = self.__get_session()
# Crée une variable netsnmp exploitable pour walk.
__varbind = netsnmp.Varbind(attribute)
# La stocke dans une liste.
__varlist = netsnmp.VarList(__varbind)
# __varlist est modifiée en place par la méthode walk.
_ = self.__session.walk(__varlist)
return [
{
'tag': ret.tag,
'iid': ret.iid,
'val': ret.val,
}
for ret in __varlist
]
def set(self, list_of_vars):
"""Met à jour un attribut"""
# On passe en SNMPv3
self.__session = self.__get_session(True)
# On construit la varlist à balancer en SNMP
__varlist = [
netsnmp.Varbind(
tag=res['tag'],
iid=res['iid'],
val=res['val']
)
for res in list_of_vars
]
# Oui, c'est moche
__varlist = netsnmp.VarList(*__varlist)
__ret = self.__session.set(__varlist)
return __ret