mirror of
https://github.com/xcat2/confluent.git
synced 2026-09-05 20:47:57 +00:00
2af402b13c
Apply ruff's safe autofixes. The changes are mechanical and behaviour-preserving. Issues fixed: - F401: remove unused imports. - F841: drop unused local variables and assignments, including discarded await/return values, unused "except ... as e" bindings, and unused "with ... as name" targets. - F541: remove the f prefix from f-strings that contain no placeholders. - E711: compare against None with "is"/"is not" instead of "=="/"!=". - E712: test truthiness directly instead of comparing to True. - E713: use "x not in y" instead of "not x in y". - E714: use "is not" instead of "not ... is". - E731: convert lambdas bound to a name into def statements. - W291/W293: trim trailing whitespace on touched lines.
140 lines
5.3 KiB
Python
Executable File
140 lines
5.3 KiB
Python
Executable File
#!/usr/bin/python3
|
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
# Copyright 2017-2021 Lenovo
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
# This script demonstrates a strategy for redfish bmcs that
|
|
# dhcp to leverage the confluent switch scanning to help
|
|
# bootstrap such devices. Be aware of the uuid reformatting
|
|
# code, and determine if it is relevant for the target system
|
|
# in question. The normal thing would be to leave UUID as-is,
|
|
# but some implementations mangle it in a misunderstanding
|
|
# of 'wire format' UUID. Also, here xCAT is used as the
|
|
# 'dhcp helper', so that may need to be replaced with dnsmasq
|
|
# or direct isc dhcp code.
|
|
|
|
# Unfortunately, this is particular about the dhcp server,
|
|
# the user must know if the bmc in question mangles the uuid
|
|
# or not, and other such limitation make this difficult to blindly
|
|
# recommend, but hopefully can be useful reference material
|
|
|
|
|
|
import asyncio
|
|
import sys
|
|
sys.path.append('/opt/confluent/lib/python')
|
|
import aiohmi.util.webclient as webclient
|
|
import confluent.client as cli
|
|
import struct
|
|
import subprocess
|
|
import time
|
|
|
|
|
|
bmcsbyuuid = {}
|
|
async def checkfish(addr, mac):
|
|
wc = webclient.WebConnection(addr, 443, verifycallback=lambda x: True)
|
|
body = await wc.grab_json_response('/redfish/v1')
|
|
if not body:
|
|
return None
|
|
uuid = body.get('UUID', None)
|
|
if not uuid:
|
|
return None
|
|
#This part is needed if a bmc sticks 'wire format' uuid in the json body
|
|
#Should be skipped for bmcs that present it sanely
|
|
uuidparts = uuid.split('-')
|
|
uuidparts[0] = '{:08x}'.format(struct.unpack('!I', struct.pack('<I', int(uuidparts[0], 16)))[0])
|
|
uuidparts[1] = '{:04x}'.format(struct.unpack('!H', struct.pack('<H', int(uuidparts[1], 16)))[0])
|
|
uuidparts[2] = '{:04x}'.format(struct.unpack('!H', struct.pack('<H', int(uuidparts[2], 16)))[0])
|
|
uuid = '-'.join(uuidparts)
|
|
return (uuid, mac, addr)
|
|
|
|
|
|
async def probe_bmcs(mactonode, mactoips):
|
|
tasks = []
|
|
macs = []
|
|
for mac in sorted(mactonode):
|
|
tasks.append(checkfish(mactoips[mac], mac))
|
|
macs.append(mac)
|
|
results = await asyncio.gather(*tasks, return_exceptions=True)
|
|
for mac, result in zip(macs, results):
|
|
if isinstance(result, Exception):
|
|
sys.stderr.write('Failed to probe {}: {}\n'.format(
|
|
mactoips[mac], result))
|
|
continue
|
|
if result is None:
|
|
continue
|
|
uuid, mac, addr = result
|
|
if uuid in bmcsbyuuid:
|
|
bmcsbyuuid[uuid]['bmcs'][mac] = addr
|
|
else:
|
|
bmcsbyuuid[uuid] = {'bmcs': {mac: addr}}
|
|
|
|
|
|
if __name__ == '__main__':
|
|
with open('/var/lib/dhcpd/dhcpd.leases', 'r') as leasefile:
|
|
leases = leasefile.read()
|
|
inlease = False
|
|
currip = None
|
|
mactoips = {}
|
|
for line in leases.split('\n'):
|
|
if line.startswith('lease '):
|
|
currip = line.split()[1]
|
|
inlease = True
|
|
continue
|
|
if not inlease:
|
|
continue
|
|
if 'hardware ethernet' in line:
|
|
currmac = line.split()[-1].replace(';', '')
|
|
mactoips[currmac] = currip
|
|
currmac = None
|
|
currip = None
|
|
inlease = False
|
|
# warm up arp tables and fdb
|
|
pings = {}
|
|
for mac in mactoips:
|
|
pings[mac] = subprocess.Popen(['ping', '-c', '1', mactoips[mac]], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
for mac in pings:
|
|
ret = pings[mac].wait()
|
|
if ret != 0:
|
|
del mactoips[mac]
|
|
c = cli.Command()
|
|
list(c.update('/networking/macs/rescan', {'rescan': 'start'}))
|
|
scanning = True
|
|
mactonode = {}
|
|
while scanning:
|
|
for rsp in c.read('/networking/macs/rescan'):
|
|
scanning = rsp.get('scanning', True)
|
|
time.sleep(0.1)
|
|
for mac in mactoips:
|
|
macinfo = list(c.read('/networking/macs/by-mac/{}'.format(mac)))
|
|
for inf in macinfo:
|
|
if inf.get('possiblenode', None):
|
|
mactonode[mac] = inf['possiblenode']
|
|
asyncio.run(probe_bmcs(mactonode, mactoips))
|
|
for uuid in sorted(bmcsbyuuid):
|
|
macd = bmcsbyuuid[uuid]['bmcs']
|
|
macs = sorted(macd)
|
|
currnode = None
|
|
for mac in macs:
|
|
currnode = mactonode.get(mac, None)
|
|
if currnode:
|
|
break
|
|
print('Performing: nodeattrib {} id.uuid={} custom.bmcmac={} bmc={}'.format(currnode, uuid, macs[0], macd[macs[0]]))
|
|
list(c.update('/nodes/{}/attributes/current'.format(currnode), {'id.uuid': uuid, 'custom.bmcmac': macs[0], 'bmc': macd[macs[0]]}))
|
|
subprocess.check_call(['nodeadd', currnode + '-bmc', 'mac.mac=' + macs[0]])
|
|
subprocess.check_call(['makedhcp', currnode + '-bmc'])
|
|
subprocess.check_call(['nodeboot', currnode])
|
|
subprocess.check_call(['nodebmcreset', currnode])
|
|
list(c.update('/nodes/{}/attributes/current'.format(currnode), {'bmc': currnode + '-bmc'}))
|
|
|