From 5a24619560664fdb955502350b15ee75d42c18a1 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Tue, 6 Oct 2020 09:36:12 -0400 Subject: [PATCH 1/6] Recognize a different m.2 name --- confluent_osdeploy/el7/profiles/default/scripts/getinstalldisk | 2 +- confluent_osdeploy/el8/profiles/default/scripts/getinstalldisk | 2 +- .../rhvh4/profiles/default/scripts/getinstalldisk | 2 +- confluent_osdeploy/suse15/profiles/hpc/scripts/getinstalldisk | 2 +- .../ubuntu20.04/profiles/default/scripts/getinstalldisk | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/confluent_osdeploy/el7/profiles/default/scripts/getinstalldisk b/confluent_osdeploy/el7/profiles/default/scripts/getinstalldisk index e4755444..4af31c0b 100644 --- a/confluent_osdeploy/el7/profiles/default/scripts/getinstalldisk +++ b/confluent_osdeploy/el7/profiles/default/scripts/getinstalldisk @@ -49,7 +49,7 @@ class DiskInfo(object): @property def priority(self): - if self.model.lower() in ('thinksystem_m.2_vd', 'thinksystem m.2'): + if self.model.lower() in ('thinksystem_m.2_vd', 'thinksystem m.2', 'thinksystem_m.2'): return 0 if 'imsm' in self.mdcontainer: return 1 diff --git a/confluent_osdeploy/el8/profiles/default/scripts/getinstalldisk b/confluent_osdeploy/el8/profiles/default/scripts/getinstalldisk index e4755444..4af31c0b 100644 --- a/confluent_osdeploy/el8/profiles/default/scripts/getinstalldisk +++ b/confluent_osdeploy/el8/profiles/default/scripts/getinstalldisk @@ -49,7 +49,7 @@ class DiskInfo(object): @property def priority(self): - if self.model.lower() in ('thinksystem_m.2_vd', 'thinksystem m.2'): + if self.model.lower() in ('thinksystem_m.2_vd', 'thinksystem m.2', 'thinksystem_m.2'): return 0 if 'imsm' in self.mdcontainer: return 1 diff --git a/confluent_osdeploy/rhvh4/profiles/default/scripts/getinstalldisk b/confluent_osdeploy/rhvh4/profiles/default/scripts/getinstalldisk index e4755444..4af31c0b 100644 --- a/confluent_osdeploy/rhvh4/profiles/default/scripts/getinstalldisk +++ b/confluent_osdeploy/rhvh4/profiles/default/scripts/getinstalldisk @@ -49,7 +49,7 @@ class DiskInfo(object): @property def priority(self): - if self.model.lower() in ('thinksystem_m.2_vd', 'thinksystem m.2'): + if self.model.lower() in ('thinksystem_m.2_vd', 'thinksystem m.2', 'thinksystem_m.2'): return 0 if 'imsm' in self.mdcontainer: return 1 diff --git a/confluent_osdeploy/suse15/profiles/hpc/scripts/getinstalldisk b/confluent_osdeploy/suse15/profiles/hpc/scripts/getinstalldisk index e4755444..4af31c0b 100644 --- a/confluent_osdeploy/suse15/profiles/hpc/scripts/getinstalldisk +++ b/confluent_osdeploy/suse15/profiles/hpc/scripts/getinstalldisk @@ -49,7 +49,7 @@ class DiskInfo(object): @property def priority(self): - if self.model.lower() in ('thinksystem_m.2_vd', 'thinksystem m.2'): + if self.model.lower() in ('thinksystem_m.2_vd', 'thinksystem m.2', 'thinksystem_m.2'): return 0 if 'imsm' in self.mdcontainer: return 1 diff --git a/confluent_osdeploy/ubuntu20.04/profiles/default/scripts/getinstalldisk b/confluent_osdeploy/ubuntu20.04/profiles/default/scripts/getinstalldisk index e4755444..4af31c0b 100644 --- a/confluent_osdeploy/ubuntu20.04/profiles/default/scripts/getinstalldisk +++ b/confluent_osdeploy/ubuntu20.04/profiles/default/scripts/getinstalldisk @@ -49,7 +49,7 @@ class DiskInfo(object): @property def priority(self): - if self.model.lower() in ('thinksystem_m.2_vd', 'thinksystem m.2'): + if self.model.lower() in ('thinksystem_m.2_vd', 'thinksystem m.2', 'thinksystem_m.2'): return 0 if 'imsm' in self.mdcontainer: return 1 From 61f793040e6eb1a95b086ee9331a6b0a4bc9d2bb Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Tue, 6 Oct 2020 17:14:20 -0400 Subject: [PATCH 2/6] Avoid setting uuid and mac in pxe if already set Notably the uuid change can end up recursing. Fix the behavior that will cause never ending loops, which in some IO situations can end in recursion limits. --- confluent_server/confluent/discovery/core.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/confluent_server/confluent/discovery/core.py b/confluent_server/confluent/discovery/core.py index 9d436427..65986a8e 100644 --- a/confluent_server/confluent/discovery/core.py +++ b/confluent_server/confluent/discovery/core.py @@ -1129,11 +1129,13 @@ def do_pxe_discovery(cfg, handler, info, manual, nodename, policies): # use uuid based scheme in lieu of tls cert, ideally only # for stateless 'discovery' targets like pxe, where data does not # change - uuidinfo = cfg.get_node_attributes(nodename, ['id.uuid', 'id.serial', 'id.model', 'net*.bootable']) + uuidinfo = cfg.get_node_attributes(nodename, ['id.uuid', 'id.serial', 'id.model', 'net*.hwaddr', 'net*.bootable']) if manual or policies & set(('open', 'pxe')): enrich_pxe_info(info) attribs = {} olduuid = uuidinfo.get(nodename, {}).get('id.uuid', None) + if isinstance(olduuid, dict): + olduuid = olduuid.get('value', None) uuid = info.get('uuid', None) if uuid and uuid != olduuid: attribs['id.uuid'] = info['uuid'] @@ -1146,7 +1148,9 @@ def do_pxe_discovery(cfg, handler, info, manual, nodename, policies): for attrname in uuidinfo.get(nodename, {}): if attrname.endswith('.bootable') and uuidinfo[nodename][attrname].get('value', None): newattrname = attrname[:-8] + 'hwaddr' - attribs[newattrname] = info['hwaddr'] + oldhwaddr = uuidinfo.get(nodename, {}).get(newattrname, {}).get('value', None) + if info['hwaddr'] != oldhwaddr: + attribs[newattrname] = info['hwaddr'] if attribs: cfg.set_node_attributes({nodename: attribs}) if info['uuid'] in known_pxe_uuids: From 247a7f5d8af935030be30031c0b1007f51b89b4f Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Thu, 8 Oct 2020 10:39:29 -0400 Subject: [PATCH 3/6] Fix problem when domain was not set domain was checked even if domain not defined, make sure domain is defined before trying to use it. --- confluent_server/confluent/selfservice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/confluent_server/confluent/selfservice.py b/confluent_server/confluent/selfservice.py index 15687d21..ac7501c7 100644 --- a/confluent_server/confluent/selfservice.py +++ b/confluent_server/confluent/selfservice.py @@ -33,7 +33,7 @@ def get_extra_names(nodename, cfg): currnames = currnames.split(',') for currname in currnames: names.add(currname) - if domain not in currname: + if domain and domain not in currname: names.add('{0}.{1}'.format(currname, domain)) return names From 72049657d7419835835c12c54874131fa8dddd1d Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Mon, 12 Oct 2020 09:47:24 -0400 Subject: [PATCH 4/6] Fix issues with leftover ssh sessions Upon connection loss, even though confluent internally decides it is done with it, it fails to close the session. Catch a number of these scenarios and ensure the connection closes. --- confluent_server/confluent/plugins/shell/ssh.py | 10 ++++++++-- confluent_server/confluent/shellserver.py | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/confluent_server/confluent/plugins/shell/ssh.py b/confluent_server/confluent/plugins/shell/ssh.py index 06da4ff7..a184764e 100644 --- a/confluent_server/confluent/plugins/shell/ssh.py +++ b/confluent_server/confluent/plugins/shell/ssh.py @@ -100,7 +100,9 @@ class SshShell(conapi.Console): while self.connected: pendingdata = self.shell.recv(8192) if not pendingdata: - self.datacallback(conapi.ConsoleEvent.Disconnect) + self.ssh.close() + if self.datacallback: + self.datacallback(conapi.ConsoleEvent.Disconnect) return self.datacallback(pendingdata) @@ -110,7 +112,7 @@ class SshShell(conapi.Console): # that would rather not use the nodename as anything but an opaque # identifier self.datacallback = callback - if self.username is not '': + if self.username is not b'': self.logon() else: self.inputmode = 0 @@ -126,12 +128,14 @@ class SshShell(conapi.Console): password=self.password, allow_agent=False, look_for_keys=False) except paramiko.AuthenticationException: + self.ssh.close() self.inputmode = 0 self.username = b'' self.password = b'' self.datacallback('\r\nlogin as: ') return except paramiko.ssh_exception.NoValidConnectionsError as e: + self.ssh.close() self.datacallback(str(e)) self.inputmode = 0 self.username = b'' @@ -139,6 +143,7 @@ class SshShell(conapi.Console): self.datacallback('\r\nlogin as: ') return except cexc.PubkeyInvalid as pi: + self.ssh.close() self.keyaction = '' self.candidatefprint = pi.fingerprint self.datacallback(pi.message) @@ -148,6 +153,7 @@ class SshShell(conapi.Console): self.datacallback('\r\nEnter "disconnect" or "accept": ') return except paramiko.SSHException as pi: + self.ssh.close() self.inputmode = -2 warn = str(pi) if warnhostkey: diff --git a/confluent_server/confluent/shellserver.py b/confluent_server/confluent/shellserver.py index f0efc85f..7a2c1027 100644 --- a/confluent_server/confluent/shellserver.py +++ b/confluent_server/confluent/shellserver.py @@ -111,6 +111,8 @@ class ShellSession(consoleserver.ConsoleSession): def destroy(self): try: + activesessions[(self.configmanager.tenant, self.node, + self.username)][self.sessionid].close() del activesessions[(self.configmanager.tenant, self.node, self.username)][self.sessionid] except KeyError: From 3903cda789e1879f98c966e384b90397a333d46a Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Thu, 29 Oct 2020 15:48:33 -0400 Subject: [PATCH 5/6] Do not clear the entire nodes lookup on remap remap may only amend part of the map, do not cause that to clear out the good data. --- confluent_server/confluent/discovery/core.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/confluent_server/confluent/discovery/core.py b/confluent_server/confluent/discovery/core.py index 65986a8e..9d504f35 100644 --- a/confluent_server/confluent/discovery/core.py +++ b/confluent_server/confluent/discovery/core.py @@ -1282,11 +1282,11 @@ known_pxe_uuids = {} def _map_unique_ids(nodes=None): global nodes_by_uuid global nodes_by_fprint - nodes_by_uuid = {} - nodes_by_fprint = {} # Map current known ids based on uuid and fingperprints for fast lookup cfg = cfm.ConfigManager(None) if nodes is None: + nodes_by_uuid = {} + nodes_by_fprint = {} nodes = cfg.list_nodes() bigmap = cfg.get_node_attributes(nodes, ('id.uuid', From 40c74699f0d8a5690ceaa6e84473e1f82eaac643 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Fri, 30 Oct 2020 08:18:27 -0400 Subject: [PATCH 6/6] Check for some issues in a manual assign request One is to provide clear feedback when a nodename is requested that was not previously defined, to make it more clear that it is a requirement and/or guard against going too far while the config function will be missing data it needs to complete onboarding. Another is to break if the request is trying to assign a node to a different definition when it already exists under a different name. --- confluent_server/confluent/discovery/core.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/confluent_server/confluent/discovery/core.py b/confluent_server/confluent/discovery/core.py index 9d504f35..e4dad354 100644 --- a/confluent_server/confluent/discovery/core.py +++ b/confluent_server/confluent/discovery/core.py @@ -1040,6 +1040,20 @@ def eval_node(cfg, handler, info, nodename, manual=False): def discover_node(cfg, handler, info, nodename, manual): + if manual: + if not cfg.is_node(nodename): + raise exc.InvalidArgumentException( + '{0} is not a defined node, must be defined before an ' + 'endpoint may be assigned to it'.format(nodename)) + if handler.https_supported: + currcert = handler.https_cert + if currcert: + currprint = util.get_fingerprint(currcert, 'sha256') + prevnode = nodes_by_fprint.get(currprint, None) + if prevnode and prevnode != nodename: + raise exc.InvalidArgumentException( + 'Attempt to assign {0} conflicts with existing node {1} ' + 'based on TLS certificate.'.format(nodename, prevnode)) known_nodes[nodename][info['hwaddr']] = info if info['hwaddr'] in unknown_info: del unknown_info[info['hwaddr']]