2
0
mirror of https://github.com/xcat2/confluent.git synced 2026-09-29 16:50:57 +00:00

Compare commits

...

11 Commits

Author SHA1 Message Date
Jarrod Johnson e186eb7319 Fix problem with autocons
autocons needed to open the devnode earlier
to have the correct name. Fixes TSM autocons
behavior
2020-09-24 08:31:20 -04:00
Jarrod Johnson 4b7d042f2d Have a clause for redfish not yet ready
We need redfish, but redfish is slow to boot on TSM..
2020-09-23 08:24:18 -04:00
Jarrod Johnson 99f533b4cb Implement redfish resilient discovery for TSM
TSM redfish stack has an issue where it refuses to recognize any
non-redfish password change. Use redfish to change.

Regretably, it takes about 10 seconds for that change to propogate
to the practical API, so we have a discovery delay now.
2020-09-23 08:24:07 -04:00
Jarrod Johnson 9828ea5898 Fix chained smm discovery on cumulus 2020-09-14 11:02:00 -04:00
Jarrod Johnson 7bdf7afb80 Fix another mistake in chained SMM discovery 2020-09-14 08:04:41 -04:00
Jarrod Johnson cd20a69eb6 Fix typo in function name in chained smm discovery 2020-09-14 08:03:18 -04:00
Jarrod Johnson c3d14977f2 Update attributes documentation 2020-09-11 09:56:35 -04:00
Jarrod Johnson 31d19e9398 Fix deployment.useinsecureprotocols
If explicitly set to 'never', it would behave as 'firmware'.
2020-09-11 09:44:09 -04:00
Jarrod Johnson ea533e64c6 Fix more issues found in configbmc 2020-09-09 13:01:01 -04:00
Jarrod Johnson 4fe84ca6dc Fix various issues in 3.0.0 release
If the kernel is new enough to do SKU, but the firmware doesn't have it,
fallback to model.

Fix outright mistakes in the config_port_tsm code

