138 lines
5 KiB
Python
138 lines
5 KiB
Python
#!/bin/bash /usr/scripts/python.sh
|
|
# -*- coding: utf-8 -*-
|
|
#
|
|
# This file is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This file is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
|
|
"""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
|
|
|