mirror of
https://github.com/xcat2/confluent.git
synced 2024-11-22 01:22:00 +00:00
Assisted redfish bmc setup
This is a quick example script of using confluent switch scanning in conjunction with checking dhcp leases to handle some generic redfish bmc.
This commit is contained in:
parent
6c32630bd9
commit
9afa33d0cc
120
misc/cfg-dhcp-redfish-bmcs-by-switch.py
Executable file
120
misc/cfg-dhcp-redfish-bmcs-by-switch.py
Executable file
@ -0,0 +1,120 @@
|
||||
#!/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.
|
||||
|
||||
import sys
|
||||
sys.path.append('/opt/confluent/lib/python')
|
||||
import confluent.client as cli
|
||||
import eventlet.greenpool
|
||||
import gzip
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
import struct
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
webclient = eventlet.import_patched('pyghmi.util.webclient')
|
||||
|
||||
|
||||
bmcsbyuuid = {}
|
||||
def checkfish(addr, mac):
|
||||
wc = webclient.SecureHTTPConnection(addr, 443, verifycallback=lambda x: True)
|
||||
wc.connect()
|
||||
wc.request('GET', '/redfish/v1')
|
||||
rsp = wc.getresponse()
|
||||
body = rsp.read()
|
||||
if body[:2] == b'\x1f\x8b':
|
||||
body = gzip.GzipFile(fileobj=io.BytesIO(body)).read()
|
||||
try:
|
||||
body = json.loads(body)
|
||||
except json.decoder.JSONDecodeError:
|
||||
return
|
||||
uuid = body.get('UUID', None)
|
||||
if not uuid:
|
||||
return
|
||||
#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)
|
||||
if uuid in bmcsbyuuid:
|
||||
bmcsbyuuid[uuid]['bmcs'][mac] = addr
|
||||
else:
|
||||
bmcsbyuuid[uuid] = {'bmcs': {mac: addr}}
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
gpool = eventlet.greenpool.GreenPool()
|
||||
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']
|
||||
for mac in sorted(mactonode):
|
||||
gpool.spawn(checkfish, mactoips[mac], mac)
|
||||
gpool.waitall()
|
||||
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'}))
|
||||
|
Loading…
Reference in New Issue
Block a user