def __init__(self, ixnObj=None, fileMgmtObj=None): self.ixnObj = ixnObj self.ixNetwork = ixnObj.ixNetwork if fileMgmtObj: self.fileMgmtObj = fileMgmtObj else: self.fileMgmtObj = FileMgmt(ixnObj)
def getCapFile(self, port, typeOfCapture='data', saveToTempLocation='c:\\Temp', localLinuxLocation='.', appendToSavedCapturedFile=None): """ Get the latest captured .cap file from ReST API server to local Linux drive. Parameters port: Format:[IxiaIpAddress, slotNumber, cardNumber] Example: [ixChassisIp, '2', '1'] typeOfCapture: data|control saveToTempLocation: Where to temporary save the .cap file on the ReST API server: C:\\Temp The folder will be created if it doesn't exists. localLinuxLocation: Where to save the .cap file on the Linux machine. appendToSavedCapturedFile: Add a text string to the captured file. Example: captureObj.getCapFile([ixChassisIp, '2', '1'], 'control', 'c:\\Temp', '/home/hgee/test') """ if appendToSavedCapturedFile != None: data = { 'arg1': saveToTempLocation, 'arg2': appendToSavedCapturedFile } else: data = {'arg1': saveToTempLocation} self.ixnObj.post(self.ixnObj.sessionUrl + '/operations/savecapture', data=data) if typeOfCapture == 'control': capFileToGet = saveToTempLocation + '\\' + port[1] + '-' + port[ 2] + '_SW.cap' if typeOfCapture == 'data': capFileToGet = saveToTempLocation + '\\' + port[1] + '-' + port[ 2] + '_HW.cap' fileMgmtObj = FileMgmt(self.ixnObj) fileMgmtObj.copyFileWindowsToLocalLinux( windowsPathAndFileName=capFileToGet, localPath=localLinuxLocation, renameDestinationFile=None)
mainObj = Connect( apiServerIp=jsonData['linuxApiServerIp'], serverIpPort=jsonData['linuxServerIpPort'], username=jsonData['username'], password=jsonData['password'], deleteSessionAfterTest=jsonData['deleteSessionAfterTest'], verifySslCert=False, serverOs='linux') if osPlatform in ['windows', 'windowsConnectionMgr']: mainObj = Connect(apiServerIp=jsonData['windowsApiServerIp'], serverIpPort=jsonData['windowsServerIpPort'], serverOs=osPlatform) #---------- Preference Settings End -------------- fileMgmtObj = FileMgmt(mainObj) portObj = PortMgmt(mainObj) portObj.connectIxChassis(ixChassisIp) if portObj.arePortsAvailable(portList, raiseException=False) != 0: if forceTakePortOwnership == True: portObj.releasePorts(portList) portObj.clearPortOwnership(portList) else: raise IxNetRestApiException( '\nPorts are owned by another user and forceTakePortOwnership is set to False. Exiting test.' ) # If the license is activated on the chassis's license server, this variable should be True. # Otherwise, if the license is in a remote server or remote chassis, this variable should be False.
portObj.releasePorts(portList) portObj.clearPortOwnership(portList) else: raise IxNetRestApiException( 'Ports are owned by another user and forceTakePortOwnership is set to False' ) # If the license is activated on the chassis's license server, this variable should be True. # Otherwise, if the license is in a remote server or remote chassis, this variable should be False. # Configuring license requires releasing all ports even for ports that is not used for this test. if licenseIsInChassis == False: portObj.releaseAllPorts() mainObj.configLicenseServerDetails([licenseServerIp], licenseModel, licenseTier) fileMgmtObj = FileMgmt(mainObj) fileMgmtObj.loadConfigFile(configFile) portObj.assignPorts(portList) portObj.verifyPortState() protocolObj = Protocol(mainObj) # MODIFY BGP CONFIG: # Step 1 of 2: Get the BGP host object. # Filter the BGP host by it's Topology Group name. # State all the BGP attributes to modify in a list. bgpAttributeMultivalue = protocolObj.getBgpObject( topologyName='Topo1', bgpAttributeList=['flap', 'uptimeInSec', 'downtimeInSec'])
httpsSecured=True) #---------- Preference Settings End -------------- portObj = PortMgmt(mainObj) portObj.connectIxChassis(ixChassisIp) if portObj.arePortsAvailable(portList, raiseException=False) != 0: if forceTakePortOwnership == True: portObj.releasePorts(portList) portObj.clearPortOwnership(portList) else: raise IxNetRestApiException( '\nPorts are owned by another user and forceTakePortOwnership is set to False. Exiting test.' ) fileMgmtObj = FileMgmt(mainObj) # localFile=True if config file is not located in the Windows c: drive. fileMgmtObj.loadConfigFile(configFile, localFile=True) portObj.releasePorts(portList) mainObj.configLicenseServerDetails([licenseServerIp], licenseModel, licenseTier) portObj = PortMgmt(mainObj) portObj.assignPorts(portList, forceTakePortOwnership) portObj.verifyPortState() protocolObj = Protocol(mainObj) # MODIFY BGP CONFIG: # Step 1 of 2: Get the BGP host object.
def getCapFile(self, port, typeOfCapture='data', saveToTempLocation='c:\\Temp', localLinuxLocation='.', appendToSavedCapturedFile=None): """ Get the latest captured .cap file from ReST API server to local Linux drive. Parameters port: Format:[IxiaIpAddress, slotNumber, cardNumber] Example: [ixChassisIp, '2', '1'] typeOfCapture: data|control saveToTempLocation: For Windows: Where to temporary save the .cap file on the ReST API server: Provide any path with double backslashes: C:\\Temp. The folder will be created if it doesn't exists. For Linux, value= 'linux'. localLinuxLocation: Where to save the .cap file on the local Linux machine. appendToSavedCapturedFile: Add a text string to the captured file. Example: captureObj.getCapFile([ixChassisIp, '2', '1'], 'control', 'c:\\Temp', '/home/hgee/test') Syntaxes: PATCH: /vport/2 DATA: {'rxMode': 'captureAndMeasure'} PATCH: /vport/2/capture DATA: {'softwareEnabled': False, 'hardwareEnabled': True} # Set traffic item to send continuous packets PATCH: /traffic/trafficItem/1/configElement/<id>/transmissionControl DATA: {'type': 'continuous'} POST: /traffic/trafficItem/operations/generate DATA: {"arg1": ["/api/v1/sessions/<id>/ixnetwork/traffic/trafficItem/1"]} POST: /traffic/operations/apply DATA: {"arg1": "/api/v1/sessions/<id>/ixnetwork/traffic"} POST: /traffic/operations/start DATA: {"arg1": "https://192.168.70.12/api/v1/sessions/<id>/ixnetwork/traffic"} Start continuous traffic POST: /ixnetwork/operations/startcapture POST: /ixnetwork/operations/stopcapture POST: /ixnetwork/operations/savecapturefiles DATA: {"arg1": "packetCaptureFolder"} <-- This could be any name. Just a temporary folder to store the captured file. Wait for the /operations/savecapturefiles/<id> to complete. May take up to a minute or more. For Windows API server: POST: /ixnetwork/operations/copyfile DATA: {"arg1": "c:\\Results\\port2_HW.cap", "arg2": "/api/v1/sessions/1/ixnetwork/files/port2_HW.cap"} GET: /ixnetwork/files?filename=port2_HW.cap For Linux API server: POST: /ixnetwork/operations/copyfile DATA: {"arg1": "captures/packetCaptureFolder/port2_HW.cap", "arg2": "/api/v1/sessions/<id>/ixnetwork/files/port2_HW.cap"} GET: /ixnetwork/files?filename=captures/packetCaptureFolder/port2_HW.cap """ # For Linux API server if '\\' not in saveToTempLocation: # For Linux API server, need to give a name for a temporary folder saveToTempLocation = 'packetCaptureFolder' # For Linux API server, must get the vport name and cannot modify the vport name. vport = self.portMgmtObj.getVports([port])[0] response = self.ixnObj.get(self.ixnObj.httpHeader + vport) vportName = response.json()['name'] vportName = vportName.replace('/', '_') vportName = vportName.replace(' ', '_') self.ixnObj.logInfo('vportName: {}'.format(vportName)) if appendToSavedCapturedFile != None: data = { 'arg1': saveToTempLocation, 'arg2': appendToSavedCapturedFile } else: data = {'arg1': saveToTempLocation} response = self.ixnObj.post(self.ixnObj.sessionUrl + '/operations/savecapturefiles', data=data) self.ixnObj.waitForComplete(response, self.ixnObj.httpHeader + response.json()['url'], timeout=300) capfilePathName = response.json()['result'][0] # example capfilePathName: 'c:\\Results\\1-7-2_HW.cap' if typeOfCapture == 'control': if '\\' not in saveToTempLocation: # For Linux capFileToGet = '/home/ixia_apps/web/platform/apps-resources/ixnetworkweb/configs/captures/{0}/{1}_SW.cap'.format( saveToTempLocation, vportName) else: # For Windows capFileToGet = capfilePathName if typeOfCapture == 'data': if '\\' not in saveToTempLocation: # For Linux capFileToGet = '/home/ixia_apps/web/platform/apps-resources/ixnetworkweb/configs/captures/{0}/{1}_HW.cap'.format( saveToTempLocation, vportName) else: capFileToGet = capfilePathName fileMgmtObj = FileMgmt(self.ixnObj) if self.ixnObj.serverOs in ['windows', 'windowsConnectionMgr']: fileMgmtObj.copyFileWindowsToLocalLinux( windowsPathAndFileName=capFileToGet, localPath=localLinuxLocation, renameDestinationFile=None) if self.ixnObj.serverOs == 'linux': # Parse out captures/packetCaptureFolder/<vportName>_HW.cap match = re.search('.*(captures.*)', capFileToGet) pathExtension = match.group(1) fileMgmtObj.copyFileLinuxToLocalLinux( linuxApiServerPathAndFileName=capFileToGet, localPath=localLinuxLocation, renameDestinationFile=None, linuxApiServerPathExtension=pathExtension)
class QuickTest(object): def __init__(self, ixnObj=None, fileMgmtObj=None): self.ixnObj = ixnObj self.ixNetwork = ixnObj.ixNetwork if fileMgmtObj: self.fileMgmtObj = fileMgmtObj else: self.fileMgmtObj = FileMgmt(ixnObj) def setMainObject(self, mainObject): self.ixnObj = mainObject self.fileMgmtObj.setMainObject(mainObject) def getAllQuickTestHandles(self): """ Description Get all the Quick Test object handles Returns: [ <ixnetwork_restpy.testplatform.sessions.ixnetwork.quicktest .openflowlayer2learningrate_3db88746f7f375303f2eda376386a9a8 .OpenFlowLayer2LearningRate object at 0x03AAE2B0>] """ quickTestObjects = [] for testId in self.ixNetwork.QuickTest.TestIds: qtType = testId.split("/")[-2] qtType = qtType[0].upper() + qtType[1:] qtObj = getattr(self.ixNetwork.QuickTest, qtType) quickTestObjects.append(qtObj.find()) return quickTestObjects def getAllQuickTestNames(self): """ Description Get all the Quick Test name. """ quickTestNameList = [] for eachQtHandle in self.getAllQuickTestHandles(): qtName = eachQtHandle.Name if qtName: quickTestNameList.append(qtName) return quickTestNameList def getQuickTestHandleByName(self, quickTestName): """ Description Get the Quick Test object handle by the name. Parameter quickTestName: The name of the Quick Test. """ for quickTestHandle in self.getAllQuickTestHandles(): if bool(re.match(quickTestName, quickTestHandle.Name, re.I)): return quickTestHandle else: raise Exception( "Unable to find quicktest with name {}".format(quickTestName)) def getQuickTestNameByHandle(self, quickTestHandle): """ Description : Get the Quick Test Name by quick test Handle Parameter : quickTestHandle = <ixnetwork_restpy.testplatform.sessions.ixnetwork.quicktest .rfc2544throughput_5a77c9a28f5fa2bb9ce9f4280eb5122f .Rfc2544throughput object at 0x03800D00> """ if quickTestHandle.Name: return quickTestHandle.Name else: raise Exception("Unable to find quicktest name for given handle") def getQuickTestDuration(self, quickTestHandle): """ Description : Get Quick Test Test Duration Time in Sec Parameter : quickTestHandle = <ixnetwork_restpy.testplatform.sessions.ixnetwork.quicktest .rfc2544throughput_5a77c9a28f5fa2bb9ce9f4280eb5122f .Rfc2544throughput object at 0x03800D00> """ return quickTestHandle.TestConfig.Duration def getQuickTestTotalFrameSizesToTest(self, quickTestHandle): """ Description : Get Quick Test Test Total Frame Sizes Parameter : quickTestHandle = <ixnetwork_restpy.testplatform.sessions.ixnetwork.quicktest .rfc2544throughput_5a77c9a28f5fa2bb9ce9f4280eb5122f .Rfc2544throughput object at 0x03800D00> """ return quickTestHandle.TestConfig.FramesizeList def applyQuickTest(self, qtHandle): """ Description Apply Quick Test configurations Parameter qtHandle: The Quick Test object handle """ try: qtHandle.Apply() except Exception as err: raise Exception( "Operation apply quicktest failed with error :\n {}".format( err)) def getQuickTestCurrentAction(self, quickTestHandle): """ Description : Returns current action like 'InitializingTest', 'ApplyFlowGroups', 'SetupStatisticsCollection', etc. Parameter : quickTestHandle = <ixnetwork_restpy.testplatform.sessions.ixnetwork.quicktest .rfc2544throughput_5a77c9a28f5fa2bb9ce9f4280eb5122f .Rfc2544throughput object at 0x03800D00> """ timer = 10 currentActions = None for counter in range(1, timer + 1): currentActions = quickTestHandle.Results.CurrentActions self.ixnObj.logInfo('\n\ngetQuickTestCurrentAction:\n') for eachCurrentAction in quickTestHandle.Results.CurrentActions: self.ixnObj.logInfo('\t{}'.format(eachCurrentAction['arg2'])) self.ixnObj.logInfo('\n') if counter < timer and currentActions == []: self.ixnObj.logInfo( '\n getQuickTestCurrentAction is empty. Waiting %s/%s \n' % (counter, timer)) time.sleep(1) continue if counter < timer and currentActions != []: break if counter == timer and currentActions == []: raise Exception( '\n\ngetQuickTestCurrentActions: Has no action') return currentActions[-1]['arg2'] def verifyQuickTestInitialization(self, quickTestHandle): """ Parameter : quickTestHandle = <ixnetwork_restpy.testplatform.sessions.ixnetwork.quicktest .rfc2544throughput_5a77c9a28f5fa2bb9ce9f4280eb5122f .Rfc2544throughput object at 0x03800D00> """ for timer in range(1, 20 + 1): currentAction = self.getQuickTestCurrentAction(quickTestHandle) self.ixnObj.logInfo( 'verifyQuickTestInitialization currentState: %s' % currentAction) if timer < 20: if currentAction == 'TestEnded' or currentAction == 'None': self.ixnObj.logInfo( '\nverifyQuickTestInitialization CurrentState = %s\n\tWaiting %s/20 ' 'seconds to change state' % (currentAction, timer)) time.sleep(1) continue else: break if timer >= 20: if currentAction == 'TestEnded' or currentAction == 'None': raise IxNetRestApiException( 'Quick Test is stuck at TestEnded.') applyQuickTestCounter = 60 for counter in range(1, applyQuickTestCounter + 1): currentAction = self.getQuickTestCurrentAction(quickTestHandle) if currentAction is None: currentAction = 'ApplyingAndInitializing' self.ixnObj.logInfo( '\n verifyQuickTestInitialization: %s Expecting: TransmittingFrames\n\tWaiting' ' %s/%s seconds' % (currentAction, counter, applyQuickTestCounter)) if counter < applyQuickTestCounter and currentAction != 'TransmittingFrames': time.sleep(1) continue if counter < applyQuickTestCounter and currentAction == 'TransmittingFrames': self.ixnObj.logInfo( '\n VerifyQuickTestInitialization is done applying configuration and' ' has started transmitting frames\n') break if counter == applyQuickTestCounter: if currentAction == 'ApplyFlowGroups': self.ixnObj.logInfo( '\nIxNetwork is stuck on Applying Flow Groups. You need to go to the ' 'session to FORCE QUIT it.\n') raise IxNetRestApiException( '\nVerifyQuickTestInitialization is stuck on %s. Waited %s/%s seconds' % (currentAction, counter, applyQuickTestCounter)) def startQuickTest(self, quickTestHandle): """ Description Start a Quick Test Parameter quickTestHandle: The Quick Test object handle. """ try: quickTestHandle.Apply() quickTestHandle.Start() except Exception as err: self.ixnObj.logInfo("Error : \n {}".format(err)) raise Exception("Failed Starting QuickTest for {}".format( quickTestHandle.Name)) def stopQuickTest(self, quickTestHandle): """ Description Stop the Quick Test. Parameter quickTestHandle: The Quick Test object handle. """ try: quickTestHandle.Stop() except Exception as err: self.ixnObj.logInfo("Error in stop quicktest : \n {}".format(err)) raise Exception("Failed Stopping QuickTest for {}".format( quickTestHandle.Name)) def monitorQuickTestRunningProgress(self, quickTestHandle, getProgressInterval=10): """ Description monitor the Quick Test running progress. For Linux API server only, it must be a NGPF configuration. Parameters quickTestHandle: quick test handle """ isRunningBreakFlag = 0 trafficStartedFlag = 0 waitForRunningProgressCounter = 0 counter = 1 while True: isRunning = quickTestHandle.Results.IsRunning if isRunning: currentRunningProgress = quickTestHandle.Results.Progress self.ixnObj.logInfo(currentRunningProgress) if not bool(re.match('^Trial.*', currentRunningProgress)): if waitForRunningProgressCounter < 30: self.ixnObj.logInfo( 'isRunning=True. Waiting for trial runs {0}/30 ' 'seconds'.format(waitForRunningProgressCounter)) waitForRunningProgressCounter += 1 time.sleep(1) if waitForRunningProgressCounter == 30: raise IxNetRestApiException( 'isRunning=True. No quick test stats showing.') else: trafficStartedFlag = 1 self.ixnObj.logInfo(currentRunningProgress) counter += 1 time.sleep(getProgressInterval) continue else: if trafficStartedFlag == 1: # We only care about traffic not running in the beginning. # If traffic ran and stopped, then break out. self.ixnObj.logInfo( '\nisRunning=False. Quick Test is complete') return 0 if isRunningBreakFlag < 20: self.ixnObj.logInfo( 'isRunning=False. Wait {0}/20 seconds'.format( isRunningBreakFlag)) isRunningBreakFlag += 1 time.sleep(1) continue if isRunningBreakFlag == 20: raise IxNetRestApiException('Quick Test failed to start:') def getQuickTestResultPath(self, quickTestHandle): """ quickTestHandle = The quick test handle """ resultsPath = quickTestHandle.Results.ResultPath if not resultsPath: raise Exception("no result path found for quicktest {}".format( quickTestHandle.Name)) return resultsPath def getQuickTestResult(self, quickTestHandle, attribute): """ Description Get Quick Test result attributes Parameter quickTestHandle: The Quick Test object handle attribute options to get: result - Returns pass status - Returns none progress - blank or Trial 1/1 Iteration 1, Size 64, Rate 10 % Wait for 2 seconds Wait 70.5169449%complete startTime - Returns 04/21/17 14:35:42 currentActions waitingStatus resultPath isRunning - Returns True or False trafficStatus duration - Returns 00:01:03 currentViews """ attribute = attribute[0].upper() + attribute[1:] result = getattr(quickTestHandle.Results, attribute) return result def getQuickTestCsvFiles(self, quickTestHandle, copyToPath, csvFile='all'): """ Description Copy Quick Test CSV result files to a specified path on either Windows or Linux. Note: Currently only supports copying from Windows. Copy from Linux is coming in November. quickTestHandle: The Quick Test handle. copyToPath: The destination path to copy to. If copy to Windows: c:\\Results\\Path If copy to Linux: /home/user1/results/path csvFile: A list of CSV files to get: 'all', one or more CSV files to get: AggregateResults.csv, iteration.csv, results.csv, logFile.txt, portMap.csv """ resultsPath = quickTestHandle.Results.ResultPath self.ixnObj.logInfo('\ngetQuickTestCsvFiles: %s' % resultsPath) if csvFile == 'all': getCsvFiles = [ 'AggregateResults.csv', 'iteration.csv', 'results.csv', 'logFile.txt', 'portMap.csv' ] else: if type(csvFile) is not list: getCsvFiles = [csvFile] else: getCsvFiles = csvFile for eachCsvFile in getCsvFiles: # Backslash indicates the results resides on a Windows OS. if '\\' in resultsPath: windowsSource = resultsPath + '\\{0}'.format(eachCsvFile) if '\\' in copyToPath: self.fileMgmtObj.copyFileWindowsToLocalWindows( windowsSource, copyToPath) else: self.fileMgmtObj.copyFileWindowsToLocalLinux( windowsSource, copyToPath) else: linuxSource = resultsPath + '/{0}'.format(eachCsvFile) self.fileMgmtObj.copyFileLinuxToLocalLinux( linuxSource, copyToPath) def getQuickTestPdf(self, quickTestHandle, copyToLocalPath, where='remoteLinux', renameDestinationFile=None, includeTimestamp=False): """ Description Generate Quick Test result to PDF and retrieve the PDF result file. Parameter where: localWindows|remoteWindows|remoteLinux. The destination. copyToLocalPath: The local destination path to store the PDF result file. renameDestinationFile: Rename the PDF file. includeTimestamp: True|False. Set to True if you don't want to overwrite previous result file. """ try: reportFile = quickTestHandle.GenerateReport() except Exception as err: raise Exception( "Generate quicktest report file failed. Error : \n {}".format( err)) if where == 'localWindows': self.fileMgmtObj.copyFileWindowsToLocalWindows( reportFile, copyToLocalPath, renameDestinationFile, includeTimestamp) if where == 'remoteWindows': self.fileMgmtObj.copyFileWindowsToRemoteWindows( reportFile, copyToLocalPath, renameDestinationFile, includeTimestamp) if where == 'remoteLinux': self.fileMgmtObj.copyFileWindowsToLocalLinux( reportFile, copyToLocalPath, renameDestinationFile, includeTimestamp) def runQuickTest(self, quickTestName, timeout=90): """ Description Run the Quick test Parameter quickTestName: <str>: name of the quick test to run timeout: <int>: timeout duration handles internally in Restpy Example runQuickTest("Macro_17_57_14_294", timeout=180) Return Note: operation run will keep checking the status of execution for the specified timeout """ eventSchedulerHandle = self.getQuickTestHandleByName(quickTestName) try: eventSchedulerHandle.Run() except Exception as err: raise Exception( "Run quicktest operation failed with error : \n {}".format( err)) def deleteQuickTest(self, quickTestName): """ Description Delete the Quick test. Parameter quickTestName: <str>: name of the quick test to delete Example deleteQuickTest("Macro_17_57_14_294") Return """ eventSchedulerHandle = self.getQuickTestHandleByName(quickTestName) try: eventSchedulerHandle.remove() except Exception as err: raise Exception( "Delete quicktest by quicktest name failed with error : \n {}". format(err)) def configQuickTest(self, quickTestName, numOfTrials=1): """ Description Configure a quick test Parameter quickTestName: <str>: name of the quick test to configure numOfTrials: <int>: number of iterations to run the quick test, default is 1 Example configQuickTest("Macro_17_57_14_294") configQuickTest("Macro_17_57_14_294", numOfTrials=2) Return event scheduler handle on success or exception on failure """ try: eventSchedulerHandle = self.ixNetwork.QuickTest.EventScheduler.add( ) eventSchedulerHandle.Name = quickTestName eventSchedulerHandle.Mode = "existingMode" eventSchedulerHandle.ForceApplyQTConfig = True eventSchedulerHandle.TestConfig.NumTrials = numOfTrials return eventSchedulerHandle except Exception as err: raise Exception( "Unable to configure quick test. Error : \n {}".format(err))
def __init__(self, ixnObj=None): self.ixnObj = ixnObj # For takesnapshot() self.fileMgmtObj = FileMgmt(self.ixnObj)
def __init__(self, ixnObj=None): self.ixnObj = ixnObj # For takesnapshot() from IxNetRestApiFileMgmt import FileMgmt self.fileMgmtObj = FileMgmt(self.ixnObj)
if portObj.arePortsAvailable(portList, raiseException=False) != 0: if forceTakePortOwnership == True: portObj.releasePorts(portList) portObj.clearPortOwnership(portList) else: raise IxNetRestApiException( '\nPorts are owned by another user and forceTakePortOwnership is set to False. Exiting test.' ) # Optional: Uncomment if required. # Configuring license requires releasing all ports even for ports that is not used for this test. portObj.releaseAllPorts() mainObj.configLicenseServerDetails([licenseServerIp], licenseModel, licenseTier) fileMgmtObj = FileMgmt(mainObj) jsonData = fileMgmtObj.jsonReadConfig(jsonConfigFile) # 8.40: Takes 5 minutes to load/assignPorts on OVA/VE Linux. fileMgmtObj.importJsonConfigFile(jsonConfigFile, type='newConfig') fileMgmtObj.jsonAssignPorts(jsonData, portList, timeout=300) portObj.verifyPortState() # Example: How to modify # Mofify the BGP configuration using JSON XPATH. XPATH are obtained from a JSON exported config file. # 1> Export the JSON configuration to a file. # 2> Get the XPATH to where you want to modify the configuraiton. # 3> Import the modified JSON to IxNetwork xpathObj = [{ "xpath": "/multivalue[@source = '/topology[1]/deviceGroup[1]/ethernet[1]/ipv4[1]/bgpIpv4Peer[1] flap']/singleValue",
class Statistics(object): def __init__(self, ixnObj=None): self.ixnObj = ixnObj # For takesnapshot() self.fileMgmtObj = FileMgmt(self.ixnObj) def setMainObject(self, mainObject): """ Description For Python Robot Framework support. """ self.ixnObj = mainObject def getStats(self, viewObject=None, viewName='Flow Statistics', csvFile=None, csvEnableFileTimestamp=False, displayStats=True, silentMode=True, ignoreError=False): """ Description Get stats for any viewName. The method calls two different methods based on the IxNetwork version that you are using. For IxNetwork version prior to 8.50, calls getStatsPage. For IxNetwork version >= 8.50, calls getStatsData. This has new APIs that is more robust and they don't work in versions prior to 8.50. Parameters csvFile = None or <filename.csv>. None will not create a CSV file. Provide a <filename>.csv to record all stats to a CSV file. Example: getStats(sessionUrl, csvFile='Flow_Statistics.csv') csvEnableFileTimestamp = True or False. If True, timestamp will be appended to the filename. displayStats: True or False. True=Display stats. ignoreError: True or False. Returns None if viewName is not found. viewObject: The view object: http://{apiServerIp:port}/api/v1/sessions/2/ixnetwork/statistics/view/13 A view object handle could be obtained by calling getViewObject(). viewName options (Not case sensitive): NOTE: Not all statistics are listed here. You could get the statistic viewName directly from the IxNetwork GUI in the statistics. """ buildNumber = float(self.ixnObj.getIxNetworkVersion()[:3]) if buildNumber >= 8.5: return self.getStatsData(viewObject=viewObject, viewName=viewName, csvFile=csvFile, csvEnableFileTimestamp=csvEnableFileTimestamp, displayStats=displayStats, silentMode=silentMode, ignoreError=ignoreError) else: return self.getStatsPage(viewObject=viewObject, viewName=viewName, csvFile=csvFile, csvEnableFileTimestamp=csvEnableFileTimestamp, displayStats=displayStats, silentMode=silentMode, ignoreError=ignoreError) def getStatsPage(self, viewObject=None, viewName='Flow Statistics', csvFile=None, csvEnableFileTimestamp=False, displayStats=True, silentMode=True, ignoreError=False): """ Description Get stats by the statistic name or get stats by providing a view object handle. This method uses deprecated APIs effective IxNetwork version 8.50: /statistics/statView/<id>/page Starting 8.50, the new API to use is: /statistics/statView/<id>/data, which is in getStatsData() Parameters csvFile = None or <filename.csv>. None will not create a CSV file. Provide a <filename>.csv to record all stats to a CSV file. Example: getStats(sessionUrl, csvFile='Flow_Statistics.csv') csvEnableFileTimestamp = True or False. If True, timestamp will be appended to the filename. displayStats: True or False. True=Display stats. ignoreError: True or False. Returns None if viewName is not found. viewObject: The view object: http://{apiServerIp:port}/api/v1/sessions/2/ixnetwork/statistics/view/13 A view object handle could be obtained by calling getViewObject(). viewName options (Not case sensitive): NOTE: Not all statistics are listed here. You could get the statistic viewName directly from the IxNetwork GUI in the statistics. 'Port Statistics' 'Tx-Rx Frame Rate Statistics' 'Port CPU Statistics' 'Global Protocol Statistics' 'Protocols Summary' 'Port Summary' 'BGP Peer Per Port' 'OSPFv2-RTR Drill Down' 'OSPFv2-RTR Per Port' 'IPv4 Drill Down' 'L2-L3 Test Summary Statistics' 'Flow Statistics' 'Traffic Item Statistics' 'IGMP Host Drill Down' 'IGMP Host Per Port' 'IPv6 Drill Down' 'MLD Host Drill Down' 'MLD Host Per Port' 'PIMv6 IF Drill Down' 'PIMv6 IF Per Port' 'Flow View' Note: Not all of the viewNames are listed here. You have to get the exact names from the IxNetwork GUI in statistics based on your protocol(s). Return a dictionary of all the stats: statDict[rowNumber][columnName] == statValue Get stats on row 2 for 'Tx Frames' = statDict[2]['Tx Frames'] """ if viewObject == None: breakFlag = 0 counterStop = 30 for counter in range(1, counterStop+1): viewList = self.ixnObj.get('%s/%s/%s' % (self.ixnObj.sessionUrl, 'statistics', 'view'), silentMode=silentMode) views = ['%s/%s/%s/%s' % (self.ixnObj.sessionUrl, 'statistics', 'view', str(i['id'])) for i in viewList.json()] if silentMode is False: self.ixnObj.logInfo('\ngetStats: Searching for viewObj for viewName: %s' % viewName) for view in views: # GetAttribute response = self.ixnObj.get('%s' % view, silentMode=silentMode) captionMatch = re.match(viewName, response.json()['caption'], re.I) if captionMatch: # viewObj: sessionUrl + /statistics/view/11' viewObject = view breakFlag = 1 break if breakFlag == 1: break if counter < counterStop: self.ixnObj.logInfo('\nGetting statview [{0}] is not ready. Waiting {1}/{2} seconds.'.format( viewName, counter, counterStop), timestamp=False) time.sleep(1) continue if counter == counterStop: if viewObject == None and ignoreError == False: raise IxNetRestApiException("viewObj wasn't found for viewName: {0}".format(viewName)) if viewObject == None and ignoreError == True: return None if silentMode is False: self.ixnObj.logInfo('\n[{0}] viewObj is: {1}'.format(viewName, viewObject)) for counter in range(0,31): response = self.ixnObj.get(viewObject+'/page', silentMode=silentMode) totalPages = response.json()['totalPages'] if totalPages == 'null': self.ixnObj.logInfo('\nGetting total pages is not ready yet. Waiting %d/30 seconds' % counter) time.sleep(1) if totalPages != 'null': break if counter == 30: raise IxNetRestApiException('getStatsPage failed: Getting total pages') if csvFile != None: import csv csvFileName = csvFile.replace(' ', '_') if csvEnableFileTimestamp: import datetime timestamp = datetime.datetime.now().strftime('%H%M%S') if '.' in csvFileName: csvFileNameTemp = csvFileName.split('.')[0] csvFileNameExtension = csvFileName.split('.')[1] csvFileName = csvFileNameTemp+'_'+timestamp+'.'+csvFileNameExtension else: csvFileName = csvFileName+'_'+timestamp csvFile = open(csvFileName, 'w') csvWriteObj = csv.writer(csvFile) # Get the stat column names columnList = response.json()['columnCaptions'] if csvFile != None: csvWriteObj.writerow(columnList) flowNumber = 1 statDict = {} # Get the stat values for pageNumber in range(1,totalPages+1): self.ixnObj.patch(viewObject+'/page', data={'currentPage': pageNumber}, silentMode=silentMode) response = self.ixnObj.get(viewObject+'/page', silentMode=silentMode) statValueList = response.json()['pageValues'] for statValue in statValueList: if csvFile != None: csvWriteObj.writerow(statValue[0]) if displayStats: self.ixnObj.logInfo('\nRow: %d' % flowNumber, timestamp=False) statDict[flowNumber] = {} index = 0 for statValue in statValue[0]: statName = columnList[index] statDict[flowNumber].update({statName: statValue}) if displayStats: self.ixnObj.logInfo('\t%s: %s' % (statName, statValue), timestamp=False) index += 1 flowNumber += 1 if csvFile != None: csvFile.close() return statDict def getStatsData(self, viewObject=None, viewName='Flow Statistics', csvFile=None, csvEnableFileTimestamp=False, displayStats=True, silentMode=False, ignoreError=False): """ Description For IxNetwork version >= 8.50. Get stats by the statistic name or get stats by providing a view object handle. This method get stats using /api/v1/sessions/{id}/ixnetwork/statistics/view/{id}/data to get attributes columnCaptions, pageValues and totalPages. This method uses new API starting in version 8.50. Parameters csvFile = None or <filename.csv>. None will not create a CSV file. Provide a <filename>.csv to record all stats to a CSV file. Example: getStats(sessionUrl, csvFile='Flow_Statistics.csv') csvEnableFileTimestamp = True or False. If True, timestamp will be appended to the filename. displayStats: True or False. True=Display stats. ignoreError: True or False. Returns None if viewName is not found. viewObject: The view object: http://{apiServerIp:port}/api/v1/sessions/2/ixnetwork/statistics/view/13 A view object handle could be obtained by calling getViewObject(). viewName options (Not case sensitive): NOTE: Not all statistics are listed here. You could get the statistic viewName directly from the IxNetwork GUI in the statistics. 'Port Statistics' 'Tx-Rx Frame Rate Statistics' 'Port CPU Statistics' 'Global Protocol Statistics' 'Protocols Summary' 'Port Summary' 'BGP Peer Per Port' 'OSPFv2-RTR Drill Down' 'OSPFv2-RTR Per Port' 'IPv4 Drill Down' 'L2-L3 Test Summary Statistics' 'Flow Statistics' 'Traffic Item Statistics' 'IGMP Host Drill Down' 'IGMP Host Per Port' 'IPv6 Drill Down' 'MLD Host Drill Down' 'MLD Host Per Port' 'PIMv6 IF Drill Down' 'PIMv6 IF Per Port' 'Flow View' Note: Not all of the viewNames are listed here. You have to get the exact names from the IxNetwork GUI in statistics based on your protocol(s). Return a dictionary of all the stats: statDict[rowNumber][columnName] == statValue Get stats on row 2 for 'Tx Frames' = statDict[2]['Tx Frames'] """ if viewObject == None: breakFlag = 0 counterStop = 30 for counter in range(1, counterStop+1): viewList = self.ixnObj.get('%s/%s/%s' % (self.ixnObj.sessionUrl, 'statistics', 'view'), silentMode=silentMode) views = ['%s/%s/%s/%s' % (self.ixnObj.sessionUrl, 'statistics', 'view', str(i['id'])) for i in viewList.json()] if silentMode is False: self.ixnObj.logInfo('\ngetStats: Searching for viewObj for viewName: {0}'.format( viewName), timestamp=False) for view in views: #print('\nview:', view) response = self.ixnObj.get('%s' % view, silentMode=True) captionMatch = re.match(viewName, response.json()['caption'], re.I) if captionMatch: # viewObj: sessionUrl + /statistics/view/11' viewObject = view breakFlag = 1 break if breakFlag == 1: break if counter < counterStop: self.ixnObj.logInfo('\nGetting statview [{0}] is not ready. Waiting {1}/{2} seconds.'.format( viewName, counter, counterStop), timestamp=False) time.sleep(1) continue if counter == counterStop: if viewObject == None and ignoreError == False: raise IxNetRestApiException("viewObj wasn't found for viewName: {0}".format(viewName)) if viewObject == None and ignoreError == True: return None if silentMode is False: self.ixnObj.logInfo('\n[{0}] viewObj is: {1}'.format(viewName, viewObject)) counterStop = 30 for counter in range(0, counterStop+1): response = self.ixnObj.get(viewObject+'/data', silentMode=silentMode) totalPages = response.json()['totalPages'] #self.ixnObj.logInfo('totalPages: {0}'.format(totalPages), timestamp=False) if totalPages == 'null' and counter < counterStop: self.ixnObj.logInfo('\nGetting total pages is not ready yet. Waiting {0}/{1} seconds'.format( counter, counterStop), timestamp=False) time.sleep(1) continue if totalPages != 'null' and counter < counterStop: break if counter == counterStop: raise IxNetRestApiException('getStats failed: Getting total pages') if csvFile != None: import csv csvFileName = csvFile.replace(' ', '_') if csvEnableFileTimestamp: import datetime timestamp = datetime.datetime.now().strftime('%H%M%S') if '.' in csvFileName: csvFileNameTemp = csvFileName.split('.')[0] csvFileNameExtension = csvFileName.split('.')[1] csvFileName = csvFileNameTemp+'_'+timestamp+'.'+csvFileNameExtension else: csvFileName = csvFileName+'_'+timestamp csvFile = open(csvFileName, 'w') csvWriteObj = csv.writer(csvFile) flowNumber = 1 statDict = {} getColumnCaptionFlag = 0 for pageNumber in range(1,totalPages+1): self.ixnObj.patch(viewObject+'/data', data={'currentPage': pageNumber}, silentMode=silentMode) counterStop = 30 for counter in range(1, counterStop+1): response = self.ixnObj.get(viewObject+'/data', silentMode=silentMode) if counter < counterStop: if response.json()['columnCaptions'] == [] or response.json()['pageValues'] == []: self.ixnObj.logInfo('[{0}] stat values not ready yet. Wait {1}/{2} seconds.'.format( viewName, counter, counterStop)) time.sleep(1) continue if response.json()['columnCaptions'] != [] or response.json()['pageValues'] != []: break if counter == counterStop: raise IxNetRestApiException('IxNetwork API server failed to provide stats') # Get the stat column names one time only if getColumnCaptionFlag == 0: getColumnCaptionFlag = 1 columnList = response.json()['columnCaptions'] if csvFile != None: csvWriteObj.writerow(columnList) statValueList = response.json()['pageValues'] for statValue in statValueList: if csvFile != None: csvWriteObj.writerow(statValue[0]) if displayStats: self.ixnObj.logInfo('\nRow: %d' % flowNumber, timestamp=False) statDict[flowNumber] = {} index = 0 for statValue in statValue[0]: statName = columnList[index] statDict[flowNumber].update({statName: statValue}) if displayStats: self.ixnObj.logInfo('\t%s: %s' % (statName, statValue), timestamp=False) index += 1 flowNumber += 1 if csvFile != None: csvFile.close() return statDict def removeAllTclViews(self): """ Description Removes all created stat views. """ removeAllTclViewsUrl = self.ixnObj.sessionUrl+'/operations/removealltclviews' response = self.ixnObj.post(removeAllTclViewsUrl) self.ixnObj.waitForComplete(response, self.ixnObj.httpHeader + response.json()['url']) def takeSnapshot(self, viewName='Flow Statistics', windowsPath=None, isLinux=False, localLinuxPath=None, renameDestinationFile=None, includeTimestamp=False, mode='overwrite'): """ Description Take a snapshot of the vieweName statistics. This is a two step process. 1> Take a snapshot of the statistics that you want and store it in the C: drive for Windows. For Linux, the snapshot goes to /home/ixia_logs. 2> Copy the statistics from the snapshot locations to the local Linux where you ran the script.. Parameters viewName: The name of the statistics to get. windowsPath: For Windows|WindowsConnectionMgr only. The C: drive + path to store the snapshot: Example: c:\\Results. isLinux: <bool>: Defaults to False. Set to True if you're getting the snapshot from Linux chassis. localLinuxPath: None|path. Provide the local Linux path to put the snapshot file. If None, this API won't copy the stat file to local Linux. The stat file will remain on Windows c: drive. renameDestinationFile: None or a name of the file other than the viewName. includeTimestamp: True|False: To include a timestamp at the end of the file. mode: append|overwrite: append=To append stats to an existing stat file. overwrite=Don't append stats. Create a new stat file. Example: For Windows: statObj.takeSnapshot(viewName='Flow Statistics', windowsPath='C:\\Results', localLinuxPath='/home/hgee', renameDestinationFile='my_renamed_stat_file.csv', includeTimestamp=True) For Linux: statObj.takeSnapshot(viewName='Flow Statistics', isLinux=True, localLinuxPath='/home/hgee') """ if mode == 'append': mode = 'kAppendCSVFile' if mode == 'overwrite': mode = 'kOverwriteCSVFile' if windowsPath: location = windowsPath if isLinux: location = '/home/ixia_logs' data = {'arg1': [viewName], 'arg2': [ "Snapshot.View.Contents: \"allPages\"", "Snapshot.View.Csv.Location: \"{0}\"".format(location), "Snapshot.View.Csv.GeneratingMode: \"%s\"" % mode, "Snapshot.View.Csv.StringQuotes: \"True\"", "Snapshot.View.Csv.SupportsCSVSorting: \"False\"", "Snapshot.View.Csv.FormatTimestamp: \"True\"", "Snapshot.View.Csv.DumpTxPortLabelMap: \"False\"", "Snapshot.View.Csv.DecimalPrecision: \"3\"" ] } url = self.ixnObj.sessionUrl+'/operations/takeviewcsvsnapshot' response = self.ixnObj.post(url, data=data) self.ixnObj.waitForComplete(response, self.ixnObj.httpHeader + response.json()['url']) if isLinux: snapshotFile = location + '/' + viewName + '.csv' self.fileMgmtObj.copyFileLinuxToLocalLinux(linuxApiServerPathAndFileName=snapshotFile, localPath=localLinuxPath, renameDestinationFile=renameDestinationFile, includeTimestamp=includeTimestamp) if windowsPath and localLinuxPath: # Get the snapshot. Use the csvFilename that was specified and the location self.fileMgmtObj.copyFileWindowsToLocalLinux('{0}\\{1}.csv'.format(windowsPath, viewName), localLinuxPath, renameDestinationFile=renameDestinationFile, includeTimestamp=includeTimestamp) def getViewObject(self, viewName='Flow Statistics'): """ Description To get just the statistic view object. Mainly used by internal APIs such as takeCsvSnapshot that requires the statistics view object handle. Parameter viewName: Options (case sensitive): "Port Statistics" "Tx-Rx Frame Rate Statistics" "Port CPU Statistics" "Global Protocol Statistics" "Protocols Summary" "Port Summary" "OSPFv2-RTR Drill Down" "OSPFv2-RTR Per Port" "IPv4 Drill Down" "L2-L3 Test Summary Statistics" "Flow Statistics" "Traffic Item Statistics" """ self.ixnObj.logInfo('\ngetStats: %s' % viewName) viewList = self.ixnObj.get("%s/%s/%s" % (self.ixnObj.sessionUrl, "statistics", "view")) views = ["%s/%s/%s/%s" % (self.ixnObj.sessionUrl, "statistics", "view", str(i["id"])) for i in viewList.json()] for view in views: # GetAttribute response = self.ixnObj.get(view) caption = response.json()["caption"] if viewName == caption: # viewObj: sessionUrl + "/statistics/view/11" viewObj = view return viewObj return None def clearStats(self): """ Description Clear all stats and wait for API server to finish. """ url = self.ixnObj.sessionUrl + '/operations/clearstats' response = self.ixnObj.post(url, data={'arg1': ['waitForPortStatsRefresh']}) self.ixnObj.waitForComplete(response, self.ixnObj.httpHeader + response.json()['url'])
def __init__(self, ixnObj=None, fileMgmtObj=None): self.ixnObj = ixnObj if fileMgmtObj: self.fileMgmtObj = fileMgmtObj else: self.fileMgmtObj = FileMgmt(ixnObj)
class QuickTest(object): def __init__(self, ixnObj=None, fileMgmtObj=None): self.ixnObj = ixnObj if fileMgmtObj: self.fileMgmtObj = fileMgmtObj else: self.fileMgmtObj = FileMgmt(ixnObj) def setMainObject(self, mainObject): # For Python Robot Framework support self.ixnObj = mainObject self.fileMgmtObj.setMainObject(mainObject) def getAllQuickTestHandles(self): """ Description Get all the Quick Test object handles Returns: ['/api/v1/sessions/1/ixnetwork/quickTest/rfc2544throughput/2', '/api/v1/sessions/1/ixnetwork/quickTest/rfc2889broadcastRate/1', '/api/v1/sessions/1/ixnetwork/quickTest/rfc2889broadcastRate/2'] """ response = self.ixnObj.get(self.ixnObj.sessionUrl + '/quickTest') quickTestHandles = [] for eachTestId in response.json()['testIds']: quickTestHandles.append(eachTestId) return quickTestHandles def getAllQuickTestNames(self): quickTestNameList = [] for eachQtHandle in self.getAllQuickTestHandles(): response = self.ixnObj.get(self.ixnObj.httpHeader + eachQtHandle) quickTestNameList.append(response.json()['name']) return quickTestNameList def getQuickTestHandleByName(self, quickTestName): """ Description Get the Quick Test object handle by the name. Parameter quickTestName: The name of the Quick Test. """ for quickTestHandle in self.getAllQuickTestHandles(): response = self.ixnObj.get(self.ixnObj.httpHeader + quickTestHandle) currentQtName = response.json()['name'] if (bool(re.match(quickTestName, currentQtName, re.I))): return quickTestHandle def getQuickTestNameByHandle(self, quickTestHandle): """ quickTestHandle = /api/v1/sessions/1/ixnetwork/quickTest/rfc2544throughput/2 """ response = self.ixnObj.get(self.ixnObj.httpHeader + quickTestHandle) return response.json()['name'] def getQuickTestDuration(self, quickTestHandle): """ quickTestHandle = /api/v1/sessions/1/ixnetwork/quickTest/rfc2544throughput/2 """ response = self.ixnObj.get(self.ixnObj.httpHeader + quickTestHandle + '/testConfig') return response.json()['duration'] def getQuickTestTotalFrameSizesToTest(self, quickTestHandle): """ quickTestHandle = /api/v1/sessions/1/ixnetwork/quickTest/rfc2544throughput/2 """ response = self.ixnObj.get(self.ixnObj.httpHeader + quickTestHandle + '/testConfig') return response.json()['framesizeList'] def applyQuickTest(self, qtHandle): """ Description Apply Quick Test configurations Parameter qtHandle: The Quick Test object handle """ response = self.ixnObj.post(self.ixnObj.sessionUrl + '/quickTest/operations/apply', data={'arg1': qtHandle}) if self.ixnObj.waitForComplete( response, self.ixnObj.sessionUrl + '/quickTest/operations/apply/' + response.json()['id']) == 1: raise IxNetRestApiException('applyTraffic: waitForComplete failed') def getQuickTestCurrentAction(self, quickTestHandle): """ quickTestHandle = /api/v1/sessions/1/ixnetwork/quickTest/rfc2544throughput/2 """ ixNetworkVersion = self.ixnObj.getIxNetworkVersion() match = re.match('([0-9]+)\.[^ ]+ *', ixNetworkVersion) if int(match.group(1)) >= 8: timer = 10 for counter in range(1, timer + 1): response = self.ixnObj.get(self.ixnObj.httpHeader + quickTestHandle + '/results', silentMode=True) if counter < timer and response.json()['currentActions'] == []: self.ixnObj.logInfo( 'getQuickTestCurrentAction is empty. Waiting %s/%s' % (counter, timer)) time.sleep(1) continue if counter < timer and response.json()['currentActions'] != []: break if counter == timer and response.json( )['currentActions'] == []: IxNetRestApiException( 'getQuickTestCurrentActions: Has no action') return response.json()['currentActions'][-1]['arg2'] else: response = self.ixnObj.get(self.ixnObj.httpHeader + quickTestHandle + '/results') return response.json()['progress'] def verifyQuickTestInitialization(self, quickTestHandle): """ quickTestHandle = /api/v1/sessions/1/ixnetwork/quickTest/rfc2544throughput/2 """ for timer in range(1, 20 + 1): currentAction = self.getQuickTestCurrentAction(quickTestHandle) print('verifyQuickTestInitialization currentState: %s' % currentAction) if timer < 20: if currentAction == 'TestEnded' or currentAction == 'None': self.ixnObj.logInfo( '\nverifyQuickTestInitialization CurrentState = %s\n\tWaiting %s/20 seconds to change state' % (currentAction, timer)) time.sleep(1) continue else: break if timer >= 20: if currentAction == 'TestEnded' or currentAction == 'None': self.ixnObj.showErrorMessage() raise IxNetRestApiException( 'Quick Test is stuck at TestEnded.') ixNetworkVersionNumber = int( self.ixnObj.getIxNetworkVersion().split('.')[0]) applyQuickTestCounter = 60 for counter in range(1, applyQuickTestCounter + 1): quickTestApplyStates = [ 'InitializingTest', 'ApplyFlowGroups', 'SetupStatisticsCollection' ] currentAction = self.getQuickTestCurrentAction(quickTestHandle) if currentAction == None: currentAction = 'ApplyingAndInitializing' print( '\nverifyQuickTestInitialization: %s Expecting: TransmittingFrames\n\tWaiting %s/%s seconds' % (currentAction, counter, applyQuickTestCounter)) if ixNetworkVersionNumber >= 8: if counter < applyQuickTestCounter and currentAction != 'TransmittingFrames': time.sleep(1) continue if counter < applyQuickTestCounter and currentAction == 'TransmittingFrames': self.ixnObj.logInfo( '\nVerifyQuickTestInitialization is done applying configuration and has started transmitting frames\n' ) break if ixNetworkVersionNumber < 8: if counter < applyQuickTestCounter and currentAction == 'ApplyingAndInitializing': time.sleep(1) continue if counter < applyQuickTestCounter and currentAction == 'ApplyingAndInitializing': self.ixnObj.logInfo( '\nVerifyQuickTestInitialization is done applying configuration and has started transmitting frames\n' ) break if counter == applyQuickTestCounter: if ixNetworkVersionNumber >= 8 and currentAction != 'TransmittingFrames': self.ixnObj.showErrorMessage() if currentAction == 'ApplyFlowGroups': self.ixnObj.logInfo( '\nIxNetwork is stuck on Applying Flow Groups. You need to go to the session to FORCE QUIT it.\n' ) raise IxNetRestApiException( '\nVerifyQuickTestInitialization is stuck on %s. Waited %s/%s seconds' % (currentAction, counter, applyQuickTestCounter)) if ixNetworkVersionNumber < 8 and currentAction != 'Trial': self.ixnObj.showErrorMessage() raise IxNetRestApiException( '\nVerifyQuickTestInitialization is stuck on %s. Waited %s/%s seconds' % (currentAction, counter, applyQuickTestCounter)) def startQuickTest(self, quickTestHandle): """ Description Start a Quick Test Parameter quickTestHandle: The Quick Test object handle. /api/v1/sessions/{id}/ixnetwork/quickTest/rfc2544throughput/2 Syntax POST: http://{apiServerIp:port}/api/v1/sessions/{1}/ixnetwork/quickTest/operations/start data={arg1: '/api/v1/sessions/{id}/ixnetwork/quickTest/rfc2544throughput/2'} headers={'content-type': 'application/json'} """ url = self.ixnObj.sessionUrl + '/quickTest/operations/start' self.ixnObj.logInfo('\nstartQuickTest:%s' % url) response = self.ixnObj.post(url, data={'arg1': quickTestHandle}) if self.ixnObj.waitForComplete(response, url + '/' + response.json()['id']) == 1: raise IxNetRestApiException def stopQuickTest(self, quickTestHandle): """ Description Stop the Quick Test. Parameter quickTestHandle: The Quick Test object handle. /api/v1/sessions/{id}/ixnetwork/quickTest/rfc2544throughput/2 Syntax POST: http://{apiServerIp:port}/api/v1/sessions/{1}/ixnetwork/quickTest/operations/stop data={arg1: '/api/v1/sessions/{id}/ixnetwork/quickTest/rfc2544throughput/2'} headers={'content-type': 'application/json'} """ url = self.ixnObj.sessionUrl + '/quickTest/operations/stop' response = self.ixnObj.post(url, data={'arg1': quickTestHandle}) if self.ixnObj.waitForComplete(response, url + '/' + response.json()['id']) == 1: raise IxNetRestApiException def monitorQuickTestRunningProgress(self, quickTestHandle, getProgressInterval=10): """ Description monitor the Quick Test running progress. For Linux API server only, it must be a NGPF configuration. (Classic Framework is not supported in REST) Parameters quickTestHandle: /api/v1/sessions/{1}/ixnetwork/quickTest/rfc2544throughput/2 """ isRunningBreakFlag = 0 trafficStartedFlag = 0 waitForRunningProgressCounter = 0 counter = 1 while True: response = self.ixnObj.get(self.ixnObj.httpHeader + quickTestHandle + '/results', silentMode=True) isRunning = response.json()['isRunning'] if isRunning == True: response = self.ixnObj.get(self.ixnObj.httpHeader + quickTestHandle + '/results', silentMode=True) currentRunningProgress = response.json()['progress'] if bool(re.match('^Trial.*', currentRunningProgress)) == False: if waitForRunningProgressCounter < 30: self.ixnObj.logInfo( 'isRunning=True. Waiting for trial runs {0}/30 seconds' .format(waitForRunningProgressCounter)) waitForRunningProgressCounter += 1 time.sleep(1) if waitForRunningProgressCounter == 30: raise IxNetRestApiException( 'isRunning=True. No quick test stats showing.') else: trafficStartedFlag = 1 self.ixnObj.logInfo(currentRunningProgress) counter += 1 time.sleep(getProgressInterval) continue else: if trafficStartedFlag == 1: # We only care about traffic not running in the beginning. # If traffic ran and stopped, then break out. self.ixnObj.logInfo( '\nisRunning=False. Quick Test is complete') return 0 if isRunningBreakFlag < 20: print('isRunning=False. Wait {0}/20 seconds'.format( isRunningBreakFlag)) isRunningBreakFlag += 1 time.sleep(1) continue if isRunningBreakFlag == 20: raise IxNetRestApiException('Quick Test failed to start:', response.json()['status']) def getQuickTestResultPath(self, quickTestHandle): """ quickTestHandle = /api/v1/sessions/1/ixnetwork/quickTest/rfc2544throughput/2 """ response = self.ixnObj.get(self.ixnObj.httpHeader + quickTestHandle + '/results') # "resultPath": "C:\\Users\\hgee\\AppData\\Local\\Ixia\\IxNetwork\\data\\result\\DP.Rfc2544Tput\\10694b39-6a8a-4e70-b1cd-52ec756910c3\\Run0001" return response.json()['resultPath'] def getQuickTestResult(self, quickTestHandle, attribute): """ Description Get Quick Test result attributes Parameter quickTestHandle: The Quick Test object handle attribute options to get: result - Returns pass status - Returns none progress - blank or Trial 1/1 Iteration 1, Size 64, Rate 10 % Wait for 2 seconds Wait 70.5169449%complete startTime - Returns 04/21/17 14:35:42 currentActions waitingStatus resultPath isRunning - Returns True or False trafficStatus duration - Returns 00:01:03 currentViews """ response = self.ixnObj.get(quickTestHandle + '/results') return response.json()[attribute] def getQuickTestCsvFiles(self, quickTestHandle, copyToPath, csvFile='all'): """ Description Copy Quick Test CSV result files to a specified path on either Windows or Linux. Note: Currently only supports copying from Windows. Copy from Linux is coming in November. quickTestHandle: The Quick Test handle. copyToPath: The destination path to copy to. If copy to Windows: c:\\Results\\Path If copy to Linux: /home/user1/results/path csvFile: A list of CSV files to get: 'all', one or more CSV files to get: AggregateResults.csv, iteration.csv, results.csv, logFile.txt, portMap.csv """ resultsPath = self.getQuickTestResultPath(quickTestHandle) self.ixnObj.logInfo('\ngetQuickTestCsvFiles: %s' % resultsPath) if csvFile == 'all': getCsvFiles = [ 'AggregateResults.csv', 'iteration.csv', 'results.csv', 'logFile.txt', 'portMap.csv' ] else: if type(csvFile) is not list: getCsvFiles = [csvFile] else: getCsvFiles = csvFile for eachCsvFile in getCsvFiles: # Backslash indicates the results resides on a Windows OS. if '\\' in resultsPath: if bool(re.match('[a-z]:.*', copyToPath, re.I)): self.fileMgmtObj.copyFileWindowsToLocalWindows( resultsPath + '\\{0}'.format(eachCsvFile), copyToPath) else: self.fileMgmtObj.copyFileWindowsToLocalLinux( resultsPath + '\\{0}'.format(eachCsvFile), copyToPath) else: # TODO: Copy from Linux to Windows and Linux to Linux. pass def getQuickTestPdf(self, quickTestHandle, copyToLocalPath, where='remoteLinux', renameDestinationFile=None, includeTimestamp=False): """ Description Generate Quick Test result to PDF and retrieve the PDF result file. Parameter where: localWindows|remoteWindows|remoteLinux. The destination. copyToLocalPath: The local destination path to store the PDF result file. renameDestinationFile: Rename the PDF file. includeTimestamp: True|False. Set to True if you don't want to overwrite previous result file. """ response = self.ixnObj.post(self.ixnObj.httpHeader + quickTestHandle + '/operations/generateReport', data={'arg1': quickTestHandle}) if response.json()['url'] != '': if self.ixnObj.waitForComplete( response, self.ixnObj.httpHeader + response.json()['url']) == 1: raise IxNetRestApiException if where == 'localWindows': response = self.ixnObj.get(self.ixnObj.httpHeader + response.json()['url']) self.fileMgmtObj.copyFileWindowsToLocalWindows( response.json()['result'], copyToLocalPath, renameDestinationFile, includeTimestamp) if where == 'remoteWindows': # TODO: Work in progress. Not sure if this is possible. resultPath = self.getQuickTestResultPath(quickTestHandle) #self.ixnObj.copyFileWindowsToRemoteWindows(response.json()['result'], copyToLocalPath, renameDestinationFile, includeTimestamp) self.fileMgmtObj.copyFileWindowsToRemoteWindows( resultPath, copyToLocalPath, renameDestinationFile, includeTimestamp) if where == 'remoteLinux': linuxResultPath = self.getQuickTestResultPath(quickTestHandle) self.fileMgmtObj.copyFileWindowsToLocalLinux( linuxResultPath + '\\TestReport.pdf', copyToLocalPath, renameDestinationFile, includeTimestamp) else: self.ixnObj.logInfo('\ngetQuickTestPdf failed. Result path = %s' % response.json()['result'])
def __init__(self, ixnObj=None): self.ixnObj = ixnObj self.fileMgmtObj = FileMgmt(self.ixnObj) self.ixNetwork = ixnObj.ixNetwork
class Statistics(object): def __init__(self, ixnObj=None): self.ixnObj = ixnObj self.fileMgmtObj = FileMgmt(self.ixnObj) self.ixNetwork = ixnObj.ixNetwork def setMainObject(self, mainObject): """ Description For Python Robot Framework support. """ self.ixnObj = mainObject def getStats(self, viewObject=None, viewName='Flow Statistics', csvFile=None, csvEnableFileTimestamp=False, displayStats=True, silentMode=True, ignoreError=False): """ Description Get stats for any viewName. The method calls two different methods based on the IxNetwork version that you are using. For IxNetwork version prior to 8.50, calls getStatsPage. Parameters csvFile = None or <filename.csv>. None will not create a CSV file. Provide a <filename>.csv to record all stats to a CSV file. Example: getStats(sessionUrl, csvFile='Flow_Statistics.csv') csvEnableFileTimestamp = True or False. If True, timestamp will be appended to the filename. displayStats: True or False. True=Display stats. ignoreError: True or False. Returns None if viewName is not found. viewObject: The view object: A view object handle could be obtained by calling getViewObject(). viewName options (Not case sensitive): NOTE: Not all statistics are listed here. You could get the statistic viewName directly from the IxNetwork GUI in the statistics. """ return self.getStatsData(viewObject=viewObject, viewName=viewName, csvFile=csvFile, csvEnableFileTimestamp=csvEnableFileTimestamp, displayStats=displayStats, silentMode=silentMode, ignoreError=ignoreError) def getStatsPage(self, viewObject=None, viewName='Flow Statistics', csvFile=None, csvEnableFileTimestamp=False, displayStats=True, silentMode=True, ignoreError=False): """ Description Get stats by the statistic name or get stats by providing a view object handle. Parameters csvFile = None or <filename.csv>. None will not create a CSV file. Provide a <filename>.csv to record all stats to a CSV file. Example: getStats(sessionUrl, csvFile='Flow_Statistics.csv') csvEnableFileTimestamp = True or False. If True, timestamp will be appended to the filename. displayStats: True or False. True=Display stats. ignoreError: True or False. Returns None if viewName is not found. viewObject: The view object: A view object handle could be obtained by calling getViewObject(). viewName options (Not case sensitive): NOTE: Not all statistics are listed here. You could get the statistic viewName directly from the IxNetwork GUI in the statistics. 'Port Statistics' 'Tx-Rx Frame Rate Statistics' 'Port CPU Statistics' 'Global Protocol Statistics' 'Protocols Summary' 'Port Summary' 'BGP Peer Per Port' 'OSPFv2-RTR Drill Down' 'OSPFv2-RTR Per Port' 'IPv4 Drill Down' 'L2-L3 Test Summary Statistics' 'Flow Statistics' 'Traffic Item Statistics' 'IGMP Host Drill Down' 'IGMP Host Per Port' 'IPv6 Drill Down' 'MLD Host Drill Down' 'MLD Host Per Port' 'PIMv6 IF Drill Down' 'PIMv6 IF Per Port' 'Flow View' Note: Not all of the viewNames are listed here. You have to get the exact names from the IxNetwork GUI in statistics based on your protocol(s). Return a dictionary of all the stats: statDict[rowNumber][columnName] == statValue Get stats on row 2 for 'Tx Frames' = statDict[2]['Tx Frames'] """ rowStats = None try: TrafficItemStats = StatViewAssistant(self.ixNetwork, viewName) except Exception as err: self.ixnObj.logInfo("Error in getstats {}".format(err)) raise Exception('getStats: Failed to get stats values') trafficItemStatsDict = {} columnCaptions = TrafficItemStats.ColumnHeaders if csvFile is not None: csvFileName = csvFile.replace(' ', '_') if csvEnableFileTimestamp: timestamp = datetime.datetime.now().strftime('%H%M%S') if '.' in csvFileName: csvFileNameTemp = csvFileName.split('.')[0] csvFileNameExtension = csvFileName.split('.')[1] csvFileName = csvFileNameTemp + '_' + timestamp + '.' + csvFileNameExtension else: csvFileName = csvFileName + '_' + timestamp csvFile = open(csvFileName, 'w') csvWriteObj = csv.writer(csvFile) csvWriteObj.writerow(columnCaptions) for rowNumber, stat in enumerate(TrafficItemStats.Rows): rowStats = stat.RawData for row in rowStats: csvWriteObj.writerow(row) csvFile.close() for rowNumber, stat in enumerate(TrafficItemStats.Rows): if displayStats: self.ixnObj.logInfo('\n Row: {}'.format(rowNumber + 1), timestamp=False) statsDict = {} for column in columnCaptions: statsDict[column] = stat[column] if displayStats: self.ixnObj.logInfo('\t%s: %s' % (column, stat[column]), timestamp=False) trafficItemStatsDict[rowNumber + 1] = statsDict return trafficItemStatsDict def getStatsData(self, viewObject=None, viewName='Flow Statistics', csvFile=None, csvEnableFileTimestamp=False, displayStats=True, silentMode=False, ignoreError=False): """ Description Get stats by the statistic name or get stats by providing a view object handle. Parameters csvFile = None or <filename.csv>. None will not create a CSV file. Provide a <filename>.csv to record all stats to a CSV file. Example: getStats(sessionUrl, csvFile='Flow_Statistics.csv') csvEnableFileTimestamp = True or False. If True, timestamp will be appended to the filename. displayStats: True or False. True=Display stats. ignoreError: True or False. Returns None if viewName is not found. viewObject: The view object: A view object handle could be obtained by calling getViewObject(). viewName options (Not case sensitive): NOTE: Not all statistics are listed here. You could get the statistic viewName directly from the IxNetwork GUI in the statistics. 'Port Statistics' 'Tx-Rx Frame Rate Statistics' 'Port CPU Statistics' 'Global Protocol Statistics' 'Protocols Summary' 'Port Summary' 'BGP Peer Per Port' 'OSPFv2-RTR Drill Down' 'OSPFv2-RTR Per Port' 'IPv4 Drill Down' 'L2-L3 Test Summary Statistics' 'Flow Statistics' 'Traffic Item Statistics' 'IGMP Host Drill Down' 'IGMP Host Per Port' 'IPv6 Drill Down' 'MLD Host Drill Down' 'MLD Host Per Port' 'PIMv6 IF Drill Down' 'PIMv6 IF Per Port' 'Flow View' Note: Not all of the viewNames are listed here. You have to get the exact names from the IxNetwork GUI in statistics based on your protocol(s). Return a dictionary of all the stats: statDict[rowNumber][columnName] == statValue Get stats on row 2 for 'Tx Frames' = statDict[2]['Tx Frames'] #Ignore vieobject,silentMode in Restpy as it is taken care by StatViewAssistant internally viewObject = None silentMode = False """ rowStats = None try: TrafficItemStats = StatViewAssistant(self.ixNetwork, viewName) except Exception as err: self.ixnObj.logInfo("Error in getting stats {}".format(err)) raise Exception('getStats: Failed to get stats values') trafficItemStatsDict = {} columnCaptions = TrafficItemStats.ColumnHeaders if csvFile is not None: csvFileName = csvFile.replace(' ', '_') if csvEnableFileTimestamp: timestamp = datetime.datetime.now().strftime('%H%M%S') if '.' in csvFileName: csvFileNameTemp = csvFileName.split('.')[0] csvFileNameExtension = csvFileName.split('.')[1] csvFileName = csvFileNameTemp + '_' + timestamp + '.' + csvFileNameExtension else: csvFileName = csvFileName + '_' + timestamp csvFile = open(csvFileName, 'w') csvWriteObj = csv.writer(csvFile) csvWriteObj.writerow(columnCaptions) for rowNumber, stat in enumerate(TrafficItemStats.Rows): rowStats = stat.RawData for row in rowStats: csvWriteObj.writerow(row) csvFile.close() for rowNumber, stat in enumerate(TrafficItemStats.Rows): if displayStats: self.ixnObj.logInfo('\n Row: {}'.format(rowNumber + 1), timestamp=False) statsDict = {} for column in columnCaptions: statsDict[column] = stat[column] if displayStats: self.ixnObj.logInfo('\t%s: %s' % (column, stat[column]), timestamp=False) trafficItemStatsDict[rowNumber + 1] = statsDict return trafficItemStatsDict def removeAllTclViews(self): """ Description Removes all created stat views. """ self.ixnObj.logInfo("Remove all tcl views") self.ixNetwork.RemoveAllTclViews() def takeSnapshot(self, viewName='Flow Statistics', windowsPath=None, isLinux=False, localLinuxPath=None, renameDestinationFile=None, includeTimestamp=False, mode='overwrite'): """ Description Take a snapshot of the vieweName statistics. This is a two step process. 1> Take a snapshot of the statistics that you want and store it in the C: drive for Windows. For Linux, the snapshot goes to /home/ixia_logs. 2> Copy the statistics from the snapshot locations to the local Linux where you ran the script.. Parameters viewName: The name of the statistics to get. windowsPath: For Windows|WindowsConnectionMgr only. The C: drive + path to store the snapshot: Example: c:\\Results. isLinux: <bool>: Defaults to False. Set to True if you're getting the snapshot from Linux chassis. localLinuxPath: None|path. Provide the local Linux path to put the snapshot file. If None, this API won't copy the stat file to local Linux. The stat file will remain on Windows c: drive. renameDestinationFile: None or a name of the file other than the viewName. includeTimestamp: True|False: To include a timestamp at the end of the file. mode: append|overwrite: append=To append stats to an existing stat file. overwrite=Don't append stats. Create a new stat file. Example: For Windows: statObj.takeSnapshot(viewName='Flow Statistics', windowsPath='C:\\Results', localLinuxPath='/home/hgee', renameDestinationFile='my_renamed_stat_file.csv', includeTimestamp=True) For Linux: statObj.takeSnapshot(viewName='Flow Statistics', isLinux=True, localLinuxPath='/home/hgee') """ location = None if mode == 'append': mode = 'kAppendCSVFile' if mode == 'overwrite': mode = 'kOverwriteCSVFile' if windowsPath: location = windowsPath if isLinux: location = '/home/ixia_logs' self.ixNetwork.TakeViewCSVSnapshot( Arg1=[viewName], Arg2=[ "Snapshot.View.Contents: \"allPages\"", "Snapshot.View.Csv.Location: \"{0}\"".format(location), "Snapshot.View.Csv.GeneratingMode: \"%s\"" % mode, "Snapshot.View.Csv.StringQuotes: \"True\"", "Snapshot.View.Csv.SupportsCSVSorting: \"False\"", "Snapshot.View.Csv.FormatTimestamp: \"True\"", "Snapshot.View.Csv.DumpTxPortLabelMap: \"False\"", "Snapshot.View.Csv.DecimalPrecision: \"3\"" ]) if isLinux: snapshotFile = location + '/' + viewName + '.csv' self.fileMgmtObj.copyFileLinuxToLocalLinux( linuxApiServerPathAndFileName=snapshotFile, localPath=localLinuxPath, renameDestinationFile=renameDestinationFile, includeTimestamp=includeTimestamp) if windowsPath and localLinuxPath: self.fileMgmtObj.copyFileWindowsToLocalLinux( '{0}\\{1}.csv'.format(windowsPath, viewName), localLinuxPath, renameDestinationFile=renameDestinationFile, includeTimestamp=includeTimestamp) def getViewObject(self, viewName='Flow Statistics'): """ Description To get just the statistic view object. Mainly used by internal APIs such as takeCsvSnapshot that requires the statistics view object handle. Parameter viewName: Options (case sensitive): "Port Statistics" "Tx-Rx Frame Rate Statistics" "Port CPU Statistics" "Global Protocol Statistics" "Protocols Summary" "Port Summary" "OSPFv2-RTR Drill Down" "OSPFv2-RTR Per Port" "IPv4 Drill Down" "L2-L3 Test Summary Statistics" "Flow Statistics" "Traffic Item Statistics" """ for viewObj in self.ixNetwork.Statistics.View.find(): if viewObj.Caption == viewName: return viewObj else: raise Exception( "View object not available for view name {}".format(viewName)) def clearStats(self): """ Description Clear all stats and wait for API server to finish. """ self.ixnObj.logInfo("Clearing all statistics") self.ixNetwork.ClearStats(Arg1=['waitForPortStatsRefresh'])
#---------- Preference Settings End -------------- portObj = PortMgmt(mainObj) portObj.connectIxChassis(ixChassisIp) if portObj.arePortsAvailable(portList, raiseException=False) != 0: if forceTakePortOwnership == True: portObj.releasePorts(portList) portObj.clearPortOwnership(portList) else: raise IxNetRestApiException('\nPorts are owned by another user and forceTakePortOwnership is set to False. Exiting test.') portObj.releasePorts(portList) mainObj.configLicenseServerDetails([licenseServerIp], licenseModel) fileMgmtObj = FileMgmt(mainObj) fileMgmtObj.importJsonConfigFile(jsonConfigFile, option='newConfig') # Set configPortName=False because loading a saved config file assumes ports already have configured names. Don't overwrite them. portObj.assignPorts(portList, forceTakePortOwnership, configPortName=False) if modifyPortMediaType: portObj.modifyPortMediaType(portList=portList, mediaType=modifyPortMediaType) portObj.verifyPortState() # Example: How to modify # Mofify the BGP configuration using JSON XPATH. XPATH are obtained from a JSON exported config file. # 1> Export the JSON configuration to a file. # 2> Get the XPATH for what you want to modify the configuraiton. # 3> Import the modified JSON data object to IxNetwork. xpathObj = [{"xpath": "/multivalue[@source = '/topology[1]/deviceGroup[1]/ethernet[1]/ipv4[1]/bgpIpv4Peer[1] flap']/singleValue",
portList.append([ixChassisIp, matchCard.group(1), matchPort.group(1)]) if osPlatform == 'linux': mainObj = Connect(apiServerIp = jsonData['linuxApiServerIp'], serverIpPort = jsonData['linuxServerIpPort'], username = jsonData['username'], password = jsonData['password'], deleteSessionAfterTest = jsonData['deleteSessionAfterTest'], verifySslCert = False, serverOs ='linux') if osPlatform in ['windows', 'windowsConnectionMgr']: mainObj = Connect(apiServerIp=jsonData['windowsApiServerIp'], serverIpPort=jsonData['windowsServerIpPort'], serverOs=osPlatform) #---------- Preference Settings End -------------- fileMgmtObj = FileMgmt(mainObj) portObj = PortMgmt(mainObj) portObj.connectIxChassis(ixChassisIp) if portObj.arePortsAvailable(portList, raiseException=False) != 0: if forceTakePortOwnership == True: portObj.releasePorts(portList) portObj.clearPortOwnership(portList) else: raise IxNetRestApiException('\nPorts are owned by another user and forceTakePortOwnership is set to False. Exiting test.') # If the license is activated on the chassis's license server, this variable should be True. # Otherwise, if the license is in a remote server or remote chassis, this variable should be False. # Configuring license requires releasing all ports even for ports that is not used for this test. if jsonData['configLicense'] == True:
mainObj = Connect(apiServerIp='192.168.70.108', serverIpPort='443', username='******', password='******', deleteSessionAfterTest=deleteSessionAfterTest, verifySslCert=False, serverOs=connectToApiServer) if connectToApiServer == 'windows': mainObj = Connect(apiServerIp='192.168.70.3', serverIpPort='11009') ixChassisIp = '192.168.70.11' # [chassisIp, cardNumber, slotNumber] portList = [[ixChassisIp, '1', '1'], [ixChassisIp, '2', '2']] fileMgmtObj = FileMgmt(mainObj) fileMgmtObj.copyFileWindowsToLocalLinux('c:\\Results\\test', '.') sys.exit() protocolObj = Protocol(mainObj) #protocolObj.verifyProtocolSessionsNgpf(['/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/bgpIpv4Peer/1']) protocolObj.verifyArp() #protocolObj.getNgpfGatewayIpMacAddress('1.1.1.2') sys.exit() response = protocolObj.configRsvpTeLsps( ipv4Obj= '/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1' ) #protocolObj.deleteRsvpTeLsps(rsvpTunnelObj='/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/rsvpteLsps/16') #protocolObj.startAllRsvpTeLsps()
class Statistics(object): def __init__(self, ixnObj=None): self.ixnObj = ixnObj # For takesnapshot() self.fileMgmtObj = FileMgmt(self.ixnObj) def setMainObject(self, mainObject): """ Description For Python Robot Framework support. """ self.ixnObj = mainObject def getStats(self, viewObject=None, viewName='Flow Statistics', csvFile=None, csvEnableFileTimestamp=False, displayStats=True, silentMode=True, ignoreError=False): """ Description Get stats by the statistic name or get stats by providing a view object handle. Parameters csvFile = None or <filename.csv>. None will not create a CSV file. Provide a <filename>.csv to record all stats to a CSV file. Example: getStats(sessionUrl, csvFile='Flow_Statistics.csv') csvEnableFileTimestamp = True or False. If True, timestamp will be appended to the filename. displayStats: True or False. True=Display stats. ignoreError: True or False. Returns None if viewName is not found. viewObject: The view object: http://{apiServerIp:port}/api/v1/sessions/2/ixnetwork/statistics/view/13 A view object handle could be obtained by calling getViewObject(). viewName options (Not case sensitive): NOTE: Not all statistics are listed here. You could get the statistic viewName directly from the IxNetwork GUI in the statistics. 'Port Statistics' 'Tx-Rx Frame Rate Statistics' 'Port CPU Statistics' 'Global Protocol Statistics' 'Protocols Summary' 'Port Summary' 'BGP Peer Per Port' 'OSPFv2-RTR Drill Down' 'OSPFv2-RTR Per Port' 'IPv4 Drill Down' 'L2-L3 Test Summary Statistics' 'Flow Statistics' 'Traffic Item Statistics' 'IGMP Host Drill Down' 'IGMP Host Per Port' 'IPv6 Drill Down' 'MLD Host Drill Down' 'MLD Host Per Port' 'PIMv6 IF Drill Down' 'PIMv6 IF Per Port' 'Flow View' Note: Not all of the viewNames are listed here. You have to get the exact names from the IxNetwork GUI in statistics based on your protocol(s). Return a dictionary of all the stats: statDict[rowNumber][columnName] == statValue Get stats on row 2 for 'Tx Frames' = statDict[2]['Tx Frames'] """ if viewObject == None: viewList = self.ixnObj.get( '%s/%s/%s' % (self.ixnObj.sessionUrl, 'statistics', 'view'), silentMode=silentMode) views = [ '%s/%s/%s/%s' % (self.ixnObj.sessionUrl, 'statistics', 'view', str(i['id'])) for i in viewList.json() ] if silentMode is False: self.ixnObj.logInfo( '\ngetStats: Searching for viewObj for viewName: %s' % viewName) for view in views: #print('\nview:', view) # GetAttribute response = self.ixnObj.get('%s' % view, silentMode=silentMode) captionMatch = re.match(viewName, response.json()['caption'], re.I) if captionMatch: # viewObj: sessionUrl + /statistics/view/11' viewObject = view break if viewObject == None and ignoreError == False: raise IxNetRestApiException( "viewObj wasn't found for viewName: %s" % viewName) if viewObject == None and ignoreError == True: return None if silentMode is False: self.ixnObj.logInfo('\nviewObj: %s' % viewObject) for counter in range(0, 31): response = self.ixnObj.get(viewObject + '/page', silentMode=silentMode) totalPages = response.json()['totalPages'] if totalPages == 'null': self.ixnObj.logInfo( '\nGetting total pages is not ready yet. Waiting %d/30 seconds' % counter, timestamp=False) time.sleep(1) if totalPages != 'null': break if totalPages == 'null' and counter == 30: self.ixnObj.logInfo('\ngetStats failed: Getting total pages') return 1 if csvFile != None: import csv csvFileName = csvFile.replace(' ', '_') if csvEnableFileTimestamp: import datetime timestamp = datetime.datetime.now().strftime('%H%M%S') if '.' in csvFileName: csvFileNameTemp = csvFileName.split('.')[0] csvFileNameExtension = csvFileName.split('.')[1] csvFileName = csvFileNameTemp + '_' + timestamp + '.' + csvFileNameExtension else: csvFileName = csvFileName + '_' + timestamp csvFile = open(csvFileName, 'w') csvWriteObj = csv.writer(csvFile) # Get the stat column names columnList = response.json()['columnCaptions'] if csvFile != None: csvWriteObj.writerow(columnList) flowNumber = 1 statDict = {} # Get the stat values for pageNumber in range(1, totalPages + 1): self.ixnObj.patch(viewObject + '/page', data={'currentPage': pageNumber}, silentMode=silentMode) response = self.ixnObj.get(viewObject + '/page', silentMode=silentMode) statValueList = response.json()['pageValues'] for statValue in statValueList: if csvFile != None: csvWriteObj.writerow(statValue[0]) if displayStats: self.ixnObj.logInfo('\nRow: %d' % flowNumber, timestamp=False) statDict[flowNumber] = {} index = 0 for statValue in statValue[0]: statName = columnList[index] statDict[flowNumber].update({statName: statValue}) if displayStats: self.ixnObj.logInfo('\t%s: %s' % (statName, statValue), timestamp=False) index += 1 flowNumber += 1 if csvFile != None: csvFile.close() return statDict # Flow Statistics dictionary output example ''' Flow: 50 Tx Port: Ethernet - 002 Rx Port: Ethernet - 001 Traffic Item: OSPF T1 to T2 Source/Dest Value Pair: 2.0.21.1-1.0.21.1 Flow Group: OSPF T1 to T2-FlowGroup-1 - Flow Group 0002 Tx Frames: 35873 Rx Frames: 35873 Packet Loss Duration (ms): 11.106 Frames Delta: 0 Loss %: 0 Tx Frame Rate: 3643.5 Rx Frame Rate: 3643.5 Tx L1 Rate (bps): 4313904 Rx L1 Rate (bps): 4313904 Rx Bytes: 4591744 Tx Rate (Bps): 466368 Rx Rate (Bps): 466368 Tx Rate (bps): 3730944 Rx Rate (bps): 3730944 Tx Rate (Kbps): 3730.944 Rx Rate (Kbps): 3730.944 Tx Rate (Mbps): 3.731 Rx Rate (Mbps): 3.731 Store-Forward Avg Latency (ns): 0 Store-Forward Min Latency (ns): 0 Store-Forward Max Latency (ns): 0 First TimeStamp: 00:00:00.722 Last TimeStamp: 00:00:10.568 ''' def removeAllTclViews(self): """ Description Removes all created stat views. """ removeAllTclViewsUrl = self.ixnObj.sessionUrl + '/operations/removealltclviews' response = self.ixnObj.post(removeAllTclViewsUrl) self.ixnObj.waitForComplete( response, removeAllTclViewsUrl + '/' + response.json()['id']) def clearStats(self): """ Description Clears all stats Syntax POST = https://{apiServerIp:port}/api/v1/sessions/<id>/ixnetwork/operations/clearstats """ self.ixnObj.post(self.ixnObj.sessionUrl + '/operations/clearstats') def takeSnapshot(self, viewName='Flow Statistics', windowsPath=None, localLinuxPath=None, renameDestinationFile=None, includeTimestamp=False, mode='overwrite'): """ Description Take a snapshot of the vieweName statistics. This is a two step process. 1> Take a snapshot of the statistics and store it in the C: drive. 2> Copy the statistics from the c: drive to remote Linux. Parameters viewName: The name of the statistics to get. windowsPath: A C: drive + path to store the snapshot: c:\\Results localLinuxPath: None|A path. If None, this API won't copy the stat file to local Linux. The stat file will remain on Windows c: drive. renameDestinationFile: None or a name of the file other than the viewName. includeTimestamp: True|False: To include a timestamp at the end of the file. mode: append|overwrite: append=To append stats to an existing stat file. overwrite=Don't append stats. Create a new stat file. Example: takeSnapshot(viewName='Flow Statistics', windowsPath='C:\\Results', localLinuxPath='/home/hgee', renameDestinationFile='my_renamed_stat_file.csv', includeTimestamp=True) """ # TODO: For Linux API server # POST /api/v1/sessions/1/ixnetwork/operations/getdefaultsnapshotsettings # "Snapshot.View.Csv.Location: \"/root/.local/share/Ixia/IxNetwork/data/logs/Snapshot CSV\"" if windowsPath is None: raise IxNetRestApiException('\nMust include windowsPath\n') if mode == 'append': mode = 'kAppendCSVFile' if mode == 'overwrite': mode = 'kOverwriteCSVFile' data = { 'arg1': [viewName], 'arg2': [ "Snapshot.View.Contents: \"allPages\"", "Snapshot.View.Csv.Location: \"{0}\"".format(windowsPath), "Snapshot.View.Csv.GeneratingMode: \"%s\"" % mode, "Snapshot.View.Csv.StringQuotes: \"True\"", "Snapshot.View.Csv.SupportsCSVSorting: \"False\"", "Snapshot.View.Csv.FormatTimestamp: \"True\"", "Snapshot.View.Csv.DumpTxPortLabelMap: \"False\"", "Snapshot.View.Csv.DecimalPrecision: \"3\"" ] } url = self.ixnObj.sessionUrl + '/operations/takeviewcsvsnapshot' response = self.ixnObj.post(url, data=data) self.ixnObj.waitForComplete(response, url + '/' + response.json()['id']) #response = self.ixnObj.get(self.ixnObj.sessionUrl+'/files?filename=Flow Statistics.csv&absolute=c:\\Results', ignoreError=True) if localLinuxPath: # Get the snapshot. Use the csvFilename that was specified and the location self.fileMgmtObj.copyFileWindowsToLocalLinux( '{0}\\{1}.csv'.format(windowsPath, viewName), localLinuxPath, renameDestinationFile=renameDestinationFile, includeTimestamp=includeTimestamp) def getViewObject(self, viewName='Flow Statistics'): """ Description To get just the statistic view object. Mainly used by internal APIs such as takeCsvSnapshot that requires the statistics view object handle. Parameter viewName: Options (case sensitive): "Port Statistics" "Tx-Rx Frame Rate Statistics" "Port CPU Statistics" "Global Protocol Statistics" "Protocols Summary" "Port Summary" "OSPFv2-RTR Drill Down" "OSPFv2-RTR Per Port" "IPv4 Drill Down" "L2-L3 Test Summary Statistics" "Flow Statistics" "Traffic Item Statistics" """ self.ixnObj.logInfo('\ngetStats: %s' % viewName) viewList = self.ixnObj.get( "%s/%s/%s" % (self.ixnObj.sessionUrl, "statistics", "view")) views = [ "%s/%s/%s/%s" % (self.ixnObj.sessionUrl, "statistics", "view", str(i["id"])) for i in viewList.json() ] for view in views: # GetAttribute response = self.ixnObj.get(view) caption = response.json()["caption"] if viewName == caption: # viewObj: sessionUrl + "/statistics/view/11" viewObj = view return viewObj return None def clearStats(self): """ Description Clear all stats and wait for API server to finish. """ url = self.ixnObj.sessionUrl + '/operations/clearStats' response = self.ixnObj.post(url, data={'arg1': ['waitForPortStatsRefresh']})
serverOs=osPlatform, deleteSessionAfterTest=deleteSessionAfterTest) if osPlatform in ['windowsConnectionMgr']: mainObj = Connect(apiServerIp='192.168.70.3', serverIpPort='11009', serverOs=osPlatform, deleteSessionAfterTest=deleteSessionAfterTest, sessionId=8021, httpsSecured=False) trafficObj = Traffic(mainObj) statObj = Statistics(mainObj) protocolObj = Protocol(mainObj) portObj = PortMgmt(mainObj) fileMgmtObj = FileMgmt(mainObj) # How to enable/disable many traffic items at once # Step 1of2: Get all the traffic item xpaths trafficItemJsonObj = fileMgmtObj.exportJsonConfigToDict( ['/traffic/descendant-or-self::*']) jsonData = [] for trafficItem in trafficItemJsonObj['traffic']['trafficItem']: data = {'xpath': trafficItem['xpath'], 'enabled': True} jsonData.append(data) # Step 2of2: Use API to send all the xpath data and modify them all at once. fileMgmtObj.importJsonConfigObj(dataObj=jsonData, option='modify') except (IxNetRestApiException, Exception, KeyboardInterrupt) as errMsg: print('\nTest failed! {0}\n'.format(traceback.print_exc()))
import sys, traceback, time sys.path.insert(0, '../Modules/Main') from IxNetRestApi import * from IxNetRestApiFileMgmt import FileMgmt # The path to your exported JSON config file: jsonConfigFile = 'bgpSimplified.json' # Where to store the exported JSON config file #exportJsonConfigFile = '/home/hgee/exportedJsonConfig.json' exportJsonConfigFile = 'bgp_ngpf_hw_8.40.json' try: restObj = Connect(apiServerIp='192.168.70.3', serverIpPort='11009') fileMgmtObj = FileMgmt(restObj) # How to export a configuration into a JSON format file. # This will export your current configuration into a specified json filename. fileMgmtObj.exportJsonConfigFile(jsonFileName=exportJsonConfigFile) # How to load a complete json config file fileMgmtObj.importJsonConfigFile(jsonConfigFile, option='newConfig') # Read a JSON config file and store all the datas into an object. # Use the jsonData object to make your modifications. jsonData = fileMgmtObj.jsonReadConfig(exportJsonConfigFile) # How to use XPATH to modify IxNetwork configurations. xpathObj = [{"xpath": "/multivalue[@source = '/topology[1]/deviceGroup[1]/ethernet[1]/ipv4[1]/bgpIpv4Peer[1] flap']/singleValue",
username='******', password='******', deleteSessionAfterTest=deleteSessionAfterTest, verifySslCert=False, serverOs='linux') if connectToApiServer in ['windows', 'windowsConnectionMgr']: mainObj = Connect(apiServerIp='192.168.70.3', serverIpPort='11009', serverOs=connectToApiServer, deleteSessionAfterTest=deleteSessionAfterTest) #---------- Preference Settings End -------------- portObj = PortMgmt(mainObj) fileMgmtObj = FileMgmt(mainObj) folderNotExists = [] fileNotExists = [] if destinationPath == '' or destinationPath == None: raise IxNetRestApiException('\nError: You must provide a destination path to store the converted JSON config files.\n') if os.path.exists(destinationPath) == False: raise IxNetRestApiException('\nError: The destinationPath does not exists: {0}'.format(destinationPath)) if ixncfgFiles: for eachIxncfgFile in ixncfgFiles: if not os.path.exists(eachIxncfgFile): fileNotExists.append(eachIxncfgFile) else: print('\nLoading ixncfg: {0}'.format(eachIxncfgFile))