169419bafSAndrew Jeffery#!/usr/bin/python3 269419bafSAndrew Jeffery""" 369419bafSAndrew Jeffery Copyright 2017,2019 IBM Corporation 469419bafSAndrew Jeffery 569419bafSAndrew Jeffery Licensed under the Apache License, Version 2.0 (the "License"); 669419bafSAndrew Jeffery you may not use this file except in compliance with the License. 769419bafSAndrew Jeffery You may obtain a copy of the License at 869419bafSAndrew Jeffery 969419bafSAndrew Jeffery http://www.apache.org/licenses/LICENSE-2.0 1069419bafSAndrew Jeffery 1169419bafSAndrew Jeffery Unless required by applicable law or agreed to in writing, software 1269419bafSAndrew Jeffery distributed under the License is distributed on an "AS IS" BASIS, 1369419bafSAndrew Jeffery WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1469419bafSAndrew Jeffery See the License for the specific language governing permissions and 1569419bafSAndrew Jeffery limitations under the License. 1669419bafSAndrew Jeffery""" 1769419bafSAndrew Jefferyimport argparse 1869419bafSAndrew Jefferyimport requests 1969419bafSAndrew Jefferyimport getpass 2069419bafSAndrew Jefferyimport json 2169419bafSAndrew Jefferyimport os 2269419bafSAndrew Jefferyimport urllib3 2369419bafSAndrew Jefferyimport time, datetime 2469419bafSAndrew Jefferyimport binascii 2569419bafSAndrew Jefferyimport subprocess 2669419bafSAndrew Jefferyimport platform 2769419bafSAndrew Jefferyimport zipfile 2869419bafSAndrew Jefferyimport tarfile 2969419bafSAndrew Jefferyimport tempfile 3069419bafSAndrew Jefferyimport hashlib 3169419bafSAndrew Jefferyimport re 3269419bafSAndrew Jefferyimport uuid 3369419bafSAndrew Jefferyimport ssl 3469419bafSAndrew Jefferyimport socket 3569419bafSAndrew Jefferyimport select 3669419bafSAndrew Jefferyimport http.client 3769419bafSAndrew Jefferyfrom subprocess import check_output 3869419bafSAndrew Jefferyimport traceback 3969419bafSAndrew Jeffery 4069419bafSAndrew Jeffery 4169419bafSAndrew JefferyMAX_NBD_PACKET_SIZE = 131088 4269419bafSAndrew JefferyjsonHeader = {'Content-Type' : 'application/json'} 4369419bafSAndrew JefferyxAuthHeader = {} 4469419bafSAndrew JefferybaseTimeout = 60 4569419bafSAndrew JefferyserverTypeMap = { 4669419bafSAndrew Jeffery 'ActiveDirectory' : 'active_directory', 4769419bafSAndrew Jeffery 'OpenLDAP' : 'openldap' 4869419bafSAndrew Jeffery } 4969419bafSAndrew Jeffery 5069419bafSAndrew Jefferyclass NBDPipe: 5169419bafSAndrew Jeffery 5269419bafSAndrew Jeffery def openHTTPSocket(self,args): 5369419bafSAndrew Jeffery 5469419bafSAndrew Jeffery try: 5569419bafSAndrew Jeffery _create_unverified_https_context = ssl._create_unverified_context 5669419bafSAndrew Jeffery except AttributeError: 5769419bafSAndrew Jeffery # Legacy Python that doesn't verify HTTPS certificates by default 5869419bafSAndrew Jeffery pass 5969419bafSAndrew Jeffery else: 6069419bafSAndrew Jeffery # Handle target environment that doesn't support HTTPS verification 6169419bafSAndrew Jeffery ssl._create_default_https_context = _create_unverified_https_context 6269419bafSAndrew Jeffery 6369419bafSAndrew Jeffery 6469419bafSAndrew Jeffery token = gettoken(args) 6569419bafSAndrew Jeffery self.conn = http.client.HTTPSConnection(args.host,port=443) 6669419bafSAndrew Jeffery 6769419bafSAndrew Jeffery uri = "/redfish/v1/Systems/system/LogServices/Dump/attachment/"+args.dumpNum 6869419bafSAndrew Jeffery 6969419bafSAndrew Jeffery self.conn.request("GET",uri, headers={"X-Auth-Token":token}) 7069419bafSAndrew Jeffery 7169419bafSAndrew Jeffery def openTCPSocket(self): 7269419bafSAndrew Jeffery # Create a TCP/IP socket 7369419bafSAndrew Jeffery self.tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 7469419bafSAndrew Jeffery # Connect the socket to the port where the server is listening 7569419bafSAndrew Jeffery server_address = ('localhost', 1043) 7669419bafSAndrew Jeffery self.tcp.connect(server_address) 7769419bafSAndrew Jeffery 7869419bafSAndrew Jeffery def waitformessage(self): 7969419bafSAndrew Jeffery inputs = [self.conn.sock,self.tcp] 8069419bafSAndrew Jeffery outputs = [] 8169419bafSAndrew Jeffery message_queues = {} 8269419bafSAndrew Jeffery while True: 8369419bafSAndrew Jeffery readable, writable, exceptional = select.select( 8469419bafSAndrew Jeffery inputs, outputs, inputs) 8569419bafSAndrew Jeffery 8669419bafSAndrew Jeffery for s in readable: 8769419bafSAndrew Jeffery if s is self.conn.sock: 8869419bafSAndrew Jeffery 8969419bafSAndrew Jeffery data = self.conn.sock.recv(MAX_NBD_PACKET_SIZE) 9069419bafSAndrew Jeffery print("<<HTTP") 9169419bafSAndrew Jeffery if data: 9269419bafSAndrew Jeffery self.tcp.send(data) 9369419bafSAndrew Jeffery else: 9469419bafSAndrew Jeffery print ("BMC Closed the connection") 9569419bafSAndrew Jeffery self.conn.close() 9669419bafSAndrew Jeffery self.tcp.close() 9769419bafSAndrew Jeffery sys.exit(1) 9869419bafSAndrew Jeffery elif s is self.tcp: 9969419bafSAndrew Jeffery data = self.tcp.recv(MAX_NBD_PACKET_SIZE) 10069419bafSAndrew Jeffery print(">>TCP") 10169419bafSAndrew Jeffery if data: 10269419bafSAndrew Jeffery self.conn.sock.send(data) 10369419bafSAndrew Jeffery else: 10469419bafSAndrew Jeffery print("NBD server closed the connection") 10569419bafSAndrew Jeffery self.conn.sock.close() 10669419bafSAndrew Jeffery self.tcp.close() 10769419bafSAndrew Jeffery sys.exit(1) 10869419bafSAndrew Jeffery for s in exceptional: 10969419bafSAndrew Jeffery inputs.remove(s) 11069419bafSAndrew Jeffery print("Exceptional closing the socket") 11169419bafSAndrew Jeffery s.close() 11269419bafSAndrew Jeffery 11369419bafSAndrew Jefferydef getsize(host,args,session): 11469419bafSAndrew Jeffery url = "https://"+host+"/redfish/v1/Systems/system/LogServices/Dump/Entries/"+str(args.dumpNum) 11569419bafSAndrew Jeffery try: 11669419bafSAndrew Jeffery resp = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 11769419bafSAndrew Jeffery if resp.status_code==200: 1184e178110SAsmitha Karunanithi size = resp.json()['AdditionalDataSizeBytes'] 11969419bafSAndrew Jeffery return size 12069419bafSAndrew Jeffery else: 12169419bafSAndrew Jeffery return "Failed get Size" 12269419bafSAndrew Jeffery except(requests.exceptions.Timeout): 12369419bafSAndrew Jeffery return connectionErrHandler(args.json, "Timeout", None) 12469419bafSAndrew Jeffery 12569419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 12669419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 12769419bafSAndrew Jeffery 12869419bafSAndrew Jefferydef gettoken(args): 12969419bafSAndrew Jeffery mysess = requests.session() 13069419bafSAndrew Jeffery resp = mysess.post('https://'+args.host+'/login', headers=jsonHeader,json={"data":[args.user,args.PW]},verify=False) 13169419bafSAndrew Jeffery if resp.status_code == 200: 13269419bafSAndrew Jeffery cookie = resp.headers['Set-Cookie'] 133*d6125fd1SGunnar Mills match = re.search('BMCWEB-SESSION=(\w+);', cookie) 13469419bafSAndrew Jeffery return match.group(1) 13569419bafSAndrew Jeffery 13669419bafSAndrew Jeffery 13769419bafSAndrew Jeffery 13869419bafSAndrew Jefferydef get_pid(name): 13969419bafSAndrew Jeffery try: 14069419bafSAndrew Jeffery pid = map(int, check_output(["pidof", "-s",name])) 14169419bafSAndrew Jeffery except Exception: 14269419bafSAndrew Jeffery pid = 0 14369419bafSAndrew Jeffery 14469419bafSAndrew Jeffery return pid 14569419bafSAndrew Jeffery 14669419bafSAndrew Jefferydef findThisProcess( process_name ): 14769419bafSAndrew Jeffery ps = subprocess.Popen("ps -eaf | grep "+process_name, shell=True, stdout=subprocess.PIPE) 14869419bafSAndrew Jeffery output = ps.stdout.read() 14969419bafSAndrew Jeffery ps.stdout.close() 15069419bafSAndrew Jeffery ps.wait() 15169419bafSAndrew Jeffery pid = get_pid(process_name) 15269419bafSAndrew Jeffery return output 15369419bafSAndrew Jeffery 15469419bafSAndrew Jefferydef isThisProcessRunning( process_name ): 15569419bafSAndrew Jeffery pid = get_pid(process_name) 15669419bafSAndrew Jeffery if (pid == 0 ): 15769419bafSAndrew Jeffery return False 15869419bafSAndrew Jeffery else: 15969419bafSAndrew Jeffery return True 16069419bafSAndrew Jeffery 16169419bafSAndrew Jefferydef NBDSetup(host,args,session): 16269419bafSAndrew Jeffery user=os.getenv("SUDO_USER") 16369419bafSAndrew Jeffery if user is None: 16469419bafSAndrew Jeffery path = os.getcwd() 16569419bafSAndrew Jeffery nbdServerPath = path + "/nbd-server" 16669419bafSAndrew Jeffery if not os.path.exists(nbdServerPath): 16769419bafSAndrew Jeffery print("Error: this program did not run as sudo!\nplease copy nbd-server to current directory and run script again") 16869419bafSAndrew Jeffery exit() 16969419bafSAndrew Jeffery 17069419bafSAndrew Jeffery if isThisProcessRunning('nbd-server') == True: 17169419bafSAndrew Jeffery print("nbd-server already Running! killing the nbd-server") 17269419bafSAndrew Jeffery os.system('killall nbd-server') 17369419bafSAndrew Jeffery 17469419bafSAndrew Jeffery if (args.dumpSaveLoc is not None): 17569419bafSAndrew Jeffery if(os.path.exists(args.dumpSaveLoc)): 17669419bafSAndrew Jeffery print("Error: File already exists.") 17769419bafSAndrew Jeffery exit() 17869419bafSAndrew Jeffery 17969419bafSAndrew Jeffery fp= open(args.dumpSaveLoc,"w") 18069419bafSAndrew Jeffery sizeInBytes = getsize(host,args,session) 18169419bafSAndrew Jeffery #Round off size to mutiples of 1024 18269419bafSAndrew Jeffery size = int(sizeInBytes) 18369419bafSAndrew Jeffery mod = size % 1024 18469419bafSAndrew Jeffery if mod : 18569419bafSAndrew Jeffery roundoff = 1024 - mod 18669419bafSAndrew Jeffery size = size + roundoff 18769419bafSAndrew Jeffery 18869419bafSAndrew Jeffery cmd = 'chmod 777 ' + args.dumpSaveLoc 18969419bafSAndrew Jeffery os.system(cmd) 19069419bafSAndrew Jeffery 19169419bafSAndrew Jeffery #Run truncate to create file with given size 19269419bafSAndrew Jeffery cmd = 'truncate -s ' + str(size) + ' '+ args.dumpSaveLoc 19369419bafSAndrew Jeffery os.system(cmd) 19469419bafSAndrew Jeffery 19569419bafSAndrew Jeffery if user is None: 19669419bafSAndrew Jeffery cmd = './nbd-server 1043 '+ args.dumpSaveLoc 19769419bafSAndrew Jeffery else: 19869419bafSAndrew Jeffery cmd = 'nbd-server 1043 '+ args.dumpSaveLoc 19969419bafSAndrew Jeffery os.system(cmd) 20069419bafSAndrew Jeffery 20169419bafSAndrew Jeffery 20269419bafSAndrew Jefferydef hilight(textToColor, color, bold): 20369419bafSAndrew Jeffery """ 20469419bafSAndrew Jeffery Used to add highlights to various text for displaying in a terminal 20569419bafSAndrew Jeffery 20669419bafSAndrew Jeffery @param textToColor: string, the text to be colored 20769419bafSAndrew Jeffery @param color: string, used to color the text red or green 20869419bafSAndrew Jeffery @param bold: boolean, used to bold the textToColor 20969419bafSAndrew Jeffery @return: Buffered reader containing the modified string. 21069419bafSAndrew Jeffery """ 21169419bafSAndrew Jeffery if(sys.platform.__contains__("win")): 21269419bafSAndrew Jeffery if(color == "red"): 21369419bafSAndrew Jeffery os.system('color 04') 21469419bafSAndrew Jeffery elif(color == "green"): 21569419bafSAndrew Jeffery os.system('color 02') 21669419bafSAndrew Jeffery else: 21769419bafSAndrew Jeffery os.system('color') #reset to default 21869419bafSAndrew Jeffery return textToColor 21969419bafSAndrew Jeffery else: 22069419bafSAndrew Jeffery attr = [] 22169419bafSAndrew Jeffery if(color == "red"): 22269419bafSAndrew Jeffery attr.append('31') 22369419bafSAndrew Jeffery elif(color == "green"): 22469419bafSAndrew Jeffery attr.append('32') 22569419bafSAndrew Jeffery else: 22669419bafSAndrew Jeffery attr.append('0') 22769419bafSAndrew Jeffery if bold: 22869419bafSAndrew Jeffery attr.append('1') 22969419bafSAndrew Jeffery else: 23069419bafSAndrew Jeffery attr.append('0') 23169419bafSAndrew Jeffery return '\x1b[%sm%s\x1b[0m' % (';'.join(attr),textToColor) 23269419bafSAndrew Jeffery 23369419bafSAndrew Jefferydef connectionErrHandler(jsonFormat, errorStr, err): 23469419bafSAndrew Jeffery """ 23569419bafSAndrew Jeffery Error handler various connection errors to bmcs 23669419bafSAndrew Jeffery 23769419bafSAndrew Jeffery @param jsonFormat: boolean, used to output in json format with an error code. 23869419bafSAndrew Jeffery @param errorStr: string, used to color the text red or green 23969419bafSAndrew Jeffery @param err: string, the text from the exception 24069419bafSAndrew Jeffery """ 24169419bafSAndrew Jeffery if errorStr == "Timeout": 24269419bafSAndrew Jeffery if not jsonFormat: 24369419bafSAndrew Jeffery return("FQPSPIN0000M: Connection timed out. Ensure you have network connectivity to the bmc") 24469419bafSAndrew Jeffery else: 24569419bafSAndrew Jeffery conerror = {} 24669419bafSAndrew Jeffery conerror['CommonEventID'] = 'FQPSPIN0000M' 24769419bafSAndrew Jeffery conerror['sensor']="N/A" 24869419bafSAndrew Jeffery conerror['state']="N/A" 24969419bafSAndrew Jeffery conerror['additionalDetails'] = "N/A" 25069419bafSAndrew Jeffery conerror['Message']="Connection timed out. Ensure you have network connectivity to the BMC" 25169419bafSAndrew Jeffery conerror['LengthyDescription'] = "While trying to establish a connection with the specified BMC, the BMC failed to respond in adequate time. Verify the BMC is functioning properly, and the network connectivity to the BMC is stable." 25269419bafSAndrew Jeffery conerror['Serviceable']="Yes" 25369419bafSAndrew Jeffery conerror['CallHomeCandidate']= "No" 25469419bafSAndrew Jeffery conerror['Severity'] = "Critical" 25569419bafSAndrew Jeffery conerror['EventType'] = "Communication Failure/Timeout" 25669419bafSAndrew Jeffery conerror['VMMigrationFlag'] = "Yes" 25769419bafSAndrew Jeffery conerror["AffectedSubsystem"] = "Interconnect (Networking)" 25869419bafSAndrew Jeffery conerror["timestamp"] = str(int(time.time())) 25969419bafSAndrew Jeffery conerror["UserAction"] = "Verify network connectivity between the two systems and the bmc is functional." 26069419bafSAndrew Jeffery eventdict = {} 26169419bafSAndrew Jeffery eventdict['event0'] = conerror 26269419bafSAndrew Jeffery eventdict['numAlerts'] = '1' 26369419bafSAndrew Jeffery errorMessageStr = errorMessageStr = json.dumps(eventdict, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False) 26469419bafSAndrew Jeffery return(errorMessageStr) 26569419bafSAndrew Jeffery elif errorStr == "ConnectionError": 26669419bafSAndrew Jeffery if not jsonFormat: 26769419bafSAndrew Jeffery return("FQPSPIN0001M: " + str(err)) 26869419bafSAndrew Jeffery else: 26969419bafSAndrew Jeffery conerror = {} 27069419bafSAndrew Jeffery conerror['CommonEventID'] = 'FQPSPIN0001M' 27169419bafSAndrew Jeffery conerror['sensor']="N/A" 27269419bafSAndrew Jeffery conerror['state']="N/A" 27369419bafSAndrew Jeffery conerror['additionalDetails'] = str(err) 27469419bafSAndrew Jeffery conerror['Message']="Connection Error. View additional details for more information" 27569419bafSAndrew Jeffery conerror['LengthyDescription'] = "A connection error to the specified BMC occurred and additional details are provided. Review these details to resolve the issue." 27669419bafSAndrew Jeffery conerror['Serviceable']="Yes" 27769419bafSAndrew Jeffery conerror['CallHomeCandidate']= "No" 27869419bafSAndrew Jeffery conerror['Severity'] = "Critical" 27969419bafSAndrew Jeffery conerror['EventType'] = "Communication Failure/Timeout" 28069419bafSAndrew Jeffery conerror['VMMigrationFlag'] = "Yes" 28169419bafSAndrew Jeffery conerror["AffectedSubsystem"] = "Interconnect (Networking)" 28269419bafSAndrew Jeffery conerror["timestamp"] = str(int(time.time())) 28369419bafSAndrew Jeffery conerror["UserAction"] = "Correct the issue highlighted in additional details and try again" 28469419bafSAndrew Jeffery eventdict = {} 28569419bafSAndrew Jeffery eventdict['event0'] = conerror 28669419bafSAndrew Jeffery eventdict['numAlerts'] = '1' 28769419bafSAndrew Jeffery errorMessageStr = json.dumps(eventdict, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False) 28869419bafSAndrew Jeffery return(errorMessageStr) 28969419bafSAndrew Jeffery 29069419bafSAndrew Jeffery else: 29169419bafSAndrew Jeffery return("Unknown Error: "+ str(err)) 29269419bafSAndrew Jeffery 29369419bafSAndrew Jeffery 29469419bafSAndrew Jefferydef setColWidth(keylist, numCols, dictForOutput, colNames): 29569419bafSAndrew Jeffery """ 29669419bafSAndrew Jeffery Sets the output width of the columns to display 29769419bafSAndrew Jeffery 29869419bafSAndrew Jeffery @param keylist: list, list of strings representing the keys for the dictForOutput 29969419bafSAndrew Jeffery @param numcols: the total number of columns in the final output 30069419bafSAndrew Jeffery @param dictForOutput: dictionary, contains the information to print to the screen 30169419bafSAndrew Jeffery @param colNames: list, The strings to use for the column headings, in order of the keylist 30269419bafSAndrew Jeffery @return: A list of the column widths for each respective column. 30369419bafSAndrew Jeffery """ 30469419bafSAndrew Jeffery colWidths = [] 30569419bafSAndrew Jeffery for x in range(0, numCols): 30669419bafSAndrew Jeffery colWidths.append(0) 30769419bafSAndrew Jeffery for key in dictForOutput: 30869419bafSAndrew Jeffery for x in range(0, numCols): 30969419bafSAndrew Jeffery colWidths[x] = max(colWidths[x], len(str(dictForOutput[key][keylist[x]]))) 31069419bafSAndrew Jeffery 31169419bafSAndrew Jeffery for x in range(0, numCols): 31269419bafSAndrew Jeffery colWidths[x] = max(colWidths[x], len(colNames[x])) +2 31369419bafSAndrew Jeffery 31469419bafSAndrew Jeffery return colWidths 31569419bafSAndrew Jeffery 31669419bafSAndrew Jefferydef loadPolicyTable(pathToPolicyTable): 31769419bafSAndrew Jeffery """ 31869419bafSAndrew Jeffery loads a json based policy table into a dictionary 31969419bafSAndrew Jeffery 32069419bafSAndrew Jeffery @param value: boolean, the value to convert 32169419bafSAndrew Jeffery @return: A string of "Yes" or "No" 32269419bafSAndrew Jeffery """ 32369419bafSAndrew Jeffery policyTable = {} 32469419bafSAndrew Jeffery if(os.path.exists(pathToPolicyTable)): 32569419bafSAndrew Jeffery with open(pathToPolicyTable, 'r') as stream: 32669419bafSAndrew Jeffery try: 32769419bafSAndrew Jeffery contents =json.load(stream) 32869419bafSAndrew Jeffery policyTable = contents['events'] 32969419bafSAndrew Jeffery except Exception as err: 33069419bafSAndrew Jeffery print(err) 33169419bafSAndrew Jeffery return policyTable 33269419bafSAndrew Jeffery 33369419bafSAndrew Jeffery 33469419bafSAndrew Jefferydef boolToString(value): 33569419bafSAndrew Jeffery """ 33669419bafSAndrew Jeffery converts a boolean value to a human readable string value 33769419bafSAndrew Jeffery 33869419bafSAndrew Jeffery @param value: boolean, the value to convert 33969419bafSAndrew Jeffery @return: A string of "Yes" or "No" 34069419bafSAndrew Jeffery """ 34169419bafSAndrew Jeffery if(value): 34269419bafSAndrew Jeffery return "Yes" 34369419bafSAndrew Jeffery else: 34469419bafSAndrew Jeffery return "No" 34569419bafSAndrew Jeffery 34669419bafSAndrew Jefferydef stringToInt(text): 34769419bafSAndrew Jeffery """ 34869419bafSAndrew Jeffery returns an integer if the string can be converted, otherwise returns the string 34969419bafSAndrew Jeffery 35069419bafSAndrew Jeffery @param text: the string to try to convert to an integer 35169419bafSAndrew Jeffery """ 35269419bafSAndrew Jeffery if text.isdigit(): 35369419bafSAndrew Jeffery return int(text) 35469419bafSAndrew Jeffery else: 35569419bafSAndrew Jeffery return text 35669419bafSAndrew Jeffery 35769419bafSAndrew Jefferydef naturalSort(text): 35869419bafSAndrew Jeffery """ 35969419bafSAndrew Jeffery provides a way to naturally sort a list 36069419bafSAndrew Jeffery 36169419bafSAndrew Jeffery @param text: the key to convert for sorting 36269419bafSAndrew Jeffery @return list containing the broken up string parts by integers and strings 36369419bafSAndrew Jeffery """ 36469419bafSAndrew Jeffery stringPartList = [] 36569419bafSAndrew Jeffery for c in re.split('(\d+)', text): 36669419bafSAndrew Jeffery stringPartList.append(stringToInt(c)) 36769419bafSAndrew Jeffery return stringPartList 36869419bafSAndrew Jeffery 36969419bafSAndrew Jefferydef tableDisplay(keylist, colNames, output): 37069419bafSAndrew Jeffery """ 37169419bafSAndrew Jeffery Logs into the BMC and creates a session 37269419bafSAndrew Jeffery 37369419bafSAndrew Jeffery @param keylist: list, keys for the output dictionary, ordered by colNames 37469419bafSAndrew Jeffery @param colNames: Names for the Table of the columns 37569419bafSAndrew Jeffery @param output: The dictionary of data to display 37669419bafSAndrew Jeffery @return: Session object 37769419bafSAndrew Jeffery """ 37869419bafSAndrew Jeffery colWidth = setColWidth(keylist, len(colNames), output, colNames) 37969419bafSAndrew Jeffery row = "" 38069419bafSAndrew Jeffery outputText = "" 38169419bafSAndrew Jeffery for i in range(len(colNames)): 38269419bafSAndrew Jeffery if (i != 0): row = row + "| " 38369419bafSAndrew Jeffery row = row + colNames[i].ljust(colWidth[i]) 38469419bafSAndrew Jeffery outputText += row + "\n" 38569419bafSAndrew Jeffery 38669419bafSAndrew Jeffery output_keys = list(output.keys()) 38769419bafSAndrew Jeffery output_keys.sort(key=naturalSort) 38869419bafSAndrew Jeffery for key in output_keys: 38969419bafSAndrew Jeffery row = "" 39069419bafSAndrew Jeffery for i in range(len(keylist)): 39169419bafSAndrew Jeffery if (i != 0): row = row + "| " 39269419bafSAndrew Jeffery row = row + output[key][keylist[i]].ljust(colWidth[i]) 39369419bafSAndrew Jeffery outputText += row + "\n" 39469419bafSAndrew Jeffery 39569419bafSAndrew Jeffery return outputText 39669419bafSAndrew Jeffery 39769419bafSAndrew Jefferydef checkFWactivation(host, args, session): 39869419bafSAndrew Jeffery """ 39969419bafSAndrew Jeffery Checks the software inventory for an image that is being activated. 40069419bafSAndrew Jeffery 40169419bafSAndrew Jeffery @return: True if an image is being activated, false is no activations are happening 40269419bafSAndrew Jeffery """ 40369419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/software/enumerate" 40469419bafSAndrew Jeffery try: 40569419bafSAndrew Jeffery resp = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 40669419bafSAndrew Jeffery except(requests.exceptions.Timeout): 40769419bafSAndrew Jeffery print(connectionErrHandler(args.json, "Timeout", None)) 40869419bafSAndrew Jeffery return(True) 40969419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 41069419bafSAndrew Jeffery print( connectionErrHandler(args.json, "ConnectionError", err)) 41169419bafSAndrew Jeffery return True 41269419bafSAndrew Jeffery fwInfo = resp.json()['data'] 41369419bafSAndrew Jeffery for key in fwInfo: 41469419bafSAndrew Jeffery if 'Activation' in fwInfo[key]: 41569419bafSAndrew Jeffery if 'Activating' in fwInfo[key]['Activation'] or 'Activating' in fwInfo[key]['RequestedActivation']: 41669419bafSAndrew Jeffery return True 41769419bafSAndrew Jeffery return False 41869419bafSAndrew Jeffery 41969419bafSAndrew Jefferydef login(host, username, pw,jsonFormat, allowExpiredPassword): 42069419bafSAndrew Jeffery """ 42169419bafSAndrew Jeffery Logs into the BMC and creates a session 42269419bafSAndrew Jeffery 42369419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc to log into 42469419bafSAndrew Jeffery @param username: The user name for the bmc to log into 42569419bafSAndrew Jeffery @param pw: The password for the BMC to log into 42669419bafSAndrew Jeffery @param jsonFormat: boolean, flag that will only allow relevant data from user command to be display. This function becomes silent when set to true. 42769419bafSAndrew Jeffery @param allowExpiredPassword: true, if the requested operation should 42869419bafSAndrew Jeffery be allowed when the password is expired 42969419bafSAndrew Jeffery @return: Session object 43069419bafSAndrew Jeffery """ 43169419bafSAndrew Jeffery if(jsonFormat==False): 43269419bafSAndrew Jeffery print("Attempting login...") 43369419bafSAndrew Jeffery mysess = requests.session() 43469419bafSAndrew Jeffery try: 43569419bafSAndrew Jeffery r = mysess.post('https://'+host+'/login', headers=jsonHeader, json = {"data": [username, pw]}, verify=False, timeout=baseTimeout) 43669419bafSAndrew Jeffery if r.status_code == 200: 43769419bafSAndrew Jeffery cookie = r.headers['Set-Cookie'] 438*d6125fd1SGunnar Mills match = re.search('BMCWEB-SESSION=(\w+);', cookie) 43969419bafSAndrew Jeffery if match: 44069419bafSAndrew Jeffery xAuthHeader['X-Auth-Token'] = match.group(1) 44169419bafSAndrew Jeffery jsonHeader.update(xAuthHeader) 44269419bafSAndrew Jeffery loginMessage = json.loads(r.text) 44369419bafSAndrew Jeffery if (loginMessage['status'] != "ok"): 44469419bafSAndrew Jeffery print(loginMessage["data"]["description"].encode('utf-8')) 44569419bafSAndrew Jeffery sys.exit(1) 44669419bafSAndrew Jeffery if (('extendedMessage' in r.json()) and 44769419bafSAndrew Jeffery ('The password for this account must be changed' in r.json()['extendedMessage'])): 44869419bafSAndrew Jeffery if not allowExpiredPassword: 44969419bafSAndrew Jeffery print("The password for this system has expired and must be changed"+ 45069419bafSAndrew Jeffery "\nsee openbmctool.py set_password --help") 45169419bafSAndrew Jeffery logout(host, username, pw, mysess, jsonFormat) 45269419bafSAndrew Jeffery sys.exit(1) 45369419bafSAndrew Jeffery# if(sys.version_info < (3,0)): 45469419bafSAndrew Jeffery# urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) 45569419bafSAndrew Jeffery# if sys.version_info >= (3,0): 45669419bafSAndrew Jeffery# requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning) 45769419bafSAndrew Jeffery return mysess 45869419bafSAndrew Jeffery else: 45969419bafSAndrew Jeffery return None 46069419bafSAndrew Jeffery except(requests.exceptions.Timeout): 46169419bafSAndrew Jeffery return (connectionErrHandler(jsonFormat, "Timeout", None)) 46269419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 46369419bafSAndrew Jeffery return (connectionErrHandler(jsonFormat, "ConnectionError", err)) 46469419bafSAndrew Jeffery 46569419bafSAndrew Jeffery 46669419bafSAndrew Jefferydef logout(host, username, pw, session, jsonFormat): 46769419bafSAndrew Jeffery """ 46869419bafSAndrew Jeffery Logs out of the bmc and terminates the session 46969419bafSAndrew Jeffery 47069419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc to log out of 47169419bafSAndrew Jeffery @param username: The user name for the bmc to log out of 47269419bafSAndrew Jeffery @param pw: The password for the BMC to log out of 47369419bafSAndrew Jeffery @param session: the active session to use 47469419bafSAndrew Jeffery @param jsonFormat: boolean, flag that will only allow relevant data from user command to be display. This function becomes silent when set to true. 47569419bafSAndrew Jeffery """ 47669419bafSAndrew Jeffery try: 47769419bafSAndrew Jeffery r = session.post('https://'+host+'/logout', headers=jsonHeader,json = {"data": [username, pw]}, verify=False, timeout=baseTimeout) 47869419bafSAndrew Jeffery except(requests.exceptions.Timeout): 47969419bafSAndrew Jeffery print(connectionErrHandler(jsonFormat, "Timeout", None)) 48069419bafSAndrew Jeffery 48169419bafSAndrew Jeffery if(jsonFormat==False): 48269419bafSAndrew Jeffery if r.status_code == 200: 48369419bafSAndrew Jeffery print('User ' +username + ' has been logged out') 48469419bafSAndrew Jeffery 48569419bafSAndrew Jeffery 48669419bafSAndrew Jefferydef fru(host, args, session): 48769419bafSAndrew Jeffery """ 48869419bafSAndrew Jeffery prints out the system inventory. deprecated see fruPrint and fruList 48969419bafSAndrew Jeffery 49069419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 49169419bafSAndrew Jeffery @param args: contains additional arguments used by the fru sub command 49269419bafSAndrew Jeffery @param session: the active session to use 49369419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 49469419bafSAndrew Jeffery """ 49569419bafSAndrew Jeffery #url="https://"+host+"/org/openbmc/inventory/system/chassis/enumerate" 49669419bafSAndrew Jeffery 49769419bafSAndrew Jeffery #print(url) 49869419bafSAndrew Jeffery #res = session.get(url, headers=httpHeader, verify=False) 49969419bafSAndrew Jeffery #print(res.text) 50069419bafSAndrew Jeffery #sample = res.text 50169419bafSAndrew Jeffery 50269419bafSAndrew Jeffery #inv_list = json.loads(sample)["data"] 50369419bafSAndrew Jeffery 50469419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/inventory/enumerate" 50569419bafSAndrew Jeffery try: 50669419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 50769419bafSAndrew Jeffery except(requests.exceptions.Timeout): 50869419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 50969419bafSAndrew Jeffery 51069419bafSAndrew Jeffery sample = res.text 51169419bafSAndrew Jeffery# inv_list.update(json.loads(sample)["data"]) 51269419bafSAndrew Jeffery# 51369419bafSAndrew Jeffery# #determine column width's 51469419bafSAndrew Jeffery# colNames = ["FRU Name", "FRU Type", "Has Fault", "Is FRU", "Present", "Version"] 51569419bafSAndrew Jeffery# colWidths = setColWidth(["FRU Name", "fru_type", "fault", "is_fru", "present", "version"], 6, inv_list, colNames) 51669419bafSAndrew Jeffery# 51769419bafSAndrew Jeffery# print("FRU Name".ljust(colWidths[0])+ "FRU Type".ljust(colWidths[1]) + "Has Fault".ljust(colWidths[2]) + "Is FRU".ljust(colWidths[3])+ 51869419bafSAndrew Jeffery# "Present".ljust(colWidths[4]) + "Version".ljust(colWidths[5])) 51969419bafSAndrew Jeffery# format the output 52069419bafSAndrew Jeffery# for key in sorted(inv_list.keys()): 52169419bafSAndrew Jeffery# keyParts = key.split("/") 52269419bafSAndrew Jeffery# isFRU = "True" if (inv_list[key]["is_fru"]==1) else "False" 52369419bafSAndrew Jeffery# 52469419bafSAndrew Jeffery# fruEntry = (keyParts[len(keyParts) - 1].ljust(colWidths[0]) + inv_list[key]["fru_type"].ljust(colWidths[1])+ 52569419bafSAndrew Jeffery# inv_list[key]["fault"].ljust(colWidths[2])+isFRU.ljust(colWidths[3])+ 52669419bafSAndrew Jeffery# inv_list[key]["present"].ljust(colWidths[4])+ inv_list[key]["version"].ljust(colWidths[5])) 52769419bafSAndrew Jeffery# if(isTTY): 52869419bafSAndrew Jeffery# if(inv_list[key]["is_fru"] == 1): 52969419bafSAndrew Jeffery# color = "green" 53069419bafSAndrew Jeffery# bold = True 53169419bafSAndrew Jeffery# else: 53269419bafSAndrew Jeffery# color='black' 53369419bafSAndrew Jeffery# bold = False 53469419bafSAndrew Jeffery# fruEntry = hilight(fruEntry, color, bold) 53569419bafSAndrew Jeffery# print (fruEntry) 53669419bafSAndrew Jeffery return sample 53769419bafSAndrew Jeffery 53869419bafSAndrew Jefferydef fruPrint(host, args, session): 53969419bafSAndrew Jeffery """ 54069419bafSAndrew Jeffery prints out all inventory 54169419bafSAndrew Jeffery 54269419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 54369419bafSAndrew Jeffery @param args: contains additional arguments used by the fru sub command 54469419bafSAndrew Jeffery @param session: the active session to use 54569419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 54669419bafSAndrew Jeffery @return returns the total fru list. 54769419bafSAndrew Jeffery """ 54869419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/inventory/enumerate" 54969419bafSAndrew Jeffery try: 55069419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 55169419bafSAndrew Jeffery except(requests.exceptions.Timeout): 55269419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 55369419bafSAndrew Jeffery 55469419bafSAndrew Jeffery frulist={} 55569419bafSAndrew Jeffery# print(res.text) 55669419bafSAndrew Jeffery if res.status_code==200: 55769419bafSAndrew Jeffery frulist['Hardware'] = res.json()['data'] 55869419bafSAndrew Jeffery else: 55969419bafSAndrew Jeffery if not args.json: 56069419bafSAndrew Jeffery return "Error retrieving the system inventory. BMC message: {msg}".format(msg=res.json()['message']) 56169419bafSAndrew Jeffery else: 56269419bafSAndrew Jeffery return res.json() 56369419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/software/enumerate" 56469419bafSAndrew Jeffery try: 56569419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 56669419bafSAndrew Jeffery except(requests.exceptions.Timeout): 56769419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 56869419bafSAndrew Jeffery# print(res.text) 56969419bafSAndrew Jeffery if res.status_code==200: 57069419bafSAndrew Jeffery frulist['Software'] = res.json()['data'] 57169419bafSAndrew Jeffery else: 57269419bafSAndrew Jeffery if not args.json(): 57369419bafSAndrew Jeffery return "Error retrieving the system inventory. BMC message: {msg}".format(msg=res.json()['message']) 57469419bafSAndrew Jeffery else: 57569419bafSAndrew Jeffery return res.json() 57669419bafSAndrew Jeffery return frulist 57769419bafSAndrew Jeffery 57869419bafSAndrew Jeffery 57969419bafSAndrew Jefferydef fruList(host, args, session): 58069419bafSAndrew Jeffery """ 58169419bafSAndrew Jeffery prints out all inventory or only a specific specified item 58269419bafSAndrew Jeffery 58369419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 58469419bafSAndrew Jeffery @param args: contains additional arguments used by the fru sub command 58569419bafSAndrew Jeffery @param session: the active session to use 58669419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 58769419bafSAndrew Jeffery """ 58869419bafSAndrew Jeffery if(args.items==True): 58969419bafSAndrew Jeffery return fruPrint(host, args, session) 59069419bafSAndrew Jeffery else: 59169419bafSAndrew Jeffery return fruPrint(host, args, session) 59269419bafSAndrew Jeffery 59369419bafSAndrew Jeffery 59469419bafSAndrew Jeffery 59569419bafSAndrew Jefferydef fruStatus(host, args, session): 59669419bafSAndrew Jeffery """ 59769419bafSAndrew Jeffery prints out the status of all FRUs 59869419bafSAndrew Jeffery 59969419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 60069419bafSAndrew Jeffery @param args: contains additional arguments used by the fru sub command 60169419bafSAndrew Jeffery @param session: the active session to use 60269419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 60369419bafSAndrew Jeffery """ 60469419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/inventory/enumerate" 60569419bafSAndrew Jeffery try: 60669419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False) 60769419bafSAndrew Jeffery except(requests.exceptions.Timeout): 60869419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 60969419bafSAndrew Jeffery# print(res.text) 61069419bafSAndrew Jeffery frulist = res.json()['data'] 61169419bafSAndrew Jeffery frus = {} 61269419bafSAndrew Jeffery for key in frulist: 61369419bafSAndrew Jeffery component = frulist[key] 61469419bafSAndrew Jeffery isFru = False 61569419bafSAndrew Jeffery present = False 61669419bafSAndrew Jeffery func = False 61769419bafSAndrew Jeffery hasSels = False 61869419bafSAndrew Jeffery keyPieces = key.split('/') 61969419bafSAndrew Jeffery fruName = keyPieces[-1] 62069419bafSAndrew Jeffery if 'core' in fruName: #associate cores to cpus 62169419bafSAndrew Jeffery fruName = keyPieces[-2] + '-' + keyPieces[-1] 62269419bafSAndrew Jeffery if 'Functional' in component: 62369419bafSAndrew Jeffery if('Present' in component): 62469419bafSAndrew Jeffery if 'FieldReplaceable' in component: 62569419bafSAndrew Jeffery if component['FieldReplaceable'] == 1: 62669419bafSAndrew Jeffery isFru = True 62769419bafSAndrew Jeffery if "fan" in fruName: 62869419bafSAndrew Jeffery isFru = True; 62969419bafSAndrew Jeffery if component['Present'] == 1: 63069419bafSAndrew Jeffery present = True 63169419bafSAndrew Jeffery if component['Functional'] == 1: 63269419bafSAndrew Jeffery func = True 63369419bafSAndrew Jeffery if ((key + "/fault") in frulist): 63469419bafSAndrew Jeffery hasSels = True; 63569419bafSAndrew Jeffery if args.verbose: 63669419bafSAndrew Jeffery if hasSels: 63769419bafSAndrew Jeffery loglist = [] 63869419bafSAndrew Jeffery faults = frulist[key+"/fault"]['endpoints'] 63969419bafSAndrew Jeffery for item in faults: 64069419bafSAndrew Jeffery loglist.append(item.split('/')[-1]) 64169419bafSAndrew Jeffery frus[fruName] = {"compName": fruName, "Functional": boolToString(func), "Present":boolToString(present), "IsFru": boolToString(isFru), "selList": ', '.join(loglist).strip() } 64269419bafSAndrew Jeffery else: 64369419bafSAndrew Jeffery frus[fruName] = {"compName": fruName, "Functional": boolToString(func), "Present":boolToString(present), "IsFru": boolToString(isFru), "selList": "None" } 64469419bafSAndrew Jeffery else: 64569419bafSAndrew Jeffery frus[fruName] = {"compName": fruName, "Functional": boolToString(func), "Present":boolToString(present), "IsFru": boolToString(isFru), "hasSEL": boolToString(hasSels) } 64669419bafSAndrew Jeffery elif "power_supply" in fruName or "powersupply" in fruName: 64769419bafSAndrew Jeffery if component['Present'] ==1: 64869419bafSAndrew Jeffery present = True 64969419bafSAndrew Jeffery isFru = True 65069419bafSAndrew Jeffery if ((key + "/fault") in frulist): 65169419bafSAndrew Jeffery hasSels = True; 65269419bafSAndrew Jeffery if args.verbose: 65369419bafSAndrew Jeffery if hasSels: 65469419bafSAndrew Jeffery loglist = [] 65569419bafSAndrew Jeffery faults = frulist[key+"/fault"]['endpoints'] 65669419bafSAndrew Jeffery for item in faults: 65769419bafSAndrew Jeffery loglist.append(item.split('/')[-1]) 65869419bafSAndrew Jeffery frus[fruName] = {"compName": fruName, "Functional": "No", "Present":boolToString(present), "IsFru": boolToString(isFru), "selList": ', '.join(loglist).strip() } 65969419bafSAndrew Jeffery else: 66069419bafSAndrew Jeffery frus[fruName] = {"compName": fruName, "Functional": "Yes", "Present":boolToString(present), "IsFru": boolToString(isFru), "selList": "None" } 66169419bafSAndrew Jeffery else: 66269419bafSAndrew Jeffery frus[fruName] = {"compName": fruName, "Functional": boolToString(not hasSels), "Present":boolToString(present), "IsFru": boolToString(isFru), "hasSEL": boolToString(hasSels) } 66369419bafSAndrew Jeffery if not args.json: 66469419bafSAndrew Jeffery if not args.verbose: 66569419bafSAndrew Jeffery colNames = ["Component", "Is a FRU", "Present", "Functional", "Has Logs"] 66669419bafSAndrew Jeffery keylist = ["compName", "IsFru", "Present", "Functional", "hasSEL"] 66769419bafSAndrew Jeffery else: 66869419bafSAndrew Jeffery colNames = ["Component", "Is a FRU", "Present", "Functional", "Assoc. Log Number(s)"] 66969419bafSAndrew Jeffery keylist = ["compName", "IsFru", "Present", "Functional", "selList"] 67069419bafSAndrew Jeffery return tableDisplay(keylist, colNames, frus) 67169419bafSAndrew Jeffery else: 67269419bafSAndrew Jeffery return str(json.dumps(frus, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False)) 67369419bafSAndrew Jeffery 67469419bafSAndrew Jefferydef sensor(host, args, session): 67569419bafSAndrew Jeffery """ 67669419bafSAndrew Jeffery prints out all sensors 67769419bafSAndrew Jeffery 67869419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 67969419bafSAndrew Jeffery @param args: contains additional arguments used by the sensor sub command 68069419bafSAndrew Jeffery @param session: the active session to use 68169419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 68269419bafSAndrew Jeffery """ 68369419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/sensors/enumerate" 68469419bafSAndrew Jeffery try: 68569419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 68669419bafSAndrew Jeffery except(requests.exceptions.Timeout): 68769419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 68869419bafSAndrew Jeffery 68969419bafSAndrew Jeffery #Get OCC status 69069419bafSAndrew Jeffery url="https://"+host+"/org/open_power/control/enumerate" 69169419bafSAndrew Jeffery try: 69269419bafSAndrew Jeffery occres = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 69369419bafSAndrew Jeffery except(requests.exceptions.Timeout): 69469419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 69569419bafSAndrew Jeffery if not args.json: 69669419bafSAndrew Jeffery colNames = ['sensor', 'type', 'units', 'value', 'target'] 69769419bafSAndrew Jeffery sensors = res.json()["data"] 69869419bafSAndrew Jeffery output = {} 69969419bafSAndrew Jeffery for key in sensors: 70069419bafSAndrew Jeffery senDict = {} 70169419bafSAndrew Jeffery keyparts = key.split("/") 70269419bafSAndrew Jeffery 70369419bafSAndrew Jeffery # Associations like the following also show up here: 70469419bafSAndrew Jeffery # /xyz/openbmc_project/sensors/<type>/<name>/<assoc-name> 70569419bafSAndrew Jeffery # Skip them. 70669419bafSAndrew Jeffery # Note: keyparts[0] = '' which is why there are 7 segments. 70769419bafSAndrew Jeffery if len(keyparts) > 6: 70869419bafSAndrew Jeffery continue 70969419bafSAndrew Jeffery 71069419bafSAndrew Jeffery senDict['sensorName'] = keyparts[-1] 71169419bafSAndrew Jeffery senDict['type'] = keyparts[-2] 71269419bafSAndrew Jeffery try: 71369419bafSAndrew Jeffery senDict['units'] = sensors[key]['Unit'].split('.')[-1] 71469419bafSAndrew Jeffery except KeyError: 71569419bafSAndrew Jeffery senDict['units'] = "N/A" 71669419bafSAndrew Jeffery if('Scale' in sensors[key]): 71769419bafSAndrew Jeffery scale = 10 ** sensors[key]['Scale'] 71869419bafSAndrew Jeffery else: 71969419bafSAndrew Jeffery scale = 1 72069419bafSAndrew Jeffery try: 72169419bafSAndrew Jeffery senDict['value'] = str(sensors[key]['Value'] * scale) 72269419bafSAndrew Jeffery except KeyError: 72369419bafSAndrew Jeffery if 'value' in sensors[key]: 72469419bafSAndrew Jeffery senDict['value'] = sensors[key]['value'] 72569419bafSAndrew Jeffery else: 72669419bafSAndrew Jeffery senDict['value'] = "N/A" 72769419bafSAndrew Jeffery if 'Target' in sensors[key]: 72869419bafSAndrew Jeffery senDict['target'] = str(sensors[key]['Target']) 72969419bafSAndrew Jeffery else: 73069419bafSAndrew Jeffery senDict['target'] = 'N/A' 73169419bafSAndrew Jeffery output[senDict['sensorName']] = senDict 73269419bafSAndrew Jeffery 73369419bafSAndrew Jeffery occstatus = occres.json()["data"] 73469419bafSAndrew Jeffery if '/org/open_power/control/occ0' in occstatus: 73569419bafSAndrew Jeffery occ0 = occstatus["/org/open_power/control/occ0"]['OccActive'] 73669419bafSAndrew Jeffery if occ0 == 1: 73769419bafSAndrew Jeffery occ0 = 'Active' 73869419bafSAndrew Jeffery else: 73969419bafSAndrew Jeffery occ0 = 'Inactive' 74069419bafSAndrew Jeffery output['OCC0'] = {'sensorName':'OCC0', 'type': 'Discrete', 'units': 'N/A', 'value': occ0, 'target': 'Active'} 74169419bafSAndrew Jeffery occ1 = occstatus["/org/open_power/control/occ1"]['OccActive'] 74269419bafSAndrew Jeffery if occ1 == 1: 74369419bafSAndrew Jeffery occ1 = 'Active' 74469419bafSAndrew Jeffery else: 74569419bafSAndrew Jeffery occ1 = 'Inactive' 74669419bafSAndrew Jeffery output['OCC1'] = {'sensorName':'OCC1', 'type': 'Discrete', 'units': 'N/A', 'value': occ0, 'target': 'Active'} 74769419bafSAndrew Jeffery else: 74869419bafSAndrew Jeffery output['OCC0'] = {'sensorName':'OCC0', 'type': 'Discrete', 'units': 'N/A', 'value': 'Inactive', 'target': 'Inactive'} 74969419bafSAndrew Jeffery output['OCC1'] = {'sensorName':'OCC1', 'type': 'Discrete', 'units': 'N/A', 'value': 'Inactive', 'target': 'Inactive'} 75069419bafSAndrew Jeffery keylist = ['sensorName', 'type', 'units', 'value', 'target'] 75169419bafSAndrew Jeffery 75269419bafSAndrew Jeffery return tableDisplay(keylist, colNames, output) 75369419bafSAndrew Jeffery else: 75469419bafSAndrew Jeffery return res.text + occres.text 75569419bafSAndrew Jeffery 75669419bafSAndrew Jefferydef sel(host, args, session): 75769419bafSAndrew Jeffery """ 75869419bafSAndrew Jeffery prints out the bmc alerts 75969419bafSAndrew Jeffery 76069419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 76169419bafSAndrew Jeffery @param args: contains additional arguments used by the sel sub command 76269419bafSAndrew Jeffery @param session: the active session to use 76369419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 76469419bafSAndrew Jeffery """ 76569419bafSAndrew Jeffery 76669419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/logging/entry/enumerate" 76769419bafSAndrew Jeffery try: 76869419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 76969419bafSAndrew Jeffery except(requests.exceptions.Timeout): 77069419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 77169419bafSAndrew Jeffery return res.text 77269419bafSAndrew Jeffery 77369419bafSAndrew Jeffery 77469419bafSAndrew Jefferydef parseESEL(args, eselRAW): 77569419bafSAndrew Jeffery """ 77669419bafSAndrew Jeffery parses the esel data and gets predetermined search terms 77769419bafSAndrew Jeffery 77869419bafSAndrew Jeffery @param eselRAW: string, the raw esel string from the bmc 77969419bafSAndrew Jeffery @return: A dictionary containing the quick snapshot data unless args.fullEsel is listed then a full PEL log is returned 78069419bafSAndrew Jeffery """ 78169419bafSAndrew Jeffery eselParts = {} 78269419bafSAndrew Jeffery esel_bin = binascii.unhexlify(''.join(eselRAW.split()[16:])) 78369419bafSAndrew Jeffery #search terms contains the search term as the key and the return dictionary key as it's value 78469419bafSAndrew Jeffery searchTerms = { 'Signature Description':'signatureDescription', 'devdesc':'devdesc', 78569419bafSAndrew Jeffery 'Callout type': 'calloutType', 'Procedure':'procedure', 'Sensor Type': 'sensorType'} 78669419bafSAndrew Jeffery uniqueID = str(uuid.uuid4()) 78769419bafSAndrew Jeffery eselBinPath = tempfile.gettempdir() + os.sep + uniqueID + 'esel.bin' 78869419bafSAndrew Jeffery with open(eselBinPath, 'wb') as f: 78969419bafSAndrew Jeffery f.write(esel_bin) 79069419bafSAndrew Jeffery errlPath = "" 79169419bafSAndrew Jeffery #use the right errl file for the machine architecture 79269419bafSAndrew Jeffery arch = platform.machine() 79369419bafSAndrew Jeffery if(arch =='x86_64' or arch =='AMD64'): 79469419bafSAndrew Jeffery if os.path.exists('/opt/ibm/ras/bin/x86_64/errl'): 79569419bafSAndrew Jeffery errlPath = '/opt/ibm/ras/bin/x86_64/errl' 79669419bafSAndrew Jeffery elif os.path.exists('errl/x86_64/errl'): 79769419bafSAndrew Jeffery errlPath = 'errl/x86_64/errl' 79869419bafSAndrew Jeffery else: 79969419bafSAndrew Jeffery errlPath = 'x86_64/errl' 80069419bafSAndrew Jeffery elif (platform.machine()=='ppc64le'): 80169419bafSAndrew Jeffery if os.path.exists('/opt/ibm/ras/bin/ppc64le/errl'): 80269419bafSAndrew Jeffery errlPath = '/opt/ibm/ras/bin/ppc64le/errl' 80369419bafSAndrew Jeffery elif os.path.exists('errl/ppc64le/errl'): 80469419bafSAndrew Jeffery errlPath = 'errl/ppc64le/errl' 80569419bafSAndrew Jeffery else: 80669419bafSAndrew Jeffery errlPath = 'ppc64le/errl' 80769419bafSAndrew Jeffery else: 80869419bafSAndrew Jeffery print("machine architecture not supported for parsing eSELs") 80969419bafSAndrew Jeffery return eselParts 81069419bafSAndrew Jeffery 81169419bafSAndrew Jeffery if(os.path.exists(errlPath)): 81269419bafSAndrew Jeffery output= subprocess.check_output([errlPath, '-d', '--file='+eselBinPath]).decode('utf-8') 81369419bafSAndrew Jeffery# output = proc.communicate()[0] 81469419bafSAndrew Jeffery lines = output.split('\n') 81569419bafSAndrew Jeffery 81669419bafSAndrew Jeffery if(hasattr(args, 'fullEsel')): 81769419bafSAndrew Jeffery return output 81869419bafSAndrew Jeffery 81969419bafSAndrew Jeffery for i in range(0, len(lines)): 82069419bafSAndrew Jeffery lineParts = lines[i].split(':') 82169419bafSAndrew Jeffery if(len(lineParts)>1): #ignore multi lines, output formatting lines, and other information 82269419bafSAndrew Jeffery for term in searchTerms: 82369419bafSAndrew Jeffery if(term in lineParts[0]): 82469419bafSAndrew Jeffery temp = lines[i][lines[i].find(':')+1:].strip()[:-1].strip() 82569419bafSAndrew Jeffery if lines[i+1].find(':') != -1: 82669419bafSAndrew Jeffery if (len(lines[i+1].split(':')[0][1:].strip())==0): 82769419bafSAndrew Jeffery while(len(lines[i][:lines[i].find(':')].strip())>2): 82869419bafSAndrew Jeffery #has multiple lines, process and update line counter 82969419bafSAndrew Jeffery if((i+1) <= len(lines)): 83069419bafSAndrew Jeffery i+=1 83169419bafSAndrew Jeffery else: 83269419bafSAndrew Jeffery i=i-1 83369419bafSAndrew Jeffery break 83469419bafSAndrew Jeffery #Append the content from the next line removing the pretty display characters 83569419bafSAndrew Jeffery #Finds the first colon then starts 2 characters after, then removes all whitespace 83669419bafSAndrew Jeffery temp = temp + lines[i][lines[i].find(':')+2:].strip()[:-1].strip()[:-1].strip() 83769419bafSAndrew Jeffery if(searchTerms[term] in eselParts): 83869419bafSAndrew Jeffery eselParts[searchTerms[term]] = eselParts[searchTerms[term]] + ", " + temp 83969419bafSAndrew Jeffery else: 84069419bafSAndrew Jeffery eselParts[searchTerms[term]] = temp 84169419bafSAndrew Jeffery os.remove(eselBinPath) 84269419bafSAndrew Jeffery else: 84369419bafSAndrew Jeffery print("errl file cannot be found") 84469419bafSAndrew Jeffery 84569419bafSAndrew Jeffery return eselParts 84669419bafSAndrew Jeffery 84769419bafSAndrew Jeffery 84869419bafSAndrew Jefferydef getESELSeverity(esel): 84969419bafSAndrew Jeffery """ 85069419bafSAndrew Jeffery Finds the severity type in an eSEL from the User Header section. 85169419bafSAndrew Jeffery @param esel - the eSEL data 85269419bafSAndrew Jeffery @return severity - e.g. 'Critical' 85369419bafSAndrew Jeffery """ 85469419bafSAndrew Jeffery 85569419bafSAndrew Jeffery # everything but 1 and 2 are Critical 85669419bafSAndrew Jeffery # '1': 'recovered', 85769419bafSAndrew Jeffery # '2': 'predictive', 85869419bafSAndrew Jeffery # '4': 'unrecoverable', 85969419bafSAndrew Jeffery # '5': 'critical', 86069419bafSAndrew Jeffery # '6': 'diagnostic', 86169419bafSAndrew Jeffery # '7': 'symptom' 86269419bafSAndrew Jeffery severities = { 86369419bafSAndrew Jeffery '1': 'Informational', 86469419bafSAndrew Jeffery '2': 'Warning' 86569419bafSAndrew Jeffery } 86669419bafSAndrew Jeffery 86769419bafSAndrew Jeffery try: 86869419bafSAndrew Jeffery headerPosition = esel.index('55 48') # 'UH' 86969419bafSAndrew Jeffery # The severity is the last byte in the 8 byte section (a byte is ' bb') 87069419bafSAndrew Jeffery severity = esel[headerPosition:headerPosition+32].split(' ')[-1] 87169419bafSAndrew Jeffery type = severity[0] 87269419bafSAndrew Jeffery except ValueError: 87369419bafSAndrew Jeffery print("Could not find severity value in UH section in eSEL") 87469419bafSAndrew Jeffery type = 'x'; 87569419bafSAndrew Jeffery 87669419bafSAndrew Jeffery return severities.get(type, 'Critical') 87769419bafSAndrew Jeffery 87869419bafSAndrew Jeffery 87969419bafSAndrew Jefferydef sortSELs(events): 88069419bafSAndrew Jeffery """ 88169419bafSAndrew Jeffery sorts the sels by timestamp, then log entry number 88269419bafSAndrew Jeffery 88369419bafSAndrew Jeffery @param events: Dictionary containing events 88469419bafSAndrew Jeffery @return: list containing a list of the ordered log entries, and dictionary of keys 88569419bafSAndrew Jeffery """ 88669419bafSAndrew Jeffery logNumList = [] 88769419bafSAndrew Jeffery timestampList = [] 88869419bafSAndrew Jeffery eventKeyDict = {} 88969419bafSAndrew Jeffery eventsWithTimestamp = {} 89069419bafSAndrew Jeffery logNum2events = {} 89169419bafSAndrew Jeffery for key in events: 89269419bafSAndrew Jeffery if key == 'numAlerts': continue 89369419bafSAndrew Jeffery if 'callout' in key: continue 89469419bafSAndrew Jeffery timestamp = (events[key]['timestamp']) 89569419bafSAndrew Jeffery if timestamp not in timestampList: 89669419bafSAndrew Jeffery eventsWithTimestamp[timestamp] = [events[key]['logNum']] 89769419bafSAndrew Jeffery else: 89869419bafSAndrew Jeffery eventsWithTimestamp[timestamp].append(events[key]['logNum']) 89969419bafSAndrew Jeffery #map logNumbers to the event dictionary keys 90069419bafSAndrew Jeffery eventKeyDict[str(events[key]['logNum'])] = key 90169419bafSAndrew Jeffery 90269419bafSAndrew Jeffery timestampList = list(eventsWithTimestamp.keys()) 90369419bafSAndrew Jeffery timestampList.sort() 90469419bafSAndrew Jeffery for ts in timestampList: 90569419bafSAndrew Jeffery if len(eventsWithTimestamp[ts]) > 1: 90669419bafSAndrew Jeffery tmplist = eventsWithTimestamp[ts] 90769419bafSAndrew Jeffery tmplist.sort() 90869419bafSAndrew Jeffery logNumList = logNumList + tmplist 90969419bafSAndrew Jeffery else: 91069419bafSAndrew Jeffery logNumList = logNumList + eventsWithTimestamp[ts] 91169419bafSAndrew Jeffery 91269419bafSAndrew Jeffery return [logNumList, eventKeyDict] 91369419bafSAndrew Jeffery 91469419bafSAndrew Jeffery 91569419bafSAndrew Jefferydef parseAlerts(policyTable, selEntries, args): 91669419bafSAndrew Jeffery """ 91769419bafSAndrew Jeffery parses alerts in the IBM CER format, using an IBM policy Table 91869419bafSAndrew Jeffery 91969419bafSAndrew Jeffery @param policyTable: dictionary, the policy table entries 92069419bafSAndrew Jeffery @param selEntries: dictionary, the alerts retrieved from the bmc 92169419bafSAndrew Jeffery @return: A dictionary of the parsed entries, in chronological order 92269419bafSAndrew Jeffery """ 92369419bafSAndrew Jeffery eventDict = {} 92469419bafSAndrew Jeffery eventNum ="" 92569419bafSAndrew Jeffery count = 0 92669419bafSAndrew Jeffery esel = "" 92769419bafSAndrew Jeffery eselParts = {} 92869419bafSAndrew Jeffery i2cdevice= "" 92969419bafSAndrew Jeffery eselSeverity = None 93069419bafSAndrew Jeffery 93169419bafSAndrew Jeffery 'prepare and sort the event entries' 93269419bafSAndrew Jeffery sels = {} 93369419bafSAndrew Jeffery for key in selEntries: 93469419bafSAndrew Jeffery if '/xyz/openbmc_project/logging/entry/' not in key: continue 93569419bafSAndrew Jeffery if 'callout' not in key: 93669419bafSAndrew Jeffery sels[key] = selEntries[key] 93769419bafSAndrew Jeffery sels[key]['logNum'] = key.split('/')[-1] 93869419bafSAndrew Jeffery sels[key]['timestamp'] = selEntries[key]['Timestamp'] 93969419bafSAndrew Jeffery sortedEntries = sortSELs(sels) 94069419bafSAndrew Jeffery logNumList = sortedEntries[0] 94169419bafSAndrew Jeffery eventKeyDict = sortedEntries[1] 94269419bafSAndrew Jeffery 94369419bafSAndrew Jeffery for logNum in logNumList: 94469419bafSAndrew Jeffery key = eventKeyDict[logNum] 94569419bafSAndrew Jeffery hasEsel=False 94669419bafSAndrew Jeffery i2creadFail = False 94769419bafSAndrew Jeffery if 'callout' in key: 94869419bafSAndrew Jeffery continue 94969419bafSAndrew Jeffery else: 95069419bafSAndrew Jeffery messageID = str(selEntries[key]['Message']) 95169419bafSAndrew Jeffery addDataPiece = selEntries[key]['AdditionalData'] 95269419bafSAndrew Jeffery calloutIndex = 0 95369419bafSAndrew Jeffery calloutFound = False 95469419bafSAndrew Jeffery for i in range(len(addDataPiece)): 95569419bafSAndrew Jeffery if("CALLOUT_INVENTORY_PATH" in addDataPiece[i]): 95669419bafSAndrew Jeffery calloutIndex = i 95769419bafSAndrew Jeffery calloutFound = True 95869419bafSAndrew Jeffery fruCallout = str(addDataPiece[calloutIndex]).split('=')[1] 95969419bafSAndrew Jeffery if("CALLOUT_DEVICE_PATH" in addDataPiece[i]): 96069419bafSAndrew Jeffery i2creadFail = True 96169419bafSAndrew Jeffery 96269419bafSAndrew Jeffery fruCallout = str(addDataPiece[calloutIndex]).split('=')[1] 96369419bafSAndrew Jeffery 96469419bafSAndrew Jeffery # Fall back to "I2C"/"FSI" if dev path isn't in policy table 96569419bafSAndrew Jeffery if (messageID + '||' + fruCallout) not in policyTable: 96669419bafSAndrew Jeffery i2cdevice = str(addDataPiece[i]).strip().split('=')[1] 96769419bafSAndrew Jeffery i2cdevice = '/'.join(i2cdevice.split('/')[-4:]) 96869419bafSAndrew Jeffery if 'fsi' in str(addDataPiece[calloutIndex]).split('=')[1]: 96969419bafSAndrew Jeffery fruCallout = 'FSI' 97069419bafSAndrew Jeffery else: 97169419bafSAndrew Jeffery fruCallout = 'I2C' 97269419bafSAndrew Jeffery calloutFound = True 97369419bafSAndrew Jeffery if("CALLOUT_GPIO_NUM" in addDataPiece[i]): 97469419bafSAndrew Jeffery if not calloutFound: 97569419bafSAndrew Jeffery fruCallout = 'GPIO' 97669419bafSAndrew Jeffery calloutFound = True 97769419bafSAndrew Jeffery if("CALLOUT_IIC_BUS" in addDataPiece[i]): 97869419bafSAndrew Jeffery if not calloutFound: 97969419bafSAndrew Jeffery fruCallout = "I2C" 98069419bafSAndrew Jeffery calloutFound = True 98169419bafSAndrew Jeffery if("CALLOUT_IPMI_SENSOR_NUM" in addDataPiece[i]): 98269419bafSAndrew Jeffery if not calloutFound: 98369419bafSAndrew Jeffery fruCallout = "IPMI" 98469419bafSAndrew Jeffery calloutFound = True 98569419bafSAndrew Jeffery if("ESEL" in addDataPiece[i]): 98669419bafSAndrew Jeffery esel = str(addDataPiece[i]).strip().split('=')[1] 98769419bafSAndrew Jeffery eselSeverity = getESELSeverity(esel) 98869419bafSAndrew Jeffery if args.devdebug: 98969419bafSAndrew Jeffery eselParts = parseESEL(args, esel) 99069419bafSAndrew Jeffery hasEsel=True 99169419bafSAndrew Jeffery if("GPU" in addDataPiece[i]): 99269419bafSAndrew Jeffery fruCallout = '/xyz/openbmc_project/inventory/system/chassis/motherboard/gpu' + str(addDataPiece[i]).strip()[-1] 99369419bafSAndrew Jeffery calloutFound = True 99469419bafSAndrew Jeffery if("PROCEDURE" in addDataPiece[i]): 99569419bafSAndrew Jeffery fruCallout = str(hex(int(str(addDataPiece[i]).split('=')[1])))[2:] 99669419bafSAndrew Jeffery calloutFound = True 99769419bafSAndrew Jeffery if("RAIL_NAME" in addDataPiece[i]): 99869419bafSAndrew Jeffery calloutFound=True 99969419bafSAndrew Jeffery fruCallout = str(addDataPiece[i]).split('=')[1].strip() 100069419bafSAndrew Jeffery if("INPUT_NAME" in addDataPiece[i]): 100169419bafSAndrew Jeffery calloutFound=True 100269419bafSAndrew Jeffery fruCallout = str(addDataPiece[i]).split('=')[1].strip() 100369419bafSAndrew Jeffery if("SENSOR_TYPE" in addDataPiece[i]): 100469419bafSAndrew Jeffery calloutFound=True 100569419bafSAndrew Jeffery fruCallout = str(addDataPiece[i]).split('=')[1].strip() 100669419bafSAndrew Jeffery 100769419bafSAndrew Jeffery if(calloutFound): 100869419bafSAndrew Jeffery if fruCallout.strip() != "": 100969419bafSAndrew Jeffery policyKey = messageID +"||" + fruCallout 101069419bafSAndrew Jeffery 101169419bafSAndrew Jeffery # Also use the severity for hostboot errors 101269419bafSAndrew Jeffery if eselSeverity and messageID == 'org.open_power.Host.Error.Event': 101369419bafSAndrew Jeffery policyKey += '||' + eselSeverity 101469419bafSAndrew Jeffery 101569419bafSAndrew Jeffery # if not in the table, fall back to the original key 101669419bafSAndrew Jeffery if policyKey not in policyTable: 101769419bafSAndrew Jeffery policyKey = policyKey.replace('||'+eselSeverity, '') 101869419bafSAndrew Jeffery 101969419bafSAndrew Jeffery if policyKey not in policyTable: 102069419bafSAndrew Jeffery policyKey = messageID 102169419bafSAndrew Jeffery else: 102269419bafSAndrew Jeffery policyKey = messageID 102369419bafSAndrew Jeffery else: 102469419bafSAndrew Jeffery policyKey = messageID 102569419bafSAndrew Jeffery event = {} 102669419bafSAndrew Jeffery eventNum = str(count) 102769419bafSAndrew Jeffery if policyKey in policyTable: 102869419bafSAndrew Jeffery for pkey in policyTable[policyKey]: 102969419bafSAndrew Jeffery if(type(policyTable[policyKey][pkey])== bool): 103069419bafSAndrew Jeffery event[pkey] = boolToString(policyTable[policyKey][pkey]) 103169419bafSAndrew Jeffery else: 103269419bafSAndrew Jeffery if (i2creadFail and pkey == 'Message'): 103369419bafSAndrew Jeffery event[pkey] = policyTable[policyKey][pkey] + ' ' +i2cdevice 103469419bafSAndrew Jeffery else: 103569419bafSAndrew Jeffery event[pkey] = policyTable[policyKey][pkey] 103669419bafSAndrew Jeffery event['timestamp'] = selEntries[key]['Timestamp'] 103769419bafSAndrew Jeffery event['resolved'] = bool(selEntries[key]['Resolved']) 103869419bafSAndrew Jeffery if(hasEsel): 103969419bafSAndrew Jeffery if args.devdebug: 104069419bafSAndrew Jeffery event['eselParts'] = eselParts 104169419bafSAndrew Jeffery event['raweSEL'] = esel 104269419bafSAndrew Jeffery event['logNum'] = key.split('/')[-1] 104369419bafSAndrew Jeffery eventDict['event' + eventNum] = event 104469419bafSAndrew Jeffery 104569419bafSAndrew Jeffery else: 104669419bafSAndrew Jeffery severity = str(selEntries[key]['Severity']).split('.')[-1] 104769419bafSAndrew Jeffery if severity == 'Error': 104869419bafSAndrew Jeffery severity = 'Critical' 104969419bafSAndrew Jeffery eventDict['event'+eventNum] = {} 105069419bafSAndrew Jeffery eventDict['event' + eventNum]['error'] = "error: Not found in policy table: " + policyKey 105169419bafSAndrew Jeffery eventDict['event' + eventNum]['timestamp'] = selEntries[key]['Timestamp'] 105269419bafSAndrew Jeffery eventDict['event' + eventNum]['Severity'] = severity 105369419bafSAndrew Jeffery if(hasEsel): 105469419bafSAndrew Jeffery if args.devdebug: 105569419bafSAndrew Jeffery eventDict['event' +eventNum]['eselParts'] = eselParts 105669419bafSAndrew Jeffery eventDict['event' +eventNum]['raweSEL'] = esel 105769419bafSAndrew Jeffery eventDict['event' +eventNum]['logNum'] = key.split('/')[-1] 105869419bafSAndrew Jeffery eventDict['event' +eventNum]['resolved'] = bool(selEntries[key]['Resolved']) 105969419bafSAndrew Jeffery count += 1 106069419bafSAndrew Jeffery return eventDict 106169419bafSAndrew Jeffery 106269419bafSAndrew Jeffery 106369419bafSAndrew Jefferydef selDisplay(events, args): 106469419bafSAndrew Jeffery """ 106569419bafSAndrew Jeffery displays alerts in human readable format 106669419bafSAndrew Jeffery 106769419bafSAndrew Jeffery @param events: Dictionary containing events 106869419bafSAndrew Jeffery @return: 106969419bafSAndrew Jeffery """ 107069419bafSAndrew Jeffery activeAlerts = [] 107169419bafSAndrew Jeffery historyAlerts = [] 107269419bafSAndrew Jeffery sortedEntries = sortSELs(events) 107369419bafSAndrew Jeffery logNumList = sortedEntries[0] 107469419bafSAndrew Jeffery eventKeyDict = sortedEntries[1] 107569419bafSAndrew Jeffery keylist = ['Entry', 'ID', 'Timestamp', 'Serviceable', 'Severity','Message'] 107669419bafSAndrew Jeffery if(args.devdebug): 107769419bafSAndrew Jeffery colNames = ['Entry', 'ID', 'Timestamp', 'Serviceable', 'Severity','Message', 'eSEL contents'] 107869419bafSAndrew Jeffery keylist.append('eSEL') 107969419bafSAndrew Jeffery else: 108069419bafSAndrew Jeffery colNames = ['Entry', 'ID', 'Timestamp', 'Serviceable', 'Severity', 'Message'] 108169419bafSAndrew Jeffery for log in logNumList: 108269419bafSAndrew Jeffery selDict = {} 108369419bafSAndrew Jeffery alert = events[eventKeyDict[str(log)]] 108469419bafSAndrew Jeffery if('error' in alert): 108569419bafSAndrew Jeffery selDict['Entry'] = alert['logNum'] 108669419bafSAndrew Jeffery selDict['ID'] = 'Unknown' 108769419bafSAndrew Jeffery selDict['Timestamp'] = datetime.datetime.fromtimestamp(int(alert['timestamp']/1000)).strftime("%Y-%m-%d %H:%M:%S") 108869419bafSAndrew Jeffery msg = alert['error'] 108969419bafSAndrew Jeffery polMsg = msg.split("policy table:")[0] 109069419bafSAndrew Jeffery msg = msg.split("policy table:")[1] 109169419bafSAndrew Jeffery msgPieces = msg.split("||") 109269419bafSAndrew Jeffery err = msgPieces[0] 109369419bafSAndrew Jeffery if(err.find("org.open_power.")!=-1): 109469419bafSAndrew Jeffery err = err.split("org.open_power.")[1] 109569419bafSAndrew Jeffery elif(err.find("xyz.openbmc_project.")!=-1): 109669419bafSAndrew Jeffery err = err.split("xyz.openbmc_project.")[1] 109769419bafSAndrew Jeffery else: 109869419bafSAndrew Jeffery err = msgPieces[0] 109969419bafSAndrew Jeffery callout = "" 110069419bafSAndrew Jeffery if len(msgPieces) >1: 110169419bafSAndrew Jeffery callout = msgPieces[1] 110269419bafSAndrew Jeffery if(callout.find("/org/open_power/")!=-1): 110369419bafSAndrew Jeffery callout = callout.split("/org/open_power/")[1] 110469419bafSAndrew Jeffery elif(callout.find("/xyz/openbmc_project/")!=-1): 110569419bafSAndrew Jeffery callout = callout.split("/xyz/openbmc_project/")[1] 110669419bafSAndrew Jeffery else: 110769419bafSAndrew Jeffery callout = msgPieces[1] 110869419bafSAndrew Jeffery selDict['Message'] = polMsg +"policy table: "+ err + "||" + callout 110969419bafSAndrew Jeffery selDict['Serviceable'] = 'Unknown' 111069419bafSAndrew Jeffery selDict['Severity'] = alert['Severity'] 111169419bafSAndrew Jeffery else: 111269419bafSAndrew Jeffery selDict['Entry'] = alert['logNum'] 111369419bafSAndrew Jeffery selDict['ID'] = alert['CommonEventID'] 111469419bafSAndrew Jeffery selDict['Timestamp'] = datetime.datetime.fromtimestamp(int(alert['timestamp']/1000)).strftime("%Y-%m-%d %H:%M:%S") 111569419bafSAndrew Jeffery selDict['Message'] = alert['Message'] 111669419bafSAndrew Jeffery selDict['Serviceable'] = alert['Serviceable'] 111769419bafSAndrew Jeffery selDict['Severity'] = alert['Severity'] 111869419bafSAndrew Jeffery 111969419bafSAndrew Jeffery 112069419bafSAndrew Jeffery eselOrder = ['refCode','signatureDescription', 'eselType', 'devdesc', 'calloutType', 'procedure'] 112169419bafSAndrew Jeffery if ('eselParts' in alert and args.devdebug): 112269419bafSAndrew Jeffery eselOutput = "" 112369419bafSAndrew Jeffery for item in eselOrder: 112469419bafSAndrew Jeffery if item in alert['eselParts']: 112569419bafSAndrew Jeffery eselOutput = eselOutput + item + ": " + alert['eselParts'][item] + " | " 112669419bafSAndrew Jeffery selDict['eSEL'] = eselOutput 112769419bafSAndrew Jeffery else: 112869419bafSAndrew Jeffery if args.devdebug: 112969419bafSAndrew Jeffery selDict['eSEL'] = "None" 113069419bafSAndrew Jeffery 113169419bafSAndrew Jeffery if not alert['resolved']: 113269419bafSAndrew Jeffery activeAlerts.append(selDict) 113369419bafSAndrew Jeffery else: 113469419bafSAndrew Jeffery historyAlerts.append(selDict) 113569419bafSAndrew Jeffery mergedOutput = activeAlerts + historyAlerts 113669419bafSAndrew Jeffery colWidth = setColWidth(keylist, len(colNames), dict(enumerate(mergedOutput)), colNames) 113769419bafSAndrew Jeffery 113869419bafSAndrew Jeffery output = "" 113969419bafSAndrew Jeffery if(len(activeAlerts)>0): 114069419bafSAndrew Jeffery row = "" 114169419bafSAndrew Jeffery output +="----Active Alerts----\n" 114269419bafSAndrew Jeffery for i in range(0, len(colNames)): 114369419bafSAndrew Jeffery if i!=0: row =row + "| " 114469419bafSAndrew Jeffery row = row + colNames[i].ljust(colWidth[i]) 114569419bafSAndrew Jeffery output += row + "\n" 114669419bafSAndrew Jeffery 114769419bafSAndrew Jeffery for i in range(0,len(activeAlerts)): 114869419bafSAndrew Jeffery row = "" 114969419bafSAndrew Jeffery for j in range(len(activeAlerts[i])): 115069419bafSAndrew Jeffery if (j != 0): row = row + "| " 115169419bafSAndrew Jeffery row = row + activeAlerts[i][keylist[j]].ljust(colWidth[j]) 115269419bafSAndrew Jeffery output += row + "\n" 115369419bafSAndrew Jeffery 115469419bafSAndrew Jeffery if(len(historyAlerts)>0): 115569419bafSAndrew Jeffery row = "" 115669419bafSAndrew Jeffery output+= "----Historical Alerts----\n" 115769419bafSAndrew Jeffery for i in range(len(colNames)): 115869419bafSAndrew Jeffery if i!=0: row =row + "| " 115969419bafSAndrew Jeffery row = row + colNames[i].ljust(colWidth[i]) 116069419bafSAndrew Jeffery output += row + "\n" 116169419bafSAndrew Jeffery 116269419bafSAndrew Jeffery for i in range(0, len(historyAlerts)): 116369419bafSAndrew Jeffery row = "" 116469419bafSAndrew Jeffery for j in range(len(historyAlerts[i])): 116569419bafSAndrew Jeffery if (j != 0): row = row + "| " 116669419bafSAndrew Jeffery row = row + historyAlerts[i][keylist[j]].ljust(colWidth[j]) 116769419bafSAndrew Jeffery output += row + "\n" 116869419bafSAndrew Jeffery# print(events[eventKeyDict[str(log)]]) 116969419bafSAndrew Jeffery return output 117069419bafSAndrew Jeffery 117169419bafSAndrew Jeffery 117269419bafSAndrew Jefferydef selPrint(host, args, session): 117369419bafSAndrew Jeffery """ 117469419bafSAndrew Jeffery prints out all bmc alerts 117569419bafSAndrew Jeffery 117669419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 117769419bafSAndrew Jeffery @param args: contains additional arguments used by the fru sub command 117869419bafSAndrew Jeffery @param session: the active session to use 117969419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 118069419bafSAndrew Jeffery """ 118169419bafSAndrew Jeffery if(args.policyTableLoc is None): 118269419bafSAndrew Jeffery if os.path.exists('policyTable.json'): 118369419bafSAndrew Jeffery ptableLoc = "policyTable.json" 118469419bafSAndrew Jeffery elif os.path.exists('/opt/ibm/ras/lib/policyTable.json'): 118569419bafSAndrew Jeffery ptableLoc = '/opt/ibm/ras/lib/policyTable.json' 118669419bafSAndrew Jeffery else: 118769419bafSAndrew Jeffery ptableLoc = 'lib/policyTable.json' 118869419bafSAndrew Jeffery else: 118969419bafSAndrew Jeffery ptableLoc = args.policyTableLoc 119069419bafSAndrew Jeffery policyTable = loadPolicyTable(ptableLoc) 119169419bafSAndrew Jeffery rawselEntries = "" 119269419bafSAndrew Jeffery if(hasattr(args, 'fileloc') and args.fileloc is not None): 119369419bafSAndrew Jeffery if os.path.exists(args.fileloc): 119469419bafSAndrew Jeffery with open(args.fileloc, 'r') as selFile: 119569419bafSAndrew Jeffery selLines = selFile.readlines() 119669419bafSAndrew Jeffery rawselEntries = ''.join(selLines) 119769419bafSAndrew Jeffery else: 119869419bafSAndrew Jeffery print("Error: File not found") 119969419bafSAndrew Jeffery sys.exit(1) 120069419bafSAndrew Jeffery else: 120169419bafSAndrew Jeffery rawselEntries = sel(host, args, session) 120269419bafSAndrew Jeffery loadFailed = False 120369419bafSAndrew Jeffery try: 120469419bafSAndrew Jeffery selEntries = json.loads(rawselEntries) 120569419bafSAndrew Jeffery except ValueError: 120669419bafSAndrew Jeffery loadFailed = True 120769419bafSAndrew Jeffery if loadFailed: 120869419bafSAndrew Jeffery cleanSels = json.dumps(rawselEntries).replace('\\n', '') 120969419bafSAndrew Jeffery #need to load json twice as original content was string escaped a second time 121069419bafSAndrew Jeffery selEntries = json.loads(json.loads(cleanSels)) 121169419bafSAndrew Jeffery selEntries = selEntries['data'] 121269419bafSAndrew Jeffery 121369419bafSAndrew Jeffery if 'description' in selEntries: 121469419bafSAndrew Jeffery if(args.json): 121569419bafSAndrew Jeffery return("{\n\t\"numAlerts\": 0\n}") 121669419bafSAndrew Jeffery else: 121769419bafSAndrew Jeffery return("No log entries found") 121869419bafSAndrew Jeffery 121969419bafSAndrew Jeffery else: 122069419bafSAndrew Jeffery if(len(policyTable)>0): 122169419bafSAndrew Jeffery events = parseAlerts(policyTable, selEntries, args) 122269419bafSAndrew Jeffery if(args.json): 122369419bafSAndrew Jeffery events["numAlerts"] = len(events) 122469419bafSAndrew Jeffery retValue = str(json.dumps(events, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False)) 122569419bafSAndrew Jeffery return retValue 122669419bafSAndrew Jeffery elif(hasattr(args, 'fullSel')): 122769419bafSAndrew Jeffery return events 122869419bafSAndrew Jeffery else: 122969419bafSAndrew Jeffery #get log numbers to order event entries sequentially 123069419bafSAndrew Jeffery return selDisplay(events, args) 123169419bafSAndrew Jeffery else: 123269419bafSAndrew Jeffery if(args.json): 123369419bafSAndrew Jeffery return selEntries 123469419bafSAndrew Jeffery else: 123569419bafSAndrew Jeffery print("error: Policy Table not found.") 123669419bafSAndrew Jeffery return selEntries 123769419bafSAndrew Jeffery 123869419bafSAndrew Jefferydef selList(host, args, session): 123969419bafSAndrew Jeffery """ 124069419bafSAndrew Jeffery prints out all all bmc alerts, or only prints out the specified alerts 124169419bafSAndrew Jeffery 124269419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 124369419bafSAndrew Jeffery @param args: contains additional arguments used by the fru sub command 124469419bafSAndrew Jeffery @param session: the active session to use 124569419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 124669419bafSAndrew Jeffery """ 124769419bafSAndrew Jeffery return(sel(host, args, session)) 124869419bafSAndrew Jeffery 124969419bafSAndrew Jeffery 125069419bafSAndrew Jefferydef selClear(host, args, session): 125169419bafSAndrew Jeffery """ 125269419bafSAndrew Jeffery clears all alerts 125369419bafSAndrew Jeffery 125469419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 125569419bafSAndrew Jeffery @param args: contains additional arguments used by the fru sub command 125669419bafSAndrew Jeffery @param session: the active session to use 125769419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 125869419bafSAndrew Jeffery """ 125969419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/logging/action/DeleteAll" 126069419bafSAndrew Jeffery data = "{\"data\": [] }" 126169419bafSAndrew Jeffery 126269419bafSAndrew Jeffery try: 126369419bafSAndrew Jeffery res = session.post(url, headers=jsonHeader, data=data, verify=False, timeout=baseTimeout) 126469419bafSAndrew Jeffery except(requests.exceptions.Timeout): 126569419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 126669419bafSAndrew Jeffery if res.status_code == 200: 126769419bafSAndrew Jeffery return "The Alert Log has been cleared. Please allow a few minutes for the action to complete." 126869419bafSAndrew Jeffery else: 126969419bafSAndrew Jeffery print("Unable to clear the logs, trying to clear 1 at a time") 127069419bafSAndrew Jeffery sels = json.loads(sel(host, args, session))['data'] 127169419bafSAndrew Jeffery for key in sels: 127269419bafSAndrew Jeffery if 'callout' not in key: 127369419bafSAndrew Jeffery logNum = key.split('/')[-1] 127469419bafSAndrew Jeffery url = "https://"+ host+ "/xyz/openbmc_project/logging/entry/"+logNum+"/action/Delete" 127569419bafSAndrew Jeffery try: 127669419bafSAndrew Jeffery session.post(url, headers=jsonHeader, data=data, verify=False, timeout=baseTimeout) 127769419bafSAndrew Jeffery except(requests.exceptions.Timeout): 127869419bafSAndrew Jeffery return connectionErrHandler(args.json, "Timeout", None) 127969419bafSAndrew Jeffery sys.exit(1) 128069419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 128169419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 128269419bafSAndrew Jeffery sys.exit(1) 128369419bafSAndrew Jeffery return ('Sel clearing complete') 128469419bafSAndrew Jeffery 128569419bafSAndrew Jefferydef selSetResolved(host, args, session): 128669419bafSAndrew Jeffery """ 128769419bafSAndrew Jeffery sets a sel entry to resolved 128869419bafSAndrew Jeffery 128969419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 129069419bafSAndrew Jeffery @param args: contains additional arguments used by the fru sub command 129169419bafSAndrew Jeffery @param session: the active session to use 129269419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 129369419bafSAndrew Jeffery """ 129469419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/logging/entry/" + str(args.selNum) + "/attr/Resolved" 129569419bafSAndrew Jeffery data = "{\"data\": 1 }" 129669419bafSAndrew Jeffery try: 129769419bafSAndrew Jeffery res = session.put(url, headers=jsonHeader, data=data, verify=False, timeout=baseTimeout) 129869419bafSAndrew Jeffery except(requests.exceptions.Timeout): 129969419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 130069419bafSAndrew Jeffery if res.status_code == 200: 130169419bafSAndrew Jeffery return "Sel entry "+ str(args.selNum) +" is now set to resolved" 130269419bafSAndrew Jeffery else: 130369419bafSAndrew Jeffery return "Unable to set the alert to resolved" 130469419bafSAndrew Jeffery 130569419bafSAndrew Jefferydef selResolveAll(host, args, session): 130669419bafSAndrew Jeffery """ 130769419bafSAndrew Jeffery sets a sel entry to resolved 130869419bafSAndrew Jeffery 130969419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 131069419bafSAndrew Jeffery @param args: contains additional arguments used by the fru sub command 131169419bafSAndrew Jeffery @param session: the active session to use 131269419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 131369419bafSAndrew Jeffery """ 131469419bafSAndrew Jeffery rawselEntries = sel(host, args, session) 131569419bafSAndrew Jeffery loadFailed = False 131669419bafSAndrew Jeffery try: 131769419bafSAndrew Jeffery selEntries = json.loads(rawselEntries) 131869419bafSAndrew Jeffery except ValueError: 131969419bafSAndrew Jeffery loadFailed = True 132069419bafSAndrew Jeffery if loadFailed: 132169419bafSAndrew Jeffery cleanSels = json.dumps(rawselEntries).replace('\\n', '') 132269419bafSAndrew Jeffery #need to load json twice as original content was string escaped a second time 132369419bafSAndrew Jeffery selEntries = json.loads(json.loads(cleanSels)) 132469419bafSAndrew Jeffery selEntries = selEntries['data'] 132569419bafSAndrew Jeffery 132669419bafSAndrew Jeffery if 'description' in selEntries: 132769419bafSAndrew Jeffery if(args.json): 132869419bafSAndrew Jeffery return("{\n\t\"selsResolved\": 0\n}") 132969419bafSAndrew Jeffery else: 133069419bafSAndrew Jeffery return("No log entries found") 133169419bafSAndrew Jeffery else: 133269419bafSAndrew Jeffery d = vars(args) 133369419bafSAndrew Jeffery successlist = [] 133469419bafSAndrew Jeffery failedlist = [] 133569419bafSAndrew Jeffery for key in selEntries: 133669419bafSAndrew Jeffery if 'callout' not in key: 133769419bafSAndrew Jeffery d['selNum'] = key.split('/')[-1] 133869419bafSAndrew Jeffery resolved = selSetResolved(host,args,session) 133969419bafSAndrew Jeffery if 'Sel entry' in resolved: 134069419bafSAndrew Jeffery successlist.append(d['selNum']) 134169419bafSAndrew Jeffery else: 134269419bafSAndrew Jeffery failedlist.append(d['selNum']) 134369419bafSAndrew Jeffery output = "" 134469419bafSAndrew Jeffery successlist.sort() 134569419bafSAndrew Jeffery failedlist.sort() 134669419bafSAndrew Jeffery if len(successlist)>0: 134769419bafSAndrew Jeffery output = "Successfully resolved: " +', '.join(successlist) +"\n" 134869419bafSAndrew Jeffery if len(failedlist)>0: 134969419bafSAndrew Jeffery output += "Failed to resolve: " + ', '.join(failedlist) + "\n" 135069419bafSAndrew Jeffery return output 135169419bafSAndrew Jeffery 135269419bafSAndrew Jefferydef chassisPower(host, args, session): 135369419bafSAndrew Jeffery """ 135469419bafSAndrew Jeffery called by the chassis function. Controls the power state of the chassis, or gets the status 135569419bafSAndrew Jeffery 135669419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 135769419bafSAndrew Jeffery @param args: contains additional arguments used by the fru sub command 135869419bafSAndrew Jeffery @param session: the active session to use 135969419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 136069419bafSAndrew Jeffery """ 136169419bafSAndrew Jeffery if(args.powcmd == 'on'): 136269419bafSAndrew Jeffery if checkFWactivation(host, args, session): 136369419bafSAndrew Jeffery return ("Chassis Power control disabled during firmware activation") 136469419bafSAndrew Jeffery print("Attempting to Power on...:") 136569419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/state/host0/attr/RequestedHostTransition" 136669419bafSAndrew Jeffery data = '{"data":"xyz.openbmc_project.State.Host.Transition.On"}' 136769419bafSAndrew Jeffery try: 136869419bafSAndrew Jeffery res = session.put(url, headers=jsonHeader, data=data, verify=False, timeout=baseTimeout) 136969419bafSAndrew Jeffery except(requests.exceptions.Timeout): 137069419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 137169419bafSAndrew Jeffery return res.text 137269419bafSAndrew Jeffery elif(args.powcmd == 'softoff'): 137369419bafSAndrew Jeffery if checkFWactivation(host, args, session): 137469419bafSAndrew Jeffery return ("Chassis Power control disabled during firmware activation") 137569419bafSAndrew Jeffery print("Attempting to Power off gracefully...:") 137669419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/state/host0/attr/RequestedHostTransition" 137769419bafSAndrew Jeffery data = '{"data":"xyz.openbmc_project.State.Host.Transition.Off"}' 137869419bafSAndrew Jeffery try: 137969419bafSAndrew Jeffery res = session.put(url, headers=jsonHeader, data=data, verify=False, timeout=baseTimeout) 138069419bafSAndrew Jeffery except(requests.exceptions.Timeout): 138169419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 138269419bafSAndrew Jeffery return res.text 138369419bafSAndrew Jeffery elif(args.powcmd == 'hardoff'): 138469419bafSAndrew Jeffery if checkFWactivation(host, args, session): 138569419bafSAndrew Jeffery return ("Chassis Power control disabled during firmware activation") 138669419bafSAndrew Jeffery print("Attempting to Power off immediately...:") 138769419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/state/chassis0/attr/RequestedPowerTransition" 138869419bafSAndrew Jeffery data = '{"data":"xyz.openbmc_project.State.Chassis.Transition.Off"}' 138969419bafSAndrew Jeffery try: 139069419bafSAndrew Jeffery res = session.put(url, headers=jsonHeader, data=data, verify=False, timeout=baseTimeout) 139169419bafSAndrew Jeffery except(requests.exceptions.Timeout): 139269419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 139369419bafSAndrew Jeffery return res.text 139469419bafSAndrew Jeffery elif(args.powcmd == 'status'): 139569419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/state/chassis0/attr/CurrentPowerState" 139669419bafSAndrew Jeffery try: 139769419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 139869419bafSAndrew Jeffery except(requests.exceptions.Timeout): 139969419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 140069419bafSAndrew Jeffery chassisState = json.loads(res.text)['data'].split('.')[-1] 140169419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/state/host0/attr/CurrentHostState" 140269419bafSAndrew Jeffery try: 140369419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 140469419bafSAndrew Jeffery except(requests.exceptions.Timeout): 140569419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 140669419bafSAndrew Jeffery hostState = json.loads(res.text)['data'].split('.')[-1] 140769419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/state/bmc0/attr/CurrentBMCState" 140869419bafSAndrew Jeffery try: 140969419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 141069419bafSAndrew Jeffery except(requests.exceptions.Timeout): 141169419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 141269419bafSAndrew Jeffery bmcState = json.loads(res.text)['data'].split('.')[-1] 141369419bafSAndrew Jeffery if(args.json): 141469419bafSAndrew Jeffery outDict = {"Chassis Power State" : chassisState, "Host Power State" : hostState, "BMC Power State":bmcState} 141569419bafSAndrew Jeffery return json.dumps(outDict, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False) 141669419bafSAndrew Jeffery else: 141769419bafSAndrew Jeffery return "Chassis Power State: " +chassisState + "\nHost Power State: " + hostState + "\nBMC Power State: " + bmcState 141869419bafSAndrew Jeffery else: 141969419bafSAndrew Jeffery return "Invalid chassis power command" 142069419bafSAndrew Jeffery 142169419bafSAndrew Jeffery 142269419bafSAndrew Jefferydef chassisIdent(host, args, session): 142369419bafSAndrew Jeffery """ 142469419bafSAndrew Jeffery called by the chassis function. Controls the identify led of the chassis. Sets or gets the state 142569419bafSAndrew Jeffery 142669419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 142769419bafSAndrew Jeffery @param args: contains additional arguments used by the fru sub command 142869419bafSAndrew Jeffery @param session: the active session to use 142969419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 143069419bafSAndrew Jeffery """ 143169419bafSAndrew Jeffery if(args.identcmd == 'on'): 143269419bafSAndrew Jeffery print("Attempting to turn identify light on...:") 143369419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/led/groups/enclosure_identify/attr/Asserted" 143469419bafSAndrew Jeffery data = '{"data":true}' 143569419bafSAndrew Jeffery try: 143669419bafSAndrew Jeffery res = session.put(url, headers=jsonHeader, data=data, verify=False, timeout=baseTimeout) 143769419bafSAndrew Jeffery except(requests.exceptions.Timeout): 143869419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 143969419bafSAndrew Jeffery return res.text 144069419bafSAndrew Jeffery elif(args.identcmd == 'off'): 144169419bafSAndrew Jeffery print("Attempting to turn identify light off...:") 144269419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/led/groups/enclosure_identify/attr/Asserted" 144369419bafSAndrew Jeffery data = '{"data":false}' 144469419bafSAndrew Jeffery try: 144569419bafSAndrew Jeffery res = session.put(url, headers=jsonHeader, data=data, verify=False, timeout=baseTimeout) 144669419bafSAndrew Jeffery except(requests.exceptions.Timeout): 144769419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 144869419bafSAndrew Jeffery return res.text 144969419bafSAndrew Jeffery elif(args.identcmd == 'status'): 145069419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/led/groups/enclosure_identify" 145169419bafSAndrew Jeffery try: 145269419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 145369419bafSAndrew Jeffery except(requests.exceptions.Timeout): 145469419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 145569419bafSAndrew Jeffery status = json.loads(res.text)['data'] 145669419bafSAndrew Jeffery if(args.json): 145769419bafSAndrew Jeffery return status 145869419bafSAndrew Jeffery else: 145969419bafSAndrew Jeffery if status['Asserted'] == 0: 146069419bafSAndrew Jeffery return "Identify light is off" 146169419bafSAndrew Jeffery else: 146269419bafSAndrew Jeffery return "Identify light is blinking" 146369419bafSAndrew Jeffery else: 146469419bafSAndrew Jeffery return "Invalid chassis identify command" 146569419bafSAndrew Jeffery 146669419bafSAndrew Jeffery 146769419bafSAndrew Jefferydef chassis(host, args, session): 146869419bafSAndrew Jeffery """ 146969419bafSAndrew Jeffery controls the different chassis commands 147069419bafSAndrew Jeffery 147169419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 147269419bafSAndrew Jeffery @param args: contains additional arguments used by the fru sub command 147369419bafSAndrew Jeffery @param session: the active session to use 147469419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 147569419bafSAndrew Jeffery """ 147669419bafSAndrew Jeffery if(hasattr(args, 'powcmd')): 147769419bafSAndrew Jeffery result = chassisPower(host,args,session) 147869419bafSAndrew Jeffery elif(hasattr(args, 'identcmd')): 147969419bafSAndrew Jeffery result = chassisIdent(host, args, session) 148069419bafSAndrew Jeffery else: 148169419bafSAndrew Jeffery return "This feature is not yet implemented" 148269419bafSAndrew Jeffery return result 148369419bafSAndrew Jeffery 14844e178110SAsmitha Karunanithidef getTask(host, args, session): 14854e178110SAsmitha Karunanithi """ 14864e178110SAsmitha Karunanithi Get operation on the Task Monitor URI 14874e178110SAsmitha Karunanithi 14884e178110SAsmitha Karunanithi @param host: string, the hostname or IP address of the bmc 14894e178110SAsmitha Karunanithi @param args: contains additional arguments used by the task sub command 14904e178110SAsmitha Karunanithi @param session: the active session to use 14914e178110SAsmitha Karunanithi @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 14924e178110SAsmitha Karunanithi """ 14934e178110SAsmitha Karunanithi if args.taskURI is not None: 14944e178110SAsmitha Karunanithi url ='https://'+host+str(args.taskURI) 14954e178110SAsmitha Karunanithi try: 14964e178110SAsmitha Karunanithi r = session.post(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 14974e178110SAsmitha Karunanithi if (r.status_code == 200 and not args.json): 14984e178110SAsmitha Karunanithi return r.text 14994e178110SAsmitha Karunanithi elif (r.status_code == 200 and args.json): 15004e178110SAsmitha Karunanithi return r.json() 15014e178110SAsmitha Karunanithi else: 15024e178110SAsmitha Karunanithi return ('Failed to retrieve the data on Task Monitor URI') 15034e178110SAsmitha Karunanithi except(requests.exceptions.Timeout): 15044e178110SAsmitha Karunanithi return connectionErrHandler(args.json, "Timeout", None) 15054e178110SAsmitha Karunanithi except(requests.exceptions.ConnectionError) as err: 15064e178110SAsmitha Karunanithi return connectionErrHandler(args.json, "ConnectionError", err) 15074e178110SAsmitha Karunanithi else: 15084e178110SAsmitha Karunanithi return 'You must specify the Task Monitor URI' 15094e178110SAsmitha Karunanithi 15104e178110SAsmitha Karunanithi 151169419bafSAndrew Jefferydef dumpRetrieve(host, args, session): 151269419bafSAndrew Jeffery """ 151369419bafSAndrew Jeffery Downloads dump of given dump type 151469419bafSAndrew Jeffery 151569419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 151669419bafSAndrew Jeffery @param args: contains additional arguments used by the collectServiceData sub command 151769419bafSAndrew Jeffery @param session: the active session to use 151869419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 151969419bafSAndrew Jeffery """ 152069419bafSAndrew Jeffery dumpType = args.dumpType 152169419bafSAndrew Jeffery if (args.dumpType=="SystemDump"): 152269419bafSAndrew Jeffery dumpResp=systemDumpRetrieve(host,args,session) 152369419bafSAndrew Jeffery elif(args.dumpType=="bmc"): 152469419bafSAndrew Jeffery dumpResp=bmcDumpRetrieve(host,args,session) 152569419bafSAndrew Jeffery return dumpResp 152669419bafSAndrew Jeffery 152769419bafSAndrew Jefferydef dumpList(host, args, session): 152869419bafSAndrew Jeffery """ 152969419bafSAndrew Jeffery Lists dump of the given dump type 153069419bafSAndrew Jeffery 153169419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 153269419bafSAndrew Jeffery @param args: contains additional arguments used by the collectServiceData sub command 153369419bafSAndrew Jeffery @param session: the active session to use 153469419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 153569419bafSAndrew Jeffery """ 153669419bafSAndrew Jeffery if (args.dumpType=="SystemDump"): 153769419bafSAndrew Jeffery dumpResp=systemDumpList(host,args,session) 153869419bafSAndrew Jeffery elif(args.dumpType=="bmc"): 153969419bafSAndrew Jeffery dumpResp=bmcDumpList(host,args,session) 154069419bafSAndrew Jeffery return dumpResp 154169419bafSAndrew Jeffery 154269419bafSAndrew Jefferydef dumpDelete(host, args, session): 154369419bafSAndrew Jeffery """ 154469419bafSAndrew Jeffery Deletes dump of the given dump type 154569419bafSAndrew Jeffery 154669419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 154769419bafSAndrew Jeffery @param args: contains additional arguments used by the collectServiceData sub command 154869419bafSAndrew Jeffery @param session: the active session to use 154969419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 155069419bafSAndrew Jeffery """ 155169419bafSAndrew Jeffery if (args.dumpType=="SystemDump"): 155269419bafSAndrew Jeffery dumpResp=systemDumpDelete(host,args,session) 155369419bafSAndrew Jeffery elif(args.dumpType=="bmc"): 155469419bafSAndrew Jeffery dumpResp=bmcDumpDelete(host,args,session) 155569419bafSAndrew Jeffery return dumpResp 155669419bafSAndrew Jeffery 155769419bafSAndrew Jefferydef dumpDeleteAll(host, args, session): 155869419bafSAndrew Jeffery """ 155969419bafSAndrew Jeffery Deletes all dumps of the given dump type 156069419bafSAndrew Jeffery 156169419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 156269419bafSAndrew Jeffery @param args: contains additional arguments used by the collectServiceData sub command 156369419bafSAndrew Jeffery @param session: the active session to use 156469419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 156569419bafSAndrew Jeffery """ 156669419bafSAndrew Jeffery if (args.dumpType=="SystemDump"): 156769419bafSAndrew Jeffery dumpResp=systemDumpDeleteAll(host,args,session) 156869419bafSAndrew Jeffery elif(args.dumpType=="bmc"): 156969419bafSAndrew Jeffery dumpResp=bmcDumpDeleteAll(host,args,session) 157069419bafSAndrew Jeffery return dumpResp 157169419bafSAndrew Jeffery 157269419bafSAndrew Jefferydef dumpCreate(host, args, session): 157369419bafSAndrew Jeffery """ 157469419bafSAndrew Jeffery Creates dump for the given dump type 157569419bafSAndrew Jeffery 157669419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 157769419bafSAndrew Jeffery @param args: contains additional arguments used by the collectServiceData sub command 157869419bafSAndrew Jeffery @param session: the active session to use 157969419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 158069419bafSAndrew Jeffery """ 158169419bafSAndrew Jeffery if (args.dumpType=="SystemDump"): 158269419bafSAndrew Jeffery dumpResp=systemDumpCreate(host,args,session) 158369419bafSAndrew Jeffery elif(args.dumpType=="bmc"): 158469419bafSAndrew Jeffery dumpResp=bmcDumpCreate(host,args,session) 158569419bafSAndrew Jeffery return dumpResp 158669419bafSAndrew Jeffery 158769419bafSAndrew Jeffery 158869419bafSAndrew Jefferydef bmcDumpRetrieve(host, args, session): 158969419bafSAndrew Jeffery """ 159069419bafSAndrew Jeffery Downloads a dump file from the bmc 159169419bafSAndrew Jeffery 159269419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 159369419bafSAndrew Jeffery @param args: contains additional arguments used by the collectServiceData sub command 159469419bafSAndrew Jeffery @param session: the active session to use 159569419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 159669419bafSAndrew Jeffery """ 159769419bafSAndrew Jeffery dumpNum = args.dumpNum 159869419bafSAndrew Jeffery if (args.dumpSaveLoc is not None): 159969419bafSAndrew Jeffery saveLoc = args.dumpSaveLoc 160069419bafSAndrew Jeffery else: 160169419bafSAndrew Jeffery saveLoc = tempfile.gettempdir() 160269419bafSAndrew Jeffery url ='https://'+host+'/download/dump/' + str(dumpNum) 160369419bafSAndrew Jeffery try: 160469419bafSAndrew Jeffery r = session.get(url, headers=jsonHeader, stream=True, verify=False, timeout=baseTimeout) 160569419bafSAndrew Jeffery if (args.dumpSaveLoc is not None): 160669419bafSAndrew Jeffery if os.path.exists(saveLoc): 160769419bafSAndrew Jeffery if saveLoc[-1] != os.path.sep: 160869419bafSAndrew Jeffery saveLoc = saveLoc + os.path.sep 160969419bafSAndrew Jeffery filename = saveLoc + host+'-dump' + str(dumpNum) + '.tar.xz' 161069419bafSAndrew Jeffery 161169419bafSAndrew Jeffery else: 161269419bafSAndrew Jeffery return 'Invalid save location specified' 161369419bafSAndrew Jeffery else: 161469419bafSAndrew Jeffery filename = tempfile.gettempdir()+os.sep + host+'-dump' + str(dumpNum) + '.tar.xz' 161569419bafSAndrew Jeffery 161669419bafSAndrew Jeffery with open(filename, 'wb') as f: 161769419bafSAndrew Jeffery for chunk in r.iter_content(chunk_size =1024): 161869419bafSAndrew Jeffery if chunk: 161969419bafSAndrew Jeffery f.write(chunk) 162069419bafSAndrew Jeffery return 'Saved as ' + filename 162169419bafSAndrew Jeffery 162269419bafSAndrew Jeffery except(requests.exceptions.Timeout): 162369419bafSAndrew Jeffery return connectionErrHandler(args.json, "Timeout", None) 162469419bafSAndrew Jeffery 162569419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 162669419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 162769419bafSAndrew Jeffery 162869419bafSAndrew Jefferydef bmcDumpList(host, args, session): 162969419bafSAndrew Jeffery """ 163069419bafSAndrew Jeffery Lists the number of dump files on the bmc 163169419bafSAndrew Jeffery 163269419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 163369419bafSAndrew Jeffery @param args: contains additional arguments used by the collectServiceData sub command 163469419bafSAndrew Jeffery @param session: the active session to use 163569419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 163669419bafSAndrew Jeffery """ 163769419bafSAndrew Jeffery url ='https://'+host+'/xyz/openbmc_project/dump/list' 163869419bafSAndrew Jeffery try: 163969419bafSAndrew Jeffery r = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 164069419bafSAndrew Jeffery dumpList = r.json() 164169419bafSAndrew Jeffery formattedList = [] 164269419bafSAndrew Jeffery #remove items that aren't dump entries 'entry, internal, manager endpoints' 164369419bafSAndrew Jeffery if 'data' in dumpList: 164469419bafSAndrew Jeffery for entry in dumpList['data']: 164569419bafSAndrew Jeffery if 'entry' in entry: 164669419bafSAndrew Jeffery if entry.split('/')[-1].isnumeric(): 164769419bafSAndrew Jeffery formattedList.append(entry) 164869419bafSAndrew Jeffery dumpList['data']= formattedList 164969419bafSAndrew Jeffery return dumpList 165069419bafSAndrew Jeffery except(requests.exceptions.Timeout): 165169419bafSAndrew Jeffery return connectionErrHandler(args.json, "Timeout", None) 165269419bafSAndrew Jeffery 165369419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 165469419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 165569419bafSAndrew Jeffery 165669419bafSAndrew Jefferydef bmcDumpDelete(host, args, session): 165769419bafSAndrew Jeffery """ 165869419bafSAndrew Jeffery Deletes BMC dump files from the bmc 165969419bafSAndrew Jeffery 166069419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 166169419bafSAndrew Jeffery @param args: contains additional arguments used by the collectServiceData sub command 166269419bafSAndrew Jeffery @param session: the active session to use 166369419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 166469419bafSAndrew Jeffery """ 166569419bafSAndrew Jeffery dumpList = [] 166669419bafSAndrew Jeffery successList = [] 166769419bafSAndrew Jeffery failedList = [] 166869419bafSAndrew Jeffery if args.dumpNum is not None: 166969419bafSAndrew Jeffery if isinstance(args.dumpNum, list): 167069419bafSAndrew Jeffery dumpList = args.dumpNum 167169419bafSAndrew Jeffery else: 167269419bafSAndrew Jeffery dumpList.append(args.dumpNum) 167369419bafSAndrew Jeffery for dumpNum in dumpList: 167469419bafSAndrew Jeffery url ='https://'+host+'/xyz/openbmc_project/dump/entry/'+str(dumpNum)+'/action/Delete' 167569419bafSAndrew Jeffery try: 167669419bafSAndrew Jeffery r = session.post(url, headers=jsonHeader, json = {"data": []}, verify=False, timeout=baseTimeout) 167769419bafSAndrew Jeffery if r.status_code == 200: 167869419bafSAndrew Jeffery successList.append(str(dumpNum)) 167969419bafSAndrew Jeffery else: 168069419bafSAndrew Jeffery failedList.append(str(dumpNum)) 168169419bafSAndrew Jeffery except(requests.exceptions.Timeout): 168269419bafSAndrew Jeffery return connectionErrHandler(args.json, "Timeout", None) 168369419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 168469419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 168569419bafSAndrew Jeffery output = "Successfully deleted dumps: " + ', '.join(successList) 168669419bafSAndrew Jeffery if(len(failedList)>0): 168769419bafSAndrew Jeffery output+= '\nFailed to delete dumps: ' + ', '.join(failedList) 168869419bafSAndrew Jeffery return output 168969419bafSAndrew Jeffery else: 169069419bafSAndrew Jeffery return 'You must specify an entry number to delete' 169169419bafSAndrew Jeffery 169269419bafSAndrew Jefferydef bmcDumpDeleteAll(host, args, session): 169369419bafSAndrew Jeffery """ 169469419bafSAndrew Jeffery Deletes All BMC dump files from the bmc 169569419bafSAndrew Jeffery 169669419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 169769419bafSAndrew Jeffery @param args: contains additional arguments used by the collectServiceData sub command 169869419bafSAndrew Jeffery @param session: the active session to use 169969419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 170069419bafSAndrew Jeffery """ 170169419bafSAndrew Jeffery dumpResp = bmcDumpList(host, args, session) 170269419bafSAndrew Jeffery if 'FQPSPIN0000M' in dumpResp or 'FQPSPIN0001M'in dumpResp: 170369419bafSAndrew Jeffery return dumpResp 170469419bafSAndrew Jeffery dumpList = dumpResp['data'] 170569419bafSAndrew Jeffery d = vars(args) 170669419bafSAndrew Jeffery dumpNums = [] 170769419bafSAndrew Jeffery for dump in dumpList: 170869419bafSAndrew Jeffery dumpNum = dump.strip().split('/')[-1] 170969419bafSAndrew Jeffery if dumpNum.isdigit(): 171069419bafSAndrew Jeffery dumpNums.append(int(dumpNum)) 171169419bafSAndrew Jeffery d['dumpNum'] = dumpNums 171269419bafSAndrew Jeffery 171369419bafSAndrew Jeffery return bmcDumpDelete(host, args, session) 171469419bafSAndrew Jeffery 171569419bafSAndrew Jeffery 171669419bafSAndrew Jefferydef bmcDumpCreate(host, args, session): 171769419bafSAndrew Jeffery """ 171869419bafSAndrew Jeffery Creates a bmc dump file 171969419bafSAndrew Jeffery 172069419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 172169419bafSAndrew Jeffery @param args: contains additional arguments used by the collectServiceData sub command 172269419bafSAndrew Jeffery @param session: the active session to use 172369419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 172469419bafSAndrew Jeffery """ 172569419bafSAndrew Jeffery url = 'https://'+host+'/xyz/openbmc_project/dump/action/CreateDump' 172669419bafSAndrew Jeffery try: 172769419bafSAndrew Jeffery r = session.post(url, headers=jsonHeader, json = {"data": []}, verify=False, timeout=baseTimeout) 172869419bafSAndrew Jeffery info = r.json() 172969419bafSAndrew Jeffery if(r.status_code == 200 and not args.json): 173069419bafSAndrew Jeffery return ('Dump successfully created') 173169419bafSAndrew Jeffery elif(args.json): 173269419bafSAndrew Jeffery return info 173369419bafSAndrew Jeffery elif 'data' in info: 173469419bafSAndrew Jeffery if 'QuotaExceeded' in info['data']['description']: 173569419bafSAndrew Jeffery return 'BMC dump space is full. Please delete at least one existing dump entry and try again.' 173669419bafSAndrew Jeffery else: 173769419bafSAndrew Jeffery return "Failed to create a BMC dump. BMC Response:\n {resp}".format(resp=info) 173869419bafSAndrew Jeffery else: 173969419bafSAndrew Jeffery return "Failed to create a BMC dump. BMC Response:\n {resp}".format(resp=info) 174069419bafSAndrew Jeffery except(requests.exceptions.Timeout): 174169419bafSAndrew Jeffery return connectionErrHandler(args.json, "Timeout", None) 174269419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 174369419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 174469419bafSAndrew Jeffery 174569419bafSAndrew Jeffery 174669419bafSAndrew Jefferydef systemDumpRetrieve(host, args, session): 174769419bafSAndrew Jeffery """ 174869419bafSAndrew Jeffery Downloads system dump 174969419bafSAndrew Jeffery 175069419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 175169419bafSAndrew Jeffery @param args: contains additional arguments used by the collectServiceData sub command 175269419bafSAndrew Jeffery @param session: the active session to use 175369419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 175469419bafSAndrew Jeffery """ 175569419bafSAndrew Jeffery NBDSetup(host,args,session) 175669419bafSAndrew Jeffery pipe = NBDPipe() 175769419bafSAndrew Jeffery pipe.openHTTPSocket(args) 175869419bafSAndrew Jeffery pipe.openTCPSocket() 175969419bafSAndrew Jeffery pipe.waitformessage() 176069419bafSAndrew Jeffery 176169419bafSAndrew Jefferydef systemDumpList(host, args, session): 176269419bafSAndrew Jeffery """ 176369419bafSAndrew Jeffery Lists system dumps 176469419bafSAndrew Jeffery 176569419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 176669419bafSAndrew Jeffery @param args: contains additional arguments used by the collectServiceData sub command 176769419bafSAndrew Jeffery @param session: the active session to use 176869419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 176969419bafSAndrew Jeffery """ 177069419bafSAndrew Jeffery url = "https://"+host+"/redfish/v1/Systems/system/LogServices/Dump/Entries" 177169419bafSAndrew Jeffery try: 177269419bafSAndrew Jeffery r = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 177369419bafSAndrew Jeffery dumpList = r.json() 177469419bafSAndrew Jeffery return dumpList 177569419bafSAndrew Jeffery except(requests.exceptions.Timeout): 177669419bafSAndrew Jeffery return connectionErrHandler(args.json, "Timeout", None) 177769419bafSAndrew Jeffery 177869419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 177969419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 178069419bafSAndrew Jeffery 178169419bafSAndrew Jeffery 178269419bafSAndrew Jefferydef systemDumpDelete(host, args, session): 178369419bafSAndrew Jeffery """ 178469419bafSAndrew Jeffery Deletes system dump 178569419bafSAndrew Jeffery 178669419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 178769419bafSAndrew Jeffery @param args: contains additional arguments used by the collectServiceData sub command 178869419bafSAndrew Jeffery @param session: the active session to use 178969419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 179069419bafSAndrew Jeffery """ 179169419bafSAndrew Jeffery dumpList = [] 179269419bafSAndrew Jeffery successList = [] 179369419bafSAndrew Jeffery failedList = [] 179469419bafSAndrew Jeffery if args.dumpNum is not None: 179569419bafSAndrew Jeffery if isinstance(args.dumpNum, list): 179669419bafSAndrew Jeffery dumpList = args.dumpNum 179769419bafSAndrew Jeffery else: 179869419bafSAndrew Jeffery dumpList.append(args.dumpNum) 179969419bafSAndrew Jeffery for dumpNum in dumpList: 180069419bafSAndrew Jeffery url = 'https://'+host+'/redfish/v1/Systems/system/LogServices/Dump/Entries/'+ str(dumpNum) 180169419bafSAndrew Jeffery try: 180269419bafSAndrew Jeffery r = session.delete(url, headers=jsonHeader, json = {"data": []}, verify=False, timeout=baseTimeout) 180369419bafSAndrew Jeffery if r.status_code == 200: 180469419bafSAndrew Jeffery successList.append(str(dumpNum)) 180569419bafSAndrew Jeffery else: 180669419bafSAndrew Jeffery failedList.append(str(dumpNum)) 180769419bafSAndrew Jeffery except(requests.exceptions.Timeout): 180869419bafSAndrew Jeffery return connectionErrHandler(args.json, "Timeout", None) 180969419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 181069419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 181169419bafSAndrew Jeffery output = "Successfully deleted dumps: " + ', '.join(successList) 181269419bafSAndrew Jeffery if(len(failedList)>0): 181369419bafSAndrew Jeffery output+= '\nFailed to delete dumps: ' + ', '.join(failedList) 181469419bafSAndrew Jeffery return output 181569419bafSAndrew Jeffery else: 181669419bafSAndrew Jeffery return 'You must specify an entry number to delete' 181769419bafSAndrew Jeffery 181869419bafSAndrew Jefferydef systemDumpDeleteAll(host, args, session): 181969419bafSAndrew Jeffery """ 182069419bafSAndrew Jeffery Deletes All system dumps 182169419bafSAndrew Jeffery 182269419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 182369419bafSAndrew Jeffery @param args: contains additional arguments used by the collectServiceData sub command 182469419bafSAndrew Jeffery @param session: the active session to use 182569419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 182669419bafSAndrew Jeffery """ 182769419bafSAndrew Jeffery url = 'https://'+host+'/redfish/v1/Systems/system/LogServices/Dump/Actions/LogService.ClearLog' 182869419bafSAndrew Jeffery try: 182969419bafSAndrew Jeffery r = session.post(url, headers=jsonHeader, json = {"data": []}, verify=False, timeout=baseTimeout) 183069419bafSAndrew Jeffery if(r.status_code == 200 and not args.json): 183169419bafSAndrew Jeffery return ('Dumps successfully cleared') 183269419bafSAndrew Jeffery elif(args.json): 183369419bafSAndrew Jeffery return r.json() 183469419bafSAndrew Jeffery else: 183569419bafSAndrew Jeffery return ('Failed to clear dumps') 183669419bafSAndrew Jeffery except(requests.exceptions.Timeout): 183769419bafSAndrew Jeffery return connectionErrHandler(args.json, "Timeout", None) 183869419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 183969419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 184069419bafSAndrew Jeffery 184169419bafSAndrew Jefferydef systemDumpCreate(host, args, session): 184269419bafSAndrew Jeffery """ 184369419bafSAndrew Jeffery Creates a system dump 184469419bafSAndrew Jeffery 184569419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 184669419bafSAndrew Jeffery @param args: contains additional arguments used by the collectServiceData sub command 184769419bafSAndrew Jeffery @param session: the active session to use 184869419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 184969419bafSAndrew Jeffery """ 18504e178110SAsmitha Karunanithi url = 'https://'+host+'/redfish/v1/Systems/system/LogServices/Dump/Actions/LogService.CollectDiagnosticData' 18514e178110SAsmitha Karunanithi params = {'DiagnosticDataType':'OEM', 'OEMDiagnosticDataType':'System'} 185269419bafSAndrew Jeffery try: 18534e178110SAsmitha Karunanithi r = session.post(url, headers=jsonHeader, params=params, data = json.dumps(params), verify=False, timeout=baseTimeout) 185469419bafSAndrew Jeffery if(r.status_code == 200): 185569419bafSAndrew Jeffery return r.json() 185669419bafSAndrew Jeffery else: 185769419bafSAndrew Jeffery return ('Failed to create dump') 185869419bafSAndrew Jeffery except(requests.exceptions.Timeout): 185969419bafSAndrew Jeffery return connectionErrHandler(args.json, "Timeout", None) 186069419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 186169419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 186269419bafSAndrew Jeffery 186369419bafSAndrew Jefferydef csdDumpInitiate(host, args, session): 186469419bafSAndrew Jeffery """ 186569419bafSAndrew Jeffery Starts the process of getting the current list of dumps then initiates the creation of one. 186669419bafSAndrew Jeffery 186769419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 186869419bafSAndrew Jeffery @param args: contains additional arguments used by the collectServiceData sub command 186969419bafSAndrew Jeffery @param session: the active session to use 187069419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 187169419bafSAndrew Jeffery """ 187269419bafSAndrew Jeffery errorInfo = "" 187369419bafSAndrew Jeffery dumpcount = 0 187469419bafSAndrew Jeffery try: 187569419bafSAndrew Jeffery d = vars(args) 187669419bafSAndrew Jeffery d['json'] = True 187769419bafSAndrew Jeffery except Exception as e: 187869419bafSAndrew Jeffery errorInfo += "Failed to set the json flag to True \n Exception: {eInfo}\n".format(eInfo=e) 187969419bafSAndrew Jeffery exc_type, exc_obj, exc_tb = sys.exc_info() 188069419bafSAndrew Jeffery fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 188169419bafSAndrew Jeffery errorInfo += "Exception: Error: {err}, Details: {etype}, {fname}, {lineno}\n".format(err=e, etype=exc_type, fname=fname, lineno=exc_tb.tb_lineno) 188269419bafSAndrew Jeffery errorInfo += traceback.format_exc() 188369419bafSAndrew Jeffery 188469419bafSAndrew Jeffery try: 188569419bafSAndrew Jeffery for i in range(3): 188669419bafSAndrew Jeffery dumpInfo = bmcDumpList(host, args, session) 188769419bafSAndrew Jeffery if 'data' in dumpInfo: 188869419bafSAndrew Jeffery dumpcount = len(dumpInfo['data']) 188969419bafSAndrew Jeffery break 189069419bafSAndrew Jeffery else: 189169419bafSAndrew Jeffery errorInfo+= "Dump List Message returned: " + json.dumps(dumpInfo,indent=0, separators=(',', ':')).replace('\n','') +"\n" 189269419bafSAndrew Jeffery except Exception as e: 189369419bafSAndrew Jeffery errorInfo+= "Failed to collect the list of dumps.\nException: {eInfo}\n".format(eInfo=e) 189469419bafSAndrew Jeffery exc_type, exc_obj, exc_tb = sys.exc_info() 189569419bafSAndrew Jeffery fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 189669419bafSAndrew Jeffery errorInfo += "Exception: Error: {err}, Details: {etype}, {fname}, {lineno}\n".format(err=e, etype=exc_type, fname=fname, lineno=exc_tb.tb_lineno) 189769419bafSAndrew Jeffery errorInfo += traceback.format_exc() 189869419bafSAndrew Jeffery 189969419bafSAndrew Jeffery #Create a user initiated dump 190069419bafSAndrew Jeffery dumpFailure = True 190169419bafSAndrew Jeffery try: 190269419bafSAndrew Jeffery for i in range(3): 190369419bafSAndrew Jeffery dumpcreated = bmcDumpCreate(host, args, session) 190469419bafSAndrew Jeffery if 'message' in dumpcreated: 190569419bafSAndrew Jeffery if 'ok' in dumpcreated['message'].lower(): 190669419bafSAndrew Jeffery dumpFailure = False 190769419bafSAndrew Jeffery break 190869419bafSAndrew Jeffery elif 'data' in dumpcreated: 190969419bafSAndrew Jeffery if 'QuotaExceeded' in dumpcreated['data']['description']: 191069419bafSAndrew Jeffery print('Not enough dump space on the BMC to create a new dump. Please delete the oldest entry (lowest number) and rerun the collect_service_data command.') 191169419bafSAndrew Jeffery errorInfo+='Dump Space is full. No new dump was created with this collection' 191269419bafSAndrew Jeffery break 191369419bafSAndrew Jeffery else: 191469419bafSAndrew Jeffery errorInfo+= "Dump create message returned: " + json.dumps(dumpcreated,indent=0, separators=(',', ':')).replace('\n','') +"\n" 191569419bafSAndrew Jeffery else: 191669419bafSAndrew Jeffery errorInfo+= "Dump create message returned: " + json.dumps(dumpcreated,indent=0, separators=(',', ':')).replace('\n','') +"\n" 191769419bafSAndrew Jeffery else: 191869419bafSAndrew Jeffery errorInfo+= "Dump create message returned: " + json.dumps(dumpcreated,indent=0, separators=(',', ':')).replace('\n','') +"\n" 191969419bafSAndrew Jeffery except Exception as e: 192069419bafSAndrew Jeffery errorInfo+= "Dump create exception encountered: {eInfo}\n".format(eInfo=e) 192169419bafSAndrew Jeffery exc_type, exc_obj, exc_tb = sys.exc_info() 192269419bafSAndrew Jeffery fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 192369419bafSAndrew Jeffery errorInfo += "Exception: Error: {err}, Details: {etype}, {fname}, {lineno}\n".format(err=e, etype=exc_type, fname=fname, lineno=exc_tb.tb_lineno) 192469419bafSAndrew Jeffery errorInfo += traceback.format_exc() 192569419bafSAndrew Jeffery 192669419bafSAndrew Jeffery output = {} 192769419bafSAndrew Jeffery output['errors'] = errorInfo 192869419bafSAndrew Jeffery output['dumpcount'] = dumpcount 192969419bafSAndrew Jeffery if dumpFailure: output['dumpFailure'] = True 193069419bafSAndrew Jeffery return output 193169419bafSAndrew Jeffery 193269419bafSAndrew Jefferydef csdInventory(host, args,session, fileDir): 193369419bafSAndrew Jeffery """ 193469419bafSAndrew Jeffery Collects the BMC inventory, retrying if necessary 193569419bafSAndrew Jeffery 193669419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 193769419bafSAndrew Jeffery @param args: contains additional arguments used by the collectServiceData sub command 193869419bafSAndrew Jeffery @param session: the active session to use 193969419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 194069419bafSAndrew Jeffery @param fileDir: string representation of the path to use for putting files created 194169419bafSAndrew Jeffery """ 194269419bafSAndrew Jeffery errorInfo = "===========Inventory =============\n" 194369419bafSAndrew Jeffery output={} 194469419bafSAndrew Jeffery inventoryCollected = False 194569419bafSAndrew Jeffery try: 194669419bafSAndrew Jeffery for i in range(3): 194769419bafSAndrew Jeffery frulist = fruPrint(host, args, session) 194869419bafSAndrew Jeffery if 'Hardware' in frulist: 194969419bafSAndrew Jeffery inventoryCollected = True 195069419bafSAndrew Jeffery break 195169419bafSAndrew Jeffery else: 195269419bafSAndrew Jeffery errorInfo += json.dumps(frulist, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False) + '\n' 195369419bafSAndrew Jeffery except Exception as e: 195469419bafSAndrew Jeffery errorInfo += "Inventory collection exception: {eInfo}\n".format(eInfo=e) 195569419bafSAndrew Jeffery exc_type, exc_obj, exc_tb = sys.exc_info() 195669419bafSAndrew Jeffery fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 195769419bafSAndrew Jeffery errorInfo += "Exception: Error: {err}, Details: {etype}, {fname}, {lineno}\n".format(err=e, etype=exc_type, fname=fname, lineno=exc_tb.tb_lineno) 195869419bafSAndrew Jeffery errorInfo += traceback.format_exc() 195969419bafSAndrew Jeffery if inventoryCollected: 196069419bafSAndrew Jeffery try: 196169419bafSAndrew Jeffery with open(fileDir +os.sep+'inventory.txt', 'w') as f: 196269419bafSAndrew Jeffery f.write(json.dumps(frulist, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False) + '\n') 196369419bafSAndrew Jeffery print("Inventory collected and stored in " + fileDir + os.sep + "inventory.txt") 196469419bafSAndrew Jeffery output['fileLoc'] = fileDir+os.sep+'inventory.txt' 196569419bafSAndrew Jeffery except Exception as e: 196669419bafSAndrew Jeffery print("Failed to write inventory to file.") 196769419bafSAndrew Jeffery errorInfo += "Error writing inventory to the file. Exception: {eInfo}\n".format(eInfo=e) 196869419bafSAndrew Jeffery exc_type, exc_obj, exc_tb = sys.exc_info() 196969419bafSAndrew Jeffery fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 197069419bafSAndrew Jeffery errorInfo += "Exception: Error: {err}, Details: {etype}, {fname}, {lineno}\n".format(err=e, etype=exc_type, fname=fname, lineno=exc_tb.tb_lineno) 197169419bafSAndrew Jeffery errorInfo += traceback.format_exc() 197269419bafSAndrew Jeffery 197369419bafSAndrew Jeffery output['errors'] = errorInfo 197469419bafSAndrew Jeffery 197569419bafSAndrew Jeffery return output 197669419bafSAndrew Jeffery 197769419bafSAndrew Jefferydef csdSensors(host, args,session, fileDir): 197869419bafSAndrew Jeffery """ 197969419bafSAndrew Jeffery Collects the BMC sensor readings, retrying if necessary 198069419bafSAndrew Jeffery 198169419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 198269419bafSAndrew Jeffery @param args: contains additional arguments used by the collectServiceData sub command 198369419bafSAndrew Jeffery @param session: the active session to use 198469419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 198569419bafSAndrew Jeffery @param fileDir: string representation of the path to use for putting files created 198669419bafSAndrew Jeffery """ 198769419bafSAndrew Jeffery errorInfo = "===========Sensors =============\n" 198869419bafSAndrew Jeffery sensorsCollected = False 198969419bafSAndrew Jeffery output={} 199069419bafSAndrew Jeffery try: 199169419bafSAndrew Jeffery d = vars(args) 199269419bafSAndrew Jeffery d['json'] = False 199369419bafSAndrew Jeffery except Exception as e: 199469419bafSAndrew Jeffery errorInfo += "Failed to set the json flag to False \n Exception: {eInfo}\n".format(eInfo=e) 199569419bafSAndrew Jeffery exc_type, exc_obj, exc_tb = sys.exc_info() 199669419bafSAndrew Jeffery fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 199769419bafSAndrew Jeffery errorInfo += "Exception: Error: {err}, Details: {etype}, {fname}, {lineno}\n".format(err=e, etype=exc_type, fname=fname, lineno=exc_tb.tb_lineno) 199869419bafSAndrew Jeffery errorInfo += traceback.format_exc() 199969419bafSAndrew Jeffery 200069419bafSAndrew Jeffery try: 200169419bafSAndrew Jeffery for i in range(3): 200269419bafSAndrew Jeffery sensorReadings = sensor(host, args, session) 200369419bafSAndrew Jeffery if 'OCC0' in sensorReadings: 200469419bafSAndrew Jeffery sensorsCollected = True 200569419bafSAndrew Jeffery break 200669419bafSAndrew Jeffery else: 200769419bafSAndrew Jeffery errorInfo += sensorReadings 200869419bafSAndrew Jeffery except Exception as e: 200969419bafSAndrew Jeffery errorInfo += "Sensor reading collection exception: {eInfo}\n".format(eInfo=e) 201069419bafSAndrew Jeffery exc_type, exc_obj, exc_tb = sys.exc_info() 201169419bafSAndrew Jeffery fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 201269419bafSAndrew Jeffery errorInfo += "Exception: Error: {err}, Details: {etype}, {fname}, {lineno}\n".format(err=e, etype=exc_type, fname=fname, lineno=exc_tb.tb_lineno) 201369419bafSAndrew Jeffery errorInfo += traceback.format_exc() 201469419bafSAndrew Jeffery if sensorsCollected: 201569419bafSAndrew Jeffery try: 201669419bafSAndrew Jeffery with open(fileDir +os.sep+'sensorReadings.txt', 'w') as f: 201769419bafSAndrew Jeffery f.write(sensorReadings) 201869419bafSAndrew Jeffery print("Sensor readings collected and stored in " + fileDir + os.sep+ "sensorReadings.txt") 201969419bafSAndrew Jeffery output['fileLoc'] = fileDir+os.sep+'sensorReadings.txt' 202069419bafSAndrew Jeffery except Exception as e: 202169419bafSAndrew Jeffery print("Failed to write sensor readings to file system.") 202269419bafSAndrew Jeffery errorInfo += "Error writing sensor readings to the file. Exception: {eInfo}\n".format(eInfo=e) 202369419bafSAndrew Jeffery exc_type, exc_obj, exc_tb = sys.exc_info() 202469419bafSAndrew Jeffery fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 202569419bafSAndrew Jeffery errorInfo += "Exception: Error: {err}, Details: {etype}, {fname}, {lineno}\n".format(err=e, etype=exc_type, fname=fname, lineno=exc_tb.tb_lineno) 202669419bafSAndrew Jeffery errorInfo += traceback.format_exc() 202769419bafSAndrew Jeffery 202869419bafSAndrew Jeffery output['errors'] = errorInfo 202969419bafSAndrew Jeffery return output 203069419bafSAndrew Jeffery 203169419bafSAndrew Jefferydef csdLEDs(host,args, session, fileDir): 203269419bafSAndrew Jeffery """ 203369419bafSAndrew Jeffery Collects the BMC LED status, retrying if necessary 203469419bafSAndrew Jeffery 203569419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 203669419bafSAndrew Jeffery @param args: contains additional arguments used by the collectServiceData sub command 203769419bafSAndrew Jeffery @param session: the active session to use 203869419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 203969419bafSAndrew Jeffery @param fileDir: string representation of the path to use for putting files created 204069419bafSAndrew Jeffery """ 204169419bafSAndrew Jeffery errorInfo = "===========LEDs =============\n" 204269419bafSAndrew Jeffery ledsCollected = False 204369419bafSAndrew Jeffery output={} 204469419bafSAndrew Jeffery try: 204569419bafSAndrew Jeffery d = vars(args) 204669419bafSAndrew Jeffery d['json'] = True 204769419bafSAndrew Jeffery except Exception as e: 204869419bafSAndrew Jeffery errorInfo += "Failed to set the json flag to False \n Exception: {eInfo}\n".format(eInfo=e) 204969419bafSAndrew Jeffery exc_type, exc_obj, exc_tb = sys.exc_info() 205069419bafSAndrew Jeffery fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 205169419bafSAndrew Jeffery errorInfo += "Exception: Error: {err}, Details: {etype}, {fname}, {lineno}\n".format(err=e, etype=exc_type, fname=fname, lineno=exc_tb.tb_lineno) 205269419bafSAndrew Jeffery errorInfo += traceback.format_exc() 205369419bafSAndrew Jeffery try: 205469419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/led/enumerate" 205569419bafSAndrew Jeffery httpHeader = {'Content-Type':'application/json'} 205669419bafSAndrew Jeffery for i in range(3): 205769419bafSAndrew Jeffery try: 205869419bafSAndrew Jeffery ledRes = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 205969419bafSAndrew Jeffery if ledRes.status_code == 200: 206069419bafSAndrew Jeffery ledsCollected = True 206169419bafSAndrew Jeffery leds = ledRes.json()['data'] 206269419bafSAndrew Jeffery break 206369419bafSAndrew Jeffery else: 206469419bafSAndrew Jeffery errorInfo += ledRes.text 206569419bafSAndrew Jeffery except(requests.exceptions.Timeout): 206669419bafSAndrew Jeffery errorInfo+=json.dumps( connectionErrHandler(args.json, "Timeout", None), sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False) + '\n' 206769419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 206869419bafSAndrew Jeffery errorInfo += json.dumps(connectionErrHandler(args.json, "ConnectionError", err), sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False) + '\n' 206969419bafSAndrew Jeffery exc_type, exc_obj, exc_tb = sys.exc_info() 207069419bafSAndrew Jeffery fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 207169419bafSAndrew Jeffery errorInfo += "Exception: Error: {err}, Details: {etype}, {fname}, {lineno}\n".format(err=e, etype=exc_type, fname=fname, lineno=exc_tb.tb_lineno) 207269419bafSAndrew Jeffery errorInfo += traceback.format_exc() 207369419bafSAndrew Jeffery except Exception as e: 207469419bafSAndrew Jeffery errorInfo += "LED status collection exception: {eInfo}\n".format(eInfo=e) 207569419bafSAndrew Jeffery exc_type, exc_obj, exc_tb = sys.exc_info() 207669419bafSAndrew Jeffery fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 207769419bafSAndrew Jeffery errorInfo += "Exception: Error: {err}, Details: {etype}, {fname}, {lineno}\n".format(err=e, etype=exc_type, fname=fname, lineno=exc_tb.tb_lineno) 207869419bafSAndrew Jeffery errorInfo += traceback.format_exc() 207969419bafSAndrew Jeffery 208069419bafSAndrew Jeffery if ledsCollected: 208169419bafSAndrew Jeffery try: 208269419bafSAndrew Jeffery with open(fileDir +os.sep+'ledStatus.txt', 'w') as f: 208369419bafSAndrew Jeffery f.write(json.dumps(leds, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False) + '\n') 208469419bafSAndrew Jeffery print("LED status collected and stored in " + fileDir + os.sep+ "ledStatus.txt") 208569419bafSAndrew Jeffery output['fileLoc'] = fileDir+os.sep+'ledStatus.txt' 208669419bafSAndrew Jeffery except Exception as e: 208769419bafSAndrew Jeffery print("Failed to write LED status to file system.") 208869419bafSAndrew Jeffery errorInfo += "Error writing LED status to the file. Exception: {eInfo}\n".format(eInfo=e) 208969419bafSAndrew Jeffery exc_type, exc_obj, exc_tb = sys.exc_info() 209069419bafSAndrew Jeffery fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 209169419bafSAndrew Jeffery errorInfo += "Exception: Error: {err}, Details: {etype}, {fname}, {lineno}\n".format(err=e, etype=exc_type, fname=fname, lineno=exc_tb.tb_lineno) 209269419bafSAndrew Jeffery errorInfo += traceback.format_exc() 209369419bafSAndrew Jeffery 209469419bafSAndrew Jeffery output['errors'] = errorInfo 209569419bafSAndrew Jeffery return output 209669419bafSAndrew Jeffery 209769419bafSAndrew Jefferydef csdSelShortList(host, args, session, fileDir): 209869419bafSAndrew Jeffery """ 209969419bafSAndrew Jeffery Collects the BMC log entries, retrying if necessary 210069419bafSAndrew Jeffery 210169419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 210269419bafSAndrew Jeffery @param args: contains additional arguments used by the collectServiceData sub command 210369419bafSAndrew Jeffery @param session: the active session to use 210469419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 210569419bafSAndrew Jeffery @param fileDir: string representation of the path to use for putting files created 210669419bafSAndrew Jeffery """ 210769419bafSAndrew Jeffery errorInfo = "===========SEL Short List =============\n" 210869419bafSAndrew Jeffery selsCollected = False 210969419bafSAndrew Jeffery output={} 211069419bafSAndrew Jeffery try: 211169419bafSAndrew Jeffery d = vars(args) 211269419bafSAndrew Jeffery d['json'] = False 211369419bafSAndrew Jeffery except Exception as e: 211469419bafSAndrew Jeffery errorInfo += "Failed to set the json flag to False \n Exception: {eInfo}\n".format(eInfo=e) 211569419bafSAndrew Jeffery exc_type, exc_obj, exc_tb = sys.exc_info() 211669419bafSAndrew Jeffery fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 211769419bafSAndrew Jeffery errorInfo += "Exception: Error: {err}, Details: {etype}, {fname}, {lineno}\n".format(err=e, etype=exc_type, fname=fname, lineno=exc_tb.tb_lineno) 211869419bafSAndrew Jeffery errorInfo += traceback.format_exc() 211969419bafSAndrew Jeffery 212069419bafSAndrew Jeffery try: 212169419bafSAndrew Jeffery for i in range(3): 212269419bafSAndrew Jeffery sels = selPrint(host,args,session) 212369419bafSAndrew Jeffery if '----Active Alerts----' in sels or 'No log entries found' in sels or '----Historical Alerts----' in sels: 212469419bafSAndrew Jeffery selsCollected = True 212569419bafSAndrew Jeffery break 212669419bafSAndrew Jeffery else: 212769419bafSAndrew Jeffery errorInfo += sels + '\n' 212869419bafSAndrew Jeffery except Exception as e: 212969419bafSAndrew Jeffery errorInfo += "SEL short list collection exception: {eInfo}\n".format(eInfo=e) 213069419bafSAndrew Jeffery exc_type, exc_obj, exc_tb = sys.exc_info() 213169419bafSAndrew Jeffery fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 213269419bafSAndrew Jeffery errorInfo += "Exception: Error: {err}, Details: {etype}, {fname}, {lineno}\n".format(err=e, etype=exc_type, fname=fname, lineno=exc_tb.tb_lineno) 213369419bafSAndrew Jeffery errorInfo += traceback.format_exc() 213469419bafSAndrew Jeffery 213569419bafSAndrew Jeffery if selsCollected: 213669419bafSAndrew Jeffery try: 213769419bafSAndrew Jeffery with open(fileDir +os.sep+'SELshortlist.txt', 'w') as f: 213869419bafSAndrew Jeffery f.write(sels) 213969419bafSAndrew Jeffery print("SEL short list collected and stored in " + fileDir + os.sep+ "SELshortlist.txt") 214069419bafSAndrew Jeffery output['fileLoc'] = fileDir+os.sep+'SELshortlist.txt' 214169419bafSAndrew Jeffery except Exception as e: 214269419bafSAndrew Jeffery print("Failed to write SEL short list to file system.") 214369419bafSAndrew Jeffery errorInfo += "Error writing SEL short list to the file. Exception: {eInfo}\n".format(eInfo=e) 214469419bafSAndrew Jeffery exc_type, exc_obj, exc_tb = sys.exc_info() 214569419bafSAndrew Jeffery fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 214669419bafSAndrew Jeffery errorInfo += "Exception: Error: {err}, Details: {etype}, {fname}, {lineno}\n".format(err=e, etype=exc_type, fname=fname, lineno=exc_tb.tb_lineno) 214769419bafSAndrew Jeffery errorInfo += traceback.format_exc() 214869419bafSAndrew Jeffery 214969419bafSAndrew Jeffery output['errors'] = errorInfo 215069419bafSAndrew Jeffery return output 215169419bafSAndrew Jeffery 215269419bafSAndrew Jefferydef csdParsedSels(host, args, session, fileDir): 215369419bafSAndrew Jeffery """ 215469419bafSAndrew Jeffery Collects the BMC log entries, retrying if necessary 215569419bafSAndrew Jeffery 215669419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 215769419bafSAndrew Jeffery @param args: contains additional arguments used by the collectServiceData sub command 215869419bafSAndrew Jeffery @param session: the active session to use 215969419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 216069419bafSAndrew Jeffery @param fileDir: string representation of the path to use for putting files created 216169419bafSAndrew Jeffery """ 216269419bafSAndrew Jeffery errorInfo = "===========SEL Parsed List =============\n" 216369419bafSAndrew Jeffery selsCollected = False 216469419bafSAndrew Jeffery output={} 216569419bafSAndrew Jeffery try: 216669419bafSAndrew Jeffery d = vars(args) 216769419bafSAndrew Jeffery d['json'] = True 216869419bafSAndrew Jeffery d['fullEsel'] = True 216969419bafSAndrew Jeffery except Exception as e: 217069419bafSAndrew Jeffery errorInfo += "Failed to set the json flag to True \n Exception: {eInfo}\n".format(eInfo=e) 217169419bafSAndrew Jeffery exc_type, exc_obj, exc_tb = sys.exc_info() 217269419bafSAndrew Jeffery fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 217369419bafSAndrew Jeffery errorInfo += "Exception: Error: {err}, Details: {etype}, {fname}, {lineno}\n".format(err=e, etype=exc_type, fname=fname, lineno=exc_tb.tb_lineno) 217469419bafSAndrew Jeffery errorInfo += traceback.format_exc() 217569419bafSAndrew Jeffery 217669419bafSAndrew Jeffery try: 217769419bafSAndrew Jeffery for i in range(3): 217869419bafSAndrew Jeffery parsedfullsels = json.loads(selPrint(host,args,session)) 217969419bafSAndrew Jeffery if 'numAlerts' in parsedfullsels: 218069419bafSAndrew Jeffery selsCollected = True 218169419bafSAndrew Jeffery break 218269419bafSAndrew Jeffery else: 218369419bafSAndrew Jeffery errorInfo += parsedfullsels + '\n' 218469419bafSAndrew Jeffery except Exception as e: 218569419bafSAndrew Jeffery errorInfo += "Parsed full SELs collection exception: {eInfo}\n".format(eInfo=e) 218669419bafSAndrew Jeffery exc_type, exc_obj, exc_tb = sys.exc_info() 218769419bafSAndrew Jeffery fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 218869419bafSAndrew Jeffery errorInfo += "Exception: Error: {err}, Details: {etype}, {fname}, {lineno}\n".format(err=e, etype=exc_type, fname=fname, lineno=exc_tb.tb_lineno) 218969419bafSAndrew Jeffery errorInfo += traceback.format_exc() 219069419bafSAndrew Jeffery 219169419bafSAndrew Jeffery if selsCollected: 219269419bafSAndrew Jeffery try: 219369419bafSAndrew Jeffery sortedSELs = sortSELs(parsedfullsels) 219469419bafSAndrew Jeffery with open(fileDir +os.sep+'parsedSELs.txt', 'w') as f: 219569419bafSAndrew Jeffery for log in sortedSELs[0]: 219669419bafSAndrew Jeffery esel = "" 219769419bafSAndrew Jeffery parsedfullsels[sortedSELs[1][str(log)]]['timestamp'] = datetime.datetime.fromtimestamp(int(parsedfullsels[sortedSELs[1][str(log)]]['timestamp']/1000)).strftime("%Y-%m-%d %H:%M:%S") 219869419bafSAndrew Jeffery if ('raweSEL' in parsedfullsels[sortedSELs[1][str(log)]] and args.devdebug): 219969419bafSAndrew Jeffery esel = parsedfullsels[sortedSELs[1][str(log)]]['raweSEL'] 220069419bafSAndrew Jeffery del parsedfullsels[sortedSELs[1][str(log)]]['raweSEL'] 220169419bafSAndrew Jeffery f.write(json.dumps(parsedfullsels[sortedSELs[1][str(log)]],sort_keys=True, indent=4, separators=(',', ': '))) 220269419bafSAndrew Jeffery if(args.devdebug and esel != ""): 220369419bafSAndrew Jeffery f.write(parseESEL(args, esel)) 220469419bafSAndrew Jeffery print("Parsed SELs collected and stored in " + fileDir + os.sep+ "parsedSELs.txt") 220569419bafSAndrew Jeffery output['fileLoc'] = fileDir+os.sep+'parsedSELs.txt' 220669419bafSAndrew Jeffery except Exception as e: 220769419bafSAndrew Jeffery print("Failed to write fully parsed SELs to file system.") 220869419bafSAndrew Jeffery errorInfo += "Error writing fully parsed SELs to the file. Exception: {eInfo}\n".format(eInfo=e) 220969419bafSAndrew Jeffery exc_type, exc_obj, exc_tb = sys.exc_info() 221069419bafSAndrew Jeffery fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 221169419bafSAndrew Jeffery errorInfo += "Exception: Error: {err}, Details: {etype}, {fname}, {lineno}\n".format(err=e, etype=exc_type, fname=fname, lineno=exc_tb.tb_lineno) 221269419bafSAndrew Jeffery errorInfo += traceback.format_exc() 221369419bafSAndrew Jeffery 221469419bafSAndrew Jeffery output['errors'] = errorInfo 221569419bafSAndrew Jeffery return output 221669419bafSAndrew Jeffery 221769419bafSAndrew Jefferydef csdFullEnumeration(host, args, session, fileDir): 221869419bafSAndrew Jeffery """ 221969419bafSAndrew Jeffery Collects a full enumeration of /xyz/openbmc_project/, retrying if necessary 222069419bafSAndrew Jeffery 222169419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 222269419bafSAndrew Jeffery @param args: contains additional arguments used by the collectServiceData sub command 222369419bafSAndrew Jeffery @param session: the active session to use 222469419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 222569419bafSAndrew Jeffery @param fileDir: string representation of the path to use for putting files created 222669419bafSAndrew Jeffery """ 222769419bafSAndrew Jeffery errorInfo = "===========BMC Full Enumeration =============\n" 222869419bafSAndrew Jeffery bmcFullCollected = False 222969419bafSAndrew Jeffery output={} 223069419bafSAndrew Jeffery try: 223169419bafSAndrew Jeffery d = vars(args) 223269419bafSAndrew Jeffery d['json'] = True 223369419bafSAndrew Jeffery except Exception as e: 223469419bafSAndrew Jeffery errorInfo += "Failed to set the json flag to False \n Exception: {eInfo}\n".format(eInfo=e) 223569419bafSAndrew Jeffery exc_type, exc_obj, exc_tb = sys.exc_info() 223669419bafSAndrew Jeffery fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 223769419bafSAndrew Jeffery errorInfo += "Exception: Error: {err}, Details: {etype}, {fname}, {lineno}\n".format(err=e, etype=exc_type, fname=fname, lineno=exc_tb.tb_lineno) 223869419bafSAndrew Jeffery errorInfo += traceback.format_exc() 223969419bafSAndrew Jeffery try: 224069419bafSAndrew Jeffery print("Attempting to get a full BMC enumeration") 224169419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/enumerate" 224269419bafSAndrew Jeffery httpHeader = {'Content-Type':'application/json'} 224369419bafSAndrew Jeffery for i in range(3): 224469419bafSAndrew Jeffery try: 224569419bafSAndrew Jeffery bmcRes = session.get(url, headers=jsonHeader, verify=False, timeout=180) 224669419bafSAndrew Jeffery if bmcRes.status_code == 200: 224769419bafSAndrew Jeffery bmcFullCollected = True 224869419bafSAndrew Jeffery fullEnumeration = bmcRes.json() 224969419bafSAndrew Jeffery break 225069419bafSAndrew Jeffery else: 225169419bafSAndrew Jeffery errorInfo += bmcRes.text 225269419bafSAndrew Jeffery except(requests.exceptions.Timeout): 225369419bafSAndrew Jeffery errorInfo+=json.dumps( connectionErrHandler(args.json, "Timeout", None), sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False) + '\n' 225469419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 225569419bafSAndrew Jeffery errorInfo += json.dumps(connectionErrHandler(args.json, "ConnectionError", err), sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False) + '\n' 225669419bafSAndrew Jeffery exc_type, exc_obj, exc_tb = sys.exc_info() 225769419bafSAndrew Jeffery fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 225869419bafSAndrew Jeffery errorInfo += "Exception: Error: {err}, Details: {etype}, {fname}, {lineno}\n".format(err=e, etype=exc_type, fname=fname, lineno=exc_tb.tb_lineno) 225969419bafSAndrew Jeffery errorInfo += traceback.format_exc() 226069419bafSAndrew Jeffery except Exception as e: 226169419bafSAndrew Jeffery errorInfo += "RAW BMC data collection exception: {eInfo}\n".format(eInfo=e) 226269419bafSAndrew Jeffery exc_type, exc_obj, exc_tb = sys.exc_info() 226369419bafSAndrew Jeffery fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 226469419bafSAndrew Jeffery errorInfo += "Exception: Error: {err}, Details: {etype}, {fname}, {lineno}\n".format(err=e, etype=exc_type, fname=fname, lineno=exc_tb.tb_lineno) 226569419bafSAndrew Jeffery errorInfo += traceback.format_exc() 226669419bafSAndrew Jeffery 226769419bafSAndrew Jeffery if bmcFullCollected: 226869419bafSAndrew Jeffery try: 226969419bafSAndrew Jeffery with open(fileDir +os.sep+'bmcFullRaw.txt', 'w') as f: 227069419bafSAndrew Jeffery f.write(json.dumps(fullEnumeration, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False) + '\n') 227169419bafSAndrew Jeffery print("RAW BMC data collected and saved into " + fileDir + os.sep+ "bmcFullRaw.txt") 227269419bafSAndrew Jeffery output['fileLoc'] = fileDir+os.sep+'bmcFullRaw.txt' 227369419bafSAndrew Jeffery except Exception as e: 227469419bafSAndrew Jeffery print("Failed to write RAW BMC data to file system.") 227569419bafSAndrew Jeffery errorInfo += "Error writing RAW BMC data collection to the file. Exception: {eInfo}\n".format(eInfo=e) 227669419bafSAndrew Jeffery exc_type, exc_obj, exc_tb = sys.exc_info() 227769419bafSAndrew Jeffery fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 227869419bafSAndrew Jeffery errorInfo += "Exception: Error: {err}, Details: {etype}, {fname}, {lineno}\n".format(err=e, etype=exc_type, fname=fname, lineno=exc_tb.tb_lineno) 227969419bafSAndrew Jeffery errorInfo += traceback.format_exc() 228069419bafSAndrew Jeffery 228169419bafSAndrew Jeffery output['errors'] = errorInfo 228269419bafSAndrew Jeffery return output 228369419bafSAndrew Jeffery 228469419bafSAndrew Jefferydef csdCollectAllDumps(host, args, session, fileDir): 228569419bafSAndrew Jeffery """ 228669419bafSAndrew Jeffery Collects all of the bmc dump files and stores them in fileDir 228769419bafSAndrew Jeffery 228869419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 228969419bafSAndrew Jeffery @param args: contains additional arguments used by the collectServiceData sub command 229069419bafSAndrew Jeffery @param session: the active session to use 229169419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 229269419bafSAndrew Jeffery @param fileDir: string representation of the path to use for putting files created 229369419bafSAndrew Jeffery """ 229469419bafSAndrew Jeffery 229569419bafSAndrew Jeffery errorInfo = "===========BMC Dump Collection =============\n" 229669419bafSAndrew Jeffery dumpListCollected = False 229769419bafSAndrew Jeffery output={} 229869419bafSAndrew Jeffery dumpList = {} 229969419bafSAndrew Jeffery try: 230069419bafSAndrew Jeffery d = vars(args) 230169419bafSAndrew Jeffery d['json'] = True 230269419bafSAndrew Jeffery d['dumpSaveLoc'] = fileDir 230369419bafSAndrew Jeffery except Exception as e: 230469419bafSAndrew Jeffery errorInfo += "Failed to set the json flag to True, or failed to set the dumpSave Location \n Exception: {eInfo}\n".format(eInfo=e) 230569419bafSAndrew Jeffery exc_type, exc_obj, exc_tb = sys.exc_info() 230669419bafSAndrew Jeffery fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 230769419bafSAndrew Jeffery errorInfo += "Exception: Error: {err}, Details: {etype}, {fname}, {lineno}\n".format(err=e, etype=exc_type, fname=fname, lineno=exc_tb.tb_lineno) 230869419bafSAndrew Jeffery errorInfo += traceback.format_exc() 230969419bafSAndrew Jeffery 231069419bafSAndrew Jeffery print('Collecting bmc dump files') 231169419bafSAndrew Jeffery 231269419bafSAndrew Jeffery try: 231369419bafSAndrew Jeffery for i in range(3): 231469419bafSAndrew Jeffery dumpResp = bmcDumpList(host, args, session) 231569419bafSAndrew Jeffery if 'message' in dumpResp: 231669419bafSAndrew Jeffery if 'ok' in dumpResp['message'].lower(): 231769419bafSAndrew Jeffery dumpList = dumpResp['data'] 231869419bafSAndrew Jeffery dumpListCollected = True 231969419bafSAndrew Jeffery break 232069419bafSAndrew Jeffery else: 232169419bafSAndrew Jeffery errorInfo += "Status was not OK when retrieving the list of dumps available. \n Response: \n{resp}\n".format(resp=dumpResp) 232269419bafSAndrew Jeffery else: 232369419bafSAndrew Jeffery errorInfo += "Invalid response received from the BMC while retrieving the list of dumps available.\n {resp}\n".format(resp=dumpResp) 232469419bafSAndrew Jeffery except Exception as e: 232569419bafSAndrew Jeffery errorInfo += "BMC dump list exception: {eInfo}\n".format(eInfo=e) 232669419bafSAndrew Jeffery exc_type, exc_obj, exc_tb = sys.exc_info() 232769419bafSAndrew Jeffery fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 232869419bafSAndrew Jeffery errorInfo += "Exception: Error: {err}, Details: {etype}, {fname}, {lineno}\n".format(err=e, etype=exc_type, fname=fname, lineno=exc_tb.tb_lineno) 232969419bafSAndrew Jeffery errorInfo += traceback.format_exc() 233069419bafSAndrew Jeffery 233169419bafSAndrew Jeffery if dumpListCollected: 233269419bafSAndrew Jeffery output['fileList'] = [] 233369419bafSAndrew Jeffery for dump in dumpList: 233469419bafSAndrew Jeffery try: 233569419bafSAndrew Jeffery if '/xyz/openbmc_project/dump/internal/manager' not in dump: 233669419bafSAndrew Jeffery d['dumpNum'] = int(dump.strip().split('/')[-1]) 233769419bafSAndrew Jeffery print('retrieving dump file ' + str(d['dumpNum'])) 233869419bafSAndrew Jeffery filename = bmcDumpRetrieve(host, args, session).split('Saved as ')[-1] 233969419bafSAndrew Jeffery output['fileList'].append(filename) 234069419bafSAndrew Jeffery except Exception as e: 234169419bafSAndrew Jeffery print("Unable to collect dump: {dumpInfo}".format(dumpInfo=dump)) 234269419bafSAndrew Jeffery errorInfo += "Exception collecting a bmc dump {dumpInfo}\n {eInfo}\n".format(dumpInfo=dump, eInfo=e) 234369419bafSAndrew Jeffery exc_type, exc_obj, exc_tb = sys.exc_info() 234469419bafSAndrew Jeffery fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 234569419bafSAndrew Jeffery errorInfo += "Exception: Error: {err}, Details: {etype}, {fname}, {lineno}\n".format(err=e, etype=exc_type, fname=fname, lineno=exc_tb.tb_lineno) 234669419bafSAndrew Jeffery errorInfo += traceback.format_exc() 234769419bafSAndrew Jeffery output['errors'] = errorInfo 234869419bafSAndrew Jeffery return output 234969419bafSAndrew Jeffery 235069419bafSAndrew Jefferydef collectServiceData(host, args, session): 235169419bafSAndrew Jeffery """ 235269419bafSAndrew Jeffery Collects all data needed for service from the BMC 235369419bafSAndrew Jeffery 235469419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 235569419bafSAndrew Jeffery @param args: contains additional arguments used by the collectServiceData sub command 235669419bafSAndrew Jeffery @param session: the active session to use 235769419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 235869419bafSAndrew Jeffery """ 235969419bafSAndrew Jeffery 236069419bafSAndrew Jeffery global toolVersion 236169419bafSAndrew Jeffery filelist = [] 236269419bafSAndrew Jeffery errorInfo = "" 236369419bafSAndrew Jeffery 236469419bafSAndrew Jeffery #get current number of bmc dumps and create a new bmc dump 236569419bafSAndrew Jeffery dumpInitdata = csdDumpInitiate(host, args, session) 236669419bafSAndrew Jeffery if 'dumpFailure' in dumpInitdata: 236769419bafSAndrew Jeffery return 'Collect service data is stopping due to not being able to create a new dump. No service data was collected.' 236869419bafSAndrew Jeffery dumpcount = dumpInitdata['dumpcount'] 236969419bafSAndrew Jeffery errorInfo += dumpInitdata['errors'] 237069419bafSAndrew Jeffery #create the directory to put files 237169419bafSAndrew Jeffery try: 237269419bafSAndrew Jeffery args.silent = True 237369419bafSAndrew Jeffery myDir = tempfile.gettempdir()+os.sep + host + "--" + datetime.datetime.now().strftime("%Y-%m-%d_%H.%M.%S") 237469419bafSAndrew Jeffery os.makedirs(myDir) 237569419bafSAndrew Jeffery 237669419bafSAndrew Jeffery except Exception as e: 237769419bafSAndrew Jeffery print('Unable to create the temporary directory for data collection. Ensure sufficient privileges to create temporary directory. Aborting.') 237869419bafSAndrew Jeffery exc_type, exc_obj, exc_tb = sys.exc_info() 237969419bafSAndrew Jeffery fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 238069419bafSAndrew Jeffery errorInfo += "Exception: Error: {err}, Details: {etype}, {fname}, {lineno}\n".format(err=e, etype=exc_type, fname=fname, lineno=exc_tb.tb_lineno) 238169419bafSAndrew Jeffery errorInfo += traceback.format_exc() 238269419bafSAndrew Jeffery return("Python exception: {eInfo}".format(eInfo = e)) 238369419bafSAndrew Jeffery 238469419bafSAndrew Jeffery #Collect Inventory 238569419bafSAndrew Jeffery inventoryData = csdInventory(host, args, session, myDir) 238669419bafSAndrew Jeffery if 'fileLoc' in inventoryData: 238769419bafSAndrew Jeffery filelist.append(inventoryData['fileLoc']) 238869419bafSAndrew Jeffery errorInfo += inventoryData['errors'] 238969419bafSAndrew Jeffery #Read all the sensor and OCC status 239069419bafSAndrew Jeffery sensorData = csdSensors(host,args,session,myDir) 239169419bafSAndrew Jeffery if 'fileLoc' in sensorData: 239269419bafSAndrew Jeffery filelist.append(sensorData['fileLoc']) 239369419bafSAndrew Jeffery errorInfo += sensorData['errors'] 239469419bafSAndrew Jeffery #Collect all of the LEDs status 239569419bafSAndrew Jeffery ledStatus = csdLEDs(host, args, session, myDir) 239669419bafSAndrew Jeffery if 'fileLoc' in ledStatus: 239769419bafSAndrew Jeffery filelist.append(ledStatus['fileLoc']) 239869419bafSAndrew Jeffery errorInfo += ledStatus['errors'] 239969419bafSAndrew Jeffery 240069419bafSAndrew Jeffery #Collect the bmc logs 240169419bafSAndrew Jeffery selShort = csdSelShortList(host, args, session, myDir) 240269419bafSAndrew Jeffery if 'fileLoc' in selShort: 240369419bafSAndrew Jeffery filelist.append(selShort['fileLoc']) 240469419bafSAndrew Jeffery errorInfo += selShort['errors'] 240569419bafSAndrew Jeffery 240669419bafSAndrew Jeffery parsedSELs = csdParsedSels(host, args, session, myDir) 240769419bafSAndrew Jeffery if 'fileLoc' in parsedSELs: 240869419bafSAndrew Jeffery filelist.append(parsedSELs['fileLoc']) 240969419bafSAndrew Jeffery errorInfo += parsedSELs['errors'] 241069419bafSAndrew Jeffery 241169419bafSAndrew Jeffery #collect RAW bmc enumeration 241269419bafSAndrew Jeffery bmcRaw = csdFullEnumeration(host, args, session, myDir) 241369419bafSAndrew Jeffery if 'fileLoc' in bmcRaw: 241469419bafSAndrew Jeffery filelist.append(bmcRaw['fileLoc']) 241569419bafSAndrew Jeffery errorInfo += bmcRaw['errors'] 241669419bafSAndrew Jeffery 241769419bafSAndrew Jeffery #wait for new dump to finish being created 241869419bafSAndrew Jeffery waitingForNewDump = True 241969419bafSAndrew Jeffery count = 0; 242069419bafSAndrew Jeffery print("Waiting for new BMC dump to finish being created. Wait time could be up to 5 minutes") 242169419bafSAndrew Jeffery while(waitingForNewDump): 242269419bafSAndrew Jeffery dumpList = bmcDumpList(host, args, session)['data'] 242369419bafSAndrew Jeffery if len(dumpList) > dumpcount: 242469419bafSAndrew Jeffery waitingForNewDump = False 242569419bafSAndrew Jeffery break; 242669419bafSAndrew Jeffery elif(count>150): 242769419bafSAndrew Jeffery print("Timed out waiting for bmc to make a new dump file. Continuing without it.") 242869419bafSAndrew Jeffery break; 242969419bafSAndrew Jeffery else: 243069419bafSAndrew Jeffery time.sleep(2) 243169419bafSAndrew Jeffery count += 1 243269419bafSAndrew Jeffery 243369419bafSAndrew Jeffery #collect all of the dump files 243469419bafSAndrew Jeffery getBMCDumps = csdCollectAllDumps(host, args, session, myDir) 243569419bafSAndrew Jeffery if 'fileList' in getBMCDumps: 243669419bafSAndrew Jeffery filelist+= getBMCDumps['fileList'] 243769419bafSAndrew Jeffery errorInfo += getBMCDumps['errors'] 243869419bafSAndrew Jeffery 243969419bafSAndrew Jeffery #write the runtime errors to a file 244069419bafSAndrew Jeffery try: 244169419bafSAndrew Jeffery with open(myDir +os.sep+'openbmctoolRuntimeErrors.txt', 'w') as f: 244269419bafSAndrew Jeffery f.write(errorInfo) 244369419bafSAndrew Jeffery print("OpenBMC tool runtime errors collected and stored in " + myDir + os.sep+ "openbmctoolRuntimeErrors.txt") 244469419bafSAndrew Jeffery filelist.append(myDir+os.sep+'openbmctoolRuntimeErrors.txt') 244569419bafSAndrew Jeffery except Exception as e: 244669419bafSAndrew Jeffery print("Failed to write OpenBMC tool runtime errors to file system.") 244769419bafSAndrew Jeffery 244869419bafSAndrew Jeffery #create the zip file 244969419bafSAndrew Jeffery try: 245069419bafSAndrew Jeffery filename = myDir.split(tempfile.gettempdir()+os.sep)[-1] + "_" + toolVersion + '_openbmc.zip' 245169419bafSAndrew Jeffery zf = zipfile.ZipFile(myDir+os.sep + filename, 'w') 245269419bafSAndrew Jeffery for myfile in filelist: 245369419bafSAndrew Jeffery zf.write(myfile, os.path.basename(myfile)) 245469419bafSAndrew Jeffery zf.close() 245569419bafSAndrew Jeffery print("Zip file with all collected data created and stored in: {fileInfo}".format(fileInfo=myDir+os.sep+filename)) 245669419bafSAndrew Jeffery except Exception as e: 245769419bafSAndrew Jeffery print("Failed to create zip file with collected information") 245869419bafSAndrew Jeffery return "data collection finished" 245969419bafSAndrew Jeffery 246069419bafSAndrew Jeffery 246169419bafSAndrew Jefferydef healthCheck(host, args, session): 246269419bafSAndrew Jeffery """ 246369419bafSAndrew Jeffery runs a health check on the platform 246469419bafSAndrew Jeffery 246569419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 246669419bafSAndrew Jeffery @param args: contains additional arguments used by the bmc sub command 246769419bafSAndrew Jeffery @param session: the active session to use 246869419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 246969419bafSAndrew Jeffery """ 247069419bafSAndrew Jeffery #check fru status and get as json to easily work through 247169419bafSAndrew Jeffery d = vars(args) 247269419bafSAndrew Jeffery useJson = d['json'] 247369419bafSAndrew Jeffery d['json'] = True 247469419bafSAndrew Jeffery d['verbose']= False 247569419bafSAndrew Jeffery 247669419bafSAndrew Jeffery frus = json.loads(fruStatus(host, args, session)) 247769419bafSAndrew Jeffery 247869419bafSAndrew Jeffery hwStatus= "OK" 247969419bafSAndrew Jeffery performanceStatus = "OK" 248069419bafSAndrew Jeffery for key in frus: 248169419bafSAndrew Jeffery if frus[key]["Functional"] == "No" and frus[key]["Present"] == "Yes": 248269419bafSAndrew Jeffery hwStatus= "Degraded" 248369419bafSAndrew Jeffery if("power_supply" in key or "powersupply" in key): 248469419bafSAndrew Jeffery gpuCount =0 248569419bafSAndrew Jeffery for comp in frus: 248669419bafSAndrew Jeffery if "gv100card" in comp: 248769419bafSAndrew Jeffery gpuCount +=1 248869419bafSAndrew Jeffery if gpuCount > 4: 248969419bafSAndrew Jeffery hwStatus = "Critical" 249069419bafSAndrew Jeffery performanceStatus="Degraded" 249169419bafSAndrew Jeffery break; 249269419bafSAndrew Jeffery elif("fan" in key): 249369419bafSAndrew Jeffery hwStatus = "Degraded" 249469419bafSAndrew Jeffery else: 249569419bafSAndrew Jeffery performanceStatus = "Degraded" 249669419bafSAndrew Jeffery if useJson: 249769419bafSAndrew Jeffery output = {"Hardware Status": hwStatus, "Performance": performanceStatus} 249869419bafSAndrew Jeffery output = json.dumps(output, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False) 249969419bafSAndrew Jeffery else: 250069419bafSAndrew Jeffery output = ("Hardware Status: " + hwStatus + 250169419bafSAndrew Jeffery "\nPerformance: " +performanceStatus ) 250269419bafSAndrew Jeffery 250369419bafSAndrew Jeffery 250469419bafSAndrew Jeffery #SW407886: Clear the duplicate entries 250569419bafSAndrew Jeffery #collect the dups 250669419bafSAndrew Jeffery d['devdebug'] = False 250769419bafSAndrew Jeffery sels = json.loads(selPrint(host, args, session)) 250869419bafSAndrew Jeffery logNums2Clr = [] 250969419bafSAndrew Jeffery oldestLogNum={"logNum": "bogus" ,"key" : ""} 251069419bafSAndrew Jeffery count = 0 251169419bafSAndrew Jeffery if sels['numAlerts'] > 0: 251269419bafSAndrew Jeffery for key in sels: 251369419bafSAndrew Jeffery if "numAlerts" in key: 251469419bafSAndrew Jeffery continue 251569419bafSAndrew Jeffery try: 251669419bafSAndrew Jeffery if "slave@00:00/00:00:00:06/sbefifo1-dev0/occ1-dev0" in sels[key]['Message']: 251769419bafSAndrew Jeffery count += 1 251869419bafSAndrew Jeffery if count > 1: 251969419bafSAndrew Jeffery #preserve first occurrence 252069419bafSAndrew Jeffery if sels[key]['timestamp'] < sels[oldestLogNum['key']]['timestamp']: 252169419bafSAndrew Jeffery oldestLogNum['key']=key 252269419bafSAndrew Jeffery oldestLogNum['logNum'] = sels[key]['logNum'] 252369419bafSAndrew Jeffery else: 252469419bafSAndrew Jeffery oldestLogNum['key']=key 252569419bafSAndrew Jeffery oldestLogNum['logNum'] = sels[key]['logNum'] 252669419bafSAndrew Jeffery logNums2Clr.append(sels[key]['logNum']) 252769419bafSAndrew Jeffery except KeyError: 252869419bafSAndrew Jeffery continue 252969419bafSAndrew Jeffery if(count >0): 253069419bafSAndrew Jeffery logNums2Clr.remove(oldestLogNum['logNum']) 253169419bafSAndrew Jeffery #delete the dups 253269419bafSAndrew Jeffery if count >1: 253369419bafSAndrew Jeffery data = "{\"data\": [] }" 253469419bafSAndrew Jeffery for logNum in logNums2Clr: 253569419bafSAndrew Jeffery url = "https://"+ host+ "/xyz/openbmc_project/logging/entry/"+logNum+"/action/Delete" 253669419bafSAndrew Jeffery try: 253769419bafSAndrew Jeffery session.post(url, headers=jsonHeader, data=data, verify=False, timeout=baseTimeout) 253869419bafSAndrew Jeffery except(requests.exceptions.Timeout): 253969419bafSAndrew Jeffery deleteFailed = True 254069419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 254169419bafSAndrew Jeffery deleteFailed = True 254269419bafSAndrew Jeffery #End of defect resolve code 254369419bafSAndrew Jeffery d['json'] = useJson 254469419bafSAndrew Jeffery return output 254569419bafSAndrew Jeffery 254669419bafSAndrew Jeffery 254769419bafSAndrew Jeffery 254869419bafSAndrew Jefferydef bmc(host, args, session): 254969419bafSAndrew Jeffery """ 255069419bafSAndrew Jeffery handles various bmc level commands, currently bmc rebooting 255169419bafSAndrew Jeffery 255269419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 255369419bafSAndrew Jeffery @param args: contains additional arguments used by the bmc sub command 255469419bafSAndrew Jeffery @param session: the active session to use 255569419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 255669419bafSAndrew Jeffery """ 255769419bafSAndrew Jeffery if(args.type is not None): 255869419bafSAndrew Jeffery return bmcReset(host, args, session) 255969419bafSAndrew Jeffery if(args.info): 256069419bafSAndrew Jeffery return "Not implemented at this time" 256169419bafSAndrew Jeffery 256269419bafSAndrew Jeffery 256369419bafSAndrew Jeffery 256469419bafSAndrew Jefferydef bmcReset(host, args, session): 256569419bafSAndrew Jeffery """ 256669419bafSAndrew Jeffery controls resetting the bmc. warm reset reboots the bmc, cold reset removes the configuration and reboots. 256769419bafSAndrew Jeffery 256869419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 256969419bafSAndrew Jeffery @param args: contains additional arguments used by the bmcReset sub command 257069419bafSAndrew Jeffery @param session: the active session to use 257169419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 257269419bafSAndrew Jeffery """ 257369419bafSAndrew Jeffery if checkFWactivation(host, args, session): 257469419bafSAndrew Jeffery return ("BMC reset control disabled during firmware activation") 257569419bafSAndrew Jeffery if(args.type == "warm"): 257669419bafSAndrew Jeffery print("\nAttempting to reboot the BMC...:") 257769419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/state/bmc0/attr/RequestedBMCTransition" 257869419bafSAndrew Jeffery data = '{"data":"xyz.openbmc_project.State.BMC.Transition.Reboot"}' 257969419bafSAndrew Jeffery res = session.put(url, headers=jsonHeader, data=data, verify=False, timeout=baseTimeout) 258069419bafSAndrew Jeffery return res.text 258169419bafSAndrew Jeffery elif(args.type =="cold"): 258269419bafSAndrew Jeffery print("\nAttempting to reboot the BMC...:") 258369419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/state/bmc0/attr/RequestedBMCTransition" 258469419bafSAndrew Jeffery data = '{"data":"xyz.openbmc_project.State.BMC.Transition.Reboot"}' 258569419bafSAndrew Jeffery res = session.put(url, headers=jsonHeader, data=data, verify=False, timeout=baseTimeout) 258669419bafSAndrew Jeffery return res.text 258769419bafSAndrew Jeffery else: 258869419bafSAndrew Jeffery return "invalid command" 258969419bafSAndrew Jeffery 259069419bafSAndrew Jefferydef gardClear(host, args, session): 259169419bafSAndrew Jeffery """ 259269419bafSAndrew Jeffery clears the gard records from the bmc 259369419bafSAndrew Jeffery 259469419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 259569419bafSAndrew Jeffery @param args: contains additional arguments used by the gardClear sub command 259669419bafSAndrew Jeffery @param session: the active session to use 259769419bafSAndrew Jeffery """ 259869419bafSAndrew Jeffery url="https://"+host+"/org/open_power/control/gard/action/Reset" 259969419bafSAndrew Jeffery data = '{"data":[]}' 260069419bafSAndrew Jeffery try: 260169419bafSAndrew Jeffery 260269419bafSAndrew Jeffery res = session.post(url, headers=jsonHeader, data=data, verify=False, timeout=baseTimeout) 260369419bafSAndrew Jeffery if res.status_code == 404: 260469419bafSAndrew Jeffery return "Command not supported by this firmware version" 260569419bafSAndrew Jeffery else: 260669419bafSAndrew Jeffery return res.text 260769419bafSAndrew Jeffery except(requests.exceptions.Timeout): 260869419bafSAndrew Jeffery return connectionErrHandler(args.json, "Timeout", None) 260969419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 261069419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 261169419bafSAndrew Jeffery 261269419bafSAndrew Jefferydef activateFWImage(host, args, session): 261369419bafSAndrew Jeffery """ 261469419bafSAndrew Jeffery activates a firmware image on the bmc 261569419bafSAndrew Jeffery 261669419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 261769419bafSAndrew Jeffery @param args: contains additional arguments used by the fwflash sub command 261869419bafSAndrew Jeffery @param session: the active session to use 261969419bafSAndrew Jeffery @param fwID: the unique ID of the fw image to activate 262069419bafSAndrew Jeffery """ 262169419bafSAndrew Jeffery fwID = args.imageID 262269419bafSAndrew Jeffery 262369419bafSAndrew Jeffery #determine the existing versions 262469419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/software/enumerate" 262569419bafSAndrew Jeffery try: 262669419bafSAndrew Jeffery resp = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 262769419bafSAndrew Jeffery except(requests.exceptions.Timeout): 262869419bafSAndrew Jeffery return connectionErrHandler(args.json, "Timeout", None) 262969419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 263069419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 263169419bafSAndrew Jeffery existingSoftware = json.loads(resp.text)['data'] 263269419bafSAndrew Jeffery altVersionID = '' 263369419bafSAndrew Jeffery versionType = '' 263469419bafSAndrew Jeffery imageKey = '/xyz/openbmc_project/software/'+fwID 263569419bafSAndrew Jeffery if imageKey in existingSoftware: 263669419bafSAndrew Jeffery versionType = existingSoftware[imageKey]['Purpose'] 263769419bafSAndrew Jeffery for key in existingSoftware: 263869419bafSAndrew Jeffery if imageKey == key: 263969419bafSAndrew Jeffery continue 264069419bafSAndrew Jeffery if 'Purpose' in existingSoftware[key]: 264169419bafSAndrew Jeffery if versionType == existingSoftware[key]['Purpose']: 264269419bafSAndrew Jeffery altVersionID = key.split('/')[-1] 264369419bafSAndrew Jeffery 264469419bafSAndrew Jeffery 264569419bafSAndrew Jeffery 264669419bafSAndrew Jeffery 264769419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/software/"+ fwID + "/attr/Priority" 264869419bafSAndrew Jeffery url1="https://"+host+"/xyz/openbmc_project/software/"+ altVersionID + "/attr/Priority" 264969419bafSAndrew Jeffery data = "{\"data\": 0}" 265069419bafSAndrew Jeffery data1 = "{\"data\": 1 }" 265169419bafSAndrew Jeffery try: 265269419bafSAndrew Jeffery resp = session.put(url, headers=jsonHeader, data=data, verify=False, timeout=baseTimeout) 265369419bafSAndrew Jeffery resp1 = session.put(url1, headers=jsonHeader, data=data1, verify=False, timeout=baseTimeout) 265469419bafSAndrew Jeffery except(requests.exceptions.Timeout): 265569419bafSAndrew Jeffery return connectionErrHandler(args.json, "Timeout", None) 265669419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 265769419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 265869419bafSAndrew Jeffery if(not args.json): 265969419bafSAndrew Jeffery if resp.status_code == 200 and resp1.status_code == 200: 266069419bafSAndrew Jeffery return 'Firmware flash and activation completed. Please reboot the bmc and then boot the host OS for the changes to take effect. ' 266169419bafSAndrew Jeffery else: 266269419bafSAndrew Jeffery return "Firmware activation failed." 266369419bafSAndrew Jeffery else: 266469419bafSAndrew Jeffery return resp.text + resp1.text 266569419bafSAndrew Jeffery 266669419bafSAndrew Jefferydef activateStatus(host, args, session): 266769419bafSAndrew Jeffery if checkFWactivation(host, args, session): 266869419bafSAndrew Jeffery return("Firmware is currently being activated. Do not reboot the BMC or start the Host OS") 266969419bafSAndrew Jeffery else: 267069419bafSAndrew Jeffery return("No firmware activations are pending") 267169419bafSAndrew Jeffery 267269419bafSAndrew Jefferydef extractFWimage(path, imageType): 267369419bafSAndrew Jeffery """ 267469419bafSAndrew Jeffery extracts the bmc image and returns information about the package 267569419bafSAndrew Jeffery 267669419bafSAndrew Jeffery @param path: the path and file name of the firmware image 267769419bafSAndrew Jeffery @param imageType: The type of image the user is trying to flash. Host or BMC 267869419bafSAndrew Jeffery @return: the image id associated with the package. returns an empty string on error. 267969419bafSAndrew Jeffery """ 268069419bafSAndrew Jeffery f = tempfile.TemporaryFile() 268169419bafSAndrew Jeffery tmpDir = tempfile.gettempdir() 268269419bafSAndrew Jeffery newImageID = "" 268369419bafSAndrew Jeffery if os.path.exists(path): 268469419bafSAndrew Jeffery try: 268569419bafSAndrew Jeffery imageFile = tarfile.open(path,'r') 268669419bafSAndrew Jeffery contents = imageFile.getmembers() 268769419bafSAndrew Jeffery for tf in contents: 268869419bafSAndrew Jeffery if 'MANIFEST' in tf.name: 268969419bafSAndrew Jeffery imageFile.extract(tf.name, path=tmpDir) 269069419bafSAndrew Jeffery with open(tempfile.gettempdir() +os.sep+ tf.name, 'r') as imageInfo: 269169419bafSAndrew Jeffery for line in imageInfo: 269269419bafSAndrew Jeffery if 'purpose' in line: 269369419bafSAndrew Jeffery purpose = line.split('=')[1] 269469419bafSAndrew Jeffery if imageType not in purpose.split('.')[-1]: 269569419bafSAndrew Jeffery print('The specified image is not for ' + imageType) 269669419bafSAndrew Jeffery print('Please try again with the image for ' + imageType) 269769419bafSAndrew Jeffery return "" 269869419bafSAndrew Jeffery if 'version' == line.split('=')[0]: 269969419bafSAndrew Jeffery version = line.split('=')[1].strip().encode('utf-8') 270069419bafSAndrew Jeffery m = hashlib.sha512() 270169419bafSAndrew Jeffery m.update(version) 270269419bafSAndrew Jeffery newImageID = m.hexdigest()[:8] 270369419bafSAndrew Jeffery break 270469419bafSAndrew Jeffery try: 270569419bafSAndrew Jeffery os.remove(tempfile.gettempdir() +os.sep+ tf.name) 270669419bafSAndrew Jeffery except OSError: 270769419bafSAndrew Jeffery pass 270869419bafSAndrew Jeffery return newImageID 270969419bafSAndrew Jeffery except tarfile.ExtractError as e: 271069419bafSAndrew Jeffery print('Unable to extract information from the firmware file.') 271169419bafSAndrew Jeffery print('Ensure you have write access to the directory: ' + tmpDir) 271269419bafSAndrew Jeffery return newImageID 271369419bafSAndrew Jeffery except tarfile.TarError as e: 271469419bafSAndrew Jeffery print('This is not a valid firmware file.') 271569419bafSAndrew Jeffery return newImageID 271669419bafSAndrew Jeffery print("This is not a valid firmware file.") 271769419bafSAndrew Jeffery return newImageID 271869419bafSAndrew Jeffery else: 271969419bafSAndrew Jeffery print('The filename and path provided are not valid.') 272069419bafSAndrew Jeffery return newImageID 272169419bafSAndrew Jeffery 272269419bafSAndrew Jefferydef getAllFWImageIDs(fwInvDict): 272369419bafSAndrew Jeffery """ 272469419bafSAndrew Jeffery gets a list of all the firmware image IDs 272569419bafSAndrew Jeffery 272669419bafSAndrew Jeffery @param fwInvDict: the dictionary to search for FW image IDs 272769419bafSAndrew Jeffery @return: list containing string representation of the found image ids 272869419bafSAndrew Jeffery """ 272969419bafSAndrew Jeffery idList = [] 273069419bafSAndrew Jeffery for key in fwInvDict: 273169419bafSAndrew Jeffery if 'Version' in fwInvDict[key]: 273269419bafSAndrew Jeffery idList.append(key.split('/')[-1]) 273369419bafSAndrew Jeffery return idList 273469419bafSAndrew Jeffery 273569419bafSAndrew Jefferydef fwFlash(host, args, session): 273669419bafSAndrew Jeffery """ 273769419bafSAndrew Jeffery updates the bmc firmware and pnor firmware 273869419bafSAndrew Jeffery 273969419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 274069419bafSAndrew Jeffery @param args: contains additional arguments used by the fwflash sub command 274169419bafSAndrew Jeffery @param session: the active session to use 274269419bafSAndrew Jeffery """ 274369419bafSAndrew Jeffery d = vars(args) 274469419bafSAndrew Jeffery if(args.type == 'bmc'): 274569419bafSAndrew Jeffery purp = 'BMC' 274669419bafSAndrew Jeffery else: 274769419bafSAndrew Jeffery purp = 'Host' 274869419bafSAndrew Jeffery 274969419bafSAndrew Jeffery #check power state of the machine. No concurrent FW updates allowed 275069419bafSAndrew Jeffery d['powcmd'] = 'status' 275169419bafSAndrew Jeffery powerstate = chassisPower(host, args, session) 275269419bafSAndrew Jeffery if 'Chassis Power State: On' in powerstate: 275369419bafSAndrew Jeffery return("Aborting firmware update. Host is powered on. Please turn off the host and try again.") 275469419bafSAndrew Jeffery 275569419bafSAndrew Jeffery #determine the existing images on the bmc 275669419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/software/enumerate" 275769419bafSAndrew Jeffery try: 275869419bafSAndrew Jeffery resp = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 275969419bafSAndrew Jeffery except(requests.exceptions.Timeout): 276069419bafSAndrew Jeffery return connectionErrHandler(args.json, "Timeout", None) 276169419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 276269419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 276369419bafSAndrew Jeffery oldsoftware = json.loads(resp.text)['data'] 276469419bafSAndrew Jeffery 276569419bafSAndrew Jeffery #Extract the tar and get information from the manifest file 276669419bafSAndrew Jeffery newversionID = extractFWimage(args.fileloc, purp) 276769419bafSAndrew Jeffery if newversionID == "": 276869419bafSAndrew Jeffery return "Unable to verify FW image." 276969419bafSAndrew Jeffery 277069419bafSAndrew Jeffery 277169419bafSAndrew Jeffery #check if the new image is already on the bmc 277269419bafSAndrew Jeffery if newversionID not in getAllFWImageIDs(oldsoftware): 277369419bafSAndrew Jeffery 277469419bafSAndrew Jeffery #upload the file 277569419bafSAndrew Jeffery httpHeader = {'Content-Type':'application/octet-stream'} 277669419bafSAndrew Jeffery httpHeader.update(xAuthHeader) 277769419bafSAndrew Jeffery url="https://"+host+"/upload/image" 277869419bafSAndrew Jeffery data=open(args.fileloc,'rb').read() 277969419bafSAndrew Jeffery print("Uploading file to BMC") 278069419bafSAndrew Jeffery try: 278169419bafSAndrew Jeffery resp = session.post(url, headers=httpHeader, data=data, verify=False) 278269419bafSAndrew Jeffery except(requests.exceptions.Timeout): 278369419bafSAndrew Jeffery return connectionErrHandler(args.json, "Timeout", None) 278469419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 278569419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 278669419bafSAndrew Jeffery if resp.status_code != 200: 278769419bafSAndrew Jeffery return "Failed to upload the file to the bmc" 278869419bafSAndrew Jeffery else: 278969419bafSAndrew Jeffery print("Upload complete.") 279069419bafSAndrew Jeffery 279169419bafSAndrew Jeffery #verify bmc processed the image 279269419bafSAndrew Jeffery software ={} 279369419bafSAndrew Jeffery for i in range(0, 5): 279469419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/software/enumerate" 279569419bafSAndrew Jeffery try: 279669419bafSAndrew Jeffery resp = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 279769419bafSAndrew Jeffery except(requests.exceptions.Timeout): 279869419bafSAndrew Jeffery return connectionErrHandler(args.json, "Timeout", None) 279969419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 280069419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 280169419bafSAndrew Jeffery software = json.loads(resp.text)['data'] 280269419bafSAndrew Jeffery #check if bmc is done processing the new image 280369419bafSAndrew Jeffery if (newversionID in getAllFWImageIDs(software)): 280469419bafSAndrew Jeffery break 280569419bafSAndrew Jeffery else: 280669419bafSAndrew Jeffery time.sleep(15) 280769419bafSAndrew Jeffery 280869419bafSAndrew Jeffery #activate the new image 280969419bafSAndrew Jeffery print("Activating new image: "+newversionID) 281069419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/software/"+ newversionID + "/attr/RequestedActivation" 281169419bafSAndrew Jeffery data = '{"data":"xyz.openbmc_project.Software.Activation.RequestedActivations.Active"}' 281269419bafSAndrew Jeffery try: 281369419bafSAndrew Jeffery resp = session.put(url, headers=jsonHeader, data=data, verify=False, timeout=baseTimeout) 281469419bafSAndrew Jeffery except(requests.exceptions.Timeout): 281569419bafSAndrew Jeffery return connectionErrHandler(args.json, "Timeout", None) 281669419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 281769419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 281869419bafSAndrew Jeffery 281969419bafSAndrew Jeffery #wait for the activation to complete, timeout after ~1 hour 282069419bafSAndrew Jeffery i=0 282169419bafSAndrew Jeffery while i < 360: 282269419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/software/"+ newversionID 282369419bafSAndrew Jeffery data = '{"data":"xyz.openbmc_project.Software.Activation.RequestedActivations.Active"}' 282469419bafSAndrew Jeffery try: 282569419bafSAndrew Jeffery resp = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 282669419bafSAndrew Jeffery except(requests.exceptions.Timeout): 282769419bafSAndrew Jeffery return connectionErrHandler(args.json, "Timeout", None) 282869419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 282969419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 283069419bafSAndrew Jeffery fwInfo = json.loads(resp.text)['data'] 283169419bafSAndrew Jeffery if 'Activating' not in fwInfo['Activation'] and 'Activating' not in fwInfo['RequestedActivation']: 283269419bafSAndrew Jeffery print('') 283369419bafSAndrew Jeffery break 283469419bafSAndrew Jeffery else: 283569419bafSAndrew Jeffery sys.stdout.write('.') 283669419bafSAndrew Jeffery sys.stdout.flush() 283769419bafSAndrew Jeffery time.sleep(10) #check every 10 seconds 283869419bafSAndrew Jeffery return "Firmware flash and activation completed. Please reboot the bmc and then boot the host OS for the changes to take effect. " 283969419bafSAndrew Jeffery else: 284069419bafSAndrew Jeffery print("This image has been found on the bmc. Activating image: " + newversionID) 284169419bafSAndrew Jeffery 284269419bafSAndrew Jeffery d['imageID'] = newversionID 284369419bafSAndrew Jeffery return activateFWImage(host, args, session) 284469419bafSAndrew Jeffery 284569419bafSAndrew Jefferydef getFWInventoryAttributes(rawFWInvItem, ID): 284669419bafSAndrew Jeffery """ 284769419bafSAndrew Jeffery gets and lists all of the firmware in the system. 284869419bafSAndrew Jeffery 284969419bafSAndrew Jeffery @return: returns a dictionary containing the image attributes 285069419bafSAndrew Jeffery """ 285169419bafSAndrew Jeffery reqActivation = rawFWInvItem["RequestedActivation"].split('.')[-1] 285269419bafSAndrew Jeffery pendingActivation = "" 285369419bafSAndrew Jeffery if reqActivation == "None": 285469419bafSAndrew Jeffery pendingActivation = "No" 285569419bafSAndrew Jeffery else: 285669419bafSAndrew Jeffery pendingActivation = "Yes" 285769419bafSAndrew Jeffery firmwareAttr = {ID: { 285869419bafSAndrew Jeffery "Purpose": rawFWInvItem["Purpose"].split('.')[-1], 285969419bafSAndrew Jeffery "Version": rawFWInvItem["Version"], 286069419bafSAndrew Jeffery "RequestedActivation": pendingActivation, 286169419bafSAndrew Jeffery "ID": ID}} 286269419bafSAndrew Jeffery 286369419bafSAndrew Jeffery if "ExtendedVersion" in rawFWInvItem: 286469419bafSAndrew Jeffery firmwareAttr[ID]['ExtendedVersion'] = rawFWInvItem['ExtendedVersion'].split(',') 286569419bafSAndrew Jeffery else: 286669419bafSAndrew Jeffery firmwareAttr[ID]['ExtendedVersion'] = "" 286769419bafSAndrew Jeffery return firmwareAttr 286869419bafSAndrew Jeffery 286969419bafSAndrew Jefferydef parseFWdata(firmwareDict): 287069419bafSAndrew Jeffery """ 287169419bafSAndrew Jeffery creates a dictionary with parsed firmware data 287269419bafSAndrew Jeffery 287369419bafSAndrew Jeffery @return: returns a dictionary containing the image attributes 287469419bafSAndrew Jeffery """ 287569419bafSAndrew Jeffery firmwareInfoDict = {"Functional": {}, "Activated":{}, "NeedsActivated":{}} 287669419bafSAndrew Jeffery for key in firmwareDict['data']: 287769419bafSAndrew Jeffery #check for valid endpoint 287869419bafSAndrew Jeffery if "Purpose" in firmwareDict['data'][key]: 287969419bafSAndrew Jeffery id = key.split('/')[-1] 288069419bafSAndrew Jeffery if firmwareDict['data'][key]['Activation'].split('.')[-1] == "Active": 288169419bafSAndrew Jeffery fwActivated = True 288269419bafSAndrew Jeffery else: 288369419bafSAndrew Jeffery fwActivated = False 288469419bafSAndrew Jeffery if 'Priority' in firmwareDict['data'][key]: 288569419bafSAndrew Jeffery if firmwareDict['data'][key]['Priority'] == 0: 288669419bafSAndrew Jeffery firmwareInfoDict['Functional'].update(getFWInventoryAttributes(firmwareDict['data'][key], id)) 288769419bafSAndrew Jeffery elif firmwareDict['data'][key]['Priority'] >= 0 and fwActivated: 288869419bafSAndrew Jeffery firmwareInfoDict['Activated'].update(getFWInventoryAttributes(firmwareDict['data'][key], id)) 288969419bafSAndrew Jeffery else: 289069419bafSAndrew Jeffery firmwareInfoDict['NeedsActivated'].update(getFWInventoryAttributes(firmwareDict['data'][key], id)) 289169419bafSAndrew Jeffery else: 289269419bafSAndrew Jeffery firmwareInfoDict['NeedsActivated'].update(getFWInventoryAttributes(firmwareDict['data'][key], id)) 289369419bafSAndrew Jeffery emptySections = [] 289469419bafSAndrew Jeffery for key in firmwareInfoDict: 289569419bafSAndrew Jeffery if len(firmwareInfoDict[key])<=0: 289669419bafSAndrew Jeffery emptySections.append(key) 289769419bafSAndrew Jeffery for key in emptySections: 289869419bafSAndrew Jeffery del firmwareInfoDict[key] 289969419bafSAndrew Jeffery return firmwareInfoDict 290069419bafSAndrew Jeffery 290169419bafSAndrew Jefferydef displayFWInvenory(firmwareInfoDict, args): 290269419bafSAndrew Jeffery """ 290369419bafSAndrew Jeffery gets and lists all of the firmware in the system. 290469419bafSAndrew Jeffery 290569419bafSAndrew Jeffery @return: returns a string containing all of the firmware information 290669419bafSAndrew Jeffery """ 290769419bafSAndrew Jeffery output = "" 290869419bafSAndrew Jeffery if not args.json: 290969419bafSAndrew Jeffery for key in firmwareInfoDict: 291069419bafSAndrew Jeffery for subkey in firmwareInfoDict[key]: 291169419bafSAndrew Jeffery firmwareInfoDict[key][subkey]['ExtendedVersion'] = str(firmwareInfoDict[key][subkey]['ExtendedVersion']) 291269419bafSAndrew Jeffery if not args.verbose: 291369419bafSAndrew Jeffery output = "---Running Images---\n" 291469419bafSAndrew Jeffery colNames = ["Purpose", "Version", "ID"] 291569419bafSAndrew Jeffery keylist = ["Purpose", "Version", "ID"] 291669419bafSAndrew Jeffery output += tableDisplay(keylist, colNames, firmwareInfoDict["Functional"]) 291769419bafSAndrew Jeffery if "Activated" in firmwareInfoDict: 291869419bafSAndrew Jeffery output += "\n---Available Images---\n" 291969419bafSAndrew Jeffery output += tableDisplay(keylist, colNames, firmwareInfoDict["Activated"]) 292069419bafSAndrew Jeffery if "NeedsActivated" in firmwareInfoDict: 292169419bafSAndrew Jeffery output += "\n---Needs Activated Images---\n" 292269419bafSAndrew Jeffery output += tableDisplay(keylist, colNames, firmwareInfoDict["NeedsActivated"]) 292369419bafSAndrew Jeffery 292469419bafSAndrew Jeffery else: 292569419bafSAndrew Jeffery output = "---Running Images---\n" 292669419bafSAndrew Jeffery colNames = ["Purpose", "Version", "ID", "Pending Activation", "Extended Version"] 292769419bafSAndrew Jeffery keylist = ["Purpose", "Version", "ID", "RequestedActivation", "ExtendedVersion"] 292869419bafSAndrew Jeffery output += tableDisplay(keylist, colNames, firmwareInfoDict["Functional"]) 292969419bafSAndrew Jeffery if "Activated" in firmwareInfoDict: 293069419bafSAndrew Jeffery output += "\n---Available Images---\n" 293169419bafSAndrew Jeffery output += tableDisplay(keylist, colNames, firmwareInfoDict["Activated"]) 293269419bafSAndrew Jeffery if "NeedsActivated" in firmwareInfoDict: 293369419bafSAndrew Jeffery output += "\n---Needs Activated Images---\n" 293469419bafSAndrew Jeffery output += tableDisplay(keylist, colNames, firmwareInfoDict["NeedsActivated"]) 293569419bafSAndrew Jeffery return output 293669419bafSAndrew Jeffery else: 293769419bafSAndrew Jeffery return str(json.dumps(firmwareInfoDict, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False)) 293869419bafSAndrew Jeffery 293969419bafSAndrew Jefferydef firmwareList(host, args, session): 294069419bafSAndrew Jeffery """ 294169419bafSAndrew Jeffery gets and lists all of the firmware in the system. 294269419bafSAndrew Jeffery 294369419bafSAndrew Jeffery @return: returns a string containing all of the firmware information 294469419bafSAndrew Jeffery """ 294569419bafSAndrew Jeffery url="https://{hostname}/xyz/openbmc_project/software/enumerate".format(hostname=host) 294669419bafSAndrew Jeffery try: 294769419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 294869419bafSAndrew Jeffery except(requests.exceptions.Timeout): 294969419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 295069419bafSAndrew Jeffery firmwareDict = json.loads(res.text) 295169419bafSAndrew Jeffery 295269419bafSAndrew Jeffery #sort the received information 295369419bafSAndrew Jeffery firmwareInfoDict = parseFWdata(firmwareDict) 295469419bafSAndrew Jeffery 295569419bafSAndrew Jeffery #display the information 295669419bafSAndrew Jeffery return displayFWInvenory(firmwareInfoDict, args) 295769419bafSAndrew Jeffery 295869419bafSAndrew Jeffery 295969419bafSAndrew Jefferydef deleteFWVersion(host, args, session): 296069419bafSAndrew Jeffery """ 296169419bafSAndrew Jeffery deletes a firmware version on the BMC 296269419bafSAndrew Jeffery 296369419bafSAndrew Jeffery @param host: string, the hostname or IP address of the BMC 296469419bafSAndrew Jeffery @param args: contains additional arguments used by the fwflash sub command 296569419bafSAndrew Jeffery @param session: the active session to use 296669419bafSAndrew Jeffery @param fwID: the unique ID of the fw version to delete 296769419bafSAndrew Jeffery """ 296869419bafSAndrew Jeffery fwID = args.versionID 296969419bafSAndrew Jeffery 297069419bafSAndrew Jeffery print("Deleting version: "+fwID) 297169419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/software/"+ fwID + "/action/Delete" 297269419bafSAndrew Jeffery data = "{\"data\": [] }" 297369419bafSAndrew Jeffery 297469419bafSAndrew Jeffery try: 297569419bafSAndrew Jeffery res = session.post(url, headers=jsonHeader, data=data, verify=False, timeout=baseTimeout) 297669419bafSAndrew Jeffery except(requests.exceptions.Timeout): 297769419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 297869419bafSAndrew Jeffery if res.status_code == 200: 297969419bafSAndrew Jeffery return ('The firmware version has been deleted') 298069419bafSAndrew Jeffery else: 298169419bafSAndrew Jeffery return ('Unable to delete the specified firmware version') 298269419bafSAndrew Jeffery 29830b5b2041SKlaus Heinrich Kiwidef deleteFWAll(host, args, session): 29840b5b2041SKlaus Heinrich Kiwi """ 29850b5b2041SKlaus Heinrich Kiwi deletes ALL contents for firmware software catalog 29860b5b2041SKlaus Heinrich Kiwi 29870b5b2041SKlaus Heinrich Kiwi @param host: string, the hostname or IP address of the BMC 29880b5b2041SKlaus Heinrich Kiwi @param args: contains additional arguments used by the fwflash sub command 29890b5b2041SKlaus Heinrich Kiwi @param session: the active session to use 29900b5b2041SKlaus Heinrich Kiwi """ 29910b5b2041SKlaus Heinrich Kiwi 29920b5b2041SKlaus Heinrich Kiwi print("Deleting ALL firmware versions") 29930b5b2041SKlaus Heinrich Kiwi url="https://"+host+"/xyz/openbmc_project/software/action/DeleteAll" 29940b5b2041SKlaus Heinrich Kiwi data = "{\"data\": [] }" 29950b5b2041SKlaus Heinrich Kiwi 29960b5b2041SKlaus Heinrich Kiwi try: 29970b5b2041SKlaus Heinrich Kiwi res = session.post(url, headers=jsonHeader, data=data, verify=False, timeout=baseTimeout) 29980b5b2041SKlaus Heinrich Kiwi except(requests.exceptions.Timeout): 29990b5b2041SKlaus Heinrich Kiwi return(connectionErrHandler(args.json, "Timeout", None)) 30000b5b2041SKlaus Heinrich Kiwi if res.status_code == 200: 30010b5b2041SKlaus Heinrich Kiwi return ('All firmware versions were deleted') 30020b5b2041SKlaus Heinrich Kiwi else: 30030b5b2041SKlaus Heinrich Kiwi return ('Uspecified error while deleting All firmware versions') 30040b5b2041SKlaus Heinrich Kiwi 300569419bafSAndrew Jeffery 300669419bafSAndrew Jefferydef restLogging(host, args, session): 300769419bafSAndrew Jeffery """ 300869419bafSAndrew Jeffery Called by the logging function. Turns REST API logging on/off. 300969419bafSAndrew Jeffery 301069419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 301169419bafSAndrew Jeffery @param args: contains additional arguments used by the logging sub command 301269419bafSAndrew Jeffery @param session: the active session to use 301369419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 301469419bafSAndrew Jeffery """ 301569419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/logging/rest_api_logs/attr/Enabled" 301669419bafSAndrew Jeffery 301769419bafSAndrew Jeffery if(args.rest_logging == 'on'): 301869419bafSAndrew Jeffery data = '{"data": 1}' 301969419bafSAndrew Jeffery elif(args.rest_logging == 'off'): 302069419bafSAndrew Jeffery data = '{"data": 0}' 302169419bafSAndrew Jeffery else: 302269419bafSAndrew Jeffery return "Invalid logging rest_api command" 302369419bafSAndrew Jeffery 302469419bafSAndrew Jeffery try: 302569419bafSAndrew Jeffery res = session.put(url, headers=jsonHeader, data=data, verify=False, timeout=baseTimeout) 302669419bafSAndrew Jeffery except(requests.exceptions.Timeout): 302769419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 302869419bafSAndrew Jeffery return res.text 302969419bafSAndrew Jeffery 303069419bafSAndrew Jeffery 303169419bafSAndrew Jefferydef remoteLogging(host, args, session): 303269419bafSAndrew Jeffery """ 303369419bafSAndrew Jeffery Called by the logging function. View config information for/disable remote logging (rsyslog). 303469419bafSAndrew Jeffery 303569419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 303669419bafSAndrew Jeffery @param args: contains additional arguments used by the logging sub command 303769419bafSAndrew Jeffery @param session: the active session to use 303869419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 303969419bafSAndrew Jeffery """ 304069419bafSAndrew Jeffery 304169419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/logging/config/remote" 304269419bafSAndrew Jeffery 304369419bafSAndrew Jeffery try: 304469419bafSAndrew Jeffery if(args.remote_logging == 'view'): 304569419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 304669419bafSAndrew Jeffery elif(args.remote_logging == 'disable'): 304769419bafSAndrew Jeffery res = session.put(url + '/attr/Port', headers=jsonHeader, json = {"data": 0}, verify=False, timeout=baseTimeout) 304869419bafSAndrew Jeffery res = session.put(url + '/attr/Address', headers=jsonHeader, json = {"data": ""}, verify=False, timeout=baseTimeout) 304969419bafSAndrew Jeffery else: 305069419bafSAndrew Jeffery return "Invalid logging remote_logging command" 305169419bafSAndrew Jeffery except(requests.exceptions.Timeout): 305269419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 305369419bafSAndrew Jeffery return res.text 305469419bafSAndrew Jeffery 305569419bafSAndrew Jeffery 305669419bafSAndrew Jefferydef remoteLoggingConfig(host, args, session): 305769419bafSAndrew Jeffery """ 305869419bafSAndrew Jeffery Called by the logging function. Configures remote logging (rsyslog). 305969419bafSAndrew Jeffery 306069419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 306169419bafSAndrew Jeffery @param args: contains additional arguments used by the logging sub command 306269419bafSAndrew Jeffery @param session: the active session to use 306369419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will be provided in json format for programmatic consumption 306469419bafSAndrew Jeffery """ 306569419bafSAndrew Jeffery 306669419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/logging/config/remote" 306769419bafSAndrew Jeffery 306869419bafSAndrew Jeffery try: 306969419bafSAndrew Jeffery res = session.put(url + '/attr/Port', headers=jsonHeader, json = {"data": args.port}, verify=False, timeout=baseTimeout) 307069419bafSAndrew Jeffery res = session.put(url + '/attr/Address', headers=jsonHeader, json = {"data": args.address}, verify=False, timeout=baseTimeout) 307169419bafSAndrew Jeffery except(requests.exceptions.Timeout): 307269419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 307369419bafSAndrew Jeffery return res.text 307469419bafSAndrew Jeffery 307569419bafSAndrew Jefferydef redfishSupportPresent(host, session): 307669419bafSAndrew Jeffery url = "https://" + host + "/redfish/v1" 307769419bafSAndrew Jeffery try: 307869419bafSAndrew Jeffery resp = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 307969419bafSAndrew Jeffery except(requests.exceptions.Timeout): 308069419bafSAndrew Jeffery return False 308169419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 308269419bafSAndrew Jeffery return False 308369419bafSAndrew Jeffery if resp.status_code != 200: 308469419bafSAndrew Jeffery return False 308569419bafSAndrew Jeffery else: 308669419bafSAndrew Jeffery return True 308769419bafSAndrew Jeffery 308869419bafSAndrew Jefferydef certificateUpdate(host, args, session): 308969419bafSAndrew Jeffery """ 309069419bafSAndrew Jeffery Called by certificate management function. update server/client/authority certificates 309169419bafSAndrew Jeffery Example: 309269419bafSAndrew Jeffery certificate update server https -f cert.pem 309369419bafSAndrew Jeffery certificate update authority ldap -f Root-CA.pem 309469419bafSAndrew Jeffery certificate update client ldap -f cert.pem 309569419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 309669419bafSAndrew Jeffery @param args: contains additional arguments used by the certificate update sub command 309769419bafSAndrew Jeffery @param session: the active session to use 309869419bafSAndrew Jeffery """ 309969419bafSAndrew Jeffery httpHeader = {'Content-Type': 'application/octet-stream'} 310069419bafSAndrew Jeffery httpHeader.update(xAuthHeader) 310169419bafSAndrew Jeffery data = open(args.fileloc, 'r').read() 310269419bafSAndrew Jeffery try: 310369419bafSAndrew Jeffery if redfishSupportPresent(host, session): 310469419bafSAndrew Jeffery if(args.type.lower() == 'server' and args.service.lower() != "https"): 310569419bafSAndrew Jeffery return "Invalid service type" 310669419bafSAndrew Jeffery if(args.type.lower() == 'client' and args.service.lower() != "ldap"): 310769419bafSAndrew Jeffery return "Invalid service type" 310869419bafSAndrew Jeffery if(args.type.lower() == 'authority' and args.service.lower() != "ldap"): 310969419bafSAndrew Jeffery return "Invalid service type" 311069419bafSAndrew Jeffery url = ""; 311169419bafSAndrew Jeffery if(args.type.lower() == 'server'): 311269419bafSAndrew Jeffery url = "https://" + host + \ 311369419bafSAndrew Jeffery "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates" 311469419bafSAndrew Jeffery elif(args.type.lower() == 'client'): 311569419bafSAndrew Jeffery url = "https://" + host + \ 311669419bafSAndrew Jeffery "/redfish/v1/AccountService/LDAP/Certificates" 311769419bafSAndrew Jeffery elif(args.type.lower() == 'authority'): 311869419bafSAndrew Jeffery url = "https://" + host + \ 311969419bafSAndrew Jeffery "/redfish/v1/Managers/bmc/Truststore/Certificates" 312069419bafSAndrew Jeffery else: 312169419bafSAndrew Jeffery return "Unsupported certificate type" 312269419bafSAndrew Jeffery resp = session.post(url, headers=httpHeader, data=data, 312369419bafSAndrew Jeffery verify=False) 312469419bafSAndrew Jeffery else: 312569419bafSAndrew Jeffery url = "https://" + host + "/xyz/openbmc_project/certs/" + \ 312669419bafSAndrew Jeffery args.type.lower() + "/" + args.service.lower() 312769419bafSAndrew Jeffery resp = session.put(url, headers=httpHeader, data=data, verify=False) 312869419bafSAndrew Jeffery except(requests.exceptions.Timeout): 312969419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 313069419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 313169419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 313269419bafSAndrew Jeffery if resp.status_code != 200: 313369419bafSAndrew Jeffery print(resp.text) 313469419bafSAndrew Jeffery return "Failed to update the certificate" 313569419bafSAndrew Jeffery else: 313669419bafSAndrew Jeffery print("Update complete.") 313769419bafSAndrew Jeffery 313869419bafSAndrew Jefferydef certificateDelete(host, args, session): 313969419bafSAndrew Jeffery """ 314069419bafSAndrew Jeffery Called by certificate management function to delete certificate 314169419bafSAndrew Jeffery Example: 314269419bafSAndrew Jeffery certificate delete server https 314369419bafSAndrew Jeffery certificate delete authority ldap 314469419bafSAndrew Jeffery certificate delete client ldap 314569419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 314669419bafSAndrew Jeffery @param args: contains additional arguments used by the certificate delete sub command 314769419bafSAndrew Jeffery @param session: the active session to use 314869419bafSAndrew Jeffery """ 314969419bafSAndrew Jeffery if redfishSupportPresent(host, session): 315069419bafSAndrew Jeffery return "Not supported, please use certificate replace instead"; 315169419bafSAndrew Jeffery httpHeader = {'Content-Type': 'multipart/form-data'} 315269419bafSAndrew Jeffery httpHeader.update(xAuthHeader) 315369419bafSAndrew Jeffery url = "https://" + host + "/xyz/openbmc_project/certs/" + args.type.lower() + "/" + args.service.lower() 315469419bafSAndrew Jeffery print("Deleting certificate url=" + url) 315569419bafSAndrew Jeffery try: 315669419bafSAndrew Jeffery resp = session.delete(url, headers=httpHeader) 315769419bafSAndrew Jeffery except(requests.exceptions.Timeout): 315869419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 315969419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 316069419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 316169419bafSAndrew Jeffery if resp.status_code != 200: 316269419bafSAndrew Jeffery print(resp.text) 316369419bafSAndrew Jeffery return "Failed to delete the certificate" 316469419bafSAndrew Jeffery else: 316569419bafSAndrew Jeffery print("Delete complete.") 316669419bafSAndrew Jeffery 316769419bafSAndrew Jefferydef certificateReplace(host, args, session): 316869419bafSAndrew Jeffery """ 316969419bafSAndrew Jeffery Called by certificate management function. replace server/client/ 317069419bafSAndrew Jeffery authority certificates 317169419bafSAndrew Jeffery Example: 317269419bafSAndrew Jeffery certificate replace server https -f cert.pem 317369419bafSAndrew Jeffery certificate replace authority ldap -f Root-CA.pem 317469419bafSAndrew Jeffery certificate replace client ldap -f cert.pem 317569419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 317669419bafSAndrew Jeffery @param args: contains additional arguments used by the certificate 317769419bafSAndrew Jeffery replace sub command 317869419bafSAndrew Jeffery @param session: the active session to use 317969419bafSAndrew Jeffery """ 318069419bafSAndrew Jeffery cert = open(args.fileloc, 'r').read() 318169419bafSAndrew Jeffery try: 318269419bafSAndrew Jeffery if redfishSupportPresent(host, session): 318369419bafSAndrew Jeffery httpHeader = {'Content-Type': 'application/json'} 318469419bafSAndrew Jeffery httpHeader.update(xAuthHeader) 318569419bafSAndrew Jeffery url = ""; 318669419bafSAndrew Jeffery if(args.type.lower() == 'server' and args.service.lower() != "https"): 318769419bafSAndrew Jeffery return "Invalid service type" 318869419bafSAndrew Jeffery if(args.type.lower() == 'client' and args.service.lower() != "ldap"): 318969419bafSAndrew Jeffery return "Invalid service type" 319069419bafSAndrew Jeffery if(args.type.lower() == 'authority' and args.service.lower() != "ldap"): 319169419bafSAndrew Jeffery return "Invalid service type" 319269419bafSAndrew Jeffery if(args.type.lower() == 'server'): 319369419bafSAndrew Jeffery url = "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/1" 319469419bafSAndrew Jeffery elif(args.type.lower() == 'client'): 319569419bafSAndrew Jeffery url = "/redfish/v1/AccountService/LDAP/Certificates/1" 319669419bafSAndrew Jeffery elif(args.type.lower() == 'authority'): 319769419bafSAndrew Jeffery url = "/redfish/v1/Managers/bmc/Truststore/Certificates/1" 319869419bafSAndrew Jeffery replaceUrl = "https://" + host + \ 319969419bafSAndrew Jeffery "/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate" 320069419bafSAndrew Jeffery data ={"CertificateUri":{"@odata.id":url}, "CertificateType":"PEM", 320169419bafSAndrew Jeffery "CertificateString":cert} 320269419bafSAndrew Jeffery resp = session.post(replaceUrl, headers=httpHeader, json=data, verify=False) 320369419bafSAndrew Jeffery else: 320469419bafSAndrew Jeffery httpHeader = {'Content-Type': 'application/octet-stream'} 320569419bafSAndrew Jeffery httpHeader.update(xAuthHeader) 320669419bafSAndrew Jeffery url = "https://" + host + "/xyz/openbmc_project/certs/" + \ 320769419bafSAndrew Jeffery args.type.lower() + "/" + args.service.lower() 320869419bafSAndrew Jeffery resp = session.delete(url, headers=httpHeader) 320969419bafSAndrew Jeffery resp = session.put(url, headers=httpHeader, data=cert, verify=False) 321069419bafSAndrew Jeffery except(requests.exceptions.Timeout): 321169419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 321269419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 321369419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 321469419bafSAndrew Jeffery if resp.status_code != 200: 321569419bafSAndrew Jeffery print(resp.text) 321669419bafSAndrew Jeffery return "Failed to replace the certificate" 321769419bafSAndrew Jeffery else: 321869419bafSAndrew Jeffery print("Replace complete.") 321969419bafSAndrew Jeffery return resp.text 322069419bafSAndrew Jeffery 322169419bafSAndrew Jefferydef certificateDisplay(host, args, session): 322269419bafSAndrew Jeffery """ 322369419bafSAndrew Jeffery Called by certificate management function. display server/client/ 322469419bafSAndrew Jeffery authority certificates 322569419bafSAndrew Jeffery Example: 322669419bafSAndrew Jeffery certificate display server 322769419bafSAndrew Jeffery certificate display authority 322869419bafSAndrew Jeffery certificate display client 322969419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 323069419bafSAndrew Jeffery @param args: contains additional arguments used by the certificate 323169419bafSAndrew Jeffery display sub command 323269419bafSAndrew Jeffery @param session: the active session to use 323369419bafSAndrew Jeffery """ 323469419bafSAndrew Jeffery if not redfishSupportPresent(host, session): 323569419bafSAndrew Jeffery return "Not supported"; 323669419bafSAndrew Jeffery 323769419bafSAndrew Jeffery httpHeader = {'Content-Type': 'application/octet-stream'} 323869419bafSAndrew Jeffery httpHeader.update(xAuthHeader) 323969419bafSAndrew Jeffery if(args.type.lower() == 'server'): 324069419bafSAndrew Jeffery url = "https://" + host + \ 324169419bafSAndrew Jeffery "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/1" 324269419bafSAndrew Jeffery elif(args.type.lower() == 'client'): 324369419bafSAndrew Jeffery url = "https://" + host + \ 324469419bafSAndrew Jeffery "/redfish/v1/AccountService/LDAP/Certificates/1" 324569419bafSAndrew Jeffery elif(args.type.lower() == 'authority'): 324669419bafSAndrew Jeffery url = "https://" + host + \ 324769419bafSAndrew Jeffery "/redfish/v1/Managers/bmc/Truststore/Certificates/1" 324869419bafSAndrew Jeffery try: 324969419bafSAndrew Jeffery resp = session.get(url, headers=httpHeader, verify=False) 325069419bafSAndrew Jeffery except(requests.exceptions.Timeout): 325169419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 325269419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 325369419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 325469419bafSAndrew Jeffery if resp.status_code != 200: 325569419bafSAndrew Jeffery print(resp.text) 325669419bafSAndrew Jeffery return "Failed to display the certificate" 325769419bafSAndrew Jeffery else: 325869419bafSAndrew Jeffery print("Display complete.") 325969419bafSAndrew Jeffery return resp.text 326069419bafSAndrew Jeffery 326169419bafSAndrew Jefferydef certificateList(host, args, session): 326269419bafSAndrew Jeffery """ 326369419bafSAndrew Jeffery Called by certificate management function. 326469419bafSAndrew Jeffery Example: 326569419bafSAndrew Jeffery certificate list 326669419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 326769419bafSAndrew Jeffery @param args: contains additional arguments used by the certificate 326869419bafSAndrew Jeffery list sub command 326969419bafSAndrew Jeffery @param session: the active session to use 327069419bafSAndrew Jeffery """ 327169419bafSAndrew Jeffery if not redfishSupportPresent(host, session): 327269419bafSAndrew Jeffery return "Not supported"; 327369419bafSAndrew Jeffery 327469419bafSAndrew Jeffery httpHeader = {'Content-Type': 'application/octet-stream'} 327569419bafSAndrew Jeffery httpHeader.update(xAuthHeader) 327669419bafSAndrew Jeffery url = "https://" + host + \ 327769419bafSAndrew Jeffery "/redfish/v1/CertificateService/CertificateLocations/" 327869419bafSAndrew Jeffery try: 327969419bafSAndrew Jeffery resp = session.get(url, headers=httpHeader, verify=False) 328069419bafSAndrew Jeffery except(requests.exceptions.Timeout): 328169419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 328269419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 328369419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 328469419bafSAndrew Jeffery if resp.status_code != 200: 328569419bafSAndrew Jeffery print(resp.text) 328669419bafSAndrew Jeffery return "Failed to list certificates" 328769419bafSAndrew Jeffery else: 328869419bafSAndrew Jeffery print("List certificates complete.") 328969419bafSAndrew Jeffery return resp.text 329069419bafSAndrew Jeffery 329169419bafSAndrew Jefferydef certificateGenerateCSR(host, args, session): 329269419bafSAndrew Jeffery """ 329369419bafSAndrew Jeffery Called by certificate management function. Generate CSR for server/ 329469419bafSAndrew Jeffery client certificates 329569419bafSAndrew Jeffery Example: 329669419bafSAndrew Jeffery certificate generatecsr server NJ w3.ibm.com US IBM IBM-UNIT NY EC prime256v1 cp abc.com an.com,bm.com gn sn un in 329769419bafSAndrew Jeffery certificate generatecsr client NJ w3.ibm.com US IBM IBM-UNIT NY EC prime256v1 cp abc.com an.com,bm.com gn sn un in 329869419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 329969419bafSAndrew Jeffery @param args: contains additional arguments used by the certificate replace sub command 330069419bafSAndrew Jeffery @param session: the active session to use 330169419bafSAndrew Jeffery """ 330269419bafSAndrew Jeffery if not redfishSupportPresent(host, session): 330369419bafSAndrew Jeffery return "Not supported"; 330469419bafSAndrew Jeffery 330569419bafSAndrew Jeffery httpHeader = {'Content-Type': 'application/octet-stream'} 330669419bafSAndrew Jeffery httpHeader.update(xAuthHeader) 330769419bafSAndrew Jeffery url = ""; 330869419bafSAndrew Jeffery if(args.type.lower() == 'server'): 330969419bafSAndrew Jeffery url = "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/" 331069419bafSAndrew Jeffery usage_list = ["ServerAuthentication"] 331169419bafSAndrew Jeffery elif(args.type.lower() == 'client'): 331269419bafSAndrew Jeffery url = "/redfish/v1/AccountService/LDAP/Certificates/" 331369419bafSAndrew Jeffery usage_list = ["ClientAuthentication"] 331469419bafSAndrew Jeffery elif(args.type.lower() == 'authority'): 331569419bafSAndrew Jeffery url = "/redfish/v1/Managers/bmc/Truststore/Certificates/" 331669419bafSAndrew Jeffery print("Generating CSR url=" + url) 331769419bafSAndrew Jeffery generateCSRUrl = "https://" + host + \ 331869419bafSAndrew Jeffery "/redfish/v1/CertificateService/Actions/CertificateService.GenerateCSR" 331969419bafSAndrew Jeffery try: 332069419bafSAndrew Jeffery alt_name_list = args.alternativeNames.split(",") 332169419bafSAndrew Jeffery data ={"CertificateCollection":{"@odata.id":url}, 332269419bafSAndrew Jeffery "CommonName":args.commonName, "City":args.city, 332369419bafSAndrew Jeffery "Country":args.country, "Organization":args.organization, 332469419bafSAndrew Jeffery "OrganizationalUnit":args.organizationUnit, "State":args.state, 332569419bafSAndrew Jeffery "KeyPairAlgorithm":args.keyPairAlgorithm, "KeyCurveId":args.keyCurveId, 332669419bafSAndrew Jeffery "AlternativeNames":alt_name_list, "ContactPerson":args.contactPerson, 332769419bafSAndrew Jeffery "Email":args.email, "GivenName":args.givenname, "Initials":args.initials, 332869419bafSAndrew Jeffery "KeyUsage":usage_list, "Surname":args.surname, 332969419bafSAndrew Jeffery "UnstructuredName":args.unstructuredname} 333069419bafSAndrew Jeffery resp = session.post(generateCSRUrl, headers=httpHeader, 333169419bafSAndrew Jeffery json=data, verify=False) 333269419bafSAndrew Jeffery except(requests.exceptions.Timeout): 333369419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 333469419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 333569419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 333669419bafSAndrew Jeffery if resp.status_code != 200: 333769419bafSAndrew Jeffery print(resp.text) 333869419bafSAndrew Jeffery return "Failed to generate CSR" 333969419bafSAndrew Jeffery else: 334069419bafSAndrew Jeffery print("GenerateCSR complete.") 334169419bafSAndrew Jeffery return resp.text 334269419bafSAndrew Jeffery 334369419bafSAndrew Jefferydef enableLDAPConfig(host, args, session): 334469419bafSAndrew Jeffery """ 334569419bafSAndrew Jeffery Called by the ldap function. Configures LDAP. 334669419bafSAndrew Jeffery 334769419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 334869419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 334969419bafSAndrew Jeffery @param session: the active session to use 335069419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will 335169419bafSAndrew Jeffery be provided in json format for programmatic consumption 335269419bafSAndrew Jeffery """ 335369419bafSAndrew Jeffery 335469419bafSAndrew Jeffery if(isRedfishSupport): 335569419bafSAndrew Jeffery return enableLDAP(host, args, session) 335669419bafSAndrew Jeffery else: 335769419bafSAndrew Jeffery return enableLegacyLDAP(host, args, session) 335869419bafSAndrew Jeffery 335969419bafSAndrew Jefferydef enableLegacyLDAP(host, args, session): 336069419bafSAndrew Jeffery """ 336169419bafSAndrew Jeffery Called by the ldap function. Configures LDAP on Lagecy systems. 336269419bafSAndrew Jeffery 336369419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 336469419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 336569419bafSAndrew Jeffery @param session: the active session to use 336669419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will 336769419bafSAndrew Jeffery be provided in json format for programmatic consumption 336869419bafSAndrew Jeffery """ 336969419bafSAndrew Jeffery 337069419bafSAndrew Jeffery url='https://'+host+'/xyz/openbmc_project/user/ldap/action/CreateConfig' 337169419bafSAndrew Jeffery scope = { 337269419bafSAndrew Jeffery 'sub' : 'xyz.openbmc_project.User.Ldap.Create.SearchScope.sub', 337369419bafSAndrew Jeffery 'one' : 'xyz.openbmc_project.User.Ldap.Create.SearchScope.one', 337469419bafSAndrew Jeffery 'base': 'xyz.openbmc_project.User.Ldap.Create.SearchScope.base' 337569419bafSAndrew Jeffery } 337669419bafSAndrew Jeffery 337769419bafSAndrew Jeffery serverType = { 337869419bafSAndrew Jeffery 'ActiveDirectory' : 'xyz.openbmc_project.User.Ldap.Create.Type.ActiveDirectory', 337969419bafSAndrew Jeffery 'OpenLDAP' : 'xyz.openbmc_project.User.Ldap.Create.Type.OpenLdap' 338069419bafSAndrew Jeffery } 338169419bafSAndrew Jeffery 338269419bafSAndrew Jeffery data = {"data": [args.uri, args.bindDN, args.baseDN, args.bindPassword, scope[args.scope], serverType[args.serverType]]} 338369419bafSAndrew Jeffery 338469419bafSAndrew Jeffery try: 338569419bafSAndrew Jeffery res = session.post(url, headers=jsonHeader, json=data, verify=False, timeout=baseTimeout) 338669419bafSAndrew Jeffery except(requests.exceptions.Timeout): 338769419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 338869419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 338969419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 339069419bafSAndrew Jeffery 339169419bafSAndrew Jeffery return res.text 339269419bafSAndrew Jeffery 339369419bafSAndrew Jefferydef enableLDAP(host, args, session): 339469419bafSAndrew Jeffery """ 339569419bafSAndrew Jeffery Called by the ldap function. Configures LDAP for systems with latest user-manager design changes 339669419bafSAndrew Jeffery 339769419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 339869419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 339969419bafSAndrew Jeffery @param session: the active session to use 340069419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output will 340169419bafSAndrew Jeffery be provided in json format for programmatic consumption 340269419bafSAndrew Jeffery """ 340369419bafSAndrew Jeffery 340469419bafSAndrew Jeffery scope = { 340569419bafSAndrew Jeffery 'sub' : 'xyz.openbmc_project.User.Ldap.Config.SearchScope.sub', 340669419bafSAndrew Jeffery 'one' : 'xyz.openbmc_project.User.Ldap.Config.SearchScope.one', 340769419bafSAndrew Jeffery 'base': 'xyz.openbmc_project.User.Ldap.Config.SearchScope.base' 340869419bafSAndrew Jeffery } 340969419bafSAndrew Jeffery 341069419bafSAndrew Jeffery serverType = { 341169419bafSAndrew Jeffery 'ActiveDirectory' : 'xyz.openbmc_project.User.Ldap.Config.Type.ActiveDirectory', 341269419bafSAndrew Jeffery 'OpenLDAP' : 'xyz.openbmc_project.User.Ldap.Config.Type.OpenLdap' 341369419bafSAndrew Jeffery } 341469419bafSAndrew Jeffery 341569419bafSAndrew Jeffery url = "https://"+host+"/xyz/openbmc_project/user/ldap/" 341669419bafSAndrew Jeffery 341769419bafSAndrew Jeffery serverTypeEnabled = getLDAPTypeEnabled(host,session) 341869419bafSAndrew Jeffery serverTypeToBeEnabled = args.serverType 341969419bafSAndrew Jeffery 342069419bafSAndrew Jeffery #If the given LDAP type is already enabled, then return 342169419bafSAndrew Jeffery if (serverTypeToBeEnabled == serverTypeEnabled): 342269419bafSAndrew Jeffery return("Server type " + serverTypeToBeEnabled + " is already enabled...") 342369419bafSAndrew Jeffery 342469419bafSAndrew Jeffery try: 342569419bafSAndrew Jeffery 342669419bafSAndrew Jeffery # Copy the role map from the currently enabled LDAP server type 342769419bafSAndrew Jeffery # to the newly enabled server type 342869419bafSAndrew Jeffery # Disable the currently enabled LDAP server type. Unless 342969419bafSAndrew Jeffery # it is disabled, we cannot enable a new LDAP server type 343069419bafSAndrew Jeffery if (serverTypeEnabled is not None): 343169419bafSAndrew Jeffery 343269419bafSAndrew Jeffery if (serverTypeToBeEnabled != serverTypeEnabled): 343369419bafSAndrew Jeffery res = syncRoleMap(host,args,session,serverTypeEnabled,serverTypeToBeEnabled) 343469419bafSAndrew Jeffery 343569419bafSAndrew Jeffery data = "{\"data\": 0 }" 343669419bafSAndrew Jeffery res = session.put(url + serverTypeMap[serverTypeEnabled] + '/attr/Enabled', headers=jsonHeader, data=data, verify=False, timeout=baseTimeout) 343769419bafSAndrew Jeffery 343869419bafSAndrew Jeffery data = {"data": args.baseDN} 343969419bafSAndrew Jeffery res = session.put(url + serverTypeMap[serverTypeToBeEnabled] + '/attr/LDAPBaseDN', headers=jsonHeader, json=data, verify=False, timeout=baseTimeout) 344069419bafSAndrew Jeffery if (res.status_code != requests.codes.ok): 344169419bafSAndrew Jeffery print("Updates to the property LDAPBaseDN failed...") 344269419bafSAndrew Jeffery return(res.text) 344369419bafSAndrew Jeffery 344469419bafSAndrew Jeffery data = {"data": args.bindDN} 344569419bafSAndrew Jeffery res = session.put(url + serverTypeMap[serverTypeToBeEnabled] + '/attr/LDAPBindDN', headers=jsonHeader, json=data, verify=False, timeout=baseTimeout) 344669419bafSAndrew Jeffery if (res.status_code != requests.codes.ok): 344769419bafSAndrew Jeffery print("Updates to the property LDAPBindDN failed...") 344869419bafSAndrew Jeffery return(res.text) 344969419bafSAndrew Jeffery 345069419bafSAndrew Jeffery data = {"data": args.bindPassword} 345169419bafSAndrew Jeffery res = session.put(url + serverTypeMap[serverTypeToBeEnabled] + '/attr/LDAPBindDNPassword', headers=jsonHeader, json=data, verify=False, timeout=baseTimeout) 345269419bafSAndrew Jeffery if (res.status_code != requests.codes.ok): 345369419bafSAndrew Jeffery print("Updates to the property LDAPBindDNPassword failed...") 345469419bafSAndrew Jeffery return(res.text) 345569419bafSAndrew Jeffery 345669419bafSAndrew Jeffery data = {"data": scope[args.scope]} 345769419bafSAndrew Jeffery res = session.put(url + serverTypeMap[serverTypeToBeEnabled] + '/attr/LDAPSearchScope', headers=jsonHeader, json=data, verify=False, timeout=baseTimeout) 345869419bafSAndrew Jeffery if (res.status_code != requests.codes.ok): 345969419bafSAndrew Jeffery print("Updates to the property LDAPSearchScope failed...") 346069419bafSAndrew Jeffery return(res.text) 346169419bafSAndrew Jeffery 346269419bafSAndrew Jeffery data = {"data": args.uri} 346369419bafSAndrew Jeffery res = session.put(url + serverTypeMap[serverTypeToBeEnabled] + '/attr/LDAPServerURI', headers=jsonHeader, json=data, verify=False, timeout=baseTimeout) 346469419bafSAndrew Jeffery if (res.status_code != requests.codes.ok): 346569419bafSAndrew Jeffery print("Updates to the property LDAPServerURI failed...") 346669419bafSAndrew Jeffery return(res.text) 346769419bafSAndrew Jeffery 346869419bafSAndrew Jeffery data = {"data": args.groupAttrName} 346969419bafSAndrew Jeffery res = session.put(url + serverTypeMap[serverTypeToBeEnabled] + '/attr/GroupNameAttribute', headers=jsonHeader, json=data, verify=False, timeout=baseTimeout) 347069419bafSAndrew Jeffery if (res.status_code != requests.codes.ok): 347169419bafSAndrew Jeffery print("Updates to the property GroupNameAttribute failed...") 347269419bafSAndrew Jeffery return(res.text) 347369419bafSAndrew Jeffery 347469419bafSAndrew Jeffery data = {"data": args.userAttrName} 347569419bafSAndrew Jeffery res = session.put(url + serverTypeMap[serverTypeToBeEnabled] + '/attr/UserNameAttribute', headers=jsonHeader, json=data, verify=False, timeout=baseTimeout) 347669419bafSAndrew Jeffery if (res.status_code != requests.codes.ok): 347769419bafSAndrew Jeffery print("Updates to the property UserNameAttribute failed...") 347869419bafSAndrew Jeffery return(res.text) 347969419bafSAndrew Jeffery 348069419bafSAndrew Jeffery #After updating the properties, enable the new server type 348169419bafSAndrew Jeffery data = "{\"data\": 1 }" 348269419bafSAndrew Jeffery res = session.put(url + serverTypeMap[serverTypeToBeEnabled] + '/attr/Enabled', headers=jsonHeader, data=data, verify=False, timeout=baseTimeout) 348369419bafSAndrew Jeffery 348469419bafSAndrew Jeffery except(requests.exceptions.Timeout): 348569419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 348669419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 348769419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 348869419bafSAndrew Jeffery return res.text 348969419bafSAndrew Jeffery 349069419bafSAndrew Jefferydef disableLDAP(host, args, session): 349169419bafSAndrew Jeffery """ 349269419bafSAndrew Jeffery Called by the ldap function. Deletes the LDAP Configuration. 349369419bafSAndrew Jeffery 349469419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 349569419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 349669419bafSAndrew Jeffery @param session: the active session to use 349769419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output 349869419bafSAndrew Jeffery will be provided in json format for programmatic consumption 349969419bafSAndrew Jeffery """ 350069419bafSAndrew Jeffery 350169419bafSAndrew Jeffery try: 350269419bafSAndrew Jeffery if (isRedfishSupport) : 350369419bafSAndrew Jeffery 350469419bafSAndrew Jeffery url = "https://"+host+"/xyz/openbmc_project/user/ldap/" 350569419bafSAndrew Jeffery 350669419bafSAndrew Jeffery serverTypeEnabled = getLDAPTypeEnabled(host,session) 350769419bafSAndrew Jeffery 350869419bafSAndrew Jeffery if (serverTypeEnabled is not None): 350969419bafSAndrew Jeffery #To keep the role map in sync, 351069419bafSAndrew Jeffery #If the server type being disabled has role map, then 351169419bafSAndrew Jeffery # - copy the role map to the other server type(s) 351269419bafSAndrew Jeffery for serverType in serverTypeMap.keys(): 351369419bafSAndrew Jeffery if (serverType != serverTypeEnabled): 351469419bafSAndrew Jeffery res = syncRoleMap(host,args,session,serverTypeEnabled,serverType) 351569419bafSAndrew Jeffery 351669419bafSAndrew Jeffery #Disable the currently enabled LDAP server type 351769419bafSAndrew Jeffery data = "{\"data\": 0 }" 351869419bafSAndrew Jeffery res = session.put(url + serverTypeMap[serverTypeEnabled] + '/attr/Enabled', headers=jsonHeader, data=data, verify=False, timeout=baseTimeout) 351969419bafSAndrew Jeffery 352069419bafSAndrew Jeffery else: 352169419bafSAndrew Jeffery return("LDAP server has not been enabled...") 352269419bafSAndrew Jeffery 352369419bafSAndrew Jeffery else : 352469419bafSAndrew Jeffery url='https://'+host+'/xyz/openbmc_project/user/ldap/config/action/delete' 352569419bafSAndrew Jeffery data = {"data": []} 352669419bafSAndrew Jeffery res = session.post(url, headers=jsonHeader, json=data, verify=False, timeout=baseTimeout) 352769419bafSAndrew Jeffery 352869419bafSAndrew Jeffery except(requests.exceptions.Timeout): 352969419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 353069419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 353169419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 353269419bafSAndrew Jeffery 353369419bafSAndrew Jeffery return res.text 353469419bafSAndrew Jeffery 353569419bafSAndrew Jefferydef enableDHCP(host, args, session): 353669419bafSAndrew Jeffery 353769419bafSAndrew Jeffery """ 353869419bafSAndrew Jeffery Called by the network function. Enables DHCP. 353969419bafSAndrew Jeffery 354069419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 354169419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 354269419bafSAndrew Jeffery args.json: boolean, if this flag is set to true, the output 354369419bafSAndrew Jeffery will be provided in json format for programmatic consumption 354469419bafSAndrew Jeffery @param session: the active session to use 354569419bafSAndrew Jeffery """ 354669419bafSAndrew Jeffery 354769419bafSAndrew Jeffery url = "https://"+host+"/xyz/openbmc_project/network/"+args.Interface+\ 354869419bafSAndrew Jeffery "/attr/DHCPEnabled" 354969419bafSAndrew Jeffery data = "{\"data\": 1 }" 355069419bafSAndrew Jeffery try: 355169419bafSAndrew Jeffery res = session.put(url, headers=jsonHeader, data=data, verify=False, 355269419bafSAndrew Jeffery timeout=baseTimeout) 355369419bafSAndrew Jeffery 355469419bafSAndrew Jeffery except(requests.exceptions.Timeout): 355569419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 355669419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 355769419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 355869419bafSAndrew Jeffery if res.status_code == 403: 355969419bafSAndrew Jeffery return "The specified Interface"+"("+args.Interface+")"+\ 356069419bafSAndrew Jeffery " doesn't exist" 356169419bafSAndrew Jeffery 356269419bafSAndrew Jeffery return res.text 356369419bafSAndrew Jeffery 356469419bafSAndrew Jeffery 356569419bafSAndrew Jefferydef disableDHCP(host, args, session): 356669419bafSAndrew Jeffery """ 356769419bafSAndrew Jeffery Called by the network function. Disables DHCP. 356869419bafSAndrew Jeffery 356969419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 357069419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 357169419bafSAndrew Jeffery args.json: boolean, if this flag is set to true, the output 357269419bafSAndrew Jeffery will be provided in json format for programmatic consumption 357369419bafSAndrew Jeffery @param session: the active session to use 357469419bafSAndrew Jeffery """ 357569419bafSAndrew Jeffery 357669419bafSAndrew Jeffery url = "https://"+host+"/xyz/openbmc_project/network/"+args.Interface+\ 357769419bafSAndrew Jeffery "/attr/DHCPEnabled" 357869419bafSAndrew Jeffery data = "{\"data\": 0 }" 357969419bafSAndrew Jeffery try: 358069419bafSAndrew Jeffery res = session.put(url, headers=jsonHeader, data=data, verify=False, 358169419bafSAndrew Jeffery timeout=baseTimeout) 358269419bafSAndrew Jeffery except(requests.exceptions.Timeout): 358369419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 358469419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 358569419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 358669419bafSAndrew Jeffery if res.status_code == 403: 358769419bafSAndrew Jeffery return "The specified Interface"+"("+args.Interface+")"+\ 358869419bafSAndrew Jeffery " doesn't exist" 358969419bafSAndrew Jeffery return res.text 359069419bafSAndrew Jeffery 359169419bafSAndrew Jeffery 359269419bafSAndrew Jefferydef getHostname(host, args, session): 359369419bafSAndrew Jeffery 359469419bafSAndrew Jeffery """ 359569419bafSAndrew Jeffery Called by the network function. Prints out the Hostname. 359669419bafSAndrew Jeffery 359769419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 359869419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 359969419bafSAndrew Jeffery args.json: boolean, if this flag is set to true, the output 360069419bafSAndrew Jeffery will be provided in json format for programmatic consumption 360169419bafSAndrew Jeffery @param session: the active session to use 360269419bafSAndrew Jeffery """ 360369419bafSAndrew Jeffery 360469419bafSAndrew Jeffery url = "https://"+host+"/xyz/openbmc_project/network/config/attr/HostName" 360569419bafSAndrew Jeffery 360669419bafSAndrew Jeffery try: 360769419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 360869419bafSAndrew Jeffery except(requests.exceptions.Timeout): 360969419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 361069419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 361169419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 361269419bafSAndrew Jeffery 361369419bafSAndrew Jeffery return res.text 361469419bafSAndrew Jeffery 361569419bafSAndrew Jeffery 361669419bafSAndrew Jefferydef setHostname(host, args, session): 361769419bafSAndrew Jeffery """ 361869419bafSAndrew Jeffery Called by the network function. Sets the Hostname. 361969419bafSAndrew Jeffery 362069419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 362169419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 362269419bafSAndrew Jeffery args.json: boolean, if this flag is set to true, the output 362369419bafSAndrew Jeffery will be provided in json format for programmatic consumption 362469419bafSAndrew Jeffery @param session: the active session to use 362569419bafSAndrew Jeffery """ 362669419bafSAndrew Jeffery 362769419bafSAndrew Jeffery url = "https://"+host+"/xyz/openbmc_project/network/config/attr/HostName" 362869419bafSAndrew Jeffery 362969419bafSAndrew Jeffery data = {"data": args.HostName} 363069419bafSAndrew Jeffery 363169419bafSAndrew Jeffery try: 363269419bafSAndrew Jeffery res = session.put(url, headers=jsonHeader, json=data, verify=False, 363369419bafSAndrew Jeffery timeout=baseTimeout) 363469419bafSAndrew Jeffery except(requests.exceptions.Timeout): 363569419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 363669419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 363769419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 363869419bafSAndrew Jeffery 363969419bafSAndrew Jeffery return res.text 364069419bafSAndrew Jeffery 364169419bafSAndrew Jeffery 364269419bafSAndrew Jefferydef getDomainName(host, args, session): 364369419bafSAndrew Jeffery 364469419bafSAndrew Jeffery """ 364569419bafSAndrew Jeffery Called by the network function. Prints out the DomainName. 364669419bafSAndrew Jeffery 364769419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 364869419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 364969419bafSAndrew Jeffery args.json: boolean, if this flag is set to true, the output 365069419bafSAndrew Jeffery will be provided in json format for programmatic consumption 365169419bafSAndrew Jeffery @param session: the active session to use 365269419bafSAndrew Jeffery """ 365369419bafSAndrew Jeffery 365469419bafSAndrew Jeffery url = "https://"+host+"/xyz/openbmc_project/network/"+args.Interface+\ 365569419bafSAndrew Jeffery "/attr/DomainName" 365669419bafSAndrew Jeffery 365769419bafSAndrew Jeffery try: 365869419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 365969419bafSAndrew Jeffery except(requests.exceptions.Timeout): 366069419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 366169419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 366269419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 366369419bafSAndrew Jeffery if res.status_code == 404: 366469419bafSAndrew Jeffery return "The DomainName is not configured on Interface"+"("+args.Interface+")" 366569419bafSAndrew Jeffery 366669419bafSAndrew Jeffery return res.text 366769419bafSAndrew Jeffery 366869419bafSAndrew Jeffery 366969419bafSAndrew Jefferydef setDomainName(host, args, session): 367069419bafSAndrew Jeffery """ 367169419bafSAndrew Jeffery Called by the network function. Sets the DomainName. 367269419bafSAndrew Jeffery 367369419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 367469419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 367569419bafSAndrew Jeffery args.json: boolean, if this flag is set to true, the output 367669419bafSAndrew Jeffery will be provided in json format for programmatic consumption 367769419bafSAndrew Jeffery @param session: the active session to use 367869419bafSAndrew Jeffery """ 367969419bafSAndrew Jeffery 368069419bafSAndrew Jeffery url = "https://"+host+"/xyz/openbmc_project/network/"+args.Interface+\ 368169419bafSAndrew Jeffery "/attr/DomainName" 368269419bafSAndrew Jeffery 368369419bafSAndrew Jeffery data = {"data": args.DomainName.split(",")} 368469419bafSAndrew Jeffery 368569419bafSAndrew Jeffery try: 368669419bafSAndrew Jeffery res = session.put(url, headers=jsonHeader, json=data, verify=False, 368769419bafSAndrew Jeffery timeout=baseTimeout) 368869419bafSAndrew Jeffery except(requests.exceptions.Timeout): 368969419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 369069419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 369169419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 369269419bafSAndrew Jeffery if res.status_code == 403: 369369419bafSAndrew Jeffery return "Failed to set Domain Name" 369469419bafSAndrew Jeffery 369569419bafSAndrew Jeffery return res.text 369669419bafSAndrew Jeffery 369769419bafSAndrew Jeffery 369869419bafSAndrew Jefferydef getMACAddress(host, args, session): 369969419bafSAndrew Jeffery 370069419bafSAndrew Jeffery """ 370169419bafSAndrew Jeffery Called by the network function. Prints out the MACAddress. 370269419bafSAndrew Jeffery 370369419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 370469419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 370569419bafSAndrew Jeffery args.json: boolean, if this flag is set to true, the output 370669419bafSAndrew Jeffery will be provided in json format for programmatic consumption 370769419bafSAndrew Jeffery @param session: the active session to use 370869419bafSAndrew Jeffery """ 370969419bafSAndrew Jeffery 371069419bafSAndrew Jeffery url = "https://"+host+"/xyz/openbmc_project/network/"+args.Interface+\ 371169419bafSAndrew Jeffery "/attr/MACAddress" 371269419bafSAndrew Jeffery 371369419bafSAndrew Jeffery try: 371469419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 371569419bafSAndrew Jeffery except(requests.exceptions.Timeout): 371669419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 371769419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 371869419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 371969419bafSAndrew Jeffery if res.status_code == 404: 372069419bafSAndrew Jeffery return "Failed to get MACAddress" 372169419bafSAndrew Jeffery 372269419bafSAndrew Jeffery return res.text 372369419bafSAndrew Jeffery 372469419bafSAndrew Jeffery 372569419bafSAndrew Jefferydef setMACAddress(host, args, session): 372669419bafSAndrew Jeffery """ 372769419bafSAndrew Jeffery Called by the network function. Sets the MACAddress. 372869419bafSAndrew Jeffery 372969419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 373069419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 373169419bafSAndrew Jeffery args.json: boolean, if this flag is set to true, the output 373269419bafSAndrew Jeffery will be provided in json format for programmatic consumption 373369419bafSAndrew Jeffery @param session: the active session to use 373469419bafSAndrew Jeffery """ 373569419bafSAndrew Jeffery 373669419bafSAndrew Jeffery url = "https://"+host+"/xyz/openbmc_project/network/"+args.Interface+\ 373769419bafSAndrew Jeffery "/attr/MACAddress" 373869419bafSAndrew Jeffery 373969419bafSAndrew Jeffery data = {"data": args.MACAddress} 374069419bafSAndrew Jeffery 374169419bafSAndrew Jeffery try: 374269419bafSAndrew Jeffery res = session.put(url, headers=jsonHeader, json=data, verify=False, 374369419bafSAndrew Jeffery timeout=baseTimeout) 374469419bafSAndrew Jeffery except(requests.exceptions.Timeout): 374569419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 374669419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 374769419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 374869419bafSAndrew Jeffery if res.status_code == 403: 374969419bafSAndrew Jeffery return "Failed to set MACAddress" 375069419bafSAndrew Jeffery 375169419bafSAndrew Jeffery return res.text 375269419bafSAndrew Jeffery 375369419bafSAndrew Jeffery 375469419bafSAndrew Jefferydef getDefaultGateway(host, args, session): 375569419bafSAndrew Jeffery 375669419bafSAndrew Jeffery """ 375769419bafSAndrew Jeffery Called by the network function. Prints out the DefaultGateway. 375869419bafSAndrew Jeffery 375969419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 376069419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 376169419bafSAndrew Jeffery args.json: boolean, if this flag is set to true, the output 376269419bafSAndrew Jeffery will be provided in json format for programmatic consumption 376369419bafSAndrew Jeffery @param session: the active session to use 376469419bafSAndrew Jeffery """ 376569419bafSAndrew Jeffery 376669419bafSAndrew Jeffery url = "https://"+host+"/xyz/openbmc_project/network/config/attr/DefaultGateway" 376769419bafSAndrew Jeffery 376869419bafSAndrew Jeffery try: 376969419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 377069419bafSAndrew Jeffery except(requests.exceptions.Timeout): 377169419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 377269419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 377369419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 377469419bafSAndrew Jeffery if res.status_code == 404: 377569419bafSAndrew Jeffery return "Failed to get Default Gateway info" 377669419bafSAndrew Jeffery 377769419bafSAndrew Jeffery return res.text 377869419bafSAndrew Jeffery 377969419bafSAndrew Jeffery 378069419bafSAndrew Jefferydef setDefaultGateway(host, args, session): 378169419bafSAndrew Jeffery """ 378269419bafSAndrew Jeffery Called by the network function. Sets the DefaultGateway. 378369419bafSAndrew Jeffery 378469419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 378569419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 378669419bafSAndrew Jeffery args.json: boolean, if this flag is set to true, the output 378769419bafSAndrew Jeffery will be provided in json format for programmatic consumption 378869419bafSAndrew Jeffery @param session: the active session to use 378969419bafSAndrew Jeffery """ 379069419bafSAndrew Jeffery 379169419bafSAndrew Jeffery url = "https://"+host+"/xyz/openbmc_project/network/config/attr/DefaultGateway" 379269419bafSAndrew Jeffery 379369419bafSAndrew Jeffery data = {"data": args.DefaultGW} 379469419bafSAndrew Jeffery 379569419bafSAndrew Jeffery try: 379669419bafSAndrew Jeffery res = session.put(url, headers=jsonHeader, json=data, verify=False, 379769419bafSAndrew Jeffery timeout=baseTimeout) 379869419bafSAndrew Jeffery except(requests.exceptions.Timeout): 379969419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 380069419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 380169419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 380269419bafSAndrew Jeffery if res.status_code == 403: 380369419bafSAndrew Jeffery return "Failed to set Default Gateway" 380469419bafSAndrew Jeffery 380569419bafSAndrew Jeffery return res.text 380669419bafSAndrew Jeffery 380769419bafSAndrew Jeffery 380869419bafSAndrew Jefferydef viewNWConfig(host, args, session): 380969419bafSAndrew Jeffery """ 381069419bafSAndrew Jeffery Called by the ldap function. Prints out network configured properties 381169419bafSAndrew Jeffery 381269419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 381369419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 381469419bafSAndrew Jeffery args.json: boolean, if this flag is set to true, the output 381569419bafSAndrew Jeffery will be provided in json format for programmatic consumption 381669419bafSAndrew Jeffery @param session: the active session to use 381769419bafSAndrew Jeffery @return returns LDAP's configured properties. 381869419bafSAndrew Jeffery """ 381969419bafSAndrew Jeffery url = "https://"+host+"/xyz/openbmc_project/network/enumerate" 382069419bafSAndrew Jeffery try: 382169419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 382269419bafSAndrew Jeffery except(requests.exceptions.Timeout): 382369419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 382469419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 382569419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 382669419bafSAndrew Jeffery except(requests.exceptions.RequestException) as err: 382769419bafSAndrew Jeffery return connectionErrHandler(args.json, "RequestException", err) 382869419bafSAndrew Jeffery if res.status_code == 404: 382969419bafSAndrew Jeffery return "LDAP server config has not been created" 383069419bafSAndrew Jeffery return res.text 383169419bafSAndrew Jeffery 383269419bafSAndrew Jeffery 383369419bafSAndrew Jefferydef getDNS(host, args, session): 383469419bafSAndrew Jeffery 383569419bafSAndrew Jeffery """ 383669419bafSAndrew Jeffery Called by the network function. Prints out DNS servers on the interface 383769419bafSAndrew Jeffery 383869419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 383969419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 384069419bafSAndrew Jeffery args.json: boolean, if this flag is set to true, the output 384169419bafSAndrew Jeffery will be provided in json format for programmatic consumption 384269419bafSAndrew Jeffery @param session: the active session to use 384369419bafSAndrew Jeffery """ 384469419bafSAndrew Jeffery 384569419bafSAndrew Jeffery url = "https://" + host + "/xyz/openbmc_project/network/" + args.Interface\ 384669419bafSAndrew Jeffery + "/attr/Nameservers" 384769419bafSAndrew Jeffery 384869419bafSAndrew Jeffery try: 384969419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 385069419bafSAndrew Jeffery except(requests.exceptions.Timeout): 385169419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 385269419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 385369419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 385469419bafSAndrew Jeffery if res.status_code == 404: 385569419bafSAndrew Jeffery return "The NameServer is not configured on Interface"+"("+args.Interface+")" 385669419bafSAndrew Jeffery 385769419bafSAndrew Jeffery return res.text 385869419bafSAndrew Jeffery 385969419bafSAndrew Jeffery 386069419bafSAndrew Jefferydef setDNS(host, args, session): 386169419bafSAndrew Jeffery """ 386269419bafSAndrew Jeffery Called by the network function. Sets DNS servers on the interface. 386369419bafSAndrew Jeffery 386469419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 386569419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 386669419bafSAndrew Jeffery args.json: boolean, if this flag is set to true, the output 386769419bafSAndrew Jeffery will be provided in json format for programmatic consumption 386869419bafSAndrew Jeffery @param session: the active session to use 386969419bafSAndrew Jeffery """ 387069419bafSAndrew Jeffery 387169419bafSAndrew Jeffery url = "https://" + host + "/xyz/openbmc_project/network/" + args.Interface\ 387269419bafSAndrew Jeffery + "/attr/Nameservers" 387369419bafSAndrew Jeffery 387469419bafSAndrew Jeffery data = {"data": args.DNSServers.split(",")} 387569419bafSAndrew Jeffery 387669419bafSAndrew Jeffery try: 387769419bafSAndrew Jeffery res = session.put(url, headers=jsonHeader, json=data, verify=False, 387869419bafSAndrew Jeffery timeout=baseTimeout) 387969419bafSAndrew Jeffery except(requests.exceptions.Timeout): 388069419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 388169419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 388269419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 388369419bafSAndrew Jeffery if res.status_code == 403: 388469419bafSAndrew Jeffery return "Failed to set DNS" 388569419bafSAndrew Jeffery 388669419bafSAndrew Jeffery return res.text 388769419bafSAndrew Jeffery 388869419bafSAndrew Jeffery 388969419bafSAndrew Jefferydef getNTP(host, args, session): 389069419bafSAndrew Jeffery 389169419bafSAndrew Jeffery """ 389269419bafSAndrew Jeffery Called by the network function. Prints out NTP servers on the interface 389369419bafSAndrew Jeffery 389469419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 389569419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 389669419bafSAndrew Jeffery args.json: boolean, if this flag is set to true, the output 389769419bafSAndrew Jeffery will be provided in json format for programmatic consumption 389869419bafSAndrew Jeffery @param session: the active session to use 389969419bafSAndrew Jeffery """ 390069419bafSAndrew Jeffery 390169419bafSAndrew Jeffery url = "https://" + host + "/xyz/openbmc_project/network/" + args.Interface\ 390269419bafSAndrew Jeffery + "/attr/NTPServers" 390369419bafSAndrew Jeffery try: 390469419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 390569419bafSAndrew Jeffery except(requests.exceptions.Timeout): 390669419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 390769419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 390869419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 390969419bafSAndrew Jeffery if res.status_code == 404: 391069419bafSAndrew Jeffery return "The NTPServer is not configured on Interface"+"("+args.Interface+")" 391169419bafSAndrew Jeffery 391269419bafSAndrew Jeffery return res.text 391369419bafSAndrew Jeffery 391469419bafSAndrew Jeffery 391569419bafSAndrew Jefferydef setNTP(host, args, session): 391669419bafSAndrew Jeffery """ 391769419bafSAndrew Jeffery Called by the network function. Sets NTP servers on the interface. 391869419bafSAndrew Jeffery 391969419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 392069419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 392169419bafSAndrew Jeffery args.json: boolean, if this flag is set to true, the output 392269419bafSAndrew Jeffery will be provided in json format for programmatic consumption 392369419bafSAndrew Jeffery @param session: the active session to use 392469419bafSAndrew Jeffery """ 392569419bafSAndrew Jeffery 392669419bafSAndrew Jeffery url = "https://" + host + "/xyz/openbmc_project/network/" + args.Interface\ 392769419bafSAndrew Jeffery + "/attr/NTPServers" 392869419bafSAndrew Jeffery 392969419bafSAndrew Jeffery data = {"data": args.NTPServers.split(",")} 393069419bafSAndrew Jeffery 393169419bafSAndrew Jeffery try: 393269419bafSAndrew Jeffery res = session.put(url, headers=jsonHeader, json=data, verify=False, 393369419bafSAndrew Jeffery timeout=baseTimeout) 393469419bafSAndrew Jeffery except(requests.exceptions.Timeout): 393569419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 393669419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 393769419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 393869419bafSAndrew Jeffery if res.status_code == 403: 393969419bafSAndrew Jeffery return "Failed to set NTP" 394069419bafSAndrew Jeffery 394169419bafSAndrew Jeffery return res.text 394269419bafSAndrew Jeffery 394369419bafSAndrew Jeffery 394469419bafSAndrew Jefferydef addIP(host, args, session): 394569419bafSAndrew Jeffery """ 394669419bafSAndrew Jeffery Called by the network function. Configures IP address on given interface 394769419bafSAndrew Jeffery 394869419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 394969419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 395069419bafSAndrew Jeffery args.json: boolean, if this flag is set to true, the output 395169419bafSAndrew Jeffery will be provided in json format for programmatic consumption 395269419bafSAndrew Jeffery @param session: the active session to use 395369419bafSAndrew Jeffery """ 395469419bafSAndrew Jeffery 395569419bafSAndrew Jeffery url = "https://" + host + "/xyz/openbmc_project/network/" + args.Interface\ 395669419bafSAndrew Jeffery + "/action/IP" 395769419bafSAndrew Jeffery protocol = { 395869419bafSAndrew Jeffery 'ipv4': 'xyz.openbmc_project.Network.IP.Protocol.IPv4', 395969419bafSAndrew Jeffery 'ipv6': 'xyz.openbmc_project.Network.IP.Protocol.IPv6' 396069419bafSAndrew Jeffery } 396169419bafSAndrew Jeffery 396269419bafSAndrew Jeffery data = {"data": [protocol[args.type], args.address, int(args.prefixLength), 396369419bafSAndrew Jeffery args.gateway]} 396469419bafSAndrew Jeffery 396569419bafSAndrew Jeffery try: 396669419bafSAndrew Jeffery res = session.post(url, headers=jsonHeader, json=data, verify=False, 396769419bafSAndrew Jeffery timeout=baseTimeout) 396869419bafSAndrew Jeffery except(requests.exceptions.Timeout): 396969419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 397069419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 397169419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 397269419bafSAndrew Jeffery if res.status_code == 404: 397369419bafSAndrew Jeffery return "The specified Interface" + "(" + args.Interface + ")" +\ 397469419bafSAndrew Jeffery " doesn't exist" 397569419bafSAndrew Jeffery 397669419bafSAndrew Jeffery return res.text 397769419bafSAndrew Jeffery 397869419bafSAndrew Jeffery 397969419bafSAndrew Jefferydef getIP(host, args, session): 398069419bafSAndrew Jeffery """ 398169419bafSAndrew Jeffery Called by the network function. Prints out IP address of given interface 398269419bafSAndrew Jeffery 398369419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 398469419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 398569419bafSAndrew Jeffery args.json: boolean, if this flag is set to true, the output 398669419bafSAndrew Jeffery will be provided in json format for programmatic consumption 398769419bafSAndrew Jeffery @param session: the active session to use 398869419bafSAndrew Jeffery """ 398969419bafSAndrew Jeffery 399069419bafSAndrew Jeffery url = "https://" + host+"/xyz/openbmc_project/network/" + args.Interface +\ 399169419bafSAndrew Jeffery "/enumerate" 399269419bafSAndrew Jeffery try: 399369419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 399469419bafSAndrew Jeffery except(requests.exceptions.Timeout): 399569419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 399669419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 399769419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 399869419bafSAndrew Jeffery if res.status_code == 404: 399969419bafSAndrew Jeffery return "The specified Interface" + "(" + args.Interface + ")" +\ 400069419bafSAndrew Jeffery " doesn't exist" 400169419bafSAndrew Jeffery 400269419bafSAndrew Jeffery return res.text 400369419bafSAndrew Jeffery 400469419bafSAndrew Jeffery 400569419bafSAndrew Jefferydef deleteIP(host, args, session): 400669419bafSAndrew Jeffery """ 400769419bafSAndrew Jeffery Called by the network function. Deletes the IP address from given Interface 400869419bafSAndrew Jeffery 400969419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 401069419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 401169419bafSAndrew Jeffery @param session: the active session to use 401269419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output 401369419bafSAndrew Jeffery will be provided in json format for programmatic consumption 401469419bafSAndrew Jeffery """ 401569419bafSAndrew Jeffery 401669419bafSAndrew Jeffery url = "https://"+host+"/xyz/openbmc_project/network/" + args.Interface+\ 401769419bafSAndrew Jeffery "/enumerate" 401869419bafSAndrew Jeffery data = {"data": []} 401969419bafSAndrew Jeffery try: 402069419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 402169419bafSAndrew Jeffery except(requests.exceptions.Timeout): 402269419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 402369419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 402469419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 402569419bafSAndrew Jeffery if res.status_code == 404: 402669419bafSAndrew Jeffery return "The specified Interface" + "(" + args.Interface + ")" +\ 402769419bafSAndrew Jeffery " doesn't exist" 402869419bafSAndrew Jeffery objDict = json.loads(res.text) 402969419bafSAndrew Jeffery if not objDict['data']: 403069419bafSAndrew Jeffery return "No object found for given address on given Interface" 403169419bafSAndrew Jeffery for obj in objDict['data']: 403269419bafSAndrew Jeffery try: 403369419bafSAndrew Jeffery if args.address in objDict['data'][obj]['Address']: 403469419bafSAndrew Jeffery url = "https://"+host+obj+"/action/Delete" 403569419bafSAndrew Jeffery try: 403669419bafSAndrew Jeffery res = session.post(url, headers=jsonHeader, json=data, 403769419bafSAndrew Jeffery verify=False, timeout=baseTimeout) 403869419bafSAndrew Jeffery except(requests.exceptions.Timeout): 403969419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 404069419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 404169419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 404269419bafSAndrew Jeffery return res.text 404369419bafSAndrew Jeffery else: 404469419bafSAndrew Jeffery continue 404569419bafSAndrew Jeffery except KeyError: 404669419bafSAndrew Jeffery continue 404769419bafSAndrew Jeffery return "No object found for address " + args.address + \ 404869419bafSAndrew Jeffery " on Interface(" + args.Interface + ")" 404969419bafSAndrew Jeffery 405069419bafSAndrew Jeffery 405169419bafSAndrew Jefferydef addVLAN(host, args, session): 405269419bafSAndrew Jeffery """ 405369419bafSAndrew Jeffery Called by the network function. Creates VLAN on given interface. 405469419bafSAndrew Jeffery 405569419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 405669419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 405769419bafSAndrew Jeffery args.json: boolean, if this flag is set to true, the output 405869419bafSAndrew Jeffery will be provided in json format for programmatic consumption 405969419bafSAndrew Jeffery @param session: the active session to use 406069419bafSAndrew Jeffery """ 406169419bafSAndrew Jeffery 406269419bafSAndrew Jeffery url = "https://" + host+"/xyz/openbmc_project/network/action/VLAN" 406369419bafSAndrew Jeffery 406469419bafSAndrew Jeffery data = {"data": [args.Interface,int(args.Identifier)]} 406569419bafSAndrew Jeffery try: 406669419bafSAndrew Jeffery res = session.post(url, headers=jsonHeader, json=data, verify=False, 406769419bafSAndrew Jeffery timeout=baseTimeout) 406869419bafSAndrew Jeffery except(requests.exceptions.Timeout): 406969419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 407069419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 407169419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 407269419bafSAndrew Jeffery if res.status_code == 400: 407369419bafSAndrew Jeffery return "Adding VLAN to interface" + "(" + args.Interface + ")" +\ 407469419bafSAndrew Jeffery " failed" 407569419bafSAndrew Jeffery 407669419bafSAndrew Jeffery return res.text 407769419bafSAndrew Jeffery 407869419bafSAndrew Jeffery 407969419bafSAndrew Jefferydef deleteVLAN(host, args, session): 408069419bafSAndrew Jeffery """ 408169419bafSAndrew Jeffery Called by the network function. Creates VLAN on given interface. 408269419bafSAndrew Jeffery 408369419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 408469419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 408569419bafSAndrew Jeffery args.json: boolean, if this flag is set to true, the output 408669419bafSAndrew Jeffery will be provided in json format for programmatic consumption 408769419bafSAndrew Jeffery @param session: the active session to use 408869419bafSAndrew Jeffery """ 408969419bafSAndrew Jeffery 409069419bafSAndrew Jeffery url = "https://" + host+"/xyz/openbmc_project/network/"+args.Interface+"/action/Delete" 409169419bafSAndrew Jeffery data = {"data": []} 409269419bafSAndrew Jeffery 409369419bafSAndrew Jeffery try: 409469419bafSAndrew Jeffery res = session.post(url, headers=jsonHeader, json=data, verify=False, timeout=baseTimeout) 409569419bafSAndrew Jeffery except(requests.exceptions.Timeout): 409669419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 409769419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 409869419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 409969419bafSAndrew Jeffery if res.status_code == 404: 410069419bafSAndrew Jeffery return "The specified VLAN"+"("+args.Interface+")" +" doesn't exist" 410169419bafSAndrew Jeffery 410269419bafSAndrew Jeffery return res.text 410369419bafSAndrew Jeffery 410469419bafSAndrew Jeffery 410569419bafSAndrew Jefferydef viewDHCPConfig(host, args, session): 410669419bafSAndrew Jeffery """ 410769419bafSAndrew Jeffery Called by the network function. Shows DHCP configured Properties. 410869419bafSAndrew Jeffery 410969419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 411069419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 411169419bafSAndrew Jeffery args.json: boolean, if this flag is set to true, the output 411269419bafSAndrew Jeffery will be provided in json format for programmatic consumption 411369419bafSAndrew Jeffery @param session: the active session to use 411469419bafSAndrew Jeffery """ 411569419bafSAndrew Jeffery 411669419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/network/config/dhcp" 411769419bafSAndrew Jeffery 411869419bafSAndrew Jeffery try: 411969419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 412069419bafSAndrew Jeffery except(requests.exceptions.Timeout): 412169419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 412269419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 412369419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 412469419bafSAndrew Jeffery 412569419bafSAndrew Jeffery return res.text 412669419bafSAndrew Jeffery 412769419bafSAndrew Jeffery 412869419bafSAndrew Jefferydef configureDHCP(host, args, session): 412969419bafSAndrew Jeffery """ 413069419bafSAndrew Jeffery Called by the network function. Configures/updates DHCP Properties. 413169419bafSAndrew Jeffery 413269419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 413369419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 413469419bafSAndrew Jeffery args.json: boolean, if this flag is set to true, the output 413569419bafSAndrew Jeffery will be provided in json format for programmatic consumption 413669419bafSAndrew Jeffery @param session: the active session to use 413769419bafSAndrew Jeffery """ 413869419bafSAndrew Jeffery 413969419bafSAndrew Jeffery 414069419bafSAndrew Jeffery try: 414169419bafSAndrew Jeffery url="https://"+host+"/xyz/openbmc_project/network/config/dhcp" 414269419bafSAndrew Jeffery if(args.DNSEnabled == True): 414369419bafSAndrew Jeffery data = '{"data": 1}' 414469419bafSAndrew Jeffery else: 414569419bafSAndrew Jeffery data = '{"data": 0}' 414669419bafSAndrew Jeffery res = session.put(url + '/attr/DNSEnabled', headers=jsonHeader, 414769419bafSAndrew Jeffery data=data, verify=False, timeout=baseTimeout) 414869419bafSAndrew Jeffery if(args.HostNameEnabled == True): 414969419bafSAndrew Jeffery data = '{"data": 1}' 415069419bafSAndrew Jeffery else: 415169419bafSAndrew Jeffery data = '{"data": 0}' 415269419bafSAndrew Jeffery res = session.put(url + '/attr/HostNameEnabled', headers=jsonHeader, 415369419bafSAndrew Jeffery data=data, verify=False, timeout=baseTimeout) 415469419bafSAndrew Jeffery if(args.NTPEnabled == True): 415569419bafSAndrew Jeffery data = '{"data": 1}' 415669419bafSAndrew Jeffery else: 415769419bafSAndrew Jeffery data = '{"data": 0}' 415869419bafSAndrew Jeffery res = session.put(url + '/attr/NTPEnabled', headers=jsonHeader, 415969419bafSAndrew Jeffery data=data, verify=False, timeout=baseTimeout) 416069419bafSAndrew Jeffery if(args.SendHostNameEnabled == True): 416169419bafSAndrew Jeffery data = '{"data": 1}' 416269419bafSAndrew Jeffery else: 416369419bafSAndrew Jeffery data = '{"data": 0}' 416469419bafSAndrew Jeffery res = session.put(url + '/attr/SendHostNameEnabled', headers=jsonHeader, 416569419bafSAndrew Jeffery data=data, verify=False, timeout=baseTimeout) 416669419bafSAndrew Jeffery except(requests.exceptions.Timeout): 416769419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 416869419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 416969419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 417069419bafSAndrew Jeffery 417169419bafSAndrew Jeffery return res.text 417269419bafSAndrew Jeffery 417369419bafSAndrew Jeffery 417469419bafSAndrew Jefferydef nwReset(host, args, session): 417569419bafSAndrew Jeffery 417669419bafSAndrew Jeffery """ 417769419bafSAndrew Jeffery Called by the network function. Resets networks setting to factory defaults. 417869419bafSAndrew Jeffery 417969419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 418069419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 418169419bafSAndrew Jeffery args.json: boolean, if this flag is set to true, the output 418269419bafSAndrew Jeffery will be provided in json format for programmatic consumption 418369419bafSAndrew Jeffery @param session: the active session to use 418469419bafSAndrew Jeffery """ 418569419bafSAndrew Jeffery 418669419bafSAndrew Jeffery url = "https://"+host+"/xyz/openbmc_project/network/action/Reset" 418769419bafSAndrew Jeffery data = '{"data":[] }' 418869419bafSAndrew Jeffery try: 418969419bafSAndrew Jeffery res = session.post(url, headers=jsonHeader, data=data, verify=False, 419069419bafSAndrew Jeffery timeout=baseTimeout) 419169419bafSAndrew Jeffery 419269419bafSAndrew Jeffery except(requests.exceptions.Timeout): 419369419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 419469419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 419569419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 419669419bafSAndrew Jeffery 419769419bafSAndrew Jeffery return res.text 419869419bafSAndrew Jeffery 419969419bafSAndrew Jefferydef getLDAPTypeEnabled(host,session): 420069419bafSAndrew Jeffery 420169419bafSAndrew Jeffery """ 420269419bafSAndrew Jeffery Called by LDAP related functions to find the LDAP server type that has been enabled. 420369419bafSAndrew Jeffery Returns None if LDAP has not been configured. 420469419bafSAndrew Jeffery 420569419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 420669419bafSAndrew Jeffery @param session: the active session to use 420769419bafSAndrew Jeffery """ 420869419bafSAndrew Jeffery 420969419bafSAndrew Jeffery enabled = False 421069419bafSAndrew Jeffery url = 'https://'+host+'/xyz/openbmc_project/user/ldap/' 421169419bafSAndrew Jeffery for key,value in serverTypeMap.items(): 421269419bafSAndrew Jeffery data = {"data": []} 421369419bafSAndrew Jeffery try: 421469419bafSAndrew Jeffery res = session.get(url + value + '/attr/Enabled', headers=jsonHeader, json=data, verify=False, timeout=baseTimeout) 421569419bafSAndrew Jeffery except(requests.exceptions.Timeout): 421669419bafSAndrew Jeffery print(connectionErrHandler(args.json, "Timeout", None)) 421769419bafSAndrew Jeffery return 421869419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 421969419bafSAndrew Jeffery print(connectionErrHandler(args.json, "ConnectionError", err)) 422069419bafSAndrew Jeffery return 422169419bafSAndrew Jeffery 422269419bafSAndrew Jeffery enabled = res.json()['data'] 422369419bafSAndrew Jeffery if (enabled): 422469419bafSAndrew Jeffery return key 422569419bafSAndrew Jeffery 422669419bafSAndrew Jefferydef syncRoleMap(host,args,session,fromServerType,toServerType): 422769419bafSAndrew Jeffery 422869419bafSAndrew Jeffery """ 422969419bafSAndrew Jeffery Called by LDAP related functions to sync the role maps 423069419bafSAndrew Jeffery Returns False if LDAP has not been configured. 423169419bafSAndrew Jeffery 423269419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 423369419bafSAndrew Jeffery @param session: the active session to use 423469419bafSAndrew Jeffery @param fromServerType : Server type whose role map has to be copied 423569419bafSAndrew Jeffery @param toServerType : Server type to which role map has to be copied 423669419bafSAndrew Jeffery """ 423769419bafSAndrew Jeffery 423869419bafSAndrew Jeffery url = "https://"+host+"/xyz/openbmc_project/user/ldap/" 423969419bafSAndrew Jeffery 424069419bafSAndrew Jeffery try: 424169419bafSAndrew Jeffery #Note: If the fromServerType has no role map, then 424269419bafSAndrew Jeffery #the toServerType will not have any role map. 424369419bafSAndrew Jeffery 424469419bafSAndrew Jeffery #delete the privilege mapping from the toServerType and 424569419bafSAndrew Jeffery #then copy the privilege mapping from fromServerType to 424669419bafSAndrew Jeffery #toServerType. 424769419bafSAndrew Jeffery args.serverType = toServerType 424869419bafSAndrew Jeffery res = deleteAllPrivilegeMapping(host, args, session) 424969419bafSAndrew Jeffery 425069419bafSAndrew Jeffery data = {"data": []} 425169419bafSAndrew Jeffery res = session.get(url + serverTypeMap[fromServerType] + '/role_map/enumerate', headers=jsonHeader, json=data, verify=False, timeout=baseTimeout) 425269419bafSAndrew Jeffery #Previously enabled server type has no role map 425369419bafSAndrew Jeffery if (res.status_code != requests.codes.ok): 425469419bafSAndrew Jeffery 425569419bafSAndrew Jeffery #fromServerType has no role map; So, no need to copy 425669419bafSAndrew Jeffery #role map to toServerType. 425769419bafSAndrew Jeffery return 425869419bafSAndrew Jeffery 425969419bafSAndrew Jeffery objDict = json.loads(res.text) 426069419bafSAndrew Jeffery dataDict = objDict['data'] 426169419bafSAndrew Jeffery for key,value in dataDict.items(): 426269419bafSAndrew Jeffery data = {"data": [value["GroupName"], value["Privilege"]]} 426369419bafSAndrew Jeffery res = session.post(url + serverTypeMap[toServerType] + '/action/Create', headers=jsonHeader, json = data, verify=False, timeout=baseTimeout) 426469419bafSAndrew Jeffery 426569419bafSAndrew Jeffery except(requests.exceptions.Timeout): 426669419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 426769419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 426869419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 426969419bafSAndrew Jeffery return res.text 427069419bafSAndrew Jeffery 427169419bafSAndrew Jeffery 427269419bafSAndrew Jefferydef createPrivilegeMapping(host, args, session): 427369419bafSAndrew Jeffery """ 427469419bafSAndrew Jeffery Called by the ldap function. Creates the group and the privilege mapping. 427569419bafSAndrew Jeffery 427669419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 427769419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 427869419bafSAndrew Jeffery @param session: the active session to use 427969419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output 428069419bafSAndrew Jeffery will be provided in json format for programmatic consumption 428169419bafSAndrew Jeffery """ 428269419bafSAndrew Jeffery 428369419bafSAndrew Jeffery try: 428469419bafSAndrew Jeffery if (isRedfishSupport): 428569419bafSAndrew Jeffery url = 'https://'+host+'/xyz/openbmc_project/user/ldap/' 428669419bafSAndrew Jeffery 428769419bafSAndrew Jeffery #To maintain the interface compatibility between op930 and op940, the server type has been made 428869419bafSAndrew Jeffery #optional. If the server type is not specified, then create the role-mapper for the currently 428969419bafSAndrew Jeffery #enabled server type. 429069419bafSAndrew Jeffery serverType = args.serverType 429169419bafSAndrew Jeffery if (serverType is None): 429269419bafSAndrew Jeffery serverType = getLDAPTypeEnabled(host,session) 429369419bafSAndrew Jeffery if (serverType is None): 429469419bafSAndrew Jeffery return("LDAP server has not been enabled. Please specify LDAP serverType to proceed further...") 429569419bafSAndrew Jeffery 429669419bafSAndrew Jeffery data = {"data": [args.groupName,args.privilege]} 429769419bafSAndrew Jeffery res = session.post(url + serverTypeMap[serverType] + '/action/Create', headers=jsonHeader, json = data, verify=False, timeout=baseTimeout) 429869419bafSAndrew Jeffery 429969419bafSAndrew Jeffery else: 430069419bafSAndrew Jeffery url = 'https://'+host+'/xyz/openbmc_project/user/ldap/action/Create' 430169419bafSAndrew Jeffery data = {"data": [args.groupName,args.privilege]} 430269419bafSAndrew Jeffery res = session.post(url, headers=jsonHeader, json = data, verify=False, timeout=baseTimeout) 430369419bafSAndrew Jeffery 430469419bafSAndrew Jeffery except(requests.exceptions.Timeout): 430569419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 430669419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 430769419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 430869419bafSAndrew Jeffery return res.text 430969419bafSAndrew Jeffery 431069419bafSAndrew Jefferydef listPrivilegeMapping(host, args, session): 431169419bafSAndrew Jeffery """ 431269419bafSAndrew Jeffery Called by the ldap function. Lists the group and the privilege mapping. 431369419bafSAndrew Jeffery 431469419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 431569419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 431669419bafSAndrew Jeffery @param session: the active session to use 431769419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output 431869419bafSAndrew Jeffery will be provided in json format for programmatic consumption 431969419bafSAndrew Jeffery """ 432069419bafSAndrew Jeffery 432169419bafSAndrew Jeffery if (isRedfishSupport): 432269419bafSAndrew Jeffery serverType = args.serverType 432369419bafSAndrew Jeffery if (serverType is None): 432469419bafSAndrew Jeffery serverType = getLDAPTypeEnabled(host,session) 432569419bafSAndrew Jeffery if (serverType is None): 432669419bafSAndrew Jeffery return("LDAP has not been enabled. Please specify LDAP serverType to proceed further...") 432769419bafSAndrew Jeffery 432869419bafSAndrew Jeffery url = 'https://'+host+'/xyz/openbmc_project/user/ldap/'+serverTypeMap[serverType]+'/role_map/enumerate' 432969419bafSAndrew Jeffery 433069419bafSAndrew Jeffery else: 433169419bafSAndrew Jeffery url = 'https://'+host+'/xyz/openbmc_project/user/ldap/enumerate' 433269419bafSAndrew Jeffery 433369419bafSAndrew Jeffery data = {"data": []} 433469419bafSAndrew Jeffery 433569419bafSAndrew Jeffery try: 433669419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, json = data, verify=False, timeout=baseTimeout) 433769419bafSAndrew Jeffery except(requests.exceptions.Timeout): 433869419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 433969419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 434069419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 434169419bafSAndrew Jeffery 434269419bafSAndrew Jeffery return res.text 434369419bafSAndrew Jeffery 434469419bafSAndrew Jefferydef deletePrivilegeMapping(host, args, session): 434569419bafSAndrew Jeffery """ 434669419bafSAndrew Jeffery Called by the ldap function. Deletes the mapping associated with the group. 434769419bafSAndrew Jeffery 434869419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 434969419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 435069419bafSAndrew Jeffery @param session: the active session to use 435169419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output 435269419bafSAndrew Jeffery will be provided in json format for programmatic consumption 435369419bafSAndrew Jeffery """ 435469419bafSAndrew Jeffery 435569419bafSAndrew Jeffery ldapNameSpaceObjects = listPrivilegeMapping(host, args, session) 435669419bafSAndrew Jeffery ldapNameSpaceObjects = json.loads(ldapNameSpaceObjects)["data"] 435769419bafSAndrew Jeffery path = '' 435869419bafSAndrew Jeffery data = {"data": []} 435969419bafSAndrew Jeffery 436069419bafSAndrew Jeffery if (isRedfishSupport): 436169419bafSAndrew Jeffery if (args.serverType is None): 436269419bafSAndrew Jeffery serverType = getLDAPTypeEnabled(host,session) 436369419bafSAndrew Jeffery if (serverType is None): 436469419bafSAndrew Jeffery return("LDAP has not been enabled. Please specify LDAP serverType to proceed further...") 436569419bafSAndrew Jeffery # search for the object having the mapping for the given group 436669419bafSAndrew Jeffery for key,value in ldapNameSpaceObjects.items(): 436769419bafSAndrew Jeffery if value['GroupName'] == args.groupName: 436869419bafSAndrew Jeffery path = key 436969419bafSAndrew Jeffery break 437069419bafSAndrew Jeffery 437169419bafSAndrew Jeffery if path == '': 437269419bafSAndrew Jeffery return "No privilege mapping found for this group." 437369419bafSAndrew Jeffery 437469419bafSAndrew Jeffery # delete the object 437569419bafSAndrew Jeffery url = 'https://'+host+path+'/action/Delete' 437669419bafSAndrew Jeffery 437769419bafSAndrew Jeffery else: 437869419bafSAndrew Jeffery # not interested in the config objet 437969419bafSAndrew Jeffery ldapNameSpaceObjects.pop('/xyz/openbmc_project/user/ldap/config', None) 438069419bafSAndrew Jeffery 438169419bafSAndrew Jeffery # search for the object having the mapping for the given group 438269419bafSAndrew Jeffery for key,value in ldapNameSpaceObjects.items(): 438369419bafSAndrew Jeffery if value['GroupName'] == args.groupName: 438469419bafSAndrew Jeffery path = key 438569419bafSAndrew Jeffery break 438669419bafSAndrew Jeffery 438769419bafSAndrew Jeffery if path == '': 438869419bafSAndrew Jeffery return "No privilege mapping found for this group." 438969419bafSAndrew Jeffery 439069419bafSAndrew Jeffery # delete the object 439169419bafSAndrew Jeffery url = 'https://'+host+path+'/action/delete' 439269419bafSAndrew Jeffery 439369419bafSAndrew Jeffery try: 439469419bafSAndrew Jeffery res = session.post(url, headers=jsonHeader, json = data, verify=False, timeout=baseTimeout) 439569419bafSAndrew Jeffery except(requests.exceptions.Timeout): 439669419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 439769419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 439869419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 439969419bafSAndrew Jeffery return res.text 440069419bafSAndrew Jeffery 440169419bafSAndrew Jefferydef deleteAllPrivilegeMapping(host, args, session): 440269419bafSAndrew Jeffery """ 440369419bafSAndrew Jeffery Called by the ldap function. Deletes all the privilege mapping and group defined. 440469419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 440569419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 440669419bafSAndrew Jeffery @param session: the active session to use 440769419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output 440869419bafSAndrew Jeffery will be provided in json format for programmatic consumption 440969419bafSAndrew Jeffery """ 441069419bafSAndrew Jeffery 441169419bafSAndrew Jeffery ldapNameSpaceObjects = listPrivilegeMapping(host, args, session) 441269419bafSAndrew Jeffery ldapNameSpaceObjects = json.loads(ldapNameSpaceObjects)["data"] 441369419bafSAndrew Jeffery path = '' 441469419bafSAndrew Jeffery data = {"data": []} 441569419bafSAndrew Jeffery 441669419bafSAndrew Jeffery if (isRedfishSupport): 441769419bafSAndrew Jeffery if (args.serverType is None): 441869419bafSAndrew Jeffery serverType = getLDAPTypeEnabled(host,session) 441969419bafSAndrew Jeffery if (serverType is None): 442069419bafSAndrew Jeffery return("LDAP has not been enabled. Please specify LDAP serverType to proceed further...") 442169419bafSAndrew Jeffery 442269419bafSAndrew Jeffery else: 442369419bafSAndrew Jeffery # Remove the config object. 442469419bafSAndrew Jeffery ldapNameSpaceObjects.pop('/xyz/openbmc_project/user/ldap/config', None) 442569419bafSAndrew Jeffery 442669419bafSAndrew Jeffery try: 442769419bafSAndrew Jeffery # search for GroupName property and delete if it is available. 442869419bafSAndrew Jeffery for path in ldapNameSpaceObjects.keys(): 442969419bafSAndrew Jeffery # delete the object 443069419bafSAndrew Jeffery url = 'https://'+host+path+'/action/Delete' 443169419bafSAndrew Jeffery res = session.post(url, headers=jsonHeader, json = data, verify=False, timeout=baseTimeout) 443269419bafSAndrew Jeffery 443369419bafSAndrew Jeffery except(requests.exceptions.Timeout): 443469419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 443569419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 443669419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 443769419bafSAndrew Jeffery return res.text 443869419bafSAndrew Jeffery 443969419bafSAndrew Jefferydef viewLDAPConfig(host, args, session): 444069419bafSAndrew Jeffery """ 444169419bafSAndrew Jeffery Called by the ldap function. Prints out active LDAP configuration properties 444269419bafSAndrew Jeffery 444369419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 444469419bafSAndrew Jeffery @param args: contains additional arguments used by the ldap subcommand 444569419bafSAndrew Jeffery args.json: boolean, if this flag is set to true, the output 444669419bafSAndrew Jeffery will be provided in json format for programmatic consumption 444769419bafSAndrew Jeffery @param session: the active session to use 444869419bafSAndrew Jeffery @return returns LDAP's configured properties. 444969419bafSAndrew Jeffery """ 445069419bafSAndrew Jeffery 445169419bafSAndrew Jeffery try: 445269419bafSAndrew Jeffery if (isRedfishSupport): 445369419bafSAndrew Jeffery 445469419bafSAndrew Jeffery url = "https://"+host+"/xyz/openbmc_project/user/ldap/" 445569419bafSAndrew Jeffery 445669419bafSAndrew Jeffery serverTypeEnabled = getLDAPTypeEnabled(host,session) 445769419bafSAndrew Jeffery 445869419bafSAndrew Jeffery if (serverTypeEnabled is not None): 445969419bafSAndrew Jeffery data = {"data": []} 446069419bafSAndrew Jeffery res = session.get(url + serverTypeMap[serverTypeEnabled], headers=jsonHeader, json=data, verify=False, timeout=baseTimeout) 446169419bafSAndrew Jeffery else: 446269419bafSAndrew Jeffery return("LDAP server has not been enabled...") 446369419bafSAndrew Jeffery 446469419bafSAndrew Jeffery else : 446569419bafSAndrew Jeffery url = "https://"+host+"/xyz/openbmc_project/user/ldap/config" 446669419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 446769419bafSAndrew Jeffery 446869419bafSAndrew Jeffery except(requests.exceptions.Timeout): 446969419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 447069419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 447169419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 447269419bafSAndrew Jeffery if res.status_code == 404: 447369419bafSAndrew Jeffery return "LDAP server config has not been created" 447469419bafSAndrew Jeffery return res.text 447569419bafSAndrew Jeffery 447669419bafSAndrew Jefferydef str2bool(v): 447769419bafSAndrew Jeffery if v.lower() in ('yes', 'true', 't', 'y', '1'): 447869419bafSAndrew Jeffery return True 447969419bafSAndrew Jeffery elif v.lower() in ('no', 'false', 'f', 'n', '0'): 448069419bafSAndrew Jeffery return False 448169419bafSAndrew Jeffery else: 448269419bafSAndrew Jeffery raise argparse.ArgumentTypeError('Boolean value expected.') 448369419bafSAndrew Jeffery 448469419bafSAndrew Jefferydef localUsers(host, args, session): 448569419bafSAndrew Jeffery """ 448669419bafSAndrew Jeffery Enables and disables local BMC users. 448769419bafSAndrew Jeffery 448869419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 448969419bafSAndrew Jeffery @param args: contains additional arguments used by the logging sub command 449069419bafSAndrew Jeffery @param session: the active session to use 449169419bafSAndrew Jeffery """ 449269419bafSAndrew Jeffery 449369419bafSAndrew Jeffery url="https://{hostname}/xyz/openbmc_project/user/enumerate".format(hostname=host) 449469419bafSAndrew Jeffery try: 449569419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False, timeout=baseTimeout) 449669419bafSAndrew Jeffery except(requests.exceptions.Timeout): 449769419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 449869419bafSAndrew Jeffery usersDict = json.loads(res.text) 449969419bafSAndrew Jeffery 450069419bafSAndrew Jeffery if not usersDict['data']: 450169419bafSAndrew Jeffery return "No users found" 450269419bafSAndrew Jeffery 450369419bafSAndrew Jeffery output = "" 450469419bafSAndrew Jeffery for user in usersDict['data']: 450569419bafSAndrew Jeffery 450669419bafSAndrew Jeffery # Skip LDAP and another non-local users 450769419bafSAndrew Jeffery if 'UserEnabled' not in usersDict['data'][user]: 450869419bafSAndrew Jeffery continue 450969419bafSAndrew Jeffery 451069419bafSAndrew Jeffery name = user.split('/')[-1] 451169419bafSAndrew Jeffery url = "https://{hostname}{user}/attr/UserEnabled".format(hostname=host, user=user) 451269419bafSAndrew Jeffery 451369419bafSAndrew Jeffery if args.local_users == "queryenabled": 451469419bafSAndrew Jeffery try: 451569419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader,verify=False, timeout=baseTimeout) 451669419bafSAndrew Jeffery except(requests.exceptions.Timeout): 451769419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 451869419bafSAndrew Jeffery 451969419bafSAndrew Jeffery result = json.loads(res.text) 452069419bafSAndrew Jeffery output += ("User: {name} Enabled: {result}\n").format(name=name, result=result['data']) 452169419bafSAndrew Jeffery 452269419bafSAndrew Jeffery elif args.local_users in ["enableall", "disableall"]: 452369419bafSAndrew Jeffery action = "" 452469419bafSAndrew Jeffery if args.local_users == "enableall": 452569419bafSAndrew Jeffery data = '{"data": true}' 452669419bafSAndrew Jeffery action = "Enabling" 452769419bafSAndrew Jeffery else: 452869419bafSAndrew Jeffery data = '{"data": false}' 452969419bafSAndrew Jeffery action = "Disabling" 453069419bafSAndrew Jeffery 453169419bafSAndrew Jeffery output += "{action} {name}\n".format(action=action, name=name) 453269419bafSAndrew Jeffery 453369419bafSAndrew Jeffery try: 453469419bafSAndrew Jeffery resp = session.put(url, headers=jsonHeader, data=data, verify=False, timeout=baseTimeout) 453569419bafSAndrew Jeffery except(requests.exceptions.Timeout): 453669419bafSAndrew Jeffery return connectionErrHandler(args.json, "Timeout", None) 453769419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 453869419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 453969419bafSAndrew Jeffery else: 454069419bafSAndrew Jeffery return "Invalid local users argument" 454169419bafSAndrew Jeffery 454269419bafSAndrew Jeffery return output 454369419bafSAndrew Jeffery 454469419bafSAndrew Jefferydef setPassword(host, args, session): 454569419bafSAndrew Jeffery """ 454669419bafSAndrew Jeffery Set local user password 454769419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 454869419bafSAndrew Jeffery @param args: contains additional arguments used by the logging sub 454969419bafSAndrew Jeffery command 455069419bafSAndrew Jeffery @param session: the active session to use 455169419bafSAndrew Jeffery @param args.json: boolean, if this flag is set to true, the output 455269419bafSAndrew Jeffery will be provided in json format for programmatic consumption 455369419bafSAndrew Jeffery @return: Session object 455469419bafSAndrew Jeffery """ 455569419bafSAndrew Jeffery try: 455669419bafSAndrew Jeffery if(isRedfishSupport): 455769419bafSAndrew Jeffery url = "https://" + host + "/redfish/v1/AccountService/Accounts/"+ \ 455869419bafSAndrew Jeffery args.user 455969419bafSAndrew Jeffery data = {"Password":args.password} 456069419bafSAndrew Jeffery res = session.patch(url, headers=jsonHeader, json=data, 456169419bafSAndrew Jeffery verify=False, timeout=baseTimeout) 456269419bafSAndrew Jeffery else: 456369419bafSAndrew Jeffery url = "https://" + host + "/xyz/openbmc_project/user/" + args.user + \ 456469419bafSAndrew Jeffery "/action/SetPassword" 456569419bafSAndrew Jeffery res = session.post(url, headers=jsonHeader, 456669419bafSAndrew Jeffery json={"data": [args.password]}, verify=False, 456769419bafSAndrew Jeffery timeout=baseTimeout) 456869419bafSAndrew Jeffery except(requests.exceptions.Timeout): 456969419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 457069419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 457169419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 457269419bafSAndrew Jeffery except(requests.exceptions.RequestException) as err: 457369419bafSAndrew Jeffery return connectionErrHandler(args.json, "RequestException", err) 457469419bafSAndrew Jeffery return res.status_code 457569419bafSAndrew Jeffery 457669419bafSAndrew Jefferydef getThermalZones(host, args, session): 457769419bafSAndrew Jeffery """ 457869419bafSAndrew Jeffery Get the available thermal control zones 457969419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 458069419bafSAndrew Jeffery @param args: contains additional arguments used to get the thermal 458169419bafSAndrew Jeffery control zones 458269419bafSAndrew Jeffery @param session: the active session to use 458369419bafSAndrew Jeffery @return: Session object 458469419bafSAndrew Jeffery """ 458569419bafSAndrew Jeffery url = "https://" + host + "/xyz/openbmc_project/control/thermal/enumerate" 458669419bafSAndrew Jeffery 458769419bafSAndrew Jeffery try: 458869419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False, timeout=30) 458969419bafSAndrew Jeffery except(requests.exceptions.Timeout): 459069419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 459169419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 459269419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 459369419bafSAndrew Jeffery except(requests.exceptions.RequestException) as err: 459469419bafSAndrew Jeffery return connectionErrHandler(args.json, "RequestException", err) 459569419bafSAndrew Jeffery 459669419bafSAndrew Jeffery if (res.status_code == 404): 459769419bafSAndrew Jeffery return "No thermal control zones found" 459869419bafSAndrew Jeffery 459969419bafSAndrew Jeffery zonesDict = json.loads(res.text) 460069419bafSAndrew Jeffery if not zonesDict['data']: 460169419bafSAndrew Jeffery return "No thermal control zones found" 460269419bafSAndrew Jeffery for zone in zonesDict['data']: 460369419bafSAndrew Jeffery z = ",".join(str(zone.split('/')[-1]) for zone in zonesDict['data']) 460469419bafSAndrew Jeffery 460569419bafSAndrew Jeffery return "Zones: [ " + z + " ]" 460669419bafSAndrew Jeffery 460769419bafSAndrew Jeffery 460869419bafSAndrew Jefferydef getThermalMode(host, args, session): 460969419bafSAndrew Jeffery """ 461069419bafSAndrew Jeffery Get thermal control mode 461169419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 461269419bafSAndrew Jeffery @param args: contains additional arguments used to get the thermal 461369419bafSAndrew Jeffery control mode 461469419bafSAndrew Jeffery @param session: the active session to use 461569419bafSAndrew Jeffery @param args.zone: the zone to get the mode on 461669419bafSAndrew Jeffery @return: Session object 461769419bafSAndrew Jeffery """ 461869419bafSAndrew Jeffery url = "https://" + host + "/xyz/openbmc_project/control/thermal/" + \ 461969419bafSAndrew Jeffery args.zone 462069419bafSAndrew Jeffery 462169419bafSAndrew Jeffery try: 462269419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False, timeout=30) 462369419bafSAndrew Jeffery except(requests.exceptions.Timeout): 462469419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 462569419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 462669419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 462769419bafSAndrew Jeffery except(requests.exceptions.RequestException) as err: 462869419bafSAndrew Jeffery return connectionErrHandler(args.json, "RequestException", err) 462969419bafSAndrew Jeffery 463069419bafSAndrew Jeffery if (res.status_code == 404): 463169419bafSAndrew Jeffery return "Thermal control zone(" + args.zone + ") not found" 463269419bafSAndrew Jeffery 463369419bafSAndrew Jeffery propsDict = json.loads(res.text) 463469419bafSAndrew Jeffery if not propsDict['data']: 463569419bafSAndrew Jeffery return "No thermal control properties found on zone(" + args.zone + ")" 463669419bafSAndrew Jeffery curMode = "Current" 463769419bafSAndrew Jeffery supModes = "Supported" 463869419bafSAndrew Jeffery result = "\n" 463969419bafSAndrew Jeffery for prop in propsDict['data']: 464069419bafSAndrew Jeffery if (prop.casefold() == curMode.casefold()): 464169419bafSAndrew Jeffery result += curMode + " Mode: " + propsDict['data'][curMode] + "\n" 464269419bafSAndrew Jeffery if (prop.casefold() == supModes.casefold()): 464369419bafSAndrew Jeffery s = ", ".join(str(sup) for sup in propsDict['data'][supModes]) 464469419bafSAndrew Jeffery result += supModes + " Modes: [ " + s + " ]\n" 464569419bafSAndrew Jeffery 464669419bafSAndrew Jeffery return result 464769419bafSAndrew Jeffery 464869419bafSAndrew Jefferydef setThermalMode(host, args, session): 464969419bafSAndrew Jeffery """ 465069419bafSAndrew Jeffery Set thermal control mode 465169419bafSAndrew Jeffery @param host: string, the hostname or IP address of the bmc 465269419bafSAndrew Jeffery @param args: contains additional arguments used for setting the thermal 465369419bafSAndrew Jeffery control mode 465469419bafSAndrew Jeffery @param session: the active session to use 465569419bafSAndrew Jeffery @param args.zone: the zone to set the mode on 465669419bafSAndrew Jeffery @param args.mode: the mode to enable 465769419bafSAndrew Jeffery @return: Session object 465869419bafSAndrew Jeffery """ 465969419bafSAndrew Jeffery url = "https://" + host + "/xyz/openbmc_project/control/thermal/" + \ 466069419bafSAndrew Jeffery args.zone + "/attr/Current" 466169419bafSAndrew Jeffery 466269419bafSAndrew Jeffery # Check args.mode against supported modes using `getThermalMode` output 466369419bafSAndrew Jeffery modes = getThermalMode(host, args, session) 466469419bafSAndrew Jeffery modes = os.linesep.join([m for m in modes.splitlines() if m]) 466569419bafSAndrew Jeffery modes = modes.replace("\n", ";").strip() 466669419bafSAndrew Jeffery modesDict = dict(m.split(': ') for m in modes.split(';')) 466769419bafSAndrew Jeffery sModes = ''.join(s for s in modesDict['Supported Modes'] if s not in '[ ]') 466869419bafSAndrew Jeffery if args.mode.casefold() not in \ 466969419bafSAndrew Jeffery (m.casefold() for m in sModes.split(',')) or not args.mode: 467069419bafSAndrew Jeffery result = ("Unsupported mode('" + args.mode + "') given, " + 467169419bafSAndrew Jeffery "select a supported mode: \n" + 467269419bafSAndrew Jeffery getThermalMode(host, args, session)) 467369419bafSAndrew Jeffery return result 467469419bafSAndrew Jeffery 467569419bafSAndrew Jeffery data = '{"data":"' + args.mode + '"}' 467669419bafSAndrew Jeffery try: 467769419bafSAndrew Jeffery res = session.get(url, headers=jsonHeader, verify=False, timeout=30) 467869419bafSAndrew Jeffery except(requests.exceptions.Timeout): 467969419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 468069419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 468169419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 468269419bafSAndrew Jeffery except(requests.exceptions.RequestException) as err: 468369419bafSAndrew Jeffery return connectionErrHandler(args.json, "RequestException", err) 468469419bafSAndrew Jeffery 468569419bafSAndrew Jeffery if (data and res.status_code != 404): 468669419bafSAndrew Jeffery try: 468769419bafSAndrew Jeffery res = session.put(url, headers=jsonHeader, 468869419bafSAndrew Jeffery data=data, verify=False, 468969419bafSAndrew Jeffery timeout=30) 469069419bafSAndrew Jeffery except(requests.exceptions.Timeout): 469169419bafSAndrew Jeffery return(connectionErrHandler(args.json, "Timeout", None)) 469269419bafSAndrew Jeffery except(requests.exceptions.ConnectionError) as err: 469369419bafSAndrew Jeffery return connectionErrHandler(args.json, "ConnectionError", err) 469469419bafSAndrew Jeffery except(requests.exceptions.RequestException) as err: 469569419bafSAndrew Jeffery return connectionErrHandler(args.json, "RequestException", err) 469669419bafSAndrew Jeffery 469769419bafSAndrew Jeffery if res.status_code == 403: 469869419bafSAndrew Jeffery return "The specified thermal control zone(" + args.zone + ")" + \ 469969419bafSAndrew Jeffery " does not exist" 470069419bafSAndrew Jeffery 470169419bafSAndrew Jeffery return res.text 470269419bafSAndrew Jeffery else: 470369419bafSAndrew Jeffery return "Setting thermal control mode(" + args.mode + ")" + \ 470469419bafSAndrew Jeffery " not supported or operation not available" 470569419bafSAndrew Jeffery 470669419bafSAndrew Jeffery 470769419bafSAndrew Jefferydef createCommandParser(): 470869419bafSAndrew Jeffery """ 470969419bafSAndrew Jeffery creates the parser for the command line along with help for each command and subcommand 471069419bafSAndrew Jeffery 471169419bafSAndrew Jeffery @return: returns the parser for the command line 471269419bafSAndrew Jeffery """ 471369419bafSAndrew Jeffery parser = argparse.ArgumentParser(description='Process arguments') 471469419bafSAndrew Jeffery parser.add_argument("-H", "--host", help='A hostname or IP for the BMC') 471569419bafSAndrew Jeffery parser.add_argument("-U", "--user", help='The username to login with') 471669419bafSAndrew Jeffery group = parser.add_mutually_exclusive_group() 471769419bafSAndrew Jeffery group.add_argument("-A", "--askpw", action='store_true', help='prompt for password') 471869419bafSAndrew Jeffery group.add_argument("-P", "--PW", help='Provide the password in-line') 471969419bafSAndrew Jeffery group.add_argument("-E", "--PWenvvar", action='store_true', help='Get password from envvar OPENBMCTOOL_PASSWORD') 472069419bafSAndrew Jeffery parser.add_argument('-j', '--json', action='store_true', help='output json data only') 472169419bafSAndrew Jeffery parser.add_argument('-t', '--policyTableLoc', help='The location of the policy table to parse alerts') 472269419bafSAndrew Jeffery parser.add_argument('-c', '--CerFormat', action='store_true', help=argparse.SUPPRESS) 472369419bafSAndrew Jeffery parser.add_argument('-T', '--procTime', action='store_true', help= argparse.SUPPRESS) 472469419bafSAndrew Jeffery parser.add_argument('-V', '--version', action='store_true', help='Display the version number of the openbmctool') 472569419bafSAndrew Jeffery subparsers = parser.add_subparsers(title='subcommands', description='valid subcommands',help="sub-command help", dest='command') 472669419bafSAndrew Jeffery 472769419bafSAndrew Jeffery #fru command 472869419bafSAndrew Jeffery parser_inv = subparsers.add_parser("fru", help='Work with platform inventory') 472969419bafSAndrew Jeffery inv_subparser = parser_inv.add_subparsers(title='subcommands', description='valid inventory actions', help="valid inventory actions", dest='command') 473069419bafSAndrew Jeffery inv_subparser.required = True 473169419bafSAndrew Jeffery #fru print 473269419bafSAndrew Jeffery inv_print = inv_subparser.add_parser("print", help="prints out a list of all FRUs") 473369419bafSAndrew Jeffery inv_print.set_defaults(func=fruPrint) 473469419bafSAndrew Jeffery #fru list [0....n] 473569419bafSAndrew Jeffery inv_list = inv_subparser.add_parser("list", help="print out details on selected FRUs. Specifying no items will list the entire inventory") 473669419bafSAndrew Jeffery inv_list.add_argument('items', nargs='?', help="print out details on selected FRUs. Specifying no items will list the entire inventory") 473769419bafSAndrew Jeffery inv_list.set_defaults(func=fruList) 473869419bafSAndrew Jeffery #fru status 473969419bafSAndrew Jeffery inv_status = inv_subparser.add_parser("status", help="prints out the status of all FRUs") 474069419bafSAndrew Jeffery inv_status.add_argument('-v', '--verbose', action='store_true', help='Verbose output') 474169419bafSAndrew Jeffery inv_status.set_defaults(func=fruStatus) 474269419bafSAndrew Jeffery 474369419bafSAndrew Jeffery #sensors command 474469419bafSAndrew Jeffery parser_sens = subparsers.add_parser("sensors", help="Work with platform sensors") 474569419bafSAndrew Jeffery sens_subparser=parser_sens.add_subparsers(title='subcommands', description='valid sensor actions', help='valid sensor actions', dest='command') 474669419bafSAndrew Jeffery sens_subparser.required = True 474769419bafSAndrew Jeffery #sensor print 474869419bafSAndrew Jeffery sens_print= sens_subparser.add_parser('print', help="prints out a list of all Sensors.") 474969419bafSAndrew Jeffery sens_print.set_defaults(func=sensor) 475069419bafSAndrew Jeffery #sensor list[0...n] 475169419bafSAndrew Jeffery sens_list=sens_subparser.add_parser("list", help="Lists all Sensors in the platform. Specify a sensor for full details. ") 475269419bafSAndrew Jeffery sens_list.add_argument("sensNum", nargs='?', help="The Sensor number to get full details on" ) 475369419bafSAndrew Jeffery sens_list.set_defaults(func=sensor) 475469419bafSAndrew Jeffery 475569419bafSAndrew Jeffery #thermal control commands 475669419bafSAndrew Jeffery parser_therm = subparsers.add_parser("thermal", help="Work with thermal control parameters") 475769419bafSAndrew Jeffery therm_subparser=parser_therm.add_subparsers(title='subcommands', description='Thermal control actions to work with', help='Valid thermal control actions to work with', dest='command') 475869419bafSAndrew Jeffery #thermal control zones 475969419bafSAndrew Jeffery parser_thermZones = therm_subparser.add_parser("zones", help="Get a list of available thermal control zones") 476069419bafSAndrew Jeffery parser_thermZones.set_defaults(func=getThermalZones) 476169419bafSAndrew Jeffery #thermal control modes 476269419bafSAndrew Jeffery parser_thermMode = therm_subparser.add_parser("modes", help="Work with thermal control modes") 476369419bafSAndrew Jeffery thermMode_sub = parser_thermMode.add_subparsers(title='subactions', description='Work with thermal control modes', help="Work with thermal control modes") 476469419bafSAndrew Jeffery #get thermal control mode 476569419bafSAndrew Jeffery parser_getThermMode = thermMode_sub.add_parser("get", help="Get current and supported thermal control modes") 476669419bafSAndrew Jeffery parser_getThermMode.add_argument('-z', '--zone', required=True, help='Thermal zone to work with') 476769419bafSAndrew Jeffery parser_getThermMode.set_defaults(func=getThermalMode) 476869419bafSAndrew Jeffery #set thermal control mode 476969419bafSAndrew Jeffery parser_setThermMode = thermMode_sub.add_parser("set", help="Set the thermal control mode") 477069419bafSAndrew Jeffery parser_setThermMode.add_argument('-z', '--zone', required=True, help='Thermal zone to work with') 477169419bafSAndrew Jeffery parser_setThermMode.add_argument('-m', '--mode', required=True, help='The supported thermal control mode') 477269419bafSAndrew Jeffery parser_setThermMode.set_defaults(func=setThermalMode) 477369419bafSAndrew Jeffery 477469419bafSAndrew Jeffery #sel command 477569419bafSAndrew Jeffery parser_sel = subparsers.add_parser("sel", help="Work with platform alerts") 477669419bafSAndrew Jeffery sel_subparser = parser_sel.add_subparsers(title='subcommands', description='valid SEL actions', help = 'valid SEL actions', dest='command') 477769419bafSAndrew Jeffery sel_subparser.required = True 477869419bafSAndrew Jeffery #sel print 477969419bafSAndrew Jeffery sel_print = sel_subparser.add_parser("print", help="prints out a list of all sels in a condensed list") 478069419bafSAndrew Jeffery sel_print.add_argument('-d', '--devdebug', action='store_true', help=argparse.SUPPRESS) 478169419bafSAndrew Jeffery sel_print.add_argument('-v', '--verbose', action='store_true', help="Changes the output to being very verbose") 478269419bafSAndrew Jeffery sel_print.add_argument('-f', '--fileloc', help='Parse a file instead of the BMC output') 478369419bafSAndrew Jeffery sel_print.set_defaults(func=selPrint) 478469419bafSAndrew Jeffery 478569419bafSAndrew Jeffery #sel list 478669419bafSAndrew Jeffery sel_list = sel_subparser.add_parser("list", help="Lists all SELs in the platform. Specifying a specific number will pull all the details for that individual SEL") 478769419bafSAndrew Jeffery sel_list.add_argument("selNum", nargs='?', type=int, help="The SEL entry to get details on") 478869419bafSAndrew Jeffery sel_list.set_defaults(func=selList) 478969419bafSAndrew Jeffery 479069419bafSAndrew Jeffery sel_get = sel_subparser.add_parser("get", help="Gets the verbose details of a specified SEL entry") 479169419bafSAndrew Jeffery sel_get.add_argument('selNum', type=int, help="the number of the SEL entry to get") 479269419bafSAndrew Jeffery sel_get.set_defaults(func=selList) 479369419bafSAndrew Jeffery 479469419bafSAndrew Jeffery sel_clear = sel_subparser.add_parser("clear", help="Clears all entries from the SEL") 479569419bafSAndrew Jeffery sel_clear.set_defaults(func=selClear) 479669419bafSAndrew Jeffery 479769419bafSAndrew Jeffery sel_setResolved = sel_subparser.add_parser("resolve", help="Sets the sel entry to resolved") 479869419bafSAndrew Jeffery sel_setResolved.add_argument('-n', '--selNum', type=int, help="the number of the SEL entry to resolve") 479969419bafSAndrew Jeffery sel_ResolveAll_sub = sel_setResolved.add_subparsers(title='subcommands', description='valid subcommands',help="sub-command help", dest='command') 480069419bafSAndrew Jeffery sel_ResolveAll = sel_ResolveAll_sub.add_parser('all', help='Resolve all SEL entries') 480169419bafSAndrew Jeffery sel_ResolveAll.set_defaults(func=selResolveAll) 480269419bafSAndrew Jeffery sel_setResolved.set_defaults(func=selSetResolved) 480369419bafSAndrew Jeffery 480469419bafSAndrew Jeffery parser_chassis = subparsers.add_parser("chassis", help="Work with chassis power and status") 480569419bafSAndrew Jeffery chas_sub = parser_chassis.add_subparsers(title='subcommands', description='valid subcommands',help="sub-command help", dest='command') 480669419bafSAndrew Jeffery 480769419bafSAndrew Jeffery parser_chassis.add_argument('status', action='store_true', help='Returns the current status of the platform') 480869419bafSAndrew Jeffery parser_chassis.set_defaults(func=chassis) 480969419bafSAndrew Jeffery 481069419bafSAndrew Jeffery parser_chasPower = chas_sub.add_parser("power", help="Turn the chassis on or off, check the power state") 481169419bafSAndrew Jeffery parser_chasPower.add_argument('powcmd', choices=['on','softoff', 'hardoff', 'status'], help='The value for the power command. on, off, or status') 481269419bafSAndrew Jeffery parser_chasPower.set_defaults(func=chassisPower) 481369419bafSAndrew Jeffery 481469419bafSAndrew Jeffery #control the chassis identify led 481569419bafSAndrew Jeffery parser_chasIdent = chas_sub.add_parser("identify", help="Control the chassis identify led") 481669419bafSAndrew Jeffery parser_chasIdent.add_argument('identcmd', choices=['on', 'off', 'status'], help='The control option for the led: on, off, blink, status') 481769419bafSAndrew Jeffery parser_chasIdent.set_defaults(func=chassisIdent) 481869419bafSAndrew Jeffery 481969419bafSAndrew Jeffery #collect service data 482069419bafSAndrew Jeffery parser_servData = subparsers.add_parser("collect_service_data", help="Collect all bmc data needed for service") 482169419bafSAndrew Jeffery parser_servData.add_argument('-d', '--devdebug', action='store_true', help=argparse.SUPPRESS) 482269419bafSAndrew Jeffery parser_servData.set_defaults(func=collectServiceData) 482369419bafSAndrew Jeffery 482469419bafSAndrew Jeffery #system quick health check 482569419bafSAndrew Jeffery parser_healthChk = subparsers.add_parser("health_check", help="Work with platform sensors") 482669419bafSAndrew Jeffery parser_healthChk.set_defaults(func=healthCheck) 482769419bafSAndrew Jeffery 48284e178110SAsmitha Karunanithi #tasks 48294e178110SAsmitha Karunanithi parser_tasks = subparsers.add_parser("task", help="Work with tasks") 48304e178110SAsmitha Karunanithi tasks_sub = parser_tasks.add_subparsers(title='subcommands', description='valid subcommands',help="sub-command help", dest='command') 48314e178110SAsmitha Karunanithi tasks_sub.required = True 48324e178110SAsmitha Karunanithi get_Task = tasks_sub.add_parser('get', help="Get on Task Monitor URL") 48334e178110SAsmitha Karunanithi get_Task.add_argument("-u", "--taskURI", help="Task Monitor URI") 48344e178110SAsmitha Karunanithi get_Task.set_defaults(func=getTask) 48354e178110SAsmitha Karunanithi 483669419bafSAndrew Jeffery #work with dumps 483769419bafSAndrew Jeffery parser_bmcdump = subparsers.add_parser("dump", help="Work with dumps") 483869419bafSAndrew Jeffery parser_bmcdump.add_argument("-t", "--dumpType", default='bmc', choices=['bmc','SystemDump'],help="Type of dump") 483969419bafSAndrew Jeffery bmcDump_sub = parser_bmcdump.add_subparsers(title='subcommands', description='valid subcommands',help="sub-command help", dest='command') 484069419bafSAndrew Jeffery bmcDump_sub.required = True 484169419bafSAndrew Jeffery dump_Create = bmcDump_sub.add_parser('create', help="Create a dump of given type") 484269419bafSAndrew Jeffery dump_Create.set_defaults(func=dumpCreate) 484369419bafSAndrew Jeffery 484469419bafSAndrew Jeffery dump_list = bmcDump_sub.add_parser('list', help="list all dumps") 484569419bafSAndrew Jeffery dump_list.set_defaults(func=dumpList) 484669419bafSAndrew Jeffery 484769419bafSAndrew Jeffery parserdumpdelete = bmcDump_sub.add_parser('delete', help="Delete dump") 484869419bafSAndrew Jeffery parserdumpdelete.add_argument("-n", "--dumpNum", nargs='*', type=int, help="The Dump entry to delete") 484969419bafSAndrew Jeffery parserdumpdelete.set_defaults(func=dumpDelete) 485069419bafSAndrew Jeffery 485169419bafSAndrew Jeffery bmcDumpDelsub = parserdumpdelete.add_subparsers(title='subcommands', description='valid subcommands',help="sub-command help", dest='command') 485269419bafSAndrew Jeffery deleteAllDumps = bmcDumpDelsub.add_parser('all', help='Delete all dumps') 485369419bafSAndrew Jeffery deleteAllDumps.set_defaults(func=dumpDeleteAll) 485469419bafSAndrew Jeffery 485569419bafSAndrew Jeffery parser_dumpretrieve = bmcDump_sub.add_parser('retrieve', help='Retrieve a dump file') 485669419bafSAndrew Jeffery parser_dumpretrieve.add_argument("-n,", "--dumpNum", help="The Dump entry to retrieve") 485769419bafSAndrew Jeffery parser_dumpretrieve.add_argument("-s", "--dumpSaveLoc", help="The location to save the bmc dump file or file path for system dump") 485869419bafSAndrew Jeffery parser_dumpretrieve.set_defaults(func=dumpRetrieve) 485969419bafSAndrew Jeffery 486069419bafSAndrew Jeffery #bmc command for reseting the bmc 486169419bafSAndrew Jeffery parser_bmc = subparsers.add_parser('bmc', help="Work with the bmc") 486269419bafSAndrew Jeffery bmc_sub = parser_bmc.add_subparsers(title='subcommands', description='valid subcommands',help="sub-command help", dest='command') 486369419bafSAndrew Jeffery parser_BMCReset = bmc_sub.add_parser('reset', help='Reset the bmc' ) 486469419bafSAndrew Jeffery parser_BMCReset.add_argument('type', choices=['warm','cold'], help="Warm: Reboot the BMC, Cold: CLEAR config and reboot bmc") 486569419bafSAndrew Jeffery parser_bmc.add_argument('info', action='store_true', help="Displays information about the BMC hardware, including device revision, firmware revision, IPMI version supported, manufacturer ID, and information on additional device support.") 486669419bafSAndrew Jeffery parser_bmc.set_defaults(func=bmc) 486769419bafSAndrew Jeffery 486869419bafSAndrew Jeffery #add alias to the bmc command 486969419bafSAndrew Jeffery parser_mc = subparsers.add_parser('mc', help="Work with the management controller") 487069419bafSAndrew Jeffery mc_sub = parser_mc.add_subparsers(title='subcommands', description='valid subcommands',help="sub-command help", dest='command') 487169419bafSAndrew Jeffery parser_MCReset = mc_sub.add_parser('reset', help='Reset the bmc' ) 487269419bafSAndrew Jeffery parser_MCReset.add_argument('type', choices=['warm','cold'], help="Reboot the BMC") 487369419bafSAndrew Jeffery #parser_MCReset.add_argument('cold', action='store_true', help="Reboot the BMC and CLEAR the configuration") 487469419bafSAndrew Jeffery parser_mc.add_argument('info', action='store_true', help="Displays information about the BMC hardware, including device revision, firmware revision, IPMI version supported, manufacturer ID, and information on additional device support.") 487569419bafSAndrew Jeffery parser_MCReset.set_defaults(func=bmcReset) 487669419bafSAndrew Jeffery parser_mc.set_defaults(func=bmc) 487769419bafSAndrew Jeffery 487869419bafSAndrew Jeffery #gard clear 487969419bafSAndrew Jeffery parser_gc = subparsers.add_parser("gardclear", help="Used to clear gard records") 488069419bafSAndrew Jeffery parser_gc.set_defaults(func=gardClear) 488169419bafSAndrew Jeffery 488269419bafSAndrew Jeffery #firmware_flash 488369419bafSAndrew Jeffery parser_fw = subparsers.add_parser("firmware", help="Work with the system firmware") 488469419bafSAndrew Jeffery fwflash_subproc = parser_fw.add_subparsers(title='subcommands', description='valid firmware commands', help='sub-command help', dest='command') 488569419bafSAndrew Jeffery fwflash_subproc.required = True 488669419bafSAndrew Jeffery 488769419bafSAndrew Jeffery fwflash = fwflash_subproc.add_parser('flash', help="Flash the system firmware") 488869419bafSAndrew Jeffery fwflash.add_argument('type', choices=['bmc', 'pnor'], help="image type to flash") 488969419bafSAndrew Jeffery fwflash.add_argument('-f', '--fileloc', required=True, help="The absolute path to the firmware image") 489069419bafSAndrew Jeffery fwflash.set_defaults(func=fwFlash) 489169419bafSAndrew Jeffery 489269419bafSAndrew Jeffery fwActivate = fwflash_subproc.add_parser('activate', help="Activate existing image on the bmc") 489369419bafSAndrew Jeffery fwActivate.add_argument('imageID', help="The image ID to activate from the firmware list. Ex: 63c95399") 489469419bafSAndrew Jeffery fwActivate.set_defaults(func=activateFWImage) 489569419bafSAndrew Jeffery 489669419bafSAndrew Jeffery fwActivateStatus = fwflash_subproc.add_parser('activation_status', help="Check Status of activations") 489769419bafSAndrew Jeffery fwActivateStatus.set_defaults(func=activateStatus) 489869419bafSAndrew Jeffery 489969419bafSAndrew Jeffery fwList = fwflash_subproc.add_parser('list', help="List all of the installed firmware") 490069419bafSAndrew Jeffery fwList.add_argument('-v', '--verbose', action='store_true', help='Verbose output') 490169419bafSAndrew Jeffery fwList.set_defaults(func=firmwareList) 490269419bafSAndrew Jeffery 490369419bafSAndrew Jeffery fwprint = fwflash_subproc.add_parser('print', help="List all of the installed firmware") 490469419bafSAndrew Jeffery fwprint.add_argument('-v', '--verbose', action='store_true', help='Verbose output') 490569419bafSAndrew Jeffery fwprint.set_defaults(func=firmwareList) 490669419bafSAndrew Jeffery 490769419bafSAndrew Jeffery fwDelete = fwflash_subproc.add_parser('delete', help="Delete an existing firmware version") 490869419bafSAndrew Jeffery fwDelete.add_argument('versionID', help="The version ID to delete from the firmware list. Ex: 63c95399") 490969419bafSAndrew Jeffery fwDelete.set_defaults(func=deleteFWVersion) 491069419bafSAndrew Jeffery 49110b5b2041SKlaus Heinrich Kiwi fwDeleteAll = fwflash_subproc.add_parser('deleteAll', help="Delete ALL firmware versions") 49120b5b2041SKlaus Heinrich Kiwi fwDeleteAll.set_defaults(func=deleteFWAll) 49130b5b2041SKlaus Heinrich Kiwi 491469419bafSAndrew Jeffery #logging 491569419bafSAndrew Jeffery parser_logging = subparsers.add_parser("logging", help="logging controls") 491669419bafSAndrew Jeffery logging_sub = parser_logging.add_subparsers(title='subcommands', description='valid subcommands',help="sub-command help", dest='command') 491769419bafSAndrew Jeffery 491869419bafSAndrew Jeffery #turn rest api logging on/off 491969419bafSAndrew Jeffery parser_rest_logging = logging_sub.add_parser("rest_api", help="turn rest api logging on/off") 492069419bafSAndrew Jeffery parser_rest_logging.add_argument('rest_logging', choices=['on', 'off'], help='The control option for rest logging: on, off') 492169419bafSAndrew Jeffery parser_rest_logging.set_defaults(func=restLogging) 492269419bafSAndrew Jeffery 492369419bafSAndrew Jeffery #remote logging 492469419bafSAndrew Jeffery parser_remote_logging = logging_sub.add_parser("remote_logging", help="Remote logging (rsyslog) commands") 492569419bafSAndrew Jeffery parser_remote_logging.add_argument('remote_logging', choices=['view', 'disable'], help='Remote logging (rsyslog) commands') 492669419bafSAndrew Jeffery parser_remote_logging.set_defaults(func=remoteLogging) 492769419bafSAndrew Jeffery 492869419bafSAndrew Jeffery #configure remote logging 492969419bafSAndrew Jeffery parser_remote_logging_config = logging_sub.add_parser("remote_logging_config", help="Configure remote logging (rsyslog)") 493069419bafSAndrew Jeffery parser_remote_logging_config.add_argument("-a", "--address", required=True, help="Set IP address of rsyslog server") 493169419bafSAndrew Jeffery parser_remote_logging_config.add_argument("-p", "--port", required=True, type=int, help="Set Port of rsyslog server") 493269419bafSAndrew Jeffery parser_remote_logging_config.set_defaults(func=remoteLoggingConfig) 493369419bafSAndrew Jeffery 493469419bafSAndrew Jeffery #certificate management 493569419bafSAndrew Jeffery parser_cert = subparsers.add_parser("certificate", help="Certificate management") 493669419bafSAndrew Jeffery certMgmt_subproc = parser_cert.add_subparsers(title='subcommands', description='valid certificate commands', help='sub-command help', dest='command') 493769419bafSAndrew Jeffery 493869419bafSAndrew Jeffery certUpdate = certMgmt_subproc.add_parser('update', help="Update the certificate") 493969419bafSAndrew Jeffery certUpdate.add_argument('type', choices=['server', 'client', 'authority'], help="certificate type to update") 494069419bafSAndrew Jeffery certUpdate.add_argument('service', choices=['https', 'ldap'], help="Service to update") 494169419bafSAndrew Jeffery certUpdate.add_argument('-f', '--fileloc', required=True, help="The absolute path to the certificate file") 494269419bafSAndrew Jeffery certUpdate.set_defaults(func=certificateUpdate) 494369419bafSAndrew Jeffery 494469419bafSAndrew Jeffery certDelete = certMgmt_subproc.add_parser('delete', help="Delete the certificate") 494569419bafSAndrew Jeffery certDelete.add_argument('type', choices=['server', 'client', 'authority'], help="certificate type to delete") 494669419bafSAndrew Jeffery certDelete.add_argument('service', choices=['https', 'ldap'], help="Service to delete the certificate") 494769419bafSAndrew Jeffery certDelete.set_defaults(func=certificateDelete) 494869419bafSAndrew Jeffery 494969419bafSAndrew Jeffery certReplace = certMgmt_subproc.add_parser('replace', 495069419bafSAndrew Jeffery help="Replace the certificate") 495169419bafSAndrew Jeffery certReplace.add_argument('type', choices=['server', 'client', 'authority'], 495269419bafSAndrew Jeffery help="certificate type to replace") 495369419bafSAndrew Jeffery certReplace.add_argument('service', choices=['https', 'ldap'], 495469419bafSAndrew Jeffery help="Service to replace the certificate") 495569419bafSAndrew Jeffery certReplace.add_argument('-f', '--fileloc', required=True, 495669419bafSAndrew Jeffery help="The absolute path to the certificate file") 495769419bafSAndrew Jeffery certReplace.set_defaults(func=certificateReplace) 495869419bafSAndrew Jeffery 495969419bafSAndrew Jeffery certDisplay = certMgmt_subproc.add_parser('display', 496069419bafSAndrew Jeffery help="Print the certificate") 496169419bafSAndrew Jeffery certDisplay.add_argument('type', choices=['server', 'client', 'authority'], 496269419bafSAndrew Jeffery help="certificate type to display") 496369419bafSAndrew Jeffery certDisplay.set_defaults(func=certificateDisplay) 496469419bafSAndrew Jeffery 496569419bafSAndrew Jeffery certList = certMgmt_subproc.add_parser('list', 496669419bafSAndrew Jeffery help="Certificate list") 496769419bafSAndrew Jeffery certList.set_defaults(func=certificateList) 496869419bafSAndrew Jeffery 496969419bafSAndrew Jeffery certGenerateCSR = certMgmt_subproc.add_parser('generatecsr', help="Generate CSR") 497069419bafSAndrew Jeffery certGenerateCSR.add_argument('type', choices=['server', 'client', 'authority'], 497169419bafSAndrew Jeffery help="Generate CSR") 497269419bafSAndrew Jeffery certGenerateCSR.add_argument('city', 497369419bafSAndrew Jeffery help="The city or locality of the organization making the request") 497469419bafSAndrew Jeffery certGenerateCSR.add_argument('commonName', 497569419bafSAndrew Jeffery help="The fully qualified domain name of the component that is being secured.") 497669419bafSAndrew Jeffery certGenerateCSR.add_argument('country', 497769419bafSAndrew Jeffery help="The country of the organization making the request") 497869419bafSAndrew Jeffery certGenerateCSR.add_argument('organization', 497969419bafSAndrew Jeffery help="The name of the organization making the request.") 498069419bafSAndrew Jeffery certGenerateCSR.add_argument('organizationUnit', 498169419bafSAndrew Jeffery help="The name of the unit or division of the organization making the request.") 498269419bafSAndrew Jeffery certGenerateCSR.add_argument('state', 498369419bafSAndrew Jeffery help="The state, province, or region of the organization making the request.") 498469419bafSAndrew Jeffery certGenerateCSR.add_argument('keyPairAlgorithm', choices=['RSA', 'EC'], 498569419bafSAndrew Jeffery help="The type of key pair for use with signing algorithms.") 498669419bafSAndrew Jeffery certGenerateCSR.add_argument('keyCurveId', 498769419bafSAndrew Jeffery help="The curve ID to be used with the key, if needed based on the value of the 'KeyPairAlgorithm' parameter.") 498869419bafSAndrew Jeffery certGenerateCSR.add_argument('contactPerson', 498969419bafSAndrew Jeffery help="The name of the user making the request") 499069419bafSAndrew Jeffery certGenerateCSR.add_argument('email', 499169419bafSAndrew Jeffery help="The email address of the contact within the organization") 499269419bafSAndrew Jeffery certGenerateCSR.add_argument('alternativeNames', 499369419bafSAndrew Jeffery help="Additional hostnames of the component that is being secured") 499469419bafSAndrew Jeffery certGenerateCSR.add_argument('givenname', 499569419bafSAndrew Jeffery help="The given name of the user making the request") 499669419bafSAndrew Jeffery certGenerateCSR.add_argument('surname', 499769419bafSAndrew Jeffery help="The surname of the user making the request") 499869419bafSAndrew Jeffery certGenerateCSR.add_argument('unstructuredname', 499969419bafSAndrew Jeffery help="he unstructured name of the subject") 500069419bafSAndrew Jeffery certGenerateCSR.add_argument('initials', 500169419bafSAndrew Jeffery help="The initials of the user making the request") 500269419bafSAndrew Jeffery certGenerateCSR.set_defaults(func=certificateGenerateCSR) 500369419bafSAndrew Jeffery 500469419bafSAndrew Jeffery # local users 500569419bafSAndrew Jeffery parser_users = subparsers.add_parser("local_users", help="Work with local users") 500669419bafSAndrew Jeffery parser_users.add_argument('local_users', choices=['disableall','enableall', 'queryenabled'], help="Disable, enable or query local user accounts") 500769419bafSAndrew Jeffery parser_users.add_argument('-v', '--verbose', action='store_true', help='Verbose output') 500869419bafSAndrew Jeffery parser_users.set_defaults(func=localUsers) 500969419bafSAndrew Jeffery 501069419bafSAndrew Jeffery #LDAP 501169419bafSAndrew Jeffery parser_ldap = subparsers.add_parser("ldap", help="LDAP controls") 501269419bafSAndrew Jeffery ldap_sub = parser_ldap.add_subparsers(title='subcommands', description='valid subcommands',help="sub-command help", dest='command') 501369419bafSAndrew Jeffery 501469419bafSAndrew Jeffery #configure and enable LDAP 501569419bafSAndrew Jeffery parser_ldap_config = ldap_sub.add_parser("enable", help="Configure and enables the LDAP") 501669419bafSAndrew Jeffery parser_ldap_config.add_argument("-a", "--uri", required=True, help="Set LDAP server URI") 501769419bafSAndrew Jeffery parser_ldap_config.add_argument("-B", "--bindDN", required=True, help="Set the bind DN of the LDAP server") 501869419bafSAndrew Jeffery parser_ldap_config.add_argument("-b", "--baseDN", required=True, help="Set the base DN of the LDAP server") 501969419bafSAndrew Jeffery parser_ldap_config.add_argument("-p", "--bindPassword", required=True, help="Set the bind password of the LDAP server") 502069419bafSAndrew Jeffery parser_ldap_config.add_argument("-S", "--scope", choices=['sub','one', 'base'], 502169419bafSAndrew Jeffery help='Specifies the search scope:subtree, one level or base object.') 502269419bafSAndrew Jeffery parser_ldap_config.add_argument("-t", "--serverType", required=True, choices=['ActiveDirectory','OpenLDAP'], 502369419bafSAndrew Jeffery help='Specifies the configured server is ActiveDirectory(AD) or OpenLdap') 502469419bafSAndrew Jeffery parser_ldap_config.add_argument("-g","--groupAttrName", required=False, default='', help="Group Attribute Name") 502569419bafSAndrew Jeffery parser_ldap_config.add_argument("-u","--userAttrName", required=False, default='', help="User Attribute Name") 502669419bafSAndrew Jeffery parser_ldap_config.set_defaults(func=enableLDAPConfig) 502769419bafSAndrew Jeffery 502869419bafSAndrew Jeffery # disable LDAP 502969419bafSAndrew Jeffery parser_disable_ldap = ldap_sub.add_parser("disable", help="disables the LDAP") 503069419bafSAndrew Jeffery parser_disable_ldap.set_defaults(func=disableLDAP) 503169419bafSAndrew Jeffery # view-config 503269419bafSAndrew Jeffery parser_ldap_config = \ 503369419bafSAndrew Jeffery ldap_sub.add_parser("view-config", help="prints out a list of all \ 503469419bafSAndrew Jeffery LDAPS's configured properties") 503569419bafSAndrew Jeffery parser_ldap_config.set_defaults(func=viewLDAPConfig) 503669419bafSAndrew Jeffery 503769419bafSAndrew Jeffery #create group privilege mapping 503869419bafSAndrew Jeffery parser_ldap_mapper = ldap_sub.add_parser("privilege-mapper", help="LDAP group privilege controls") 503969419bafSAndrew Jeffery parser_ldap_mapper_sub = parser_ldap_mapper.add_subparsers(title='subcommands', description='valid subcommands', 504069419bafSAndrew Jeffery help="sub-command help", dest='command') 504169419bafSAndrew Jeffery 504269419bafSAndrew Jeffery parser_ldap_mapper_create = parser_ldap_mapper_sub.add_parser("create", help="Create mapping of ldap group and privilege") 504369419bafSAndrew Jeffery parser_ldap_mapper_create.add_argument("-t", "--serverType", choices=['ActiveDirectory','OpenLDAP'], 504469419bafSAndrew Jeffery help='Specifies the configured server is ActiveDirectory(AD) or OpenLdap') 504569419bafSAndrew Jeffery parser_ldap_mapper_create.add_argument("-g","--groupName",required=True,help="Group Name") 504669419bafSAndrew Jeffery parser_ldap_mapper_create.add_argument("-p","--privilege",choices=['priv-admin','priv-operator','priv-user','priv-callback'],required=True,help="Privilege") 504769419bafSAndrew Jeffery parser_ldap_mapper_create.set_defaults(func=createPrivilegeMapping) 504869419bafSAndrew Jeffery 504969419bafSAndrew Jeffery #list group privilege mapping 505069419bafSAndrew Jeffery parser_ldap_mapper_list = parser_ldap_mapper_sub.add_parser("list",help="List privilege mapping") 505169419bafSAndrew Jeffery parser_ldap_mapper_list.add_argument("-t", "--serverType", choices=['ActiveDirectory','OpenLDAP'], 505269419bafSAndrew Jeffery help='Specifies the configured server is ActiveDirectory(AD) or OpenLdap') 505369419bafSAndrew Jeffery parser_ldap_mapper_list.set_defaults(func=listPrivilegeMapping) 505469419bafSAndrew Jeffery 505569419bafSAndrew Jeffery #delete group privilege mapping 505669419bafSAndrew Jeffery parser_ldap_mapper_delete = parser_ldap_mapper_sub.add_parser("delete",help="Delete privilege mapping") 505769419bafSAndrew Jeffery parser_ldap_mapper_delete.add_argument("-t", "--serverType", choices=['ActiveDirectory','OpenLDAP'], 505869419bafSAndrew Jeffery help='Specifies the configured server is ActiveDirectory(AD) or OpenLdap') 505969419bafSAndrew Jeffery parser_ldap_mapper_delete.add_argument("-g","--groupName",required=True,help="Group Name") 506069419bafSAndrew Jeffery parser_ldap_mapper_delete.set_defaults(func=deletePrivilegeMapping) 506169419bafSAndrew Jeffery 506269419bafSAndrew Jeffery #deleteAll group privilege mapping 506369419bafSAndrew Jeffery parser_ldap_mapper_delete = parser_ldap_mapper_sub.add_parser("purge",help="Delete All privilege mapping") 506469419bafSAndrew Jeffery parser_ldap_mapper_delete.add_argument("-t", "--serverType", choices=['ActiveDirectory','OpenLDAP'], 506569419bafSAndrew Jeffery help='Specifies the configured server is ActiveDirectory(AD) or OpenLdap') 506669419bafSAndrew Jeffery parser_ldap_mapper_delete.set_defaults(func=deleteAllPrivilegeMapping) 506769419bafSAndrew Jeffery 506869419bafSAndrew Jeffery # set local user password 506969419bafSAndrew Jeffery parser_set_password = subparsers.add_parser("set_password", 507069419bafSAndrew Jeffery help="Set password of local user") 507169419bafSAndrew Jeffery parser_set_password.add_argument( "-p", "--password", required=True, 507269419bafSAndrew Jeffery help="Password of local user") 507369419bafSAndrew Jeffery parser_set_password.set_defaults(func=setPassword) 507469419bafSAndrew Jeffery 507569419bafSAndrew Jeffery # network 507669419bafSAndrew Jeffery parser_nw = subparsers.add_parser("network", help="network controls") 507769419bafSAndrew Jeffery nw_sub = parser_nw.add_subparsers(title='subcommands', 507869419bafSAndrew Jeffery description='valid subcommands', 507969419bafSAndrew Jeffery help="sub-command help", 508069419bafSAndrew Jeffery dest='command') 508169419bafSAndrew Jeffery 508269419bafSAndrew Jeffery # enable DHCP 508369419bafSAndrew Jeffery parser_enable_dhcp = nw_sub.add_parser("enableDHCP", 508469419bafSAndrew Jeffery help="enables the DHCP on given " 508569419bafSAndrew Jeffery "Interface") 508669419bafSAndrew Jeffery parser_enable_dhcp.add_argument("-I", "--Interface", required=True, 508769419bafSAndrew Jeffery help="Name of the ethernet interface(it can" 508869419bafSAndrew Jeffery "be obtained by the " 508969419bafSAndrew Jeffery "command:network view-config)" 509069419bafSAndrew Jeffery "Ex: eth0 or eth1 or VLAN(VLAN=eth0_50 etc)") 509169419bafSAndrew Jeffery parser_enable_dhcp.set_defaults(func=enableDHCP) 509269419bafSAndrew Jeffery 509369419bafSAndrew Jeffery # disable DHCP 509469419bafSAndrew Jeffery parser_disable_dhcp = nw_sub.add_parser("disableDHCP", 509569419bafSAndrew Jeffery help="disables the DHCP on given " 509669419bafSAndrew Jeffery "Interface") 509769419bafSAndrew Jeffery parser_disable_dhcp.add_argument("-I", "--Interface", required=True, 509869419bafSAndrew Jeffery help="Name of the ethernet interface(it can" 509969419bafSAndrew Jeffery "be obtained by the " 510069419bafSAndrew Jeffery "command:network view-config)" 510169419bafSAndrew Jeffery "Ex: eth0 or eth1 or VLAN(VLAN=eth0_50 etc)") 510269419bafSAndrew Jeffery parser_disable_dhcp.set_defaults(func=disableDHCP) 510369419bafSAndrew Jeffery 510469419bafSAndrew Jeffery # get HostName 510569419bafSAndrew Jeffery parser_gethostname = nw_sub.add_parser("getHostName", 510669419bafSAndrew Jeffery help="prints out HostName") 510769419bafSAndrew Jeffery parser_gethostname.set_defaults(func=getHostname) 510869419bafSAndrew Jeffery 510969419bafSAndrew Jeffery # set HostName 511069419bafSAndrew Jeffery parser_sethostname = nw_sub.add_parser("setHostName", help="sets HostName") 511169419bafSAndrew Jeffery parser_sethostname.add_argument("-H", "--HostName", required=True, 511269419bafSAndrew Jeffery help="A HostName for the BMC") 511369419bafSAndrew Jeffery parser_sethostname.set_defaults(func=setHostname) 511469419bafSAndrew Jeffery 511569419bafSAndrew Jeffery # get domainname 511669419bafSAndrew Jeffery parser_getdomainname = nw_sub.add_parser("getDomainName", 511769419bafSAndrew Jeffery help="prints out DomainName of " 511869419bafSAndrew Jeffery "given Interface") 511969419bafSAndrew Jeffery parser_getdomainname.add_argument("-I", "--Interface", required=True, 512069419bafSAndrew Jeffery help="Name of the ethernet interface(it " 512169419bafSAndrew Jeffery "can be obtained by the " 512269419bafSAndrew Jeffery "command:network view-config)" 512369419bafSAndrew Jeffery "Ex: eth0 or eth1 or VLAN(VLAN=eth0_50 etc)") 512469419bafSAndrew Jeffery parser_getdomainname.set_defaults(func=getDomainName) 512569419bafSAndrew Jeffery 512669419bafSAndrew Jeffery # set domainname 512769419bafSAndrew Jeffery parser_setdomainname = nw_sub.add_parser("setDomainName", 512869419bafSAndrew Jeffery help="sets DomainName of given " 512969419bafSAndrew Jeffery "Interface") 513069419bafSAndrew Jeffery parser_setdomainname.add_argument("-D", "--DomainName", required=True, 513169419bafSAndrew Jeffery help="Ex: DomainName=Domain1,Domain2,...") 513269419bafSAndrew Jeffery parser_setdomainname.add_argument("-I", "--Interface", required=True, 513369419bafSAndrew Jeffery help="Name of the ethernet interface(it " 513469419bafSAndrew Jeffery "can be obtained by the " 513569419bafSAndrew Jeffery "command:network view-config)" 513669419bafSAndrew Jeffery "Ex: eth0 or eth1 or VLAN(VLAN=eth0_50 etc)") 513769419bafSAndrew Jeffery parser_setdomainname.set_defaults(func=setDomainName) 513869419bafSAndrew Jeffery 513969419bafSAndrew Jeffery # get MACAddress 514069419bafSAndrew Jeffery parser_getmacaddress = nw_sub.add_parser("getMACAddress", 514169419bafSAndrew Jeffery help="prints out MACAddress the " 514269419bafSAndrew Jeffery "given Interface") 514369419bafSAndrew Jeffery parser_getmacaddress.add_argument("-I", "--Interface", required=True, 514469419bafSAndrew Jeffery help="Name of the ethernet interface(it " 514569419bafSAndrew Jeffery "can be obtained by the " 514669419bafSAndrew Jeffery "command:network view-config)" 514769419bafSAndrew Jeffery "Ex: eth0 or eth1 or VLAN(VLAN=eth0_50 etc)") 514869419bafSAndrew Jeffery parser_getmacaddress.set_defaults(func=getMACAddress) 514969419bafSAndrew Jeffery 515069419bafSAndrew Jeffery # set MACAddress 515169419bafSAndrew Jeffery parser_setmacaddress = nw_sub.add_parser("setMACAddress", 515269419bafSAndrew Jeffery help="sets MACAddress") 515369419bafSAndrew Jeffery parser_setmacaddress.add_argument("-MA", "--MACAddress", required=True, 515469419bafSAndrew Jeffery help="A MACAddress for the given " 515569419bafSAndrew Jeffery "Interface") 515669419bafSAndrew Jeffery parser_setmacaddress.add_argument("-I", "--Interface", required=True, 515769419bafSAndrew Jeffery help="Name of the ethernet interface(it can" 515869419bafSAndrew Jeffery "be obtained by the " 515969419bafSAndrew Jeffery "command:network view-config)" 516069419bafSAndrew Jeffery "Ex: eth0 or eth1 or VLAN(VLAN=eth0_50 etc)") 516169419bafSAndrew Jeffery parser_setmacaddress.set_defaults(func=setMACAddress) 516269419bafSAndrew Jeffery 516369419bafSAndrew Jeffery # get DefaultGW 516469419bafSAndrew Jeffery parser_getdefaultgw = nw_sub.add_parser("getDefaultGW", 516569419bafSAndrew Jeffery help="prints out DefaultGateway " 516669419bafSAndrew Jeffery "the BMC") 516769419bafSAndrew Jeffery parser_getdefaultgw.set_defaults(func=getDefaultGateway) 516869419bafSAndrew Jeffery 516969419bafSAndrew Jeffery # set DefaultGW 517069419bafSAndrew Jeffery parser_setdefaultgw = nw_sub.add_parser("setDefaultGW", 517169419bafSAndrew Jeffery help="sets DefaultGW") 517269419bafSAndrew Jeffery parser_setdefaultgw.add_argument("-GW", "--DefaultGW", required=True, 517369419bafSAndrew Jeffery help="A DefaultGateway for the BMC") 517469419bafSAndrew Jeffery parser_setdefaultgw.set_defaults(func=setDefaultGateway) 517569419bafSAndrew Jeffery 517669419bafSAndrew Jeffery # view network Config 517769419bafSAndrew Jeffery parser_ldap_config = nw_sub.add_parser("view-config", help="prints out a " 517869419bafSAndrew Jeffery "list of all network's configured " 517969419bafSAndrew Jeffery "properties") 518069419bafSAndrew Jeffery parser_ldap_config.set_defaults(func=viewNWConfig) 518169419bafSAndrew Jeffery 518269419bafSAndrew Jeffery # get DNS 518369419bafSAndrew Jeffery parser_getDNS = nw_sub.add_parser("getDNS", 518469419bafSAndrew Jeffery help="prints out DNS servers on the " 518569419bafSAndrew Jeffery "given interface") 518669419bafSAndrew Jeffery parser_getDNS.add_argument("-I", "--Interface", required=True, 518769419bafSAndrew Jeffery help="Name of the ethernet interface(it can" 518869419bafSAndrew Jeffery "be obtained by the " 518969419bafSAndrew Jeffery "command:network view-config)" 519069419bafSAndrew Jeffery "Ex: eth0 or eth1 or VLAN(VLAN=eth0_50 etc)") 519169419bafSAndrew Jeffery parser_getDNS.set_defaults(func=getDNS) 519269419bafSAndrew Jeffery 519369419bafSAndrew Jeffery # set DNS 519469419bafSAndrew Jeffery parser_setDNS = nw_sub.add_parser("setDNS", 519569419bafSAndrew Jeffery help="sets DNS servers on the given " 519669419bafSAndrew Jeffery "interface") 519769419bafSAndrew Jeffery parser_setDNS.add_argument("-d", "--DNSServers", required=True, 519869419bafSAndrew Jeffery help="Ex: DNSSERVERS=DNS1,DNS2,...") 519969419bafSAndrew Jeffery parser_setDNS.add_argument("-I", "--Interface", required=True, 520069419bafSAndrew Jeffery help="Name of the ethernet interface(it can" 520169419bafSAndrew Jeffery "be obtained by the " 520269419bafSAndrew Jeffery "command:network view-config)" 520369419bafSAndrew Jeffery "Ex: eth0 or eth1 or VLAN(VLAN=eth0_50 etc)") 520469419bafSAndrew Jeffery parser_setDNS.set_defaults(func=setDNS) 520569419bafSAndrew Jeffery 520669419bafSAndrew Jeffery # get NTP 520769419bafSAndrew Jeffery parser_getNTP = nw_sub.add_parser("getNTP", 520869419bafSAndrew Jeffery help="prints out NTP servers on the " 520969419bafSAndrew Jeffery "given interface") 521069419bafSAndrew Jeffery parser_getNTP.add_argument("-I", "--Interface", required=True, 521169419bafSAndrew Jeffery help="Name of the ethernet interface(it can" 521269419bafSAndrew Jeffery "be obtained by the " 521369419bafSAndrew Jeffery "command:network view-config)" 521469419bafSAndrew Jeffery "Ex: eth0 or eth1 or VLAN(VLAN=eth0_50 etc)") 521569419bafSAndrew Jeffery parser_getNTP.set_defaults(func=getNTP) 521669419bafSAndrew Jeffery 521769419bafSAndrew Jeffery # set NTP 521869419bafSAndrew Jeffery parser_setNTP = nw_sub.add_parser("setNTP", 521969419bafSAndrew Jeffery help="sets NTP servers on the given " 522069419bafSAndrew Jeffery "interface") 522169419bafSAndrew Jeffery parser_setNTP.add_argument("-N", "--NTPServers", required=True, 522269419bafSAndrew Jeffery help="Ex: NTPSERVERS=NTP1,NTP2,...") 522369419bafSAndrew Jeffery parser_setNTP.add_argument("-I", "--Interface", required=True, 522469419bafSAndrew Jeffery help="Name of the ethernet interface(it can" 522569419bafSAndrew Jeffery "be obtained by the " 522669419bafSAndrew Jeffery "command:network view-config)" 522769419bafSAndrew Jeffery "Ex: eth0 or eth1 or VLAN(VLAN=eth0_50 etc)") 522869419bafSAndrew Jeffery parser_setNTP.set_defaults(func=setNTP) 522969419bafSAndrew Jeffery 523069419bafSAndrew Jeffery # configure IP 523169419bafSAndrew Jeffery parser_ip_config = nw_sub.add_parser("addIP", help="Sets IP address to" 523269419bafSAndrew Jeffery "given interface") 523369419bafSAndrew Jeffery parser_ip_config.add_argument("-a", "--address", required=True, 523469419bafSAndrew Jeffery help="IP address of given interface") 523569419bafSAndrew Jeffery parser_ip_config.add_argument("-gw", "--gateway", required=False, default='', 523669419bafSAndrew Jeffery help="The gateway for given interface") 523769419bafSAndrew Jeffery parser_ip_config.add_argument("-l", "--prefixLength", required=True, 523869419bafSAndrew Jeffery help="The prefixLength of IP address") 523969419bafSAndrew Jeffery parser_ip_config.add_argument("-p", "--type", required=True, 524069419bafSAndrew Jeffery choices=['ipv4', 'ipv6'], 524169419bafSAndrew Jeffery help="The protocol type of the given" 524269419bafSAndrew Jeffery "IP address") 524369419bafSAndrew Jeffery parser_ip_config.add_argument("-I", "--Interface", required=True, 524469419bafSAndrew Jeffery help="Name of the ethernet interface(it can" 524569419bafSAndrew Jeffery "be obtained by the " 524669419bafSAndrew Jeffery "command:network view-config)" 524769419bafSAndrew Jeffery "Ex: eth0 or eth1 or VLAN(VLAN=eth0_50 etc)") 524869419bafSAndrew Jeffery parser_ip_config.set_defaults(func=addIP) 524969419bafSAndrew Jeffery 525069419bafSAndrew Jeffery # getIP 525169419bafSAndrew Jeffery parser_getIP = nw_sub.add_parser("getIP", help="prints out IP address" 525269419bafSAndrew Jeffery "of given interface") 525369419bafSAndrew Jeffery parser_getIP.add_argument("-I", "--Interface", required=True, 525469419bafSAndrew Jeffery help="Name of the ethernet interface(it can" 525569419bafSAndrew Jeffery "be obtained by the command:network view-config)" 525669419bafSAndrew Jeffery "Ex: eth0 or eth1 or VLAN(VLAN=eth0_50 etc)") 525769419bafSAndrew Jeffery parser_getIP.set_defaults(func=getIP) 525869419bafSAndrew Jeffery 525969419bafSAndrew Jeffery # rmIP 526069419bafSAndrew Jeffery parser_rmIP = nw_sub.add_parser("rmIP", help="deletes IP address" 526169419bafSAndrew Jeffery "of given interface") 526269419bafSAndrew Jeffery parser_rmIP.add_argument("-a", "--address", required=True, 526369419bafSAndrew Jeffery help="IP address to remove form given Interface") 526469419bafSAndrew Jeffery parser_rmIP.add_argument("-I", "--Interface", required=True, 526569419bafSAndrew Jeffery help="Name of the ethernet interface(it can" 526669419bafSAndrew Jeffery "be obtained by the command:network view-config)" 526769419bafSAndrew Jeffery "Ex: eth0 or eth1 or VLAN(VLAN=eth0_50 etc)") 526869419bafSAndrew Jeffery parser_rmIP.set_defaults(func=deleteIP) 526969419bafSAndrew Jeffery 527069419bafSAndrew Jeffery # add VLAN 527169419bafSAndrew Jeffery parser_create_vlan = nw_sub.add_parser("addVLAN", help="enables VLAN " 527269419bafSAndrew Jeffery "on given interface with given " 527369419bafSAndrew Jeffery "VLAN Identifier") 527469419bafSAndrew Jeffery parser_create_vlan.add_argument("-I", "--Interface", required=True, 527569419bafSAndrew Jeffery choices=['eth0', 'eth1'], 527669419bafSAndrew Jeffery help="Name of the ethernet interface") 527769419bafSAndrew Jeffery parser_create_vlan.add_argument("-n", "--Identifier", required=True, 527869419bafSAndrew Jeffery help="VLAN Identifier") 527969419bafSAndrew Jeffery parser_create_vlan.set_defaults(func=addVLAN) 528069419bafSAndrew Jeffery 528169419bafSAndrew Jeffery # delete VLAN 528269419bafSAndrew Jeffery parser_delete_vlan = nw_sub.add_parser("deleteVLAN", help="disables VLAN " 528369419bafSAndrew Jeffery "on given interface with given " 528469419bafSAndrew Jeffery "VLAN Identifier") 528569419bafSAndrew Jeffery parser_delete_vlan.add_argument("-I", "--Interface", required=True, 528669419bafSAndrew Jeffery help="Name of the ethernet interface(it can" 528769419bafSAndrew Jeffery "be obtained by the " 528869419bafSAndrew Jeffery "command:network view-config)" 528969419bafSAndrew Jeffery "Ex: eth0 or eth1 or VLAN(VLAN=eth0_50 etc)") 529069419bafSAndrew Jeffery parser_delete_vlan.set_defaults(func=deleteVLAN) 529169419bafSAndrew Jeffery 529269419bafSAndrew Jeffery # viewDHCPConfig 529369419bafSAndrew Jeffery parser_viewDHCPConfig = nw_sub.add_parser("viewDHCPConfig", 529469419bafSAndrew Jeffery help="Shows DHCP configured " 529569419bafSAndrew Jeffery "Properties") 529669419bafSAndrew Jeffery parser_viewDHCPConfig.set_defaults(func=viewDHCPConfig) 529769419bafSAndrew Jeffery 529869419bafSAndrew Jeffery # configureDHCP 529969419bafSAndrew Jeffery parser_configDHCP = nw_sub.add_parser("configureDHCP", 530069419bafSAndrew Jeffery help="Configures/updates DHCP " 530169419bafSAndrew Jeffery "Properties") 530269419bafSAndrew Jeffery parser_configDHCP.add_argument("-d", "--DNSEnabled", type=str2bool, 530369419bafSAndrew Jeffery required=True, help="Sets DNSEnabled property") 530469419bafSAndrew Jeffery parser_configDHCP.add_argument("-n", "--HostNameEnabled", type=str2bool, 530569419bafSAndrew Jeffery required=True, 530669419bafSAndrew Jeffery help="Sets HostNameEnabled property") 530769419bafSAndrew Jeffery parser_configDHCP.add_argument("-t", "--NTPEnabled", type=str2bool, 530869419bafSAndrew Jeffery required=True, 530969419bafSAndrew Jeffery help="Sets NTPEnabled property") 531069419bafSAndrew Jeffery parser_configDHCP.add_argument("-s", "--SendHostNameEnabled", type=str2bool, 531169419bafSAndrew Jeffery required=True, 531269419bafSAndrew Jeffery help="Sets SendHostNameEnabled property") 531369419bafSAndrew Jeffery parser_configDHCP.set_defaults(func=configureDHCP) 531469419bafSAndrew Jeffery 531569419bafSAndrew Jeffery # network factory reset 531669419bafSAndrew Jeffery parser_nw_reset = nw_sub.add_parser("nwReset", 531769419bafSAndrew Jeffery help="Resets networks setting to " 531869419bafSAndrew Jeffery "factory defaults. " 531969419bafSAndrew Jeffery "note:Reset settings will be applied " 532069419bafSAndrew Jeffery "after BMC reboot") 532169419bafSAndrew Jeffery parser_nw_reset.set_defaults(func=nwReset) 532269419bafSAndrew Jeffery 532369419bafSAndrew Jeffery return parser 532469419bafSAndrew Jeffery 532569419bafSAndrew Jefferydef main(argv=None): 532669419bafSAndrew Jeffery """ 532769419bafSAndrew Jeffery main function for running the command line utility as a sub application 532869419bafSAndrew Jeffery """ 532969419bafSAndrew Jeffery global toolVersion 533069419bafSAndrew Jeffery toolVersion = "1.19" 533169419bafSAndrew Jeffery global isRedfishSupport 533269419bafSAndrew Jeffery 533369419bafSAndrew Jeffery parser = createCommandParser() 533469419bafSAndrew Jeffery args = parser.parse_args(argv) 533569419bafSAndrew Jeffery 533669419bafSAndrew Jeffery totTimeStart = int(round(time.time()*1000)) 533769419bafSAndrew Jeffery 533869419bafSAndrew Jeffery if(sys.version_info < (3,0)): 533969419bafSAndrew Jeffery urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) 534069419bafSAndrew Jeffery if sys.version_info >= (3,0): 534169419bafSAndrew Jeffery requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning) 534269419bafSAndrew Jeffery if (args.version): 534369419bafSAndrew Jeffery print("Version: "+ toolVersion) 534469419bafSAndrew Jeffery sys.exit(0) 534569419bafSAndrew Jeffery if (hasattr(args, 'fileloc') and args.fileloc is not None and 'print' in args.command): 534669419bafSAndrew Jeffery mysess = None 534769419bafSAndrew Jeffery print(selPrint('N/A', args, mysess)) 534869419bafSAndrew Jeffery else: 534969419bafSAndrew Jeffery if(hasattr(args, 'host') and hasattr(args,'user')): 535069419bafSAndrew Jeffery if (args.askpw): 535169419bafSAndrew Jeffery pw = getpass.getpass() 535269419bafSAndrew Jeffery elif(args.PW is not None): 535369419bafSAndrew Jeffery pw = args.PW 535469419bafSAndrew Jeffery elif(args.PWenvvar): 535569419bafSAndrew Jeffery pw = os.environ['OPENBMCTOOL_PASSWORD'] 535669419bafSAndrew Jeffery else: 535769419bafSAndrew Jeffery print("You must specify a password") 535869419bafSAndrew Jeffery sys.exit() 535969419bafSAndrew Jeffery logintimeStart = int(round(time.time()*1000)) 536069419bafSAndrew Jeffery mysess = login(args.host, args.user, pw, args.json, 536169419bafSAndrew Jeffery args.command == 'set_password') 536269419bafSAndrew Jeffery if(mysess == None): 536369419bafSAndrew Jeffery print("Login Failed!") 536469419bafSAndrew Jeffery sys.exit() 536569419bafSAndrew Jeffery if(sys.version_info < (3,0)): 536669419bafSAndrew Jeffery if isinstance(mysess, basestring): 536769419bafSAndrew Jeffery print(mysess) 536869419bafSAndrew Jeffery sys.exit(1) 536969419bafSAndrew Jeffery elif sys.version_info >= (3,0): 537069419bafSAndrew Jeffery if isinstance(mysess, str): 537169419bafSAndrew Jeffery print(mysess) 537269419bafSAndrew Jeffery sys.exit(1) 537369419bafSAndrew Jeffery logintimeStop = int(round(time.time()*1000)) 537469419bafSAndrew Jeffery isRedfishSupport = redfishSupportPresent(args.host,mysess) 537569419bafSAndrew Jeffery commandTimeStart = int(round(time.time()*1000)) 537669419bafSAndrew Jeffery output = args.func(args.host, args, mysess) 537769419bafSAndrew Jeffery commandTimeStop = int(round(time.time()*1000)) 537869419bafSAndrew Jeffery if isinstance(output, dict): 537969419bafSAndrew Jeffery print(json.dumps(output, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False)) 538069419bafSAndrew Jeffery else: 538169419bafSAndrew Jeffery print(output) 538269419bafSAndrew Jeffery if (mysess is not None): 538369419bafSAndrew Jeffery logout(args.host, args.user, pw, mysess, args.json) 538469419bafSAndrew Jeffery if(args.procTime): 538569419bafSAndrew Jeffery print("Total time: " + str(int(round(time.time()*1000))- totTimeStart)) 538669419bafSAndrew Jeffery print("loginTime: " + str(logintimeStop - logintimeStart)) 538769419bafSAndrew Jeffery print("command Time: " + str(commandTimeStop - commandTimeStart)) 538869419bafSAndrew Jeffery else: 538969419bafSAndrew Jeffery print("usage:\n" 539069419bafSAndrew Jeffery " OPENBMCTOOL_PASSWORD=secret # if using -E\n" 539169419bafSAndrew Jeffery " openbmctool.py [-h] -H HOST -U USER {-A | -P PW | -E} [-j]\n" + 539269419bafSAndrew Jeffery "\t[-t POLICYTABLELOC] [-V]\n" + 539369419bafSAndrew Jeffery "\t{fru,sensors,sel,chassis,collect_service_data, \ 539469419bafSAndrew Jeffery health_check,dump,bmc,mc,gardclear,firmware,logging}\n" + 539569419bafSAndrew Jeffery "\t...\n" + 539669419bafSAndrew Jeffery "openbmctool.py: error: the following arguments are required: -H/--host, -U/--user") 539769419bafSAndrew Jeffery sys.exit() 539869419bafSAndrew Jeffery 539969419bafSAndrew Jefferyif __name__ == '__main__': 540069419bafSAndrew Jeffery """ 540169419bafSAndrew Jeffery main function when called from the command line 540269419bafSAndrew Jeffery 540369419bafSAndrew Jeffery """ 540469419bafSAndrew Jeffery import sys 540569419bafSAndrew Jeffery 540669419bafSAndrew Jeffery isTTY = sys.stdout.isatty() 540769419bafSAndrew Jeffery assert sys.version_info >= (2,7) 540869419bafSAndrew Jeffery main() 5409