173 lines
5.6 KiB
Python
173 lines
5.6 KiB
Python
from snmp import snmp_walk, SnmpConfiguration, SnmpEngine, CommunityData, UdpTransportTarget, ContextData
|
|
from https import get_json_response, HttpsConfiguration
|
|
from targets.fan import FAN_ENDPOINT
|
|
from targets.temp import TEMP_ENDPOINT
|
|
import traceback
|
|
|
|
|
|
def detect_things(c: SnmpConfiguration, base_oid: str) -> list[int]:
|
|
""" Scans for things and returns a list of their ids. """
|
|
things = []
|
|
for _, index in snmp_walk(c, base_oid):
|
|
assert isinstance(index, int)
|
|
assert index not in things
|
|
things.append(index)
|
|
return things
|
|
|
|
|
|
# because of the way drive indexing works, this is the simplest way I can think to do it without over-complicating
|
|
# everything else
|
|
def detect_complex(c: SnmpConfiguration, base_oid: str) -> list[tuple[int]]:
|
|
""" Scans for things and returns a list of their oid indexes. """
|
|
drives = []
|
|
for oid, _ in snmp_walk(c, base_oid):
|
|
index = oid[len(base_oid) + 1:]
|
|
index = (*[int(i) for i in index.split('.')],)
|
|
assert index not in drives
|
|
drives.append(index)
|
|
return drives
|
|
|
|
|
|
# since there's only two that get fetched via https, these are just kinda hacked together
|
|
def get_fan_speeds(c: HttpsConfiguration) -> dict[int, tuple[int | float, str]]: # {id: (speed, unit)}
|
|
speed_map = {}
|
|
|
|
response = get_json_response(c, FAN_ENDPOINT)
|
|
try:
|
|
fans = response['fans']
|
|
for fan in fans:
|
|
|
|
# try to derive fan id
|
|
label = fan.get('label')
|
|
if not isinstance(label, str):
|
|
continue
|
|
|
|
fan_id = str(label[4:]) # label seems to follow a format of "Fan X"
|
|
if not fan_id.isnumeric():
|
|
continue
|
|
fan_id = int(fan_id)
|
|
|
|
# get speed
|
|
speed = fan.get('speed')
|
|
if not (isinstance(speed, int) or isinstance(speed, float)):
|
|
speed = -1
|
|
|
|
# get units
|
|
unit = fan.get('speed_unit')
|
|
if not isinstance(unit, str):
|
|
unit = 'unknown'
|
|
|
|
speed_map[fan_id] = (speed, unit)
|
|
except (KeyError, TypeError) as e:
|
|
print('unexpected response from ILO')
|
|
traceback.print_exception(e)
|
|
print('response:', response)
|
|
|
|
return speed_map
|
|
|
|
|
|
def get_temp_sensor_info(c: HttpsConfiguration) -> dict[int, dict[str, str | int | float]]:
|
|
# {id: {name: value}}
|
|
labels = {}
|
|
|
|
response = get_json_response(c, TEMP_ENDPOINT)
|
|
try:
|
|
sensors = response['temperature']
|
|
for sensor in sensors:
|
|
sensor_labels = {}
|
|
|
|
# try to derive sensor id
|
|
label = sensor.get('label')
|
|
if not isinstance(label, str):
|
|
continue
|
|
|
|
sensor_id = str(label[:2]) # label seems to follow a format of "XX-Some Sensor"
|
|
if not sensor_id.isnumeric():
|
|
continue
|
|
sensor_id = int(sensor_id)
|
|
|
|
for key in ['label', 'xposition', 'yposition']:
|
|
value = sensor.get(key)
|
|
if value is not None:
|
|
sensor_labels[key] = str(value)
|
|
|
|
for key in ['caution', 'critical']:
|
|
value = sensor.get(key)
|
|
if isinstance(value, int) or isinstance(value, float):
|
|
sensor_labels[key] = value
|
|
|
|
labels[sensor_id] = sensor_labels
|
|
except (KeyError, TypeError) as e:
|
|
print('unexpected response from ILO')
|
|
traceback.print_exception(e)
|
|
print('response:', response)
|
|
|
|
return labels
|
|
|
|
|
|
if __name__ == '__main__':
|
|
from targets.fan import FAN_VALUES, FAN_INDEX
|
|
from targets.temp import TEMP_VALUES, TEMP_INDEX
|
|
from targets.cpu import CPU_VALUES, CPU_INDEX
|
|
from targets.memory import MEMORY_VALUES, MEMORY_INDEX
|
|
from targets.drive import DRIVE_INDEX
|
|
from targets.logical_drive import LOGICAL_DRIVES_INDEX
|
|
|
|
config = SnmpConfiguration(
|
|
SnmpEngine(),
|
|
CommunityData('public'),
|
|
UdpTransportTarget(('192.168.100.88', 161)),
|
|
ContextData(),
|
|
)
|
|
|
|
print('scanning hardware...')
|
|
fans = detect_things(config, FAN_INDEX)
|
|
temp_sensors = detect_things(config, TEMP_INDEX)
|
|
cpus = detect_things(config, CPU_INDEX)
|
|
logical_drives = detect_things(config, LOGICAL_DRIVES_INDEX)
|
|
drives = detect_complex(config, DRIVE_INDEX)
|
|
memory_slots = detect_things(config, MEMORY_INDEX)
|
|
|
|
print('\'puter has', len(fans), 'fans')
|
|
print('\'puter has', len(temp_sensors), 'temp sensors')
|
|
print('\'puter has', len(cpus), 'processors')
|
|
print('\'puter has', len(logical_drives), 'logical drives')
|
|
print('\'puter has', len(drives), 'physical drives')
|
|
print('\'puter has', len(memory_slots), 'memory slots')
|
|
|
|
for ilo_enum in FAN_VALUES:
|
|
states = ilo_enum.get_values(config, fans)
|
|
for fan in fans:
|
|
print('fan', fan, ilo_enum.name, 'is', states[fan])
|
|
print()
|
|
|
|
for value in TEMP_VALUES:
|
|
states = value.get_values(config, temp_sensors)
|
|
for sensor in temp_sensors:
|
|
print('temperature', sensor, value.name, 'is', states[sensor])
|
|
print()
|
|
|
|
for value in CPU_VALUES:
|
|
states = value.get_values(config, cpus)
|
|
for cpu in cpus:
|
|
print('cpu', cpu, value.name, 'is', states[cpu])
|
|
print()
|
|
|
|
for value in MEMORY_VALUES:
|
|
states = value.get_values(config, memory_slots)
|
|
for slot in memory_slots:
|
|
print('memory slot', slot, value.name, 'is', states[slot])
|
|
print()
|
|
|
|
print('asdf')
|
|
conf = HttpsConfiguration(
|
|
'192.168.100.88',
|
|
'some username',
|
|
'some password',
|
|
'./ilo.pem',
|
|
5
|
|
)
|
|
|
|
print(get_fan_speeds(conf))
|
|
print(get_temp_sensor_info(conf))
|