proliantutils/proliantutils/ilo/snmp/snmp_cpqdisk_sizes.py

223 lines
8.8 KiB
Python
Executable File

#!/usr/bin/env python
# Copyright 2017 Hewlett-Packard Enterprise Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
__author__ = 'HPE'
import os
from pysnmp import hlapi
from pysnmp.smi import builder
from pysnmp.smi import view
from proliantutils import exception
from proliantutils import log
LOG = log.get_logger(__name__)
cpq_mibs_path = os.path.dirname(os.path.abspath(__file__))
cpq_mibs_path = os.path.join(cpq_mibs_path, "cpqdisk_mibs")
mBuilder = builder.MibBuilder()
mBuilder.addMibSources(builder.DirMibSource(cpq_mibs_path))
mibBuilder = mBuilder.loadModules('CPQIDA-MIB', 'CPQSCSI-MIB')
mibViewController = view.MibViewController(mibBuilder)
# A dictionary of supported mapped snmp attributes
MAPPED_SNMP_ATTRIBUTES = {
'authProtocol': {
'SHA': hlapi.usmHMACSHAAuthProtocol,
'MD5': hlapi.usmHMACMD5AuthProtocol,
},
'privProtocol': {
'AES': hlapi.usmAesCfb128Protocol,
'DES': hlapi.usmDESPrivProtocol,
},
}
def _create_usm_user_obj(snmp_cred):
"""Creates the UsmUserData obj for the given credentials.
This method creates an instance for the method hlapi.UsmUserData.
The UsmUserData() allows the 'auth_protocol' and 'priv_protocol'
to be undefined by user if their pass phrases are provided.
:param snmp_cred: Dictionary of SNMP credentials.
auth_user: SNMP user
auth_protocol: Auth Protocol
auth_prot_pp: Pass phrase value for AuthProtocol.
priv_protocol:Privacy Protocol.
auth_priv_pp: Pass phrase value for Privacy Protocol.
:returns UsmUserData object as per given credentials.
"""
auth_protocol = snmp_cred.get('auth_protocol')
priv_protocol = snmp_cred.get('priv_protocol')
auth_user = snmp_cred.get('auth_user')
auth_prot_pp = snmp_cred.get('auth_prot_pp')
auth_priv_pp = snmp_cred.get('auth_priv_pp')
if ((not auth_protocol) and priv_protocol):
priv_protocol = (
MAPPED_SNMP_ATTRIBUTES['privProtocol'][priv_protocol])
usm_user_obj = hlapi.UsmUserData(auth_user, auth_prot_pp,
auth_priv_pp,
privProtocol=priv_protocol)
elif ((not priv_protocol) and auth_protocol):
auth_protocol = (
MAPPED_SNMP_ATTRIBUTES['authProtocol'][auth_protocol])
usm_user_obj = hlapi.UsmUserData(auth_user, auth_prot_pp,
auth_priv_pp,
authProtocol=auth_protocol)
elif not all([priv_protocol and auth_protocol]):
usm_user_obj = hlapi.UsmUserData(auth_user, auth_prot_pp,
auth_priv_pp)
else:
auth_protocol = (
MAPPED_SNMP_ATTRIBUTES['authProtocol'][auth_protocol])
priv_protocol = (
MAPPED_SNMP_ATTRIBUTES['privProtocol'][priv_protocol])
usm_user_obj = hlapi.UsmUserData(auth_user, auth_prot_pp,
auth_priv_pp,
authProtocol=auth_protocol,
privProtocol=priv_protocol)
return usm_user_obj
def _parse_mibs(iLOIP, snmp_credentials):
"""Parses the MIBs.
:param iLOIP: IP address of the server on which SNMP discovery
has to be executed.
:param snmp_credentials: a Dictionary of SNMP credentials.
auth_user: SNMP user
auth_protocol: Auth Protocol
auth_prot_pp: Pass phrase value for AuthProtocol.
priv_protocol:Privacy Protocol.
auth_priv_pp: Pass phrase value for Privacy Protocol.
:returns the dictionary of parsed MIBs.
:raises exception.InvalidInputError if pysnmp is unable to get
SNMP data due to wrong inputs provided.
:raises exception.IloError if pysnmp raises any exception.
"""
result = {}
usm_user_obj = _create_usm_user_obj(snmp_credentials)
try:
for(errorIndication,
errorStatus,
errorIndex,
varBinds) in hlapi.nextCmd(
hlapi.SnmpEngine(),
usm_user_obj,
hlapi.UdpTransportTarget((iLOIP, 161), timeout=3, retries=3),
hlapi.ContextData(),
# cpqida cpqDaPhyDrvTable Drive Array Physical Drive Table
hlapi.ObjectType(
hlapi.ObjectIdentity('1.3.6.1.4.1.232.3.2.5.1')),
# cpqscsi SCSI Physical Drive Table
hlapi.ObjectType(
hlapi.ObjectIdentity('1.3.6.1.4.1.232.5.2.4.1')),
# cpqscsi SAS Physical Drive Table
hlapi.ObjectType(
hlapi.ObjectIdentity('1.3.6.1.4.1.232.5.5.2.1')),
lexicographicMode=False,
ignoreNonIncreasingOid=True):
if errorIndication:
LOG.error(errorIndication)
msg = "SNMP failed to traverse MIBs %s", errorIndication
raise exception.IloSNMPInvalidInputFailure(msg)
else:
if errorStatus:
msg = ('Parsing MIBs failed. %s at %s' % (
errorStatus.prettyPrint(),
errorIndex and varBinds[-1][int(errorIndex)-1]
or '?'
)
)
LOG.error(msg)
raise exception.IloSNMPInvalidInputFailure(msg)
else:
for varBindTableRow in varBinds:
name, val = tuple(varBindTableRow)
oid, label, suffix = (
mibViewController.getNodeName(name))
key = name.prettyPrint()
# Don't traverse outside the tables we requested
if not (key.find("SNMPv2-SMI::enterprises.232.3") >= 0
or (key.find(
"SNMPv2-SMI::enterprises.232.5") >= 0)):
break
if key not in result:
result[key] = {}
result[key][label[-1]] = {}
result[key][label[-1]][suffix] = val
except Exception as e:
msg = "SNMP library failed with error %s", e
LOG.error(msg)
raise exception.IloSNMPExceptionFailure(msg)
return result
def _get_disksize_MiB(iLOIP, cred):
"""Reads the dictionary of parsed MIBs and gets the disk size.
:param iLOIP: IP address of the server on which SNMP discovery
has to be executed.
:param snmp_credentials in a dictionary having following mandatory
keys.
auth_user: SNMP user
auth_protocol: Auth Protocol
auth_prot_pp: Pass phrase value for AuthProtocol.
priv_protocol:Privacy Protocol.
auth_priv_pp: Pass phrase value for Privacy Protocol.
:returns the dictionary of disk sizes of all physical drives.
"""
# '1.3.6.1.4.1.232.5.5.1.1', # cpqscsi SAS HBA Table
# '1.3.6.1.4.1.232.3.2.3.1', # cpqida Drive Array Logical Drive Table
result = _parse_mibs(iLOIP, cred)
disksize = {}
for uuid in sorted(result):
for key in result[uuid]:
# We only track the Physical Disk Size
if key.find('PhyDrvSize') >= 0:
disksize[uuid] = dict()
for suffix in sorted(result[uuid][key]):
size = result[uuid][key][suffix]
disksize[uuid][key] = str(size)
return disksize
def get_local_gb(iLOIP, snmp_credentials):
"""Gets the maximum disk size among all disks.
:param iLOIP: IP address of the server on which SNMP discovery
has to be executed.
:param snmp_credentials in a dictionary having following mandatory
keys.
auth_user: SNMP user
auth_protocol: Auth Protocol
auth_prot_pp: Pass phrase value for AuthProtocol.
priv_protocol:Privacy Protocol.
auth_priv_pp: Pass phrase value for Privacy Protocol.
"""
disk_sizes = _get_disksize_MiB(iLOIP, snmp_credentials)
max_size = 0
for uuid in disk_sizes:
for key in disk_sizes[uuid]:
if int(disk_sizes[uuid][key]) > max_size:
max_size = int(disk_sizes[uuid][key])
max_size_gb = max_size/1024
return max_size_gb