#!/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 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('