Up mac count from 2 to 3. If querying cumulus switches using SNMP
the switch will add its own mac to the list bringing the
total for a shared port to 3.
2020-09-09 10:58:37 -04:00
Jarrod Johnson 6f55a4ffe0 Python 3.7 fix for ipv6 lla handling
Python 3.7 changes behavior of recfrom (because.. why not apparently...)
Use getnameinfo to normalize the printable version.
2020-09-02 12:12:10 -04:00
10 changed files with 64 additions and 25 deletions
@@ -169,6 +169,7 @@ def set_port_tsm(s, port, model):
raise Exception("Unsupported port for TSM")
timer = 15
while timer:
timer = timer - 1
time.sleep(1.0)
sys.stdout.write('.')
sys.stdout.flush()
@@ -178,7 +179,7 @@ def set_port_tsm(s, port, model):
elif port == 'dedicated':
iface = 1
s.raw_command(0x32, 0x71, b'\x00\x01\x03')
rsp = s.raw_command(0x32, 0x72, bytearray(4, iface, 0))
rsp = s.raw_command(0x32, 0x72, bytearray([4, iface, 0]))
print('Complete')
return int(rsp['data'][0])
@@ -261,16 +262,18 @@ def set_ipv4(s, ipaddr, channel):
return
rsp = int(s.raw_command(0xc, 2, bytearray([channel, 4, 0, 0]))['data'][1]) & 0b1111
if rsp != 1:
sys.stdout.print("Changing configuration to static...")
sys.stdout.write("Changing configuration to static...")
sys.stdout.flush()
resp = s.raw_command(0xc, 1, bytearray([channel, 4, 1]))
tries = 0
while rsp != 1 and tries < 30:
sys.stdout.write('.')
sys.stdout.flush()
tries += 1
time.sleep(0.5)
rsp = int(s.raw_command(0xc, 2, bytearray([channel, 4, 0, 0]))['data'][1]) & 0b1111
sys.stdout.write('Complete')
sys.stdout.write('Complete\n')
sys.stdout.flush()
print('Setting IP to {}'.format(oipaddr))
s.raw_command(0xc, 1, bytearray([channel, 3]) + ipaddr)
@@ -321,7 +324,9 @@ def main():
vendor = open('/sys/devices/virtual/dmi/id/sys_vendor').read()
vendor = vendor.strip()
try:
model = open('/sys/devices/virtual/dmi/id/product_sku').read()
model = open('/sys/devices/virtual/dmi/id/product_sku').read().strip()
if model == 'none':
raise Exception('No SKU')
except Exception:
model = open('/sys/devices/virtual/dmi/id/product_name').read()
if vendor in ('Lenovo', 'IBM'):
@@ -169,6 +169,7 @@ def set_port_tsm(s, port, model):
raise Exception("Unsupported port for TSM")
timer = 15
while timer:
timer = timer - 1
time.sleep(1.0)
sys.stdout.write('.')
sys.stdout.flush()
@@ -178,7 +179,7 @@ def set_port_tsm(s, port, model):
elif port == 'dedicated':
iface = 1
s.raw_command(0x32, 0x71, b'\x00\x01\x03')
rsp = s.raw_command(0x32, 0x72, bytearray(4, iface, 0))
rsp = s.raw_command(0x32, 0x72, bytearray([4, iface, 0]))
print('Complete')
return int(rsp['data'][0])
@@ -261,16 +262,18 @@ def set_ipv4(s, ipaddr, channel):
return
rsp = int(s.raw_command(0xc, 2, bytearray([channel, 4, 0, 0]))['data'][1]) & 0b1111
if rsp != 1:
sys.stdout.print("Changing configuration to static...")
sys.stdout.write("Changing configuration to static...")
sys.stdout.flush()
resp = s.raw_command(0xc, 1, bytearray([channel, 4, 1]))
tries = 0
while rsp != 1 and tries < 30:
sys.stdout.write('.')
sys.stdout.flush()
tries += 1
time.sleep(0.5)
rsp = int(s.raw_command(0xc, 2, bytearray([channel, 4, 0, 0]))['data'][1]) & 0b1111
sys.stdout.write('Complete')
sys.stdout.write('Complete\n')
sys.stdout.flush()
print('Setting IP to {}'.format(oipaddr))
s.raw_command(0xc, 1, bytearray([channel, 3]) + ipaddr)
@@ -321,7 +324,9 @@ def main():
vendor = open('/sys/devices/virtual/dmi/id/sys_vendor').read()
vendor = vendor.strip()
try:
model = open('/sys/devices/virtual/dmi/id/product_sku').read()
model = open('/sys/devices/virtual/dmi/id/product_sku').read().strip()
if model == 'none':
raise Exception('No SKU')
except Exception:
model = open('/sys/devices/virtual/dmi/id/product_name').read()
if vendor in ('Lenovo', 'IBM'):
+2 -2
View File
@@ -51,6 +51,7 @@ int main(int argc, char* argv[]) {
} else {
exit(0);
}
ttyf = open(buff, O_RDWR | O_NOCTTY);
if (currspeed == SPEED9600) {
cspeed = B9600;
strcpy(offset, ",9600");
@@ -66,8 +67,6 @@ int main(int argc, char* argv[]) {
} else {
exit(0);
}
printf("%s\n", buff);
ttyf = open(buff, O_RDWR | O_NOCTTY);
tcgetattr(ttyf, &tty);
if (cspeed) {
cfsetospeed(&tty, B115200);
@@ -75,6 +74,7 @@ int main(int argc, char* argv[]) {
}
tcsetattr(ttyf, TCSANOW, &tty);
ioctl(ttyf, TIOCCONS, 0);
printf("%s\n", buff);
}
+1 -1
View File
@@ -114,7 +114,7 @@ def local_node_trust_setup():
'IgnoreRhosts no'])
if domain and not myname.endswith(domain):
myprincipals.add('{0}.{1}'.format(myname, domain))
if '.' in myname and myname.endswith(domain):
if domain and '.' in myname and myname.endswith(domain):
myprincipals.add(myname.split('.')[0])
for pubkey in glob.glob('/etc/ssh/ssh_host_*_key.pub'):
currpubkey = open(pubkey, 'rb').read()
@@ -209,14 +209,14 @@ node = {
},
'deployment.useinsecureprotocols': {
'description': ('What phase(s) of boot are permitted to use insecure protocols '
'(TFTP and HTTP without TLS. By default, HTTPS is allowed. However '
'(TFTP and HTTP without TLS. By default, only HTTPS is used. However '
'this is not compatible with most firmware in most scenarios. Using '
'"firmware" as the setting will still use HTTPS after the initial download, '
'though be aware that a successful compromise during the firmware phase '
'though be aware that a successful attack during the firmware phase '
'will negate future TLS protections. The value "always" will result in '
'tftp/http being used for entire deployment. Note that ONIE does not '
'support secure protocols, and in that case this setting must be "always" '
'or "firmware"'),
'tftp/http being used for most of the deployment. The value "never" will '
'allow HTTPS only. Note that Ubuntu will still use HTTP without TLS for '
'a phase of the installation process.'),
'validlist': ('always', 'firmware', 'never'),
},
'discovery.passwordrules': {
+12 -4
View File
@@ -81,6 +81,7 @@ import confluent.noderange as noderange
import confluent.util as util
import eventlet
import traceback
import socket as nsocket
webclient = eventlet.import_patched('pyghmi.util.webclient')
@@ -206,13 +207,16 @@ def uuid_is_valid(uuid):
'00112233-4455-6677-8899-aabbccddeeff',
'20202020-2020-2020-2020-202020202020')
def _printable_ip(sa):
return nsocket.getnameinfo(
sa, nsocket.NI_NUMERICHOST|nsocket.NI_NUMERICSERV)[0]
def send_discovery_datum(info):
addresses = info.get('addresses', [])
if info['handler'] == pxeh:
enrich_pxe_info(info)
yield msg.KeyValueData({'nodename': info.get('nodename', '')})
yield msg.KeyValueData({'ipaddrs': [x[0] for x in addresses]})
yield msg.KeyValueData({'ipaddrs': [_printable_ip(x) for x in addresses]})
sn = info.get('serialnumber', '')
mn = info.get('modelnumber', '')
uuid = info.get('uuid', '')
@@ -1016,9 +1020,13 @@ def eval_node(cfg, handler, info, nodename, manual=False):
if nl:
# The candidate nodename is the head of a chain, we must
# validate the smm certificate by the switch
macmap.get_node_fingerprint(nodename, cfg)
util.handler.cert_matches(fprint, handler.https_cert)
return
fprints = macmap.get_node_fingerprints(nodename, cfg)
for fprint in fprints:
if util.cert_matches(fprint[0], handler.https_cert):
if not discover_node(cfg, handler, info,
nodename, manual):
pending_nodes[nodename] = info
return
if (info.get('maccount', False) and
not handler.discoverable_by_switch(info['maccount'])):
errorstr = 'The detected node {0} was detected using switch, ' \
@@ -14,13 +14,14 @@
import errno
import eventlet
import socket
webclient = eventlet.import_patched('pyghmi.util.webclient')
class NodeHandler(object):
https_supported = True
is_enclosure = False
devname = ''
maxmacs = 2 # reasonable default, allowing for common scenario of
maxmacs = 3 # reasonable default, allowing for common scenario of
# shared nic in theory, but blocking enclosure managers
# and uplink ports
@@ -38,7 +39,8 @@ class NodeHandler(object):
else:
if info.get('addresses', False):
targsa = info['addresses'][0]
self.ipaddr = targsa[0]
self.ipaddr = socket.getnameinfo(
targsa, socket.NI_NUMERICHOST|socket.NI_NUMERICSERV)[0]
@classmethod
def adequate(cls, info):
@@ -120,4 +122,4 @@ class NodeHandler(object):
except Exception:
self._certfailreason = 2
return None
return self._fp
return self._fp
@@ -16,6 +16,7 @@ import confluent.discovery.handlers.generic as generic
import confluent.exceptions as exc
import confluent.netutil as netutil
import confluent.util as util
import eventlet
import eventlet.support.greendns
import json
try:
@@ -85,7 +86,24 @@ class NodeHandler(generic.NodeHandler):
'username': self.DEFAULT_USER
}
if authmode == 2:
rsp, status = wc.grab_json_response_with_status('/api/reset-pass', passchange)
passchange = {
'Password': self.targpass,
}
rwc = webclient.SecureHTTPConnection(
self.ipaddr, 443,
verifycallback=self.validate_cert)
rwc.set_basic_credentials(authdata['username'],
authdata['password'])
rwc.set_header('If-Match', '*')
rwc.set_header('Content-Type', 'application/json')
rsp, status = rwc.grab_json_response_with_status(
'/redfish/v1/AccountService/Accounts/1',
passchange, method='PATCH')
if status >= 200 and status < 300:
authdata['password'] = self.targpass
eventlet.sleep(10)
else:
raise Exception("Redfish may not have been ready yet")
else:
rsp, status = wc.grab_json_response_with_status('/api/reset-pass', urlencode(passchange))
authdata['password'] = self.targpass
@@ -441,7 +441,7 @@ def check_reply(node, info, packet, sock, cfg, reqview):
return
rqtype = packet[53][0]
insecuremode = cfd.get(node, {}).get('deployment.useinsecureprotocols',
'never')
{}).get('value', 'never')
if not insecuremode:
insecuremode = 'never'
if insecuremode == 'never' and not httpboot:
@@ -199,6 +199,7 @@ def _extract_neighbor_data_affluent(switch, user, password, cfm, lldpdata):
'port': record['localport'],
'peerid': peerid,
}
_extract_extended_desc(portdata, portdata['peerdescription'], True)
_neighbypeerid[peerid] = portdata
lldpdata[localport] = portdata
neighdata[switch] = lldpdata