From 29965f6ec9f1d5603cd4be2152e36494a0f6222e Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Mon, 27 Jun 2022 14:12:51 -0400 Subject: [PATCH 01/10] Add a catch all to redfish for xcc Newer xcc changes things yet again, but we are comfortably in the firmware that can be bootstrapped with redfish, so use that instead once we've cleared the redfish incapable variants. --- .../confluent/discovery/handlers/xcc.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/confluent_server/confluent/discovery/handlers/xcc.py b/confluent_server/confluent/discovery/handlers/xcc.py index a4723e31..1da1af58 100644 --- a/confluent_server/confluent/discovery/handlers/xcc.py +++ b/confluent_server/confluent/discovery/handlers/xcc.py @@ -409,7 +409,21 @@ class NodeHandler(immhandler.NodeHandler): rsp, status = wc.grab_json_response_with_status( '/api/function', {'USER_UserModify': '{0},{1},,1,4,0,0,0,0,,8,,,'.format(uid, username)}) + if status == 200 and rsp.get('return', 0) == 13: + wc.set_basic_credentials(self._currcreds[0], self._currcreds[1]) + status = 503 + while status != 200: + rsp, status = wc.grab_json_response_with_status( + '/redfish/v1/AccountService/Accounts/{0}'.format(uid), + {'UserName': username}, method='PATCH') + if status != 200: + rsp = json.loads(rsp) + if rsp.get('error', {}).get('code', 'Unknown') in ('Base.1.8.GeneralError', 'Base.1.12.GeneralError'): + eventlet.sleep(10) + else: + break self.tmppasswd = None + wc.grab_json_response('/api/providers/logout') self._currcreds = (username, passwd) def _convert_sha256account(self, user, passwd, wc): @@ -501,6 +515,7 @@ class NodeHandler(immhandler.NodeHandler): 'Request to use default credentials, but refused by target after it has been changed to {0}'.format(self.tmppasswd)) if not isdefault: self._setup_xcc_account(user, passwd, wc) + wc = self.wc self._convert_sha256account(user, passwd, wc) cd = self.configmanager.get_node_attributes( nodename, ['secret.hardwaremanagementuser', From 500e08374644b2536c16844bdc0f083fa7fa936a Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Mon, 27 Jun 2022 14:34:37 -0400 Subject: [PATCH 02/10] Enable ipmi user if required If redfish models ipmi as an account type, and user wants ipmi, add it to the account. --- .../confluent/discovery/handlers/xcc.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/confluent_server/confluent/discovery/handlers/xcc.py b/confluent_server/confluent/discovery/handlers/xcc.py index 1da1af58..32fdb63a 100644 --- a/confluent_server/confluent/discovery/handlers/xcc.py +++ b/confluent_server/confluent/discovery/handlers/xcc.py @@ -534,6 +534,20 @@ class NodeHandler(immhandler.NodeHandler): _, _ = nwc.grab_json_response_with_status( '/redfish/v1/Managers/1/NetworkProtocol', {'IPMI': {'ProtocolEnabled': True}}, method='PATCH') + rsp, status = nwc.grab_json_response_with_status( + '/redfish/v1/AccountService/Accounts/1') + if status == 200: + allowable = rsp.get('AccountTypes@Redfish.AllowableValues', []) + current = rsp.get('AccountTypes', []) + if 'IPMI' in allowable and 'IPMI' not in current: + current.append('IPMI') + updateinf = { + 'AccountTypes': current, + 'Password': self._currcreds[1] + } + rsp, status = nwc.grab_json_response_with_status( + '/redfish/v1/AccountService/Accounts/1', + updateinf, method='PATCH') if ('hardwaremanagement.manager' in cd and cd['hardwaremanagement.manager']['value'] and not cd['hardwaremanagement.manager']['value'].startswith( From eaffac04332a6d9bc5428970a10f85ebdb55ea47 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Thu, 30 Jun 2022 13:27:25 -0400 Subject: [PATCH 03/10] Allow blanking a value to default a plugin attribute --- confluent_server/confluent/core.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/confluent_server/confluent/core.py b/confluent_server/confluent/core.py index 6d7d9366..aeec5c8d 100644 --- a/confluent_server/confluent/core.py +++ b/confluent_server/confluent/core.py @@ -823,17 +823,17 @@ def handle_dispatch(connection, cert, dispatch, peername): connection.close() return plugroute = routespec.routeinfo - plugpath = None nodesbyhandler = {} passvalues = [] nodeattr = configmanager.get_node_attributes( nodes, plugroute['pluginattrs']) for node in nodes: + plugpath = None for attrname in plugroute['pluginattrs']: if attrname in nodeattr[node]: plugpath = nodeattr[node][attrname]['value'] - elif 'default' in plugroute: - plugpath = plugroute['default'] + if not plugpath and 'default' in plugroute: + plugpath = plugroute['default'] if plugpath: try: hfunc = getattr(pluginmap[plugpath], operation) @@ -990,15 +990,15 @@ def handle_node_request(configmanager, inputdata, operation, elif 'pluginattrs' in plugroute: nodeattr = configmanager.get_node_attributes( nodes, plugroute['pluginattrs'] + ['collective.manager']) - plugpath = None nodesbymanager = {} nodesbyhandler = {} badcollnodes = [] for node in nodes: + plugpath = None for attrname in plugroute['pluginattrs']: if attrname in nodeattr[node]: plugpath = nodeattr[node][attrname]['value'] - elif 'default' in plugroute: + if not plugpath and 'default' in plugroute: plugpath = plugroute['default'] if plugpath in dispatch_plugins: cfm.check_quorum() From 3bd11da8076b211793bfa93453ac55be19f1cbcf Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Thu, 30 Jun 2022 13:27:39 -0400 Subject: [PATCH 04/10] Remove extraneous line from setupssh.sh --- misc/setupssh.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/misc/setupssh.sh b/misc/setupssh.sh index 7ac31040..3fdf0ef5 100644 --- a/misc/setupssh.sh +++ b/misc/setupssh.sh @@ -2,7 +2,6 @@ [ -f /etc/confluent/functions ] && . /etc/confluent/functions [ -f /opt/confluent/bin/apiclient ] && confapiclient=/opt/confluent/bin/apiclient [ -f /etc/confluent/apiclient ] && confapiclient=/etc/confluent/apiclient -nodename=$(grep ^NODENAME: /etc/confluent.info|awk '{print $NF}') for pubkey in /etc/ssh/ssh_host*key.pub; do certfile=${pubkey/.pub/-cert.pub} rm $certfile From f467cfe7c47c7454484174b09f2d8c5c1eabafb9 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Thu, 30 Jun 2022 13:28:26 -0400 Subject: [PATCH 05/10] Add log message for mac interrogation of switch Clarify when things go wrong due to certificate. --- confluent_server/confluent/networking/macmap.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/confluent_server/confluent/networking/macmap.py b/confluent_server/confluent/networking/macmap.py index 16edffca..f44e8c93 100644 --- a/confluent_server/confluent/networking/macmap.py +++ b/confluent_server/confluent/networking/macmap.py @@ -260,6 +260,11 @@ def _map_switch_backend(args): if switch not in noaffluent: try: return _affluent_map_switch(args) + except exc.PubkeyInvalid: + log.log({'error': 'While trying to gather ethernet mac addresses ' + 'from {0}, the TLS certificate failed validation. ' + 'Clear pubkeys.tls_hardwaremanager if this was ' + 'expected due to reinstall or new certificate'.format(switch)}) except Exception: pass mactobridge, ifnamemap, bridgetoifmap = _offload_map_switch( From beb4c66b65df40b0621c23a8ea48c0ab9cb7b662 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Fri, 8 Jul 2022 10:50:25 -0400 Subject: [PATCH 06/10] Fix spelling in error message --- confluent_osdeploy/utils/copernicus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/confluent_osdeploy/utils/copernicus.c b/confluent_osdeploy/utils/copernicus.c index 872b51f0..bf54f853 100644 --- a/confluent_osdeploy/utils/copernicus.c +++ b/confluent_osdeploy/utils/copernicus.c @@ -154,7 +154,7 @@ int main(int argc, char* argv[]) { } /* For now, bind to 190 to prove we are a privileged process */ if (bind(n4, (const struct sockaddr *)&addr4, sizeof(addr4)) < 0) { - fprintf(stderr, "Eror binding privilged port!\n"); + fprintf(stderr, "Error binding privilged port!\n"); exit(1); } if (bind(ns, (const struct sockaddr *)&addr, sizeof(addr)) < 0) { From 2058d1fba8498953d1d2e8086ffad398205cbcf6 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Fri, 8 Jul 2022 13:36:21 -0400 Subject: [PATCH 07/10] Add ESXi 8 support ESXi changes security policies, adapt to navigate both old and new sorts of rules --- confluent_osdeploy/confluent_osdeploy.spec.tmpl | 4 +++- confluent_osdeploy/esxi7/initramfs/bin/dcuiweasel | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/confluent_osdeploy/confluent_osdeploy.spec.tmpl b/confluent_osdeploy/confluent_osdeploy.spec.tmpl index 1fb3bdcd..e3607c0f 100644 --- a/confluent_osdeploy/confluent_osdeploy.spec.tmpl +++ b/confluent_osdeploy/confluent_osdeploy.spec.tmpl @@ -73,11 +73,13 @@ mv ../addons.tgz . cd .. cp -a esxi7out esxi6out cp -a esxi7 esxi6 +cp -a esxi7out esxi8out +cp -a esxi7 esxi8 %install mkdir -p %{buildroot}/opt/confluent/share/licenses/confluent_osdeploy/ cp LICENSE %{buildroot}/opt/confluent/share/licenses/confluent_osdeploy/ -for os in rhvh4 el7 el8 el9 genesis suse15 ubuntu20.04 ubuntu22.04 esxi6 esxi7 coreos; do +for os in rhvh4 el7 el8 el9 genesis suse15 ubuntu20.04 ubuntu22.04 esxi6 esxi7 esxi8 coreos; do mkdir -p %{buildroot}/opt/confluent/lib/osdeploy/$os/initramfs mkdir -p %{buildroot}/opt/confluent/lib/osdeploy/$os/profiles cp ${os}out/addons.* %{buildroot}/opt/confluent/lib/osdeploy/$os/initramfs diff --git a/confluent_osdeploy/esxi7/initramfs/bin/dcuiweasel b/confluent_osdeploy/esxi7/initramfs/bin/dcuiweasel index 4a490b79..ca3b124b 100644 --- a/confluent_osdeploy/esxi7/initramfs/bin/dcuiweasel +++ b/confluent_osdeploy/esxi7/initramfs/bin/dcuiweasel @@ -8,6 +8,7 @@ mkdir -p /etc/confluent localcli network firewall unload touch /etc/confluent/confluent.info begin=$(date +%s) +localcli system secpolicy domain set -n appDom -l disabled while ! grep NODENAME /etc/confluent/confluent.info; do echo "Searching for deployment service on local network..." /opt/confluent/bin/copernicus > /etc/confluent/confluent.info @@ -27,7 +28,7 @@ done node=$(grep NODENAME: /etc/confluent/confluent.info|head -n 1|awk '{print $2}') mgr=$(grep MANAGER: /etc/confluent/confluent.info|head -n 1|awk '{print $2}') cp /opt/confluent/bin/clortho /clortho -/clortho $node $mgr > /etc/confluent/confluent.apikey +(/clortho $node $mgr || /opt/confluent/bin/clortho $node $mgr) > /etc/confluent/confluent.apikey APIKEY=$(cat /etc/confluent/confluent.apikey) while [ -z "$APIKEY" ]; do if [ ! -f /var/run/vmware/show-esx-shell-login ]; then @@ -38,7 +39,7 @@ while [ -z "$APIKEY" ]; do fi echo "Deployment server failed to grant node deployment token, retrying token retrieval" echo "A debug session has been made available on Alt-F1" - /clortho $node $mgr > /etc/confluent/confluent.apikey + (/clortho $node $mgr || /opt/confluent/bin/clortho $node $mgr) > /etc/confluent/confluent.apikey APIKEY=$(cat /etc/confluent/confluent.apikey) done cat /tls/*.pem > /etc/confluent/ca.pem From c627ac73ee6bc5dce4b5a5b1d5f47907710babd0 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Mon, 11 Jul 2022 16:18:33 -0400 Subject: [PATCH 08/10] Make a specific error on nodesupport --- confluent_server/confluent/firmwaremanager.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/confluent_server/confluent/firmwaremanager.py b/confluent_server/confluent/firmwaremanager.py index 33f14a80..a7713943 100644 --- a/confluent_server/confluent/firmwaremanager.py +++ b/confluent_server/confluent/firmwaremanager.py @@ -78,7 +78,10 @@ def execupdate(handler, filename, updateobj, type, owner, node, datfile): completion = 'complete' if owner: pwent = pwd.getpwnam(owner) - os.chown(filename, pwent.pw_uid, pwent.pw_gid) + try: + os.chown(filename, pwent.pw_uid, pwent.pw_gid) + except: + raise Exception('Error changing ownership of {} to {}, file is complete but owned by confluent instead'.format(filename, owner)) updateobj.handle_progress({'phase': completion, 'progress': 100.0}) except exc.PubkeyInvalid as pi: errstr = 'Certificate mismatch detected, does not match value in ' \ From 926f9e2cdd3db8b167e69405e153dc739a6bc80b Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Wed, 13 Jul 2022 08:57:54 -0400 Subject: [PATCH 09/10] Enable more plugins for collective routing --- confluent_server/confluent/core.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/confluent_server/confluent/core.py b/confluent_server/confluent/core.py index aeec5c8d..61b23c69 100644 --- a/confluent_server/confluent/core.py +++ b/confluent_server/confluent/core.py @@ -71,7 +71,8 @@ import struct import sys pluginmap = {} -dispatch_plugins = (b'ipmi', u'ipmi', b'redfish', u'redfish', b'tsmsol', u'tsmsol') +dispatch_plugins = (b'ipmi', u'ipmi', b'redfish', u'redfish', b'tsmsol', u'tsmsol', b'geist', u'geist', b'deltapdu', u'deltapdu', b'eatonpdu', u'eatonpdu', b'affluent', u'affluent', b'cnos', u'cnos') + PluginCollection = plugin.PluginCollection try: From 789def17d16fb2dd3f3ebb9a8cc03cc2a1bc6243 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Mon, 18 Jul 2022 09:35:40 -0400 Subject: [PATCH 10/10] Do not tail old content from firstboot Tail only new content being fleshly logged --- confluent_osdeploy/el8/profiles/default/scripts/firstboot.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/confluent_osdeploy/el8/profiles/default/scripts/firstboot.sh b/confluent_osdeploy/el8/profiles/default/scripts/firstboot.sh index a735e2cf..1903f448 100644 --- a/confluent_osdeploy/el8/profiles/default/scripts/firstboot.sh +++ b/confluent_osdeploy/el8/profiles/default/scripts/firstboot.sh @@ -25,7 +25,7 @@ export nodename confluent_mgr confluent_profile exec >> /var/log/confluent/confluent-firstboot.log exec 2>> /var/log/confluent/confluent-firstboot.log chmod 600 /var/log/confluent/confluent-firstboot.log -tail -f /var/log/confluent/confluent-firstboot.log > /dev/console & +tail -n 0 -f /var/log/confluent/confluent-firstboot.log > /dev/console & logshowpid=$! while ! ping -c 1 $confluent_pingtarget >& /dev/null; do sleep 1