From: Guillaume Abrioux Date: Tue, 20 Jun 2023 11:28:55 +0000 (+0200) Subject: node-proxy: redfish_dell.py refactor X-Git-Tag: v18.2.4~314^2~82 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=bf83849705d4f01dc3c08b815757b4377174e63b;p=ceph.git node-proxy: redfish_dell.py refactor This commit introduces a small refactor of `redfish_dell.py` in order to avoid code redundancy. Signed-off-by: Guillaume Abrioux (cherry picked from commit c538030f9e70afc687ed1e5734d0d603fc4b0a31) --- diff --git a/src/cephadm/node-proxy/redfish_dell.py b/src/cephadm/node-proxy/redfish_dell.py index f940a9ec3c3..9bf69b32470 100644 --- a/src/cephadm/node-proxy/redfish_dell.py +++ b/src/cephadm/node-proxy/redfish_dell.py @@ -1,5 +1,5 @@ from redfish_system import RedfishSystem -from util import Logger, normalize_dict +from util import Logger, normalize_dict, to_snake_case from typing import Dict, Any log = Logger(__name__) @@ -12,62 +12,39 @@ class RedfishDell(RedfishSystem): super().__init__(**kw) def _update_network(self) -> None: - net_path = self._system['EthernetInterfaces']['@odata.id'] + fields = ['Description', 'Name', 'SpeedMbps', 'Status'] log.logger.info("Updating network") - network_info = self._get_path(net_path) - self._system['network'] = {} - result: Dict[str, Dict[str, Dict]] = dict() - for interface in network_info['Members']: - interface_path = interface['@odata.id'] - interface_info = self._get_path(interface_path) - interface_id = interface_info['Id'] - result[interface_id] = dict() - result[interface_id]['description'] = interface_info['Description'] - result[interface_id]['name'] = interface_info['Name'] - result[interface_id]['speed_mbps'] = interface_info['SpeedMbps'] - result[interface_id]['status'] = interface_info['Status'] - self._system['network'] = normalize_dict(result) + self._system['network'] = self.build_data(fields, 'EthernetInterfaces') def _update_processors(self) -> None: - cpus_path = self._system['Processors']['@odata.id'] + fields = ['Description', + 'TotalCores', + 'TotalThreads', + 'ProcessorType', + 'Model', + 'Status', + 'Manufacturer'] log.logger.info("Updating processors") - cpus_info = self._get_path(cpus_path) - self._system['processors'] = {} - result: Dict[str, Dict[str, Dict]] = dict() - for cpu in cpus_info['Members']: - cpu_path = cpu['@odata.id'] - cpu_info = self._get_path(cpu_path) - cpu_id = cpu_info['Id'] - result[cpu_id] = dict() - result[cpu_id]['description'] = cpu_info['Description'] - result[cpu_id]['cores'] = cpu_info['TotalCores'] - result[cpu_id]['threads'] = cpu_info['TotalThreads'] - result[cpu_id]['type'] = cpu_info['ProcessorType'] - result[cpu_id]['model'] = cpu_info['Model'] - result[cpu_id]['status'] = cpu_info['Status'] - result[cpu_id]['manufacturer'] = cpu_info['Manufacturer'] - self._system['processors'] = normalize_dict(result) + self._system['processors'] = self.build_data(fields, 'Processors') def _update_storage(self) -> None: - storage_path = self._system['Storage']['@odata.id'] + fields = ['Description', + 'CapacityBytes', + 'Model', 'Protocol', + 'SerialNumber', 'Status', + 'PhysicalLocation'] + entities = self.get_members('Storage') log.logger.info("Updating storage") - storage_info = self._get_path(storage_path) result: Dict[str, Dict[str, Dict]] = dict() - for storage in storage_info['Members']: - entity_path = storage['@odata.id'] - entity_info = self._get_path(entity_path) - for drive in entity_info['Drives']: + for entity in entities: + for drive in entity['Drives']: drive_path = drive['@odata.id'] drive_info = self._get_path(drive_path) drive_id = drive_info['Id'] result[drive_id] = dict() - result[drive_id]['description'] = drive_info['Description'] - result[drive_id]['capacity_bytes'] = drive_info['CapacityBytes'] - result[drive_id]['model'] = drive_info['Model'] - result[drive_id]['protocol'] = drive_info['Protocol'] - result[drive_id]['serial_number'] = drive_info['SerialNumber'] - result[drive_id]['status'] = drive_info['Status'] - result[drive_id]['location'] = drive_info['PhysicalLocation'] + for field in fields: + result[drive_id][to_snake_case(field)] = drive_info[field] + result[drive_id]['entity'] = entity['Id'] self._system['storage'] = normalize_dict(result) def _update_metadata(self) -> None: diff --git a/src/cephadm/node-proxy/redfish_system.py b/src/cephadm/node-proxy/redfish_system.py index eb1f323acb2..a41a861df46 100644 --- a/src/cephadm/node-proxy/redfish_system.py +++ b/src/cephadm/node-proxy/redfish_system.py @@ -2,8 +2,8 @@ from basesystem import BaseSystem from redfish_client import RedFishClient from threading import Thread, Lock from time import sleep -from util import Logger, retry -from typing import Dict, Any +from util import Logger, retry, normalize_dict, to_snake_case +from typing import Dict, Any, List log = Logger(__name__) @@ -34,6 +34,26 @@ class RedfishSystem(BaseSystem): raise RuntimeError(f"Could not get path: {path}") return result + def get_members(self, path: str) -> List: + _path = self._system[path]['@odata.id'] + data = self._get_path(_path) + return [self._get_path(member['@odata.id']) for member in data['Members']] + + def build_data(self, + fields: List, + path: str) -> Dict[str, Dict[str, Dict]]: + result: Dict[str, Dict[str, Dict]] = dict() + for member_info in self.get_members(path): + member_id = member_info['Id'] + result[member_id] = dict() + for field in fields: + try: + result[member_id][to_snake_case(field)] = member_info[field] + except KeyError: + log.logger.warning(f"Could not find field: {field} in member_info: {member_info}") + + return normalize_dict(result) + def start_client(self) -> None: if not self.client: self.client = RedFishClient(self.host, self.username, self.password) diff --git a/src/cephadm/node-proxy/util.py b/src/cephadm/node-proxy/util.py index 112652f7bd7..98c1a7d3671 100644 --- a/src/cephadm/node-proxy/util.py +++ b/src/cephadm/node-proxy/util.py @@ -2,6 +2,7 @@ import logging import yaml import os import time +import re from typing import Dict, List, Callable, Any @@ -65,6 +66,11 @@ class Config: log = Logger(__name__) +def to_snake_case(name: str) -> str: + name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name) + return re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower() + + def normalize_dict(test_dict: Dict) -> Dict: res = dict() for key in test_dict.keys():