You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
4.7 KiB

4 years ago
  1. # -*- coding: utf-8 -*-
  2. #
  3. # This file is part of Glances.
  4. #
  5. # Copyright (C) 2018 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. import sys
  20. from glances.logger import logger
  21. # Import mandatory PySNMP lib
  22. try:
  23. from pysnmp.entity.rfc3413.oneliner import cmdgen
  24. except ImportError:
  25. logger.critical("PySNMP library not found. To install it: pip install pysnmp")
  26. sys.exit(2)
  27. class GlancesSNMPClient(object):
  28. """SNMP client class (based on pysnmp library)."""
  29. def __init__(self, host='localhost', port=161, version='2c',
  30. community='public', user='private', auth=''):
  31. super(GlancesSNMPClient, self).__init__()
  32. self.cmdGen = cmdgen.CommandGenerator()
  33. self.version = version
  34. self.host = host
  35. self.port = port
  36. self.community = community
  37. self.user = user
  38. self.auth = auth
  39. def __buid_result(self, varBinds):
  40. """Build the results."""
  41. ret = {}
  42. for name, val in varBinds:
  43. if str(val) == '':
  44. ret[name.prettyPrint()] = ''
  45. else:
  46. ret[name.prettyPrint()] = val.prettyPrint()
  47. # In Python 3, prettyPrint() return 'b'linux'' instead of 'linux'
  48. if ret[name.prettyPrint()].startswith('b\''):
  49. ret[name.prettyPrint()] = ret[name.prettyPrint()][2:-1]
  50. return ret
  51. def __get_result__(self, errorIndication, errorStatus, errorIndex, varBinds):
  52. """Put results in table."""
  53. ret = {}
  54. if not errorIndication or not errorStatus:
  55. ret = self.__buid_result(varBinds)
  56. return ret
  57. def get_by_oid(self, *oid):
  58. """SNMP simple request (list of OID).
  59. One request per OID list.
  60. * oid: oid list
  61. > Return a dict
  62. """
  63. if self.version == '3':
  64. errorIndication, errorStatus, errorIndex, varBinds = self.cmdGen.getCmd(
  65. cmdgen.UsmUserData(self.user, self.auth),
  66. cmdgen.UdpTransportTarget((self.host, self.port)),
  67. *oid
  68. )
  69. else:
  70. errorIndication, errorStatus, errorIndex, varBinds = self.cmdGen.getCmd(
  71. cmdgen.CommunityData(self.community),
  72. cmdgen.UdpTransportTarget((self.host, self.port)),
  73. *oid
  74. )
  75. return self.__get_result__(errorIndication, errorStatus, errorIndex, varBinds)
  76. def __bulk_result__(self, errorIndication, errorStatus, errorIndex, varBindTable):
  77. ret = []
  78. if not errorIndication or not errorStatus:
  79. for varBindTableRow in varBindTable:
  80. ret.append(self.__buid_result(varBindTableRow))
  81. return ret
  82. def getbulk_by_oid(self, non_repeaters, max_repetitions, *oid):
  83. """SNMP getbulk request.
  84. In contrast to snmpwalk, this information will typically be gathered in
  85. a single transaction with the agent, rather than one transaction per
  86. variable found.
  87. * non_repeaters: This specifies the number of supplied variables that
  88. should not be iterated over.
  89. * max_repetitions: This specifies the maximum number of iterations over
  90. the repeating variables.
  91. * oid: oid list
  92. > Return a list of dicts
  93. """
  94. if self.version.startswith('3'):
  95. errorIndication, errorStatus, errorIndex, varBinds = self.cmdGen.getCmd(
  96. cmdgen.UsmUserData(self.user, self.auth),
  97. cmdgen.UdpTransportTarget((self.host, self.port)),
  98. non_repeaters,
  99. max_repetitions,
  100. *oid
  101. )
  102. if self.version.startswith('2'):
  103. errorIndication, errorStatus, errorIndex, varBindTable = self.cmdGen.bulkCmd(
  104. cmdgen.CommunityData(self.community),
  105. cmdgen.UdpTransportTarget((self.host, self.port)),
  106. non_repeaters,
  107. max_repetitions,
  108. *oid
  109. )
  110. else:
  111. # Bulk request are not available with SNMP version 1
  112. return []
  113. return self.__bulk_result__(errorIndication, errorStatus, errorIndex, varBindTable)