2
0
mirror of https://github.com/xcat2/confluent.git synced 2026-01-11 10:32:31 +00:00

Automatically sign XCC certificates on discover

If an XCC doesn't have a 'real' certificate, sign it with the confluent
CA for 47 days.
This commit is contained in:
Jarrod Johnson
2025-11-03 14:02:33 -05:00
parent 5de063212f
commit 5adb5fa780
4 changed files with 62 additions and 1 deletions

View File

@@ -98,6 +98,7 @@ import eventlet
import eventlet.greenpool
import eventlet.semaphore
autosensors = set()
scanner = None
@@ -1472,7 +1473,7 @@ def discover_node(cfg, handler, info, nodename, manual):
break
log.log({'info': 'Discovered {0} ({1})'.format(nodename,
handler.devname)})
if nodeconfig:
if nodeconfig or handler.current_cert_self_signed():
bmcaddr = cfg.get_node_attributes(nodename, 'hardwaremanagement.manager')
bmcaddr = bmcaddr.get(nodename, {}).get('hardwaremanagement.manager', {}).get('value', '')
if not bmcaddr:
@@ -1481,9 +1482,12 @@ def discover_node(cfg, handler, info, nodename, manual):
bmcaddr = bmcaddr.split('/', 1)[0]
wait_for_connection(bmcaddr)
socket.getaddrinfo(bmcaddr, 443)
if nodeconfig:
subprocess.check_call(['/opt/confluent/bin/nodeconfig', nodename] + nodeconfig)
log.log({'info': 'Configured {0} ({1})'.format(nodename,
handler.devname)})
if handler.current_cert_self_signed():
handler.autosign_certificate()
info['discostatus'] = 'discovered'
for i in pending_by_uuid.get(curruuid, []):

View File

@@ -17,6 +17,10 @@ import errno
import eventlet
import socket
webclient = eventlet.import_patched('pyghmi.util.webclient')
try:
import cryptography.x509 as x509
except ImportError:
x509 = None
class NodeHandler(object):
https_supported = True
@@ -59,6 +63,40 @@ class NodeHandler(object):
# may occur against the target in a short while
return True
def current_cert_self_signed(self):
if not x509:
return
if not self._ipaddr:
return
try:
wc = webclient.SecureHTTPConnection(self._ipaddr, verifycallback=self._savecert, port=443)
wc.connect()
wc.close()
if not self._fp:
return False
# Check if certificate is self-signed by comparing issuer and subject
cert = self._fp
certobj = x509.load_der_x509_certificate(cert)
skid = None
akid = None
for ext in certobj.extensions:
if ext.oid == x509.ExtensionOID.SUBJECT_KEY_IDENTIFIER:
skid = ext.value
elif ext.oid == x509.ExtensionOID.AUTHORITY_KEY_IDENTIFIER:
akid = ext.value
if akid:
if skid.digest == akid.key_identifier:
return True
elif certobj.issuer == certobj.subject:
return True
except Exception:
pass
return False
def autosign_certificate(self):
# A no-op by default
return
def scan(self):
# Do completely passive things to enhance data.
# Probe is permitted to for example attempt a login

View File

@@ -23,6 +23,7 @@ try:
from urllib import urlencode
except ImportError:
from urllib.parse import urlencode
import eventlet.green.subprocess as subprocess
getaddrinfo = eventlet.support.greendns.getaddrinfo
@@ -326,6 +327,14 @@ class NodeHandler(generic.NodeHandler):
raise exc.TargetEndpointUnreachable(
'hardwaremanagement.manager must be set to desired address (No IPv6 Link Local detected)')
def autosign_certificate(self):
nodename = self.nodename
hwmgt_method = self.configmanager.get_node_attributes(
nodename, 'hardwaremanagement.method').get(
nodename, {}).get('hardwaremanagement.method', {}).get('value', 'ipmi')
if hwmgt_method != 'redfish':
return
subprocess.check_call(['/opt/confluent/bin/nodecertutil', nodename, 'signbmccert', '--days', '47'])
def remote_nodecfg(nodename, cfm):
cfg = cfm.get_node_attributes(

View File

@@ -29,6 +29,7 @@ import eventlet.green.socket as socket
webclient = eventlet.import_patched('pyghmi.util.webclient')
import struct
getaddrinfo = eventlet.support.greendns.getaddrinfo
import eventlet.green.subprocess as subprocess
def fixuuid(baduuid):
@@ -704,6 +705,15 @@ class NodeHandler(immhandler.NodeHandler):
if em:
self.configmanager.set_node_attributes(
{em: {'id.uuid': enclosureuuid}})
def autosign_certificate(self):
nodename = self.nodename
hwmgt_method = self.configmanager.get_node_attributes(
nodename, 'hardwaremanagement.method').get(
nodename, {}).get('hardwaremanagement.method', {}).get('value', 'ipmi')
if hwmgt_method != 'redfish':
return
subprocess.check_call(['/opt/confluent/bin/nodecertutil', nodename, 'signbmccert', '--days', '47'])
def remote_nodecfg(nodename, cfm):
cfg = cfm.get_node_attributes(