]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
node-proxy: redfish_dell.py refactor
authorGuillaume Abrioux <gabrioux@ibm.com>
Tue, 20 Jun 2023 11:28:55 +0000 (13:28 +0200)
committerGuillaume Abrioux <gabrioux@ibm.com>
Thu, 25 Jan 2024 14:43:30 +0000 (14:43 +0000)
This commit introduces a small refactor of `redfish_dell.py` in order
to avoid code redundancy.

Signed-off-by: Guillaume Abrioux <gabrioux@ibm.com>
src/cephadm/node-proxy/redfish_dell.py
src/cephadm/node-proxy/redfish_system.py
src/cephadm/node-proxy/util.py

index f940a9ec3c30b3a04f1c824bbf5f890d73530269..9bf69b32470780fbd023f1cbc1ad983dba8b6846 100644 (file)
@@ -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:
index eb1f323acb2cbd364201e0254735f212d4de45ae..a41a861df46c43134e9f28af86ad1ada989c73e4 100644 (file)
@@ -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)
index 112652f7bd769795041685d0143aad781ca53508..98c1a7d36712eed635e1f15cdf397606f55e1d7f 100644 (file)
@@ -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():