From: Guillaume Abrioux Date: Tue, 3 Feb 2026 12:22:03 +0000 (+0100) Subject: node-proxy: handle nested Redfish paths for components X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=6e5b46c1f6490b46a370c66cae2db5d690e2e162;p=ceph.git node-proxy: handle nested Redfish paths for components Add a _resolve_path() helper to support components whose data lives under nested Redfish paths when assembling component data. For instance, power is exposed at 'PowerSubsystem/PowerSupplies' Fixes: https://tracker.ceph.com/issues/74749 Signed-off-by: Guillaume Abrioux --- diff --git a/src/ceph-node-proxy/ceph_node_proxy/atollon.py b/src/ceph-node-proxy/ceph_node_proxy/atollon.py index 5d71b773042..5b083420b45 100644 --- a/src/ceph-node-proxy/ceph_node_proxy/atollon.py +++ b/src/ceph-node-proxy/ceph_node_proxy/atollon.py @@ -1,12 +1,9 @@ from ceph_node_proxy.baseredfishsystem import BaseRedfishSystem from ceph_node_proxy.util import get_logger -from typing import Any, Dict +from typing import Any class AtollonSystem(BaseRedfishSystem): def __init__(self, **kw: Any) -> None: super().__init__(**kw) self.log = get_logger(__name__) - - def get_component_spec_overrides(self) -> Dict[str, Dict[str, Any]]: - return {'power': {'path': 'PowerSubsystem'}} diff --git a/src/ceph-node-proxy/ceph_node_proxy/baseredfishsystem.py b/src/ceph-node-proxy/ceph_node_proxy/baseredfishsystem.py index 98b88d8416e..50f5b01c9d5 100644 --- a/src/ceph-node-proxy/ceph_node_proxy/baseredfishsystem.py +++ b/src/ceph-node-proxy/ceph_node_proxy/baseredfishsystem.py @@ -29,7 +29,8 @@ class BaseRedfishSystem(BaseSystem): 'network': ComponentUpdateSpec('systems', 'EthernetInterfaces', NETWORK_FIELDS, None), 'processors': ComponentUpdateSpec('systems', 'Processors', PROCESSORS_FIELDS, None), 'memory': ComponentUpdateSpec('systems', 'Memory', MEMORY_FIELDS, None), - 'power': ComponentUpdateSpec('chassis', 'Power', POWER_FIELDS, 'PowerSupplies'), + # Power supplies: Chassis/.../PowerSubsystem/PowerSupplies (not like other components: like Systems/.../Memory) + 'power': ComponentUpdateSpec('chassis', 'PowerSubsystem/PowerSupplies', POWER_FIELDS, None), 'fans': ComponentUpdateSpec('chassis', 'Thermal', FANS_FIELDS, 'Fans'), 'firmwares': ComponentUpdateSpec('update_service', 'FirmwareInventory', FIRMWARES_FIELDS, None), } diff --git a/src/ceph-node-proxy/ceph_node_proxy/redfish.py b/src/ceph-node-proxy/ceph_node_proxy/redfish.py index c9ef874f31f..70a99f380d1 100644 --- a/src/ceph-node-proxy/ceph_node_proxy/redfish.py +++ b/src/ceph-node-proxy/ceph_node_proxy/redfish.py @@ -245,6 +245,15 @@ def build_data( return normalize_dict(result) +def _resolve_path(endpoint: Endpoint, path: str) -> Endpoint: + """Resolve an endpoint by traversing path segments (example: 'PowerSubsystem/PowerSupplies').""" + parts = [p for p in path.split('/') if p] + current = endpoint + for part in parts: + current = current[part] + return current + + def update_component( endpoints: EndpointMgr, collection: str, @@ -255,21 +264,25 @@ def update_component( log: Any, attribute: Optional[str] = None, ) -> None: - """Update _sys[component] from Redfish endpoints using the given spec.""" + """Update _sys[component] from Redfish endpoints using the given spec. + path can be a single segment ('Memory') or multiple ('PowerSubsystem/PowerSupplies'). + """ members: List[str] = endpoints[collection].get_members_names() result: Dict[str, Any] = {} if not members: - data = endpoints[collection][path].get_members_data() + ep = _resolve_path(endpoints[collection], path) + data = ep.get_members_data() result = build_data(data=data, fields=fields, log=log, attribute=attribute) else: for member in members: try: + ep = _resolve_path(endpoints[collection][member], path) if attribute is None: - data = endpoints[collection][member][path].get_members_data() + data = ep.get_members_data() else: - data = endpoints[collection][member][path].data + data = ep.data + result[member] = build_data(data=data, fields=fields, log=log, attribute=attribute) except HTTPError as e: log.error(f'Error while updating {component}: {e}') continue - result[member] = build_data(data=data, fields=fields, log=log, attribute=attribute) _sys[component] = result