From c5dd024557ccde06df37357418450589ca52dbea Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Mon, 27 Nov 2017 16:59:13 -0500 Subject: [PATCH] Move the switch discoverable check for non-SMM into eval_node eval_node can establish that this is a direct discovery attempt. In that specific context, the check can be performed. Otherwise, we can't check in this way, but the enclosure manager should raise the error on behalf of the rest of the situation. --- confluent_server/confluent/discovery/core.py | 27 ++++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/confluent_server/confluent/discovery/core.py b/confluent_server/confluent/discovery/core.py index 63844429..7fbef1de 100644 --- a/confluent_server/confluent/discovery/core.py +++ b/confluent_server/confluent/discovery/core.py @@ -476,7 +476,7 @@ def _recheck_single_unknown(configmanager, mac): rechecker = eventlet.spawn_after(300, _periodic_recheck, configmanager) return - nodename = get_nodename(configmanager, handler, info) + nodename, info['maccount'] = get_nodename(configmanager, handler, info) if nodename: if handler.https_supported: dp = configmanager.get_node_attributes([nodename], @@ -591,7 +591,7 @@ def detected(info): #TODO, eventlet spawn after to recheck sooner, or somehow else # influence periodic recheck to shorten delay? return - nodename = get_nodename(cfg, handler, info) + nodename, info['maccount'] = get_nodename(cfg, handler, info) if nodename and handler.https_supported: dp = cfg.get_node_attributes([nodename], ('pubkeys.tls_hardwaremanager',)) @@ -619,11 +619,12 @@ def detected(info): def get_nodename(cfg, handler, info): nodename = None + maccount = None if handler.https_supported: currcert = handler.https_cert if not currcert: info['discofailure'] = 'nohttps' - return None + return None, None currprint = util.get_fingerprint(currcert) nodename = nodes_by_fprint.get(currprint, None) if not nodename: @@ -635,6 +636,7 @@ def get_nodename(cfg, handler, info): nodename = nodes_by_uuid.get(curruuid, None) if not nodename: # as a last resort, search switch for info nodename, macinfo = macmap.find_nodeinfo_by_mac(info['hwaddr'], cfg) + maccount = macinfo['maccount'] if (nodename and not handler.discoverable_by_switch(macinfo['maccount'])): if handler.devname == 'SMM': @@ -644,8 +646,8 @@ def get_nodename(cfg, handler, info): 'of SMM, nodename would have been ' \ '{0}'.format(nodename) log.log({'error': errorstr}) - return None - return nodename + return None, None + return nodename, maccount def eval_node(cfg, handler, info, nodename, manual=False): @@ -698,6 +700,9 @@ def eval_node(cfg, handler, info, nodename, manual=False): nl = cfg.filter_node_attributes( 'enclosure.bay={0}'.format(info['enclosure.bay']), nl) nl = list(nl) + # sadly, we cannot detect when user has a daisy chain smm config + # without ability to disambiguate, however the SMM will be caught so + # at least one actionable error will be encountered. if len(nl) != 1: info['discofailure'] = 'ambigconfig' if len(nl): @@ -724,6 +729,18 @@ def eval_node(cfg, handler, info, nodename, manual=False): pending_nodes[nodename] = info else: # we can and did accurately discover by switch or in enclosure + # but... is this really ok? could be on an upstream port or + # erroneously put in the enclosure with no nodes yet + if (info['maccount'] and + not handler.discoverable_by_switch(info['maccount'])): + errorstr = 'The detected node {0} was detected using switch, ' \ + 'however the relevant port has too many macs learned ' \ + 'for this type of device ({1}) to be discovered by ' \ + 'switch.'.format(nodename, handler.devname) + if manual: + raise exc.InvalidArgumentException(errorstr) + log.log({'error': errorstr}) + return if not discover_node(cfg, handler, info, nodename, manual): pending_nodes[nodename] = info