#!/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