1# -*- coding: utf-8 -*- 2# 3# This file is part of Glances. 4# 5# Copyright (C) 2019 Nicolargo <nicolas@nicolargo.com> 6# 7# Glances is free software; you can redistribute it and/or modify 8# it under the terms of the GNU Lesser General Public License as published by 9# the Free Software Foundation, either version 3 of the License, or 10# (at your option) any later version. 11# 12# Glances is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15# GNU Lesser General Public License for more details. 16# 17# You should have received a copy of the GNU Lesser General Public License 18# along with this program. If not, see <http://www.gnu.org/licenses/>. 19 20"""The stats manager.""" 21 22import re 23 24from glances.stats import GlancesStats 25from glances.compat import iteritems 26from glances.logger import logger 27 28# SNMP OID regexp pattern to short system name dict 29oid_to_short_system_name = {'.*Linux.*': 'linux', 30 '.*Darwin.*': 'mac', 31 '.*BSD.*': 'bsd', 32 '.*Windows.*': 'windows', 33 '.*Cisco.*': 'cisco', 34 '.*VMware ESXi.*': 'esxi', 35 '.*NetApp.*': 'netapp'} 36 37 38class GlancesStatsClientSNMP(GlancesStats): 39 40 """This class stores, updates and gives stats for the SNMP client.""" 41 42 def __init__(self, config=None, args=None): 43 super(GlancesStatsClientSNMP, self).__init__() 44 45 # Init the configuration 46 self.config = config 47 48 # Init the arguments 49 self.args = args 50 51 # OS name is used because OID is differents between system 52 self.os_name = None 53 54 # Load AMPs, plugins and exports modules 55 self.load_modules(self.args) 56 57 def check_snmp(self): 58 """Chek if SNMP is available on the server.""" 59 # Import the SNMP client class 60 from glances.snmp import GlancesSNMPClient 61 62 # Create an instance of the SNMP client 63 clientsnmp = GlancesSNMPClient(host=self.args.client, 64 port=self.args.snmp_port, 65 version=self.args.snmp_version, 66 community=self.args.snmp_community, 67 user=self.args.snmp_user, 68 auth=self.args.snmp_auth) 69 70 # If we cannot grab the hostname, then exit... 71 ret = clientsnmp.get_by_oid("1.3.6.1.2.1.1.5.0") != {} 72 if ret: 73 # Get the OS name (need to grab the good OID...) 74 oid_os_name = clientsnmp.get_by_oid("1.3.6.1.2.1.1.1.0") 75 try: 76 self.system_name = self.get_system_name(oid_os_name['1.3.6.1.2.1.1.1.0']) 77 logger.info("SNMP system name detected: {}".format(self.system_name)) 78 except KeyError: 79 self.system_name = None 80 logger.warning("Cannot detect SNMP system name") 81 82 return ret 83 84 def get_system_name(self, oid_system_name): 85 """Get the short os name from the OS name OID string.""" 86 short_system_name = None 87 88 if oid_system_name == '': 89 return short_system_name 90 91 # Find the short name in the oid_to_short_os_name dict 92 for r, v in iteritems(oid_to_short_system_name): 93 if re.search(r, oid_system_name): 94 short_system_name = v 95 break 96 97 return short_system_name 98 99 def update(self): 100 """Update the stats using SNMP.""" 101 # For each plugins, call the update method 102 for p in self._plugins: 103 if self._plugins[p].is_disable(): 104 # If current plugin is disable 105 # then continue to next plugin 106 continue 107 108 # Set the input method to SNMP 109 self._plugins[p].input_method = 'snmp' 110 self._plugins[p].short_system_name = self.system_name 111 112 # Update the stats... 113 try: 114 self._plugins[p].update() 115 except Exception as e: 116 logger.error("Update {} failed: {}".format(p, e)) 117 else: 118 # ... the history 119 self._plugins[p].update_stats_history() 120 # ... and the views 121 self._plugins[p].update_views() 122