From 7493cc5d48088376638c7a97c84e70ad0a643d59 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Thu, 30 Jan 2025 09:37:10 -0500 Subject: [PATCH] Normalize enclosure handling --- .../confluent/plugins/info/layout.py | 59 ++++++++++++++++--- 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/confluent_server/confluent/plugins/info/layout.py b/confluent_server/confluent/plugins/info/layout.py index 71f288d3..8604eaeb 100644 --- a/confluent_server/confluent/plugins/info/layout.py +++ b/confluent_server/confluent/plugins/info/layout.py @@ -15,6 +15,22 @@ import confluent.core as core import confluent.messages as msg +def baytonumber(bay): + if not bay: + return None + try: + return int(bay) + except ValueError: + if len(bay) == 2: + # Treat a hexadecimal system as a leading decimal digit and letter compile + # 1a == slot 1, 1b == slot 2, 2a == slot 1, etc.. + try: + tmp = int(bay, 16) + return (2 * (tmp >> 4) - 1) + ((tmp & 15) % 10) + except ValueError: + return None + return None + def retrieve(nodes, element, configmanager, inputdata): locationinfo = configmanager.get_node_attributes(nodes, (u'enclosure.manager', u'enclosure.bay', u'location.rack', @@ -24,6 +40,7 @@ def retrieve(nodes, element, configmanager, inputdata): allnodedata = {} needenclosures = set([]) locatednodes = set([]) + needcoord = {} for node in locationinfo: nodeinfo = locationinfo[node] rack = nodeinfo.get(u'location.rack', {}).get('value', '') @@ -31,17 +48,23 @@ def retrieve(nodes, element, configmanager, inputdata): row = nodeinfo.get(u'location.row', {}).get('value', '') enclosure = nodeinfo.get(u'enclosure.manager', {}).get('value', None) bay = nodeinfo.get(u'enclosure.bay', {}).get('value', None) + height = nodeinfo.get(u'location.height', {}).get('value', None) if enclosure: if enclosure not in enclosuremap: - enclosuremap[enclosure] = {} - enclosuremap[enclosure][bay] = node + enclosuremap[enclosure] = {'bays': {}, 'coordinates': {}} + bay = baytonumber(bay) + if bay is None: + continue + bay = f'{bay}' + enclosuremap[enclosure]['bays'][bay] = node + needcoord[node] = enclosure if u: if row not in rackmap: rackmap[row] = {} if rack not in rackmap[row]: rackmap[row][rack] = {} - rackmap[row][rack][u] = {'node': enclosure, 'children': enclosuremap[enclosure]} + rackmap[row][rack][u] = {'node': enclosure, 'children': enclosuremap[enclosure]['bays'], 'nodecoordinates': enclosuremap[enclosure]['coordinates']} allnodedata[enclosure] = rackmap[row][rack][u] if height: allnodedata[enclosure]['height'] = height @@ -66,7 +89,7 @@ def retrieve(nodes, element, configmanager, inputdata): row = nodeinfo.get(u'location.row', {}).get('value', '') height = nodeinfo.get(u'location.height', {}).get('value', None) if u: - allnodedata[enclosure] = {'node': enclosure, 'children': enclosuremap[enclosure]} + allnodedata[enclosure] = {'node': enclosure, 'children': enclosuremap[enclosure]['bays'], 'nodecoordinates': enclosuremap[enclosure]['coordinates']} if height: allnodedata[enclosure]['height'] = height if row not in rackmap: @@ -82,13 +105,14 @@ def retrieve(nodes, element, configmanager, inputdata): if enclosure not in allnodedata: results['errors'].append('Enclosure {} is missing required location information'.format(enclosure)) else: - allnodedata[enclosure]['children'] = enclosuremap[enclosure] + allnodedata[enclosure]['children'] = enclosuremap[enclosure]['bays'] + allnodedata[enclosure]['nodecoordinates'] = enclosuremap[enclosure]['coordinates'] needheight = set([]) needslots = set(enclosuremap) for node in allnodedata: if 'height' not in allnodedata[node]: needheight.add(node) - needheightrange = ','.join(needheight.union(needslots)) + needheightrange = ','.join(needheight.union(needslots).union(needcoord)) if needheightrange: for rsp in core.handle_path( '/noderange/{0}/description'.format(needheightrange), @@ -101,8 +125,29 @@ def retrieve(nodes, element, configmanager, inputdata): for node in kvp: if node in needheight: allnodedata[node]['height'] = kvp[node]['height'] - if node in needslots: + if node in needslots and 'slots' in kvp[node]: allnodedata[node]['slots'] = kvp[node]['slots'] + if node in needcoord and 'slotcoord' in kvp[node]: + enclosuremap[needcoord[node]]['coordinates'][node] = kvp[node]['slotcoord'] + del needcoord[node] + for enclosure in enclosuremap: + if 'slots' not in allnodedata[enclosure]: + # if slots not described by chassis, assume a double-wide form factor + allnodedata[enclosure]['slots'] = [2, allnodedata[enclosure]['height']] + for node in needcoord: # have to fill in based on heuristic absent of specific data + enclosure = needcoord[node] + currslot = None + for bay in enclosuremap[enclosure]['bays']: + if enclosuremap[enclosure]['bays'][bay] == node: + currslot = int(bay) + if currslot is None: + continue + if enclosure in allnodedata and 'slots' in allnodedata[enclosure]: + dimensions = allnodedata[enclosure]['slots'] + if dimensions[0] > dimensions[1]: + enclosuremap[enclosure]['coordinates'][node] = [(currslot - 1) // dimensions[1] + 1, (currslot - 1) % dimensions[1] + 1] + else: + enclosuremap[enclosure]['coordinates'][node] = [(currslot - 1) % dimensions[0] + 1, (currslot - 1) // dimensions[0] + 1] for node in allnodedata: if 'height' not in allnodedata[node]: allnodedata[node]['height'] = 1