Skip to content

Commit cc279a3

Browse files
committed
mgr/node-proxy: handle 'None' statuses returned by RedFish
Looks like RedFish might return 'None' values for some attributes. for instance: ``` [root@ceph-node-01 ~]# curl -s -k -X GET https://169.254.1.1/redfish/v1/Systems/System.Embedded.1/Storage/AHCI.SL.6-1/Drives/Disk.Direct.0-0:AHCI.SL.6-1 -H "X-Auth-Token: 3264251c28191fa5e7c9ebec49ef90fc" | jq .Status { "Health": "OK", "HealthRollup": "OK", "State": "Enabled" } [root@ceph-node-01 ~]# curl -s -k -X GET https://169.254.1.1/redfish/v1/Systems/System.Embedded.1/Storage/NonRAID.Slot.2-1/Drives/Disk.Bay.0:Enclosure.Internal.0-1:NonRAID.Slot.2-1 -H "X-Auth-Token: 3264251c28191fa5e7c9ebec49ef90fc" | jq .Status { "Health": null, "HealthRollup": null, "State": "Enabled" } [root@ceph-node-01 ~]# ``` Although this seems to be a bug from RedFish, we need to handle the case when it happens otherwise it makes the mgr orchestrator module throw an error. The idea here is to create a new status "unknown" when we can't fetch the real status of a component. Fixes: https://tracker.ceph.com/issues/64712 Signed-off-by: Guillaume Abrioux <[email protected]>
1 parent b420380 commit cc279a3

File tree

2 files changed

+18
-8
lines changed

2 files changed

+18
-8
lines changed

src/ceph-node-proxy/ceph_node_proxy/util.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ def normalize_dict(test_dict: Dict) -> Dict:
126126
if isinstance(test_dict[key], dict):
127127
res[key.lower()] = normalize_dict(test_dict[key])
128128
else:
129+
if test_dict[key] is None:
130+
test_dict[key] = 'unknown'
129131
res[key.lower()] = test_dict[key]
130132
return res
131133

src/pybind/mgr/cephadm/inventory.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import math
99
import socket
1010
from typing import TYPE_CHECKING, Dict, List, Iterator, Optional, Any, Tuple, Set, Mapping, cast, \
11-
NamedTuple, Type
11+
NamedTuple, Type, ValuesView
1212

1313
import orchestrator
1414
from ceph.deployment import inventory
@@ -1485,20 +1485,28 @@ def summary(self, **kw: Any) -> Dict[str, Any]:
14851485
"""
14861486
hostname = kw.get('hostname')
14871487
hosts = [hostname] if hostname else self.data.keys()
1488-
mapper: Dict[bool, str] = {
1489-
True: 'error',
1490-
False: 'ok'
1491-
}
1488+
1489+
def is_unknown(statuses: ValuesView) -> bool:
1490+
return any([status['status']['health'].lower() == 'unknown' for status in statuses]) and not is_error(statuses)
1491+
1492+
def is_error(statuses: ValuesView) -> bool:
1493+
return any([status['status']['health'].lower() == 'error' for status in statuses])
14921494

14931495
_result: Dict[str, Any] = {}
14941496

14951497
for host in hosts:
14961498
_result[host] = {}
14971499
_result[host]['status'] = {}
14981500
data = self.data[host]
1499-
for component, details in data['status'].items():
1500-
res = any([member['status']['health'].lower() != 'ok' for member in data['status'][component].values()])
1501-
_result[host]['status'][component] = mapper[res]
1501+
for component in data['status'].keys():
1502+
values = data['status'][component].values()
1503+
if is_error(values):
1504+
state = 'error'
1505+
elif is_unknown(values):
1506+
state = 'unknown'
1507+
else:
1508+
state = 'ok'
1509+
_result[host]['status'][component] = state
15021510
_result[host]['sn'] = data['sn']
15031511
_result[host]['host'] = data['host']
15041512
_result[host]['firmwares'] = data['firmwares']

0 commit comments

Comments
 (0)