def get_xname_status(xname, auth_token): dbgPrint(dbgMed, "get_xname_status") postHeaders = { 'Authorization': 'Bearer %s' % auth_token, 'cache-control': 'no-cache', 'Content-Type': 'application/json', } payload = { 'xnames': [xname], } URL = "https://api-gw-service-nmn.local/apis/capmc/capmc/v1/get_xname_status" dbgPrint(dbgMed, "POST: %s %s %s" % (URL, postHeaders, payload)) r = requests.post(url = URL, headers = postHeaders, data = json.dumps(payload)) dbgPrint(dbgMed, "Response: %s" % r.text) label = "" msg = "" if r.status_code >= 500: label = "CAPMC" msg = "Internal CAPMC Error" elif r.status_code >= 400: label = xname msg = "Bad Request" elif r.status_code >= 300: label = "CAPMC" msg = "URI redirection" if r.status_code >= 300: printError("get_xname_status") printExtraError(label, msg) return 1 status = json.loads(r.text) err = status['e'] if err < 0: printError("get_xname_status") printExtraError(xname, "Could not talk to BMC, undefined") return 1 printOK("get_xname_status") return 0
def checkRedfishChassis(bmcName): dbgPrint(dbgMed, "checkRedfishChassis") badResults = 0 path = "https://" + bmcName + "/redfish/v1/Chassis" dbgPrint(dbgMed, "checkRedfishChassis checking " + path) payload, label, msg = makeRedfishCall("GET", path) if not payload: printError("checkRedfishChassis") printExtraError(label, msg) return 1 response = json.loads(payload) if "Members" not in response: printError("checkRedfishChassis") printExtraError(path + " .Members", "missing") return 1 for member in response["Members"]: path = "https://" + bmcName + member["@odata.id"] dbgPrint(dbgMed, "checkRedfishChassis checking " + path) payload, label, msg = makeRedfishCall("GET", path) if not payload: printError("checkRedfishChassis") printExtraError(label, msg) badResults += 1 continue mResponse = json.loads(payload) if ("ChassisType" in mResponse and (mResponse["ChassisType"] == "Enclosure" or mResponse["ChassisType"] == "RackMount")): for check in chassisURIs: badResults += validateField("checkRedfishChassis", member["@odata.id"], check[FIELD], mResponse, check[TYPE]) else: printInfo("checkRedfishChassis") printExtraInfo("Skipping " + member["@odata.id"], "URI is for a " + mResponse["ChassisType"]) if badResults == 0: printOK("checkRedfishChassis") return badResults
def checkRedfishSystems(bmcName): fname = "checkRedfishSystems" dbgPrint(dbgMed, fname) badResults = 0 path = "https://" + bmcName + "/redfish/v1/Systems" dbgPrint(dbgMed, fname + " checking " + path) payload, label, msg = makeRedfishCall("GET", path) if not payload: printError(fname) printExtraError(label, msg) return 1 response = json.loads(payload) if "Members" not in response: printError(fname) printExtraError(path + " .Members", "missing") return 1 for member in response["Members"]: path = "https://" + bmcName + member["@odata.id"] dbgPrint(dbgMed, fname + " checking " + path) payload, label, msg = makeRedfishCall("GET", path) if not payload: printError(fname) printExtraError(label, msg) badResults += 1 continue mResponse = json.loads(payload) for check in systemsURIs: badResults += validateField(fname, member["@odata.id"], check[FIELD], mResponse, check[TYPE]) if check[FIELD] == "Memory" and check[FIELD] in mResponse: badResults += checkRedfishSystemsMemory( bmcName, mResponse[check[FIELD]]["@odata.id"]) if check[FIELD] == "Processors" and check[FIELD] in mResponse: badResults += checkRedfishSystemsProcessors( bmcName, mResponse[check[FIELD]]["@odata.id"]) if badResults == 0: printOK(fname) return badResults
def nidsToXnames(nidlist): dbgPrint(dbgMed, "nidsToXnames") auth_token = getAuthenticationToken() getHeaders = { 'Authorization': 'Bearer %s' % auth_token, 'cache-control': 'no-cache', } queryparams = {} queryparams['nid'] = [] for n in nidlist.split(','): queryparams['nid'].append(int(n)) URL = "https://api-gw-service-nmn.local/apis/smd/hsm/v1/State/Components" dbgPrint(dbgMed, "POST: %s %s" % (URL, queryparams)) dbgPrint(dbgHigh, "POST: %s" % getHeaders) r = requests.get(url=URL, headers=getHeaders, params=queryparams) dbgPrint(dbgMed, "Response: %s" % r.text) if r.status_code >= 300: return 1 components = json.loads(r.text) xnames = None for comp in components['Components']: if xnames is None: xnames = comp['ID'] else: xnames = xnames + ',' + comp['ID'] return xnames
def checkRedfishManagers(bmcName): dbgPrint(dbgMed, "checkRedfishManagers") badResults = 0 path = "https://" + bmcName + "/redfish/v1/Managers" dbgPrint(dbgMed, "checkRedfishManagers checking " + path) payload, label, msg = makeRedfishCall("GET", path) if not payload: printError("checkRedfishManagers") printExtraError(label, msg) return 1 response = json.loads(payload) if "Members" not in response: printError("checkRedfishManagers") printExtraError(path + " .Members", "missing") return 1 for member in response["Members"]: path = "https://" + bmcName + member["@odata.id"] dbgPrint(dbgMed, "checkRedfishManagers checking " + path) payload, label, msg = makeRedfishCall("GET", path) if not payload: printError("checkRedfishManagers") printExtraError(label, msg) badResults += 1 continue mResponse = json.loads(payload) for check in managerURIs: badResults += validateField("checkRedfishManagers", member["@odata.id"], check[FIELD], mResponse, check[TYPE]) if badResults == 0: printOK("checkRedfishManagers") return badResults
def getNid(xname, auth_token): dbgPrint(dbgMed, "getNid") getHeaders = { 'Authorization': 'Bearer %s' % auth_token, 'cache-control': 'no-cache', } URL = "https://api-gw-service-nmn.local/apis/smd/hsm/v1/State/Components/" + xname dbgPrint(dbgMed, "POST: %s %s" % (URL, getHeaders)) r = requests.get(url = URL, headers = getHeaders) dbgPrint(dbgMed, "Response: %s" % r.text) if r.status_code >= 300: return 1 comp = json.loads(r.text) return comp['NID']
def capmc(xname, tests=None, list=False, args=None): dbgPrint(dbgMed, "capmc") if list: return validations auth_token = getAuthenticationToken() failures = 0 if tests: for t in tests: for test in validations: if t == test.__name__: dbgPrint(dbgMed, "Calling: capmc:%s" % test.__name__) ret = test(xname, auth_token) failures = failures + ret else: for test in validations: dbgPrint(dbgMed, "Calling: capmc:%s" % test.__name__) ret = test(xname, auth_token) failures = failures + ret return failures
def redfish(xname, tests=None, list=False, args=None): dbgPrint(dbgMed, "redfish") if list: return validations if not args: printError("redfish") printExtraError(xname, "Missing arguments") return 1 if not args.user or not args.passwd: printError("redfish") printExtraError(xname, "Missing credentials") return 1 bmcName = convertXnameToBMCName(xname) if not bmcName: printWarning("redfish") printExtraWarning(xname, "Could not determine BMC name") failures = 0 if tests: for t in tests: for test in validations: if t == test.__name__: dbgPrint(dbgMed, "Calling: redfish:%s" % test.__name__) ret = test(bmcName) failures = failures + ret else: for test in validations: dbgPrint(dbgMed, "Calling: redfish:%s" % test.__name__) ret = test(bmcName) failures = failures + ret return failures
def getK8sClient(): dbgPrint(dbgMed, "getK8sClient") return k8sClient
def get_power_cap_capabilities(xname, auth_token): dbgPrint(dbgMed, "get_power_cap_capabilities") global capMin global capMax nid = getNid(xname, auth_token) if nid < 0: printError("get_power_cap_capabilities") printExtraError(xname, "Could not get nid") return 1 postHeaders = { 'Authorization': 'Bearer %s' % auth_token, 'cache-control': 'no-cache', 'Content-Type': 'application/json', } payload = { 'nids': [nid], } URL = "https://api-gw-service-nmn.local/apis/capmc/capmc/v1/get_power_cap_capabilities" dbgPrint(dbgMed, "POST: %s %s %s" % (URL, postHeaders, payload)) r = requests.post(url = URL, headers = postHeaders, data = json.dumps(payload)) dbgPrint(dbgMed, "Response: %s" % r.text) if r.status_code >= 500: label = "CAPMC" msg = "Internal CAPMC Error" elif r.status_code >= 400: label = xname msg = "Bad Request" elif r.status_code >= 300: label = "CAPMC" msg = "URI redirection" if r.status_code >= 300: printError("get_power_cap_capabilities") printExtraError(label, msg) return 1 capInfo = json.loads(r.text) group = capInfo['groups'][0] if group['controls']: control = None for tmp in group['controls']: if tmp['name'].startswith('Node'): control = tmp break if control != None: capMax = control['max'] capMin = control['min'] supply = group['supply'] if capMax == 0: if supply == 0: printError("get_power_cap_capabilities") printExtraError("min", capMin) printExtraError("max", capMax) printExtraError("supply", supply) return 1 else: capMax = supply printOK("get_power_cap_capabilities") return 0
def get_node_energy_counter(xname, auth_token): dbgPrint(dbgMed, "get_node_energy_counter") nid = getNid(xname, auth_token) if nid < 0: printError("get_node_energy_stats") printExtraError(xname, "Could not get nid") return 1 postHeaders = { 'Authorization': 'Bearer %s' % auth_token, 'cache-control': 'no-cache', 'Content-Type': 'application/json', } etime = datetime.today() stime = etime - timedelta(hours=1) payload = { 'nids': [nid], 'start_time': stime.strftime('%Y-%m-%d %H:%M:%S'), 'end_time': etime.strftime('%Y-%m-%d %H:%M:%S'), } URL = "https://api-gw-service-nmn.local/apis/capmc/capmc/v1/get_node_energy_counter" dbgPrint(dbgMed, "POST: %s %s %s" % (URL, postHeaders, payload)) r = requests.post(url = URL, headers = postHeaders, data = json.dumps(payload)) dbgPrint(dbgMed, "Response: %s" % r.text) label = "" msg = "" if r.status_code >= 500: label = "CAPMC" msg = "Internal CAPMC Error" elif r.status_code >= 400: label = xname msg = "Bad Request" elif r.status_code >= 300: label = "CAPMC" msg = "URI redirection" if r.status_code >= 300: printError("get_node_energy_counter") printExtraError(label, msg) return 1 energyInfo = json.loads(r.text) err = energyInfo['e'] if err > 0: printError("get_node_energy_counter") printExtraError(xname, "No data in time window") return 1 energy = energyInfo['nodes'][0]['energy_ctr'] if energy <= 0: printError("get_node_energy_counter") printExtraError("energy_ctr", energy) return 1 printOK("get_node_energy_counter") return 0
def set_power_cap(xname, auth_token): dbgPrint(dbgMed, "set_power_cap") if capMax == 0: printError("set_power_cap") printExtraError("Invalid max cap value", capMax) return 1 nid = getNid(xname, auth_token) if nid < 0: printError("set_power_cap") printExtraError(xname, "Could not get nid") return 1 # Get and save original value postHeaders = { 'Authorization': 'Bearer %s' % auth_token, 'cache-control': 'no-cache', 'Content-Type': 'application/json', } payload = { 'nids': [nid], } URL = "https://api-gw-service-nmn.local/apis/capmc/capmc/v1/get_power_cap" dbgPrint(dbgMed, "POST: %s %s %s" % (URL, postHeaders, payload)) r = requests.post(url = URL, headers = postHeaders, data = json.dumps(payload)) dbgPrint(dbgMed, "Response: %s" % r.text) if r.status_code >= 500: label = "CAPMC" msg = "Internal CAPMC Error" elif r.status_code >= 400: label = xname msg = "Bad Request" elif r.status_code >= 300: label = "CAPMC" msg = "URI redirection" if r.status_code >= 300: printError("set_power_cap") printExtraError(label, msg) return 1 capInfo = json.loads(r.text) err = capInfo['e'] if err != 0: printError("set_power_cap") printExtraError(xname, "Node not in the Ready state") return 1 origVal = extract_power_cap_val(capInfo) if origVal is not None and origVal <= 0: printError("set_power_cap") printExtraError("value", origVal) return 1 # Verify in range if origVal is not None and (origVal < capMin or origVal > capMax): printError("set_power_cap") printExtraError("value", origVal) return 1 # Set to (max - 10) postHeaders = { 'Authorization': 'Bearer %s' % auth_token, 'cache-control': 'no-cache', 'Content-Type': 'application/json', } capVal = capMax - 10 payload = { 'nids': [{'controls': [{'name': 'node', 'val': capVal}], 'nid': nid}], } URL = "https://api-gw-service-nmn.local/apis/capmc/capmc/v1/set_power_cap" dbgPrint(dbgMed, "POST: %s %s %s" % (URL, postHeaders, payload)) r = requests.post(url = URL, headers = postHeaders, data = json.dumps(payload)) dbgPrint(dbgMed, "Response: %s" % r.text) if r.status_code >= 500: label = "CAPMC" msg = "Internal CAPMC Error" elif r.status_code >= 400: label = xname msg = "Bad Request" elif r.status_code >= 300: label = "CAPMC" msg = "URI redirection" if r.status_code >= 300: printError("set_power_cap") printExtraError(label, msg) return 1 capInfo = json.loads(r.text) err = capInfo['e'] if err != 0: printError("set_power_cap") printExtraError(xname, capInfo['nids'][0]['err_msg']) return 1 # Get postHeaders = { 'Authorization': 'Bearer %s' % auth_token, 'cache-control': 'no-cache', 'Content-Type': 'application/json', } payload = { 'nids': [nid], } URL = "https://api-gw-service-nmn.local/apis/capmc/capmc/v1/get_power_cap" dbgPrint(dbgMed, "POST: %s %s %s" % (URL, postHeaders, payload)) r = requests.post(url = URL, headers = postHeaders, data = json.dumps(payload)) dbgPrint(dbgMed, "Response: %s" % r.text) if r.status_code >= 500: label = "CAPMC" msg = "Internal CAPMC Error" elif r.status_code >= 400: label = xname msg = "Bad Request" elif r.status_code >= 300: label = "CAPMC" msg = "URI redirection" if r.status_code >= 300: printError("set_power_cap") printExtraError(label, msg) return 1 capInfo = json.loads(r.text) err = capInfo['e'] if err != 0: printError("set_power_cap") printExtraError(xname, "Node not in the Ready state") return 1 setVal = extract_power_cap_val(capInfo) if setVal is not None and setVal <= 0: printError("set_power_cap") printExtraError("value", setVal) return 1 # Verify avg of min/max if setVal != capVal: printError("set_power_cap") printExtraError("set value", setVal) printExtraError("expected value", capVal) return 1 # Set original value postHeaders = { 'Authorization': 'Bearer %s' % auth_token, 'cache-control': 'no-cache', 'Content-Type': 'application/json', } if origVal is None: capVal = 0 else: capVal = origVal payload = { 'nids': [{'controls': [{'name': 'node', 'val': capVal}], 'nid': nid}], } URL = "https://api-gw-service-nmn.local/apis/capmc/capmc/v1/set_power_cap" dbgPrint(dbgMed, "POST: %s %s %s" % (URL, postHeaders, payload)) r = requests.post(url = URL, headers = postHeaders, data = json.dumps(payload)) dbgPrint(dbgMed, "Response: %s" % r.text) if r.status_code >= 500: label = "CAPMC" msg = "Internal CAPMC Error" elif r.status_code >= 400: label = xname msg = "Bad Request" elif r.status_code >= 300: label = "CAPMC" msg = "URI redirection" if r.status_code >= 300: printError("set_power_cap") printExtraError(label, msg) return 1 printOK("set_power_cap") return 0
def get_power_cap(xname, auth_token): dbgPrint(dbgMed, "get_power_cap") nid = getNid(xname, auth_token) if nid < 0: printError("get_power_cap") printExtraError(xname, "Could not get nid") return 1 postHeaders = { 'Authorization': 'Bearer %s' % auth_token, 'cache-control': 'no-cache', 'Content-Type': 'application/json', } payload = { 'nids': [nid], } URL = "https://api-gw-service-nmn.local/apis/capmc/capmc/v1/get_power_cap" dbgPrint(dbgMed, "POST: %s %s %s" % (URL, postHeaders, payload)) r = requests.post(url = URL, headers = postHeaders, data = json.dumps(payload)) dbgPrint(dbgMed, "Response: %s" % r.text) if r.status_code >= 500: label = "CAPMC" msg = "Internal CAPMC Error" elif r.status_code >= 400: label = xname msg = "Bad Request" elif r.status_code >= 300: label = "CAPMC" msg = "URI redirection" if r.status_code >= 300: printError("get_power_cap") printExtraError(label, msg) return 1 capInfo = json.loads(r.text) err = capInfo['e'] if err != 0: printError("get_power_cap") printExtraError(xname, capInfo['nids'][0]['err_msg']) return 1 val = capInfo['nids'][0]['controls'][0]['val'] if val is not None and val <= 0: printError("get_power_cap") printExtraError("value", val) return 1 printOK("get_power_cap") return 0
def capmc(xname, tests=None, list=False, args=None): dbgPrint(dbgMed, "capmc") if list: return validations auth_token = getAuthenticationToken() failures = 0 if tests: for t in tests: for test in validations: if t == test.__name__: dbgPrint(dbgMed, "Calling: capmc:%s" % test.__name__) ret = test(xname, auth_token) failures = failures + ret else: for test in validations: dbgPrint(dbgMed, "Calling: capmc:%s" % test.__name__) ret = test(xname, auth_token) failures = failures + ret return failures if __name__ == "__main__": setDbgLevel(dbgLow) dbgPrint(dbgLow, "Calling: capmc(%s, %s, %s)" % (sys.argv[1], sys.argv[2], sys.argv[3])) exit(capmc(sys.argv[1], sys.argv[2], sys.argv[3]))
def eventTest(bmcName): dbgPrint(dbgMed, "eventTest") global event hostPath = "https://" + bmcName path = hostPath + "/redfish/v1/Chassis" payload, label, msg = makeRedfishCall("GET", path) if not payload: printError("telemetryPoll") printExtraError(label, msg) return 1 chassisList = json.loads(payload) chassis = chassisList['Members'][0] testEvent = {} path = hostPath + "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent" if isGigabyte(chassis['@odata.id']): evID = randrange(10000, 99999) testEvent = { "EventTimestamp": "2020-05-26T23:04:09+02:00", "EventId": evID, "OriginOfCondition": "/redfish/v1/Chassis/Self", "MessageId": "PropertyValueNotInList", "MessageArgs": ["Lit", "IndicatorLED"], "Severity": "Warning" } elif isHPERiver(chassis['@odata.id']): testEvent = { 'EventID': 'Test Event', 'Severity': 'OK', 'EventType': 'StatusChange', 'OriginOfCondition': 'Test', 'EventTimestamp': str(datetime.datetime.now()), 'MessageArgs': [], 'Message': 'This is a test event', 'MessageId': 'TestMsg.v0' } elif isHPEMountain(chassis['@odata.id']): printInfo("eventValidate") printExtraInfo("Test Event", "Not supported") return 1 if httpd is None: startRedfishEventServer() payload, label, msg = makeRedfishCall("POST", path, json.dumps(testEvent)) if not payload: printError("eventValidate") printExtraError(label, msg) return 1 if event.wait(timeout=30): printOK("eventValidate") return 0 else: printError("eventValidate") printExtraError("event", "timed out waiting for Redfish test event") return 1
def telemetryPoll(bmcName): dbgPrint(dbgMed, "telemetryPoll") hostPath = "https://" + bmcName path = hostPath + "/redfish/v1/Chassis" payload, label, msg = makeRedfishCall("GET", path) if not payload: printError("telemetryPoll") printExtraError(label, msg) return 1 chassisList = json.loads(payload) badResults = 0 for chassis in chassisList['Members']: chassisPath = hostPath + chassis['@odata.id'] path = chassisPath + "/Power" payload, label, msg = makeRedfishCall("GET", path) if not payload: printError("telemetryPoll power") printExtraError(label, msg) return 1 Power = json.loads(payload) path = chassisPath + "/Thermal" payload, label, msg = makeRedfishCall("GET", path) if not payload: printError("telemetryPoll thermal") printExtraError(label, msg) return 1 Thermal = json.loads(payload) # Gigabyte # /Power # .PowerControl.PowerMetrics.AverageConsumedWatts # .Voltages[].ReadingVolts # /Thermal # .Fans[].Reading # .Temperatures[].ReadingCelsius if isGigabyte(chassis['@odata.id']): ret = checkAvgConsumedWatts(Power) if ret != 0: printError("telemetryPoll power") printExtraError(bmcName, "AverageConsumedWatts missing") badResults += 1 ret = checkVoltages(Power) if ret != 0: printError("telemetryPoll power") printExtraError(bmcName, "Voltages missing") badResults += 1 ret = checkFans(Thermal) if ret != 0: printError("telemetryPoll thermal") printExtraError(bmcName, "Fans missing") badResults += 1 ret = checkTemps(Thermal) if ret != 0: printError("telemetryPoll thermal") printExtraError(bmcName, "Temperatures missing") badResults += 1 # HPE - Mountain (we don't poll, but check what we can) # /Power # .Voltages[].ReadingVolts # /Thermal # .Temperatures[].ReadingCelsius if isHPEMountain(chassis['@odata.id']): ret = checkVoltages(Power) if ret != 0: printError("telemetryPoll power") printExtraError(bmcName, "Voltages missing") badResults += 1 ret = checkTemps(Thermal) if ret != 0: printError("telemetryPoll thermal") printExtraError(bmcName, "Temperatures missing") badResults += 1 # HPE - River # /Power # .PowerControl.PowerMetrics.AverageConsumedWatts # .PowerSupplies[].LineInputVoltage # /Thermal # .Fans[].Reading # .Temperatures[].ReadingCelsius if isHPERiver(chassis['@odata.id']): ret = checkAvgConsumedWatts(Power) if ret != 0: printError("telemetryPoll power") printExtraError(bmcName, "AverageConsumedWatts missing") badResults += 1 ret = checkLineVoltages(Power) if ret != 0: printError("telemetryPoll power") printExtraError(bmcName, "Voltages missing") badResults += 1 ret = checkFans(Thermal) if ret != 0: printError("telemetryPoll thermal") printExtraError(bmcName, "Fans missing") badResults += 1 ret = checkTemps(Thermal) if ret != 0: printError("telemetryPoll thermal") printExtraError(bmcName, "Temperatures missing") badResults += 1 if badResults == 0: printOK("telemetryPoll") return badResults
def printOK(msg): r""" printOK(msg) - Prints the message with an OK """ dbgPrint(dbgLow, "\033[1;32m%-50s\tOK\033[0m" % msg)
def makeRedfishCall(action, targPath, reqData=None): dbgPrint(dbgMed, "makeRedfishCall %s: %s %s" % (action, targPath, reqData)) # Until certificates are being used to talk to Redfish endpoints the basic # auth method will be used. To do so, SSL verification needs to be turned # off which results in a InsecureRequestWarning. The following line # disables only the IsnsecureRequestWarning. urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) rfUser = config.rfUser rfPass = config.rfPass if action == "GET": getHeaders = { 'cache-control': 'no-cache', } r = requests.get(url=targPath, headers=getHeaders, auth=HTTPBasicAuth(rfUser, rfPass), verify=False) elif action == "POST": postHeaders = { 'cache-control': 'no-cache', 'Content-Type': 'application/json', } r = requests.post(url=targPath, headers=postHeaders, data=reqData, auth=HTTPBasicAuth(rfUser, rfPass), verify=False) elif action == "DELETE": deleteHeaders = { 'cache-control': 'no-cache', } r = requests.delete(url=targPath, headers=deleteHeaders, auth=HTTPBasicAuth(rfUser, rfPass), verify=False) else: return None, "Redfish Operation", "Bad Request" dbgPrint(dbgMed, "makeRedfishCall %s complete" % action) dbgPrint(dbgHigh, "makeRedfishCall %s Response: %s" % (action, r.text)) ret = r.text if not ret: ret = r.status_code label = "" msg = "" if r.status_code >= 500: label = "Redfish" msg = "Internal Redfish Error" ret = None elif r.status_code >= 400: label = targPath msg = "Bad Request (%d)" % r.status_code ret = None elif r.status_code >= 300: label = "Redfish" msg = "URI redirection" ret = None return ret, label, msg
def printExtraError(label, msg): r""" printExtraHealth(label, msg) - Prints a label and then the message """ dbgPrint(dbgLow, "\033[1;31m%50s\t%s\033[0m" % (label, msg))
def printExtraInfo(label, msg): r""" printExtraInfo(label, msg) - Prints a label and then the message """ dbgPrint(dbgLow, "\033[1;35m%50s\t%s\033[0m" % (label, msg))
def main(): parser = argparse.ArgumentParser( description='Automatic hardware validation tool.') parser.add_argument( '-l', '--list', help='List modules and tests that are available. all: show all ' 'modules and tests, top: show top level modules, <module>: show ' 'tests for the module') parser.add_argument( '-x', '--xnames', help='Xnames to do hardware validation on. Valid options are a ' 'single xname, comma separated xnames, or hostlist style xnames') parser.add_argument( '-n', '--nids', help='Nids to do hardware validation on. Valid options are a ' 'single nid, comma separated nids, or hostlist style nids: ' '[1-10]') parser.add_argument( '-i', '--ips', help='IPs to do hardware validation on. Valid options are a ' 'single IP, comma separated IPs, or hostlist style IPs: ' '10.1.100.[1-36]') parser.add_argument('-t', '--tests', help='List of tests to execute in the form ' '<module>[:<test>][,<module>[:<test>][,...]]') parser.add_argument('-v', '--verbose', action="count", default=0, help='Increase output verbosity.') parser.add_argument('-V', '--version', action="store_true", help='Print the script version information and exit.') parser.add_argument( '-u', '--user', help='Username for Redfish validation. All --xnames must have the ' 'same username for their BMC.') parser.add_argument( '-p', '--passwd', help='Password for Redfish validation. All --xnames must have the ' 'same password for their BMC.') args = parser.parse_args() if args.version is True: script_dir = path.dirname(__file__) filename = ".version" with open(script_dir + "/" + filename, "r") as ver: print("%s: %s" % (__file__, ver.read())) return 0 if args.verbose: setDbgLevel(args.verbose) if args.list: if args.list == "all" or args.list == "top": for pkg in hwValidationModule: print("%s" % pkg.__name__) if args.list == "all": tests = pkg(None, None, True) for t in tests: print(" %s" % t.__name__) else: for pkg in hwValidationModule: if pkg.__name__ == args.list: print("%s" % pkg.__name__) tests = pkg(None, None, True) for t in tests: print(" %s" % t.__name__) return 0 if args.xnames is None and args.nids is None and args.ips is None: parser.print_usage() print("%s: error: missing argument" % path.basename(__file__)) return 1 xnames = None if args.nids is not None: nids = expand(args.nids) xnames = nidsToXnames(nids) if args.xnames is not None: if xnames is not None: args.xnames = args.xnames + ',' + xnames xnames = expand(args.xnames) if args.ips is not None: if xnames is not None: args.ips = args.ips + ',' + xnames xnames = expand(args.ips) dbgPrint(dbgMed, "Nodes to validate: %s" % xnames) # Convert into a list and remove duplicates xnames = xnames.split(',') xnames_set = set(xnames) xnames = (list(xnames_set)) tests = {} if args.tests: pairs = args.tests.split(',') for p in pairs: kv = p.split(':') if kv[0] not in tests: tests[kv[0]] = [] if len(kv) == 1: for pkg in hwValidationModule: if pkg.__name__ == kv[0]: pkgTests = pkg(None, None, True) for t in pkgTests: tests[kv[0]].append(t.__name__) else: tests[kv[0]].append(kv[1]) dbgPrint(dbgMed, "Tests to execute: %s" % tests) failures = 0 config.rfUser = args.user config.rfPass = args.passwd for xname in xnames: if tests: for m in tests.keys(): for module in hwValidationModule: if m == module.__name__: print("\033[1;36m%s(%s):\033[0m" % (module.__name__, xname)) ret = module(xname, tests[m], None, args) failures = failures + ret else: for module in hwValidationModule: print("\033[1;36m%s(%s):\033[0m" % (module.__name__, xname)) ret = module(xname, None, False, args) failures = failures + ret if failures == 0: print("All validations PASSED") else: print("%d Validations did not pass cleanly" % failures) print("Done") return 0
bmcName = convertXnameToBMCName(xname) if not bmcName: printWarning("redfish") printExtraWarning(xname, "Could not determine BMC name") failures = 0 if tests: for t in tests: for test in validations: if t == test.__name__: dbgPrint(dbgMed, "Calling: redfish:%s" % test.__name__) ret = test(bmcName) failures = failures + ret else: for test in validations: dbgPrint(dbgMed, "Calling: redfish:%s" % test.__name__) ret = test(bmcName) failures = failures + ret return failures if __name__ == "__main__": setDbgLevel(dbgLow) dbgPrint( dbgLow, "Calling: redfish(%s, %s, %s)" % (sys.argv[1], sys.argv[2], sys.argv[3])) exit(redfish(sys.argv[1], sys.argv[2], sys.argv[3]))