diff --git a/RestApi/Python/Modules/ClassInheritance.py b/RestApi/Python/Modules/ClassInheritance.py index 373addf3..d626f018 100644 --- a/RestApi/Python/Modules/ClassInheritance.py +++ b/RestApi/Python/Modules/ClassInheritance.py @@ -7,7 +7,7 @@ Your scripts will be instantiating objects using your classes. With inheritance, this allows your scripts to use all of OpenIxia functions and use your added functions in your classes. - This allows you to keep getting OpenIxia updates without interferring with + This allows you to keep getting OpenIxia updates without interferring with your extended functions. """ @@ -20,10 +20,12 @@ from IxNetRestApiPacketCapture import PacketCapture from IxNetRestApiQuickTest import QuickTest + class Connection(Connect): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + class Port_Mgmt(PortMgmt): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -37,14 +39,17 @@ def exportJsonConfig(self): # For enhancement or to fix a bug in exportJsonConfig(). pass + class Traffic_Config(Traffic): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + class Protocol_Config(Protocol): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + class Statistics_View(Statistics): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) diff --git a/RestApi/Python/Modules/IxNetRestApi.py b/RestApi/Python/Modules/IxNetRestApi.py index 6b2157be..235e76c6 100644 --- a/RestApi/Python/Modules/IxNetRestApi.py +++ b/RestApi/Python/Modules/IxNetRestApi.py @@ -1,4 +1,3 @@ - # PLEASE READ DISCLAIMER # # This class demonstrates sample IxNetwork REST API usage for @@ -11,7 +10,13 @@ # from __future__ import absolute_import, print_function, division -import os, re, sys, requests, json, time, subprocess, traceback, time, datetime, platform +import sys +import requests +import datetime +import platform +import time +from ixnetwork_restpy import TestPlatform + class IxNetRestApiException(Exception): def __init__(self, msg=None): @@ -19,7 +24,7 @@ def __init__(self, msg=None): super().__init__(msg) if platform.python_version().startswith('2'): - super(IxNetRestApiException, self). __init__(msg) + super(IxNetRestApiException, self).__init__(msg) if Connect.robotStdout is not None: Connect.robotStdout.log_to_console(msg) @@ -30,24 +35,27 @@ def __init__(self, msg=None): with open(Connect.debugLogFile, 'a') as restLogFile: restLogFile.write(showErrorMsg) + class Connect: # For IxNetRestApiException debugLogFile = None enableDebugLogFile = False robotStdout = None - def __init__(self, apiServerIp=None, serverIpPort=None, serverOs='windows', linuxChassisIp=None, manageSessionMode=False, - webQuickTest=False, username=None, password='admin', licenseServerIp=None, licenseMode=None, licenseTier=None, - deleteSessionAfterTest=True, verifySslCert=False, includeDebugTraceback=True, sessionId=None, httpsSecured=None, - apiKey=None, generateLogFile=True, robotFrameworkStdout=False, linuxApiServerTimeout=120): + def __init__(self, apiServerIp=None, serverIpPort=None, + serverOs='windows', linuxChassisIp=None, + manageSessionMode=False, webQuickTest=False, + username=None, password='admin', licenseServerIp=None, + licenseMode=None, licenseTier=None, + deleteSessionAfterTest=True, verifySslCert=False, + includeDebugTraceback=True, sessionId=None, + httpsSecured=None, apiKey=None, + generateLogFile=True, robotFrameworkStdout=False, + linuxApiServerTimeout=120): """ Description Initializing default parameters and making a connection to the API server - Notes - Starting IxNetwork 8.50, https will be enforced even for Windows connection. - If you still want to use http, you need to add -restInsecure to the IxNetwork.exe appliaction under "target". - Examples Right click on "IxNetwork API server", select properties and under target ixnetwork.exe -restInsecure -restPort 11009 -restOnAllInterfaces -tclPort 8009 @@ -57,94 +65,54 @@ def __init__(self, apiServerIp=None, serverIpPort=None, serverOs='windows', linu serverIpPort: (str): The API server IP address socket port. serverOs: (str): windows|windowsConnectionMgr|linux linuxChassisIp: (str): Connect to a Linux OS chassis IP address. - webQuickTest: (bool): True: Using IxNetwork Web Quick Test. Otherwise, using IxNetwork. + webQuickTest: (bool): True: Using IxNetwork + Web Quick Test. Otherwise, using IxNetwork. includeDebugTraceback: (bool): - True: Traceback messsages are included in raised exceptions. - False: No traceback. Less verbose for debugging. + True: Traceback messsages are + included in raised exceptions. + False: No traceback. + Less verbose for debugging. username: (str): The login username. For Linux API server only. password: (str): The login password. For Linux API server only. licenseServerIp: (str): The license server IP address. licenseMode: (str): subscription | perpetual | mixed licenseTier: (str): tier1 | tier2 | tier3 - linuxApiServerTimeout: (int): For Linux API server start operation timeout. Defaults to 120 seconds. + linuxApiServerTimeout: (int): For Linux API server start operation timeout. Defaults + to 120 seconds. deleteSessionAfterTest: (bool): True: Delete the session. False: Don't delete the session. verifySslCert: (str): Optional: Include your SSL certificate for added security. - httpsSecured: (bool): This parameter is only used by Connection Mgr when user wants to connect to - an existing session. - True = IxNetwork ReST API server is using HTTPS. - This parameter must also include sessionId and serverIpPort= - - serverOs: (str): Defaults to windows. windows|windowsConnectionMgr|linux. + httpsSecured: (bool): This parameter is only used by Connection Mgr when user wants to + connect to an existing session. + True = IxNetwork ReST API server is using HTTPS + This parameter must also include sessionId + and serverIpPort= + + serverOs: (str): Defaults to windows. + windows|windowsConnectionMgr|linux. includeDebugTraceback: (bool): True: Include tracebacks in raised exceptions. - sessionId: (str): The session ID on the Linux API server or Windows Connection Mgr to connect to. - apiKey: (str): The Linux API server user account API-Key to use for the sessionId connection. - generateLogFile: True|False|. If you want to generate a log file, provide - the log file name. - True = Then the log file default name is ixNetRestApi_debugLog.txt - False = Disable generating a log file. - = The full path + file name of the log file to create. + sessionId: (str): The session ID on the Linux API server or Windows Connection Mgr to + connect to. + apiKey: (str): The Linux API server user account API-Key to use for the sessionId + connection. + generateLogFile: True|False|. + If you want to generate a log file, provide the log file name. + True = Then the log file default name is ixNetRestApi_debugLog.txt + False = Disable generating a log file. + = The full path + file name of the log file to create. robotFrameworkStdout: (bool): True = Print to stdout. httpInsecure: (bool): This parameter is only for Windows connections. - True: Using http. False: Using https. - Starting 8.50: IxNetwork defaults to use https. - If you are using versions prior to 8.50, it needs to be a http connection. - In this case, set httpInsecure=True. - - Notes - Class attributes - self._session: The requests initial Session(). - self.serverOs: windows|windowsConnectionMgr|linux - - self.httpHeader: http://{apiServerIp}:{port} - self.sessionId : http://{apiServerIp}:{port}/api/v1/sessions/{id} - self.sessionUrl: http://{apiServerIp}:{port}/api/v1/sessions/{id}/ixnetwork - self.headlessSessionId: /api/v1/sessions/{id} - self.apiSessionId: /api/v1/sessions/{id}/ixnetwork - - self.jsonHeader: The default header: {"content-type": "application/json"} - self.apiKey: For Linux API server only. Automatically provided by the server when login - successfully authenticated. - You could also provide an API-Key to connect to an existing session. - Get the API-Key from the Linux API server user account. - - Examples: - Steps to connect to Linux API server steps: - 1> POST: https://{apiServerIp}/api/v1/auth/session - DATA: {"username": "admin", "password": "admin"} - HEADERS: {'content-type': 'application/json'} - - 2> POST: https://{apiServerIp:{port}/api/v1/sessions - DATA: {"applicationType": "ixnrest"} - HEADERS: {'content-type': 'application/json', 'x-api-key': 'd9f4da46f3c142f48dddfa464788hgee'} - - 3> POST: https://{apiServerIp}:443/api/v1/sessions/4/operations/start - DATA: {} - HEADERS: {'content-type': 'application/json', 'x-api-key': 'd9f4da46f3c142f48dddfa464788hgee'} - - sessionId = https://{apiServerIp}:443/api/v1/sessions/{id} - - Steps to connect to Linux Web Quick Test: - 1> POST: https://{apiServerIp}:443/api/v1/auth/session - DATA: {"username": "admin", "password": "admin"} - HEADERS: {'content-type': 'application/json'} - - 2> POST: https://{apiServeIp}:443/api/v1/sessions - DATA: {'applicationType': 'ixnetwork'} - - 3> POST: https://{apiServerIp}:443/api/v1/sessions/2/operations/start - DATA: {'applicationType': 'ixnetwork'} - - sessionId = https://{apiServerIp}/ixnetworkweb/api/v1/sessions/{id} + True: Using http. False: Using https. + Starting 8.50: IxNetwork defaults to use https. + If you are using versions prior to 8.50, it needs to be a http + connection. In this case, set httpInsecure=True. Notes To connect to an existing configuration. - Windows: Nothing special to include. The session ID is always "1". - Linux API server: Include the api-key and sessionId that you want to connect to. - Windows Connection Manager: Include just the sessionId: For example: 8021. + Windows: Nothing special to include. The session ID is always "1". + Linux API server: Include the api-key and sessionId that you want to connect to. + Windows Connection Manager: Include just the sessionId: For example: 8021. """ - from requests.exceptions import ConnectionError - from requests.packages.urllib3.connection import HTTPConnection # Disable SSL warnings requests.packages.urllib3.disable_warnings() @@ -155,8 +123,7 @@ def __init__(self, apiServerIp=None, serverIpPort=None, serverOs='windows', linu self._session = requests.Session() - self.serverOs = serverOs ;# windows|windowsConnectionMgr|linux - self.jsonHeader = {"content-type": "application/json"} + self.serverOs = serverOs # windows|windowsConnectionMgr|linux self.username = username self.password = password self.apiKey = apiKey @@ -169,6 +136,7 @@ def __init__(self, apiServerIp=None, serverIpPort=None, serverOs='windows', linu self.robotFrameworkStdout = robotFrameworkStdout self.linuxChassisIp = linuxChassisIp self.linuxApiServerTimeout = linuxApiServerTimeout + self.sessionId = sessionId # Make Robot print to stdout if self.robotFrameworkStdout: @@ -177,180 +145,80 @@ def __init__(self, apiServerIp=None, serverIpPort=None, serverOs='windows', linu Connect.robotStdout = self.robotStdout if generateLogFile: - if generateLogFile == True: - # Default the log file name - self.restLogFile = 'ixNetRestApi_debugLog.txt' - Connect.enableDebugLogFile = True - Connect.debugLogFile = self.restLogFile - - if type(generateLogFile) != bool: - self.restLogFile = generateLogFile + # Default the log file name + self.restLogFile = 'ixNetRestApi_debugLog.txt' + Connect.enableDebugLogFile = True + Connect.debugLogFile = self.restLogFile - # Instantiate a new log file here. - with open(self.restLogFile, 'w') as restLogFile: - restLogFile.write('Date: {0}\nTime: {1}\n\n'.format(self.getDate, self.getTime)) - - if self.serverOs == 'windowsConnectionMgr': - if httpsSecured is False or self.apiServerPort is None: - raise IxNetRestApiException('If using windowsConnectionMgr, you must state httpsSecured=True|False and a serverIpPort to use.') + if type(generateLogFile) != bool: + self.restLogFile = generateLogFile - self.httpScheme = 'http' ;# This will dynamically change to https. - - # Automatic default to https for linux - if self.serverOs == 'linux': - self.logInfo('Connecting to API server: linux') - self.httpScheme = 'https' - if self.apiServerPort is not None: - self.apiServerPort = serverIpPort - else: - self.apiServerPort = 443 - - - # Windows supports only http if self.serverOs == 'windows': - self.logInfo('Connecting to API server: windows') - if httpsSecured: - self.httpScheme = 'https' - if self.apiServerPort is None: self.apiServerPort = 11009 else: self.apiServerPort = serverIpPort + self.testPlatform = TestPlatform(ip_address=self.linuxApiServerIp, + rest_port=self.apiServerPort, + platform=self.serverOs, + verify_cert=verifySslCert, + log_file_name=self.restLogFile) + self.session = self.testPlatform.Sessions.add() + self.sessionId = self.session.Id + self.ixNetwork = self.session.Ixnetwork - # windowsConnectionMgr supports only https and allows users to set the SSL port. - # This is the only api server that requires user to state httpsSecured=True|False because 8.40 users could be using http. - # While 8.50+ users could be using http or https. if self.serverOs == 'windowsConnectionMgr': - self.logInfo('Connecting to API server: windowsConnectionMgr') - - if httpsSecured: - # For Windows Connection Mgr only because WCM allows http and https - # When creating a new session, there is no way to know by doing a POST for a new session to - # understand if it's for http or https. You must enter https for the POST to create a new session. - if httpsSecured == True: - self.httpScheme = 'https' - else: - self.httpScheme = 'http' - - # Make Robot print to stdout - #if self.robotFrameworkStdout: - # from robot.libraries.BuiltIn import _Misc - # self.robotStdout = _Misc() - # Connect.robotStdout = self.robotStdout - - if linuxChassisIp: - self.connectToLinuxIxosChassis(self.linuxChassisIp, self.username, self.password) - return - - if serverOs == 'windows': - self.createWindowsSession(apiServerIp, self.apiServerPort) - - if serverOs == 'windowsConnectionMgr': - # User connecting to existing sessionId - # - # Starting 8.50, IxNetwork API server supports https on Windows. - # If connecting to an existing session with the api server set to https:: - # - Pass in apiServerIp, serverIpPort, httpsSecured and sessionId - # - Although the serverIpPort default is 443 for https, this could change in the future. - - if sessionId: - url = '{0}://{1}:{2}/api/v1/sessions/{3}'.format(self.httpScheme, apiServerIp, self.apiServerPort, str(sessionId)) - try: - response = self._session.request('GET', url, verify=self.verifySslCert, allow_redirects=False) - if '3' in str(response.status_code): - self.httpScheme = 'https' - # Here, needs to set to use https. - url = '{0}://{1}:{2}/api/v1/sessions/{3}'.format(self.httpScheme, apiServerIp, self.apiServerPort, str(sessionId)) - - except requests.exceptions.RequestException as errMsg: - errMsg = 'Connecting to existing config failed on a GET: {0}'.format(errMsg) - raise IxNetRestApiException(errMsg) - - self.logInfo('Connecting to existing session: {}'.format(url)) - self.sessionUrl = url + '/ixnetwork' - self.sessionId = '{0}://{1}:{2}/api/v1/sessions/{3}'.format(self.httpScheme, apiServerIp, - self.apiServerPort, str(sessionId)) - self.apiSessionId = '/api/v1/sessions/{0}/ixnetwork'.format(str(sessionId)) - self.httpHeader = self.sessionUrl.split('/api')[0] - else: - # Create a new session - self.createWindowsSession(apiServerIp, self.apiServerPort) + if self.sessionId: + self.testPlatform = TestPlatform( + ip_address=self.linuxApiServerIp, + rest_port=self.apiServerPort, + platform=self.serverOs, + verify_cert=verifySslCert, + log_file_name=self.restLogFile) - if serverOs == 'linux': - if self.apiServerPort == None: + if self.serverOs == 'linux': + if self.apiServerPort is None: self.apiServerPort = 443 - # Connect to no session ID. Connects to a Linux API server to get and delete open sessions. - if self.manageSessionMode: - if self.apiKey == None: - response = self.post('https://{}:{}/api/v1/auth/session'.format(self.linuxApiServerIp, self.apiServerPort), - data={"username": "admin", "password": "admin"}, - headers={'content-type': 'application/json'}) - - self.jsonHeader = {'content-type': 'application/json', 'x-api-key': self.apiKey} - self.sessionUrl = 'https://{0}:{1}/ixnetworkweb/api/v1/sessions'.format(self.linuxApiServerIp, self.apiServerPort) - return - - # Connect to an existing session on the Linux API server - if sessionId: - if self.apiKey == None: - url = 'https://{0}:{1}/api/v1/auth/session'.format(self.linuxApiServerIp, self.apiServerPort) - response = self.post(url, data={'username': username, 'password': password}, ignoreError=True) - if not str(response.status_code).startswith('2'): - raise IxNetRestApiException('\nLogin username/password failed\n') - - self.apiKey = response.json()['apiKey'] - - self.sessionId = 'https://{0}:{1}/api/v1/sessions/{2}'.format(self.linuxApiServerIp, - self.apiServerPort, str(sessionId)) - self.sessionUrl = self.sessionId + '/ixnetwork' - self.httpHeader = self.sessionUrl.split('/ixnetworkweb')[0] - self.jsonHeader = {'content-type': 'application/json', 'x-api-key': self.apiKey} - - response = self.get('https://{0}:{1}/api/v1/sessions/{2}'.format(self.linuxApiServerIp, self.apiServerPort, str(sessionId))) - - if self.webQuickTest == False: - # https://192.168.70.108/ixnetworkweb/api/v1/sessions/4 - self.sessionId = response.json()['links'][0]['href'] - # Remove the redirect /ixnetworkweb from the URL. IxNetwork 8.50 will resolve this. - self.sessionId = self.sessionId.replace('ixnetworkweb/', '') - - # https://192.168.70.108/ixnetworkweb/api/v1/sessions/4/ixnetork - self.sessionUrl = self.sessionId + '/ixnetwork' - - # /api/v1/sessions/4/ixnetwork - match = re.match('.*(/api.*)', self.sessionId) - self.apiSessionId = match.group(1) + '/ixnetwork' - - # https://10.10.10.1:443 - matchHeader = re.match('(https://[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+(:[0-9]+)?)', self.sessionId) - self.httpHeader = matchHeader.group(1) - - if self.webQuickTest: - self.sessionId = 'https://{0}:{1}/ixnetwork/api/v1/sessions/{2}'.format(self.linuxApiServerIp, - self.apiServerPort, str(sessionId)) - self.sessionUrl = self.sessionId - self.httpHeader = self.sessionUrl.split('/ixnetworkweb')[0] - - # Create new session: connectToLinuxApiServer API knows whether to create a new session or connect to an existing - # session by looking at the self.apiKey. - if apiKey == None and sessionId == None: - self.connectToLinuxApiServer(self.linuxApiServerIp, self.apiServerPort, username=username, password=password, - verifySslCert=verifySslCert, timeout=self.linuxApiServerTimeout) + if username is None or password is None: + self.username = 'admin' + self.password = 'admin' + + self.testPlatform = TestPlatform(ip_address=self.linuxApiServerIp, + rest_port=self.apiServerPort, + platform=self.serverOs, + verify_cert=verifySslCert, + log_file_name=self.restLogFile) + self.testPlatform.Authenticate(self.username, self.password) + + if apiKey is not None and sessionId is None: + raise IxNetRestApiException('Providing an apiKey must also provide a sessionId.') + # Connect to an existing session on the Linux API server + if apiKey and sessionId: + self.session = self.testPlatform.Sessions.find(Id=sessionId) + self.ixNetwork = self.session.Ixnetwork + + if apiKey is None and sessionId: + self.session = self.testPlatform.Sessions.find(Id=sessionId) + self.ixNetwork = self.session.Ixnetwork + + if apiKey is None and sessionId is None: + self.session = self.testPlatform.Sessions.add() + self.sessionId = self.session.Id + self.ixNetwork = self.session.Ixnetwork if licenseServerIp or licenseMode or licenseTier: - self.configLicenseServerDetails(licenseServerIp, licenseMode, licenseTier) - - # For Linux API Server and Windoww Connection Mgr only: Delete the session when script is done if deleteSessionAfterTest = True. - self.deleteSessionAfterTest = deleteSessionAfterTest + self.configLicenseServerDetails( + licenseServerIp, licenseMode, licenseTier) - match = re.match('http.*(/api.*/sessions/[0-9]+)/ixnetwork', self.sessionUrl) - self.headlessSessionId = match.group(1) + # For Linux API Server and Windoww Connection Mgr only: + # Delete the session when script is done + self.deleteSessionAfterTest = deleteSessionAfterTest + if includeDebugTraceback is False: + sys.tracebacklimit = 0 - if includeDebugTraceback == False: - sys.tracebacklimit = 0 - - def get(self, restApi, data={}, stream=False, silentMode=False, ignoreError=False, maxRetries=5): + def get(self, restApi, data={}, stream=False, silentMode=False, ignoreError=False, + maxRetries=5): """ Description A HTTP GET function to send REST APIs. @@ -359,56 +227,18 @@ def get(self, restApi, data={}, stream=False, silentMode=False, ignoreError=Fals restApi: (str): The REST API URL. data: (dict): The data payload for the URL. silentMode: (bool): To display on stdout: URL, data and header info. - ignoreError: (bool): True: Don't raise an exception. False: The response will be returned. - maxRetries: : The maximum amount of GET retries before declaring as server connection failure. + ignoreError: (bool): True: Don't raise an exception. + False: The response will be returned. + maxRetries: : The maximum amount of GET retries before declaring as server + connection failure. - Syntax - /api/v1/sessions/1/ixnetwork/operations + Note: + This API is not needed in RestPY, Added pass to avoid exception """ - retryInterval = 3 - restExecutionFailures = 0 - while True: - if silentMode is False: - self.logInfo('\n\tGET: {0}'.format(restApi)) - - try: - # For binary file - if stream: - response = self._session.request('GET', restApi, stream=True, headers=self.jsonHeader, allow_redirects=True, verify=self.verifySslCert) - - if stream == False: - response = self._session.request('GET', restApi, headers=self.jsonHeader, allow_redirects=True, verify=self.verifySslCert) - - if silentMode is False: - for redirectStatus in response.history: - if '307' in str(response.history): - self.logInfo('\t{0}: {1}'.format(redirectStatus, response.url), timestamp=False) - - self.logInfo('\tSTATUS CODE: {0}'.format(response.status_code), timestamp=False) - - if not str(response.status_code).startswith('2'): - if ignoreError == False: - if 'message' in response.json() and response.json()['messsage'] != None: - self.logWarning('\n%s' % response.json()['message']) - - errMsg = 'GET Exception error: {0}'.format(response.text) - raise IxNetRestApiException(errMsg) - - return response - - except (requests.exceptions.RequestException, Exception) as errMsg: - errMsg = 'GET Exception error {}/{} retries: {}'.format(restExecutionFailures, maxRetries, errMsg) - - if restExecutionFailures < maxRetries: - self.logError(errMsg) - restExecutionFailures += 1 - time.sleep(retryInterval) - continue - - if restExecutionFailures == maxRetries: - raise IxNetRestApiException(errMsg) + pass - def post(self, restApi, data={}, headers=None, silentMode=False, noDataJsonDumps=False, ignoreError=False, maxRetries=5): + def post(self, restApi, data={}, headers=None, silentMode=False, noDataJsonDumps=False, + ignoreError=False, maxRetries=5): """ Description A HTTP POST function to create and start operations. @@ -418,66 +248,16 @@ def post(self, restApi, data={}, headers=None, silentMode=False, noDataJsonDumps data: (dict): The data payload for the URL. headers: (str): The special header to use for the URL. silentMode: (bool): To display on stdout: URL, data and header info. - noDataJsonDumps: (bool): True: Use json dumps. False: Accept the data as-is. - ignoreError: (bool): True: Don't raise an exception. False: The response will be returned. - maxRetries: : The maximum amount of GET retries before declaring as server connection failure. + noDataJsonDumps: (bool): True: Use json dumps. + False: Accept the data as-is. + ignoreError: (bool): True: Don't raise an exception. + False: The response will be returned. + maxRetries: : The maximum amount of GET retries before declaring as server + connection failure. + Note: + This API is not needed in RestPY, Added pass to avoid exception """ - if headers != None: - originalJsonHeader = self.jsonHeader - self.jsonHeader = headers - - if noDataJsonDumps == True: - data = data - else: - data = json.dumps(data) - - retryInterval = 3 - restExecutionFailures = 0 - while True: - if silentMode == False: - self.logInfo('\n\tPOST: {0}\n\tDATA: {1}'.format(restApi, data)) - - try: - if self.linuxChassisIp and json.loads(data) == {}: - # Interacting with LinuxOS chassis doesn't like empty data payload. So excluding it here. - response = self._session.request('POST', restApi, headers=self.jsonHeader, allow_redirects=True, verify=self.verifySslCert) - else: - response = self._session.request('POST', restApi, data=data, headers=self.jsonHeader, allow_redirects=True, - verify=self.verifySslCert) - - # 200 or 201 - if silentMode == False: - for redirectStatus in response.history: - if '307' in str(response.history): - self.logInfo('\t{0}: {1}'.format(redirectStatus, response.url), timestamp=False) - - self.logInfo('\tSTATUS CODE: %s' % response.status_code, timestamp=False) - - if str(response.status_code).startswith('2') == False: - if ignoreError == False: - if 'errors' in response.json(): - errMsg = 'POST Exception error: {0}\n'.format(response.json()['errors']) - raise IxNetRestApiException(errMsg) - - raise IxNetRestApiException('POST error: {0}\n'.format(response.text)) - - # Change it back to the original json header - if headers != None: - self.jsonHeader = originalJsonHeader - - return response - - except (requests.exceptions.RequestException, Exception) as errMsg: - errMsg = 'POST Exception error {}/{} retries: {}'.format(restExecutionFailures, maxRetries, errMsg) - - if restExecutionFailures < maxRetries: - self.logError(errMsg) - restExecutionFailures += 1 - time.sleep(retryInterval) - continue - - if restExecutionFailures == maxRetries: - raise IxNetRestApiException(errMsg) + pass def patch(self, restApi, data={}, silentMode=False, ignoreError=False, maxRetries=5): """ @@ -488,45 +268,14 @@ def patch(self, restApi, data={}, silentMode=False, ignoreError=False, maxRetrie restApi: (str): The REST API URL. data: (dict): The data payload for the URL. silentMode: (bool): To display on stdout: URL, data and header info. - ignoreError: (bool): True: Don't raise an exception. False: The response will be returned. - maxRetries: : The maximum amount of GET retries before declaring as server connection failure. - """ - retryInterval = 3 - restExecutionFailures = 0 - while True: - if silentMode == False: - self.logInfo('\n\tPATCH: {0}\n\tDATA: {1}'.format(restApi, data)) - - try: - response = self._session.request('PATCH', restApi, data=json.dumps(data), headers=self.jsonHeader, allow_redirects=True, - verify=self.verifySslCert) - - if silentMode == False: - for redirectStatus in response.history: - if '307' in str(response.history): - self.logInfo('\t{0}: {1}'.format(redirectStatus, response.url), timestamp=False) - - self.logInfo('\tSTATUS CODE: %s' % response.status_code, timestamp=False) - - if ignoreError == False: - if not str(response.status_code).startswith('2'): - if response.json() and 'errors' in response.json(): - errMsg = 'PATCH Exception error: {0}\n'.format(response.json()['errors']) - raise IxNetRestApiException('PATCH error: {0}\n'.format(errMsg)) - - return response - - except (requests.exceptions.RequestException, Exception) as errMsg: - errMsg = 'PATCH Exception error {}/{} retries: {}\n'.format(restExecutionFailures, maxRetries, errMsg) - - if restExecutionFailures < maxRetries: - self.logError(errMsg) - restExecutionFailures += 1 - time.sleep(retryInterval) - continue - - if restExecutionFailures == maxRetries: - raise IxNetRestApiException(errMsg) + ignoreError: (bool): True: Don't raise an exception. + False: The response will be returned. + maxRetries: : The maximum amount of GET retries before declaring as server + connection failure. + Note: + This API is not needed in RestPY, Added pass to avoid exception + """ + pass def options(self, restApi, data={}, silentMode=False, ignoreError=False, maxRetries=5): """ @@ -536,46 +285,14 @@ def options(self, restApi, data={}, silentMode=False, ignoreError=False, maxRetr Parameters restApi: (str): The REST API URL. silentMode: (bool): To display on stdout: URL, data and header info. - ignoreError: (bool): True: Don't raise an exception. False: The response will be returned. - maxRetries: : The maximum amount of GET retries before declaring as server connection failu - """ - retryInterval = 3 - restExecutionFailures = 0 - while True: - if silentMode is False: - self.logInfo('\n\tOPTIONS: {0}'.format(restApi)) - - try: - # For binary file - response = self._session.request('OPTIONS', restApi, headers=self.jsonHeader, allow_redirects=True, verify=self.verifySslCert) - - if silentMode is False: - for redirectStatus in response.history: - if '307' in str(response.history): - self.logInfo('\t{0}: {1}'.format(redirectStatus, response.url), timestamp=False) - - self.logInfo('\tSTATUS CODE: {0}'.format(response.status_code), timestamp=False) - - if not str(response.status_code).startswith('2'): - if ignoreError == False: - if 'message' in response.json() and response.json()['messsage'] != None: - self.logWarning('\n%s' % response.json()['message']) - - errMsg = 'OPTIONS Exception error: {0}'.format(response.text) - raise IxNetRestApiException(errMsg) - return response - - except (requests.exceptions.RequestException, Exception) as errMsg: - errMsg = 'OPTIONS Exception error {}/{} retries: {}'.format(restExecutionFailures, maxRetries, errMsg) - - if restExecutionFailures < maxRetries: - self.logError(errMsg) - restExecutionFailures += 1 - time.sleep(retryInterval) - continue - - if restExecutionFailures == maxRetries: - raise IxNetRestApiException(errMsg) + ignoreError: (bool): True: Don't raise an exception. + False: The response will be returned. + maxRetries: : The maximum amount of GET retries before declaring as server + connection failure + Note: + This API is not needed in RestPY, Added pass to avoid exception + """ + pass def delete(self, restApi, data={}, headers=None, maxRetries=5): """ @@ -587,43 +304,12 @@ def delete(self, restApi, data={}, headers=None, maxRetries=5): restApi: (str): The REST API URL. data: (dict): The data payload for the URL. headers: (str): The headers to use for the URL. - maxRetries: : The maximum amount of GET retries before declaring as server connection failure. - """ - if headers != None: - self.jsonHeader = headers - - retryInterval = 3 - restExecutionFailures = 0 - while True: - self.logInfo('\n\tDELETE: {0}\n\tDATA: {1}'.format(restApi, data)) - - try: - response = self._session.request('DELETE', restApi, data=json.dumps(data), headers=self.jsonHeader, allow_redirects=True, - verify=self.verifySslCert) - - for redirectStatus in response.history: - if '307' in str(response.history): - self.logInfo('\t{0}: {1}'.format(redirectStatus, response.url), timestamp=False) - - self.logInfo('\tSTATUS CODE: %s' % response.status_code, timestamp=False) - if not str(response.status_code).startswith('2'): - self.showErrorMessage() - errMsg = 'DELETE Exception error: {0}\n'.format(response.text) - self.logError(errMsg) - raise IxNetRestApiException(errMsg) - return response - - except (requests.exceptions.RequestException, Exception) as errMsg: - errMsg = 'DELETE Exception error {}/{} retries: {}\n'.format(restExecutionFailures, maxRetries, errMsg) - - if restExecutionFailures < maxRetries: - self.logError(errMsg) - restExecutionFailures += 1 - time.sleep(retryInterval) - continue - - if restExecutionFailures == maxRetries: - raise IxNetRestApiException(errMsg) + maxRetries: : The maximum amount of GET retries before declaring as server + connection failure. + Note: + This API is not needed in RestPY, Added pass to avoid exception + """ + pass def getDate(self): dateAndTime = str(datetime.datetime.now()).split(' ') @@ -646,105 +332,29 @@ def getSelfObject(self): def createWindowsSession(self, ixNetRestServerIp, ixNetRestServerPort='11009'): """ Description - Connect to a Windows IxNetwork API Server. This is - for both Windows and Windows server with IxNetwork Connection Manager. - This will set up the session URL to use throughout the test. + Connect to a Windows IxNetwork API Server. This is for both Windows and Windows server + with IxNetwork Connection Manager. This will set up the session URL to use throughout + the test. Parameter - ixNetRestServerIp: (str): The Windows IxNetwork API Server IP address. - ixNetRestServerPort: (str): Default: 11009. Provide a port number to connect to. - On a Linux API Server, a socket port is not needed. State "None". + ixNetRestServerIp: (str): The Windows IxNetwork API Server IP address + ixNetRestServerPort: (str): Default: 11009. Provide a port number to connect to. + On a Linux API Server, a socket port is not needed. State "None". + Note: + This API is not needed in RestPY, since class constructor is handling creation of + sessions """ - # Handle __import__(IxNetRestApi) to not error out - if ixNetRestServerIp == None: return - - url = '{0}://{1}:{2}/api/v1/sessions'.format(self.httpScheme, ixNetRestServerIp, ixNetRestServerPort) - - if self.serverOs == 'windowsConnectionMgr': - try: - self.logInfo('Please wait while IxNetwork Connection Mgr starts up an IxNetwork session...') - self.logInfo('\t{}'.format(url), timestamp=False) - response = self._session.request('POST', url, data={}, verify=self.verifySslCert, allow_redirects=True) - - except requests.exceptions.RequestException as errMsg: - errMsg = 'Creating new session failed: {0}'.format(errMsg) - raise IxNetRestApiException(errMsg) - - sessionIdNumber = response.json()['links'][0]['href'].split('/')[-1] - response = self._session.request('GET', url+'/'+str(sessionIdNumber), verify=self.verifySslCert, allow_redirects=False) - - if str(response.status_code).startswith('3'): - # >= 8.50 - self.httpScheme = 'https' - # https://192.168.70.3:443/api/v1/sessions/8020 - self.sessionId = response.headers['location'] - match = re.match('https://.*:([0-9]+)/api.*', self.sessionId) - ixNetRestServerPort = match.group(1) - else: - # < 8.50 - self.sessionId = url + '/'+str(sessionIdNumber) - - self.sessionUrl = '{httpScheme}://{apiServer}:{port}/api/v1/sessions/{id}/ixnetwork'.format( - httpScheme=self.httpScheme, - apiServer=ixNetRestServerIp, - port=ixNetRestServerPort, - id=sessionIdNumber) - - counterStop = 10 - for counter in range(1, counterStop+1): - response = self.get(self.sessionId) - if type(response.json()) == list: - currentState = response.json()[0]['state'] - else: - currentState = response.json()['state'] - - self.logInfo('\n\tNew Windows session current state: {0}'.format(currentState), timestamp=False) - if currentState != 'ACTIVE' and counter < counterStop: - self.logInfo('\tWaiting {0}/{1} seconds'.format(counter, counterStop), timestamp=False) - time.sleep(1) - - if currentState != 'ACTIVE' and counter == counterStop: - raise IxNetRestApiException('New Windows session state failed to become ACTVIE state') - - if currentState == 'ACTIVE' and counter < counterStop: - break - - # Version < 8.50 requires more waiting time. And we cannot verify the version number at this point. - time.sleep(25) - - if self.serverOs == 'windows': - # windows sessionId is always 1 because it only supports one session. - self.sessionUrl = url + '/1/ixnetwork' - - try: - self.logInfo('\nVerifying API server connection: {}'.format(self.sessionUrl)) - response = self._session.request('GET', self.sessionUrl, allow_redirects=False, verify=self.verifySslCert) - if '307' in str(response.status_code) and response.headers['location'].startswith('https'): - # Overwrite the sessionUrl with the redirected https URL - self.sessionUrl = response.headers['location'] - - except requests.exceptions.RequestException as errMsg: - errMsg = 'Connection failed: {0}'.format(errMsg) - raise IxNetRestApiException(errMsg) - - # http://192.168.70.127:11009/api/v1/sessions/1 - self.sessionId = self.sessionUrl.split('/ixnetwork')[0] - - # http://192.168.70.127:11009 - self.httpHeader = self.sessionUrl.split('/api')[0] - - # /api/v1/sessions/{id}/ixnetwork - self.apiSessionId = '/api/v1/sessions/{0}/ixnetwork'.format(str(self.sessionId)) - - self.get(self.sessionUrl) + pass def deleteSession(self): """ Description - Delete the instance session ID. For Linux and Windows Connection Manager only. + Delete the instance session ID. + For Linux and Windows Connection Manager only. """ if self.deleteSessionAfterTest: - self.delete(self.sessionId) + session = self.testPlatform.Sessions.find(Id=self.sessionId) + session.remove() def logInfo(self, msg, end='\n', timestamp=True): """ @@ -759,13 +369,12 @@ def logInfo(self, msg, end='\n', timestamp=True): if timestamp: msg = '\n' + currentTime + ': ' + msg else: - # No timestamp and no newline are mainly for verifying states and status msg = msg print('{0}'.format(msg), end=end) if self.generateLogFile: with open(self.restLogFile, 'a') as restLogFile: - restLogFile.write(msg+end) + restLogFile.write(msg + end) if self.robotFrameworkStdout: self.robotStdout.log_to_console(msg) @@ -783,13 +392,12 @@ def logWarning(self, msg, end='\n', timestamp=True): if timestamp: msg = '\n{0}: Warning: {1}'.format(currentTime, msg) else: - # No timestamp and no newline are mainly for verifying states and status msg = msg print('{0}'.format(msg), end=end) if self.generateLogFile: with open(self.restLogFile, 'a') as restLogFile: - restLogFile.write('Warning: '+msg+end) + restLogFile.write('Warning: ' + msg + end) if self.robotFrameworkStdout: self.robotStdout.log_to_console(msg) @@ -807,13 +415,12 @@ def logError(self, msg, end='\n', timestamp=True): if timestamp: msg = '\n{0}: Error: {1}'.format(currentTime, msg) else: - # No timestamp and no newline are mainly for verifying states and status msg = '\nError: {0}'.format(msg) print('{0}'.format(msg), end=end) if self.generateLogFile: with open(self.restLogFile, 'a') as restLogFile: - restLogFile.write('Error: '+msg+end) + restLogFile.write('Error: ' + msg + end) if self.robotFrameworkStdout: self.robotStdout.log_to_console(msg) @@ -823,11 +430,9 @@ def getIxNetworkVersion(self): Description Get the IxNetwork version. - Syntax - GET: /api/v1/sessions/{id}/globals """ - response = self.get(self.sessionUrl+'/globals', silentMode=True) - return response.json()['buildNumber'] + buildNumber = self.ixNetwork.Globals.BuildNumber + return buildNumber def getAllSessionId(self): """ @@ -846,23 +451,14 @@ def getAllSessionId(self): 'userName': 'admin'} } """ - response = self.get(self.httpHeader+'/api/v1/sessions', silentMode=True) sessionId = {} - for eachSessionId in response.json(): - sessionId.update({eachSessionId['id']: {'userName': eachSessionId['userName'], - 'createdOn': eachSessionId['createdOn'].replace('T', ' '), - 'state': eachSessionId['state'], - 'subState': eachSessionId['subState'] - } - }) - - print('\nSessionId: {}'.format(eachSessionId['id'])) - print(' UserName: {}'.format(eachSessionId['userName'])) - print(' StartedOn: {}'.format(eachSessionId['createdOn'].replace('T', ' '))) - print(' State: {}'.format(eachSessionId['state'])) - print(' SubState: {}'.format(eachSessionId['subState'])) + sessions = self.testPlatform.Sessions.find() + for session in sessions: + sessionId.update({session.Id: { + 'state': session.State, + 'UserName': session.UserName + }}) - print() return sessionId def showErrorMessage(self, silentMode=False): @@ -873,99 +469,56 @@ def showErrorMessage(self, silentMode=False): Parameter silentMode: (bool): True: Don't print the REST API on stdout. - Syntax - GET: /api/v1/sessions/{id}/globals/appErrors/error """ errorList = [] - response = self.get(self.sessionUrl+'/globals/appErrors/error', silentMode=silentMode) + errorObj = self.ixNetwork.Globals.AppErrors.find().Error.find() + print() - for errorId in response.json(): - if errorId['errorLevel'] == 'kError': - print('CurrentErrorMessage: {0}'.format(errorId['name'])) - print('\tDescription: {0}'.format(errorId['lastModified'])) - errorList.append(errorId['name']) + for errorId in errorObj: + if errorId.ErrorLevel == 'kError': + print('CurrentErrorMessage: {0}'.format(errorId.Name)) + print('\tDescription: {0}'.format(errorId.LastModified)) + errorList.append(errorId.Name) print() return errorList - def waitForComplete(self, response='', url='', silentMode=False, ignoreException=False, httpAction='get', timeout=90): + def waitForComplete(self, response='', url='', silentMode=False, ignoreException=False, + httpAction='get', timeout=90): """ Description Wait for an operation progress to complete. Parameters - response: (json response/dict): The POST action response. Generally, after an /operations action. - Such as /operations/startallprotocols, /operations/assignports. + response: (json response/dict): The POST action response. Generally, after an + /operations action. Such as /operations/startallprotocols, + /operations/assignports. silentMode: (bool): If True, display info messages on stdout. - ignoreException: (bool): ignoreException is for assignPorts. Don't want to exit test. - Verify port connectionStatus for: License Failed and Version Mismatch to report problem immediately. + ignoreException: (bool): ignoreException is for assignPorts. Don't want to exit test. + Verify port connectionStatus for: License Failed and Version Mismatch to + report problem immediately. - httpAction: (get|post): Defaults to GET. For chassisMgmt, it uses POST. + httpAction: (get|post): Defaults to GET. + For chassisMgmt, it uses POST. timeout: (int): The time allowed to wait for success completion in seconds. + Note: + This API is not needed in RestPY, Added pass to avoid exception """ - if silentMode == False: - self.logInfo('\nwaitForComplete:', timestamp=False) - self.logInfo("\tState: %s " % response.json()["state"], timestamp=False) - - if response.json() == []: - raise IxNetRestApiException('waitForComplete: response is empty.') - - if response.json() == '' or response.json()['state'] == 'SUCCESS': - return response - - if 'errors' in response.json(): - raise IxNetRestApiException(response.json()["errors"][0]) - - if response.json()['state'] in ["ERROR", "EXCEPTION"]: - raise IxNetRestApiException('WaitForComplete: STATE=%s: %s' % (response.json()['state'], response.text)) - - for counter in range(1,timeout+1): - if httpAction == 'get': - response = self.get(url, silentMode=True) - if httpAction == 'post': - response = self.post(url, silentMode=True) - - state = response.json()["state"] - if silentMode == False: - if state != 'SUCCESS': - self.logInfo("\tState: {0}: Wait {1}/{2} seconds".format(state, counter, timeout), timestamp=False) - if state == 'SUCCESS': - self.logInfo("\tState: {0}".format(state), timestamp=False) - - if counter < timeout and state in ["IN_PROGRESS", "down"]: - time.sleep(1) - continue - - if counter < timeout and state in ["ERROR", "EXCEPTION"]: - # ignoreException is for assignPorts. Don't want to exit test. - # Verify port connectionStatus for: License Failed and Version Mismatch to report problem immediately. - if ignoreException: - return response - raise IxNetRestApiException(response.text) - - if counter < timeout and state == 'SUCCESS': - return response - - if counter == timeout and state != 'SUCCESS': - if ignoreException: - return response - raise IxNetRestApiException('waitForComplete failed: %s' % response.json()) + pass def connectToLinuxIxosChassis(self, chassisIp, username, password): - url = 'https://{0}/platform/api/v1/auth/session'.format(chassisIp) - response = self.post(url, data={'username': username, 'password': password}) - self.apiKey = response.json()['apiKey'] - self.jsonHeader = {'content-type': 'application/json', 'x-api-key': self.apiKey} - - # userAccountUrl: https://{ip}/platform/api/v1/auth/users/{id} - self.userSessionId = response.json()['userAccountUrl'] + """ + Description + Connect to a Linux IxOS Chassis - self.ixosHeader = 'https://{0}/chassis/api/v2/ixos'.format(chassisIp) - self.chassisPlatformHeader = 'https://{0}/platform/api/v2'.format(chassisIp) - self.diagnosticsHeader = 'https://{0}/chassis/api/v1/diagnostics'.format(chassisIp) - self.authenticationHeader = 'https://{0}/chassis/api/v1/auth'.format(chassisIp) - self.sessionUrl = self.ixosHeader + Parameters + chassisIp: The Linux chassis IP address + username: Login username. + password: Login password + """ + self.ixNetwork.ConnectToChassis(Arg1=chassisIp) - def connectToLinuxApiServer(self, linuxServerIp, linuxServerIpPort, username='admin', password='admin', verifySslCert=False, timeout=120): + def connectToLinuxApiServer(self, linuxServerIp, linuxServerIpPort, username='admin', + password='admin', verifySslCert=False, timeout=120): """ Description Connect to a Linux API server. @@ -974,69 +527,15 @@ def connectToLinuxApiServer(self, linuxServerIp, linuxServerIpPort, username='ad linuxServerIp: (str): The Linux API server IP address. username: (str): Login username. Default = admin. password: (str): Login password. Default = admin. - verifySslCert: (str): Default: None. The SSL Certificate for secure access verification. + verifySslCert: (str): Default: None. The SSL Certificate for secure access verification. timeout: (int): Default:120. The timeout to wait for the Linux API server to start up. - Problem: In case the linux api server is installed in a chassis and the DNS is misconfigured, - it takes longer to start up. + Problem: In case the linux api server is installed in a chassis and + the DNS is misconfigured, it takes longer to start up. - Syntax - POST: /api/v1/auth/session + Note: + This API is not needed in RestPY,as RestPy API is already available """ - self.verifySslCert = verifySslCert - - if self.apiKey is None: - # 1: Connect to the Linux API server - url = 'https://{0}:{1}/api/v1/auth/session'.format(linuxServerIp, linuxServerIpPort) - self.logInfo('connectToLinuxApiServer: %s' % url) - response = self.post(url, data={'username': username, 'password': password}, ignoreError=True) - if not str(response.status_code).startswith('2'): - raise IxNetRestApiException('\nLogin username/password failed\n') - self.apiKey = response.json()['apiKey'] - - url = 'https://{0}:{1}/api/v1/sessions'.format(linuxServerIp, linuxServerIpPort) - if self.webQuickTest == False: - data = {'applicationType': 'ixnrest'} - if self.webQuickTest == True: - data = {'applicationType': 'ixnetwork'} - - self.jsonHeader = {'content-type': 'application/json', 'x-api-key': self.apiKey} - self.logInfo('linuxServerCreateSession') - response = self.post(url, data=data, headers=self.jsonHeader) - - self.sessionIdNumber = response.json()['id'] - response = self.get(url+'/'+str(self.sessionIdNumber)) - - # https://192.168.70.108/ixnetworkweb/api/v1/sessions/7 - self.sessionId = response.json()['links'][0]['href'] - # Remove the redirect /ixnetworkweb from the URL. IxNetwork 8.50 will resolve this. - self.sessionId = self.sessionId.replace('ixnetworkweb/', '') - - # https://10.10.10.1:443 - matchHeader = re.match('(https://[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+(:[0-9]+)?)', self.sessionId) - self.httpHeader = matchHeader.group(1) - - if ':' not in self.httpHeader: - self.httpHeader + '/' + linuxServerIpPort - - self.sessionUrl = self.sessionId+'/ixnetwork' - - # /api/v1/sessions/4/ixnetwork - match = re.match('.*(/api.*)', self.sessionId) - self.apiSessionId = match.group(1) + '/ixnetwork' - - # 3: Start the new session - response = self.post(self.sessionId+'/operations/start') - if self.linuxServerWaitForSuccess(response.json()['url'], timeout=timeout) == 1: - raise IxNetRestApiException - - if self.webQuickTest == True: - self.sessionId = 'https://{0}/ixnetworkweb/api/v1/sessions/{1}'.format(linuxServerIp, self.sessionIdNumber) - self.sessionUrl = 'https://{0}/ixnetworkweb/api/v1/sessions/{1}/ixnetwork'.format(linuxServerIp, self.sessionIdNumber) - self.httpHeader = self.sessionUrl.split('/api')[0] - - # If an API-Key is provided, then verify the session ID connection. - if self.apiKey: - self.get(self.sessionId) + pass def linuxServerGetGlobalLicense(self, linuxServerIp): """ @@ -1046,20 +545,11 @@ def linuxServerGetGlobalLicense(self, linuxServerIp): Paramters linuxServerIp: (str): The IP address of the Linux API server. - Syntax - GET: /api/v1/sessions/9999/ixnetworkglobals/license - """ - staticUrl = 'https://{linuxServerIp}/api/v1/sessions/9999/ixnetworkglobals/license'.format(linuxServerIp=linuxServerIp) - self.logInfo('linuxServerGetGlobalLicense: %s ' % linuxServerIp) - response = self.get(staticUrl, silentMode=False) - licenseServerIp = response.json()['servers'][0] - licenseServerMode = response.json()['mode'] - licenseServerTier = response.json()['tier'] - self.logInfo('linuxServerGetGlobalLicenses:') - self.logInfo('\t%s' % licenseServerIp) - self.logInfo('\t%s' % licenseServerMode) - self.logInfo('\t%s' % licenseServerTier) - return licenseServerIp,licenseServerMode,licenseServerTier + """ + licenseServerIp = self.ixNetwork.Globals.Licensing.LicensingServers + licenseServerMode = self.ixNetwork.Globals.Licensing.Mode + licenseServerTier = self.ixNetwork.Globals.Licensing.Tier + return licenseServerIp, licenseServerMode, licenseServerTier def configLicenseServerDetails(self, licenseServer=None, licenseMode=None, licenseTier=None): """ @@ -1071,19 +561,17 @@ def configLicenseServerDetails(self, licenseServer=None, licenseMode=None, licen licenseMode: (str): subscription | perpetual | mixed licenseTier: (str): tier1 | tier2 | tier3 ... - Syntax - PATCH: /api/v1/sessions/{id}/ixnetwork/globals/licensing """ - # Each new session requires configuring the new session's license details. - data = {} + # Each new session requires configuring the + # new session's license details. + if licenseServer: - data.update({'licensingServers': licenseServer}) + self.ixNetwork.Globals.Licensing.LicensingServers = [licenseServer] if licenseMode: - data.update({'mode': licenseMode}) + self.ixNetwork.Globals.Licensing.Mode = licenseMode if licenseTier: - data.update({'tier': licenseTier}) + self.ixNetwork.Globals.Licensing.Tier = licenseTier - response = self.patch(self.sessionUrl+'/globals/licensing', data=data) self.showLicenseDetails() def showLicenseDetails(self): @@ -1091,40 +579,36 @@ def showLicenseDetails(self): Description Display the new session's license details. - Syntax - GET: /api/v1/sessions/{id}/globals/licensing """ - response = self.get(self.sessionUrl+'/globals/licensing') - self.logInfo('\nVerifying sessionId license server: %s' % self.sessionUrl, timestamp=False) - self.logInfo('\t%s' % response.json()['licensingServers'], timestamp=False) - self.logInfo('\t%s'% response.json()['mode'], timestamp=False) - self.logInfo('\t%s' % response.json()['tier'], timestamp=False) + self.logInfo('\nVerifying sessionId license server: %s' % self.ixNetwork.href, + timestamp=False) + self.logInfo('\tLicensce Servers: %s' % self.ixNetwork.Globals.Licensing.LicensingServers, + timestamp=False) + self.logInfo('\tLicensing Mode: %s' % self.ixNetwork.Globals.Licensing.Mode, + timestamp=False) + self.logInfo('\tTier Level: %s' % self.ixNetwork.Globals.Licensing.Tier, timestamp=False) def getAllOpenSessionIds(self): """ Description Get a list of open session IDs and some session metas. - - Syntax - GETE: /api/v1/sessions Return A dict - """ - response = self.get(self.sessionUrl) - sessionIdDict = {} + activeSessionDict = {} + availableSessions = self.testPlatform.Sessions.find() - for session in response.json(): - href = session['links'][0]['href'] - id = session['id'] - username = session['userName'] - state = session['state'] - createOn = session['createdOn'] - - sessionIdDict[id] = {'id': id, 'sessionIdUrl': href, 'username': username, 'state': state, 'createdOn': createOn} - - return sessionIdDict + for session in availableSessions: + if session.State == 'ACTIVE': + activeSessionDict.update({session.Id: {'id': session.Id, + 'sessionIdUrl': session.href, + 'username': session.UserName, + 'state': session.State + } + } + ) + return activeSessionDict def linuxServerStopAndDeleteSession(self): """ @@ -1135,10 +619,9 @@ def linuxServerStopAndDeleteSession(self): linuxServerStopOperations() linuxServerDeleteSession() - Syntax - GET = /api/v1/sessions/{id} """ - if self.serverOs == 'linux' and self.deleteSessionAfterTest==True: + + if self.serverOs == 'linux' and self.deleteSessionAfterTest: self.linuxServerStopOperations() self.linuxServerDeleteSession() @@ -1153,17 +636,13 @@ def linuxServerStopOperations(self, sessionId=None): Requirement self.linuxServerWaitForSuccess() - Syntax - POST: /api/v1/sessions/{id}/operations/stop """ - if sessionId != None: + if sessionId is not None: sessionId = sessionId else: sessionId = self.sessionId - - response = self.post(sessionId+'/operations/stop') - if self.linuxServerWaitForSuccess(response.json()['url'], timeout=90) == 1: - raise IxNetRestApiException + print("removing sesionId", sessionId) + self.testPlatform.Sessions.find(Id=sessionId).remove() def linuxServerDeleteSession(self, sessionId=None): """ @@ -1173,15 +652,12 @@ def linuxServerDeleteSession(self, sessionId=None): Paramter sessionId: (str): The session ID to delete on the Linux API server. - Syntax - DELETE: /api/v1/sessions/{id}/operations/stop """ - if sessionId != None: + if sessionId is not None: sessionId = sessionId else: sessionId = self.sessionId - - response = self.delete(sessionId) + self.testPlatform.Sessions.find(Id=sessionId).remove() def linuxServerWaitForSuccess(self, url, timeout=120): """ @@ -1192,21 +668,29 @@ def linuxServerWaitForSuccess(self, url, timeout=120): url: (str): The URL's ID of the operation to verify. timeout: (int): The timeout value. """ - data = {'applicationType': 'ixnrest'} - jsonHeader = {'content-type': 'application/json', 'x-api-key': self.apiKey} - self.logInfo('linuxServerWaitForSuccess') - for counter in range(1,timeout+1): - response = self.get(url, data=data, silentMode=True) - currentStatus = response.json()['message'] - self.logInfo('\tCurrentStatus: {0}: {1}/{2} seconds'.format(currentStatus, counter, timeout), timestamp=False) - if counter < timeout+1 and currentStatus != 'Operation successfully completed': - time.sleep(1) + foundUrl = False + session = None + availableSessions = self.testPlatform.Sessions.find() + for session in availableSessions: + if url in session.href: + foundUrl = True + break + + if foundUrl: + for counter in range(1, timeout + 1): + currentStatus = session.State + self.logInfo('\tCurrentStatus: {0}: {1}/{2} seconds. SessionId {3}'.format( + currentStatus, counter, timeout, session.Id), timestamp=False) + if counter < timeout + 1 and currentStatus != 'ACTIVE': + time.sleep(1) - if counter == timeout+1 and currentStatus != 'Operation successfully completed': - return 1 + if counter == timeout + 1 and currentStatus != 'ACTIVE': + return 1 - if counter < timeout+1 and currentStatus == 'Operation successfully completed': - return 0 + if counter < timeout + 1 and currentStatus == 'ACTIVE': + return 0 + else: + self.logInfo('\tUrl not found {0}'.format(url)) def newBlankConfig(self): """ @@ -1216,13 +700,8 @@ def newBlankConfig(self): Requirement self.waitForComplete() - Syntax: - /api/v1/sessions/{1}/ixnetwork/operations/newconfig """ - url = self.sessionUrl+'/operations/newconfig' - response = self.post(url) - url = self.sessionUrl+'/operations/newconfig/'+response.json()['id'] - self.waitForComplete(response, url) + self.ixNetwork.NewConfig() def refreshHardware(self, chassisObj): """ @@ -1231,16 +710,12 @@ def refreshHardware(self, chassisObj): Parameter chassisObj: (str):The chassis object. - Ex: /api/v1/sessions/{1}/ixnetwork/availableHardware/chassis/1 Requirement self.waitForComplete() - Syntax - /api/v1/sessions/{1}/ixnetwork/availableHardware/chassis/operations/refreshinfo """ - response = self.post(self.sessionUrl+'/availableHardware/chassis/operations/refreshinfo', data={'arg1': [chassisObj]}) - self.waitForComplete(response, self.sessionUrl+'/availableHardware/chassis/operations/refreshinfo') + chassisObj.RefreshInfo() def query(self, data, silentMode=False): """ @@ -1251,80 +726,81 @@ def query(self, data, silentMode=False): silentMode: (bool): True: Don't display any output on stdout. Notes - Assuming this is a BGP configuration, which has two Topologies. - Below demonstrates how to query the BGP host object by - drilling down the Topology by its name and the specific the BGP attributes to modify at the - BGPIpv4Peer node: flap, downtimeInSec, uptimeInSec. - The from '/' is the entry point to the API tree. - Notice all the node. This represents the API tree from the / entry point and starting at - Topology level to the BGP host level. - - Notes - Use the API Browser tool on the IxNetwork GUI to view the API tree. - data: {'from': '/', - 'nodes': [{'node': 'topology', 'properties': ['name'], 'where': [{'property': 'name', 'regex': 'Topo1'}]}, - {'node': 'deviceGroup', 'properties': [], 'where': []}, - {'node': 'ethernet', 'properties': [], 'where': []}, - {'node': 'ipv4', 'properties': [], 'where': []}, - {'node': 'bgpIpv4Peer', 'properties': ['flap', 'downtimeInSec', 'uptimeInSec'], 'where': []}] - } + Assuming this is a BGP configuration, which has two Topologies. Below demonstrates + how to query the BGP host object by drilling down the Topology by its name and the + specific the BGP attributes to modify at the BGPIpv4Peer node: flap, downtimeInSec, + uptimeInSec. The from '/' is the entry point to the API tree. Notice all the node. + This represents the API tree from the / entry point and starting at Topology level to + the BGP host level. Requirements self.waitForComplete() Examples - response = restObj.query(data=queryData) - bgpHostAttributes = response.json()['result'][0]['topology'][0]['deviceGroup'][0]['ethernet'][0]['ipv4'][0]['bgpIpv4Peer'][0] - # GET THE BGP ATTRIBUTES TO MODIFY bgpHostFlapMultivalue = bgpHostAttributes['flap'] bgpHostFlapUpTimeMultivalue = bgpHostAttributes['uptimeInSec'] bgpHostFlapDownTimeMultivalue = bgpHostAttributes['downtimeInSec'] - restObj.configMultivalue(bgpHostFlapMultivalue, multivalueType='valueList', data={'values': ['true', 'true']}) - restObj.configMultivalue(bgpHostFlapUpTimeMultivalue, multivalueType='singleValue', data={'value': '60'}) - restObj.configMultivalue(bgpHostFlapDownTimeMultivalue, multivalueType='singleValue', data={'value': '30'}) + restObj.configMultivalue(bgpHostFlapMultivalue, multivalueType='valueList', + data={'values': ['true', 'true']}) + restObj.configMultivalue(bgpHostFlapUpTimeMultivalue, multivalueType='singleValue', + data={'value': '60'}) + restObj.configMultivalue(bgpHostFlapDownTimeMultivalue, multivalueType='singleValue', + data={'value': '30'}) + Note: + This API is not needed in RestPY, Added pass to avoid exception """ - url = self.sessionUrl+'/operations/query' - reformattedData = {'selects': [data]} - response = self.post(url, data=reformattedData, silentMode=silentMode) - self.waitForComplete(response, url+'/'+response.json()['id'], silentMode=silentMode) - return response + pass def select(self, data): """ Description Using the Select operation to query for objects using filters. + + Note: + This API is not needed in RestPY, Added pass to avoid exception """ - url = self.sessionUrl+'/operations/select' - response = self.post(url, data=data) - self.waitForComplete(response, url+'/'+response.json()['id']) - return response - + pass + def configMultivalue(self, multivalueUrl, multivalueType, data): """ Description Configure multivalues. Parameters - multivalueUrl: (str): The multivalue: /api/v1/sessions/{1}/ixnetwork/multivalue/1 + multivalueUrl: (str): The multivalue multivalueType: (str): counter|singleValue|valueList data: (dict): singleValue: data={'value': '1.1.1.1'}) - valueList: data needs to be in a [list]: data={'values': [list]} - counter: data={'start': value, 'direction': increment|decrement, 'step': value} - """ - if multivalueType == 'counter': - # Examples: macAddress = {'start': '00:01:01:00:00:01', 'direction': 'increment', 'step': '00:00:00:00:00:01'} - # data=macAddress) - self.patch(self.httpHeader+multivalueUrl+'/counter', data=data) - - if multivalueType == 'singleValue': - # data={'value': value} - self.patch(self.httpHeader+multivalueUrl+'/singleValue', data=data) - - if multivalueType == 'valueList': - # data={'values': ['item1', 'item2']} - self.patch(self.httpHeader+multivalueUrl+'/valueList', data=data) + valueList:data needs to be in a [list]: data={'values': [list]} + counter:data={'start': value, 'direction': increment|decrement, + 'step': value} + """ + if multivalueType.lower() == "counter": + if data['direction'] == "increment": + multivalueUrl.Increment(start_value=data['start'], step_value=data['step']) + if data['direction'] == "decrement": + multivalueUrl.Decrement(start_value=data['start'], step_value=data['step']) + elif multivalueType.lower() == "singlevalue": + multivalueUrl.Single(data['value']) + elif multivalueType.lower() == "valuelist": + multivalueUrl.ValueList(data['values']) + elif multivalueType.lower() == "randomrange": + multivalueUrl.RandomRange(min_value=data['min_value'], max_value=data['max_value'], + step_value=data['step_value'], seed=data['seed']) + elif multivalueType.lower() == "custom": + multivalueUrl.Custom(start_value=data['start_value'], step_value=data['step_value'], + increments=data['increments']) + elif multivalueType.lower() == "alternate": + multivalueUrl.Alternate(data['alternating_value']) + elif multivalueType.lower() == "distributed": + multivalueUrl.Distributed(algorithm=data['algorithm'], mode=data['mode'], + values=data['values']) + elif multivalueType.lower() == "randommask": + multivalueUrl.RandomMask(fixed_value=data['fixed_value'], mask_value=data['mask_value'], + seed=data['seed'], count=data['count']) + elif multivalueType.lower() == "string": + multivalueUrl.String(string_pattern=data['string_pattern']) def getMultivalueValues(self, multivalueObj, silentMode=False): """ @@ -1332,23 +808,17 @@ def getMultivalueValues(self, multivalueObj, silentMode=False): Get the multivalue values. Parameters - multivalueObj: (str): The multivalue object: /api/v1/sessions/{1}/ixnetwork/multivalue/208 - silentMode: (bool): True=Display the GET and status code. False=Don't display. + multivalueObj: : The multivalue object + silentMode: : True=Display the GET and status code. + False=Don't display. Requirements - self.waitForComplete() + self.ixnObj.waitForComplete() + + Return + The multivalue values """ - response = self.get(self.httpHeader+multivalueObj+'?includes=count', silentMode=silentMode) - count = response.json()['count'] - if silentMode == False: - self.logInfo('getMultivalueValues: {0} Count={1}'.format(multivalueObj, count)) - data = {'arg1': multivalueObj, - 'arg2': 0, - 'arg3': count - } - response = self.post(self.sessionUrl+'/multivalue/operations/getValues', data=data, silentMode=silentMode) - self.waitForComplete(response, self.sessionUrl+'/operations/multivalue/getValues'+response.json()['id']) - return response.json()['result'] + return multivalueObj.Values def getObjAttributeValue(self, obj, attribute): """ @@ -1357,35 +827,29 @@ def getObjAttributeValue(self, obj, attribute): Parameter obj: : An object handle: - For example: If you want the ethernet MTU, then pass in the ethernet object handle: - /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id} - and set attribute='mtu' Note: Where to get the object's attribute names: - Use the API browser and go to your object. - All the attributes are listed on the right pane. """ - response = self.get(self.httpHeader + obj) - - # value: Could be /api/v1/sessions/{id}/ixnetwork/multivalue/{id} or the actual value - value = response.json()[attribute] - if type(value) == str and 'multivalue' in value: - multivalueObj = value - value = self.getMultivalueValues(multivalueObj) - return value - else: + try: + attribute = attribute[0].capitalize() + attribute[1:] + value = eval("obj." + attribute) + values = self.getMultivalueValues(value) + return values + except AttributeError: + value = getattr(obj, attribute) return value def stdoutRedirect(self): """ Description - For Robot Framework. Robot captures the stdout. This stdoutRedirect - will redirect the output back to stdout so you could see the test progress - and to troubleshoot. + For Robot Framework. Robot captures the stdout. This stdoutRedirect will redirect the + output back to stdout so you could see the test progress and to troubleshoot. """ for attr in ('stdin', 'stdout', 'stderr'): - setattr(sys, attr, getattr(sys, '__%s__' %attr)) + setattr(sys, attr, getattr(sys, '__%s__' % attr)) @staticmethod def prettyprintAllOperations(sessionUrl): @@ -1393,20 +857,10 @@ def prettyprintAllOperations(sessionUrl): Description A staticmethod to rendering a nice output of an operations options and descriptions. - Parameter - sessionUrl: (str): http://{apiServerIp}:{port}/api/v1/sessions/1/ixnetwork - - Syntax: - /api/v1/sessions/{1}/ixnetwork/operations + Note: + This API is not needed in RestPY, Added pass to avoid exception """ - response = self._session.request('GET', sessionUrl+'/operations') - for item in response.json(): - if 'operation' in item.keys(): - print('\n', item['operation']) - print('\t%s' % item['description']) - if 'args' in item.keys(): - for nestedKey,nestedValue in item['args'][0].items(): - print('\t\t%s: %s' % (nestedKey, nestedValue)) + pass @staticmethod def printDict(obj, nested_level=0, output=sys.stdout): @@ -1417,27 +871,29 @@ def printDict(obj, nested_level=0, output=sys.stdout): spacing = ' ' spacing2 = ' ' if type(obj) == dict: - print( '%s' % ((nested_level) * spacing), file=output) + print('%s' % (nested_level * spacing), file=output) for k, v in obj.items(): if hasattr(v, '__iter__'): - print('%s%s:' % ( (nested_level+1) * spacing, k), file=output, end='') - IxNetRestMain.printDict(v, nested_level+1, output) + print('%s%s:' % ((nested_level + 1) * spacing, k), file=output, end='') + Connect.printDict(v, nested_level + 1, output) else: - print('%s%s: %s' % ( (nested_level + 1) * spacing, k, v), file=output) + print('%s%s: %s' % ((nested_level + 1) * spacing, k, v), file=output) print('%s' % (nested_level * spacing), file=output) elif type(obj) == list: - print('%s[' % ((nested_level) * spacing), file=output) + print('%s[' % (nested_level * spacing), file=output) for v in obj: if hasattr(v, '__iter__'): - IxNetRestMain.printDict(v, nested_level + 1, file=output) + Connect.printDict(v, nested_level + 1, output) else: print('%s%s' % ((nested_level + 1) * spacing, v), file=output) - print('%s]' % ((nested_level) * spacing), output) + print('%s]' % (nested_level * spacing), output) else: - print('%s%s' % ((nested_level * spacing2), obj), file=output) + print('%s%s' % ((nested_level * spacing2), obj), output) - def placeholder(): + def placeholder(self): + """ + Note: + This API is not needed in RestPY, Added pass to avoid exception + """ pass - - diff --git a/RestApi/Python/Modules/IxNetRestApiClassicProtocol.py b/RestApi/Python/Modules/IxNetRestApiClassicProtocol.py index 7f2af3ac..c9bb241a 100644 --- a/RestApi/Python/Modules/IxNetRestApiClassicProtocol.py +++ b/RestApi/Python/Modules/IxNetRestApiClassicProtocol.py @@ -1,14 +1,18 @@ # PLEASE READ DISCLAIMER # -# This class demonstrates sample IxNetwork REST API usage for -# demo and reference purpose only. -# It is subject to change for updates without warning. +# This class demonstrates sample IxNetwork REST PY usage for demo and +# reference purpose only.It is subject to change for updates without +# warning. # # Description # A class object for IxNetwork Classic Framework. +import re +import time from IxNetRestApi import IxNetRestApiException -import requests, json, os, re, sys, time, datetime, ast +from IxNetRestApiPortMgmt import PortMgmt +from IxNetRestApiStatistics import Statistics + class ClassicProtocol(object): def __init__(self, ixnObj=None): @@ -17,11 +21,8 @@ def __init__(self, ixnObj=None): ixnObj: : The main connection object. """ self.ixnObj = ixnObj - - from IxNetRestApiPortMgmt import PortMgmt + self.ixNetwork = ixnObj.ixNetwork self.portMgmtObj = PortMgmt(self.ixnObj) - - from IxNetRestApiStatistics import Statistics self.statObj = Statistics(self.ixnObj) def getPortsByProtocol(self, protocolName): @@ -31,35 +32,26 @@ def getPortsByProtocol(self, protocolName): Parameters protocolName options: - bfd, bgp, cfm, eigrp, elmi, igmp, isis, lacp, ldp, linkOam, lisp, mld, - mplsOam, mplsTp, openFlow, ospf, ospfV3, pimsm, ping, rip, ripng, rsvp, - static, stp + bfd, bgp, cfm, eigrp, elmi, igmp, isis, lacp, ldp, linkOam, lisp, mld, mplsOam, + mplsTp, openFlow, ospf, ospfV3, pimsm, ping, rip, ripng, rsvp, static, stp Returns: [chassisIp, cardNumber, portNumber] - Example: [['192.168.70.11', '1', '1'], ['192.168.70.11', '1', '2']] + Example: [['192.168.70.11', '1', '1'],['192.168.70.11', '1', '2']] Returns [] if no port is configured with the specified protocolName """ portList = [] - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/vport') - # ['http://{apiServerIp:port}/api/v1/sessions/1/ixnetwork/vport/1'] - vportList = ['%s/%s/%s' % (self.ixnObj.sessionUrl, 'vport', str(i["id"])) for i in response.json()] - - # Go through each port that has the protocol enabled. + vportList = self.ixNetwork.Vport.find() for vport in vportList: - # http://{apiServerIp:port}/api/v1/sessions/1/ixnetwork/vport/1/protocols/ospf - currentProtocol = vport+'/protocols/'+protocolName - response = self.ixnObj.get(currentProtocol) - if response.json()['enabled'] == True: - # 192.168.70.11:1:5 - response = self.ixnObj.get(vport) - assignedTo = response.json()['assignedTo'] - currentChassisIp = str(assignedTo.split(':')[0]) - currentCardNumber = str(assignedTo.split(':')[1]) - currentPortNumber = str(assignedTo.split(':')[2]) + protocol = protocolName[0].capitalize() + protocolName[1:] + protocolObj = getattr(vport.Protocols.find(), protocol) + if protocolObj.Enabled: + assignedTo = vport.AssignedTo + currentChassisIp = assignedTo.split(':')[0] + currentCardNumber = assignedTo.split(':')[1] + currentPortNumber = assignedTo.split(':')[2] currentPort = [currentChassisIp, currentCardNumber, currentPortNumber] portList.append(currentPort) - return portList def getProtocolListByPort(self, port): @@ -68,39 +60,24 @@ def getProtocolListByPort(self, port): Get all enabled protocols by the specified port. Parameters - port: [chassisIp, cardNumber, portNumber] -> ['192.168.70.11', '2', '8'] + port: [chassisIp, cardNumber, portNumber] ->['192.168.70.11', '2', '8'] """ self.ixnObj.logInfo('\ngetProtocolListByPort...') + protocolList = ['bfd', 'bgp', 'cfm', 'eigrp', 'elmi', 'igmp', 'isis', 'lacp', 'ldp', + 'linkOam', 'lisp', 'mld', 'mplsOam', 'mplsTp', 'openFlow', 'ospf', 'ospfV3', + 'pimsm', 'ping', 'rip', 'ripng', 'rsvp', 'stp'] + self.ixnObj.logInfo('\ngetProtocolListByPort...') chassis = str(port[0]) card = str(port[1]) port = str(port[2]) - specifiedPort = [chassis, card, port] + portObj = chassis + ":" + card + ":" + port enabledProtocolList = [] - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/vport') - vportList = ['%s/%s/%s' % (self.ixnObj.sessionUrl, 'vport', str(i["id"])) for i in response.json()] - for vport in vportList: - response = self.ixnObj.get(vport, 'assignedTo') - # 192.168.70.11:1:5 - assignedTo = response.json()['assignedTo'] - currentChassisIp = str(assignedTo.split(':')[0]) - currentCardNumber = str(assignedTo.split(':')[1]) - currentPortNumber = str(assignedTo.split(':')[2]) - currentPort = [currentChassisIp, currentCardNumber, currentPortNumber] - if currentPort != specifiedPort: - continue - else: - response = self.ixnObj.get(vport+'/protocols?links=true') - if response.status_code == 200: - #print 'json', response.json()['links'] - for protocol in response.json()['links']: - currentProtocol = protocol['href'] - url = self.ixnObj.httpHeader+currentProtocol - response = self.ixnObj.get(url) - if 'enabled' in response.json() and response.json()['enabled'] == True: - # Exclude ARP object - if 'arp' not in currentProtocol: - enabledProtocolList.append(str(currentProtocol)) - + vport = self.ixNetwork.Vport.find(AssignedTo=portObj) + for protocol in protocolList: + currentProtocol = protocol[0].capitalize() + protocol[1:] + protocolObj = getattr(vport.Protocols.find(), currentProtocol) + if protocolObj.Enabled: + enabledProtocolList.append(str(protocol)) return enabledProtocolList def sendArpOnPort(self, portName): @@ -111,20 +88,13 @@ def sendArpOnPort(self, portName): Parameters portName: : Name of the port. eg: '1/1/11' - Syntax - POST: http://10.154.162.94:11009/api/v1/sessions/1/ixnetwork/vport/operations/sendarp - DATA: {"arg1": "/api/v1/sessions/1/ixnetwork/vport/1"} - Examples sendArpOnPort(portName='1/1/11') """ vport = self.portMgmtObj.getVportObjectByName(portName) - if vport == None: + if vport is None: raise IxNetRestApiException('PortName {0} not connected to chassis'.format(portName)) - - url = self.ixnObj.sessionUrl + '/vport/operations/sendarp' - response = self.ixnObj.post(url, data={'arg1': vport}) - self.ixnObj.waitForComplete(response, url + '/' + response.json()['id']) + vport.SendArp() def getDiscoverdNeighborOnPort(self, portName): """ @@ -134,9 +104,6 @@ def getDiscoverdNeighborOnPort(self, portName): Parameters portName: : Name of the port. eg: '1/1/11' - Syntax - GET: http://10.154.162.94:11009/api/v1/sessions/1/ixnetwork/vport/1/discoveredNeighbor/1 - Examples getDiscoverdNeighborOnPort(portName='1/1/11') @@ -144,18 +111,11 @@ def getDiscoverdNeighborOnPort(self, portName): Discovered mac address """ vport = self.portMgmtObj.getVportObjectByName(portName) - if vport == None: + if vport is None: raise IxNetRestApiException('PortName {0} not connected to chassis'.format(portName)) - - url = vport + '/discoveredNeighbor' - response = self.ixnObj.get(url) - - url = self.ixnObj.httpHeader + response.json()[0]['links'][0]['href'] - response = self.ixnObj.get(url) - - self.ixnObj.logInfo('Discovered Neighbor: %s' % response.json()['neighborMac']) - return response.json()['neighborMac'] - + discoveredNeighborMac = vport.DiscoveredNeighbor.find().NeighborMac + self.ixnObj.logInfo('Discovered Neighbor: %s' % discoveredNeighborMac) + return discoveredNeighborMac def startStopProtocolOnPort(self, protocol, portName, action='start'): """ @@ -167,23 +127,19 @@ def startStopProtocolOnPort(self, protocol, portName, action='start'): portName: : Name of the port, eg: '1/1/11' action: : start or stop a protocol, default is start - Syntax - POST: /api/v1/sessions/{id}/ixnetwork/vport/protocols/ - DATA: {'args': 'api/v1/sessions/1/ixnetwork/vport/1'} - Examples startStopProtocolOnPort(protocol='ospf', portName='1/1/11') startStopProtocolOnPort(protocol='ospf', portName='1/1/11', action='stop') - """ vport = self.portMgmtObj.getVportObjectByName(portName) - if vport == None: + if vport is None: raise IxNetRestApiException('PortName {0} not connected to chassis'.format(portName)) - - url = self.ixnObj.sessionUrl + '/vport/protocols/' + protocol + '/operations/' + action - vport = vport + '/protocols/' + protocol - response = self.ixnObj.post(url, data={'arg1': vport}) - self.ixnObj.waitForComplete(response, url + '/' + response.json()['id']) + protocol = protocol[0].capitalize() + protocol[1:] + protocolObj = getattr(vport.Protocols.find(), protocol) + if action == "start": + protocolObj.Start() + if action == "stop": + protocolObj.Stop() def getConfiguredProtocols(self): """ @@ -194,26 +150,33 @@ def getConfiguredProtocols(self): A list or one or more congfigured protocols eg: "['ospf','bgp']" return [] if no protocol is configured """ - time.sleep(5) configuredProtocolList = [] - protocolList = ['bfd', 'bgp', 'eigrp', 'isis', 'ldp', 'lisp', - 'mplsOam', 'mplsTp', 'ospf', 'ospfV3', 'pimsm', - 'rip', 'ripng'] - response = self.ixnObj.get(self.ixnObj.sessionUrl + '/vport') - if response == False: + availableProtocolList = ['bfd', 'bgp', 'cfm', 'eigrp', 'elmi', 'igmp', 'isis', 'lacp', + 'ldp', 'linkOam', 'lisp', 'mld', 'mplsOam', 'mplsTp', 'openFlow', + 'ospf', 'ospfV3', 'pimsm', 'ping', 'rip', 'ripng', 'rsvp', 'stp'] + vportList = self.ixNetwork.Vport.find() + if not vportList: raise IxNetRestApiException('No ports connected to chassis') - vportList = ['%s' % vport['links'][0]['href'] for vport in response.json()] + protocolNextNodeDict = {'bgp': 'NeighborRange', 'igmp': 'Host', 'mld': 'Host', + 'stp': 'Bridge', 'cfm': 'Bridge', 'rsvp': 'NeighborPair', + 'lacp': 'Link', 'linkOam': 'Link', 'elmi': 'Uni', + 'openFlow': 'Device'} + protocols = ['bgp', 'igmp', 'mld', 'stp', 'cfm', 'rsvp', 'lacp', 'linkOam', 'elmi', + 'openFlow'] for eachVport in vportList: - for eachProtocol in protocolList: - node = '/router' - if re.search('bgp', eachProtocol, re.I): - node = '/neighborRange' - protocolResponse = self.ixnObj.get(self.ixnObj.httpHeader + eachVport + '/protocols/' + eachProtocol) - response = self.ixnObj.get(self.ixnObj.httpHeader + eachVport + '/protocols/' + eachProtocol + node) - if response.json() != []: - if response.json()[0]['enabled'] == True and protocolResponse.json()['runningState'] == 'started': - configuredProtocolList.append(eachProtocol) + for protocol in availableProtocolList: + if protocol in protocols: + nextNode = protocolNextNodeDict[protocol] + else: + nextNode = 'Router' + protocol = protocol[0].capitalize() + protocol[1:] + protocolResponse = getattr(eachVport.Protocols.find(), protocol) + nextNodeObj = getattr(protocolResponse, nextNode) + routerInstancesObj = nextNodeObj.find() + if routerInstancesObj: + if routerInstancesObj.Enabled and protocolResponse.RunningState == 'started': + configuredProtocolList.append(protocol) configuredProtocolList = list(set(configuredProtocolList)) return configuredProtocolList @@ -225,31 +188,22 @@ def enableProtocolOnPort(self, protocol, portName, enable=True): Parameters protocol: : Protocol to start portName: : Name of the port eg: '1/1/11' - enable: enable or disable specified protocol. default is True - - Syntax - PATCH: /api/v1/sessions/{id}/ixnetwork/vport/{id}/protocols//router/{id} - PATCH: /api/v1/sessions/{id}/ixnetwork/vport/{id}/protocols//neighborRange/{id} - PATCH: /api/v1/sessions/{id}/ixnetwork/vport/{id}/protocols//host/{id} - PATCH: /api/v1/sessions/{id}/ixnetwork/vport/{id}/protocols//bridge/{id} - PATCH: /api/v1/sessions/{id}/ixnetwork/vport/{id}/protocols//actor/{id} - PATCH: /api/v1/sessions/{id}/ixnetwork/vport/{id}/protocols//neighborPair/{id} + enable: enable or disable specified protocol. Examples enableProtocolOnPort(protocol='ospf', portName='1/1/11') enableProtocolOnPort(protocol='ospf', portName='1/1/11', enable=False) """ vport = self.portMgmtObj.getVportObjectByName(portName) - if vport == None: + if vport is None: raise IxNetRestApiException('PortName {0} not connected to chassis'.format(portName)) RouterInstanceList = self.getRouterInstanceByPortAndProtocol(protocol=protocol, vport=vport) - if RouterInstanceList == []: - raise IxNetRestApiException('No Router instance exists in protocol {0}'.format(protocol)) - + if not RouterInstanceList: + raise IxNetRestApiException('No Router instance exists in protocol {0}'.format( + protocol)) for eachRouterInstance in RouterInstanceList: - url = self.ixnObj.httpHeader + eachRouterInstance - self.ixnObj.patch(url, data={"enabled": enable}) + eachRouterInstance.Enabled = enable def getProtocolSessionsStats(self, portName, protocol): """ @@ -257,8 +211,8 @@ def getProtocolSessionsStats(self, portName, protocol): Get a protocol session status for a specified protocol on a port Parameters - portName: : Name of the Port to get the protocol session stats eg: "1/1/11" - protocol: : Name of the protocol. eg: + portName: : Name of the Port eg: "1/1/11" + protocol: : Name of the protocol. eg: Examples getProtocolSessionsStats(portName='1/1/11', protocol='ospf') @@ -268,83 +222,115 @@ def getProtocolSessionsStats(self, portName, protocol): """ protocolStats = {} vport = self.portMgmtObj.getVportObjectByName(portName) - if vport == None: + if vport is None: raise IxNetRestApiException('PortName {0} not connected to chassis'.format(portName)) - - node = '/router' - if re.search('bgp', protocol, re.I): - node = '/neighborRange' - protocolResponse = self.ixnObj.get(vport + '/protocols/' + protocol) - response = self.ixnObj.get(vport + '/protocols/' + protocol + node) - - if response.json() != []: - if response.json()[0]['enabled'] == True and protocolResponse.json()['runningState'] == 'started': - if re.search('ospf', protocol, re.I): - protocolViewName = 'OSPF Aggregated Statistics' - elif re.search('ospfV3', protocol, re.I): + protocolNextNodeDict = {'bgp': 'NeighborRange', 'igmp': 'Host', 'mld': 'Host', + 'stp': 'Bridge', 'cfm': 'Bridge', 'rsvp': 'NeighborPair', 'lacp': + 'Link', 'linkOam': 'Link', 'elmi': 'Uni', 'openFlow': 'Device'} + protocols = ['bgp', 'igmp', 'mld', 'stp', 'cfm', 'rsvp', 'lacp', 'linkOam', 'elmi', + 'openFlow'] + if protocol in protocols: + nextNode = protocolNextNodeDict[protocol] + else: + nextNode = 'Router' + protocol = protocol[0].capitalize() + protocol[1:] + protocolResponse = getattr(vport.Protocols.find(), protocol) + nextNodeObj = getattr(protocolResponse, nextNode) + routerInstancesObj = nextNodeObj.find() + + if routerInstancesObj: + if routerInstancesObj.Enabled and (protocolResponse.RunningState == 'started' or + protocolResponse.ProtocolState == 'started'): + if protocol in ['Bfd', 'Bgp', 'Cfm', 'Eigrp', 'Elmi', 'Igmp', 'Isis', 'Lacp', 'Ldp', + 'Lisp', 'Mld', 'MplsTp', 'MplsOam', 'Ospf', 'Rip', 'Rsvp', 'Stp']: + protocolViewName = protocol.upper() + 'Aggregated Statistics' + elif re.search('LinkOam', protocol, re.I): + protocolViewName = 'OAM Aggregated Statistics' + elif re.search('openFlow', protocol, re.I): + protocolViewName = 'OpenFlow Switch Aggregated Statistics' + elif re.search('OspfV3', protocol, re.I): protocolViewName = 'OSPFv3 Aggregated Statistics' - elif re.search('bgp', protocol, re.I): - protocolViewName = 'BGP Aggregated Statistics' - elif re.search('isis', protocol, re.I): - protocolViewName = 'ISIS Aggregated Statistics' - elif re.search('ripng', protocol, re.I): - protocolViewName = 'RIPng Aggregated Statistics' - elif re.search('bfd', protocol, re.I): - protocolViewName = 'BFD Aggregated Statistics' - elif re.search('rip', protocol, re.I): - protocolViewName = 'RIP Aggregated Statistics' - elif re.search('ldp', protocol, re.I): - protocolViewName = 'LDP Aggregated Statistics' - elif re.search('mplsoam', protocol, re.I): - protocolViewName = 'MPLSOAM Aggregated Statistics' - elif re.search('pim', protocol, re.I): + elif re.search('Pim', protocol, re.I): protocolViewName = 'PIMSM Aggregated Statistics' + elif re.search('Ripng', protocol, re.I): + protocolViewName = 'RIPng Aggregated Statistics' else: raise IxNetRestApiException('No viewName defined') else: - raise IxNetRestApiException('No {0} protocol running or enabled on port {1}'.format(protocol, portName)) + raise IxNetRestApiException('No {0} protocol running or enabled on port {1}'. + format(protocol, portName)) else: - raise IxNetRestApiException('No {0} protocol configured on port {1}'.format(protocol, portName)) + raise IxNetRestApiException('No {0} protocol configured on port {1}'.format(protocol, + portName)) stats = self.statObj.getStats(viewName=protocolViewName, displayStats=False) - - #totalPorts = len(stats.keys()); # Length stats.keys() represents total ports. self.ixnObj.logInfo('ProtocolViewName: {0}'.format(protocolViewName)) for session in stats.keys(): - if re.search('OSPF', protocolViewName, re.I): - sessionsUp = int(stats[session]['Full Nbrs.']) - totalSessions = int(stats[session]['Sess. Configured']) + if re.search('BFD', protocolViewName, re.I) or re.search('RIPng', protocolViewName, + re.I): + sessionsUp = int(stats[session]['Routers Running']) + totalSessions = int(stats[session]['Routers Configured']) elif re.search('BGP', protocolViewName, re.I): sessionsUp = int(stats[session]['Sess. Up']) totalSessions = int(stats[session]['Sess. Configured']) + elif re.search('CFM', protocolViewName, re.I): + sessionsUp = int(stats[session]['Bridges Running']) + totalSessions = int(stats[session]['Bridges Configured']) + elif re.search('EIGRP', protocolViewName, re.I) or re.search('ELMI', protocolViewName, + re.I): + sessionsUp = int(stats[session]['IPv4 Routers Running']) + totalSessions = int(stats[session]['IPv4 Routers Configured']) + elif re.search('IGMP', protocolViewName, re.I) or re.search('MLD', protocolViewName, + re.I): + sessionsUp = int(stats[session]['Host Total Frames Tx']) + totalSessions = int(stats[session]['Host Total Frames Rx']) elif re.search('ISIS', protocolViewName, re.I): sessionsUp = int(stats[session]['L2 Sess. Up']) totalSessions = int(stats[session]['L2 Sess. Configured']) - elif re.search('RIPng', protocolViewName, re.I) or re.search('BFD', protocolViewName, re.I): - sessionsUp = int(stats[session]['Routers Running']) - totalSessions = int(stats[session]['Routers Configured']) - elif re.search('RIP', protocolViewName, re.I): - sessionsUp = int(stats[session]['Request Packet Tx']) - totalSessions = int(stats[session]['Routers Configured']) elif re.search('LACP', protocolViewName, re.I): sessionsUp = int(stats[session]['LAG Member Ports UP']) totalSessions = int(stats[session]['Total LAG Member Ports']) elif re.search('LDP', protocolViewName, re.I): sessionsUp = int(stats[session]['Targeted Sess. Up']) totalSessions = int(stats[session]['Targeted Sess. Configured']) - elif re.search('MPLS', protocolViewName, re.I): + elif re.search('OAM', protocolViewName, re.I): + sessionsUp = int(stats[session]['Links Running']) + totalSessions = int(stats[session]['Links Configured']) + elif re.search('LISP', protocolViewName, re.I): + sessionsUp = int(stats[session]['MS/MR Running']) + totalSessions = int(stats[session]['MS/MR Configured']) + elif re.search('MPLSTP', protocolViewName, re.I): + sessionsUp = int(stats[session]['CCCV Up']) + totalSessions = int(stats[session]['CCCV Configured']) + elif re.search('MPLSOAM', protocolViewName, re.I): sessionsUp = int(stats[session]['BFD Up-Sessions']) totalSessions = int(stats[session]['BFD Session Count']) + elif re.search('OpenFlow', protocolViewName, re.I): + sessionsUp = int(stats[session]['OF Channel Configured Up']) + totalSessions = int(stats[session]['OF Channel Configured']) + elif re.search('OSPF', protocolViewName, re.I): + sessionsUp = int(stats[session]['Full Nbrs.']) + totalSessions = int(stats[session]['Sess. Configured']) elif re.search('PIM', protocolViewName, re.I): sessionsUp = int(stats[session]['Rtrs. Running']) totalSessions = int(stats[session]['Rtrs. Configured']) - # totalSessionsNotStarted = int(stats[session]['Sessions Not Started']) + elif re.search('RIP', protocolViewName, re.I): + sessionsUp = int(stats[session]['Request Packet Tx']) + totalSessions = int(stats[session]['Routers Configured']) + elif re.search('RSVP', protocolViewName, re.I): + sessionsUp = int(stats[session]['Ingress LSPs Up']) + totalSessions = int(stats[session]['Ingress LSPs Configured']) + elif re.search('STP', protocolViewName, re.I): + sessionsUp = int(stats[session]['Forwarding State Count']) + totalSessions = int(stats[session]['Discarding State Count']) else: raise IxNetRestApiException('No protocol viewName found') if stats[session]['Port Name'] == portName: - self.ixnObj.logInfo('\n\tPortName: {0}\n\t TotalSessionsUp: {1}\n\t TotalSessionsConfigured: {2}'.format( - stats[session]['Port Name'], sessionsUp, totalSessions), timestamp=False) + self.ixnObj.logInfo('\n\tPortName: {0}\n\t TotalSessionsUp: {1}\n\t ' + 'TotalSessionsConfigured: {2}'. + format(stats[session]['Port Name'], sessionsUp, totalSessions), + timestamp=False) protocolStats[protocol] = {'Configured': totalSessions, 'Up': sessionsUp} return protocolStats @@ -355,47 +341,41 @@ def enableRouteRangeOnProtocol(self, portName, protocol, routeRange, enable=True Parameters portName: : Name of the port eg: "1/1/11" - protocol: : protocol to enable route range. eg: + protocol: : protocol to enable route range. routeRange: : route range address - enable: : enable or disable route range, default is True (enable) - - Syntax - PATCH: /api/v1/sessions/{id}/ixnetwork/vport/{id}/protocols//router/{id}/routeRange/{id} - PATCH: /api/v1/sessions/{id}/ixnetwork/vport/{id}/protocols//neighborRange/{id}/routeRange/{id} + enable: : enable or disable route range, default is True Examples: enableRouteRangeOnProtocol(protName='1/1/11', protocol='ospf', routeRange='10.10.10.1') - enableRouteRangeOnProtocol(protName='1/1/11', protocol='ospfv3', routeRange='10::1', enable=True) + enableRouteRangeOnProtocol(protName='1/1/11', protocol='ospfv3', routeRange='10::1', + enable=True) """ vport = self.portMgmtObj.getVportObjectByName(portName) - if vport == None: + if vport is None: raise IxNetRestApiException('PortName {0} not connected to chassis'.format(portName)) RouterInstanceList = self.getRouterInstanceByPortAndProtocol(protocol=protocol, vport=vport) - if RouterInstanceList == []: - raise IxNetRestApiException('No Router instance exists in protocol {0}'.format(protocol)) + if not RouterInstanceList: + raise IxNetRestApiException('No Router instance exists in protocol {0}'. + format(protocol)) + argsDict = {'ospf': 'NetworkNumber', 'bgp': 'NetworkAddress'} - args = 'firstRoute' - if protocol == 'ospf': - args = 'networkNumber' - if protocol == 'bgp': - args = 'networkAddress' + if protocol in ['ospf', 'bgp']: + args = argsDict[protocol] + else: + args = 'firstRoute' for eachRouterInstance in RouterInstanceList: - url = self.ixnObj.httpHeader + eachRouterInstance + '/routeRange' - response = self.ixnObj.get(url) - RouteRangeInstanceList = ["%s" % (str(i["links"][0]["href"])) for i in response.json()] + RouteRangeInstanceList = eachRouterInstance.RouteRange.find() self.ixnObj.logInfo('Route Range list %s' % RouteRangeInstanceList) for eachRouteRange in RouteRangeInstanceList: - url = self.ixnObj.httpHeader + eachRouteRange - response = self.ixnObj.get(url) - RouteRangeNetwork = response.json()[args] + RouteRangeNetwork = getattr(eachRouteRange, args) if RouteRangeNetwork == routeRange: - self.ixnObj.patch(url, data={"enabled": enable}) + eachRouteRange.Enabled = enable return - raise IxNetRestApiException( - 'Route range: {0} does not exist in protocol: {1} port: {2}'.format(routeRange, protocol, portName)) + raise IxNetRestApiException('Route range: {0} does not exist in protocol: {1} port: {2}' + .format(routeRange, protocol, portName)) def removeRouteRangeOnProtocol(self, portName, protocol, routeRange): """ @@ -404,47 +384,40 @@ def removeRouteRangeOnProtocol(self, portName, protocol, routeRange): Parameters portName: : Name of the port eg: "1/1/11" - protocol: : protocol to remove route range. eg: + protocol: : protocol to remove route range. routeRange: : route range address - Syntax - DELETE: /api/v1/sessions/{id}/ixnetwork/vport/{id}/protocols//router/{id}/routeRange/{id} - DELETE: /api/v1/sessions/{id}/ixnetwork/vport/{id}/protocols//neighborRange/{id}/routeRange/{id} - Examples: removeRouteRangeOnProtocol(protName='1/1/11', protocol='ospf', routeRange='10.10.10.1') removeRouteRangeOnProtocol(protName='1/1/11', protocol='ospfv3', routeRange='10::1') """ vport = self.portMgmtObj.getVportObjectByName(portName) - if vport == None: + if vport is None: raise IxNetRestApiException('PortName {0} not connected to chassis'.format(portName)) RouterInstanceList = self.getRouterInstanceByPortAndProtocol(protocol=protocol, vport=vport) - if RouterInstanceList == []: - raise IxNetRestApiException('No Router instance exists in protocol {0}'.format(protocol)) + if not RouterInstanceList: + raise IxNetRestApiException('No Router instance exists in protocol {0}'.format( + protocol)) self.ixnObj.logInfo('Router list %s' % RouterInstanceList) - args = 'firstRoute' - if protocol == 'ospf': - args = 'networkNumber' - if protocol == 'bgp': - args = 'networkAddress' + argsDict = {'ospf': 'NetworkNumber', 'bgp': 'NetworkAddress'} + + if protocol in ['ospf', 'bgp']: + args = argsDict[protocol] + else: + args = 'firstRoute' for eachRouterInstance in RouterInstanceList: - url = self.ixnObj.httpHeader + eachRouterInstance + '/routeRange' - response = self.ixnObj.get(url) - RouteRangeInstanceList = ["%s" % (str(i["links"][0]["href"])) for i in response.json()] + RouteRangeInstanceList = eachRouterInstance.RouteRange.find() self.ixnObj.logInfo('Route Range list %s' % RouteRangeInstanceList) for eachRouteRange in RouteRangeInstanceList: - url = self.ixnObj.httpHeader + eachRouteRange - response = self.ixnObj.get(url) - RouteRangeNetwork = response.json()[args] + RouteRangeNetwork = getattr(eachRouteRange, args) if RouteRangeNetwork == routeRange: - self.ixnObj.delete(url) + eachRouteRange.remove() return - - raise IxNetRestApiException( - 'Route range: {0} does not exist in protocol: {1} port: {2}'.format(routeRange, protocol, portName)) + raise IxNetRestApiException('Route range: {0} does not exist in protocol: {1} port: {2}' + .format(routeRange, protocol, portName)) def createRouteRangeOnProtocol(self, portName, protocol, routeRange): """ @@ -453,53 +426,39 @@ def createRouteRangeOnProtocol(self, portName, protocol, routeRange): Parameters portName: : Name of the port eg: "1/1/11" - protocol: : protocol to create route range. eg: + protocol: : protocol to create route range. routeRange: : route range to configure address - eg: {'enabled': 'True', 'mask': 24, 'numberOfRoutes': 5, 'networkNumber': '8.7.7.1', 'metric': 10, 'origin': 'externalType1'} - {'enabled': 'True', 'maskWidth': 64, 'numberOfRoute': 10, 'firstRoute': '7::1', 'metric': 10, 'nextHop': '7::2'} - - Syntax - POST: /api/v1/sessions/{id}/ixnetwork/vport/{id}/protocols/ospf/router/{id}/routeRange/{id} - DATA: {'enabled': 'True', 'mask': 24, 'numberOfRoutes': 5, 'networkNumber': '7.7.7.1', 'metric': 10, 'origin': 'externalType1'} - - POST: /api/v1/sessions/{id}/ixnetwork/vport/{id}/protocols/ospfV3/router/{id}/routeRange/{id} - DATA: {'enabled': 'True', 'mask': 64, 'numberOfRoutes': 5, 'firstRoute': '7::1', 'metric': 10, 'type': 'anotherArea', 'addressFamily': 'unicast'} - - POST: /api/v1/sessions/{id}/ixnetwork/vport/{id}/protocols/eigrp/router/{id}/routeRange/{id} - DATA: {'enabled': 'True', 'mask': 24, 'numberOfRoutes': 10, 'firstRoute': '7.7.7.1', 'metric': 10, 'nextHop': '7.7.7.2'} - - POST: /api/v1/sessions/{id}/ixnetwork/vport/{id}/protocols/rip/router/{id}/routeRange/{id} - DATA: {'enabled': 'True', 'maskWidth': 24, 'noOfRoutes': 10, 'firstRoute': '7.7.7.1', 'metric': 10, 'nextHop': '7.7.7.2'} - - POST: /api/v1/sessions/{id}/ixnetwork/vport/{id}/protocols/ripng/router/{id}/routeRange/{id} - DATA: {'enabled': 'True', 'maskWidth': 64, 'numberOfRoute': 10, 'firstRoute': '7::1', 'metric': 10, 'nextHop': '7::2'} - - POST: /api/v1/sessions/{id}/ixnetwork/vport/{id}/protocols/bgp/neighborRange/{id}/routeRange/{id} - DATA: {'enabled': 'True', 'fromPrefix': 24, 'thruPrefix': 24, 'numRoutes': 10, 'networkAddress': '7.7.7.7'} - - POST: /api/v1/sessions/{id}/ixnetwork/vport/{id}/protocols/bgp/neighborRange/{id}/routeRange/{id} - DATA: {'enabled': 'True', 'fromPrefix': 64, 'thruPrefix': 64, 'numRoutes': 10, 'networkAddress': '7::1'} + eg: {'enabled': 'True', 'mask': 24, 'origin': 'externalType1', + 'networkNumber': '8.7.7.1', 'metric': 10, 'numberOfRoutes': 5} + {'enabled': 'True', 'maskWidth': 64, 'numberOfRoute': 10, 'firstRoute': '7::1', + 'metric': 10, 'nextHop': '7::2'} Examples - createRouteRangeOnProtocol(portName='1/1/11', protocol='ospf', routeRange={'enabled': 'True', 'mask': 24, - 'numberOfRoutes': 5, 'networkNumber': '8.7.7.1', - 'metric': 10, 'origin': 'externalType1'} - createRouteRangeOnProtocol(portName='1/1/11', protocol='ospf', routeRange={'networkNumber': '8.7.7.1'} + createRouteRangeOnProtocol(portName='1/1/11', protocol='ospf', + routeRange={'enabled': 'True', 'mask': 24, 'numberOfRoutes': 5, + 'networkNumber': '8.7.7.1', 'metric': 10, 'origin': 'externalType1'} + createRouteRangeOnProtocol(portName='1/1/11', protocol='ospf', + routeRange={'networkNumber': '8.7.7.1'} """ vport = self.portMgmtObj.getVportObjectByName(portName) - if vport == None: + if vport is None: raise IxNetRestApiException('PortName {0} not connected to chassis'.format(portName)) RouterInstanceList = self.getRouterInstanceByPortAndProtocol(protocol=protocol, vport=vport) - if RouterInstanceList == []: - raise IxNetRestApiException('No Router instance exists in protocol {0}'.format(protocol)) + if not RouterInstanceList: + raise IxNetRestApiException('No Router instance exists in protocol {0}'.format( + protocol)) self.ixnObj.logInfo('Router list %s' % RouterInstanceList) - #routeRange = ast.literal_eval(routeRange) for eachRouterInstance in RouterInstanceList: - url = self.ixnObj.httpHeader + eachRouterInstance + '/routeRange' - self.ixnObj.post(url, data=routeRange) + if not eachRouterInstance.RouteRange.find(): + routeRangeObj = eachRouterInstance.RouteRange.add() + else: + routeRangeObj = eachRouterInstance.RouteRange.find() + for key, value in routeRange: + key = key[0].capitalize() + key[1:] + setattr(routeRangeObj, key, value) def getRouterInstanceByPortAndProtocol(self, protocol, vport): """ @@ -508,38 +467,32 @@ def getRouterInstanceByPortAndProtocol(self, protocol, vport): Parameters protocol: : protocol to get a router instance - vport: : vport instance eg: "/api/v1/sessions/1/ixnetwork/vport/1" - - Syntax - GET: /api/v1/sessions/{id}/ixnetwork/vport/{id}/protocols//router - GET: /api/v1/sessions/{id}/ixnetwork/vport/{id}/protocols//neighborRange - GET: /api/v1/sessions/{id}/ixnetwork/vport/{id}/protocols//host - GET: /api/v1/sessions/{id}/ixnetwork/vport/{id}/protocols//bridge - GET: /api/v1/sessions/{id}/ixnetwork/vport/{id}/protocols//actor - GET: /api/v1/sessions/{id}/ixnetwork/vport/{id}/protocols//neighborPair + vport: : vport instance Examples - getRouterInstanceByPortAndProtocol(protocol='ospf', vport='/api/v1/sessions/1/ixnetwork/vport/1') + getRouterInstanceByPortAndProtocol(protocol='ospf', vport=vport object) Return RouterInstanceList Returns [] if no router instance exists """ - if protocol == 'bgp': - nextNode = '/neighborRange' - elif protocol == 'igmp' or protocol == 'mld': - nextNode = '/host' - elif protocol == 'stp': - nextNode = '/bridge' - elif protocol == 'rsvp': - nextNode = '/neighborPair' - elif protocol == 'lacp': - nextNode = '/link' + protocolNextNodeDict = {'bgp': 'NeighborRange', 'igmp': 'Host', 'mld': 'Host', + 'stp': 'Bridge', 'cfm': 'Bridge', 'rsvp': 'NeighborPair', + 'lacp': 'Link', 'linkOam': 'Link', 'elmi': 'Uni', + 'openFlow': 'Device'} + protocols = ['bgp', 'igmp', 'mld', 'stp', 'cfm', 'rsvp', 'lacp', 'linkOam', 'elmi', + 'openFlow'] + if protocol in protocols: + nextNode = protocolNextNodeDict[protocol] else: - nextNode = '/router' - url = vport+'/protocols/'+protocol+nextNode - response = self.ixnObj.get(url) - RouterInstanceList = ["%s" % (str(i["links"][0]["href"])) for i in response.json()] + nextNode = 'Router' + RouterInstanceList = [] + protocol = protocol[0].capitalize() + protocol[1:] + protocolObj = getattr(vport.Protocols.find(), protocol) + nextNodeObj = getattr(protocolObj, nextNode) + RouterInstancesList = nextNodeObj.find() + for eachRouterInstance in RouterInstancesList: + RouterInstanceList.append(eachRouterInstance) self.ixnObj.logInfo('Router Instance list %s' % RouterInstanceList) return RouterInstanceList @@ -549,8 +502,8 @@ def verifyProtocolSessionsUp(self, protocolViewName='BGP Peer Per Port', timeout Verify the specified protocol sessions are UP or not. Parameters - protocolViewName: : The protocol view name. Get this name from API browser or in IxNetwork GUI statistic tabs. - timeout: : Duration to wait for the protocol sessions to up. Default = 60 seconds. + protocolViewName: : The protocol view name. + timeout: : Duration to wait for the protocol sessions to up.Default = 60 seconds. protocolViewName options: 'BFD Aggregated Statistics' @@ -567,50 +520,81 @@ def verifyProtocolSessionsUp(self, protocolViewName='BGP Peer Per Port', timeout verifyProtocolSessionsUp(protcolViewName='ospf Aggregated Statistics') verifyProtocolSessionsUp(protcolViewName='ospf Aggregated Statistics',timeout=90) """ - totalSessionsDetectedUp = 0 - totalSessionsDetectedDown = 0 + totalSessions = 0 totalPortsUpFlag = 0 + totalExpectedSessionsUp = 0 + sessionsUp = 0 self.ixnObj.logInfo('Protocol view name %s' % protocolViewName) time.sleep(10) for counter in range(1, timeout + 1): stats = self.statObj.getStats(viewName=protocolViewName, displayStats=False) - totalPorts = len(stats.keys()) # Length stats.keys() represents total ports. + totalPorts = len(stats.keys()) self.ixnObj.logInfo('ProtocolName: {0}'.format(protocolViewName)) for session in stats.keys(): - if re.search('OSPF', protocolViewName, re.I): - sessionsUp = int(stats[session]['Full Nbrs.']) - totalSessions = int(stats[session]['Sess. Configured']) + if re.search('BFD', protocolViewName, re.I) or re.search('RIPng', protocolViewName, + re.I): + sessionsUp = int(stats[session]['Routers Running']) + totalSessions = int(stats[session]['Routers Configured']) elif re.search('BGP', protocolViewName, re.I): sessionsUp = int(stats[session]['Sess. Up']) totalSessions = int(stats[session]['Sess. Configured']) + elif re.search('CFM', protocolViewName, re.I): + sessionsUp = int(stats[session]['Bridges Running']) + totalSessions = int(stats[session]['Bridges Configured']) + elif re.search('EIGRP', protocolViewName, re.I) or \ + re.search('ELMI', protocolViewName, re.I): + sessionsUp = int(stats[session]['IPv4 Routers Running']) + totalSessions = int(stats[session]['IPv4 Routers Configured']) + elif re.search('IGMP', protocolViewName, re.I) or re.search('MLD', + protocolViewName, re.I): + sessionsUp = int(stats[session]['Host Total Frames Tx']) + totalSessions = int(stats[session]['Host Total Frames Rx']) elif re.search('ISIS', protocolViewName, re.I): sessionsUp = int(stats[session]['L2 Sess. Up']) totalSessions = int(stats[session]['L2 Sess. Configured']) - elif re.search('RIPng', protocolViewName, re.I) or re.search('BFD', protocolViewName, re.I): - sessionsUp = int(stats[session]['Routers Running']) - totalSessions = int(stats[session]['Routers Configured']) - elif re.search('RIP', protocolViewName, re.I): - sessionsUp = int(stats[session]['Request Packet Tx']) - totalSessions = int(stats[session]['Routers Configured']) elif re.search('LACP', protocolViewName, re.I): sessionsUp = int(stats[session]['LAG Member Ports UP']) totalSessions = int(stats[session]['Total LAG Member Ports']) elif re.search('LDP', protocolViewName, re.I): sessionsUp = int(stats[session]['Targeted Sess. Up']) totalSessions = int(stats[session]['Targeted Sess. Configured']) - elif re.search('MPLS', protocolViewName, re.I): + elif re.search('OAM', protocolViewName, re.I): + sessionsUp = int(stats[session]['Links Running']) + totalSessions = int(stats[session]['Links Configured']) + elif re.search('LISP', protocolViewName, re.I): + sessionsUp = int(stats[session]['MS/MR Running']) + totalSessions = int(stats[session]['MS/MR Configured']) + elif re.search('MPLSTP', protocolViewName, re.I): + sessionsUp = int(stats[session]['CCCV Up']) + totalSessions = int(stats[session]['CCCV Configured']) + elif re.search('MPLSOAM', protocolViewName, re.I): sessionsUp = int(stats[session]['BFD Up-Sessions']) totalSessions = int(stats[session]['BFD Session Count']) + elif re.search('OpenFlow', protocolViewName, re.I): + sessionsUp = int(stats[session]['OF Channel Configured Up']) + totalSessions = int(stats[session]['OF Channel Configured']) + elif re.search('OSPF', protocolViewName, re.I): + sessionsUp = int(stats[session]['Full Nbrs.']) + totalSessions = int(stats[session]['Sess. Configured']) elif re.search('PIM', protocolViewName, re.I): sessionsUp = int(stats[session]['Rtrs. Running']) totalSessions = int(stats[session]['Rtrs. Configured']) - # totalSessionsNotStarted = int(stats[session]['Sessions Not Started']) + elif re.search('RIP', protocolViewName, re.I): + sessionsUp = int(stats[session]['Request Packet Tx']) + totalSessions = int(stats[session]['Routers Configured']) + elif re.search('RSVP', protocolViewName, re.I): + sessionsUp = int(stats[session]['Ingress LSPs Up']) + totalSessions = int(stats[session]['Ingress LSPs Configured']) + elif re.search('STP', protocolViewName, re.I): + sessionsUp = int(stats[session]['Forwarding State Count']) + totalSessions = int(stats[session]['Discarding State Count']) totalExpectedSessionsUp = totalSessions if totalExpectedSessionsUp != 0: - self.ixnObj.logInfo( - '\n\tPortName: {0}\n\t TotalSessionsUp: {1}\n\t ExpectedTotalSessionsup: {2}'.format( - stats[session]['Port Name'], sessionsUp, totalExpectedSessionsUp), timestamp=False) + self.ixnObj.logInfo('\n\tPortName: {0}\n\t TotalSessionsUp: {1}\n\t ' + 'ExpectedTotalSessionsup: {2}'. + format(stats[session]['Port Name'], sessionsUp, + totalExpectedSessionsUp), timestamp=False) if counter < timeout and sessionsUp != totalExpectedSessionsUp: self.ixnObj.logInfo('\t Protocol Session is still down', timestamp=False) @@ -623,7 +607,8 @@ def verifyProtocolSessionsUp(self, protocolViewName='BGP Peer Per Port', timeout if counter == timeout and sessionsUp != totalExpectedSessionsUp: raise IxNetRestApiException('Protocol Sessions failed to come up') - self.ixnObj.logInfo('\n\tWait {0}/{1} seconds\n'.format(counter, timeout), timestamp=False) + self.ixnObj.logInfo('\n\tWait {0}/{1} seconds\n'.format(counter, timeout), + timestamp=False) time.sleep(1) def verifyAllConfiguredProtocolSessions(self, duration): @@ -638,32 +623,24 @@ def verifyAllConfiguredProtocolSessions(self, duration): verifyAllConfiguredProtocolSessions(duration=120) verifyAllConfiguredProtocolSessions(120) """ - response = self.getConfiguredProtocols() - if response == []: + confifuredProtocols = self.getConfiguredProtocols() + if not confifuredProtocols: raise IxNetRestApiException('No protocols Running or Configured or Enabled') - for eachProtocol in response: - if re.search('ospf', eachProtocol,re.I): - viewName = 'OSPF Aggregated Statistics' - elif re.search('ospfV3', eachProtocol,re.I): - viewName = 'OSPFv3 Aggregated Statistics' - elif re.search('bgp', eachProtocol,re.I): - viewName = 'BGP Aggregated Statistics' - elif re.search('isis', eachProtocol,re.I): - viewName = 'ISIS Aggregated Statistics' - elif re.search('ripng', eachProtocol,re.I): - viewName = 'RIPng Aggregated Statistics' - elif re.search('bfd', eachProtocol,re.I): - viewName = 'BFD Aggregated Statistics' - elif re.search('rip', eachProtocol,re.I): - viewName = 'RIP Aggregated Statistics' - elif re.search('ldp', eachProtocol,re.I): - viewName = 'LDP Aggregated Statistics' - elif re.search('mplsoam', eachProtocol,re.I): - viewName = 'MPLSOAM Aggregated Statistics' - elif re.search('pim', eachProtocol,re.I): - viewName = 'PIMSM Aggregated Statistics' + for protocol in confifuredProtocols: + if protocol in ['Bfd', 'Bgp', 'Cfm', 'Eigrp', 'Elmi', 'Igmp', 'Isis', 'Lacp', 'Ldp', + 'Lisp', 'Mld', 'MplsTp', 'MplsOam', 'Ospf', 'Rip', 'Rsvp', 'Stp']: + protocolViewName = protocol.upper() + 'Aggregated Statistics' + elif re.search('LinkOam', protocol, re.I): + protocolViewName = 'OAM Aggregated Statistics' + elif re.search('openFlow', protocol, re.I): + protocolViewName = 'OpenFlow Switch Aggregated Statistics' + elif re.search('OspfV3', protocol, re.I): + protocolViewName = 'OSPFv3 Aggregated Statistics' + elif re.search('Pim', protocol, re.I): + protocolViewName = 'PIMSM Aggregated Statistics' + elif re.search('Ripng', protocol, re.I): + protocolViewName = 'RIPng Aggregated Statistics' else: raise IxNetRestApiException('No viewName defined') - - self.verifyProtocolSessionsUp(protocolViewName=viewName, timeout=duration) + self.verifyProtocolSessionsUp(protocolViewName=protocolViewName, timeout=duration) diff --git a/RestApi/Python/Modules/IxNetRestApiFileMgmt.py b/RestApi/Python/Modules/IxNetRestApiFileMgmt.py index 37888c4d..41ccef76 100644 --- a/RestApi/Python/Modules/IxNetRestApiFileMgmt.py +++ b/RestApi/Python/Modules/IxNetRestApiFileMgmt.py @@ -1,5 +1,10 @@ -import sys, re, os, json, platform, io +import re +import os +import json from IxNetRestApi import IxNetRestApiException +from ixnetwork_restpy.files import Files +import datetime + class FileMgmt(object): def __init__(self, ixnObj=None): @@ -11,6 +16,7 @@ def __init__(self, ixnObj=None): ixnObj: (Object): The parent object. """ self.ixnObj = ixnObj + self.ixNetwork = ixnObj.ixNetwork def setMainObject(self, mainObject): """ @@ -29,301 +35,191 @@ def loadConfigFile(self, configFile, localFile=True): Parameters configFile: (str): The full path including the saved config filename. - If the config file is in a Windows filesystem, the format is c:\\path\\bgp.ixncfg - If you are executing the script from Linux and the config file is in local Linux filesystem, - the format is /path/bgp.ixncfg and localFile=True. - - localFile: (bool): For Windows API server and Connection Mgr running on a Windows server only. - Set to False if the config file is in the Windows API server filesystem. - """ - if localFile == False: - # The config file is located in Windows - fileName = configFile.split('\\')[-1] - copyFileUrl = self.ixnObj.sessionUrl+'/operations/copyfile' - destinationPath = '{0}/ixnetwork/files/'.format(self.ixnObj.headlessSessionId) + fileName - response = self.ixnObj.post(copyFileUrl,data={"arg1": configFile, "arg2": destinationPath}) - self.ixnObj.waitForComplete(response, self.ixnObj.httpHeader+'/'+response.json()['url'], silentMode=False, timeout=30) - - if localFile == True: - if os.path.exists(configFile) is False: - raise IxNetRestApiException("Config file doesn't exists: %s" % configFile) - - if self.ixnObj.serverOs == 'linux': - octetStreamHeader = {'content-type': 'application/octet-stream', 'x-api-key': self.ixnObj.apiKey} - else: - octetStreamHeader = {'content-type': 'application/octet-stream'} - - fileName = configFile.split('/')[-1] - - # Read the config file - self.ixnObj.logInfo('\nReading saved config file') - with open(configFile, mode='rb') as byteFile: - configContents = byteFile.read() - configContents = io.BytesIO(configContents) - - # Upload it to the server and give it any name you want for the filename - uploadFile = self.ixnObj.sessionUrl+'/files?filename='+fileName - self.ixnObj.logInfo('\nUploading file to server: %s' % uploadFile) - - # Note: - # There is no status checking for this POST. This command is synchronous. The server won't return until it's done. - # The response payload: {'absolute': None, 'files': [{'name': 'bgp_ngpf_8.30.ixncfg', 'length': 177791, 'modifiedUnixTime': 1572009307, - # 'createdUnixTime': 1568302806}], 'directories': []} - response = self.ixnObj.post(uploadFile, data=configContents, noDataJsonDumps=True, headers=octetStreamHeader, silentMode=False) - - loadConfigUrl = self.ixnObj.sessionUrl+'/operations/loadconfig' - - # Set the payload to load the given filename: /api/v1/sessions/{id}/ixnetwork/files/ospfNgpf_8.10.ixncfg - payload = {'arg1': '{0}/ixnetwork/files/{1}'.format(self.ixnObj.headlessSessionId, fileName)} - - # Tell the server to load the config file - if localFile == True: - response = self.ixnObj.post(loadConfigUrl, data=payload) - - if localFile == False: - response = self.ixnObj.post(loadConfigUrl, data=payload) - - self.ixnObj.waitForComplete(response, self.ixnObj.httpHeader+response.json()['url'], silentMode=False, timeout=140) - - def copyFileWindowsToRemoteWindows(self, windowsPathAndFileName, localPath, renameDestinationFile=None, includeTimestamp=False): + If the config file is in a Windows filesystem, the format is + c:\\path\\bgp.ixncfg + If you are executing the script from Linux and the config file is in + local Linux filesystem, the format is /path/bgp.ixncfg and + localFile=True. + + localFile: (bool): For Windows API server and Connection Mgr running on a Windows + server only. Set to False if the config file is in the Windows API server filesystem. + """ + + self.ixnObj.logInfo("Loading Config File {}".format(configFile)) + try: + self.ixNetwork.LoadConfig(Files(configFile, local_file=localFile)) + except Exception as err: + self.ixnObj.logInfo("Error with Load config {}".format(err)) + raise Exception("Failed to load config file {} ".format(configFile)) + + def copyFileWindowsToRemoteWindows(self, windowsPathAndFileName, localPath, + renameDestinationFile=None, includeTimestamp=False): """ Description Copy files from the IxNetwork API Server c: drive to local Linux filesystem. - The filename to be copied will remain the same filename unless you set renameDestinationFile to something you otherwise preferred. - You could also include a timestamp for the destination file. + The filename to be copied will remain the same filename unless you set + renameDestinationFile to something you otherwise preferred. You could also include a + timestamp for the destination file. Parameters - windowsPathAndFileName: (str): The full path and filename to retrieve from Windows API server. + windowsPathAndFileName: (str): The full path and filename to retrieve from Windows API + server. localPath: (str): The remote Windows destination path to put the file to. renameDestinationFile: (str): You could rename the destination file. - includeTimestamp: (bool): If False, each time you copy the same file will be overwritten. + includeTimestamp: (bool): If False, each time you copy the same file will be + overwritten. """ - import datetime - - self.ixnObj.logInfo('\ncopyFileWindowsToRemoteWindows: From: %s to %s\n' % (windowsPathAndFileName, localPath)) - windowsPathAndFileName = windowsPathAndFileName.replace('\\', '\\\\') + self.ixnObj.logInfo('\n copyFileWindowsToRemoteWindows: From: %s to %s\n' % + (windowsPathAndFileName, localPath)) fileName = windowsPathAndFileName.split('\\')[-1] fileName = fileName.replace(' ', '_') - # Default location: "C:\\Users\\\\AppData\\Local\\sdmStreamManager\\common" - destinationPath = '{0}/ixnetwork/files/'.format(self.ixnObj.headlessSessionId) + fileName - currentTimestamp = datetime.datetime.now().strftime('%H%M%S') - - # Step 1 of 2: - response = self.ixnObj.post(self.ixnObj.sessionUrl+'/operations/copyfile', - data={"arg1": windowsPathAndFileName, "arg2": destinationPath}) - - # curl http://{apiServerIp:port}/api/v1/sessions/1/ixnetwork/files/AggregateResults.csv -O -H "Content-Type: application/octet-stream" -output /home/hgee/AggregateResults.csv - # Step 2 of 2: - requestStatus = self.ixnObj.get(self.ixnObj.sessionUrl+'/files/%s' % (fileName), stream=True, ignoreError=True) - if requestStatus.status_code == 200: - if renameDestinationFile is not None: - fileName = renameDestinationFile - - contents = requestStatus.raw.read() - - if includeTimestamp: - tempFileName = fileName.split('.') - if len(tempFileName) > 1: - extension = fileName.split('.')[-1] - fileName = tempFileName[0]+'_' + currentTimestamp + '.' + extension - else: - fileName = tempFileName[0]+'_' + currentTimestamp - - localPath = localPath+'/'+fileName - else: - localPath = localPath+'/'+fileName + if renameDestinationFile: + fileName = renameDestinationFile - with open(localPath, 'wb') as downloadedFileContents: - downloadedFileContents.write(contents) + if includeTimestamp: + fileName = self._addTimestampToFile(fileName) - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/files') + destinationPath = localPath + '\\' + fileName - self.ixnObj.logInfo('\nA copy of your saved file/report is in:\n\t%s' % (windowsPathAndFileName)) - self.ixnObj.logInfo('\ncopyFileWindowsToLocalLinux: %s' % localPath) - else: - self.ixnObj.logInfo('\ncopyFileWindowsToLocalLinux Error: Failed to download file from IxNetwork API Server.') + try: + self.ixNetwork.CopyFile(windowsPathAndFileName, destinationPath) + except Exception as err: + self.ixnObj.logInfo("Error with file transfer {}".format(err)) + raise Exception("Copy File from {} to {} Failed".format(windowsPathAndFileName, + destinationPath)) - def copyFileWindowsToLocalLinux(self, windowsPathAndFileName, localPath, renameDestinationFile=None, includeTimestamp=False): + def copyFileWindowsToLocalLinux(self, windowsPathAndFileName, localPath, + renameDestinationFile=None, includeTimestamp=False): """ Description Copy files from the IxNetwork API Server c: drive to local Linux filesystem. - The filename to be copied will remain the same filename unless you set renameDestinationFile to something you otherwise preferred. - You could also include a timestamp for the destination file. + The filename to be copied will remain the same filename unless you set + renameDestinationFile to something you otherwise preferred. You could also include a + timestamp for the destination file. Parameters - windowsPathAndFileName: (str): The full path and filename to retrieve from Windows client. + windowsPathAndFileName: (str): The full path and filename to retrieve from Windows + client. localPath: (str): The Linux destination path to put the file to. renameDestinationFile: (str): You could rename the destination file. - includeTimestamp: (bool): If False, each time you copy the same file will be overwritten. - - Syntax - post: /api/v1/sessions/1/ixnetwork/operations/copyfile - data: {'arg1': windowsPathAndFileName, 'arg2': '/api/v1/sessions/1/ixnetwork/files/'+fileName'} + includeTimestamp: (bool): If False, each time you copy the same file will be + overwritten. """ - import datetime - self.ixnObj.logInfo('\ncopyFileWindowsToLocalLinux: From: %s to %s\n' % (windowsPathAndFileName, localPath)) + self.ixnObj.logInfo('\n copyFileWindowsToLocalLinux: From: %s to %s\n' % + (windowsPathAndFileName, localPath)) fileName = windowsPathAndFileName.split('\\')[-1] fileName = fileName.replace(' ', '_') - destinationPath = '{0}/ixnetwork/files/'.format(self.ixnObj.headlessSessionId) + fileName - currentTimestamp = datetime.datetime.now().strftime('%H%M%S') - - # Step 1 of 2: - url = self.ixnObj.sessionUrl+'/operations/copyfile' - response = self.ixnObj.post(url, - data={"arg1": windowsPathAndFileName, "arg2": destinationPath}) - # curl http://{apiServerIp:port}/api/v1/sessions/1/ixnetwork/files/AggregateResults.csv -O -H "Content-Type: application/octet-stream" -output /home/hgee/AggregateResults.csv - - # Step 2 of 2: - #requestStatus = self.ixnObj.get(self.ixnObj.sessionUrl+'/files/%s' % (fileName), stream=True, ignoreError=True) - url = self.ixnObj.sessionUrl+'/files?filename=%s' % (fileName) - requestStatus = self.ixnObj.get(url, stream=True, ignoreError=True) - if requestStatus.status_code == 200: - if renameDestinationFile is not None: - fileName = renameDestinationFile - - contents = requestStatus.raw.read() - if includeTimestamp: - tempFileName = fileName.split('.') - if len(tempFileName) > 1: - extension = fileName.split('.')[-1] - fileName = tempFileName[0]+'_' + currentTimestamp + '.' + extension - else: - fileName = tempFileName[0]+'_' + currentTimestamp + if renameDestinationFile: + fileName = renameDestinationFile - localPath = localPath+'/'+fileName - else: - localPath = localPath+'/'+fileName + if includeTimestamp: + fileName = self._addTimestampToFile(fileName) - with open(localPath, 'wb') as downloadedFileContents: - downloadedFileContents.write(contents) + destinationPath = localPath + '/' + fileName - self.ixnObj.logInfo('\nA copy of your saved file/report is in:\n\t%s' % (windowsPathAndFileName)) - self.ixnObj.logInfo('\ncopyFileWindowsToLocalLinux: %s' % localPath) - else: - self.ixnObj.logInfo('\ncopyFileWindowsToLocalLinux Error: Failed to download file from IxNetwork API Server.') + try: + self.ixNetwork.CopyFile(windowsPathAndFileName, destinationPath) + except Exception as err: + self.ixnObj.logInfo("Error with file transfer {}".format(err)) + raise Exception("\n copyFileWindowsToLocalLinux Error: Failed to download file from " + "IxNetwork API Server ") - def copyFileWindowsToLocalWindows(self, windowsPathAndFileName, localPath, renameDestinationFile=None, includeTimestamp=False): + def copyFileWindowsToLocalWindows(self, windowsPathAndFileName, localPath, + renameDestinationFile=None, includeTimestamp=False): """ Description Copy files from the Windows IxNetwork API Server to a local c: drive destination. - The filename to be copied will remain the same filename unless you set renameDestinationFile to something you otherwise preferred. - You could include a timestamp for the destination file. + The filename to be copied will remain the same filename unless you set + renameDestinationFile to something you otherwise preferred. You could include a + timestamp for the destination file. Parameters - windowsPathAndFileName: (str): The full path and filename to retrieve from Windows client. + windowsPathAndFileName: (str): The full path and filename to retrieve from Windows + client. localPath: (str): The Windows local filesystem. Ex: C:\\Results. renameDestinationFile: (str): You could name the destination file. - includeTimestamp: (bool): If False, each time you copy the same file will be overwritten. + includeTimestamp: (bool): If False, each time you copy the same file will be + overwritten. Example: - WindowsPathAndFileName = 'C:\\Users\\hgee\\AppData\\Local\\Ixia\\IxNetwork\\data\\result\\DP.Rfc2544Tput\\9e1a1f04-fca5-42a8-b3f3-74e5d165e68c\\Run0001\\TestReport.pdf' + WindowsPathAndFileName = 'C:\\Users\\hgee\\AppData\\Local\\Ixia\\IxNetwork\\data\\result + \\DP.Rfc2544Tput\\9e1a1f04-fca5-42a8-b3f3-74e5d165e68c\\Run0001\\TestReport.pdf' localPath = 'C:\\Results' """ - import datetime - - self.ixnObj.logInfo('\ncopyFileWindowsToLocalWindows: From: %s to %s\n' % (windowsPathAndFileName, localPath)) - self.ixnObj.logInfo('\nYou need to manually remove the saved copy in: %s' % windowsPathAndFileName) + self.ixnObj.logInfo('\n copyFileWindowsToLocalWindows: From: %s to %s\n\n' % + (windowsPathAndFileName, localPath)) fileName = windowsPathAndFileName.split('\\')[-1] + fileName = fileName.replace(' ', '_') if renameDestinationFile: fileName = renameDestinationFile - fileName = fileName.replace(' ', '_') if includeTimestamp: - currentTimestamp = datetime.datetime.now().strftime('%H%M%S') - tempFileName = fileName.split('.') - if len(tempFileName) > 1: - extension = fileName.split('.')[-1] - fileName = tempFileName[0]+'_' + currentTimestamp + '.' + extension - else: - fileName = tempFileName[0]+'_' + currentTimestamp + fileName = self._addTimestampToFile(fileName) - destinationPath = localPath+'\\'+fileName - response = self.ixnObj.post(self.ixnObj.sessionUrl+'/operations/copyfile', - data={"arg1": windowsPathAndFileName, "arg2": destinationPath}) + destinationPath = localPath + '\\' + fileName + self.ixnObj.logInfo('Copying from {} -> {}'.format(windowsPathAndFileName, destinationPath)) + self.ixNetwork.CopyFile(windowsPathAndFileName, destinationPath) - def copyFileLinuxToLocalLinux(self, linuxApiServerPathAndFileName, localPath, renameDestinationFile=None, - includeTimestamp=False, linuxApiServerPathExtension=None): + def _addTimestampToFile(self, filename): """ - Description - Copy files from Linux API Server to local Linux filesystem. - The filename to be copied will remain the same filename unless you set renameDestinationFile - to something you otherwise preferred. + Function used internally by API rfc2544_quicktest + :param filename: filename for which timestamp to be added + """ + currentTimestamp = datetime.datetime.now().strftime('%H%M%S') + if '\\' in filename: + filename = filename.split('\\')[-1] + + if '/' in filename: + filename = filename.split('/')[-1] + + newFilename = filename.split('.')[0] + newFileExtension = filename.split('.')[1] + newFileWithTimestamp = '{}_{}.{}'.format(newFilename, currentTimestamp, newFileExtension) + return newFileWithTimestamp + + def copyFileLinuxToLocalLinux(self, linuxApiServerPathAndFileName, localPath, + renameDestinationFile=None, includeTimestamp=False, + linuxApiServerPathExtension=None): + """ + Description + Copy files from Linux API Server to local Linux filesystem. The filename to be copied + will remain the same filename unless you set renameDestinationFile to something you + otherwise preferred. You could also include a timestamp for the destination file. Parameters linuxApiServerPathAndFileName: (str): The full path and filename to retrieve. - linuxApiServerPathExtension: (str): In a situation such as packet capture for Linux API server only, the - captured file is saved at 'captures//file. - Value example: 'captures/packetCaptureFolder/port2_HW.cap' - + linuxApiServerPathExtension: (str): Not using in Resrpy localPath: (str): The Linux destination path to put the file to. renameDestinationFile: (str): You could rename the destination file. - includeTimestamp: (bool): If False, each time you copy the same file will be overwritten. - - Syntax - post: /api/v1/sessions/1/ixnetwork/operations/copyfile - data: {'arg1': '/root/.local/share/Ixia/sdmStreamManager/common/bgpExportedConfigFile', - 'arg2': '/api/v1/sessions/1/ixnetwork/files/'+fileName'} + includeTimestamp: (bool): If False, each time you copy the same file will be + overwritten. """ - import datetime - self.ixnObj.logInfo('\ncopyFileLinuxToLocalLinux: From: %s to %s\n' % (linuxApiServerPathAndFileName, localPath)) + self.ixnObj.logInfo('\n copyFileLinuxToLocalLinux: From: %s to %s\n' % + (linuxApiServerPathAndFileName, localPath)) fileName = linuxApiServerPathAndFileName.split('/')[-1] fileName = fileName.replace(' ', '_') - - destinationPath = self.ixnObj.sessionUrl.split(self.ixnObj.httpHeader)[1] - destinationPath = destinationPath + '/files/' + fileName - currentTimestamp = datetime.datetime.now().strftime('%H%M%S') - - # Step 1 of 3: - url = self.ixnObj.sessionUrl+'/operations/copyfile' - response = self.ixnObj.post(url, data={"arg1": linuxApiServerPathAndFileName, "arg2": destinationPath}) - # Step 2 of 3: - if linuxApiServerPathExtension: - # Situations like packet capturing puts the captured file in 'captures//' - fileName = linuxApiServerPathExtension - - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/files?filename=%s' % (fileName), stream=True, ignoreError=True) - - if response.status_code == 200: - if renameDestinationFile is not None: - fileName = renameDestinationFile - - if linuxApiServerPathExtension: - # This extension means that it has an extended path: captures//fileToGet - fileName = linuxApiServerPathExtension.split('/')[-1] - - contents = response.raw.read() - - if includeTimestamp: - if linuxApiServerPathAndFileNameAsIs: - fileName = fileName.split('/')[-1] - - tempFileName = fileName.split('.') - if len(tempFileName) > 1: - extension = fileName.split('.')[-1] - fileName = tempFileName[0]+'_' + currentTimestamp + '.' + extension - else: - fileName = tempFileName[0]+'_' + currentTimestamp + if renameDestinationFile: + fileName = renameDestinationFile - localPath = localPath+'/'+fileName - else: - localPath = localPath+'/'+fileName + if includeTimestamp: + fileName = self._addTimestampToFile(fileName) - # Step 3 of 3: - self.ixnObj.logInfo('\ncopyFileLinuxToLocalLinux: %s' % localPath) - with open(localPath, 'wb') as downloadedFileContents: - downloadedFileContents.write(contents) + destinationPath = localPath + '/' + fileName - self.ixnObj.logInfo('\nA copy of your saved file/report is in:\n\t%s' % (linuxApiServerPathAndFileName)) - else: - self.ixnObj.logInfo('\ncopyFileLinuxToLocalLinux Error: Failed to download file from Linux API Server.') + try: + self.ixNetwork.CopyFile(linuxApiServerPathAndFileName, destinationPath) + except Exception as err: + self.ixnObj.logInfo("Error with file transfer {}".format(err)) + raise Exception("\n copyFileLinuxToLocalLinux Error: Failed to download file from " + "IxNetwork API Server ") def convertIxncfgToJson(self, ixncfgFile, destinationPath): """ @@ -337,14 +233,18 @@ def convertIxncfgToJson(self, ixncfgFile, destinationPath): ixncfgFile: (str): The binary IxNetwork .ixncfg file. destinationPath: (str): The destination path to save the .json config file. """ + self.ixnObj.logInfo("convertIxncfgToJson") self.loadConfigFile(ixncfgFile) - filename = ixncfgFile.split('/')[-1] - match = re.match('(.*).ixncfg', filename) - if match: - filename = match.group(1) + filename = re.findall(r'[^\/|\\]+(?=\.)', ixncfgFile)[0] - jsonFilename = destinationPath+'/'+filename+'.json' - self.exportJsonConfigFile(jsonFilename) + if self.ixnObj.serverOs in ['windows', 'windowsConnectionMgr']: + jsonFilename = destinationPath + '\\' + filename + '.json' + destinationPath = jsonFilename.replace('\\', '\\\\') + + if self.ixnObj.serverOs == 'linux': + destinationPath = destinationPath+'/'+filename + '.json' + + self.exportJsonConfigFile(destinationPath) def importJsonConfigObj(self, dataObj, option='modify', silentMode=False, timeout=90): """ @@ -355,7 +255,8 @@ def importJsonConfigObj(self, dataObj, option='modify', silentMode=False, timeou Then pass in the json object to the data parameter. For modify: - Import the modified JSON data object to make a configuration modification on the API server. + Import the modified JSON data object to make a configuration modification + on the API server. Supports one xpath at a time. Example: {"xpath": "/traffic/trafficItem[1]", "enabled": True, @@ -364,37 +265,24 @@ def importJsonConfigObj(self, dataObj, option='modify', silentMode=False, timeou Parameters data: (json object): The JSON config object. option: (str): newConfig|modify - silentMode: (bool): If True, don't display REST API command on stdout. - timeout: (int): The timeout value to declare as failed. + silentMode: (bool): Not required in Restpy + timeout: (int): Not required in Restpy Note - arg2 value must be a string of JSON data: '{"xpath": "/traffic/trafficItem[1]", "enabled": false}' + arg2 value must be a string of JSON data: '{"xpath": "/traffic/trafficItem[1]", + "enabled": false}' """ - if option is 'modify': + if option == 'modify': arg3 = False - if option is 'newConfig': + if option == 'newConfig': arg3 = True - dataReformatted = {"arg1": "{0}/ixnetwork/resourceManager".format(self.ixnObj.headlessSessionId), - "arg2": json.dumps(dataObj), - "arg3": arg3} - - url = self.ixnObj.sessionUrl+'/resourceManager/operations/importconfig' - response = self.ixnObj.post(url, data=dataReformatted, silentMode=silentMode) - response = self.ixnObj.waitForComplete(response, url+'/'+response.json()['id'], silentMode=False, timeout=timeout) - if response.json()['result'] != []: - if option == 'modify': - errorFlag = 0 - for errorMsg in response.json()['result']: - self.ixnObj.logError('JSON Import: %s' % errorMsg, timestamp=False) - errorFlag = 1 - - if errorFlag: - raise IxNetRestApiException('\nimportJsonConfigObj Error') - else: - self.ixnObj.logInfo('importJsonConfigObj: No error in JSON import') - + try: + self.ixNetwork.ResourceManager.ImportConfig(Arg2=json.dumps(dataObj), Arg3=arg3) + except Exception as e: + print(e) + raise Exception('\nimportJsonConfigObj Error') def importJsonConfigFile(self, jsonFileName, option='modify'): """ @@ -410,45 +298,28 @@ def importJsonConfigFile(self, jsonFileName, option='modify'): jsonFileName: (json object): The JSON config file. Could include absolute path also. option: (str): newConfig|modify """ - if option is 'modify': + if option == 'modify': arg3 = False - if option is 'newConfig': + if option == 'newConfig': arg3 = True - fileName = jsonFileName.split('/')[-1] - uploadFile = self.ixnObj.sessionUrl+'/files?filename='+fileName - - if self.ixnObj.serverOs == 'linux': - headers = {'content-type': 'application/octet-stream', 'x-api-key': self.ixnObj.apiKey} - else: - headers = {'content-type': 'application/octet-stream'} - - # 1> Upload the config file to the server and give it any name you want for the filename - self.ixnObj.logInfo('Uploading file to server: %s' % uploadFile) - with open(jsonFileName, mode='rb') as file: - configContents = file.read() - configContents = io.BytesIO(configContents) - response = self.ixnObj.post(uploadFile, data=configContents, noDataJsonDumps=True, - headers=headers, silentMode=False) - - # 2> Tell IxNetwork to import the JSON config file - data = {"arg1": "{0}/ixnetwork/resourceManager".format(self.ixnObj.headlessSessionId), - "arg2": "{0}/ixnetwork/files/{1}".format(self.ixnObj.headlessSessionId, fileName), - "arg3": arg3} - - url = self.ixnObj.sessionUrl+'/resourceManager/operations/importconfigfile' - response = self.ixnObj.post(url, data=data) - self.ixnObj.waitForComplete(response, url+'/'+response.json()['id'], silentMode=False, timeout=300) + try: + self.ixNetwork.ResourceManager.ImportConfigFile(Arg2=Files(jsonFileName), Arg3=arg3) + except Exception as err: + self.ixnObj.logInfo("Error with importJsonConfig {}".format(err)) + raise Exception('\nimportJsonConfigObj Error') def exportJsonConfigFile(self, jsonFileName, xpathList=None): """ Description - Export the current configuration to a JSON format config file and copy it to local filesystem. + Export the current configuration to a JSON format config file and copy it to local + filesystem. Parameters - jsonFileName: (str): The JSON config file name to create. Could include absolute path also. + jsonFileName: (str): The JSON config file name to create. Could include absolute path + also. - xpathList: + xpathList: To get entire configuration = ['/descendant-or-self::*'] To get code fragments such as /vport = ['/vport/descendant-or-self::*'] @@ -459,71 +330,24 @@ def exportJsonConfigFile(self, jsonFileName, xpathList=None): self.jsonReadConfig() self.jsonWriteToFile() - Syntax - POST /api/v1/sessions/{id}/ixnetwork/resourceManager/operations/exportconfigfile - DATA = {'arg1': '/api/v1/sessions/{id}/ixnetwork/resourceManager', - 'arg2': ['/descendant-or-self::*'], - 'arg3': True, - 'arg4': 'json', - 'arg5': '/api/v1/sessions/{id}/ixnetwork/files/'+fileName - } - Example restObj.exportJsonConfigFile(jsonFileName='/path/exportedJsonConfig.json') - + """ - if xpathList == None: + if xpathList is None: xpathList = ['/descendant-or-self::*'] - jsonFileNameTemp = jsonFileName.split('/') - if jsonFileNameTemp[0] == '': - jsonFileNameTemp.pop(0) - - if len(jsonFileNameTemp) > 1: - destinationPath = '/' - destinationPath = destinationPath + '/'.join(jsonFileNameTemp[:-1]) - else: - destinationPath = os.getcwd() - - self.ixnObj.logInfo('Storing the exported file to: %s' % destinationPath) - - fileName = jsonFileNameTemp[-1] - # sessionId example: /api/v1/sessions/{id}/ixnetwork - sessionId = self.ixnObj.sessionUrl.split(self.ixnObj.httpHeader)[1] - - data = {'arg1': sessionId+"/resourceManager", - 'arg2': xpathList, - 'arg3': True, - 'arg4': 'json', - 'arg5': sessionId+'/files/'+fileName - } + self.ixnObj.logInfo('Storing the exported file to: %s' % jsonFileName) - url = self.ixnObj.sessionUrl+'/resourceManager/operations/exportconfigfile' - response = self.ixnObj.post(url, data=data) - self.ixnObj.waitForComplete(response, url+'/'+response.json()['id'], silentMode=False) - - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/files') - absolutePath = response.json()['absolute'] - - if self.ixnObj.serverOs in ['windows', 'windowsConnectionMgr']: - absolutePath = absolutePath.replace('\\', '\\\\') - absolutePath = absolutePath + '\\\\'+fileName - - if self.ixnObj.serverOs == 'linux': - absolutePath = absolutePath+'/'+fileName + try: + ret = self.ixNetwork.ResourceManager.ExportConfig(Arg2=xpathList, Arg3=True, + Arg4='json') + convStrToDict = json.loads(ret) + with open(jsonFileName, 'w') as fp: + json.dump(convStrToDict, fp) + except Exception as err: + raise Exception("Failed Exporting Configuration {}".format(err)) - if self.ixnObj.serverOs in ['windows', 'windowsConnectionMgr']: - self.copyFileWindowsToLocalLinux(windowsPathAndFileName=absolutePath, - localPath=destinationPath, - renameDestinationFile=None, - includeTimestamp=False) - - if self.ixnObj.serverOs == 'linux': - self.copyFileLinuxToLocalLinux(linuxApiServerPathAndFileName=absolutePath, - localPath=destinationPath, - renameDestinationFile=None, - includeTimestamp=False) - # Indent the serialized json config file jsonObj = self.jsonReadConfig(jsonFileName) self.jsonWriteToFile(jsonObj, jsonFileName) @@ -531,8 +355,7 @@ def exportJsonConfigFile(self, jsonFileName, xpathList=None): def exportJsonConfigToDict(self, xpathList=None): """ Description - Export the current configuration to a JSON config format and convert to a - Python Dict. + Export the current configuration to a JSON config format and convert to a Python Dict. Parameter xpathList: To get entire configuration = ['/descendant-or-self::*'] @@ -541,32 +364,32 @@ def exportJsonConfigToDict(self, xpathList=None): Return JSON config in a dictionary format. """ - if xpathList == None: + if xpathList is None: xpathList = ['/descendant-or-self::*'] - - data = {'arg1': self.ixnObj.apiSessionId+"/resourceManager", - 'arg2': xpathList, - 'arg3': True, - 'arg4': 'json' - } - url = self.ixnObj.sessionUrl+'/resourceManager/operations/exportconfig' - response = self.ixnObj.post(url, data=data) - response = self.ixnObj.waitForComplete(response, url+'/'+response.json()['id'], silentMode=False) - return json.loads(response.json()['result']) + try: + ret = self.ixNetwork.ResourceManager.ExportConfig(Arg2=xpathList, Arg3=True, + Arg4='json') + return json.loads(ret) + except Exception as err: + raise Exception("Failed Exporting Configuration {}".format(err)) def getJsonConfigPortList(self, jsonData): """ Description - Read an exported json data and create a list of all the vports from the json configuration. + Read an exported json data and create a list of all the vports from the json + configuration. Parameter - jsonData: (json object): The json data after calling: jsonData = jsonReadConfig(jsonConfigFile) + jsonData: (json object): The json data after calling: jsonData = jsonReadConfig( + jsonConfigFile) """ portList = [] for vport in jsonData['vport']: # /availableHardware/chassis[@alias = '172.28.95.60']/card[1]/port[2]" connectedTo = vport['connectedTo'] - match = re.match("/availableHardware/.*'([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)']/card\[([0-9]+)]/port\[([0-9]+)", connectedTo) + match = re.match( + "/availableHardware/.*'([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)']/card\[([0-9]+)]/port\[([0-9]+)", + connectedTo) portList.append([match.group(1), match.group(2), match.group(3)]) return portList @@ -574,11 +397,11 @@ def jsonReadConfig(self, jsonFile): """ Description Read the input json file. - + Parameter jsonFile: (json object): The json file to read. """ - if os.path.isfile(jsonFile) == False: + if not os.path.isfile(jsonFile): raise IxNetRestApiException("JSON param file doesn't exists: %s" % jsonFile) with open(jsonFile.strip()) as inFile: @@ -589,7 +412,7 @@ def jsonWriteToFile(self, dataObj, jsonFile, sortKeys=False): """ Description Write data to a json file. - + Parameters dataObj: (json object): The json object containing the data. jsonFile (str): The the destination json file to write the json data. @@ -599,36 +422,35 @@ def jsonWriteToFile(self, dataObj, jsonFile, sortKeys=False): with open(jsonFile, 'w') as outFile: json.dump(dataObj, outFile, sort_keys=sortKeys, indent=4) - def jsonPrettyprint(self,data, sortKeys=False, **kwargs): + def jsonPrettyprint(self, data, sortKeys=False, **kwargs): """ Description Display the JSON data in human readable format with indentations. """ self.ixnObj.logInfo('\nimportJsonConfigObj pretty print:', timestamp=False) - self.ixnObj.logInfo('\n\n{0}'.format(json.dumps(data, indent=4, sort_keys=sortKeys)), timestamp=False) + self.ixnObj.logInfo('\n\n{0}'.format(json.dumps(data, indent=4, sort_keys=sortKeys)), + timestamp=False) def collectDiagnostics(self, diagZipFilename='ixiaDiagnostics.zip', localPath=None): """ Description Collect diagnostics for debugging. - + Parameter diagZipFileName: : The diagnostic filename to name with .zip extension. localPath: : The local destination where you want to put the collected diag file. """ - if localPath is None: - localPath = '.' - - url = self.ixnObj.sessionUrl+'/operations/collectlogs' - data = {'arg1': self.ixnObj.headlessSessionId+'/'+diagZipFilename} - response = self.ixnObj.post(url, data=data) - self.ixnObj.waitForComplete(response, url+'/'+response.json()['id'], silentMode=False, timeout=900) - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/files') - absolutePath = response.json()['absolute'] - if self.ixnObj.serverOs in ['windows', 'windowsConnectionMgr']: - absolutePath = absolutePath.replace('/', '\\') - self.copyFileWindowsToLocalLinux(windowsPathAndFileName=absolutePath+'\\'+diagZipFilename, localPath=localPath) + try: + self.ixNetwork.CollectLogs(Arg1=Files(diagZipFilename, local_file=True)) + except Exception as err: + raise Exception("Failed Creating Diag logs {}".format(err)) - if self.ixnObj.serverOs == 'linux': - self.copyFileLinuxToLocalLinux(linuxApiServerPathAndFileName=absolutePath+'/'+diagZipFilename, localPath=localPath) + if localPath: + try: + self.ixNetwork.CopyFile(Files(diagZipFilename, local_file=True), + localPath + "\\" + diagZipFilename) + except Exception as e: + print(e) + self.ixNetwork.CopyFile(Files(diagZipFilename, local_file=True), + localPath + "/" + diagZipFilename) diff --git a/RestApi/Python/Modules/IxNetRestApiGlobals.py b/RestApi/Python/Modules/IxNetRestApiGlobals.py index 83931f0b..643d8f87 100644 --- a/RestApi/Python/Modules/IxNetRestApiGlobals.py +++ b/RestApi/Python/Modules/IxNetRestApiGlobals.py @@ -1,7 +1,3 @@ -import re - -from IxNetRestApiProtocol import Protocol - class Globals(object): def __init__(self, ixnObj=None): """ @@ -9,7 +5,7 @@ def __init__(self, ixnObj=None): ixnObj: : The main connection object. """ self.ixnObj = ixnObj - self.protocolObj = Protocol(ixnObj) + self.ixNetwork = ixnObj.ixNetwork def dhcpV4ClientStartStopRate(self, endpoint='startRate', **kwargs): """ @@ -19,7 +15,8 @@ def dhcpV4ClientStartStopRate(self, endpoint='startRate', **kwargs): Parameters endpoint: : startRate|stopRate - **kwargs: Any attribute for the /globals/topology/dhcpv4client/startRate|stopRate endpoint. + **kwargs: Any attribute for the /globals/topology/dhcpv4client/ + startRate|stopRate endpoint. enabled = bool interval = int maxOutstanding = int @@ -35,16 +32,16 @@ def dhcpV4ClientStartStopRate(self, endpoint='startRate', **kwargs): ) """ - restApi = '/globals/topology/dhcpv4client/{0}?links=true'.format(endpoint) - - response = self.ixnObj.get(self.ixnObj.sessionUrl + restApi) - for key,value in response.json().items(): - if key != 'links': - if bool(re.search('multivalue', str(value))) == True: - if key in kwargs: - multiValue = response.json()[key] - self.ixnObj.patch(self.ixnObj.httpHeader+multiValue+"/singleValue", data={'value': kwargs[key]}) - else: - if key in kwargs: - self.ixnObj.patch(self.ixnObj.sessionUrl + restApi, data={key: kwargs[key]}) - + rateObj = None + + if endpoint == 'startRate': + rateObj = self.ixNetwork.Globals.Topology.Dhcpv4client.StartRate + if endpoint == 'stopRate': + rateObj = self.ixNetwork.Globals.Topology.Dhcpv4client.StopRate + for key, value in kwargs.items(): + key = key[0].capitalize() + key[1:] + try: + multiValueObj = getattr(rateObj, key) + self.ixnObj.configMultivalue(multiValueObj, 'singlevalue', {'value': value}) + except(ValueError, Exception): + setattr(rateObj, key, value) diff --git a/RestApi/Python/Modules/IxNetRestApiPacketCapture.py b/RestApi/Python/Modules/IxNetRestApiPacketCapture.py index a4de0551..a1a5d4b2 100644 --- a/RestApi/Python/Modules/IxNetRestApiPacketCapture.py +++ b/RestApi/Python/Modules/IxNetRestApiPacketCapture.py @@ -1,7 +1,8 @@ -import sys, re -from IxNetRestApiFileMgmt import FileMgmt +import time from IxNetRestApiPortMgmt import PortMgmt from IxNetRestApi import IxNetRestApiException +from ixnetwork_restpy.files import Files + class PacketCapture(object): """ @@ -13,30 +14,32 @@ def __init__(self, ixnObj=None, portMgmtObj=None): """ Parameters ixnObj: The main ixnObj object - portMgmtObj: (Optional): The PortMgmt object. - If you already have the portMgmt object, then pass it in. + portMgmtObj: (Optional): The PortMgmt object. If you already have the portMgmt + object, then pass it in. Otherwise, leave portMgmtObj=None - Example: trafficObj = Traffic(mainObj) portMgmtObj = PortMgmt(mainObj) captureObj = PacketCapture(mainObj, portMgmtObj) - captureObj.packetCaptureConfigPortMode(port=[ixChassisIp, '2', '1'], enableControlPlane=False, enableDataPlane=True) + captureObj.packetCaptureConfigPortMode(port=[ixChassisIp, '2', '1'], + enableControlPlane=False, enableDataPlane=True) trafficObj.startTraffic() <-- Make sure traffic is running in continuous mode captureObj.packetCaptureStart() time.sleep(10) captureObj.packetCaptureStop() trafficObj.stopTraffic() - pktCaptureObj.getCapFile(port=[ixChassisIp, '2', '1'], typeOfCapture='data', saveToTempLocation='c:\\Results', - localLinuxLocation='.', appendToSavedCapturedFile=None) + pktCaptureObj.getCapFile(port=[ixChassisIp, '2', '1'], typeOfCapture='data', + saveToTempLocation='c:\\Results', localLinuxLocation='.', + appendToSavedCapturedFile=None) - pktCaptureObj.packetCaptureGetCurrentPackets(getUpToPacketNumber=5, capturePacketsToFile=True, - getSavedCapturedDotCapFile=True) + pktCaptureObj.packetCaptureGetCurrentPackets(getUpToPacketNumber=5, + capturePacketsToFile=True, getSavedCapturedDotCapFile=True) captureObj.packetCaptureClearTabs() """ self.ixnObj = ixnObj + self.ixNetwork = ixnObj.ixNetwork if portMgmtObj: self.portMgmtObj = portMgmtObj else: @@ -50,7 +53,11 @@ def setMainObject(self, mainObject): self.ixnObj = mainObject self.portMgmtObj.setMainObject(mainObject) - def packetCaptureConfigPortMode(self, port, portRxMode='capture', enableControlPlane=True, enableDataPlane=True): + def packetCaptureConfigPortMode(self, + port, + portRxMode='capture', + enableControlPlane=True, + enableDataPlane=True): """ Description Enable|Disable port capturing for control plane and data plane. @@ -60,209 +67,206 @@ def packetCaptureConfigPortMode(self, port, portRxMode='capture', enableControlP -hardwareEnabled == Data Plane Parameters - port: : [ixChassisIp, '1', '3'] => [ixChasssisIp, str(cardNumber), str(portNumber)] + port: :[ixChassisIp, '1', '3'] => [ixChasssisIp, str(cardNumber), str(portNumber)] portRxMode: : capture|captureAndMeasure enableControlPlane: enableDataPlane: """ - if enableControlPlane == True: + self.ixnObj.logInfo("Configuring and enable control/data plane capture") + if enableControlPlane: self.enableControlPlane = True - if enableDataPlane == True: + if enableDataPlane: self.enableDataPlane = True self.captureRxPort = port vport = self.portMgmtObj.getVports([port])[0] - self.ixnObj.patch(self.ixnObj.httpHeader+vport, data={'rxMode': portRxMode}) - self.ixnObj.patch(self.ixnObj.httpHeader+vport+'/capture', data={'softwareEnabled': enableControlPlane, - 'hardwareEnabled': enableDataPlane}) + vport.RxMode = portRxMode + + vport.Capture.SoftwareEnabled = enableControlPlane + vport.Capture.HardwareEnabled = enableDataPlane def packetCaptureStart(self): """ Start packet capturing """ - response = self.ixnObj.post(self.ixnObj.sessionUrl+'/operations/startcapture') - self.ixnObj.waitForComplete(response, self.ixnObj.sessionUrl+'/operations/startcapture/'+response.json()['id']) + try: + self.ixNetwork.StartCapture() + except Exception as err: + self.ixnObj.logInfo("Error {} ".format(err)) + raise Exception('\n Failed to start captures') def packetCaptureStop(self): """ Stop packet capturing """ - response = self.ixnObj.post(self.ixnObj.sessionUrl+'/operations/stopcapture') - self.ixnObj.waitForComplete(response, self.ixnObj.sessionUrl+'/operations/stopcapture/'+response.json()['id']) + try: + self.ixNetwork.StopCapture() + except Exception as err: + self.ixnObj.logInfo("Error {} ".format(err)) + raise Exception('\n Failed to stop captures') def packetCaptureClearTabs(self): """ Remove all captured tabs on Windows IxNetwork GUI """ - response = self.ixnObj.post(self.ixnObj.sessionUrl+'/operations/closeAllTabs') - self.ixnObj.waitForComplete(response, self.ixnObj.sessionUrl+'/operations/closeAllTabs/'+response.json()['id']) + try: + self.ixNetwork.CloseAllTabs() + except Exception as err: + self.ixnObj.logInfo("Error {} ".format(err)) + raise Exception('\n Failed closing all tabs') def packetCaptureGetCurrentPackets(self, getUpToPacketNumber=20, capturePacketsToFile=True): """ Description Packet Capturing in wireshark style details. By default, it saved 7209 packet counts. - It takes a long time to save all the packet header details into a file. + It takes a long time to save all the packet header details into a file. This API will default saving 20 packet counts. You could increase the packet count. Parameters - getUpToPacketNumber: None|The last packet number to get. - Always starts at 1. If you state 10, then this function will get 1-10 packets. + getUpToPacketNumber: None|The last packet number to get. Always starts at 1. + If you state 10, then this function will get 1-10 packets. capturePacketsToFile: True|False """ - import subprocess, time if capturePacketsToFile: timestamp = int(time.time()) if self.enableDataPlane: packetCaptureFilenameData = 'packetCaptureForData_'+str(timestamp) - subprocess.call(['touch', packetCaptureFilenameData]) if self.enableControlPlane: packetCaptureFilenameControl = 'packetCaptureForControl_'+str(timestamp) - subprocess.call(['touch', packetCaptureFilenameControl]) - if self.enableDataPlane == False and self.enableControlPlane == False: - raise IxNetRestApiException('\nPacketCapture Error: You must enable one of the options: enableDataPlane|enableControlPlane') - + if not self.enableDataPlane and not self.enableControlPlane: + raise IxNetRestApiException('\n PacketCapture Error: You must enable one of the ' + 'options: enableDataPlane|enableControlPlane') + vport = self.portMgmtObj.getVports([self.captureRxPort])[0] - response = self.ixnObj.get(self.ixnObj.httpHeader+vport+'/capture') - totalDataCapturedPackets = response.json()['dataPacketCounter'] - totalControlCapturedPackets = response.json()['controlPacketCounter'] + totalDataCapturedPackets = vport.Capture.DataPacketCounter + totalControlCapturedPackets = vport.Capture.ControlPacketCounter if type(totalDataCapturedPackets) != int: totalDataCapturedPackets = 0 else: - if getUpToPacketNumber != None: + if getUpToPacketNumber is not None: totalDataCapturedPackets = getUpToPacketNumber if type(totalControlCapturedPackets) != int: totalControlCapturedPackets = 0 else: - if getUpToPacketNumber != None: + if getUpToPacketNumber is not None: totalControlCapturedPackets = getUpToPacketNumber - for eachTypeOfCaptures, totalCapturedPackets in zip(('data', 'control'), (totalDataCapturedPackets, totalControlCapturedPackets)): - self.ixnObj.logInfo('Getting captured packets for capture type: {0}'.format(eachTypeOfCaptures)) + for eachTypeOfCaptures, totalCapturedPackets in \ + zip(('data', 'control'), (totalDataCapturedPackets, totalControlCapturedPackets)): + self.ixnObj.logInfo( + 'Getting captured packets for capture type: {0}'.format(eachTypeOfCaptures)) if capturePacketsToFile and int(totalCapturedPackets) != 0: timestamp = int(time.time()) if self.enableDataPlane: packetCaptureFilenameData = 'packetCaptureForData_'+str(timestamp) - subprocess.call(['touch', packetCaptureFilenameData]) if self.enableControlPlane: packetCaptureFilenameControl = 'packetCaptureForControl_'+str(timestamp) - subprocess.call(['touch', packetCaptureFilenameControl]) for packetIndex in range(1, int(totalCapturedPackets)): - self.ixnObj.logInfo('Getting captured packet index number: {}/{}'.format(packetIndex, getUpToPacketNumber)) + self.ixnObj.logInfo('Getting captured packet index number: {}/{}'. + format(packetIndex, getUpToPacketNumber)) if self.enableDataPlane and eachTypeOfCaptures == 'data': - data = {'arg1': vport+'/capture/currentPacket', 'arg2': packetIndex} - response = self.ixnObj.post(self.ixnObj.sessionUrl+'/vport/capture/currentPacket/operations/getpacketfromdatacapture', - data=data, silentMode=False) - self.ixnObj.waitForComplete(response, self.ixnObj.sessionUrl+'/vport/capture/currentPacket/operations/getpacketfromdatacapture/'+response.json()['id']) + vport.Capture.CurrentPacket.GetPacketFromDataCapture(Arg2=packetIndex) if self.enableControlPlane and eachTypeOfCaptures == 'control': - data = {'arg1': vport+'/capture/currentPacket', 'arg2': packetIndex} - response = self.ixnObj.post(self.ixnObj.sessionUrl+'/vport/capture/currentPacket/operations/getpacketfromcontrolcapture', - data=data, silentMode=False) - - self.ixnObj.waitForComplete(response, self.ixnObj.sessionUrl+'/vport/capture/currentPacket/operations/getpacketfromcontrolcapture/'+response.json()['id']) + vport.Capture.CurrentPacket.GetPacketFromControlCapture(Arg2=packetIndex) - response = self.ixnObj.get(self.ixnObj.httpHeader+vport+'/capture/currentPacket/stack', silentMode=False) + stackObj = vport.Capture.CurrentPacket.Stack.find() - for eachStack in response.json(): - displayName = eachStack['displayName'] - stackIdObject = eachStack['links'][0]['href'] - self.ixnObj.logInfo('\nStack: %s' % displayName) + for eachStack in stackObj: + displayName = eachStack.DisplayName + self.ixnObj.logInfo('\n Stack: %s' % displayName) if capturePacketsToFile: if eachTypeOfCaptures == 'data': with open(packetCaptureFilenameData, 'a') as packetCaptureFile: - packetCaptureFile.write('\nStack: %s\n' % displayName) + packetCaptureFile.write('\n Stack: %s\n' % displayName) if eachTypeOfCaptures == 'control': with open(packetCaptureFilenameControl, 'a') as packetCaptureFile: - packetCaptureFile.write('\nStack: %s\n' % displayName) + packetCaptureFile.write('\n Stack: %s\n' % displayName) - response = self.ixnObj.get(self.ixnObj.httpHeader+stackIdObject+'/field', silentMode=False) - for eachField in response.json(): - fieldId = eachField['id'] - fieldName = eachField['displayName'] - fieldValue = eachField['fieldValue'] - self.ixnObj.logInfo('\t{0}: {1}: {2}'.format(fieldId, fieldName, fieldValue)) + for eachFieldObj in eachStack.Field.find(): + fieldId = eachFieldObj.href.split('/')[-1] + fieldName = eachFieldObj.DisplayName + fieldValue = eachFieldObj.FieldValue + self.ixnObj.logInfo( + '\t{0}: {1}: {2}'.format(fieldId, fieldName, fieldValue)) if capturePacketsToFile: if eachTypeOfCaptures == 'data': with open(packetCaptureFilenameData, 'a') as packetCaptureFile: - packetCaptureFile.write('\t{0}: {1}: {2}\n'.format(fieldId, fieldName, fieldValue)) + packetCaptureFile.write( + '\t{0}: {1}: {2}\n'.format(fieldId, fieldName, fieldValue)) if eachTypeOfCaptures == 'control': with open(packetCaptureFilenameControl, 'a') as packetCaptureFile: - packetCaptureFile.write('\t{0}: {1}: {2}\n'.format(fieldId, fieldName, fieldValue)) + packetCaptureFile.write( + '\t{0}: {1}: {2}\n'.format(fieldId, fieldName, fieldValue)) - def packetCaptureGetCurrentPacketsHex(self, getUpToPacketNumber=20): + def packetCaptureGetCurrentPacketsHex(self, getUpToPacketNumber=10): """ Description - Returns captured packets in hex format. + Returns captured packets in hex format. This API will default return 20 packet hex. You could increase the packet count. Parameters - getUpToPacketNumber: None|The last packet number to get. - Always starts at 1. If you state 10, then this function will get 1-10 packets. - + getUpToPacketNumber: None|The last packet number to get. + Always starts at 1. If you state 10, + then this function will get 1-10 packets. + Return capturedData: dictionary. key is 'data' and/or 'control' capturedData['data'] is dictionary of packet hex data for Data Capture Buffer capturedData['control'] is dictionary of packet hex data for Control Capture Buffer """ - import time vport = self.portMgmtObj.getVports([self.captureRxPort])[0] - response = self.ixnObj.get(self.ixnObj.httpHeader+vport+'/capture') - totalDataCapturedPackets = response.json()['dataPacketCounter'] - totalControlCapturedPackets = response.json()['controlPacketCounter'] + totalDataCapturedPackets = vport.Capture.DataPacketCounter + totalControlCapturedPackets = vport.Capture.ControlPacketCounter if type(totalDataCapturedPackets) != int: totalDataCapturedPackets = 0 else: - if getUpToPacketNumber != None: + if getUpToPacketNumber is not None: totalDataCapturedPackets = getUpToPacketNumber if type(totalControlCapturedPackets) != int: totalControlCapturedPackets = 0 else: - if getUpToPacketNumber != None: + if getUpToPacketNumber is not None: totalControlCapturedPackets = getUpToPacketNumber - capturedData={} - for eachTypeOfCaptures, totalCapturedPackets in zip(('data', 'control'), (totalDataCapturedPackets, totalControlCapturedPackets)): - self.ixnObj.logInfo('Getting captured packets for capture type: {0}'.format(eachTypeOfCaptures)) + capturedData = {} + for eachTypeOfCaptures, totalCapturedPackets in \ + zip(('data', 'control'), (totalDataCapturedPackets, totalControlCapturedPackets)): + self.ixnObj.logInfo( + 'Getting captured packets for capture type: {0}'.format(eachTypeOfCaptures)) - capturedData[eachTypeOfCaptures]={} + capturedData[eachTypeOfCaptures] = {} for packetIndex in range(1, int(totalCapturedPackets)): - self.ixnObj.logInfo('Getting captured packet index number: {}/{}'.format(packetIndex, getUpToPacketNumber)) + self.ixnObj.logInfo('Getting captured packet index number: {}/{}'. format( + packetIndex, getUpToPacketNumber)) if totalDataCapturedPackets > 0: - data = {'arg1': vport+'/capture/currentPacket', 'arg2': packetIndex} - response = self.ixnObj.post(self.ixnObj.sessionUrl+'/vport/capture/currentPacket/operations/getpacketfromdatacapture', - data=data, silentMode=False) - self.ixnObj.waitForComplete(response, self.ixnObj.sessionUrl+'/vport/capture/currentPacket/operations/getpacketfromdatacapture/'+response.json()['id']) + vport.Capture.CurrentPacket.GetPacketFromDataCapture(Arg2=packetIndex) if totalControlCapturedPackets > 0: - data = {'arg1': vport+'/capture/currentPacket', 'arg2': packetIndex} - response = self.ixnObj.post(self.ixnObj.sessionUrl+'/vport/capture/currentPacket/operations/getpacketfromcontrolcapture', - data=data, silentMode=False) - - self.ixnObj.waitForComplete(response, self.ixnObj.sessionUrl+'/vport/capture/currentPacket/operations/getpacketfromcontrolcapture/'+response.json()['id']) - - data = {'arg1': '-packetHex'} - response = self.ixnObj.get(self.ixnObj.httpHeader+vport+'/capture/currentPacket', data=data, silentMode=False) - packetHex = response.json()['packetHex'] - capturedData[eachTypeOfCaptures][packetIndex]=packetHex + vport.Capture.CurrentPacket.GetPacketFromControlCapture(Arg2=packetIndex) + + packetHex = vport.Capture.CurrentPacket.PacketHex + capturedData[eachTypeOfCaptures][packetIndex] = packetHex return capturedData - - def getCapFile(self, port, typeOfCapture='data', saveToTempLocation='c:\\Temp', localLinuxLocation='.', appendToSavedCapturedFile=None): + + 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. @@ -273,12 +277,12 @@ def getCapFile(self, port, typeOfCapture='data', saveToTempLocation='c:\\Temp', typeOfCapture: data|control saveToTempLocation: For Windows: - Where to temporary save the .cap file on the ReST API server: + 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. @@ -287,95 +291,54 @@ def getCapFile(self, port, typeOfCapture='data', saveToTempLocation='c:\\Temp', 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//transmissionControl - DATA: {'type': 'continuous'} + DATA: {"arg1": "packetCaptureFolder"} <-- This could be any name. + Just a temporary folder to store the captured file. - POST: /traffic/trafficItem/operations/generate - DATA: {"arg1": ["/api/v1/sessions//ixnetwork/traffic/trafficItem/1"]} + Wait for the /operations/savecapturefiles/ to complete. + May take up to a minute or more. - POST: /traffic/operations/apply - DATA: {"arg1": "/api/v1/sessions//ixnetwork/traffic"} + For Windows API server: - POST: /traffic/operations/start - DATA: {"arg1": "https://192.168.70.12/api/v1/sessions//ixnetwork/traffic"} + DATA: {"arg1": "c:\\Results\\port2_HW.cap", + "arg2": "/api/v1/sessions/1/ixnetwork/files/port2_HW.cap"} - Start continuous traffic + For Linux API server: - 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. + DATA: {"arg1": "captures/packetCaptureFolder/port2_HW.cap", + "arg2": "/api/v1/sessions//ixnetwork/files/port2_HW.cap"} - Wait for the /operations/savecapturefiles/ 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 + vport = self.portMgmtObj.getVports([port])[0] + vportName = vport.Name - For Linux API server: - POST: /ixnetwork/operations/copyfile - DATA: {"arg1": "captures/packetCaptureFolder/port2_HW.cap", "arg2": "/api/v1/sessions//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} + if appendToSavedCapturedFile is not None: + self.ixNetwork.SaveCaptureFiles(Arg1=saveToTempLocation, Arg2=appendToSavedCapturedFile) else: - data = {'arg1': saveToTempLocation} + self.ixNetwork.SaveCaptureFiles(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) + if self.ixnObj.serverOs in ['windows', 'windowsConnectionMgr']: + capFileToGet = saveToTempLocation + "\\" + vportName + "_SW.cap" + filename = vportName + "_HW.cap" else: - # For Windows - capFileToGet = capfilePathName + capFileToGet = saveToTempLocation + "/" + vportName + "_SW.cap" + filename = vportName + "_HW.cap" 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) + if self.ixnObj.serverOs in ['windows', 'windowsConnectionMgr']: + capFileToGet = saveToTempLocation + "\\" + vportName + "_HW.cap" + filename = vportName + "_HW.cap" 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/_HW.cap - match = re.search('.*(captures.*)', capFileToGet) - pathExtension = match.group(1) - - fileMgmtObj.copyFileLinuxToLocalLinux(linuxApiServerPathAndFileName=capFileToGet, localPath=localLinuxLocation, - renameDestinationFile=None, linuxApiServerPathExtension=pathExtension) - + capFileToGet = saveToTempLocation + "/" + vportName + "_HW.cap" + filename = vportName + "_HW.cap" + + try: + self.ixNetwork.CopyFile(Files(capFileToGet, local_file=False), + localLinuxLocation + "\\" + filename + ".cap") + except Exception as err: + self.ixnObj.logInfo("Error {} ".format(err)) + self.ixNetwork.CopyFile(Files(capFileToGet, local_file=False), + localLinuxLocation + "/" + filename + ".cap") diff --git a/RestApi/Python/Modules/IxNetRestApiPortMgmt.py b/RestApi/Python/Modules/IxNetRestApiPortMgmt.py index 35ce255c..4263e3f6 100644 --- a/RestApi/Python/Modules/IxNetRestApiPortMgmt.py +++ b/RestApi/Python/Modules/IxNetRestApiPortMgmt.py @@ -1,9 +1,11 @@ import time from IxNetRestApi import IxNetRestApiException + class PortMgmt(object): def __init__(self, ixnObj=None): self.ixnObj = ixnObj + self.ixNetwork = ixnObj.ixNetwork def getSelfObject(self): # For Python Robot Framework support @@ -14,93 +16,66 @@ def setMainObject(self, mainObject): self.ixnObj = mainObject def connectToVChassis(self, chassisIp): - # Connects to the virtual chassis - - url = self.ixnObj.sessionUrl+'/operations/connecttochassis' - data = {"arg1": chassisIp} + """ + Description + Connect to an virtual chassis chassis. - response = self.ixnObj.post(url, data=data) - if response == 1: return 1 - if response.json()['state'] == 'ERROR': - self.ixnObj.logInfo('connectToVChassis error: %s' % response.json()['result']) - return 1 - else: - self.ixnObj.logInfo('connectToVChassis: Successfully connected to chassis: %s' % chassisIp) - while response.json()["state"] == "IN_PROGRESS" or response.json()["state"] == "down": - if timeout == 0: - break + Parameter + chassisIp: : A string of chassis IP addresses. + """ + counterStop = 45 + for counter in range(1, counterStop + 1): + chassisStatus = self.ixNetwork.AvailableHardware.Chassis.add(Hostname=chassisIp) + if chassisStatus.State != 'ready': + self.ixnObj.logInfo('\nChassis {0} is not connected yet. Waiting {1}/{2} seconds'. + format(chassisIp, counter, counterStop)) time.sleep(1) - response = request.get(self.ixnObj.sessionUrl) - state = response.json()["state"] - self.ixnObj.logInfo("\t\t%s" % state) - timeout = timeout - 1 - return 0 - def connectIxChassis(self, chassisIp, timeout=30, **kwargs): + if chassisStatus.State == 'ready': + self.ixnObj.logInfo('\n{0}'.format(chassisStatus)) + return 0 + + if counter == counterStop: + raise Exception('\nFailed to connect to chassis: {0}'.format(chassisIp)) + + def connectIxChassis(self, chassisIp, timeout=45, **kwargs): """ Description Connect to an Ixia chassis. Parameter chassisIp: |: A string or a list of chassis IP addresses. - timeout: : Default=30 seconds. The amount of time to wait for the - chassis to be in the ready state. - - kwargs: Any chassis attributes and values. For example, if two chassis' are dasisy chained, include: - chainTopology=None, masterChassis='10.10.10.1', sequenceId=1 + timeout: : Default=30 seconds. The amount of time to wait for the chassis to be + in the ready state. - Syntax - /api/v1/sessions/{id}/ixnetwork/availableHardware/chassis + kwargs: Any chassis attributes and values. For example, if two chassis are dasisy + chained, include: chainTopology=None, masterChassis='10.10.10.1', sequenceId=1 """ - if isinstance(chassisIp, list) == False: + if not isinstance(chassisIp, list): chassisIp = chassisIp.split(' ') chassisObjList = [] - url = self.ixnObj.sessionUrl+'/availableHardware/chassis' - for chassisIpAddress in chassisIp: - data = {'hostname': chassisIpAddress} - if kwargs: - data.update(kwargs) - - response = self.ixnObj.post(url, data=data) - - if type(response.json()) == list: - # 8.50 json response is a list. - chassisIdObj = response.json()[0]['links'][0]['href'] - else: - chassisIdObj = response.json()['links'][0]['href'] - - self.ixnObj.logInfo('\n', timestamp=False) - - # Chassis states: down, polling, ready - - for timer in range(1,timeout+1): - response = self.ixnObj.get(self.ixnObj.httpHeader + chassisIdObj, silentMode=True) - currentStatus = response.json()['state'] - self.ixnObj.logInfo('connectIxChassis {0}: Status: {1}. Wait {2}/{3} seconds'.format( - chassisIpAddress, currentStatus, timer, timeout), timestamp=False) - - if currentStatus != 'ready' and timer < timeout: + for ixChassisIp in chassisIp: + self.ixnObj.logInfo("Connecting to chassis {}".format(ixChassisIp)) + for counter in range(1, timeout + 1): + + chassisStatus = self.ixNetwork.AvailableHardware.Chassis.add(Hostname=ixChassisIp) + if chassisStatus.State != 'ready': + self.ixnObj.logInfo('\nChassis {0} is not connected yet. Waiting {1}/{2} ' + 'seconds'.format(ixChassisIp, counter, timeout)) time.sleep(1) - if currentStatus != 'ready' and timer == timeout: - #raise IxNetRestApiException('connectIxChassis: Connecting to chassis {0} failed'.format(chassisIpAddress)) - if currentStatus == 'polling': - errorMsg = "Chassis could not be located." - else: - errorMsg = '' - - raise IxNetRestApiException('connectIxChassis failed. chassisIP:{0}. It is in the {1} state. {2}'.format(chassisIp, currentStatus, errorMsg)) - - if currentStatus == 'ready' and timer < timeout: - chassisObjList.append(chassisIdObj) + if chassisStatus.State == 'ready': + self.ixnObj.logInfo('\n{0}'.format(chassisStatus)) + chassisObjList.append(chassisStatus) break - # http://192.168.70.127:11009/api/v1/sessions/1/ixnetwork/availableHardware/chassis/1 + if counter == timeout: + raise Exception('\nFailed to connect to chassis: {0}'.format(ixChassisIp[0])) + return chassisObjList - def disconnectIxChassis(self, chassisIp): """ Description @@ -109,29 +84,20 @@ def disconnectIxChassis(self, chassisIp): Parameter chassisIp: : The chassis IP address. - Syntax - /api/v1/sessions/{id}/ixnetwork/availableHardware/chassis/{id} """ - url = self.ixnObj.sessionUrl+'/availableHardware/chassis' - response = self.ixnObj.get(url) - for eachChassisId in response.json(): - if eachChassisId['hostname'] == chassisIp: - chassisIdUrl = eachChassisId['links'][0]['href'] - self.ixnObj.logInfo('disconnectIxChassis: %s' % chassisIdUrl) - response = self.ixnObj.delete(self.ixnObj.httpHeader+chassisIdUrl) + self.ixnObj.logInfo("disconnecting from chassis {}".format(chassisIp)) + try: + self.ixNetwork.AvailableHardware.Chassis.find(Hostname=chassisIp).remove() + except Exception as err: + self.ixnObj.logInfo('Errored : \n {}'.format(err)) + raise Exception("Failed disconnecting chassis {}".format(chassisIp)) def getChassisId(self, chassisIp): """ - Description - Get the chassis ID based on the chassis IP address. - - Parameter - chassisIp: : The chassis IP address + This parameter is used to get chassis Id from Chassis Ip for REST API + For RESTpy we can ignore this """ - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/availableHardware/chassis') - for eachChassis in response.json(): - if eachChassis['ip'] == chassisIp: - return eachChassis['id'] + pass def connectVportTo(self, portList): """ @@ -142,28 +108,17 @@ def connectVportTo(self, portList): portList: : A list of ports in a list: [[ixChassisIp, card, port]] """ self.createVports(portList) - vportObjectList = self.ixnObj.get(self.ixnObj.sessionUrl+'/vport') - portListIndex = 0 - for vportObj in vportObjectList.json(): - print('\n', vportObj) - connectedTo = vportObj['connectedTo'] - vportHref = vportObj['links'][0]['href'] - if connectedTo == 'null': - # RW: 'connectedTo': '/api/v1/sessions/1/ixnetwork/availableHardware/chassis/1/card/1/port/1' - # ReadOnly: 'assignedTo': '192.168.70.11:1:1' - chassisIp = portList[portListIndex][0] - cardNumber = portList[portListIndex][1] - portNumber = portList[portListIndex][2] - chassisId = self.getChassisId(chassisIp) - self.ixnObj.patch(self.ixnObj.sessionUrl+'/availableHardware/chassis/'+str(chassisId)+'/card/'+str(cardNumber)+'/port/'+str(portNumber)) - data = '/api/v1/sessions/{0}/ixnetwork/availableHardware/chassis/{1}/card/{2}/port/{3}'.format( - self.ixnObj.sessionIdNumber, chassisId, cardNumber, portNumber) - self.ixnObj.patch(self.ixnObj.httpHeader+vportHref, data={'connectedTo': data}) - if portListIndex < len(portList): - portListIndex += 1 - continue - else: - break + testPorts = [] + vportList = self.ixNetwork.Vport.find() + for port in portList: + testPorts.append(dict(Arg1=port[0], Arg2=port[1], Arg3=port[2])) + + self.ixnObj.logInfo('\nAssignPorts: {0}'.format(portList)) + try: + self.ixNetwork.AssignPorts(testPorts, [], vportList, True) + except Exception as err: + self.ixnObj.logInfo('Errored : \n {}'.format(err)) + raise Exception("Failed to Assign ports {} ".format(portList)) def createVports(self, portList=None, rawTrafficVportStyle=False): """ @@ -172,37 +127,22 @@ def createVports(self, portList=None, rawTrafficVportStyle=False): Next step is to call assignPort. Parameters - portList: : Pass in a list of ports in the format of ixChassisIp, slotNumber, portNumber - portList = [[ixChassisIp, '1', '1'], [ixChassisIp, '2', '1']] - - rawTrafficVportStyle: : For raw Traffic Item src/dest endpoints, vports must be in format: - /api/v1/sessions1/vport/{id}/protocols - - Return - A list of vports - """ - createdVportList = [] - for index in range(0, len(portList)): - self.ixnObj.logInfo('Creating a new virtual port') - response = self.ixnObj.post(self.ixnObj.sessionUrl+'/vport') - vportObj = response.json()['links'][0]['href'] - if rawTrafficVportStyle: - createdVportList.append(vportObj+'/protocols') - else: - createdVportList.append(vportObj) - if portList != None: - response = self.ixnObj.get(self.ixnObj.httpHeader+vportObj) - card = portList[index][1] - port = portList[index][2] - portNumber = str(card)+'/'+str(port) - self.ixnObj.logInfo('\tName: %s' % portNumber) - response = self.ixnObj.patch(self.ixnObj.httpHeader+vportObj, data={'name': portNumber}) - - if createdVportList == []: - raise IxNetRestApiException('No vports created') - - self.ixnObj.logInfo('createVports: %s' % createdVportList) - return createdVportList + portList: : Pass in a list of ports in the format of + ixChassisIp, slotNumber, portNumber + portList = [[ixChassisIp, '1', '1'], [ixChassisIp, '2', '1']] + + rawTrafficVportStyle: This parameter is not useful in RESTpy ang Ignoring this + """ + if portList is not None: + createdVportList = [] + self.ixnObj.logInfo('\n Creating Vports for portList {}'.format(portList)) + for i in range(1, len(portList) + 1): + createdVportList.append(self.ixNetwork.Vport.add()) + if createdVportList == []: + raise Exception("Uable to create vports") + return createdVportList + else: + raise Exception("Please pass the portlist") def getVportObjectByName(self, portName): """ @@ -211,14 +151,17 @@ def getVportObjectByName(self, portName): Parameter portName: : The name of the virtual port. + + Return + vport object : ixnetwork_restpy.testplatform.sessions.ixnetwork.vport.vport.Vport object """ - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/vport') - vportList = ["%s/vport/%s" % (self.ixnObj.sessionUrl, str(i["id"])) for i in response.json()] - for vportObj in vportList: - response = self.ixnObj.get(vportObj) - if response.json()['name'] == portName: - return vportObj - return None + + self.ixnObj.logInfo("getting vport object for portname {}".format(portName)) + vport = self.ixNetwork.Vport.find(Name=portName) + if vport: + return vport + else: + raise Exception("Unable to find vportObj for portname {}".format(portName)) def getVportName(self, vportObj): """ @@ -226,10 +169,19 @@ def getVportName(self, vportObj): Get the name of the vport by the specified vport object Parameter - vportObj: : /api/v1/sessions/1/ixnetwork/vport/1 + vportObj: + : ixnetwork_restpy.testplatform.sessions.ixnetwork.vport.vport.Vport object + + Return + vport Name + + Eg : + Syntax : + getVportName(vportObj) + Return : Ethernet - VM - 001 """ - response = self.ixnObj.get(self.ixnObj.httpHeader+vportObj) - return response.json()['name'] + self.ixnObj.logInfo("getting vport name for vportObj") + return vportObj.Name def linkUpDown(self, port, action='down'): """ @@ -237,11 +189,18 @@ def linkUpDown(self, port, action='down'): Flap a port up or down. Parameters - port: : A list of ports in a list. [[ixChassisIp, str(card), str(port)]] -> ['10.10.10.1', '1', '3'] + port: : A list of ports in a list. + [[ixChassisIp, str(card), str(port)]] -> ['10.10.10.1', '1', '3'] action: : up|down """ - vport = self.ixnObj.getVports([port])[0] - self.ixnObj.post(self.ixnObj.sessionUrl+'/vport/operations/linkUpDn', data={'arg1': [vport], 'arg2': action}) + + action = action.lower() + self.ixnObj.logInfo("Link {} operation for ports {}".format(action, port)) + for eachPort in port: + self.ixnObj.logInfo("\n Make port {} to {} state".format(":".join(eachPort), action)) + vport = self.ixNetwork.Vport.find(AssignedTo=":".join(eachPort)) + if vport: + vport.LinkUpDn(action) def getAllVportList(self): """ @@ -249,10 +208,14 @@ def getAllVportList(self): Returns a list of all the created virtual ports Returns - List of vports: ['/api/v1/sessions/1/ixnetwork/vport/1', '/api/v1/sessions/1/ixnetwork/vport/2'] - """ - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/vport') - vportList = ['%s' % vport['links'][0]['href'] for vport in response.json()] + List of vport Objects: + [, + ] + """ + self.ixnObj.logInfo("Get vports for all ports") + vportList = self.ixNetwork.Vport.find() + if not vportList: + raise Exception("vport list is empty hence failing") return vportList def getVports(self, portList): @@ -261,20 +224,21 @@ def getVports(self, portList): Get the vports for the portList Parameter - portList: : A list of ports in a list: [[str(chassisIp), str(slotNumber), str(portNumber)]] + portList: : A list of ports in a list: + [[str(chassisIp), str(slotNumber), str(portNumber)]] Example 1: [[ixChassisIp, '1', '1']] Example 2: [[ixChassisIp, '1', '1'], [ixChassisIp, '2', '1']] Returns - Vports in a list: ['/api/v1/sessions/1/ixnetwork/vport/1', /api/v1/sessions/1/ixnetwork/vport/2'] + Vports Objects in a list: + [, + ] """ - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/vport') vportList = [] - for vportAttributes in response.json(): - currentVportId = vportAttributes['links'][0]['href'] - # "assignedTo": "192.168.70.10:1:1 - assignedTo = vportAttributes['assignedTo'] + self.ixnObj.logInfo("get vport objects for portList {}".format(portList)) + for vport in self.ixnObj.ixNetwork.Vport.find(): + assignedTo = vport.AssignedTo if assignedTo == '': continue @@ -282,14 +246,12 @@ def getVports(self, portList): cardNum = assignedTo.split(':')[1] portNum = assignedTo.split(':')[2] port = [chassisIp, cardNum, portNum] - if port in portList: - # ['192.168.70.10', '1', '1'] - vport = vportAttributes['links'][0]['href'] vportList.append(vport) - # Returns: - # ['/api/v1/sessions/1/ixnetwork/vport/1', /api/v1/sessions/1/ixnetwork/vport/2'] + if not vportList: + raise Exception("Unable to find vport for the given portList {} ".format(portList)) + return vportList def getPhysicalPortsFromCreatedVports(self): @@ -298,21 +260,22 @@ def getPhysicalPortsFromCreatedVports(self): Get all the ports that are configured. Return - None or a list of ports in format: [['192.168.70.11', '1', '1'], ['192.168.70.11', '2', '1']] + None or a list of ports in format: + [['192.168.70.11', '1', '1'], ['192.168.70.11', '2', '1']] """ + self.ixnObj.logInfo("get physical port details from all vport objects ") portList = [] - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/vport') - vportList = ['%s' % vport['links'][0]['href'] for vport in response.json()] + for vport in self.ixnObj.ixNetwork.Vport.find(): + assignedTo = vport.AssignedTo + if assignedTo == '': + continue + + chassisIp = assignedTo.split(':')[0] + cardNum = assignedTo.split(':')[1] + portNum = assignedTo.split(':')[2] + port = [chassisIp, cardNum, portNum] + portList.append(port) - for eachVport in vportList: - response = self.ixnObj.get(self.ixnObj.httpHeader+eachVport) - assignedTo = response.json()['assignedTo'] - # assignedTo: 192.168.70.11:2:1 - if assignedTo: - chassis = assignedTo.split(':')[0] - card = assignedTo.split(':')[1] - port = assignedTo.split(':')[2] - portList.append([chassis, card, port]) return portList def getPhysicalPortFromVport(self, vportList): @@ -326,163 +289,77 @@ def getPhysicalPortFromVport(self, vportList): Returns A list of ports: ['192.168.70.11:1:1'] """ + + self.ixnObj.logInfo("get physical port details from particular vport objects ") + portList = [] - for eachVport in vportList: - response = self.ixnObj.get(self.ixnObj.httpHeader+eachVport) - assignedTo = response.json()['assignedTo'] - if assignedTo: - portList.append(assignedTo) + for vport in vportList: + port = vport.AssignedTo + if port: + portList.append(port) return portList def verifyPortConnectionStatus(self, vport=None): """ Description - Verify port connection status for errors such as License Failed, + Verify port connection status for errors such as License Failed, Version Mismatch, Incompatible IxOS version, or any other error. """ - self.ixnObj.logInfo('verifyPortConnectionStatus') - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/vport') - - for vport in response.json(): - connectionStatus = vport['connectionStatus'] - if 'Port Released' in connectionStatus: - raise IxNetRestApiException(connectionStatus) + self.ixnObj.logInfo('verifyPortConnectionStatus raise exception if any port is not ' + 'connected to') + if vport: + if 'Port Released' in vport.ConnectionStatus: + raise Exception(vport.ConnectionStatus) + else: + for vport in self.ixNetwork.Vport.find(): + if 'Port Released' in vport.ConnectionStatus: + raise Exception(vport.ConnectionStatus) def assignPorts(self, portList, forceTakePortOwnership=True, createVports=False, rawTraffic=False, configPortName=True, timeout=900): """ Description - Assuming that you already connected to an ixia chassis and ports are available for usage. - Use this API to assign physical ports to the virtual ports. + Assuming that you already connected to an ixia chassis and ports are available for + usage. Use this API to assign physical ports to the virtual ports. Parameters - portList: : A list of ports in a list: [ [ixChassisIp, '1','1'], [ixChassisIp, '1','2'] ] + portList: : A list of ports in a list: + [ [ixChassisIp, '1','1'], [ixChassisIp, '1','2'] ] forceTakePortOwnership: : True = Forcefully take ownership of portList. createVports: : Optional: If True: Create vports to the amount of portList. - If False: Automatically create vport on the server side. Optimized for port bootup performance. - - rawTraffic: : If traffic item is raw, then vport needs to be /vport/{id}/protocols - resetPortCput: : Default=False. Some cards like the Novus 10GigLan requires a cpu reboot. - timeout: : Timeout for port up state. Default=600 seconds. - - Syntaxes - POST: /api/v1/sessions/{id}/ixnetwork/operations/assignports - data={arg1: [{arg1: ixChassisIp, arg2: 1, arg3: 1}, {arg1: ixChassisIp, arg2: 1, arg3: 2}], - arg2: [], - arg3: ['/api/v1/sessions/{1}/ixnetwork/vport/1', - '/api/v1/sessions/{1}/ixnetwork/vport/2'], - arg4: true} <-- True will clear port ownership - headers={'content-type': 'application/json'} - - GET: /api/v1/sessions/{id}/ixnetwork/operations/assignports/1 - data={} - headers={} - Expecting: RESPONSE: SUCCESS - """ - # Verify if the portList has duplicates. - self.verifyForDuplicatePorts(portList) + If False: Automatically create vport on the server side. + Optimized for port bootup performance. - # Verify if there is existing vports. If yes, user either loaded a saved config file or - # the configuration already has vports. - # If loading a saved config file and reassigning ports, assign ports to existing vports. - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/vport') + rawTraffic: : Ignored in Restpy + timeout: : Ignored in Restpy + configPortName : : Optional: + If True: Configure vportname based on card and port Id. + If False: Default vportname - # If response.json() != [], means there are existing vports created already. - if response.json() != []: - mode = 'modify' - preamble = self.ixnObj.sessionUrl.split('/api')[1] - vportList = ["/api%s/vport/%s" % (preamble, str(i["id"])) for i in response.json()] - if len(vportList) != len(portList): - raise IxNetRestApiException('assignPorts: The amount of configured virtual ports:{0} is not equal to the amount of portList:{1}'.format(len(vportList), len(portList))) + """ + if createVports: + self.createVports(portList) + testPorts = [] + vportList = [vport for vport in self.ixNetwork.Vport.find()] + for port in portList: + testPorts.append(dict(Arg1=port[0], Arg2=port[1], Arg3=port[2])) + self.ixnObj.logInfo('\nAssignPorts: {0}'.format(portList)) - else: - if createVports == False: - vportList = [] - - if createVports: - self.createVports(portList) - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/vport') - preamble = self.ixnObj.sessionUrl.split('/api')[1] - - vportList = ["/api%s/vport/%s" % (preamble, str(i["id"])) for i in response.json()] - if len(vportList) != len(portList): - raise IxNetRestApiException('assignPorts: The amount of configured virtual ports:{0} is not equal to the amount of portList:{1}'.format(len(vportList), len(portList))) - - #data = {"arg1": [], "arg2": [], "arg3": vportList, "arg4": 'true'} - data = {"arg1": [], "arg2": [], "arg3": vportList, "arg4": forceTakePortOwnership} - [data["arg1"].append({"arg1":str(chassis), "arg2":str(card), "arg3":str(port)}) for chassis,card,port in portList] - url = self.ixnObj.sessionUrl+'/operations/assignports' - response = self.ixnObj.post(url, data=data) - response = self.ixnObj.waitForComplete(response, url + '/' + response.json()['id'], silentMode=False, timeout=timeout, ignoreException=True) - - # Ignore these verifications. Avoid trying to resolve too many issues. - ''' - if response.json()['state'] in ['ERROR', 'EXCEPTION']: - # Some cards like the Novus 10gLan sometimes requires a cpu reboot. - # To reboot the port cpu, the ports have to be assigned to a vport first. - # So it has to be done at this spot. - self.resetPortCpu(vportList=vportList, portList=portList) - self.verifyPortState() - raise IxNetRestApiException('assignPort Error: {}'.format(response.json()['message'])) - elif response.json()['state'] == 'IN_PROGRESS': - raise IxNetRestApiException('assignPort Error: Port failed to boot up after 120 seconds') - else: - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/vport') - for vport in response.json(): - chassisIp = vport['assignedTo'].split(':')[0] - slot = vport['assignedTo'].split(':')[1] - port = vport['assignedTo'].split(':')[2] - currentPort = [chassisIp, int(slot), int(port)] - for chassis,card,port in portList: - currentPortList = [chassis, int(card), int(port)] - if set(currentPort) & set(currentPortList): - if 'License Failed' in vport['connectionStatus']: - raise IxNetRestApiException('Port License failed.') - - if vport['connectionStatus'] == 'connectedLinkDown': - raise IxNetRestApiException('Port link connection is down: {0}'.format(vport['assignedTo'])) - ''' - - # Verify if port license was the cause of the assignport failure - if response.json()['state'] in ['ERROR', 'EXCEPTION']: - vportResponse = self.ixnObj.get(self.ixnObj.sessionUrl+'/vport') - for vport in vportResponse.json(): - chassisIp = vport['assignedTo'].split(':')[0] - slot = vport['assignedTo'].split(':')[1] - port = vport['assignedTo'].split(':')[2] - currentPort = [chassisIp, int(slot), int(port)] - - for chassis,card,port in portList: - currentPortList = [chassis, int(card), int(port)] - if set(currentPort) & set(currentPortList): - if 'License Failed' in vport['connectionStatus']: - raise IxNetRestApiException('Port License failed.') - if vport['connectionStatus'] == 'connectedLinkDown': - raise IxNetRestApiException('Port link connection is down: {0}'.format(vport['assignedTo'])) - - raise IxNetRestApiException('AssignPort failed: {}'.format(response.json())) - - if response.json()['state'] == 'IN_PROGRESS': - raise IxNetRestApiException('AssignPort failed: It has been 10 minutes and the ports have not booted up successful. Something is wrong. Maybe you need to reboot the port CPU.') + try: + self.ixNetwork.AssignPorts(testPorts, [], vportList, forceTakePortOwnership) + except Exception as err: + self.ixnObj.logInfo('Errored : \n {}'.format(err)) + raise Exception("Failed to Assign ports {} ".format(portList)) if configPortName: # Name the vports - for vportObj in self.getAllVportList(): - port = self.getPhysicalPortFromVport([vportObj])[0] - chassisIp = port.split(':')[0] + for vportObj in self.ixNetwork.Vport.find(): + port = vportObj.AssignedTo card = port.split(':')[1] port = port.split(':')[2] - self.ixnObj.patch(self.ixnObj.httpHeader+vportObj, data={'name': 'Port'+card+'_'+port}) - - if rawTraffic: - vportProtocolList = [] - for vport in self.getAllVportList(): - vportProtocolList.append(vport+'/protocols') - return vportProtocolList - else: - return vportList + vportObj.Name = 'Port' + card + '_' + port def unassignPorts(self, deleteVirtualPorts=False): """ @@ -493,32 +370,21 @@ def unassignPorts(self, deleteVirtualPorts=False): deleteVirtualPorts: : True = Delete the virtual ports from the configuration. False = Unassign the virtual ports from the configuration. - - Syntaxes - POST: http://{apiServerIp:port}/api/v1/sessions/{id}/ixnetwork/vport/operations/unassignports - data={arg1: [http://{apiServerIp:port}/api/v1/sessions/{id}/ixnetwork/vport/1, - http://{apiServerIp:port}/api/v1/sessions/{id}/ixnetwork/vport/2], - arg2: true|false} """ - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/vport') - vportList = ["%s/vport/%s" % (self.ixnObj.sessionUrl, str(i["id"])) for i in response.json()] - url = self.ixnObj.sessionUrl+'/vport/operations/unassignports' - response = self.ixnObj.post(url, data={'arg1': vportList, 'arg2': deleteVirtualPorts}) - self.ixnObj.waitForComplete(response, self.ixnObj.sessionUrl+'/vport/operations/unassignports/'+response.json()['id'], timeout=120) + + self.ixnObj.logInfo('Unassign all ports') + for vport in self.ixNetwork.Vport.find(): + vport.UnassignPorts(Arg2=deleteVirtualPorts) def releaseAllPorts(self): """ Description Release all the connected ports. """ - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/vport') - vportList = ["%s/vport/%s" % (self.ixnObj.sessionUrl, str(i["id"])) for i in response.json()] - url = self.ixnObj.sessionUrl+'/vport/operations/releaseport' - response = self.ixnObj.post(url, data={'arg1': vportList}) - if response.json()['state'] == 'SUCCESS': return 0 - if response.json()['id'] != '': - self.ixnObj.waitForComplete(response, url+'/'+response.json()['id'], timeout=120) - + self.ixnObj.logInfo('Release all ports from configuration') + for vport in self.ixNetwork.Vport.find(): + vport.ReleasePort() + def releasePorts(self, portList): """ Description @@ -528,32 +394,28 @@ def releasePorts(self, portList): portList: : A list of ports in a list, to release in format of... [[ixChassisIp, str(cardNum), str(portNum)], [], [] ...] """ - vportList = [] - for port in portList: - vport = self.getVports([port]) - if vport == []: - continue - vportList.append(vport[0]) - url = self.ixnObj.sessionUrl+'/vport/operations/releaseport' - response = self.ixnObj.post(url, data={'arg1': vportList}) - self.ixnObj.waitForComplete(response, url+'/'+response.json()['id'], timeout=120) + self.ixnObj.logInfo('Release selected ports {} from configuration'.format(portList)) + vportList = self.getVports(portList) + for vport in vportList: + vport.ReleasePort() def resetPortCpu(self, vportList=None, portList=None, timeout=90): """ Description Reset/Reboot ports CPU. Must call IxNetRestApi.py waitForComplete() afterwards to verify port state - + Parameter vportList: : A list of one or more vports to reset. """ - url = self.ixnObj.sessionUrl+'/vport/operations/resetportcpu' - if vportList == None: + + self.ixnObj.logInfo('Reset all / selected ports from configuration') + if vportList is None: vportList = self.getVportFromPortList(portList) - response = self.ixnObj.post(url, data={'arg1': vportList}) - self.ixnObj.waitForComplete(response, url + '/' +response.json()['id'], silentMode=False, timeout=timeout) + for vport in vportList: + vport.ResetPortCpu() def clearPortOwnership(self, portList): """ @@ -563,20 +425,16 @@ def clearPortOwnership(self, portList): Parameters portList: : A list of ports in a list: [[chassisIp, cardId, portId]] """ - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/availableHardware/chassis') - for eachChassis in response.json(): - chassisIp = eachChassis['ip'] - chassisHref = eachChassis['links'][0]['href'] - - for userPort in portList: - userChassisIp = userPort[0] - if userChassisIp != chassisIp: - continue - userCardId = userPort[1] - userPortId = userPort[2] - url = self.ixnObj.httpHeader+chassisHref+'/card/'+str(userCardId)+'/port/'+str(userPortId)+'/operations/clearownership' - data = {'arg1': [chassisHref+'/card/'+str(userCardId)+'/port/'+str(userPortId)]} - self.ixnObj.post(url, data=data) + self.ixnObj.logInfo('Clear port ownership for ports {}'.format(portList)) + for port in portList: + ixChassisIp = port[0] + cardId = port[1] + portId = port[2] + for chassisObj in self.ixNetwork.AvailableHardware.Chassis.find(Hostname=ixChassisIp): + for cardObj in chassisObj.Card.find(CardId=cardId): + portObj = cardObj.Port.find(PortId=portId) + if portObj: + portObj.ClearOwnership() def isPortConnected(self, portList): """ @@ -584,25 +442,23 @@ def isPortConnected(self, portList): Verify if the port is connected or released Parameters - portList: : A list of ports in a list: [[ixChassisIp, str(cardNumber), str(portNumber)]] + portList: : A list of ports in a list: + [[ixChassisIp, str(cardNumber), str(portNumber)]] Return A list of 'connected' and 'released'. """ + self.ixnObj.logInfo('Verify {} is connected or released '.format(portList)) returnValues = [] for port in portList: vport = self.getVports([port]) if vport == []: returnValues.append('released') continue - response = self.ixnObj.get(self.ixnObj.httpHeader+vport[0]) - connectedStatus = response.json()['connectionStatus'] - print('\nisPortConnected:', port) - if connectedStatus == 'Port Released': - self.ixnObj.logInfo('\tFalse: %s' % connectedStatus) + + if 'Port Released' in vport.ConnectionStatus: returnValues.append('released') else: - self.ixnObj.logInfo('\tTrue: %s' % connectedStatus) returnValues.append('connected') return returnValues @@ -612,9 +468,11 @@ def verifyForDuplicatePorts(self, portList): Verify if the portList has any duplicate ports. Raise an exception if true. """ - duplicatePorts = [x for n, x in enumerate(portList) if x in portList[:n]] + duplicatePorts = [port for numberOfPorts, port in enumerate(portList) if port in + portList[:numberOfPorts]] if duplicatePorts: - raise IxNetRestApiException('\nYour portList has duplicate ports {0}'.format(duplicatePorts)) + raise IxNetRestApiException('\nYour portList has duplicate ports {0}'. + format(duplicatePorts)) def arePortsAvailable(self, portList, raiseException=True): """ @@ -632,38 +490,24 @@ def arePortsAvailable(self, portList, raiseException=True): """ # Verify if the portList has duplicates. self.verifyForDuplicatePorts(portList) - self.ixnObj.logInfo('Verify if ports are currently owned') portOwnedList = [] for port in portList: - chassisIp = port[0] + ixChassisIp = port[0] cardId = port[1] portId = port[2] - try: - queryData = {"from": "/availableHardware", - "nodes": [{"node": "chassis", "properties": ["ip"], "where": [{"property": "ip", "regex": chassisIp}]}, - {"node": "card", "properties": ["cardId"], "where": [{"property": "cardId", "regex": cardId}]}, - {"node": "port", "properties": ["portId", "owner"], "where": [{"property": "portId", "regex": portId}]}]} - - self.ixnObj.logInfo('Querying for %s/%s/%s' % (chassisIp, cardId, portId)) - queryResponse = self.ixnObj.query(data=queryData, silentMode=False) - - queryResponse.json()['result'][0]['chassis'][0]['ip'] - queryResponse.json()['result'][0]['chassis'][0]['card'][0]['id'] - queryResponse.json()['result'][0]['chassis'][0]['card'][0]['port'][0]['portId'] - except: - raise IxNetRestApiException('\nNot found: {0}:{1}:{2}'.format(chassisIp, cardId, portId)) - - self.ixnObj.logInfo('Port currently owned by: %s' % queryResponse.json()['result'][0]['chassis'][0]['card'][0]['port'][0]['owner']) - if queryResponse.json()['result'][0]['chassis'][0]['card'][0]['port'][0]['owner'] != '': - self.ixnObj.logInfo('Port is still owned: {0}/cardId:{1}/portId:{2}'.format(chassisIp, cardId, portId)) - portOwnedList.append([chassisIp, cardId, portId]) - - self.ixnObj.logInfo('Ports are still owned: %s' % portOwnedList) + for chassisObj in self.ixNetwork.AvailableHardware.Chassis.find(Hostname=ixChassisIp): + for cardObj in chassisObj.Card.find(CardId=cardId): + portObj = cardObj.Port.find(PortId=portId) + if portObj: + if portObj.Owner != '': + self.ixnObj.logInfo( + '{0} is currently owned by: {1}'.format(port, portObj.Owner)) + portOwnedList.append([ixChassisIp, cardId, portId]) if portOwnedList != []: if raiseException: - raise IxNetRestApiException('arePortsAvailable: Ports are still owned') + raise Exception('arePortsAvailable: Ports are still owned') else: return portOwnedList return 0 @@ -676,28 +520,24 @@ def verifyPortState(self, timeout=70): Parameter timeout: : The timeout value to declare as failed. Default=70 seconds. """ - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/vport') - vportList = [metaDatas["links"][0]['href'] for metaDatas in response.json()] - for eachVport in vportList: - for counter in range(1,timeout+1): - stateResponse = self.ixnObj.get(self.ixnObj.httpHeader+eachVport+'?includes=state,connectionStatus', silentMode=True) - assignedToResponse = self.ixnObj.get(self.ixnObj.httpHeader+eachVport+'?includes=assignedTo', silentMode=True) - - if 'Port Released' in stateResponse.json()['connectionStatus']: - raise IxNetRestApiException(stateResponse.json()['connectionStatus']) - if stateResponse.json()['state'] == 'unassigned': - self.ixnObj.logWarning('\nThe vport {0} is not assigned to a physical port. Skipping this vport verification.'.format(eachVport)) + vportList = [vport for vport in self.ixNetwork.Vport.find()] + for vport in vportList: + for counter in range(1, timeout + 1): + if 'Port Released' in vport.ConnectionStatus: + raise Exception(vport.ConnectionStatus) + if not vport.IsConnected: + self.ixnObj.logWarning('\nThe vport {0} is not assigned to a physical port. ' + 'Skipping this vport verification.'.format(vport.href)) break - - self.ixnObj.logInfo('Port: %s' % assignedToResponse.json()['assignedTo']) - self.ixnObj.logInfo('\tVerifyPortState: %s\n\tWaiting %s/%s seconds' % (stateResponse.json()['state'], counter, timeout), timestamp=False) - if counter < timeout and stateResponse.json()['state'] in ['down', 'busy']: + if vport.ConnectionState in ['down', 'connecting']: time.sleep(1) continue - if counter < timeout and stateResponse.json()['state'] in ['up', 'connectedLinkUp']: + if vport.ConnectionState in ['up', 'connectedLinkUp']: break - if counter == timeout and stateResponse.json()['state'] == 'down': + if counter == timeout and vport.ConnectionState in ['assignedInUseByOther', + 'assignedUnconnected', + 'connectedLinkDown']: # Failed raise IxNetRestApiException('Port failed to come up') @@ -707,59 +547,49 @@ def getVportFromPortList(self, portList): Get a list of vports from the specified portList. Parameter - portList: : Format: [[ixChassisIp, cardNumber1, portNumber1], [ixChassisIp, cardNumber1, portNumber2]] - + portList: : Format: [[ixChassisIp, cardNumber1, portNumber1], + [ixChassisIp, cardNumber1, portNumber2]] + Return A list of vports. [] if vportList is empty. """ - vportList = [] - for eachPort in portList: - chassisIp = eachPort[0] - card = eachPort[1] - portNum = eachPort[2] - port = chassisIp+':'+card+':'+portNum - # {'href': '/api/v1/sessions/1/ixnetwork/', - # 'vport': [{'id': 2, 'href': '/api/v1/sessions/1/ixnetwork/vport/2', 'assignedTo': '10.10.10.8:1:2'}]} - queryData = {"from": "/", - "nodes": [{"node": "vport", "properties": ["assignedTo"], - "where": [{"property": "assignedTo", "regex": port}] - }]} - - queryResponse = self.ixnObj.query(data=queryData, silentMode=False) - vport = queryResponse.json()['result'][0]['vport'] - if vport == []: - raise IxNetRestApiException('getVportFromPortList error: The port has no vport and not assigned. Check for port typo: {0}'.format(port)) + regexString = '' + for port in portList: + # Construct the regex string format = '(1.1.1.1:2:3)|(1.1.1.1:6:2)' + regexString = \ + regexString + '(' + str(port[0]) + ':' + str(port[1]) + ':' + str(port[2]) + ')' + if port != portList[-1]: + regexString = regexString + '|' + vports = [vport for vport in self.ixNetwork.Vport.find(AssignedTo=regexString)] + if not vports: + raise Exception("unable to find vports for ports {} ".format(portList)) + return vports - if vport: - # Appending vportList: ['/api/v1/sessions/1/ixnetwork/vport/1', '/api/v1/sessions/1/ixnetwork/vport/2'] - vportList.append(vport[0]['href']) - return vportList - def modifyPortMediaType(self, portList='all', mediaType='fiber'): """ Description Modify the port media type: fiber, copper, SGMII Parameters - portList: <'all'|list of ports>: + portList: <'all'|list of ports>: : Format: [[ixChassisIp, str(cardNumber1), str(portNumber1])]...] - Or if portList ='all', will modify all assigned ports to the specified mediaType. + Or if portList ='all', + will modify all assigned ports to the specified mediaType. mediaType: : copper, fiber or SGMII """ self.ixnObj.logInfo('modifyPortMediaType: {0}'.format(mediaType)) - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/vport') if portList == 'all': - #vportList = self.getAllVportList() - portList = self.getPhysicalPortsFromCreatedVports() + vportList = self.getAllVportList() + else: + vportList = self.getVports(portList) - # vportList: ['/api/v1/sessions/1/ixnetwork/vport/1', '/api/v1/sessions/1/ixnetwork/vport/2'] - vportList = self.getVportFromPortList(portList) for vport in vportList: - response = self.ixnObj.get(self.ixnObj.httpHeader+vport, silentMode=True) - portType = response.json()['type'] - self.ixnObj.patch(self.ixnObj.httpHeader+vport+'/l1Config/'+portType, data={'media': mediaType}) + cardType = vport.Type + cardType = cardType[0].upper() + cardType[1:] + cardObj = getattr(vport.L1Config, cardType) + cardObj.Media = mediaType def modifyL1Config(self, configSettings, portList='all'): """ @@ -767,13 +597,14 @@ def modifyL1Config(self, configSettings, portList='all'): Modify Layer 1 Configuration Parameters - portList: <'all'|list of ports>: + portList: <'all'|list of ports>: : Format: [[ixChassisIp, str(cardNumber1), str(portNumber1])]...] - Or if portList ='all', will modify all assigned ports to the specified configSettings. + Or if portList ='all', will modify all assigned ports to the specified + configSettings. Note: all ports must be of the same type configSettings: : L1 Settings. The actual settings depend on the card type. - example for novusHundredGigLan card: + example for novusHundredGigLan card: configSettings ={'enabledFlowControl': True, 'flowControlDirectedAddress': '01 80 C2 00 00 00 CC', 'txIgnoreRxLinkFaults': False, @@ -790,43 +621,49 @@ def modifyL1Config(self, configSettings, portList='all'): 'rsFecForceOn': False, 'forceDisableFEC': False} """ - self.ixnObj.logInfo('modifyL1Config: portList = {} configSettings = {}'.format(portList, configSettings)) - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/vport') + self.ixnObj.logInfo( + 'modifyL1Config: portList = {} configSettings = {}'.format(portList, configSettings)) + if portList == 'all': - #vportList = self.getAllVportList() - portList = self.getPhysicalPortsFromCreatedVports() + vportList = self.getAllVportList() + else: + vportList = self.getVports(portList) - # vportList: ['/api/v1/sessions/1/ixnetwork/vport/1', '/api/v1/sessions/1/ixnetwork/vport/2'] - vportList = self.getVportFromPortList(portList) for vport in vportList: - response = self.ixnObj.get(self.ixnObj.httpHeader+vport, silentMode=True) - portType = response.json()['type'] - # There are several portTypes that ends with 'Fcoe'. This has to be stripped. - portType = portType.strip('Fcoe') - self.ixnObj.patch(self.ixnObj.httpHeader+vport+'/l1Config/'+portType, data=configSettings) + cardType = vport.Type + cardType = cardType[0].upper() + cardType[1:] + obj = getattr(vport.L1Config, cardType) + for key, value in configSettings.items(): + key = key[0].upper() + key[1:] + try: + setattr(obj, key, value) + except Exception as err: + self.ixnObj.logInfo('Errored : \n {}'.format(err)) + raise Exception("Failed setting value {} for {} in L1config".format(value, key)) - def configLoopbackPort(self, portList='all', enabled=True): """ Description Configure port to loopback. Parameters - portList: <'all'|list of ports>: + portList: <'all'|list of ports>: : Format: [[ixChassisIp, str(cardNumber1), str(portNumber1])]...] - Or if portList ='all', will modify all assigned ports to the specified mediaType. + Or if portList ='all', will modify all assigned ports to the specified + mediaType. enabled: : True=Enable port to loopback mode. """ - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/vport') if portList == 'all': - portList = self.getPhysicalPortsFromCreatedVports() + vportList = self.getAllVportList() + else: + vportList = self.getVports(portList) - vportList = self.getVportFromPortList(portList) for vport in vportList: - response = self.ixnObj.get(self.ixnObj.httpHeader+vport+'/l1Config', silentMode=False) - currentPortType = response.json()['currentType'] - self.ixnObj.patch(self.ixnObj.httpHeader+vport+'/l1Config/'+currentPortType, data={'loopback': enabled}) + cardType = vport.Type + cardType = cardType[0].upper() + cardType[1:] + cardObj = getattr(vport.L1Config, cardType) + cardObj.Loopback = enabled def setTxMode(self, vportList='all', txMode='interleaved', timeout=70): """ @@ -837,14 +674,12 @@ def setTxMode(self, vportList='all', txMode='interleaved', timeout=70): vportList: : vports to set the transmitMode on. Default = all txMode: : transmit mode setting - can be either 'interleaved' or 'sequential' timeout: : the timeout value to declare as failed. Default=70 seconds. + """ if vportList == 'all': - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/vport') - vportList = ['%s' % vport['links'][0]['href'] for vport in response.json()] - - # vportList: ['/api/v1/sessions/1/ixnetwork/vport/1', '/api/v1/sessions/1/ixnetwork/vport/2'] + vportList = self.getAllVportList() for eachVport in vportList: - self.ixnObj.patch(self.ixnObj.httpHeader+eachVport, data={'txMode':txMode}) + eachVport.TxMode = txMode def configUdsRxFilters(self, portList='all', filterPalette=None, udsNum='1', udsArgs=None): """ @@ -852,40 +687,58 @@ def configUdsRxFilters(self, portList='all', filterPalette=None, udsNum='1', uds Configure rxFilters and User Defined Stats on a port Parameters - portList: <'all'|list of ports>: + portList: <'all'|list of ports>: : Format: [[ixChassisIp, str(cardNumber1), str(portNumber1])]...] - Or if portList ='all', will modify all assigned ports to the specified mediaType. + Or if portList ='all', will modify all assigned ports to the specified + mediaType. filterPalette: Filter Palette kwargs. - udsNum: : uds number + udsNum: : uds number udsArgs: uds kwargs. USAGE EXAMPLE: - portMgmtObj.configUdsRxFilters(portList=[['10.113.9.219', '6', '1']], + portMgmtObj.configUdsRxFilters(portList=[['10.113.9.219', '6', '1']], filterPalette={'pattern1':'01', 'pattern1Mask':'FC', - 'pattern1Offset':'15', 'pattern1OffsetType':'fromStartOfFrame', + 'pattern1Offset':'15', + 'pattern1OffsetType':'fromStartOfFrame', udsNum=1 - udsArgs={'isEnabled':'true', 'patternSelector':'pattern1'}) + udsArgs={'isEnabled':'true', + 'patternSelector':'pattern1'}) - portMgmtObj.configUdsRxFilters(portList=[['10.113.9.219', '6', '1']], + portMgmtObj.configUdsRxFilters(portList=[['10.113.9.219', '6', '1']], filterPalette={'pattern2':'03', 'pattern2Mask':'FC', - 'pattern2Offset':'19', 'pattern2OffsetType':'fromStartOfFrame', + 'pattern2Offset':'19', + 'pattern2OffsetType':'fromStartOfFrame', udsNum=2 - udsArgs={'isEnabled':'true', 'patternSelector':'pattern2'}) + udsArgs={'isEnabled':'true', + 'patternSelector':'pattern2'}) """ self.ixnObj.logInfo('configUdsRxFilters: filterPalette={0}'.format(filterPalette)) self.ixnObj.logInfo('\t\t uds={0} udsArgs={1}'.format(udsNum, udsArgs)) - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/vport') if portList == 'all': - #vportList = self.getAllVportList() - portList = self.getPhysicalPortsFromCreatedVports() + vportList = self.getAllVportList() + else: + vportList = self.getVports(portList) - # vportList: ['/api/v1/sessions/1/ixnetwork/vport/1', '/api/v1/sessions/1/ixnetwork/vport/2'] - vportList = self.getVportFromPortList(portList) for vport in vportList: - response = self.ixnObj.get(self.ixnObj.httpHeader+vport, silentMode=True) - portType = response.json()['type'] - self.ixnObj.patch(self.ixnObj.httpHeader+vport+'/l1Config/rxFilters/filterPalette', data=filterPalette) - self.ixnObj.patch(self.ixnObj.httpHeader+vport+'/l1Config/rxFilters/uds/'+udsNum, data=udsArgs) - + filterObj = vport.L1Config.RxFilters.FilterPalette + for key, value in filterPalette.items(): + key = key[0].upper() + key[1:] + try: + setattr(filterObj, key, value) + except Exception as err: + self.ixnObj.logInfo('Errored : \n {}'.format(err)) + raise Exception( + "Failed setting value {} for {} in filterpallete ".format(value, key)) + + for udsObj in vport.L1Config.RxFilters.Uds.find(): + if udsNum == udsObj.href.split("/")[-1]: + for key, value in udsArgs.items(): + key = key[0].upper() + key[1:] + try: + setattr(udsObj, key, value) + except Exception as err: + self.ixnObj.logInfo('Errored : \n {}'.format(err)) + raise Exception( + "Failed setting value {} for {} in uds".format(value, key)) diff --git a/RestApi/Python/Modules/IxNetRestApiProtocol.py b/RestApi/Python/Modules/IxNetRestApiProtocol.py index 87dbf6e9..741c7901 100644 --- a/RestApi/Python/Modules/IxNetRestApiProtocol.py +++ b/RestApi/Python/Modules/IxNetRestApiProtocol.py @@ -6,22 +6,18 @@ # # Here are some APIs that get object handles: # -# obj = getNgpfObjectHandleByName(ngpfEndpointObject='bgpIpv4Peer', ngpfEndpointName='bgp_2') +# obj = getNgpfObjectHandleByName(ngpfEndpointObject='bgpIpv4Peer',ngpfEndpointName='bgp_2') # # Get all device group objects for all the created topology groups -# obj = getTopologyObjAndDeviceGroupObjByPortName(portName='2/1'): -# Returns: ['/api/v1/sessions/1/ixnetwork/topology/2', ['/api/v1/sessions/1/ixnetwork/topology/2/deviceGroup/1']] +# obj = getTopologyObjAndDeviceGroupObjByPortName(portName='2/1') # # deviceGroupObj = getDeviceGroupObjAndIpObjBySrcIp(srcIpAddress='1.1.1.1') -# Returns: ('/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1', -# '/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1') # deviceGroupObj = getDeviceGroupByRouterId(routerId='192.0.0.3') # # ethernetObj = getNgpfObjectHandleByRouterId(routerId=routerId, ngpfEndpointObject='ethernet') # ipv4Obj = getIpv4ObjByPortName(portName='1/2') # # gatewayObj = getDeviceGroupSrcIpGatewayIp(srcIpAddress) -# # indexNumber = getIpAddrIndexNumber('10.10.10.1') # networkGroupObj = getNetworkGroupObjByIp(networkGroupIpAddress='10.10.10.1') @@ -29,7 +25,8 @@ # x = getProtocolListByHostIpNgpf('1.1.1.1') # objHandle = getProtocolObjFromHostIp(x, protocol='bgpIpv4Peer') # -# Get any NGPF object handle by either the physical port or by the vport name. +# Get any NGPF object handle by either the physical +# port or by the vport name. # x = getProtocolListByPortNgpf(port=['192.168.70.120', '1', '1']) # x = getProtocolListByPortNgpf(portName='1/1') # objHandle = getProtocolObjFromProtocolList(x['deviceGroup'], 'bgpIpv4Peer') @@ -39,41 +36,38 @@ # # Get a NGPF object handle that is configured in a Device Group by the name. # x = getEndpointObjByDeviceGroupName('DG-2', 'bgpIpv4Peer') -# -import re, time +import re +import time from IxNetRestApi import IxNetRestApiException from IxNetRestApiPortMgmt import PortMgmt from IxNetRestApiStatistics import Statistics +from IxNetRestApiClassicProtocol import ClassicProtocol -# 8.40 updates: -# sessionStatus uses ?includes=sessionStatus and then response.json()['sessionStatus'] -# - verifyProtocolSessionsNgpf -# - verifyAllProtocolSessionsInternal -# - getNgpfGatewayIpMacAddress (resolvedGatewayMac rquires ?includes=resolvedGatewayMac) -# - showTopologies -# - verifyArp -# -# bgpIpv4Peer/1: LocalIpv4Ver2 for localIpAddress is removed. -# class Protocol(object): def __init__(self, ixnObj=None, portMgmtObj=None): """ Parameters ixnObj: : The main connection object. - portMgmtObj: : Optional. This is deprecated. Leaving it here for backward compatibility. + portMgmtObj: : Optional. This is deprecated. Leaving it here + for backward compatibility. """ self.ixnObj = ixnObj + self.ixNetwork = ixnObj.ixNetwork self.configuredProtocols = [] - self.portMgmtObj = PortMgmt(self.ixnObj) self.statObj = Statistics(self.ixnObj) + self.classicProtocolObj = ClassicProtocol(self.ixnObj) + if portMgmtObj: + self.portMgmtObj = portMgmtObj + else: + self.portMgmtObj = PortMgmt(self.ixnObj) def setMainObject(self, mainObject): """ Description For Python Robot Framework support - + Parameter mainObject: : The connect object. """ @@ -95,31 +89,23 @@ def createTopologyNgpf(self, portList, topologyName=None): Create a new Topology and assign ports to it. Parameters - portList: : format = [[(str(chassisIp), str(slotNumber), str(portNumber)] ] + portList: : format = [[(str(chassisIp), + str(slotNumber), str(portNumber)] ] Example 1: [ ['192.168.70.10', '1', '1'] ] - Example 2: [ ['192.168.70.10', '1', '1'], ['192.168.70.10', '2', '1'] ] + Example 2: [ ['192.168.70.10', '1', '1'], + ['192.168.70.10', '2', '1'] ] topologyName: : Give a name to the Topology Group. - Syntax - POST: /api/v1/sessions/{id}/ixnetwork/topology - Return - /api/v1/sessions/{id}/topology/{id} + Topology Object """ - url = self.ixnObj.sessionUrl+'/topology' vportList = self.portMgmtObj.getVports(portList) - if len(vportList) != len(portList): - raise IxNetRestApiException('createTopologyNgpf: There is not enough vports created to match the number of ports.') + raise IxNetRestApiException('createTopologyNgpf: There is not enough vports created ' + 'to match the number of ports.') - topologyData = {'vports': vportList} - if topologyName != None: - topologyData['name'] = topologyName - - self.ixnObj.logInfo('Create new Topology Group') - response = self.ixnObj.post(url, data=topologyData) - topologyObj = response.json()['links'][0]['href'] + topologyObj = self.ixNetwork.Topology.add(Name=topologyName, Vports=vportList) return topologyObj def createDeviceGroupNgpf(self, topologyObj, multiplier=1, deviceGroupName=None): @@ -128,24 +114,11 @@ def createDeviceGroupNgpf(self, topologyObj, multiplier=1, deviceGroupName=None) Create a new Device Group. Parameters - topologyObj: : A Topology object: /api/v1/sessions/1/ixnetwork/topology/{id} + topologyObj: : A Topology object multiplier: : The amount of host to create (In integer). deviceGroupName: : Optional: Device Group name. - - Syntax - POST: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup - - Returns: - /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id} """ - url = self.ixnObj.httpHeader+topologyObj+'/deviceGroup' - deviceGroupData = {'multiplier': int(multiplier)} - if deviceGroupName != None: - deviceGroupData['name'] = deviceGroupName - - self.ixnObj.logInfo('Create new Device Group') - response = self.ixnObj.post(url, data=deviceGroupData) - deviceGroupObj = response.json()['links'][0]['href'] + deviceGroupObj = topologyObj.DeviceGroup.add(Name=deviceGroupName, Multiplier=multiplier) return deviceGroupObj def configLacpNgpf(self, ethernetObj, **kwargs): @@ -155,7 +128,6 @@ def configLacpNgpf(self, ethernetObj, **kwargs): Parameter ethernetObj: : The Ethernet stack object to create the LACP. - Example: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1 administrativeKey: : Default=1 actorSystemId: : Default='00 00 00 00 00 01'. @@ -164,41 +136,34 @@ def configLacpNgpf(self, ethernetObj, **kwargs): actorPortNumber: : Default=1 actorPortPriority: : Default=1 - Syntax - POST: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/lacp - PATCH: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/lacp/{id} - Return - /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/lacp/{id} + Lacp Object """ - response = self.ixnObj.post(self.ixnObj.httpHeader+ethernetObj+'/lacp') - lacpObj = response.json()['links'][0]['href'] + lacpObj = ethernetObj.Lacp.add() self.configuredProtocols.append(lacpObj) - self.ixnObj.logInfo('Create new LACP NGPF') - lacpResponse = self.ixnObj.get(self.ixnObj.httpHeader+lacpObj) - - lacpAttributes = ['administrativeKey', 'actorSystemId', 'actorSystemPriority', 'actorKey', 'actorPortNumber', 'actorPortPriority'] - - data = {} - for lacpAttribute in lacpAttributes: - if lacpAttribute in kwargs: - multiValue = lacpResponse.json()[lacpAttribute] - self.ixnObj.logInfo('Configuring LACP attribute: %s' % lacpAttribute) - self.ixnObj.patch(self.ixnObj.httpHeader+multiValue+"/singleValue", data={'value': kwargs[lacpAttribute]}) - data.update({'value': kwargs[lacpAttribute]}) - + for key, value in kwargs.items(): + key = key[0:1].capitalize() + key[1:] + try: + multiValueObj = getattr(lacpObj, key) + self.ixnObj.configMultivalue(multiValueObj, 'singlevalue', {'value': value}) + except(ValueError, Exception): + setattr(lacpObj, key, value) return lacpObj - def createEthernetNgpf(self, obj=None, port=None, portName=None, ngpfEndpointName=None, **kwargs): + def createEthernetNgpf(self, obj=None, port=None, portName=None, ngpfEndpointName=None, + **kwargs): """ Description - This API is for backward compatiblility. Use self.configEthernetNgpf() + This API is for backward compatiblility. + Use self.configEthernetNgpf() """ - ethernetObj = self.configEthernetNgpf(obj=obj, port=port, portName=portName, ngpfEndpointName=ngpfEndpointName, **kwargs) + ethernetObj = self.configEthernetNgpf(obj=obj, port=port, portName=portName, + ngpfEndpointName=ngpfEndpointName, **kwargs) return ethernetObj - def configEthernetNgpf(self, obj=None, port=None, portName=None, ngpfEndpointName=None, **kwargs): + def configEthernetNgpf(self, obj=None, port=None, portName=None, ngpfEndpointName=None, + **kwargs): """ Description Create or modify NGPF Ethernet. @@ -206,32 +171,31 @@ def configEthernetNgpf(self, obj=None, port=None, portName=None, ngpfEndpointNam To modify an existing Ethernet stack in NGPF, pass in the Ethernet object. Parameters - obj: : Device Group obj: '/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/2' - Ethernet obj: '/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1' - + obj: : Device Group obj + port: : Format: [ixChassisIp, str(cardNumber), str(portNumber)] + portName: : The virtual port name. + ngpfEndpointName: : The name that you configured for the NGPF Ethernet endpoint. name|ethernetName: : Ethernet name. macAddressMultivalueType: Default=counter. - Options: alternate, custom, customDistributed, random, repeatableRandom, - repeatableRandomRange, valueList + Options: alternate, custom, customDistributed, random, + repeatableRandom, repeatableRandomRange, valueList To get the multivalue settings, refer to the API browser. macAddress: : By default, IxNetwork will generate unique Mac Addresses. - {'start': '00:01:02:00:00:01', 'direction': 'increment', 'step': '00:00:00:00:00:01'} + configIpv4Ngpf {'start': '00:01:02:00:00:01','direction': 'increment', + 'step': '00:00:00:00:00:01'} Note: step: '00:00:00:00:00:00' means don't increment. macAddressPortStep:: disable|00:00:00:01:00:00 Incrementing the Mac address on each port based on your input. - '00:00:00:00:00:01' means to increment the last byte on each port. + '00:00:00:00:00:01' means to increment the last byte on each + port. vlanId: : Example: {'start': 103, 'direction': 'increment', 'step': 1} vlanPriority: : Example: {'start': 2, 'direction': 'increment', 'step': 1} mtu: : Example: {'start': 1300, 'direction': 'increment', 'step': 1}) - Syntax - POST: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet - PATCH: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id} - - Example: + Example: createEthernetNgpf(deviceGroupObj1, ethernetName='Eth1', macAddress={'start': '00:01:01:00:00:01', @@ -240,203 +204,177 @@ def configEthernetNgpf(self, obj=None, port=None, portName=None, ngpfEndpointNam macAddressPortStep='00:00:00:00:01:00', vlanId={'start': 128, 'direction': 'increment', 'step':0}, vlanPriority={'start': 7, 'direction': 'increment', 'step': 0}, - mtu={'start': 1400, 'direction': 'increment', 'step': 0}, + mtu={'start': 1400, 'direction': 'increment', 'step': 0}, ) """ - createNewEthernetObj = True - - # To create a new Ethernet object - if obj != None: - if 'ethernet' not in obj: - url = self.ixnObj.httpHeader+obj + '/ethernet' - self.ixnObj.logInfo('Create new Ethernet on NGPF') - response = self.ixnObj.post(url) - ethernetObj = response.json()['links'][0]['href'] + if obj is not None: - # To modify - if 'ethernet' in obj: - ethernetObj = obj - createNewEthernetObj = False - - # To modify - if ngpfEndpointName: - ethernetObj = self.getNgpfObjectHandleByName(ngpfEndpointName=ngpfEndpointName, ngpfEndpointObject='ethernet') - createNewEthernetObj = False + # To modify + if ngpfEndpointName: + ethObj = self.getNgpfObjectHandleByName(ngpfEndpointName=ngpfEndpointName, + ngpfEndpointObject='ethernet') - # To modify - if port: - x = self.getProtocolListByPortNgpf(port=port) - ethernetObj = self.getProtocolObjFromProtocolList(x['deviceGroup'], 'ethernet')[0] - createNewEthernetObj = False + # To modify + if port: + x = self.getProtocolListByPortNgpf(port=port) + ethObj = self.getProtocolObjFromProtocolList(x['deviceGroup'], 'ethernet')[0] - # To modify - if portName: - x = self.getProtocolListByPortNgpf(portName=portName) - ethernetObj = self.getProtocolObjFromProtocolList(x['deviceGroup'], 'ethernet')[0] - createNewEthernetObj = False + # To modify + if portName: + x = self.getProtocolListByPortNgpf(portName=portName) + ethObj = self.getProtocolObjFromProtocolList(x['deviceGroup'], 'ethernet')[0] - ethObjResponse = self.ixnObj.get(self.ixnObj.httpHeader+ethernetObj) + if 'ethernet' in obj.href: + ethObj = obj + else: + ethObj = obj.Ethernet.add() - if 'ethernetName' in kwargs or 'name' in kwargs: if 'ethernetName' in kwargs: - # This is to handle backward compatibility. This attribute should not be created. - # Should be using 'name'. - name = kwargs['ethernetName'] - if 'name' in kwargs: - name = kwargs['name'] - self.ixnObj.logInfo('Configure MAC address name') - self.ixnObj.patch(self.ixnObj.httpHeader+ethernetObj, data={'name': name}) - - if 'multiplier' in kwargs: - self.configDeviceGroupMultiplier(objectHandle=ethernetObj, multiplier=kwargs['multiplier'], applyOnTheFly=False) + kwargs['name'] = kwargs['ethernetName'] + del kwargs['ethernetName'] - if 'macAddress' in kwargs: - multivalue = ethObjResponse.json()['mac'] - self.ixnObj.logInfo('Configure MAC address. Attribute for multivalueId = jsonResponse["mac"]') - - # Default to counter - multivalueType = 'counter' + if 'macAddress' in kwargs: + macObj = ethObj.Mac + macValues = kwargs['macAddress'] + self.configMultivalue(macObj, 'counter', macValues) + del kwargs['macAddress'] - if 'macAddressMultivalueType' in kwargs: - multivalueType = kwargs['macAddressMultivalueType'] + if 'macAddressPortStep' in kwargs: + macStepObj = ethObj.Mac.Steps.find() + macStepValue = kwargs['macAddressPortStep'] - if multivalueType == 'random': - self.ixnObj.patch(self.ixnObj.httpHeader+multivalue, data={'pattern': 'random'}) - else: - self.configMultivalue(multivalue, multivalueType, data=kwargs['macAddress']) + if macStepValue != 'disabled': + macStepObj.Enabled = True + macStepObj.Step = macStepValue + else: + macStepObj.Enabled = False + del kwargs['macAddressPortStep'] + + if 'vlanId' in kwargs: + vlanObj = ethObj.Vlan.find().VlanId + enableVlanObj = ethObj.EnableVlans + enableVlanObj.Single(True) + + vlanValues = kwargs['vlanId'] + self.configMultivalue(vlanObj, 'counter', vlanValues) + del kwargs['vlanId'] + + if 'vlanPriority' in kwargs: + priorityObj = ethObj.Vlan.find().Priority + enableVlanObj = ethObj.EnableVlans + enableVlanObj.Single(True) + priorityValues = kwargs['vlanPriority'] + self.configMultivalue(priorityObj, 'counter', priorityValues) + del kwargs['vlanPriority'] + + for key, value in kwargs.items(): + key = key[0:1].capitalize() + key[1:] + multivalueObj = getattr(ethObj, key) + try: + if type(value) == dict: + self.configMultivalue(multivalueObj, 'counter', value) + else: + self.configMultivalue(multivalueObj, 'singlevalue', {'value': value}) + except Exception as e: + print(e) + setattr(ethObj, key, value) - # Config Mac Address Port Step - if 'macAddressPortStep' in kwargs: - self.ixnObj.logInfo('Configure MAC address port step') - portStepMultivalue = self.ixnObj.httpHeader + multivalue+'/nest/1' - if 'macAddressPortStep' in kwargs: - if kwargs['macAddressPortStep'] != 'disabled': - self.ixnObj.patch(portStepMultivalue, data={'step': kwargs['macAddressPortStep']}) - if kwargs['macAddressPortStep'] == 'disabled': - self.ixnObj.patch(portStepMultivalue, data={'enabled': False}) - - if 'vlanId' in kwargs and kwargs['vlanId'] != None: - # Enable VLAN - if createNewEthernetObj == True: - multivalue = ethObjResponse.json()['enableVlans'] - self.ixnObj.logInfo('Enabling VLAN ID. Attribute for multivalueId = jsonResponse["enablevlans"]') - self.configMultivalue(multivalue, 'singleValue', data={'value': True}) - - # CREATE vlan object (Creating vlanID always /vlan/1 and then do a get for 'vlanId') - vlanIdObj = self.ixnObj.httpHeader+ethernetObj+'/vlan/1' - vlanIdResponse = self.ixnObj.get(vlanIdObj) - multivalue = vlanIdResponse.json()['vlanId'] - - # CONFIG VLAN ID - self.ixnObj.logInfo('Configure VLAN ID. Attribute for multivalueId = jsonResponse["vlanId"]') - self.configMultivalue(multivalue, 'counter', data=kwargs['vlanId']) - - # CONFIG VLAN PRIORITY - if 'vlanPriority' in kwargs and kwargs['vlanPriority'] != None: - multivalue = vlanIdResponse.json()['priority'] - self.ixnObj.logInfo('Configure VLAN ID priority. Attribute for multivalue = jsonResponse["priority"]') - self.configMultivalue(multivalue, 'counter', data=kwargs['vlanPriority']) - - if 'mtu' in kwargs and kwargs['mtu'] != None: - multivalue = ethObjResponse.json()['mtu'] - self.ixnObj.logInfo('Configure MTU. Attribute for multivalueId = jsonResponse["mtu"]') - self.configMultivalue(multivalue, 'counter', data=kwargs['mtu']) - - return ethernetObj + if ethObj not in self.configuredProtocols: + self.configuredProtocols.append(ethObj) + return ethObj - # Was configIsIsL3Ngpf def configIsIsL3Ngpf(self, obj, **data): """ Description Create or modify ethernet/ISISL3 Parameters - ethernetObj: '/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1' - data: The ISISL3 attributes. You could view all the attributes from the IxNetwork API browser. - - Syntax - POST: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/isisL3 - PATCH: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/isisL3/{id} + ethernetObj + data: The ISISL3 attributes. You could view all the attributes from the + IxNetwork API browser. - Return - /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/isisL3/{id} """ - createNewIsIsObj = True - if 'isis' in obj: + if 'isis' in obj.href: # To modify ISIS isisObj = obj - createNewIsIsObj = False else: - # To create a new ISIS object - url = self.ixnObj.httpHeader+obj + '/isisL3' - response = self.ixnObj.post(url, data=data) - isisObj = response.json()['links'][0]['href'] - - response = self.ixnObj.get(self.ixnObj.httpHeader+isisObj) - self.configuredProtocols.append(isisObj) + isisObj = obj.IsisL3.add() + + for key, value in data.items(): + key = key[0:1].capitalize() + key[1:] + print("checking for key", key) + try: + multivalueObj = getattr(isisObj, key) + if type(value) == dict: + self.configMultivalue(multivalueObj, 'counter', value) + else: + self.configMultivalue(multivalueObj, 'singlevalue', {'value': value}) + except Exception as e: + print(e) + setattr(isisObj, key, value) + + if isisObj not in self.configuredProtocols: + self.configuredProtocols.append(isisObj) return isisObj def getDeviceGroupIsIsL3RouterObj(self, deviceGroupObj): - """ + """ Description Get and the Device Group's ISIS L3 Router object. Mainly used after configIsIsNgpf(). - + Parameter - deviceGroupObj: : /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{1} + deviceGroupObj: - Return - IsIsL3Router obj: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/isisL3Router/{id} """ - response = self.ixnObj.get(self.ixnObj.httpHeader + deviceGroupObj + '/isisL3Router') - return response.json()[0]['links'][0]['href'] + isisL3RouterObj = deviceGroupObj.IsisL3Router.find() + return isisL3RouterObj def configIsIsL3RouterNgpf(self, isisL3RouterObj, **data): """ Description Configure ISIS L3 Router. - Parameter - isisL3RouterObj: : /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/isisL3Router/{id} - data: : Get attributes from the IxNetwork API browser. """ - response = self.ixnObj.get(self.ixnObj.httpHeader + isisL3RouterObj) - - if 'enableBIER' in data: - self.ixnObj.patch(self.ixnObj.httpHeader + isisL3RouterObj, data={'enableBIER': data['enableBIER']}) - # Note: Feel free to add additional parameters. - for attribute in ['active', 'bierNFlag', 'bierRFlag']: - if attribute in data: - multivalue = response.json()[attribute] - self.ixnObj.logInfo('Configuring ISIS BIER Subdomain multivalue attribute: %s' % attribute) - self.ixnObj.patch(self.ixnObj.httpHeader+multivalue+"/singleValue", data={'value': data[attribute]}) + for key, value in data.items(): + key = key[0:1].capitalize() + key[1:] + print("checking for key", key) + try: + multivalueObj = getattr(isisL3RouterObj, key) + if type(value) == dict: + self.configMultivalue(multivalueObj, 'counter', value) + else: + self.configMultivalue(multivalueObj, 'singlevalue', {'value': value}) + except Exception as e: + print(e) + setattr(isisL3RouterObj, key, value) def configIsIsBierSubDomainListNgpf(self, isisL3RouterObj, **data): """ Description Configure ISIS BIER Subdomain. - Parameter - isisL3RouterObj: : /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/isisL3Router/{id} - data: : active, subDomainId, BAR """ - response = self.ixnObj.get(self.ixnObj.httpHeader + isisL3RouterObj + '/isisBierSubDomainList') - for attribute in ['active', 'subDomainId', 'BAR']: - if attribute in data: - multiValue = response.json()[attribute] - self.ixnObj.logInfo('Configuring ISIS DIER Subdomain multivalue attribute: %s' % attribute) - self.ixnObj.patch(self.ixnObj.httpHeader+multiValue+"/singleValue", data={'value': data[attribute]}) + isisBierSubDomainListObj = isisL3RouterObj.IsisBierSubDomainList + for key, value in data.items(): + key = key[0:1].capitalize() + key[1:] + try: + self.configMultivalue(isisBierSubDomainListObj, 'singlevalue', {'value': value}) + except Exception as e: + print(e) + setattr(isisBierSubDomainListObj, key, value) def createIpv4Ngpf(self, obj=None, port=None, portName=None, ngpfEndpointName=None, **kwargs): """ Description This API is for backward compatiblility. Use self.configIpv4Ngpf() """ - ipv4Obj = self.configIpv4Ngpf(obj=obj, port=port, portName=portName, ngpfEndpointName=ngpfEndpointName, **kwargs) + ipv4Obj = self.configIpv4Ngpf(obj=obj, port=port, portName=portName, + ngpfEndpointName=ngpfEndpointName, **kwargs) return ipv4Obj def configIpv4Ngpf(self, obj=None, port=None, portName=None, ngpfEndpointName=None, **kwargs): @@ -452,8 +390,7 @@ def configIpv4Ngpf(self, obj=None, port=None, portName=None, ngpfEndpointName=No 4> Set NGPF IP name that you configured. Parameters - obj: : None or Ethernet obj: '/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1' - IPv4 obj: '/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1' + obj: : None or Ethernet obj port: : Format: [ixChassisIp, str(cardNumber), str(portNumber)] portName: : The virtual port name. @@ -461,143 +398,102 @@ def configIpv4Ngpf(self, obj=None, port=None, portName=None, ngpfEndpointName=No kwargs: ipv4AddressMultivalueType & gatewayMultivalueType: - Default='counter'. Options: alternate, custom, customDistributed, random, repeatableRandom, - repeatableRandomRange, valueList + Default='counter'. + Options: alternate, custom, customDistributed, random, + repeatableRandom, repeatableRandomRange, valueList To get the multivalue settings, refer to the API browser. - ipv4Address: : {'start': '100.1.1.100', 'direction': 'increment', 'step': '0.0.0.1'}, - ipv4AddressPortStep: |: disable|0.0.0.1 + ipv4Address: : {'start': '100.1.1.100', 'direction': 'increment', + 'step': '0.0.0.1'}, + ipv4AddressPortStep: |: disable|0.0.0.1 Incrementing the IP address on each port based on your input. 0.0.0.1 means to increment the last octet on each port. gateway: : {'start': '100.1.1.1', 'direction': 'increment', 'step': '0.0.0.1'}, - gatewayPortStep: |: disable|0.0.0.1 + gatewayPortStep: |: disable|0.0.0.1 Incrementing the IP address on each port based on your input. 0.0.0.1 means to increment the last octet on each port. prefix: : Example: 24 rsolveGateway: - Syntax - POST: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4 - PATCH: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id} Example to create a new IPv4 object: ipv4Obj1 = createIpv4Ngpf(ethernetObj1, - ipv4Address={'start': '100.1.1.1', 'direction': 'increment', 'step': '0.0.0.1'}, + ipv4Address={'start': '100.1.1.1', 'direction': 'increment', + 'step': '0.0.0.1'}, ipv4AddressPortStep='disabled', - gateway={'start': '100.1.1.100', 'direction': 'increment', 'step': '0.0.0.0'}, + gateway={'start': '100.1.1.100', 'direction': 'increment', + 'step': '0.0.0.0'}, gatewayPortStep='disabled', prefix=24, resolveGateway=True) - Return - /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id} """ - createNewIpv4Obj = True - - if obj != None: - if 'ipv4' in obj: - # To modify IPv4 - ipv4Obj = obj - createNewIpv4Obj = False - else: - # To create a new IPv4 object - ipv4Url = self.ixnObj.httpHeader+obj+'/ipv4' - - self.ixnObj.logInfo('Creating new IPv4 in NGPF') - response = self.ixnObj.post(ipv4Url) - ipv4Obj = response.json()['links'][0]['href'] - + ipv4Obj = None # To modify if ngpfEndpointName: - ipv4Obj = self.getNgpfObjectHandleByName(ngpfEndpointName=ngpfEndpointName, ngpfEndpointObject='ipv4') - createNewIpv4Obj = False + ipv4Obj = self.getNgpfObjectHandleByName(ngpfEndpointName=ngpfEndpointName, + ngpfEndpointObject='ipv4') # To modify if port: x = self.getProtocolListByPortNgpf(port=port) ipv4Obj = self.getProtocolObjFromProtocolList(x['deviceGroup'], 'ipv4')[0] - createNewIpv4Obj = False # To modify if portName: x = self.getProtocolListByPortNgpf(portName=portName) ipv4Obj = self.getProtocolObjFromProtocolList(x['deviceGroup'], 'ipv4')[0] - createNewIpv4Obj = False - - ipv4Response = self.ixnObj.get(self.ixnObj.httpHeader+ipv4Obj) - - if 'name' in kwargs: - self.ixnObj.patch(self.ixnObj.httpHeader+ipv4Obj, data={'name': kwargs['name']}) - - if 'multiplier' in kwargs: - self.configDeviceGroupMultiplier(objectHandle=ipv4Obj, multiplier=kwargs['multiplier'], applyOnTheFly=False) - - # Config IPv4 address - if 'ipv4Address' in kwargs: - multivalue = ipv4Response.json()['address'] - self.ixnObj.logInfo('Configuring IPv4 address. Attribute for multivalueId = jsonResponse["address"]') - # Default to counter - multivalueType = 'counter' - - if 'ipv4AddressMultivalueType' in kwargs: - multivalueType = kwargs['ipv4AddressMultivalueType'] + if obj is not None: + if 'ipv4' in obj.href: + ipv4Obj = obj + else: + ipv4Obj = obj.Ipv4.add() - if multivalueType == 'random': - self.ixnObj.patch(self.ixnObj.httpHeader+multivalue, data={'pattern': 'random'}) + if 'gatewayPortStep' in kwargs: + gatewayPortStepObj = ipv4Obj.GatewayIp.Steps.find() + gatewayPortStepValues = kwargs['gatewayPortStep'] + if gatewayPortStepValues == 'enabled': + self.configMultivalue(gatewayPortStepObj, 'counter', gatewayPortStepValues) else: - self.configMultivalue(multivalue, multivalueType, data=kwargs['ipv4Address']) + gatewayPortStepObj.Enabled = False + del kwargs['gatewayPortStep'] - # Config IPv4 port step - # disabled|0.0.0.1 if 'ipv4AddressPortStep' in kwargs: - portStepMultivalue = self.ixnObj.httpHeader+multivalue+'/nest/1' - self.ixnObj.logInfo('Configure IPv4 address port step') - if kwargs['ipv4AddressPortStep'] != 'disabled': - self.ixnObj.patch(portStepMultivalue, data={'step': kwargs['ipv4AddressPortStep']}) - if kwargs['ipv4AddressPortStep'] == 'disabled': - self.ixnObj.patch(portStepMultivalue, data={'enabled': False}) + addrPortStepObj = ipv4Obj.Address.Steps.find() + addrPortStepValues = kwargs['ipv4AddressPortStep'] - # Config Gateway - if 'gateway' in kwargs: - multivalue = ipv4Response.json()['gatewayIp'] - self.ixnObj.logInfo('Configure IPv4 gateway. Attribute for multivalueId = jsonResponse["gatewayIp"]') - # Default to counter - multivalueType = 'counter' - - if 'gatewayMultivalueType' in kwargs: - multivalueType = kwargs['gatewayMultivalueType'] - - if multivalueType == 'random': - self.ixnObj.patch(self.ixnObj.httpHeader+multivalue, data={'pattern': 'random'}) + if addrPortStepValues != 'disabled': + addrPortStepObj.Enabled = True + addrPortStepObj.Step = addrPortStepValues else: - self.configMultivalue(multivalue, multivalueType, data=kwargs['gateway']) + addrPortStepObj.Enabled = False + del kwargs['ipv4AddressPortStep'] - # Config Gateway port step - if 'gatewayPortStep' in kwargs: - portStepMultivalue = self.ixnObj.httpHeader+multivalue+'/nest/1' - self.ixnObj.logInfo('Configure IPv4 gateway port step') - if kwargs['gatewayPortStep'] != 'disabled': - self.ixnObj.patch(portStepMultivalue, data={'step': kwargs['gatewayPortStep']}) - if kwargs['gatewayPortStep'] == 'disabled': - self.ixnObj.patch(portStepMultivalue, data={'enabled': False}) - - # Config resolve gateway - if 'resolveGateway' in kwargs: - multivalue = ipv4Response.json()['resolveGateway'] - self.ixnObj.logInfo('Configure IPv4 gateway to resolve gateway. Attribute for multivalueId = jsonResponse["resolveGateway"]') - self.configMultivalue(multivalue, 'singleValue', data={'value': kwargs['resolveGateway']}) + if 'ipv4Address' in kwargs: + kwargs['Address'] = kwargs['ipv4Address'] + del kwargs['ipv4Address'] - if 'prefix' in kwargs: - multivalue = ipv4Response.json()['prefix'] - self.ixnObj.logInfo('Configure IPv4 prefix. Attribute for multivalueId = jsonResponse["prefix"]') - self.configMultivalue(multivalue, 'singleValue', data={'value': kwargs['prefix']}) + if 'gateway' in kwargs: + kwargs['gatewayIp'] = kwargs['gateway'] + del kwargs['gateway'] - if createNewIpv4Obj == True: - self.configuredProtocols.append(ipv4Obj) + for key, value in kwargs.items(): + key = key[0:1].capitalize() + key[1:] + multivalueObj = getattr(ipv4Obj, key) + try: + if type(value) == dict: + self.configMultivalue(multivalueObj, 'counter', value) + else: + self.configMultivalue(multivalueObj, 'singlevalue', {'value': value}) + except Exception as e: + print(e) + setattr(ipv4Obj, key, value) + if ipv4Obj not in self.configuredProtocols: + self.configuredProtocols.append(ipv4Obj) return ipv4Obj def configIpv4Loopback(self, deviceGroupObj, **kwargs): @@ -606,7 +502,7 @@ def configIpv4Loopback(self, deviceGroupObj, **kwargs): Configure an IPv4 loopback. Parameters - deviceGroupObj: : /api/v1/sessions/1/ixnetwork/topology{id}/deviceGroup/{id} + deviceGroupObj: kwargs: Example: @@ -621,16 +517,20 @@ def configIpv4Loopback(self, deviceGroupObj, **kwargs): """ createNewIpv4Obj = True - response = self.ixnObj.post(self.ixnObj.httpHeader+deviceGroupObj+'/ipv4Loopback') - ipv4LoopbackObj = response.json()['links'][0]['href'] - response = self.ixnObj.get(self.ixnObj.httpHeader+ipv4LoopbackObj) - + ipv4LoopbackObj = deviceGroupObj.Ipv4Loopback.add() if 'name' in kwargs: - self.ixnObj.patch(self.ixnObj.httpHeader+ipv4LoopbackObj, data={'name': kwargs['name']}) + ipv4LoopbackObj.Name = kwargs['name'] + + if 'multiplier' in kwargs: + ipv4LoopbackObj.Multiplier = kwargs['multiplier'] + + if 'prefix' in kwargs: + ipv4LoopbackObj.Prefix.Single(kwargs['prefix']) if 'ipv4Address' in kwargs: - multivalue = response.json()['address'] - self.ixnObj.logInfo('Configuring IPv4 address. Attribute for multivalueId = jsonResponse["address"]') + addressObj = ipv4LoopbackObj.Address + self.ixnObj.logInfo('Configuring IPv4 address. Attribute for multivalueId = ' + 'addressObj.href') # Default to counter multivalueType = 'counter' @@ -639,20 +539,13 @@ def configIpv4Loopback(self, deviceGroupObj, **kwargs): multivalueType = kwargs['ipv4AddressMultivalueType'] if multivalueType == 'random': - self.ixnObj.patch(self.ixnObj.httpHeader+multivalue, data={'pattern': 'random'}) + addressObj.Random() else: - self.configMultivalue(multivalue, multivalueType, data=kwargs['ipv4Address']) + self.configMultivalue(addressObj, multivalueType, data=kwargs['ipv4Address']) - if 'multiplier' in kwargs: - self.ixnObj.patch(self.ixnObj.httpHeader+ipv4LoopbackObj, data={'multiplier': kwargs['multiplier']}) - - if 'prefix' in kwargs: - multivalue = response.json()['prefix'] - self.configMultivalue(multivalue, 'singleValue', data={'value': kwargs['prefix']}) - - if createNewIpv4Obj == True: + if createNewIpv4Obj: self.configuredProtocols.append(ipv4LoopbackObj) - + def configDhcpClientV4(self, obj, **kwargs): """ Description @@ -662,10 +555,7 @@ def configDhcpClientV4(self, obj, **kwargs): Parameters obj: : To create new DHCP obj. - Example: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1 - obj: : To Modify DHCP client. - Example: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/dhcpv4client/1 dhcp4Broadcast: multiplier: : The amount of DHCP clients to create. @@ -674,10 +564,6 @@ def configDhcpClientV4(self, obj, **kwargs): dhcp4GatewayMac: : Gateway mac address in the format of 00:00:00:00:00:00 useRapdCommit: : Default=False renewTimer: : Default=0 - - Syntax - POST: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id}/dhcpv4client - PATCH: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id}/dhcpv4client/{id} Example: dhcpClientObj = protocolObj.configV4DhcpClient(ethernetObj1, @@ -688,38 +574,33 @@ def configDhcpClientV4(self, obj, **kwargs): dhcp4GatewayMac='00:00:00:00:00:00', useRapdCommit=False, renewTimer=0) - - Return - /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id}/dhcpv4client/{id} """ - # To create new DHCP object - if 'dhcp' not in obj: - dhcpUrl = self.ixnObj.httpHeader+obj+'/dhcpv4client' - self.ixnObj.logInfo('Create new DHCP client V4') - response = self.ixnObj.post(dhcpUrl) - # /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/dhcpv4client/1 - dhcpObj = response.json()['links'][0]['href'] + dhcpObj = None + if 'dhcp' not in obj.href: + dhcpObj = obj.Dhcpv4client.add() # To modify DHCP - if 'dhcp' in obj: + if 'dhcp' in obj.href: dhcpObj = obj - dhcpObjResponse = self.ixnObj.get(self.ixnObj.httpHeader+dhcpObj) - if 'name' in kwargs: - self.ixnObj.patch(self.ixnObj.httpHeader+dhcpObj, data={'name': kwargs['name']}) - - # All of these DHCP attributes configures multivalue singleValue. So just loop them to do the same thing. - dhcpAttributes = ['dhcp4Broadcast', 'dhcp4UseFirstServer', 'dhcp4ServerAddress', 'dhcp4GatewayMac', 'dhcp4GatewayAddress' - 'useRapidCommit', 'dhcp4GatewayMac', 'renewTimer'] - - for dhcpAttribute in dhcpAttributes: - if dhcpAttribute in kwargs: - multiValue = dhcpObjResponse.json()[dhcpAttribute] - self.ixnObj.logInfo('Configuring DHCP Client attribute: %s' % dhcpAttribute) - self.ixnObj.patch(self.ixnObj.httpHeader+multiValue+"/singleValue", data={'value': kwargs[dhcpAttribute]}) + dhcpObj.Name = kwargs['name'] - self.configuredProtocols.append(dhcpObj) + for key, value in kwargs.items(): + key = key[0:1].capitalize() + key[1:] + multivalueObj = getattr(dhcpObj, key) + try: + if type(value) == dict: + self.configMultivalue(multivalueObj, 'counter', value) + else: + self.configMultivalue(multivalueObj, 'singleValue', {'value': value}) + multivalueObj.Single(value) + except Exception as e: + print(e) + setattr(dhcpObj, key, value) + + if dhcpObj not in self.configuredProtocols: + self.configuredProtocols.append(dhcpObj) return dhcpObj def configDhcpServerV4(self, obj, **kwargs): @@ -730,8 +611,8 @@ def configDhcpServerV4(self, obj, **kwargs): To modify an existing DHCP V4 server stack in NGPF, pass in the dhcpv4server object. Parameters - obj: : To create new DHCP: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1 - obj: : To modify DHCP server: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/dhcpv4server/1 + obj: : To create new DHCP + obj: : To modify DHCP server useRapidCommit: : Default=False multiplier: : Default-1 @@ -746,72 +627,62 @@ def configDhcpServerV4(self, obj, **kwargs): ipPrefix: : The DHCP server IP address prefix. Ex: 16. poolSize: : The DHCP server pool size. - Syntax - POST: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id}/dhcpv4server - PATCH: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id}/dhcpv4server/{id} - Example: - protocolObj.configV4DhcpServer('/api/v1/sessions/1/ixnetwork/topology/2/deviceGroup/1/ethernet/1/ipv4/1', - name='DHCP-Server-1', - multiplier='1', - useRapidCommit=False, - subnetAddrAssign=False, - defaultLeaseTime=86400, - echoRelayInfo=True, - ipAddress='1.1.1.1', - ipAddressIncrement='0.0.0.1', - ipDns1='0.0.0.0', - ipDns2='0.0.0.0', - ipGateway='1.1.1.11', - ipPrefix=24, - poolSize=10) - - Return - /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id}/dhcpv4server/{id} """ - # To create new DHCP serverobject - if 'dhcp' not in obj: - dhcpUrl = self.ixnObj.httpHeader+obj+'/dhcpv4server' - self.ixnObj.logInfo('Create new DHCP server v4') - response = self.ixnObj.post(dhcpUrl) - # /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/dhcpv4server/1 - dhcpObj = response.json()['links'][0]['href'] + dhcpObj = None + if 'dhcp' not in obj.href: + dhcpObj = obj.Dhcpv4server.add() # To modify DHCP server - if 'dhcp' in obj: + if 'dhcp' in obj.href: dhcpObj = obj - dhcpObjResponse = self.ixnObj.get(self.ixnObj.httpHeader+dhcpObj) - if 'name' in kwargs: - self.ixnObj.patch(self.ixnObj.httpHeader+dhcpObj, data={'name': kwargs['name']}) + dhcpObj.Name = kwargs['name'] - # All of these DHCP attributes configures multivalue singleValue. So just loop them to do the same thing. dhcpServerAttributes = ['useRapidCommit', 'subnetAddrAssign'] - - for dhcpAttribute in dhcpServerAttributes: - if dhcpAttribute in kwargs: - multiValue = dhcpObjResponse.json()[dhcpAttribute] - self.ixnObj.logInfo('Configuring DHCP Server attribute: %s' % dhcpAttribute) - self.ixnObj.patch(self.ixnObj.httpHeader+multiValue+"/singleValue", data={'value': kwargs[dhcpAttribute]}) + dhcpServerSessionAttributes = ['defaultLeaseTime', 'echoRelayInfo', 'ipAddress', + 'ipAddressIncrement', 'ipDns1', 'ipDns2', 'ipGateway', + 'ipPrefix', 'poolSize'] + + # All of these DHCP attributes configures multivalue singleValue. + # So just loop them to do the same thing. + for key, value in kwargs.items(): + if key in dhcpServerAttributes: + key = key[0].capitalize() + key[1:] + multivalueObj = getattr(dhcpObj, key) + try: + if type(value) == dict: + self.configMultivalue(multivalueObj, 'counter', value) + else: + self.configMultivalue(multivalueObj, 'singleValue', {'value': value}) + except Exception as e: + print(e) + setattr(dhcpObj, key, value) if 'multiplier' in kwargs: - self.ixnObj.patch(self.ixnObj.httpHeader+dhcpObj, data={'multiplier': kwargs['multiplier']}) + dhcpObj.Multiplier = kwargs['multiplier'] - dhcpServerSessionObjResponse = self.ixnObj.get(self.ixnObj.httpHeader+dhcpObj+'/dhcp4ServerSessions') - dhcpServerSessionAttributes = ['defaultLeaseTime', 'echoRelayInfo', 'ipAddress', 'ipAddressIncrement', - 'ipDns1', 'ipDns2', 'ipGateway', 'ipPrefix', 'poolSize'] - - for dhcpAttribute in dhcpServerSessionAttributes: - if dhcpAttribute in kwargs: - multiValue = dhcpServerSessionObjResponse.json()[dhcpAttribute] - self.ixnObj.logInfo('Configuring DHCP Server session attribute: %s' % dhcpAttribute) - self.ixnObj.patch(self.ixnObj.httpHeader+multiValue+"/singleValue", data={'value': kwargs[dhcpAttribute]}) + dhcpServerSessionObj = dhcpObj.Dhcp4ServerSessions + for key, value in kwargs.items(): + if key in dhcpServerSessionAttributes: + key = key[0:1].capitalize() + key[1:] + multivalObj = getattr(dhcpServerSessionObj, key) + try: + if type(value) == dict: + self.configMultivalue(multivalObj, 'counter', value) + else: + self.configMultivalue(multivalObj, 'singleValue', {'value': value}) + except Exception as e: + print(e) + setattr(dhcpServerSessionObj, key, value) - #self.configuredProtocols.append(dhcpObj) + if dhcpObj not in self.configuredProtocols: + self.configuredProtocols.append(dhcpObj) return dhcpObj - def configOspf(self, obj=None, routerId=None, port=None, portName=None, ngpfEndpointName=None, hostIp=None, **kwargs): + def configOspf(self, obj=None, routerId=None, port=None, portName=None, + ngpfEndpointName=None, hostIp=None, **kwargs): """ Description Create or modify OSPF. If creating a new OSPF, provide an IPv4 object handle. @@ -825,22 +696,15 @@ def configOspf(self, obj=None, routerId=None, port=None, portName=None, ngpfEndp 6> Set hostIp: The src IP. Parameters - IPv4 object handle example: - obj: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1 - - OSPF object handle example: - obj: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/ospfv2/1 - + IPv4 object handle + OSPF object handle routerId: : The router ID IP address. port: : Format: [ixChassisIp, str(cardNumber), str(portNumber)] portName: : The virtual port name. ngpfEndpointName: : The name that you configured for the NGPF endpoint. hostIp: : The source IP address to query for the object. - kwargs: OSPF configuration attributes. The attributes could be obtained from the IxNetwork API browser. - - Syntax - POST: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id}/ospfv2 - PATCH: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id}/ospfv2/{id} + kwargs: OSPF configuration attributes. The attributes could be obtained from the + IxNetwork API browser. Example: ospfObj1 = configOspf(ipv4Obj, @@ -852,105 +716,61 @@ def configOspf(self, obj=None, routerId=None, port=None, portName=None, ngpfEndp networkType = 'pointtomultipoint', deadInterval = '40') - Return - /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id}/ospfv2/{id} - """ - # To create new OSPF object - if obj != None: - if 'ospf' not in obj: - ospfUrl = self.ixnObj.httpHeader+obj+'/ospfv2' - self.ixnObj.logInfo('Create new OSPFv2 in NGPF') - response = self.ixnObj.post(ospfUrl) - # /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/ospfv2/1 - ospfObj = response.json()['links'][0]['href'] - - # To modify OSPF - if 'ospf' in obj: - ospfObj = obj - - # To modify - if ngpfEndpointName: - ospfObj = self.getNgpfObjectHandleByName(ngpfEndpointName=ngpfEndpointName, ngpfEndpointObject='ospfv2') - - # To modify - if port: - x = self.getProtocolListByPortNgpf(port=port) - ospfObj = self.getProtocolObjFromProtocolList(x['deviceGroup'], 'ospvv2')[0] - - # To modify - if portName: - x = self.getProtocolListByPortNgpf(portName=portName) - ospfObj = self.getProtocolObjFromProtocolList(x['deviceGroup'], 'ospfv2')[0] + """ + ospfObj = None + if obj is not None: + if routerId: + ospfObj = self.getNgpfObjectHandleByRouterId(routerId=routerId, + ngpfEndpointObject='ospfv2') - # To modify - if routerId: - ospfObj = self.getNgpfObjectHandleByRouterId(routerId=routerId, ngpfEndpointObject='ospfv2') + if port: + x = self.getProtocolListByPortNgpf(port=port) + ospfObj = self.getProtocolObjFromProtocolList(x['deviceGroup'], 'ospfv2')[0] - # To modify - if hostIp: - x = self.getProtocolListByHostIpNgpf(hostIp) - ospfObj = self.getProtocolObjFromHostIp(x, protocol='ospfv2') + if portName: + x = self.getProtocolListByPortNgpf(portName=portName) + ospfObj = self.getProtocolObjFromProtocolList(x['deviceGroup'], 'ospfv2')[0] - ospfObjResponse = self.ixnObj.get(self.ixnObj.httpHeader+ospfObj) + if 'ospf' not in obj.href: + ospfObj = obj.Ospfv2.add() - if 'name' in kwargs: - self.ixnObj.patch(self.ixnObj.httpHeader+ospfObj, data={'name': kwargs['name']}) - - for key,value in ospfObjResponse.json().items(): - if key != 'links': - if bool(re.search('multivalue', str(value))) == True: - if key in kwargs: - multiValue = ospfObjResponse.json()[key] - self.ixnObj.logInfo('Configuring OSPF multivalue attribute: %s' % key) - self.ixnObj.patch(self.ixnObj.httpHeader+multiValue+"/singleValue", data={'value': kwargs[key]}) - else: - if key in kwargs: - self.ixnObj.patch(self.ixnObj.httpHeader+ospfObj, data={key: kwargs[key]}) - - # Anish added - ospfv2AttributeList = ['lsaRefreshTime','lsaRetransmitTime','interFloodLsUpdateBurstGap'] - if (any(attribute in ospfv2AttributeList for attribute in kwargs)): - ospfRouterUrl = self.ixnObj.httpHeader+ospfObj.split('ethernet')[0]+'ospfv2Router' - - ospfRouterObjResponse = self.ixnObj.get(ospfRouterUrl+'/'+str(self.ixnObj.get(ospfRouterUrl).json()[0]['id'])) - - for key, value in ospfRouterObjResponse.json().items(): - if key != 'links': - if bool(re.search('multivalue', str(value))) == True: - if key in kwargs: - multiValue = ospfRouterObjResponse.json()[key] - self.ixnObj.logInfo('Configuring OSPF Router multivalue attribute: %s' % key) - self.configMultivalue(multiValue, 'singleValue', data={'value': kwargs[key]}) - else: - if key in kwargs: - self.ixnObj.patch(self.ixnObj.httpHeader + ospfRouterObjResponse, data={key: kwargs[key]}) - - # Anish added - ospfv2TrafficEngAttributeList = ['metricLevel'] - if (any(attribute in ospfv2TrafficEngAttributeList for attribute in kwargs)): - ospfTrafficEngObj = ospfObj + '/ospfTrafficEngineering' - - ospfTrafficEngObjResponse = self.ixnObj.get(self.ixnObj.httpHeader+ospfTrafficEngObj) - - for key, value in ospfTrafficEngObjResponse.json().items(): - if key != 'links': - if bool(re.search('multivalue', str(value))) == True: - if key in kwargs: - multiValue = ospfTrafficEngObjResponse.json()[key] - self.ixnObj.logInfo('Configuring OSPF Router multivalue attribute: %s' % key) - self.configMultivalue(multiValue, 'singleValue', data={'value': kwargs[key]}) - else: - if key in kwargs: - self.ixnObj.patch(self.ixnObj.httpHeader + ospfTrafficEngObjResponse, data={key: kwargs[key]}) + if 'ospf' in obj.href: + ospfObj = obj - self.configuredProtocols.append(ospfObj) + for key, value in kwargs.items(): + if key not in ['lsaRefreshTime', 'lsaRetransmitTime', 'interFloodLsUpdateBurstGap']: + itemObj = key[0:1].capitalize() + key[1:] + multivalueObj = getattr(ospfObj, itemObj) + try: + if type(value) == dict: + self.configMultivalue(multivalueObj, 'counter', value) + else: + self.configMultivalue(multivalueObj, 'singleValue', {'value': value}) + except Exception as e: + print(e) + setattr(ospfObj, itemObj, value) + + if 'lsaRefreshTime' in kwargs: + self.ixNetwork.Vport.find( + Name=portName).Protocols.find().Ospf.Router.find().LsaRefreshTime = \ + kwargs['lsaRefreshTime'] + if 'lsaRetransmitTime' in kwargs: + self.ixNetwork.Vport.find(Name=portName).Protocols.find().Ospf.Router.find(). \ + LsaRefreshTime = kwargs['lsaRetransmitTime'] + if 'interFloodLsUpdateBurstGap' in kwargs: + self.ixNetwork.Vport.find(Name=portName).Protocols.find().Ospf.Router.find(). \ + LsaRefreshTime = kwargs['interFloodLsUpdateBurstGap'] + + if ospfObj not in self.configuredProtocols: + self.configuredProtocols.append(ospfObj) return ospfObj - def configOspfv3(self, obj=None, routerId=None, port=None, portName=None, ngpfEndpointName=None, hostIp=None, **kwargs): + def configOspfv3(self, obj=None, routerId=None, port=None, portName=None, + ngpfEndpointName=None, hostIp=None, **kwargs): """ Description Create or modify OSPFv3. If creating a new OSPFv3, provide an IPv6 object handle. - If modifying a OSPF, there are five options. 2-6 will query for the OSPFv3 object handle. + If modifying a OSPF,there are five options. 2-6 will query for the OSPFv3 object handle. 1> Provide the OSPFv3 object handle using the obj parameter. 2> Set routerId. @@ -960,22 +780,16 @@ def configOspfv3(self, obj=None, routerId=None, port=None, portName=None, ngpfEn 6> Set hostIp: The src IP. Parameters - IPv6 object handle example: - obj: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv6/1 - - OSPF object handle example: - obj: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv6/1/ospfv3/1 + IPv6 object handle + OSPF object handle routerId: : The router ID IP address. port: : Format: [ixChassisIp, str(cardNumber), str(portNumber)] portName: : The virtual port name. ngpfEndpointName: : The name that you configured for the NGPF endpoint. hostIp: : The source IP address to query for the object. - kwargs: OSPF configuration attributes. The attributes could be obtained from the IxNetwork API browser. - - Syntax - POST: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv6/{id}/ospfv3 - PATCH: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv6/{id}/ospfv3/{id} + kwargs: OSPF configuration attributes. The attributes could be obtained from the + IxNetwork API browser. Example: ospfObj1 = configOspf(ipv6Obj, @@ -987,85 +801,69 @@ def configOspfv3(self, obj=None, routerId=None, port=None, portName=None, ngpfEn networkType = 'pointtomultipoint', deadInterval = '40') - Return - /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv6/{id}/ospfv3/{id} """ - # To create new OSPFV3 object - - if obj != None: - if 'ospf' not in obj: - ospfUrl = self.ixnObj.httpHeader+obj+'/ospfv3' - self.ixnObj.logInfo('Create new OSPFv3 in NGPF') - response = self.ixnObj.post(ospfUrl) - # /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv6/1/ospfv3/1 - ospfObj = response.json()['links'][0]['href'] - - # To modify OSPF - if 'ospf' in obj: - ospfObj = obj - - # To modify - if ngpfEndpointName: - ospfObj = self.getNgpfObjectHandleByName(ngpfEndpointName=ngpfEndpointName, ngpfEndpointObject='ospfv3') + ospfObj = None + if obj is not None: + if routerId: + ospfObj = self.getNgpfObjectHandleByRouterId(routerId=routerId, + ngpfEndpointObject='ospfv3') - # To modify - if port: - x = self.getProtocolListByPortNgpf(port=port) - ospfObj = self.getProtocolObjFromProtocolList(x['deviceGroup'], 'ospfv3')[0] + if port: + x = self.getProtocolListByPortNgpf(port=port) + ospfObj = self.getProtocolObjFromProtocolList(x['deviceGroup'], + 'ospfv3')[0] - # To modify - if portName: - x = self.getProtocolListByPortNgpf(portName=portName) - ospfObj = self.getProtocolObjFromProtocolList(x['deviceGroup'], 'ospfv3')[0] - - # To modify - if routerId: - ospfObj = self.getNgpfObjectHandleByRouterId(routerId=routerId, ngpfEndpointObject='ospfv3') - - # To modify - if hostIp: - x = self.getProtocolListByHostIpNgpf(hostIp) - ospfObj = self.getProtocolObjFromHostIp(x, protocol='ospfv3') - - ospfObjResponse = self.ixnObj.get(self.ixnObj.httpHeader+ospfObj) - - if 'name' in kwargs: - self.ixnObj.patch(self.ixnObj.httpHeader+ospfObj, data={'name': kwargs['name']}) - - for key,value in ospfObjResponse.json().items(): - if key != 'links': - if bool(re.search('multivalue', str(value))) == True: - if key in kwargs: - multiValue = ospfObjResponse.json()[key] - self.ixnObj.logInfo('Configuring OSPF multivalue attribute: %s' % key) - self.ixnObj.patch(self.ixnObj.httpHeader+multiValue+"/singleValue", data={'value': kwargs[key]}) - else: - if key in kwargs: - self.ixnObj.patch(self.ixnObj.httpHeader+ospfObj, data={key: kwargs[key]}) - - ospfv3AttributeList = ['lsaRefreshTime', 'lsaRetransmitTime', 'interFloodLsUpdateBurstGap'] + if portName: + x = self.getProtocolListByPortNgpf(portName=portName) + ospfObj = self.getProtocolObjFromProtocolList(x['deviceGroup'], + 'ospfv3')[0] - if (any(attribute in ospfv3AttributeList for attribute in kwargs)): - ospfRouterUrl = self.ixnObj.httpHeader + ospfObj.split('ethernet')[0] + 'ospfv3Router' + if ngpfEndpointName: + ospfObj = self.getNgpfObjectHandleByName( + ngpfEndpointName=ngpfEndpointName, + ngpfEndpointObject='ospfv3') - ospfRouterObjResponse = self.ixnObj.get( - ospfRouterUrl + '/' + str(self.ixnObj.get(ospfRouterUrl).json()[0]['id'])) + if hostIp: + x = self.getProtocolListByHostIpNgpf(hostIp) + ospfObj = self.getProtocolObjFromHostIp(x, protocol='ospfv3') - for key, value in ospfRouterObjResponse.json().items(): - if key != 'links': - if bool(re.search('multivalue', str(value))) == True: - if key in kwargs: - multiValue = ospfRouterObjResponse.json()[key] - self.ixnObj.logInfo('Configuring OSPF Router multivalue attribute: %s' % key) - self.configMultivalue(multiValue, 'singleValue', data={'value': kwargs[key]}) - else: - if key in kwargs: - self.ixnObj.patch(self.ixnObj.httpHeader + ospfRouterObjResponse, data={key: kwargs[key]}) + if 'ospf' not in obj.href: + ospfObj = obj.Ospfv3.add() + else: + ospfObj = obj - self.configuredProtocols.append(ospfObj) + for item, value in kwargs.items(): + if item not in ['lsaRefreshTime', 'lsaRetransmitTime', + 'interFloodLsUpdateBurstGap']: + itemObj = item[0].capitalize() + item[1:] + print("checking for key", itemObj) + try: + multivalObj = getattr(ospfObj, itemObj) + if type(value) == dict: + self.configMultivalue(multivalObj, 'counter', value) + else: + self.configMultivalue(multivalObj, 'singleValue', {'value': value}) + except Exception as e: + print(e) + setattr(ospfObj, itemObj, value) + + if 'lsaRefreshTime' in kwargs: + self.ixNetwork.Vport.find(Name=portName).Protocols.find().OspfV3.Router.find(). \ + LsaRefreshTime = kwargs['lsaRefreshTime'] + if 'lsaRetransmitTime' in kwargs: + self.ixNetwork.Vport.find(Name=portName).Protocols.find().OspfV3.Router.find(). \ + LsaRefreshTime = kwargs['lsaRetransmitTime'] + if 'interFloodLsUpdateBurstGap' in kwargs: + self.ixNetwork.Vport.find(Name=portName).Protocols.find().OspfV3.Router.find(). \ + LsaRefreshTime = kwargs['interFloodLsUpdateBurstGap'] + + if ospfObj not in self.configuredProtocols: + self.configuredProtocols.append(ospfObj) return ospfObj - def configBgp(self, obj=None, routerId=None, port=None, portName=None, ngpfEndpointName=None, hostIp=None, **kwargs): + def configBgp(self, obj=None, routerId=None, port=None, portName=None, + ngpfEndpointName=None, hostIp=None, + **kwargs): """ Description Create or modify BGP. If creating a new BGP, provide an IPv4 object handle. @@ -1081,20 +879,16 @@ def configBgp(self, obj=None, routerId=None, port=None, portName=None, ngpfEndpo Parameters obj: : None or Either an IPv4 object or a BGP object. If creating new bgp object: - IPv4 object example: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1 If modifying, you could provide the bgp object handle using the obj parameter: - BGP object example: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/bgpIpv4Peer/1 - + BGP object + routerId: : The router ID IP address. port: : Format: [ixChassisIp, str(cardNumber), str(portNumber)] portName: : The virtual port name. ngpfEndpointName: : The name that you configured for the NGPF endpoint. hostIp: : The source IP address to query for the object. - kwargs: BGP configuration attributes. The attributes could be obtained from the IxNetwork API browser. - - Syntax - POST: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id}/bgpIpv4Peer - PATCH: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id}/bgpIpv4Peer/{id} + kwargs: BGP configuration attributes. The attributes could be obtained from the + IxNetwork API browser. Example: Create a new bgp object... configBgp(ipv4Obj, @@ -1108,30 +902,11 @@ def configBgp(self, obj=None, routerId=None, port=None, portName=None, ngpfEndpo type = 'internal', enableBgpIdSameasRouterId = True - Return - /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id}/bgpIpv4Peer/{id} """ - # To create a new BGP stack using IPv4 object. - if obj != None: - if 'bgp' not in obj: - if 'ipv4' in obj: - bgpUrl = self.ixnObj.httpHeader+obj+'/bgpIpv4Peer' - - if 'ipv6' in obj: - bgpUrl = self.ixnObj.httpHeader+obj+'/bgpIpv6Peer' - - self.ixnObj.logInfo('Create new BGP in NGPF') - response = self.ixnObj.post(bgpUrl) - # /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/bgpIpv4Peer/1 - bgpObj = response.json()['links'][0]['href'] - - # To modify BGP by providing a BGP object handle. - if 'bgp' in obj: - bgpObj = obj - # To modify if ngpfEndpointName: - bgpObj = self.getNgpfObjectHandleByName(ngpfEndpointName=ngpfEndpointName, ngpfEndpointObject='bgpIpv4Peer') + bgpObj = self.getNgpfObjectHandleByName(ngpfEndpointName=ngpfEndpointName, + ngpfEndpointObject='bgpIpv4Peer') # To modify if port: @@ -1145,63 +920,48 @@ def configBgp(self, obj=None, routerId=None, port=None, portName=None, ngpfEndpo # To modify if routerId: - bgpObj = self.getNgpfObjectHandleByRouterId(routerId=routerId, ngpfEndpointObject='bgpIpv4Peer') + bgpObj = self.getNgpfObjectHandleByRouterId(routerId=routerId, + ngpfEndpointObject='bgpIpv4Peer') # To modify if hostIp: x = self.getProtocolListByHostIpNgpf(hostIp) bgpObj = self.getProtocolObjFromHostIp(x, protocol='bgpIpv4Peer') - bgpObjResponse = self.ixnObj.get(self.ixnObj.httpHeader+bgpObj + '?links=true') - - if 'name' in kwargs: - self.ixnObj.patch(self.ixnObj.httpHeader+bgpObj, data={'name': kwargs['name']}) - - # For BgpIpv4Peer - if 'enableBgp' in kwargs and kwargs['enableBgp'] == True: - multiValue = bgpObjResponse.json()['enableBgpId'] - self.ixnObj.patch(self.ixnObj.httpHeader+multiValue+"/singleValue", data={'value': True}) - - # For BgpIpv6Peer - if 'active' in kwargs and kwargs['active'] == True: - multiValue = bgpObjResponse.json()['active'] - self.ixnObj.patch(self.ixnObj.httpHeader+multiValue+"/singleValue", data={'value': True}) - - if 'dutIp' in kwargs: - multiValue = bgpObjResponse.json()['dutIp'] - self.configMultivalue(multiValue, 'counter', data=kwargs['dutIp']) - - for key,value in bgpObjResponse.json().items(): - if key != 'links' and key not in ['dutIp']: - if bool(re.search('multivalue', str(value))) == True: - if key in kwargs: - multiValue = bgpObjResponse.json()[key] - self.ixnObj.logInfo('Configuring BGP multivalue attribute: %s' % key) - self.ixnObj.patch(self.ixnObj.httpHeader+multiValue+"/singleValue", data={'value': kwargs[key]}) + if 'Bgp' in obj.href or 'bgp' in obj.href: + # To modify BGP + bgpObj = obj + else: + # Common code for BgpIpv4 and BgpIpv6 + if hasattr(obj, 'BgpIpv4Peer'): + bgpObj = obj.BgpIpv4Peer.add() + if hasattr(obj, 'BgpIpv6Peer'): + bgpObj = obj.BgpIpv6Peer.add() + + if 'enableBgp' in kwargs: + kwargs['enableBgpId'] = kwargs['enableBgp'] + del kwargs['enableBgp'] + + for key, value in kwargs.items(): + key = key[0:1].capitalize() + key[1:] + multivalue = getattr(bgpObj, key) + try: + if type(value) == dict: + self.configMultivalue(multivalue, 'counter', value) else: - if key in kwargs: - self.ixnObj.patch(self.ixnObj.httpHeader+bgpObj, data={key: kwargs[key]}) + self.configMultivalue(multivalue, 'singleValue', {'value': value}) + except Exception as e: + print(e) + setattr(bgpObj, key, value) - self.configuredProtocols.append(bgpObj) + if bgpObj not in self.configuredProtocols: + self.configuredProtocols.append(bgpObj) return bgpObj - def configBgpIpv6(self, obj=None, routerId=None, port=None, portName=None, ngpfEndpointName=None, hostIp=None, **kwargs): + def configBgpIpv6(self, obj=None, routerId=None, port=None, portName=None, + ngpfEndpointName=None, hostIp=None, **kwargs): """ Creating a namespace for BgpIpv6Peer. Pass everything to configBgp() - - Example: - ipv6Obj2 = '/api/v1/sessions/1/ixnetwork/topology/2/deviceGroup/1/ethernet/1/ipv6' - - bgpObj2 = protocolObj.configBgpIpv6(ipv6Obj2, - name = 'bgp_2', - active = True, - holdTimer = 90, - dutIp={'start': '2001:0:0:1:0:0:0:1', 'direction': 'increment', 'step': '0:0:0:0:0:0:0:0'}, - localAs2Bytes = 101, - enableGracefulRestart = False, - restartTime = 45, - type = 'internal', - enableBgpIdSameasRouterId = True) """ return self.configBgp(obj, routerId, port, portName, ngpfEndpointName, hostIp, **kwargs) @@ -1212,107 +972,81 @@ def configIgmpHost(self, ipObj, **kwargs): Create or modify IGMP host. Provide an IPv4|IPv6 obj to create a new IGMP host object. Provide an IGMP host object to modify. - - Parameters - ipObj: : /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1 - igmpObj: : /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/igmp/1 - - Syntax - POST: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id}/igmp - PATCH: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id}/igmp/{id} - - Example: - - Return - /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id}/igmp/{id} """ # To create new IGMP object - if 'igmp' not in obj: - igmpUrl = self.ixnObj.httpHeader+obj+'/igmp' + igmpObj = None + if 'igmp' not in ipObj.href: self.ixnObj.logInfo('Create new IGMP V4 host') - response = self.ixnObj.post(igmpUrl) - # /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/igmp/1 - igmpObj = response.json()['links'][0]['href'] - - # To modify OSPF - if 'igmp' in obj: - igmpObj = obj - - igmpObjResponse = self.ixnObj.get(self.ixnObj.httpHeader+igmpObj) - - if 'name' in kwargs: - self.ixnObj.patch(self.ixnObj.httpHeader+igmpObj, data={'name': kwargs['name']}) + igmpObj = ipObj.IgmpHost.add() - # All of these BGP attributes configures multivalue singleValue. So just loop them to do the same thing. - igmpAttributes = ['areaId', 'neighborIp', 'helloInterval', 'areadIdIp', 'networkType', 'deadInterval'] + # To modify IGMP + if 'igmp' in ipObj.href: + igmpObj = ipObj - for igmpAttribute in igmpAttributes: - if igmpAttribute in kwargs: - multiValue = igmpObjResponse.json()[igmpAttribute] - self.ixnObj.logInfo('Configuring IGMP host attribute: %s' % igmpAttribute) - self.ixnObj.patch(self.ixnObj.httpHeader+multiValue+"/singleValue", data={'value': kwargs[igmpAttribute]}) + for key, value in kwargs.items(): + key = key[0:1].capitalize() + key[1:] + multivalueObj = getattr(igmpObj, key) + try: + if type(value) == dict: + self.configMultivalue(multivalueObj, 'counter', value) + else: + self.configMultivalue(multivalueObj, 'singleValue', {'value': value}) + except Exception as e: + print(e) + setattr(igmpObj, key, value) - self.configuredProtocols.append(igmpObj) + if igmpObj not in self.configuredProtocols: + self.configuredProtocols.append(igmpObj) return igmpObj def configMpls(self, ethernetObj, **kwargs): """ Description - Create or modify static MPLS. - - Parameters - ethernetObj: : The Ethernet object handle. - Example: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id} - - Syntax - POST: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/mpls - PATCH: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/mpls/{id} + Create or modify static MPLS. Example: mplsObj1 = protocolObj.configMpls(ethernetObj1, name = 'mpls-1', - destMac = {'start': '00:01:02:00:00:01', 'direction': 'increment', 'step': '00:00:00:00:00:01'}, + destMac = {'start': '00:01:02:00:00:01', + 'direction': 'increment', + 'step': '00:00:00:00:00:01'}, exp = {'start': 0, 'direction': 'increment', 'step': 1}, ttl = {'start': 16, 'direction': 'increment', 'step': 1}, - rxLabelValue = {'start': 288, 'direction': 'increment', 'step': 1}, - txLabelValue = {'start': 888, 'direction': 'increment', 'step': 1}) + rxLabelValue = {'start': 288, 'direction': increment', + 'step': 1}, + txLabelValue = {'start': 888, 'direction': 'increment', + 'step': 1}) - Return - /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/mpls/{id} """ - # To create a new MPLS if 'mpls' not in ethernetObj: - mplsUrl = self.ixnObj.httpHeader+ethernetObj+'/mpls' - self.ixnObj.logInfo('Create new MPLS protocol in NGPF') - response = self.ixnObj.post(mplsUrl) - mplsObj = response.json()['links'][0]['href'] - - # To modify MPLS - if 'mpls' in ethernetObj: + mplsObj = ethernetObj.Mpls.add() + else: mplsObj = ethernetObj - self.ixnObj.logInfo('GET ATTRIBUTE MULTIVALUE IDs') - mplsResponse = self.ixnObj.get(self.ixnObj.httpHeader+mplsObj) - if 'name' in kwargs: - self.ixnObj.patch(self.ixnObj.httpHeader+mplsObj, data={'name': kwargs['name']}) + setattr(mplsObj, 'Name', kwargs['name']) + del kwargs['name'] - # All of these mpls attributes configures multivalue counter. So just loop them to do the same thing. mplsAttributes = ['rxLabelValue', 'txLabelValue', 'destMac', 'cos', 'ttl'] - for mplsAttribute in mplsAttributes: - if mplsAttribute in kwargs: - multiValue = mplsResponse.json()[mplsAttribute] - self.ixnObj.logInfo('Configuring MPLS attribute: %s' % mplsAttribute) - self.configMultivalue(multiValue, 'counter', data=kwargs[mplsAttribute]) - - self.configuredProtocols.append(mplsObj) + for key, value in kwargs.items(): + if key in mplsAttributes: + key = key[0].capitalize() + key[1:] + multivalueObj = getattr(mplsObj, key) + if type(value) == dict: + self.configMultivalue(multivalueObj, 'counter', value) + else: + self.configMultivalue(multivalueObj, 'singleValue', {'value': value}) + + if mplsObj not in self.configuredProtocols: + self.configuredProtocols.append(mplsObj) return mplsObj - def configVxlanNgpf(self, obj=None, routerId=None, port=None, portName=None, ngpfEndpointName=None, hostIp=None, **kwargs): + def configVxlanNgpf(self, obj=None, routerId=None, port=None, portName=None, + ngpfEndpointName=None, hostIp=None, **kwargs): """ Description - Create or modify a VXLAN. If creating a new VXLAN header, provide an IPv4 object handle. + Create or modify a VXLAN. If creating a new VXLAN header, provide an IPv4 object handle. If creating a new VxLAN object, provide an IPv4 object handle. If modifying a OSPF, there are five options. 2-6 will query for the OSPF object handle. @@ -1322,219 +1056,148 @@ def configVxlanNgpf(self, obj=None, routerId=None, port=None, portName=None, ngp 4> Set portName: The vport port name. 5> Set NGPF OSPF name that you configured. 6> Set hostIp: The src IP. - - Parameters - obj: : IPv4 Obj example: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id} - VxLAN Obj example: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id}/vxlan/{id} - - Syntax - POST: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id}/vxlan - PATCH: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id}/vxlan/{id} - Example: - createVxlanNgpf(ipv4Object='/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1', - vtepName='vtep_1', - vtepVni={'start':2008, 'step':2, 'direction':'increment'}, - vtepIpv4Multicast={'start':'225.8.0.1', 'step':'0.0.0.1', 'direction':'increment'}) - - start = The starting value - step = 0 means don't increment or decrement. - For IP step = 0.0.0.1. Increment on the last octet. - 0.0.1.0. Increment on the third octet. - direction = increment or decrement the starting value. - - Return - /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id}/vxlan/{id} """ - if obj != None: + vxlanId = None + if obj is not None: if 'vxlan' not in obj: - self.ixnObj.logInfo('Create new VxLAN in NGPF') - response = self.ixnObj.post(self.ixnObj.httpHeader+obj+'/vxlan') - vxlanId = response.json()['links'][0]['href'] - self.ixnObj.logInfo('createVxlanNgpf: %s' % vxlanId) + vxlanId = obj.Ipv4.find().Vxlan.add() if 'vxlan' in obj: vxlanId = obj - # To modify + # To modify if ngpfEndpointName: - vxlanId = self.getNgpfObjectHandleByName(ngpfEndpointName=ngpfEndpointName, ngpfEndpointObject='vxlan') + vxlanId = self.getNgpfObjectHandleByName(ngpfEndpointName=ngpfEndpointName, + ngpfEndpointObject='vxlan') - # To modify + # To modify if port: x = self.getProtocolListByPortNgpf(port=port) vxlanId = self.getProtocolObjFromProtocolList(x['deviceGroup'], 'vxlan')[0] - # To modify + # To modify if portName: x = self.getProtocolListByPortNgpf(portName=portName) vxlanId = self.getProtocolObjFromProtocolList(x['deviceGroup'], 'vxlan')[0] - # To modify + # To modify if routerId: - vxlanId = self.getNgpfObjectHandleByRouterId(routerId=routerId, ngpfEndpointObject='vxlan') + vxlanId = self.getNgpfObjectHandleByRouterId(routerId=routerId, + ngpfEndpointObject='vxlan') - # To modify + # To modify if hostIp: x = self.getProtocolListByHostIpNgpf(hostIp) vxlanId = self.getProtocolObjFromHostIp(x, protocol='vxlan') - # Get VxLAN metadatas - vxlanResponse = self.ixnObj.get(self.ixnObj.httpHeader+vxlanId) - - for key,value in kwargs.items(): - if key == 'vtepName': - self.ixnObj.patch(self.ixnObj.httpHeader+vxlanId, data={'name': value}) + if 'vtepName' in kwargs: + kwargs['name'] = kwargs['vtepName'] + del kwargs['vtepName'] - if key == 'vtepVni': - multivalue = vxlanResponse.json()['vni'] - self.ixnObj.logInfo('Configuring VxLAN attribute: %s: %s' % (key, value)) - data={'start':kwargs['vtepVni']['start'], 'step':kwargs['vtepVni']['step'], 'direction':kwargs['vtepVni']['direction']} - self.configMultivalue(multivalue, 'counter', data=data) + if 'vtepIpv4Multicast' in kwargs: + kwargs['ipv4_multicast'] = kwargs['vtepIpv4Multicast'] + del kwargs['vtepIpv4Multicast'] - if key == 'vtepIpv4Multicast': - self.ixnObj.logInfo('Configuring VxLAN IPv4 multicast') - multivalue = vxlanResponse.json()['ipv4_multicast'] - data={'start':kwargs['vtepIpv4Multicast']['start'], 'step':kwargs['vtepIpv4Multicast']['step'], - 'direction':kwargs['vtepIpv4Multicast']['direction']} - self.configMultivalue(multivalue, 'counter', data=data) + for key, value in kwargs.items(): + itemObj = key[0:1].capitalize() + key[1:] + multivalueObj = getattr(vxlanId, itemObj) + try: + if type(value) == dict: + self.configMultivalue(multivalueObj, 'counter', value) + else: + self.configMultivalue(multivalueObj, 'singleValue', {'value': value}) + except Exception as e: + print(e) + setattr(vxlanId, itemObj, value) - self.configuredProtocols.append(vxlanId) + if vxlanId not in self.configuredProtocols: + self.configuredProtocols.append(vxlanId) return vxlanId def configRsvpTeLsps(self, ipv4Obj): """ Description - Create new RSVP-TE LSPS Tunnel. A RSVP-TE interface is created automatically if there + Create new RSVP-TE LSPS Tunnel. A RSVP-TE interface is created automatically if there is no RSVR-TE configured. - Parameter - ipv4Obj: : /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1 - - Syntax - POST: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id}/rsvpteLsps - - Return - /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id}/rsvrteLsps/{id} """ - self.ixnObj.logInfo('Creating new RSVP TE LSPS') - response = self.ixnObj.post(self.ixnObj.httpHeader+ipv4Obj+'/rsvpteLsps') - return response.json()['links'][0]['href'] - + rsvpTeObj = ipv4Obj.RsvpteLsps.add() + return rsvpTeObj + def deleteRsvpTeLsps(self, rsvpTunnelObj): """ Description Delete a RSVP-TE tunnel. Note: Deleting the last tunnel will also delete the RSVR-TE Interface. - Parameter - rsvrTunnelObj: : /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id}/rsvpteLsps/{id} - - Syntax - DELETE: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id}/rsvpteLsps/{id} """ - self.ixnObj.delete(self.ixnObj.httpHeader+rsvpTunnelObj) + rsvpTunnelObj.remove() def configNetworkGroup(self, **kwargs): """ Description Create or modify a Network Group for network advertisement. Supports both IPv4 and IPv6 - Pass in the Device Group obj for creating a new Network Group. - /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1 - Pass in the Network Group obj to modify. - /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/networkGroup/1 - - Syntax - POST: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/networkGroup - POST: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/networkGroup/{id}/ipv4PrefixPools Example: NOTE: Supports both IPv4 and IPv6 - Device Group object sample: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1 configNetworkGroup(create=deviceGroupObj name='networkGroup1', multiplier = 100, - networkAddress = {'start': '160.1.0.0', 'step': '0.0.0.1', 'direction': 'increment'}, + networkAddress = {'start': '160.1.0.0', 'step': '0.0.0.1', + 'direction': 'increment'}, prefixLength = 24) - To modify a Network Group: - NetworkGroup obj sample: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/networkGroup/1 + NetworkGroup obj configNetworkGroup(modify=networkGroupObj, name='networkGroup-ospf', multiplier = 500, - networkAddress = {'start': '200.1.0.0', 'step': '0.0.0.1', 'direction': 'increment'}, + networkAddress = {'start': '200.1.0.0', 'step': '0.0.0.1', + 'direction': 'increment'}, prefixLength = 32) - Return - /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/networkGroup/{id}/ipv4PrefixPools/{id} """ - # In case it is modify, we still need to return self.prefixPoolObj - self.prefixPoolObj = None - ipVersion = kwargs.get('ipVersion','ipv4') - + ipVersion = kwargs.get('ipVersion', 'ipv4') + prefixObj = None + networkGroupObj = None if 'create' not in kwargs and 'modify' not in kwargs: - raise IxNetRestApiException('configNetworkGroup requires either a create or modify parameter.') + raise IxNetRestApiException('configNetworkGroup requires either a create or modify ' + 'parameter.') if 'create' in kwargs: deviceGroupObj = kwargs['create'] - self.ixnObj.logInfo('Creating new Network Group') - response = self.ixnObj.post(self.ixnObj.httpHeader+deviceGroupObj+'/networkGroup') - networkGroupObj = response.json()['links'][0]['href'] + networkGroupObj = deviceGroupObj.find().NetworkGroup.add() + + if ipVersion == 'ipv4': + prefixObj = networkGroupObj.find().Ipv4PrefixPools.add() + elif ipVersion == 'ipv6': + prefixObj = networkGroupObj.find().Ipv6PrefixPools.add() if 'modify' in kwargs: networkGroupObj = kwargs['modify'] - - if 'name' in kwargs: - self.ixnObj.patch(self.ixnObj.httpHeader+networkGroupObj, data={'name': kwargs['name']}) - - if 'multiplier' in kwargs: - self.ixnObj.patch(self.ixnObj.httpHeader+networkGroupObj, data={'multiplier': kwargs['multiplier']}) - - if 'create' in kwargs: - if ipVersion == 'ipv6': - self.ixnObj.logInfo('Create new Network Group IPv6 Prefix Pools') - response = self.ixnObj.post(self.ixnObj.httpHeader+networkGroupObj+'/ipv6PrefixPools') - prefixObj = response.json()['links'][0]['href'] - else: - # For IPv4 - self.ixnObj.logInfo('Create new Network Group IPv4 Prefix Pools') - response = self.ixnObj.post(self.ixnObj.httpHeader+networkGroupObj+'/ipv4PrefixPools') - prefixObj = response.json()['links'][0]['href'] - else: - if ipVersion == 'ipv6': - prefixObj = networkGroupObj+'/ipv6PrefixPools/1' + if ipVersion == 'ipv4': + prefixObj = networkGroupObj.find().Ipv4PrefixPools.find() else: - prefixObj = networkGroupObj+'/ipv4PrefixPools/1' - - # prefixPoolId = /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/networkGroup/3/ipv4PrefixPools/1 - response = self.ixnObj.get(self.ixnObj.httpHeader + prefixObj) - self.ixnObj.logInfo('Config Network Group advertising routes') - - multivalue = response.json()['networkAddress'] + prefixObj = networkGroupObj.find().Ipv6PrefixPools.find() + networkAddrObj = prefixObj.find().NetworkAddress if 'networkAddress' in kwargs: - data={'start': kwargs['networkAddress']['start'], - 'step': kwargs['networkAddress']['step'], - 'direction': kwargs['networkAddress']['direction']} - else: - data={} + self.configMultivalue(networkAddrObj, 'counter', kwargs['networkAddress']) - self.ixnObj.configMultivalue(multivalue, 'counter', data) + if 'name' in kwargs: + networkGroupObj.Name = kwargs['name'] - if 'prefixLength' in kwargs: - self.ixnObj.logInfo('Config Network Group prefix pool length') - response = self.ixnObj.get(self.ixnObj.httpHeader + prefixObj) - multivalue = response.json()['prefixLength'] - data={'value': kwargs['prefixLength']} - self.ixnObj.configMultivalue(multivalue, 'singleValue', data) + if 'multiplier' in kwargs: + networkGroupObj.Multiplier = kwargs['multiplier'] - if 'numberOfAddresses' in kwargs: - self.ixnObj.patch(self.ixnObj.httpHeader+prefixObj, data={'numberOfAddresses': kwargs['numberOfAddresses']}) + if 'prefixLength' in kwargs: + if type(kwargs['prefixLength']) == 'int': + networkAddrObj.Single(kwargs['prefixLength']) return networkGroupObj, prefixObj @@ -1544,79 +1207,65 @@ def configNetworkGroupWithTopology(self, topoType='Linear', **kwargs): Create or modify a Network Group Topology for network advertisement. Pass in the Device Group obj for creating a new Network Group. - /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1 Pass in the Network Group obj to modify. - /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/networkGroup/1 Pass in topoType(topology type) to configure require network with topology type Ex: 'Custom','Fat Tree','Grid','Hub-And-Spoke','Linear','Mesh','Ring','Tree' - Syntax - POST: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/networkGroup - POST: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/networkGroup/{id}/networkTopology/ - Example: - Device Group object sample: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1 configNetworkGroupWithTopology(topoType='Linear',create=deviceGroupObj name='networkGroup1', multiplier = 100 ) - To modify a Network Group: - NetworkGroup obj sample: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/networkGroup/1 configNetworkGroupWithTopology(topoType='Linear',modify=networkGroupObj, name='networkGroup-ospf', multiplier = 100, ) - - Return - /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/networkGroup/{id} - /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/networkGroup/{id}/networkTopology/netTopologyLinear """ + networkGroupObj = None + networkTopologyObj = None # In case it is modify, we still need to return self.prefixPoolObj - self.topoTypeDict = {'Custom' : 'netTopologyCustom', - 'Fat Tree' : 'netTopologyFatTree', - 'Grid' : 'netTopologyGrid', - 'Hub-And-Spoke' : 'netTopologyHubNSpoke', - 'Linear' : 'netTopologyLinear', - 'Mesh' : 'netTopologyMesh', - 'Ring' : 'netTopologyRing', - 'Tree' : 'netTopologyTree', - } - - self.networkTopologyObj = None + self.topoTypeDict = {'Custom': 'NetTopologyCustom', + 'Fat Tree': 'NetTopologyFatTree', + 'Grid': 'NetTopologyGrid', + 'Hub-And-Spoke': 'NetTopologyHubNSpoke', + 'Linear': 'NetTopologyLinear', + 'Mesh': 'NetTopologyMesh', + 'Ring': 'NetTopologyRing', + 'Tree': 'NetTopologyTree', + } if 'create' not in kwargs and 'modify' not in kwargs: - raise IxNetRestApiException('configNetworkGroup requires either a create or modify parameter.') + raise IxNetRestApiException('configNetworkGroup requires either a create or modify ' + 'parameter.') if 'create' in kwargs: deviceGroupObj = kwargs['create'] self.ixnObj.logInfo('Creating new Network Group') - response = self.ixnObj.post(self.ixnObj.httpHeader + deviceGroupObj + '/networkGroup') - networkGroupObj = response.json()['links'][0]['href'] - + networkGroupObj = deviceGroupObj.NetworkGroup.add() + networkTopology = networkGroupObj.NetworkTopology.add() + networkTopologyTypeObj = getattr(networkTopology, self.topoTypeDict[topoType]) + networkTopologyObj = networkTopologyTypeObj.add() if 'modify' in kwargs: networkGroupObj = kwargs['modify'] + networkTopology = networkGroupObj.NetworkTopology.find() + networkTopologyTypeObj = getattr(networkTopology, self.topoTypeDict[topoType]) + if networkTopologyTypeObj.find(): + networkTopologyObj = networkTopologyTypeObj.find() + else: + networkTopologyTypeObj = getattr(networkTopology, self.topoTypeDict[topoType]) + networkTopologyObj = networkTopologyTypeObj.add() if 'name' in kwargs: - self.ixnObj.patch(self.ixnObj.httpHeader + networkGroupObj, data={'name': kwargs['name']}) + networkGroupObj.Name = kwargs['name'] if 'multiplier' in kwargs: - self.ixnObj.patch(self.ixnObj.httpHeader + networkGroupObj, data={'multiplier': kwargs['multiplier']}) - - if 'create' in kwargs: - self.ixnObj.logInfo('Create new Network Group network topology') - response = self.ixnObj.post(self.ixnObj.httpHeader + networkGroupObj + '/networkTopology') - response = self.ixnObj.post(self.ixnObj.httpHeader + networkGroupObj + '/networkTopology/'+self.topoTypeDict[topoType]) - networkTopologyObj = response.json()['links'][0]['href'] - else: - networkTopologyObj = networkGroupObj + '/networkTopology/'+self.topoTypeDict[topoType] - + networkGroupObj.Multiplier = kwargs['multiplier'] return networkGroupObj, networkTopologyObj - def configNetworkTopologyProperty(self, networkGroupObj, pseudoRouter, **kwargs): """ Description @@ -1624,68 +1273,52 @@ def configNetworkTopologyProperty(self, networkGroupObj, pseudoRouter, **kwargs) Supports all networkTopology. For networkTopologyRange attributes, use the IxNetwork API browser. - Parameters - networkGroupObj: : Example: - /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/networkGroup/{id} - - pseudoRouter: : Example: ospfv3PseudoRouter - - data: The protocol properties. Make your configuration and get from IxNetwork API Browser. - - Syntax - PATCH: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/networkGroup/{id}/networkTopology/simRouter/1{id} """ - response = self.ixnObj.get(self.ixnObj.httpHeader + networkGroupObj + '/networkTopology/simRouter/1') - self.ixnObj.logInfo('Config Network Group advertising routes') - multivalue = response.json()['routerId'] - + simRouteObj = networkGroupObj.NetworkTopology.find().SimRouter.find() if 'routerId' in kwargs: data = {'start': kwargs['routerId']['start'], 'step': kwargs['routerId']['step'], 'direction': kwargs['routerId']['direction']} - else: - data = {} - - self.ixnObj.configMultivalue(multivalue, 'counter', data) + self.configMultivalue(simRouteObj.RouterId, 'counter', kwargs['routerId']) + pseudoRouter = pseudoRouter[0].capitalize() + pseudoRouter[1:] if 'routerLsaBit' in kwargs: self.ixnObj.logInfo('Config router lsa type') - response = self.ixnObj.get( - self.ixnObj.httpHeader + networkGroupObj + '/networkTopology/simRouter/1'+ '/{0}/1'.format(pseudoRouter)) - if kwargs['routerLsaBit'] == 'B': - multivalue = response.json()['bBit'] data = {'value': 'True'} - self.ixnObj.configMultivalue(multivalue, 'singleValue', data) + pseudoRouterObj = getattr(simRouteObj, pseudoRouter) + multiValue = pseudoRouterObj.find().BBit + self.configMultivalue(multiValue, 'singleValue', data) elif kwargs['routerLsaBit'] == 'E': - multivalue = response.json()['eBit'] data = {'value': 'True'} - self.ixnObj.configMultivalue(multivalue, 'singleValue', data) + pseudoRouterObj = getattr(simRouteObj, pseudoRouter) + multiValue = pseudoRouterObj.find().EBit + self.configMultivalue(multiValue, 'singleValue', data) def prefixPoolsConnector(self, prefixPoolsObj, protocolObj): """ Description To attach prefixPoolsObj to required protocolobj stack - :param prefixPoolsObj: Prefix Pools Object which should be connected to given protocol object + :param prefixPoolsObj: Prefix Pools Object which should be connected to given protocol + object :param protocolObj: Protocol object for which prefixpool object should be connected """ - response = self.ixnObj.patch(self.ixnObj.httpHeader + prefixPoolsObj + '/connector', - data={"connectedTo": protocolObj}) + prefixPoolsObj.Connector.add(ConnectedTo=protocolObj) def networkGroupWithTopologyConnector(self, networkGroupObj, protocolObj): """ Description To attach networkgroupobj to required protocolobj stack - :param networkGroupObj: networkgroup object with topology which should be connected to protocol object - :param protocolObj: protocol object for which networkgroup with topology object should be connected + :param networkGroupObj: networkgroup object with topology which should be connected to + protocol object + :param protocolObj: protocol object for which networkgroup with topology object should be + connected """ - response = self.ixnObj.patch(self.ixnObj.httpHeader + networkGroupObj + '/networkTopology/simRouter/1/connector', - data={"connectedTo": protocolObj}) - - + connectorObj = networkGroupObj.NetworkTopology.find().SimRouter.find().Connector.find() + connectorObj.ConnectedTo = protocolObj def configBgpRouteRangeProperty(self, prefixPoolsObj, protocolRouteRange, data, asPath): """ @@ -1695,33 +1328,38 @@ def configBgpRouteRangeProperty(self, prefixPoolsObj, protocolRouteRange, data, For protocolRouteRange attributes, use the IxNetwork API browser. Parameters - prefixPoolsObj: : Example: - /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/networkGroup/{id}/ipv4PrefixPools/{id} + prefixPoolsObj: : protocolRouteRange: : Get choices from IxNetwork API Browser. Current choices: bgpIPRouteProperty, isisL3RouteProperty, etc. - data: The protocol properties. Make your configuration and get from IxNetwork API Browser. + data:The protocol properties.Make your configuration and get from IxNetwork API Browser. - asPath: AS path protocol properties. Make your configuration and get from IxNetwork API Browser + asPath: AS path protocol properties. Make your configuration and get from IxNetwork API + Browser - Syntax - PATCH: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/networkGroup/{id}/ipv4PrefixPools/{id}/protocolRouterRange/{id} """ - response = self.ixnObj.get(self.ixnObj.httpHeader + prefixPoolsObj + '/{0}/1'.format(protocolRouteRange)) - routeRangeObj = response.json()['links'][0]['href'] + protocolRouteRangeResponse = getattr(prefixPoolsObj, protocolRouteRange) + routeProtocolObj = protocolRouteRangeResponse.find() for attribute, value in data.items(): - multivalue = response.json()[attribute] - self.ixnObj.logInfo('Configuring PrefixPools {0} Route Property multivalue attribute: {1}'.format(protocolRouteRange, attribute)) - self.ixnObj.patch(self.ixnObj.httpHeader+multivalue+"/singleValue", data={'value': data[attribute]}) - + attribute = attribute[0].capitalize() + attribute[1:] + try: + multiValueObj = getattr(routeProtocolObj, attribute) + self.ixnObj.configMultivalue(multiValueObj, 'singlevalue', {'value': value}) + except Exception as e: + print(e) + setattr(routeProtocolObj, attribute, value) + # TODO Need confirmation on below AS path attributes. if asPath != {}: - response = self.ixnObj.get(self.ixnObj.httpHeader + routeRangeObj + '/{0}/1'.format('bgpAsPathSegmentList')) + asPathObj = routeProtocolObj.BgpAsPathSegmentList.find() for attribute, value in asPath.items(): - multivalue = response.json()[attribute] - self.ixnObj.logInfo('Configuring AsPath {0} Segment Property multivalue attribute: {1}'.format('bgpAsPathSegmentList', attribute)) - self.ixnObj.patch(self.ixnObj.httpHeader + multivalue + "/singleValue", data={'value': asPath[attribute]}) - + attribute = attribute[0].capitalize() + attribute[1:] + try: + multiValueObj = getattr(asPathObj, attribute) + self.ixnObj.configMultivalue(multiValueObj, 'singlevalue', {'value': value}) + except Exception as e: + print(e) + setattr(asPathObj, attribute, value) def configPrefixPoolsIsisL3RouteProperty(self, prefixPoolsObj, **data): """ @@ -1731,19 +1369,21 @@ def configPrefixPoolsIsisL3RouteProperty(self, prefixPoolsObj, **data): For more property and value references, use the IxNetwork API browser. Parameters - prefixPoolsObj: : Example: - /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/networkGroup/{id}/ipv4PrefixPools/{id} + prefixPoolsObj: : - data: Properties: active, advIPv6Prefix, BAR, BFRId, BFRIdStep, BIERBitStingLength, eFlag, labelRangeSize, - labelStart, nFlag, pFlag, rFlag, vFlag, redistribution, routeOrigin, subDomainId - Syntax - PATCH: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/networkGroup/{id}/ipv4PrefixPools/{id} + data: Properties: active, advIPv6Prefix, BAR, BFRId, BFRIdStep, BIERBitStingLength, + eFlag, labelRangeSize, labelStart, nFlag, pFlag, rFlag, vFlag, + redistribution, routeOrigin, subDomainId """ - response = self.ixnObj.get(self.ixnObj.httpHeader + prefixPoolsObj + '/isisL3RouteProperty/1') + isisL3RoutePropObj = prefixPoolsObj.IsisL3RouteProperty.find() for attribute, value in data.items(): - multivalue = response.json()[attribute] - self.ixnObj.logInfo('Configuring PrefixPools ISIS L3 Route Property multivalue attribute: %s' % attribute) - self.ixnObj.patch(self.ixnObj.httpHeader+multivalue+"/singleValue", data={'value': data[attribute]}) + attribute = attribute[0].capitalize() + attribute[1:] + try: + multiValueObj = getattr(isisL3RoutePropObj, attribute) + self.ixnObj.configMultivalue(multiValueObj, 'singlevalue', {'value': value}) + except Exception as e: + print(e) + setattr(isisL3RoutePropObj, attribute, value) def configPrefixPoolsRouteProperty(self, prefixPoolsObj, protocolRouteRange, **data): """ @@ -1753,32 +1393,32 @@ def configPrefixPoolsRouteProperty(self, prefixPoolsObj, protocolRouteRange, **d For protocolRouteRange attributes, use the IxNetwork API browser. Parameters - prefixPoolsObj: : Example: - /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/networkGroup/{id}/ipv4PrefixPools/{id} + prefixPoolsObj: : protocolRouteRange: : Get choices from IxNetwork API Browser. Current choices: bgpIPRouteProperty, isisL3RouteProperty, etc. - data: The protocol properties. Make your configuration and get from IxNetwork API Browser. - Syntax - PATCH: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/networkGroup/{id}/ipv4PrefixPools/{id}/protocolRouterRange/{id} + data: The protocol properties. Make your configuration and get from IxNetwork + API Browser. """ - ''' - response = self.ixnObj.get(self.ixnObj.httpHeader + prefixPoolsObj + '/{0}/1'.format(protocolRouteRange)) - for attribute, value in data.items(): - multivalue = response.json()[attribute] - self.ixnObj.logInfo('Configuring PrefixPools {0} Route Property multivalue attribute: {1}'.format(protocolRouteRange, attribute)) - self.ixnObj.patch(self.ixnObj.httpHeader+multivalue+"/singleValue", data={'value': data[attribute]}) - ''' - response = self.ixnObj.get(self.ixnObj.httpHeader + prefixPoolsObj + '/{0}/1'.format(protocolRouteRange)) + protocolRouteRange = protocolRouteRange[0].capitalize() + protocolRouteRange[1:] + protocolRouteRange = getattr(prefixPoolsObj, protocolRouteRange) + protocolRouteRangeObj = protocolRouteRange.find() for attribute, value in data.items(): - multivalue = response.json()[attribute] - self.ixnObj.logInfo('Configuring PrefixPools {0} Route Property multivalue attribute: {1}'.format(protocolRouteRange, attribute)) - if type(value) == dict: - if 'direction' in value: - self.ixnObj.patch(self.ixnObj.httpHeader + multivalue + "/counter", data=value) - else: - self.ixnObj.patch(self.ixnObj.httpHeader+multivalue+"/singleValue", data={'value': data[attribute]}) + attribute = attribute[0:1].capitalize() + attribute[1:] + self.ixnObj.logInfo('Configuring PrefixPools {0} Route Property multivalue attribute: ' + '{1}'.format(protocolRouteRange, attribute)) + try: + multivalue = getattr(protocolRouteRangeObj, attribute) + if type(value) == dict: + if 'direction' in value: + self.configMultivalue(multivalue, 'counter', data=value) + else: + self.configMultivalue(multivalue, "singleValue", + data={'value': data[attribute]}) + except Exception as e: + print(e) + setattr(protocolRouteRangeObj, attribute, value) def configMultivalue(self, multivalueUrl, multivalueType, data): """ @@ -1786,26 +1426,49 @@ def configMultivalue(self, multivalueUrl, multivalueType, data): Configure multivalues. Parameters - multivalueUrl: : The multivalue: /api/v1/sessions/{1}/ixnetwork/multivalue/1 - multivalueType: : counter|singleValue|valueList|repeatableRandom|repeatableRandomRange|custom + multivalueUrl: : + multivalueType: : counter|singleValue|valueList|repeatableRandom| + repeatableRandomRange|custom data: : singleValue: data={'value': '1.1.1.1'}) - valueList: data needs to be in a [list]: data={'values': [list]} - counter: data={'start': value, 'direction': increment|decrement, 'step': value} + valueList:data needs to be in a [list]: data={'values': [list]} + counter:data={'start': value, 'direction': increment|decrement, + 'step': value} data examples if multivalueType == 'counter': - data = {'start': '00:01:01:00:00:01', 'direction': 'increment', 'step': '00:00:00:00:00:01'} + data = {'start': '00:01:01:00:00:01', 'direction': 'increment', + 'step': '00:00:00:00:00:01'} if multivalueType == 'singleValue': data={'value': value} if multivalueType == 'valueList': data={'values': ['item1', 'item2']} - Syntax - PATCH: /api/v1/sessions/{id}/ixnetwork/multivalue/{id}/singleValue - PATCH: /api/v1/sessions/{id}/ixnetwork/multivalue/{id}/counter - PATCH: /api/v1/sessions/{id}/ixnetwork/multivalue/{id}/valueList """ - self.ixnObj.patch(self.ixnObj.httpHeader+multivalueUrl+'/'+multivalueType, data=data) + if multivalueType.lower() == "counter": + if data['direction'] == "increment": + multivalueUrl.Increment(start_value=data['start'], step_value=data['step']) + if data['direction'] == "decrement": + multivalueUrl.Decrement(start_value=data['start'], step_value=data['step']) + elif multivalueType.lower() == "singlevalue": + multivalueUrl.Single(data['value']) + elif multivalueType.lower() == "valuelist": + multivalueUrl.ValueList(data['values']) + elif multivalueType.lower() == "randomrange": + multivalueUrl.RandomRange(min_value=data['min_value'], max_value=data['max_value'], + step_value=data['step_value'], seed=data['seed']) + elif multivalueType.lower() == "custom": + multivalueUrl.Custom(start_value=data['start_value'], step_value=data['step_value'], + increments=data['increments']) + elif multivalueType.lower() == "alternate": + multivalueUrl.Alternate(data['alternating_value']) + elif multivalueType.lower() == "distributed": + multivalueUrl.Distributed(algorithm=data['algorithm'], mode=data['mode'], + values=data['values']) + elif multivalueType.lower() == "randommask": + multivalueUrl.RandomMask(fixed_value=data['fixed_value'], mask_value=data['mask_value'], + seed=data['seed'], count=data['count']) + elif multivalueType.lower() == "string": + multivalueUrl.String(string_pattern=data['string_pattern']) def getMultivalueValues(self, multivalueObj, silentMode=False): """ @@ -1813,11 +1476,8 @@ def getMultivalueValues(self, multivalueObj, silentMode=False): Get the multivalue values. Parameters - multivalueObj: : The multivalue object: /api/v1/sessions/{1}/ixnetwork/multivalue/{id} + multivalueObj: : The multivalue object silentMode: : True=Display the GET and status code. False=Don't display. - - Syntax - /api/v1/sessions/{id}/ixnetwork/multivalue/{id}?includes=count Requirements self.ixnObj.waitForComplete() @@ -1825,31 +1485,22 @@ def getMultivalueValues(self, multivalueObj, silentMode=False): Return The multivalue values """ - response = self.ixnObj.get(self.ixnObj.httpHeader+multivalueObj+'?includes=count', silentMode=silentMode) - count = response.json()['count'] - if silentMode == False: - self.ixnObj.logInfo('getMultivalueValues: {0} Count={1}'.format(multivalueObj, count)) - data = {'arg1': multivalueObj, - 'arg2': 0, - 'arg3': count - } - response = self.ixnObj.post(self.ixnObj.sessionUrl+'/multivalue/operations/getValues', data=data, silentMode=silentMode) - self.ixnObj.waitForComplete(response, self.ixnObj.sessionUrl+'/operations/multivalue/getValues'+response.json()['id'], silentMode=silentMode) - return response.json()['result'] + return multivalueObj.Values def verifyProtocolSessionsUp(self, protocolViewName='BGP Peer Per Port', timeout=60): """ Description - This method either verify a specified protocol sessions for UP or automatically verify for all - the configured protocols for sessions UP. + This method either verify a specified protocol sessions for UP or automatically + verify for all the configured protocols for sessions UP. - This method calls verifyProtocolSessionsNgpf() if you're using IxNetwork version prior to 8.50. - For IxNetwork versions >8.50, it calls verifyProtocolSessionsUp2() which is more robust + This method calls verifyProtocolSessionsNgpf() if you're using IxNetwork version + prior to 8.50. + For IxNetwork versions >8.50, it calls verifyProtocolSessionsUp2() which is more robust because 8.50 introduced new APIs. - + Parameters - protocolViewName: : The protocol to verify. You could get the exact view name in the - IxNetwork API browser. + protocolViewName: : The protocol to verify. You could get the exact view + name in the IxNetwork API browser. Some protocolViewName options: 'ISIS-L3 RTR Per Port' @@ -1858,16 +1509,17 @@ def verifyProtocolSessionsUp(self, protocolViewName='BGP Peer Per Port', timeout """ buildNumber = float(self.ixnObj.getIxNetworkVersion()[:3]) if buildNumber >= 8.5: - self.verifyProtocolSessionsUp2() + self.verifyProtocolSessionsUp2(protocolViewName, timeout) else: - self.verifyAllProtocolSessionsNgpf() + self.verifyAllProtocolSessionsNgpf(timeout) def verifyProtocolSessionsUp1(self, protocolViewName='BGP Peer Per Port', timeout=60): """ Description Verify a specified protocol sessions for UP. - This method is mainly for IxNetwork version prior to 8.50. 8.50+ could still use this method, - but using verifyProtocolSessionsUp2 is more robust because 8.50 introduced new APIs. + This method is mainly for IxNetwork version prior to 8.50. 8.50+ could still use this + method, but using verifyProtocolSessionsUp2 is more robust because 8.50 + introduced new APIs. Parameter protocolViewName: The protocol view name. @@ -1877,13 +1529,12 @@ def verifyProtocolSessionsUp1(self, protocolViewName='BGP Peer Per Port', timeou 'BGP Peer Per Port' 'OSPFv2-RTR Per Port' """ - totalSessionsDetectedUp = 0 - totalSessionsDetectedDown = 0 totalPortsUpFlag = 0 - - for counter in range(1,timeout+1): + sessionsUp = 0 + totalExpectedSessionsUp = 0 + for counter in range(1, timeout + 1): stats = self.ixnObj.getStatsPage(viewName=protocolViewName, displayStats=False) - totalPorts = len(stats.keys()) ;# Length stats.keys() represents total ports. + totalPorts = len(stats.keys()) self.ixnObj.logInfo('\nProtocolName: {0}'.format(protocolViewName)) for session in stats.keys(): @@ -1892,8 +1543,10 @@ def verifyProtocolSessionsUp1(self, protocolViewName='BGP Peer Per Port', timeou totalSessionsNotStarted = int(stats[session]['Sessions Not Started']) totalExpectedSessionsUp = totalSessions - totalSessionsNotStarted - self.ixnObj.logInfo('\n\tPortName: {0}\n\t TotalSessionsUp: {1}\n\t ExpectedTotalSessionsup: {2}'.format( - stats[session]['Port'], sessionsUp, totalExpectedSessionsUp)) + self.ixnObj.logInfo('\n\tPortName: {0}\n\t TotalSessionsUp: {1}\n\t ' + 'ExpectedTotalSessionsup: {2}'.format(stats[session]['Port'], + sessionsUp, + totalExpectedSessionsUp)) if counter < timeout and sessionsUp != totalExpectedSessionsUp: self.ixnObj.logInfo('\t Session is still down') @@ -1915,19 +1568,15 @@ def verifyProtocolSessionsUp2(self, protocolViewName='Protocols Summary', timeou """ Description For IxNetwork version >= 8.50. - Defaults to Protocols Summary to verify all configured protocol sessions. There is no need - to specify specific protocols to verify. However, you still have the option to specific - protocol session to verify. - - Note: This get stats by using /statistics/statview//data. Prior to 8.50, - get stats uses /statistics/statview//page, which is deprecated started 8.50. - /statistics/statview//data is more robust. + Defaults to Protocols Summary to verify all configured protocol sessions. There is no + need to specify specific protocols to verify. However, you still have the option to + specific protocol session to verify. Parameter - protocolViewName: : The protocol view name. + protocolViewName: : The protocol view name. Get this name from API browser or in IxNetwork GUI statistic tabs. Defaults to 'Protocols Summary' - + timeout: : The timeout value to declare as failed. Default = 60 seconds. protocolViewName options: @@ -1938,21 +1587,18 @@ def verifyProtocolSessionsUp2(self, protocolViewName='Protocols Summary', timeou 'OSPFv2-RTR Per Port' 'Protocols Summary' """ - totalSessionsDetectedUp = 0 - totalSessionsDetectedDown = 0 - totalPortsUpFlag = 0 - - for counter in range(1,timeout+1): - stats = self.statObj.getStatsData(viewName=protocolViewName, displayStats=False, silentMode=True) - self.ixnObj.logInfo('\n%-16s %-14s %-16s %-23s %-22s' % ('Name', 'SessionsUp', 'SessionsDown', - 'ExpectedSessionsUp', 'SessionsNotStarted' ), + label = None + for counter in range(1, timeout + 1): + stats = self.statObj.getStatsData(viewName=protocolViewName, displayStats=False, + silentMode=True) + self.ixnObj.logInfo('\n%-16s %-14s %-16s %-23s %-22s' % ('Name', 'SessionsUp', + 'SessionsDown', + 'ExpectedSessionsUp', + 'SessionsNotStarted'), timestamp=False) - self.ixnObj.logInfo('-'*91, timestamp=False) - totalPorts = len(stats.keys()) ;# Length stats.keys() represents total ports or total protocols. - + self.ixnObj.logInfo('-' * 91, timestamp=False) sessionDownFlag = 0 sessionNotStartedFlag = 0 - sessionFailedFlag = 0 for session in stats.keys(): if 'Protocol Type' in stats[session]: @@ -1967,8 +1613,10 @@ def verifyProtocolSessionsUp2(self, protocolViewName='Protocols Summary', timeou sessionsNotStarted = int(stats[session]['Sessions Not Started']) expectedSessionsUp = totalSessions - sessionsNotStarted - self.ixnObj.logInfo('%-16s %-14s %-16s %-23s %-22s' % (label, sessionsUp, sessionsDown, - expectedSessionsUp, sessionsNotStarted), + self.ixnObj.logInfo('%-16s %-14s %-16s %-23s %-22s' % (label, sessionsUp, + sessionsDown, + expectedSessionsUp, + sessionsNotStarted), timestamp=False) if counter < timeout: @@ -1987,9 +1635,8 @@ def verifyProtocolSessionsUp2(self, protocolViewName='Protocols Summary', timeou if sessionNotStartedFlag == 1: if counter < timeout: - sessionNotStartedFlag = 0 - self.ixnObj.logInfo('Protocol sessions are not started yet. Waiting {0}/{1} seconds'.format( - counter, timeout)) + self.ixnObj.logInfo('Protocol sessions are not started yet. Waiting {0}/{1} ' + 'seconds'.format(counter, timeout)) time.sleep(1) continue @@ -2010,133 +1657,71 @@ def startAllOspfv2(self): Description Start all OSPFv2. """ - queryData = {'from': '/', - 'nodes': [{'node': 'topology', 'properties': ['name'], 'where': []}, - {'node': 'deviceGroup', 'properties': [], 'where': []}, - {'node': 'ethernet', 'properties': [], 'where': []}, - {'node': 'ipv4', 'properties': [], 'where': []}, - {'node': 'ospfv2', 'properties': [], 'where': []}] - } - queryResponse = self.ixnObj.query(data=queryData) - for topologyObj in queryResponse.json()['result'][0]['topology']: - for deviceGroupObj in topologyObj['deviceGroup']: - if deviceGroupObj['ethernet'][0]['ipv4'][0]['ospfv2'] != []: - for ospfObj in deviceGroupObj['ethernet'][0]['ipv4'][0]['ospfv2']: - data = {'arg1': [ospfObj['href']]} - self.ixnObj.post(self.ixnObj.httpHeader+ospfObj['href']+'/operations/start', data=data) + self.ixNetwork.Topology.find().DeviceGroup.find().Ethernet.find().Ipv4.find().Ospfv2.find() def startAllRsvpTeIf(self): """ Description Start all RSVP-TE Interface. """ - queryData = {'from': '/', - 'nodes': [{'node': 'topology', 'properties': ['name'], 'where': []}, - {'node': 'deviceGroup', 'properties': [], 'where': []}, - {'node': 'ethernet', 'properties': [], 'where': []}, - {'node': 'ipv4', 'properties': [], 'where': []}, - {'node': 'rsvpteIf', 'properties': [], 'where': []}] - } - queryResponse = self.ixnObj.query(data=queryData) - for topologyObj in queryResponse.json()['result'][0]['topology']: - for deviceGroupObj in topologyObj['deviceGroup']: - if deviceGroupObj['ethernet'][0]['ipv4'][0]['rsvpteIf'] != []: - for rsvpTeIfObj in deviceGroupObj['ethernet'][0]['ipv4'][0]['rsvpteIf']: - data = {'arg1': [rsvpTeIfObj['href']]} - self.ixnObj.post(self.ixnObj.httpHeader+rsvpTeIfObj['href']+'/operations/start', data=data) + rsvpTeList = self.ixNetwork.Topology.find().DeviceGroup.find().Ethernet.find().Ipv4.find() \ + .RsvpteIf.find() + for rsvpObj in rsvpTeList: + rsvpObj.start() def startAllRsvpTeLsps(self): """ Description Start all RSVP-TE LSPS (Tunnels). """ - queryData = {'from': '/', - 'nodes': [{'node': 'topology', 'properties': ['name'], 'where': []}, - {'node': 'deviceGroup', 'properties': [], 'where': []}, - {'node': 'ethernet', 'properties': [], 'where': []}, - {'node': 'ipv4', 'properties': [], 'where': []}, - {'node': 'rsvpteLsps', 'properties': [], 'where': []}] - } - queryResponse = self.ixnObj.query(data=queryData) - for topologyObj in queryResponse.json()['result'][0]['topology']: - for deviceGroupObj in topologyObj['deviceGroup']: - if deviceGroupObj['ethernet'][0]['ipv4'][0]['rsvpteLsps'] != []: - for rsvpTeLspsObj in deviceGroupObj['ethernet'][0]['ipv4'][0]['rsvpteLsps']: - data = {'arg1': [rsvpTeLspsObj['href']]} - self.ixnObj.post(self.ixnObj.httpHeader+rsvpTeLspsObj['href']+'/operations/start', data=data) + rsvpTeLspList = self.ixNetwork.Topology.find().DeviceGroup.find().Ethernet.find() \ + .Ipv4.find().RsvpteLsps.find() + for rsvpTeLspObj in rsvpTeLspList: + rsvpTeLspObj.start() def verifyDeviceGroupStatus(self): - queryData = {'from': '/', - 'nodes': [{'node': 'topology', 'properties': [], 'where': []}, - {'node': 'deviceGroup', 'properties': ['href', 'enabled'], 'where': []}, - {'node': 'deviceGroup', 'properties': ['href', 'enabled'], 'where': []}] - } - - queryResponse = self.ixnObj.query(data=queryData) - deviceGroupTimeout = 90 - for topology in queryResponse.json()['result'][0]['topology']: - for deviceGroup in topology['deviceGroup']: - deviceGroupObj = deviceGroup['href'] - response = self.ixnObj.get(self.ixnObj.httpHeader+deviceGroupObj, silentMode=False) - # Verify if the Device Group is enabled. If not, don't go further. - enabledMultivalue = response.json()['enabled'] - enabled = self.ixnObj.getMultivalueValues(enabledMultivalue, silentMode=False) - if enabled[0] == 'true': - for counter in range(1,deviceGroupTimeout+1): - response = self.ixnObj.get(self.ixnObj.httpHeader+deviceGroupObj, silentMode=False) - deviceGroupStatus = response.json()['status'] - self.ixnObj.logInfo('\t%s' % deviceGroupObj, timestamp=False) - self.ixnObj.logInfo('\t\tStatus: %s' % deviceGroupStatus, timestamp=False) - if counter < deviceGroupTimeout and deviceGroupStatus != 'started': - self.ixnObj.logInfo('\t\tWaiting %d/%d seconds ...' % (counter, deviceGroupTimeout), timestamp=False) + innerDeviceGroupObj = None + deviceGroupList = self.ixNetwork.Topology.find().DeviceGroup.find() + for counter in range(1, deviceGroupTimeout + 1): + for deviceGroupObj in deviceGroupList: + deviceGroupStatus = deviceGroupObj.Status + if counter < deviceGroupTimeout and deviceGroupStatus != 'started': + self.ixnObj.logInfo('\t\tWaiting %d/%d seconds ...' % (counter, + deviceGroupTimeout), + timestamp=False) + time.sleep(1) + if counter < deviceGroupTimeout and deviceGroupStatus == 'started': + break + if counter == deviceGroupTimeout and deviceGroupStatus != 'started': + raise IxNetRestApiException('\nDevice Group failed to start up') + + innerDeviceGroupObj = deviceGroupObj.DeviceGroup.find() + for counter in range(1, deviceGroupTimeout): + for innerDeviceGroupObj in innerDeviceGroupObj: + innerDeviceGroupStatus = innerDeviceGroupObj.Status + if counter < deviceGroupTimeout and innerDeviceGroupStatus != 'started': + self.ixnObj.logInfo('\tWait %d/%d' % (counter, deviceGroupTimeout), + timestamp=False) time.sleep(1) - if counter < deviceGroupTimeout and deviceGroupStatus == 'started': + if counter < deviceGroupTimeout and innerDeviceGroupStatus == 'started': break - if counter == deviceGroupTimeout and deviceGroupStatus != 'started': - raise IxNetRestApiException('\nDevice Group failed to start up') - - # Inner Device Group - if deviceGroup['deviceGroup'] != []: - innerDeviceGroupObj = deviceGroup['deviceGroup'][0]['href'] - for counter in range(1,deviceGroupTimeout): - response = self.ixnObj.get(self.ixnObj.httpHeader+innerDeviceGroupObj, silentMode=True) - innerDeviceGroupStatus = response.json()['status'] - self.ixnObj.logInfo('\tInnerDeviceGroup: %s' % innerDeviceGroupObj, timestamp=False) - self.ixnObj.logInfo('\t Status: %s' % innerDeviceGroupStatus, timestamp=False) - if counter < deviceGroupTimeout and innerDeviceGroupStatus != 'started': - self.ixnObj.logInfo('\tWait %d/%d' % (counter, deviceGroupTimeout), timestamp=False) - time.sleep(1) - if counter < deviceGroupTimeout and innerDeviceGroupStatus == 'started': - break - if counter == deviceGroupTimeout and innerDeviceGroupStatus != 'started': - raise IxNetRestApiException('\nInner Device Group failed to start up') - print() + if counter == deviceGroupTimeout and innerDeviceGroupStatus != 'started': + raise IxNetRestApiException('\nInner Device Group failed to start up') def startAllProtocols(self): """ Description Start all protocols in NGPF and verify all Device Groups are started. - - Syntax - POST: /api/v1/sessions/{id}/ixnetwork/operations/startallprotocols """ - url = self.ixnObj.sessionUrl+'/operations/startallprotocols' - response = self.ixnObj.post(url) - self.ixnObj.waitForComplete(response, url+'/'+response.json()['id']) - self.verifyDeviceGroupStatus() + self.ixNetwork.StartAllProtocols() def stopAllProtocols(self): """ Description Stop all protocols in NGPF - - Syntax - POST: /api/v1/sessions/{id}/ixnetwork/operations/stopallprotocols """ - url = self.ixnObj.sessionUrl+'/operations/stopallprotocols' - response = self.ixnObj.post(url, data={'arg1': 'sync'}) - self.ixnObj.waitForComplete(response, url+'/'+response.json()['id']) + self.stopAllProtocols() def startProtocol(self, protocolObj): """ @@ -2144,15 +1729,9 @@ def startProtocol(self, protocolObj): Start the specified protocol by its object handle. Parameters - protocolObj: : Ex: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/bgpIpv4Peer/1 - - Syntax - POST: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/bgpIpv4Peer/1/operations/start - DATA: {['arg1': [/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/bgpIpv4Peer/1']} + protocolObj: """ - url = self.ixnObj.httpHeader+protocolObj+'/operations/start' - response = self.ixnObj.post(url, data={'arg1': [protocolObj]}) - self.ixnObj.waitForComplete(response, url+'/'+response.json()['id']) + protocolObj.Start() def stopProtocol(self, protocolObj): """ @@ -2160,15 +1739,9 @@ def stopProtocol(self, protocolObj): Stop the specified protocol by its object handle. Parameters - protocolObj: : /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/bgpIpv4Peer/1 - - Syntax - POST: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/bgpIpv4Peer/1/operations/stop - DATA: {['arg1': [/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/bgpIpv4Peer/1']} + protocolObj: """ - url = self.ixnObj.httpHeader+protocolObj+'/operations/stop' - response = self.ixnObj.post(url, data={'arg1': [protocolObj]}) - self.ixnObj.waitForComplete(response, url+'/'+response.json()['id']) + protocolObj.Stop() def startTopology(self, topologyObjList='all'): """ @@ -2176,26 +1749,12 @@ def startTopology(self, topologyObjList='all'): Start a Topology Group and all of its protocol stacks. Parameters - topologyObjList: |: 'all' or a list of Topology Group href. - Ex: ['/api/v1/sessions/1/ixnetwork/topology/1'] + topologyObjList: |: 'all' or a list of Topology Group obj. """ if topologyObjList == 'all': - queryData = {'from': '/', - 'nodes': [{'node': 'topology', 'properties': ['href'], 'where': []}] - } - - # QUERY FOR THE BGP HOST ATTRIBITE OBJECTS - queryResponse = self.ixnObj.query(data=queryData) - try: - topologyList = queryResponse.json()['result'][0]['topology'] - except IndexError: - raise IxNetRestApiException('\nNo Topology Group objects found') - - topologyObjList = [topology['href'] for topology in topologyList] - - url = self.ixnObj.sessionUrl+'/topology/operations/start' - response = self.ixnObj.post(url, data={'arg1': topologyObjList}) - self.ixnObj.waitForComplete(response, url+'/'+response.json()['id']) + self.ixNetwork.Topology.find().Start() + else: + topologyObjList.Start() self.verifyDeviceGroupStatus() def stopTopology(self, topologyObjList='all'): @@ -2204,25 +1763,12 @@ def stopTopology(self, topologyObjList='all'): Stop the running Topology and all protocol sessions. Parameters - topologyObjList: : A list of Topology Group href. - Ex: ['/api/v1/sessions/1/ixnetwork/topology/1'] + topologyObjList: : A list of Topology Group obj. """ if topologyObjList == 'all': - queryData = {'from': '/', - 'nodes': [{'node': 'topology', 'properties': ['href'], 'where': []}] - } - - # QUERY FOR THE BGP HOST ATTRIBITE OBJECTS - queryResponse = self.ixnObj.query(data=queryData) - try: - topologyList = queryResponse.json()['result'][0]['topology'] - except IndexError: - raise IxNetRestApiException('\nNo Topology Group objects found') - - topologyObjList = [topology['href'] for topology in topologyList] - - self.ixnObj.post(self.ixnObj.sessionUrl+'/topology/operations/stop', data={'arg1': topologyObjList}) - self.ixnObj.waitForComplete(response, url+'/'+response.json()['id']) + self.ixNetwork.Topology.find().Stop() + else: + topologyObjList.Stop() def startStopDeviceGroup(self, deviceGroupObjList='all', action='start'): """ @@ -2231,57 +1777,34 @@ def startStopDeviceGroup(self, deviceGroupObjList='all', action='start'): Parameters deviceGroupObj: |: 'all' or a list of Device Group objects. - Ex: ['/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1'] - action: : 'start'|'stop' """ if deviceGroupObjList == 'all': - queryData = {'from': '/', - 'nodes': [{'node': 'topology', 'properties': [], 'where': []}, - {'node': 'deviceGroup', 'properties': ['href'], 'where': []}] - } - - queryResponse = self.ixnObj.query(data=queryData) - try: - topologyGroupList = queryResponse.json()['result'][0]['topology'] - except IndexError: - raise IxNetRestApiException('\nNo Device Group objects found') - - deviceGroupObjList = [] - for dg in topologyGroupList: - for dgHref in dg['deviceGroup']: - deviceGroupObjList.append(dgHref['href']) - - url = self.ixnObj.sessionUrl+'/topology/deviceGroup/operations/%s' % action - response = self.ixnObj.post(url, data={'arg1': deviceGroupObjList}) - self.ixnObj.waitForComplete(response, url+'/'+response.json()['id']) + if action == 'stop': + self.ixNetwork.Topology.find.DeviceGroup.find().Stop() + else: + self.ixNetwork.Topology.find.DeviceGroup.find().Start() + else: + if action == 'stop': + deviceGroupObjList.Stop() + else: + deviceGroupObjList.Start() time.sleep(3) def verifyProtocolSessionsNgpf(self, protocolObjList=None, timeout=90): """ Description Either verify the user specified protocol list to verify for session UP or verify - the default object's self.configuredProtocols list that accumulates the emulation protocol object - when it was configured. - When verifying IPv4, this API will verify ARP failures and return you a list of IP interfaces - that failed ARP. + the default object's self.configuredProtocols list that accumulates the emulation + protocol object when it was configured. When verifying IPv4, this API will verify + ARP failures and return you a list of IP interfaces that failed ARP. Parameters - protocolObjList: : A list of protocol objects. Default = None. The class will automatically verify all - of the configured protocols. - Ex: ['/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1', - '/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1', - '/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/bgpIpv4Peer/1', - '/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/ospfv2/1',] + protocolObjList: : A list of protocol objects. Default = None. + The class will automatically verify all of the configured protocols. timeout: : Total wait time for all the protocols in the provided list to come up. - Syntaxes - GET: http://10.219.117.103:11009/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1 - RESPONSE: [u'notStarted', u'notStarted', u'notStarted', u'notStarted', u'notStarted', u'notStarted'] - GET: http://10.219.117.103:11009/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1 - RESPONSE: [u'up', u'up', u'up', u'up', u'up', u'up', u'up', u'up'] - GET: http://10.219.117.103:11009/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/bgpIpv4Peer/1 """ timerStop = timeout if protocolObjList is None: @@ -2289,57 +1812,65 @@ def verifyProtocolSessionsNgpf(self, protocolObjList=None, timeout=90): for eachProtocol in protocolObjList: # notStarted, up or down - protocolName = eachProtocol.split('/')[-2] - for timer in range(1,timerStop+1): + protocolName = eachProtocol.href.split('/')[-2] + for timer in range(1, timerStop + 1): sessionStatus = self.getSessionStatus(eachProtocol) - # ['up'] - response = self.ixnObj.get(self.ixnObj.httpHeader+eachProtocol, silentMode=True) - # Started - protocolSessionStatus = response.json()['status'] + protocolSessionStatus = eachProtocol.Status - self.ixnObj.logInfo('\nVerifyProtocolSessions: %s\n' % eachProtocol, timestamp=False) - self.ixnObj.logInfo('\tprotocolSessionStatus: %s' % protocolSessionStatus, timestamp=False) + self.ixnObj.logInfo('\nVerifyProtocolSessions: %s\n' % eachProtocol, + timestamp=False) + self.ixnObj.logInfo('\tprotocolSessionStatus: %s' % protocolSessionStatus, + timestamp=False) self.ixnObj.logInfo('\tsessionStatusResponse: %s' % sessionStatus, timestamp=False) if timer < timerStop: if protocolSessionStatus != 'started': - self.ixnObj.logInfo('\tWait %s/%s seconds' % (timer, timerStop), timestamp=False) + self.ixnObj.logInfo('\tWait %s/%s seconds' % (timer, timerStop), + timestamp=False) time.sleep(1) continue # Started if 'up' not in sessionStatus: - self.ixnObj.logInfo('\tProtocol session is down: Wait %s/%s seconds' % (timer, timerStop), timestamp=False) + self.ixnObj.logInfo('\tProtocol session is down: Wait %s/%s seconds' % ( + timer, timerStop), + timestamp=False) time.sleep(1) continue if 'up' in sessionStatus: - self.ixnObj.logInfo('Protocol sessions are all up: {0}'.format(protocolName)) + self.ixnObj.logInfo('Protocol sessions are all up: {0}'. + format(protocolName)) break if timer == timerStop: if 'notStarted' in protocolSessionStatus: - raise IxNetRestApiException('\tverifyProtocolSessions: {0} session failed to start'.format(protocolName)) - + raise IxNetRestApiException('\tverifyProtocolSessions: {0} session failed' + 'to start'.format(protocolName)) + if protocolSessionStatus == 'started' and 'down' in sessionStatus: # Show ARP failures if protocolName == 'ipv4': ipInterfaceIndexList = [] index = 0 for eachSessionStatus in sessionStatus: - self.ixnObj.logInfo('eachSessionStatus index: {0} {1}'.format(eachSessionStatus, index), timestamp=False) + self.ixnObj.logInfo('eachSessionStatus index: {0} {1}'.format( + eachSessionStatus, index), timestamp=False) if eachSessionStatus == 'down': ipInterfaceIndexList.append(index) index += 1 - - ipMultivalue = response.json()['address'] - ipAddressList = self.ixnObj.getMultivalueValues(ipMultivalue, silentMode=True) + ipMultivalue = eachProtocol.Address + ipAddressList = self.ixnObj.getMultivalueValues(ipMultivalue, + silentMode=True) self.ixnObj.logWarning('ARP failed on IP interface:') for eachIpIndex in ipInterfaceIndexList: - self.ixnObj.logInfo('\t{0}'.format(ipAddressList[eachIpIndex]), timestamp=False) + self.ixnObj.logInfo('\t{0}'.format(ipAddressList[eachIpIndex]), + timestamp=False) else: - self.ixnObj.logWarning('\tverifyProtocolSessions: {0} session failed'.format(protocolName)) + self.ixnObj.logWarning('\tverifyProtocolSessions: {0} session failed'. + format(protocolName)) - raise IxNetRestApiException('Verify protocol sessions failed: {0}'.format(protocolName)) + raise IxNetRestApiException('Verify protocol sessions failed: {0}'. + format(protocolName)) def verifyAllProtocolSessionsInternal(self, protocol, timeout=120, silentMode=True): """ @@ -2351,19 +1882,19 @@ def verifyAllProtocolSessionsInternal(self, protocol, timeout=120, silentMode=Tr Parameters protocol: : The protocol object to verify the session state. timeout: : The timeout value for declaring as failed. Default = 120 seconds. - silentMode: : True to not display less on the terminal. False for debugging purpose. + silentMode: : True to not display less on the terminal. False for debugging + purpose. """ sessionDownList = ['down', 'notStarted'] - startCounter = 1 - response = self.ixnObj.get(self.ixnObj.httpHeader+protocol, silentMode=silentMode) - protocolActiveMultivalue = response.json()['active'] - response = self.ixnObj.getMultivalueValues(protocolActiveMultivalue, silentMode=silentMode) + + protocolActiveMultivalue = protocol.Active + response = self.getMultivalueValues(protocolActiveMultivalue) self.ixnObj.logInfo('\t%s' % protocol, timestamp=False) self.ixnObj.logInfo('\tProtocol is enabled: %s\n' % response[0], timestamp=False) if response[0] == 'false': return - for timer in range(startCounter, timeout+1): + for timer in range(1, timeout + 1): currentStatus = self.getSessionStatus(protocol) self.ixnObj.logInfo('\n%s' % protocol, timestamp=False) self.ixnObj.logInfo('\tTotal sessions: %d' % len(currentStatus), timestamp=False) @@ -2372,97 +1903,50 @@ def verifyAllProtocolSessionsInternal(self, protocol, timeout=120, silentMode=Tr if eachStatus != 'up': totalDownSessions += 1 self.ixnObj.logInfo('\tTotal sessions Down: %d' % totalDownSessions, timestamp=False) - #self.ixnObj.logInfo('\tCurrentStatus: %s' % currentStatus, timestamp=False) + self.ixnObj.logInfo('\tCurrentStatus: %s' % currentStatus, timestamp=False) - if timer < timeout and [element for element in sessionDownList if element in currentStatus] == []: + if timer < timeout and [element for element in sessionDownList + if element in currentStatus] == []: self.ixnObj.logInfo('Protocol sessions are all up') - startCounter = timer break - if timer < timeout and [element for element in sessionDownList if element in currentStatus] != []: + if timer < timeout and [element for element in sessionDownList + if element in currentStatus] != []: self.ixnObj.logInfo('\tWait %d/%d seconds' % (timer, timeout), timestamp=False) time.sleep(1) continue - if timer == timeout and [element for element in sessionDownList if element in currentStatus] != []: + if timer == timeout and [element for element in sessionDownList + if element in currentStatus] != []: raise IxNetRestApiException('\nError: Protocols failed') def verifyAllProtocolSessionsNgpf(self, timeout=120, silentMode=False): """ Description - Loop through each Topology Group and its enabled Device Groups and verify - all the created and activated protocols for session up. - Applies to Ethernet, IPv4 and IPv6. + Loop through each Topology Group and its enabled Device Groups and verify all the + created and activated protocols for session up. Applies to Ethernet, IPv4 and IPv6. Parameters timeout: : The timeout value for declaring as failed. Default = 120 seconds. - silentMode: : True to not display less on the terminal. False for debugging purpose. + silentMode: : True to not display less on the terminal. False for debugging + purpose. """ l2ProtocolList = ['isisL3', 'lacp', 'mpls'] - l3ProtocolList = ['ancp', 'bfdv4Interface', 'bgpIpv4Peer', 'bgpIpv6Peer', 'dhcpv4relayAgent', 'dhcpv6relayAgent', - 'geneve', 'greoipv4', 'greoipv6', 'igmpHost', 'igmpQuerier', - 'lac', 'ldpBasicRouter', 'ldpBasicRouterV6', 'ldpConnectedInterface', 'ldpv6ConnectedInterface', - 'ldpTargetedRouter', 'ldpTargetedRouterV6', 'lns', 'mldHost', 'mldQuerier', 'ptp', 'ipv6sr', - 'openFlowController', 'openFlowSwitch', 'ospfv2', 'ospfv3', 'ovsdbcontroller', 'ovsdbserver', - 'pcc', 'pce', 'pcepBackupPCEs', 'pimV4Interface', 'pimV6Interface', 'ptp', 'rsvpteIf', + l3ProtocolList = ['ancp', 'bfdv4Interface', 'bgpIpv4Peer', 'bgpIpv6Peer', + 'dhcpv4relayAgent', 'dhcpv6relayAgent', 'geneve', 'greoipv4', + 'greoipv6', 'igmpHost', 'igmpQuerier', 'lac', 'ldpBasicRouter', + 'ldpBasicRouterV6', 'ldpConnectedInterface', 'ldpv6ConnectedInterface', + 'ldpTargetedRouter', 'ldpTargetedRouterV6', 'lns', 'mldHost', + 'mldQuerier', 'ptp', 'ipv6sr', 'openFlowController', 'openFlowSwitch', + 'ospfv2', 'ospfv3', 'ovsdbcontroller', 'ovsdbserver', 'pcc', 'pce', + 'pcepBackupPCEs', 'pimV4Interface', 'pimV6Interface', 'ptp', 'rsvpteIf', 'rsvpteLsps', 'tag', 'vxlan'] - queryData = {'from': '/', - 'nodes': [{'node': 'topology', 'properties': [], 'where': []}, - {'node': 'deviceGroup', 'properties': ['href'], 'where': []}] - } - queryResponse = self.ixnObj.query(data=queryData) - try: - topologyGroupList = queryResponse.json()['result'][0]['topology'] - except IndexError: - raise IxNetRestApiException('\nNo Device Group objects found') + for protocol in l2ProtocolList: + self.verifyAllProtocolSessionsInternal(protocol) - deviceGroupObjList = [] - for topology in topologyGroupList: - for deviceGroup in topology['deviceGroup']: - deviceGroup = deviceGroup['href'] - response = self.ixnObj.get(self.ixnObj.httpHeader+deviceGroup) - # Verify if the Device Group is enabled. If not, don't go further. - enabledMultivalue = response.json()['enabled'] - response = self.ixnObj.getMultivalueValues(enabledMultivalue, silentMode=silentMode) - - self.ixnObj.logInfo('DeviceGroup is enabled: %s'% response) - if response[0] == 'false': - continue - - response = self.ixnObj.get(self.ixnObj.httpHeader+deviceGroup+'/ethernet', silentMode=silentMode) - match = re.match('/api/v[0-9]+/sessions/[0-9]+/ixnetwork(.*)', deviceGroup) - queryData = {'from': match.group(1), - 'nodes': [{'node': 'ethernet', 'properties': [], 'where': []}] - } - queryResponse = self.ixnObj.query(data=queryData) - ethernetIds = queryResponse.json()['result'][0]['ethernet'] - ethernetList = [ethernet['href'] for ethernet in ethernetIds] - - for ethernet in ethernetList: - # Verify Layer2 first - for protocol in l2ProtocolList: - response = self.ixnObj.get(self.ixnObj.httpHeader+ethernet+'/'+protocol, silentMode=True, ignoreError=True) - if response.json() == [] or 'errors' in response.json(): - continue - currentProtocolList = ['%s/%s/%s' % (ethernet, protocol, str(i["id"])) for i in response.json()] - for currentProtocol in currentProtocolList: - if 'isis' in currentProtocol: - response = self.ixnObj.get(self.ixnObj.httpHeader+deviceGroup+'/isisL3Router', silentMode=silentMode) - self.verifyAllProtocolSessionsInternal(currentProtocol) - - response = self.ixnObj.get(self.ixnObj.httpHeader+ethernet+'/ipv4', silentMode=silentMode) - ipv4List = ['%s/%s/%s' % (ethernet, 'ipv4', str(i["id"])) for i in response.json()] - response = self.ixnObj.get(self.ixnObj.httpHeader+ethernet+'/ipv6', silentMode=silentMode) - ipv6List = ['%s/%s/%s' % (ethernet, 'ipv6', str(i["id"])) for i in response.json()] - for layer3Ip in ipv4List+ipv6List: - for protocol in l3ProtocolList: - response = self.ixnObj.get(self.ixnObj.httpHeader+layer3Ip+'/'+protocol, silentMode=True, ignoreError=True) - if response.json() == [] or 'errors' in response.json(): - continue - currentProtocolList = ['%s/%s/%s' % (layer3Ip, protocol, str(i["id"])) for i in response.json()] - for currentProtocol in currentProtocolList: - self.verifyAllProtocolSessionsInternal(currentProtocol, silentMode=silentMode) + for protocol in l3ProtocolList: + self.verifyAllProtocolSessionsInternal(protocol) def getIpObjectsByTopologyObject(self, topologyObj, ipType='ipv4'): """ @@ -2473,14 +1957,7 @@ def getIpObjectsByTopologyObject(self, topologyObj, ipType='ipv4'): ipType = ipv4 or ipv6 """ ipObjList = [] - deviceGroupResponse = self.ixnObj.get(topologyObj+'/deviceGroup') - deviceGroupList = ['%s/%s/%s' % (topologyObj, 'deviceGroup', str(i["id"])) for i in deviceGroupResponse.json()] - for deviceGroup in deviceGroupList: - response = self.ixnObj.get(deviceGroup+'/ethernet') - ethernetList = ['%s/%s/%s' % (deviceGroup, 'ethernet', str(i["id"])) for i in response.json()] - for ethernet in ethernetList: - response = self.ixnObj.get(ethernet+'/{0}'.format(ipType)) - ipObjList = ['%s/%s/%s' % (ethernet, 'ipv4', str(i["id"])) for i in response.json()] + ipObjList = topologyObj.DeviceGroup.find().Ethernet.find().Ipv4.find() return ipObjList def getAllTopologyList(self): @@ -2491,15 +1968,13 @@ def getAllTopologyList(self): Return If no Topology exists: Returns [] """ - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/topology') - topologyList = ['%s/%s/%s' % (self.ixnObj.sessionUrl, 'topology', str(i["id"])) for i in response.json()] + topologyList = self.ixNetwork.Topology.find() return topologyList def clearAllTopologyVports(self): - response = self.ixnObj.get(self.ixnObj.sessionUrl + "/topology") - topologyList = ["%s%s" % (self.ixnObj.httpHeader, str(i["links"][0]["href"])) for i in response.json()] + topologyList = self.ixNetwork.Topology.find() for topology in topologyList: - self.ixnObj.patch(topology, data={"vports": []}) + topology.ClearPortsAndTrafficStats() def modifyTopologyPortsNgpf(self, topologyObj, portList, topologyName=None): """ @@ -2508,31 +1983,27 @@ def modifyTopologyPortsNgpf(self, topologyObj, portList, topologyName=None): Parameters topologyObj: : The Topology Group object. - portList: : A list of all the ports that you want for the Topology even if the port exists in - the Topology. + portList: : A list of all the ports that you want for the Topology even if the + port exists in the Topology. topologyName: : The Topology Group name to modify. - + Requirements: - 1> You must have already connected all the required ports for your configuration. Otherwise, - adding additional port(s) that doesn't exists in your configuration's assigned port list - will not work. + 1> You must have already connected all the required ports for your configuration. + Otherwise, adding additional port(s) that doesn't exists in your configuration's + assigned port list will not work. 2> This API requires getVports() - Examples - topologyObj = '/api/v1/sessions/1/ixnetwork/topology/1' portList format = [(str(chassisIp), str(slotNumber), str(portNumber))] Example 1: [ ['192.168.70.10', '1', '1'] ] Example 2: [ ['192.168.70.10', '1', '1'], ['192.168.70.10', '2', '1'] ] """ - vportList = self.portMgmtObj.getVports(portList) - if len(vportList) != len(portList): - raise IxNetRestApiException('modifyTopologyPortsNgpf: There is not enough vports created to match the number of ports.') - self.ixnObj.logInfo('vportList: %s' % vportList) - topologyData = {'vports': vportList} - response = self.ixnObj.patch(self.ixnObj.httpHeader+topologyObj, data=topologyData) + if topologyName is not None and topologyObj is None: + topologyObj = self.ixNetwork.Topology.find(Name=topologyName) + else: + topologyObj.update(Ports=portList) def getTopologyPorts(self, topologyObj): """ @@ -2540,26 +2011,11 @@ def getTopologyPorts(self, topologyObj): Get all the configured ports in the Topology. Parameter - topologyObj: : /api/v1/sessions/1/ixnetwork/topology/1 - + topologyObj: Returns A list of ports: [('192.168.70.10', '1', '1') ('192.168.70.10', '1', '2')] """ - topologyResponse = self.ixnObj.get(self.ixnObj.httpHeader+topologyObj) - vportList = topologyResponse.json()['vports'] - if vportList == []: - self.ixnObj.logError('No vport is created') - return 1 - self.ixnObj.logInfo('vportList: %s' % vportList) - portList = [] - for vport in vportList: - response = self.ixnObj.get(self.ixnObj.httpHeader+vport) - # 192.168.70.10:1:1 - currentPort = response.json()['assignedTo'] - chassisIp = currentPort.split(':')[0] - card = currentPort.split(':')[1] - port = currentPort.split(':')[2] - portList.append((chassisIp, card, port)) + portList = topologyObj.ports return portList def sendArpNgpf(self, ipv4ObjList): @@ -2567,16 +2023,14 @@ def sendArpNgpf(self, ipv4ObjList): Description Send ARP out of all the IPv4 objects that you provide in a list. - ipv4ObjList: : Provide a list of one or more IPv4 object handles to send arp. - Ex: ["/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1"] + ipv4ObjList: : Provide a list of one or more IPv4 object handles to send arp. """ if type(ipv4ObjList) != list: - raise IxNetRestApiException('sendArpNgpf error: The parameter ipv4ObjList must be a list of objects.') + raise IxNetRestApiException( + 'sendArpNgpf error: The parameter ipv4ObjList must be a list of objects.') - url = self.ixnObj.sessionUrl+'/topology/deviceGroup/ethernet/ipv4/operations/sendarp' - data = {'arg1': ipv4ObjList} - response = self.ixnObj.post(url, data=data) - self.ixnObj.waitForComplete(response, url+'/'+response.json()['id']) + for ipv4Obj in ipv4ObjList: + ipv4Obj.SendArp() def sendPing(self, srcIpList=None, destIp=None): """ @@ -2585,8 +2039,8 @@ def sendPing(self, srcIpList=None, destIp=None): object that has the srcIp address. Parameters - srcIpList: : The srcIp addresses in a list. Could be 1 or more src IP addresses, but must - be in a list. This API will look up the IPv4 object that has the srcIp. + srcIpList: : The srcIp addresses in a list. Could be 1 or more src IP addresses, + but must be in a list. This API will look up the IPv4 object that has the srcIp. destIp: : The destination IP to ping. Returns @@ -2594,46 +2048,17 @@ def sendPing(self, srcIpList=None, destIp=None): Failed: Ping: 1.1.1.1 -> 1.1.1.10 failed - timeout 0: Returns 0 if no src IP address found in the srcIpList. """ - queryData = {'from': '/', - 'nodes': [{'node': 'topology', 'properties': ['name'], 'where': []}, - {'node': 'deviceGroup', 'properties': [], 'where': []}, - {'node': 'ethernet', 'properties': [], 'where': []}, - {'node': 'ipv4', 'properties': ['address', 'count'], 'where': []}] - } - url = self.ixnObj.sessionUrl+'/topology/deviceGroup/ethernet/ipv4/operations/sendping' - queryResponse = self.ixnObj.query(data=queryData) - srcIpIndexList = [] - noSrcIpIndexFound = [] - for topology in queryResponse.json()['result'][0]['topology']: - for ipv4 in topology['deviceGroup'][0]['ethernet'][0]['ipv4']: - ipv4Obj = ipv4['href'] - ipv4Count = ipv4['count'] - ipv4AddressMultivalue = ipv4['address'] - ipv4AddressList = self.ixnObj.getMultivalueValues(ipv4AddressMultivalue) - url = self.ixnObj.httpHeader+ipv4Obj+'/operations/sendping' - for eachSrcIp in srcIpList: - # Don't error out if eachSrcIp is not found in the ipv4AddressList because - # it may not be in the current for loop topology. - try: - srcIpIndex = ipv4AddressList.index(eachSrcIp) - srcIpIndexList.append(srcIpIndex+1) - except: - noSrcIpIndexFound.append(eachSrcIp) - pass - if srcIpIndexList != []: - data = {'arg1': ipv4Obj, 'arg2': destIp, 'arg3': srcIpIndexList} - response = self.ixnObj.post(url, data=data) - self.ixnObj.waitForComplete(response, url+response.json()['id']) - self.ixnObj.logInfo(response.json()['result'][0]['arg3']) - if noSrcIpIndexFound != []: - self.ixnObj.logError('No srcIp address found in configuration: {0}'.format(noSrcIpIndexFound)) - return response.json()['result'][0]['arg3'] - - # Reset these variable to empty list. - srcIpIndexList = [] - noSrcIpIndexFound = [] - if srcIpIndexList == []: - raise IxNetRestApiException('No srcIp addresses found in configuration: {0}'.format(srcIpList)) + ipv4ObjSessionList = self.ixNetwork.Topology.find.DeviceGroup.find().Ethernet.find() \ + .Ipv4.find() + ipv4ObjList = [ipv4Obj for ipv4Obj in ipv4ObjSessionList if + ipv4Obj.Address.Values in srcIpList] + + if ipv4ObjList == []: + raise IxNetRestApiException('No srcIp addresses found in configuration: {0}'.format( + srcIpList)) + + for ipv4Obj in ipv4ObjList: + ipv4Obj.SendPing(destIp) def verifyNgpfProtocolStarted(self, protocolObj, ignoreFailure=False, timeout=30): """ @@ -2641,11 +2066,10 @@ def verifyNgpfProtocolStarted(self, protocolObj, ignoreFailure=False, timeout=30 Verify if NGPF protocol started. Parameter - protocolObj: : /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1 + protocolObj: timeout: : The timeout value. Default=30 seconds. """ - for counter in range(1,timeout+1): - # sessionStatus is a list of status for each 'session' (host) + for counter in range(1, timeout + 1): sessionStatus = self.getSessionStatus(protocolObj) self.ixnObj.logInfo('\nVerifyNgpfProtocolStarted: %s' % protocolObj, timestamp=False) @@ -2654,7 +2078,8 @@ def verifyNgpfProtocolStarted(self, protocolObj, ignoreFailure=False, timeout=30 for session in sessionStatus: if session in ['notStarted', 'down']: count += 1 - self.ixnObj.logInfo('\t{0} out of {1} sessions are still down'.format(count, len(sessionStatus)), timestamp=False) + self.ixnObj.logInfo('\t{0} out of {1} sessions are still down'. + format(count, len(sessionStatus)), timestamp=False) self.ixnObj.logInfo('\tWait %d/%d seconds' % (counter, timeout), timestamp=False) time.sleep(1) @@ -2663,11 +2088,12 @@ def verifyNgpfProtocolStarted(self, protocolObj, ignoreFailure=False, timeout=30 for session in sessionStatus: if session in ['notStarted', 'down']: count += 1 - + if count != 0: - errMsg = '{0} out of {1} sessions failed to start'.format(count, len(sessionStatus)) + errMsg = '{0} out of {1} sessions failed to start'.format(count, + len(sessionStatus)) self.ixnObj.logError(errMsg) - if ignoreFailure == False: + if not ignoreFailure: raise IxNetRestApiException(errMsg) else: return 1 @@ -2678,10 +2104,12 @@ def verifyNgpfProtocolStarted(self, protocolObj, ignoreFailure=False, timeout=30 if session in ['notStarted', 'down']: flag = 1 if flag == 0: - self.ixnObj.logInfo('\tTotal of {0} sessions started'.format(len(sessionStatus)), timestamp=False) + self.ixnObj.logInfo('\tTotal of {0} sessions started'. + format(len(sessionStatus)), timestamp=False) return 0 - def deviceGroupProtocolStackNgpf(self, deviceGroupObj, ipType, arpTimeout=3, silentMode=True): + def deviceGroupProtocolStackNgpf(self, deviceGroupObj, ipType, + arpTimeout=3, silentMode=True): """ Description This API is an internal API for VerifyArpNgpf. @@ -2690,78 +2118,68 @@ def deviceGroupProtocolStackNgpf(self, deviceGroupObj, ipType, arpTimeout=3, sil Therefore, you can loop device groups. Parameters - deviceGroupObj: : /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1 + deviceGroupObj: ipType: : ipv4|ipv6 arpTimeout: : Timeout value. Default=60 seconds. - silentMode: : True to show less display on the terminal. False for debugging purposes. + silentMode: : True to show less display on the terminal. + False for debugging purposes. Requires self.verifyNgpfProtocolStarted() """ unresolvedArpList = [] - response = self.ixnObj.get(self.ixnObj.httpHeader+deviceGroupObj+'/ethernet', silentMode=silentMode) - ethernetObjList = ['%s/%s/%s' % (deviceGroupObj, 'ethernet', str(i["id"])) for i in response.json()] - for ethernetObj in ethernetObjList: - response = self.ixnObj.get(self.ixnObj.httpHeader+ethernetObj+'/'+ipType, ignoreError=True, silentMode=silentMode) - if response.status_code != 200: - raise IxNetRestApiException(response.text) - - ipProtocolList = ['%s/%s/%s' % (ethernetObj, ipType, str(i["id"])) for i in response.json()] - if ipProtocolList == []: - self.ixnObj.logWarning('{0} is not configured in {1}'.format(ipType, ethernetObj)) - return unresolvedArpList - # raise IxNetRestApiException('Layer3 is not configured in {0}'.format(ethernetObj)) - - for ipProtocol in ipProtocolList: - # match.group(1): /topology/1/deviceGroup/1/deviceGroup/1/ethernet/1/ipv4/1 - match = re.match('.*(/topology.*)', ipProtocol) - # sessionStatus could be: down, up, notStarted - - # result == 0 means passed. 1 means failed. - result = self.verifyNgpfProtocolStarted(ipProtocol, ignoreFailure=True) - - for counter in range(1,arpTimeout+1): - sessionStatus = self.getSessionStatus(ipProtocol) - if counter < arpTimeout and 'down' in sessionStatus: - self.ixnObj.logInfo('\tARP is not resolved yet. Wait {0}/{1}'.format(counter, arpTimeout), timestamp=False) - time.sleep(1) - continue - if counter < arpTimeout and 'down' not in sessionStatus: - break - if counter == arpTimeout and 'down' in sessionStatus: - #raise IxNetRestApiException('\nARP is not getting resolved') - # Let it flow down to get the unresolved ARPs - pass + deviceGroupObjList = [deviceGroupObj] + if deviceGroupObj.DeviceGroup.find(): + deviceGroupObjList.append(deviceGroupObj.DeviceGroup.find()) + for eachDeviceGroup in deviceGroupObjList: + ethernetObjList = eachDeviceGroup.Ethernet.find() + for ethernetObj in ethernetObjList: + ipType = ipType[0].capitalize() + ipType[1:] + ipTypeObj = getattr(ethernetObj, ipType) + ipProtocolList = ipTypeObj.find() + if not ipProtocolList: + self.ixnObj.logWarning('{0} is not configured in {1}'.format(ipType, + ethernetObj)) + raise IxNetRestApiException('Layer3 is not configured in {0}'. + format(ethernetObj)) + + for ipProtocol in ipProtocolList: + self.verifyNgpfProtocolStarted(ipProtocol, ignoreFailure=True) + + for counter in range(1, arpTimeout + 1): + sessionStatus = self.getSessionStatus(ipProtocol) + if counter < arpTimeout and 'down' in sessionStatus: + self.ixnObj.logInfo('\tARP is not resolved yet. Wait {0}/{1}'.format( + counter, arpTimeout), timestamp=False) + time.sleep(1) + continue + if counter < arpTimeout and 'down' not in sessionStatus: + break + if counter == arpTimeout and 'down' in sessionStatus: + pass - protocolResponse = self.ixnObj.get(self.ixnObj.httpHeader+ipProtocol+'?includes=resolvedGatewayMac,address,gatewayIp', ignoreError=True, silentMode=silentMode) - - resolvedGatewayMac = protocolResponse.json()['resolvedGatewayMac'] - - # sessionStatus: ['up', 'up'] - # resolvedGatewayMac ['00:0c:29:8d:d8:35', '00:0c:29:8d:d8:35'] - - # Only care for unresolved ARPs. - # resolvedGatewayMac: 00:01:01:01:00:01 00:01:01:01:00:02 removePacket[Unresolved] - # Search each mac to see if they're resolved or not. - for index in range(0, len(resolvedGatewayMac)): - if (bool(re.search('.*Unresolved.*', resolvedGatewayMac[index]))): - multivalue = protocolResponse.json()['address'] - multivalueResponse = self.ixnObj.getMultivalueValues(multivalue, silentMode=silentMode) - # Get the IP Address of the unresolved mac address - srcIpAddrNotResolved = multivalueResponse[index] - gatewayMultivalue = protocolResponse.json()['gatewayIp'] - response = self.ixnObj.getMultivalueValues(gatewayMultivalue, silentMode=silentMode) - gatewayIp = response[index] - self.ixnObj.logError('Failed to resolve ARP: srcIp:{0} gateway:{1}'.format(srcIpAddrNotResolved, gatewayIp)) - unresolvedArpList.append((srcIpAddrNotResolved, gatewayIp)) - - if unresolvedArpList == []: - self.ixnObj.logInfo('ARP is resolved') - return 0 - else: - return unresolvedArpList + resolvedGatewayMac = ipProtocol.ResolvedGatewayMac + for index in range(0, len(resolvedGatewayMac)): + if bool(re.search('.*Unresolved.*', resolvedGatewayMac[index])): + multivalue = ipProtocol.Address + multivalueResponse = self.ixnObj.getMultivalueValues( + multivalue, silentMode=silentMode) + srcIpAddrNotResolved = multivalueResponse[index] + gatewayMultivalue = ipProtocol.GatewayIp + response = self.ixnObj.getMultivalueValues( + gatewayMultivalue, silentMode=silentMode) + gatewayIp = response[index] + self.ixnObj.logError('Failed to resolve ARP: srcIp:{0} gateway:{1}'. + format(srcIpAddrNotResolved, gatewayIp)) + unresolvedArpList.append((srcIpAddrNotResolved, gatewayIp)) + + if not unresolvedArpList: + self.ixnObj.logInfo('ARP is resolved') + return 0 + else: + return unresolvedArpList - def verifyArp(self, ipType='ipv4', deviceGroupName=None , silentMode=True): + def verifyArp(self, ipType='ipv4', deviceGroupName=None, silentMode=True): """ Description Verify for ARP resolvement on every enabled Device Group including inner Device Groups. @@ -2776,45 +2194,38 @@ def verifyArp(self, ipType='ipv4', deviceGroupName=None , silentMode=True): If not, then arp is not resolved. Requires - self.deviceGroupProtocolStacksNgpf() + self.deviceGroupProtocolStacksNgpf() self.verifyNgpfProtocolStarted() Parameter ipType: : ipv4 or ipv6 deviceGroupName: : Name of the device group to send arp request - silentMode: : True to show less display on the terminal. False for debugging purposes. + silentMode: : True to show less display on the terminal. False for debugging + purposes. """ self.ixnObj.logInfo('Verify ARP: %s' % ipType) unresolvedArpList = [] startFlag = 0 - queryData = {'from': '/', - 'nodes': [{'node': 'topology', 'properties': [], 'where': []}, - {'node': 'deviceGroup', 'properties': [], 'where': []} - ]} - queryResponse = self.ixnObj.query(data=queryData, silentMode=False) - for topology in queryResponse.json()['result'][0]['topology']: - for deviceGroup in topology['deviceGroup']: - deviceGroupObj = deviceGroup['href'] - - response = self.ixnObj.get(self.ixnObj.httpHeader+deviceGroupObj, silentMode=silentMode) - deviceName = response.json()['name'] + deviceGroupStatus = None + for topology in self.ixNetwork.Topology.find(): + for deviceGroup in topology.DeviceGroup.find(): + deviceName = deviceGroup.Name if deviceGroupName: if deviceName == deviceGroupName: pass else: continue - # Verify if the Device Group is enabled. If not, don't go further. - enabledMultivalue = response.json()['enabled'] + enabledMultivalue = deviceGroup.Enabled response = self.getMultivalueValues(enabledMultivalue, silentMode=silentMode) if response[0] == 'false': continue timeout = 30 - for counter in range(1,timeout+1): - response = self.ixnObj.get(self.ixnObj.httpHeader+deviceGroupObj, silentMode=silentMode) - deviceGroupStatus = response.json()['status'] + for counter in range(1, timeout + 1): + deviceGroupStatus = deviceGroup.Status if deviceGroupStatus == 'notStarted': - raise IxNetRestApiException('\nDevice Group is not started: {0}.'.format(deviceGroupObj)) + raise IxNetRestApiException('\nDevice Group is not started: {0}.'.format( + deviceGroup)) if counter < timeout and deviceGroupStatus == 'starting': self.ixnObj.logInfo('\tWait %d/%d' % (counter, timeout), timestamp=False) @@ -2823,33 +2234,35 @@ def verifyArp(self, ipType='ipv4', deviceGroupName=None , silentMode=True): if counter < timeout and deviceGroupStatus in ['started', 'mixed']: break if counter == timeout and deviceGroupStatus not in ['started', 'mixed']: - raise IxNetRestApiException('\nDevice Group failed to come up: {0}.'.format(deviceGroupObj)) + raise IxNetRestApiException('\nDevice Group failed to come up: {0}.'. + format(deviceGroup)) if deviceGroupStatus in ['started', 'mixed']: startFlag = 1 - arpResult = self.deviceGroupProtocolStackNgpf(deviceGroupObj, ipType, silentMode=silentMode) + arpResult = self.deviceGroupProtocolStackNgpf(deviceGroup, ipType, + silentMode=silentMode) if arpResult != 0: unresolvedArpList = unresolvedArpList + arpResult - - response = self.ixnObj.get(self.ixnObj.httpHeader+deviceGroupObj+'/deviceGroup', silentMode=silentMode) - if response.status_code == 200 and response.json() != []: - innerDeviceGroupObj = response.json()[0]['links'][0]['href'] - self.ixnObj.logInfo('%s' % self.ixnObj.httpHeader+innerDeviceGroupObj, timestamp=False) - response = self.ixnObj.get(self.ixnObj.httpHeader+innerDeviceGroupObj, silentMode=silentMode) - deviceGroupStatus1 = response.json()['status'] - self.ixnObj.logInfo('\tdeviceGroup Status: %s' % deviceGroupStatus1, timestamp=False) - - if deviceGroupStatus == 'started': - arpResult = self.deviceGroupProtocolStackNgpf(innerDeviceGroupObj, ipType, silentMode=silentMode) + innerDeviceGroup = deviceGroup.DeviceGroup.find() + if innerDeviceGroup: + innerDeviceGroupObj = innerDeviceGroup + self.ixnObj.logInfo('%s' % innerDeviceGroupObj, timestamp=False) + deviceGroupStatus1 = innerDeviceGroupObj.Status + self.ixnObj.logInfo('\tdeviceGroup Status: %s' % deviceGroupStatus1, + timestamp=False) + + if deviceGroupStatus1 == 'started': + arpResult = self.deviceGroupProtocolStackNgpf(innerDeviceGroupObj, + ipType, + silentMode=silentMode) if arpResult != 0: unresolvedArpList = unresolvedArpList + arpResult if unresolvedArpList == [] and startFlag == 0: - # Device group status is not started. - raise IxNetRestApiException("\nError: Device Group is not started. It must've went down. Can't verify arp.") + raise IxNetRestApiException("\nError: Device Group is not started. It must've went " + "down. Can't verify arp.") if unresolvedArpList != [] and startFlag == 1: - # Device group status is started and there are arp unresolved. print() raise IxNetRestApiException('\nError: Unresolved ARP: {0}'.format(unresolvedArpList)) @@ -2867,45 +2280,13 @@ def getNgpfGatewayIpMacAddress(self, gatewayIp): - removePacket[Unresolved] - The Gateway IP's Mac Address. """ - queryData = {'from': '/', - 'nodes': [{'node': 'topology', 'properties': [], 'where': []}, - {'node': 'deviceGroup', 'properties': [], 'where': []}, - {'node': 'ethernet', 'properties': [], 'where': []}, - {'node': 'ipv4', 'properties': ['gatewayIp'], 'where': []} - ]} - queryResponse = self.ixnObj.query(data=queryData, silentMode=False) - for topology in queryResponse.json()['result'][0]['topology']: - for deviceGroup in topology['deviceGroup']: - try: - # Getting in here means IPv4 session status is UP. - ipv4Href = deviceGroup['ethernet'][0]['ipv4'][0]['href'] - ipv4SessionStatus = self.getSessionStatus(ipv4Href) - gatewayIpMultivalue = deviceGroup['ethernet'][0]['ipv4'][0]['gatewayIp'] - self.ixnObj.logInfo('\t%s' % ipv4Href) - self.ixnObj.logInfo('\tIPv4 sessionStatus: %s' % ipv4SessionStatus) - self.ixnObj.logInfo('\tGatewayIpMultivalue: %s' % gatewayIpMultivalue) - response = self.ixnObj.getMultivalueValues(gatewayIpMultivalue) - valueList = response - - self.ixnObj.logInfo('gateway IP: %s' % valueList) - if gatewayIp in valueList: - gatewayIpIndex = valueList.index(gatewayIp) - self.ixnObj.logInfo('Found gateway: %s ; Index:%s' % (gatewayIp, gatewayIpIndex)) - - queryData = {'from': deviceGroup['ethernet'][0]['href'], - 'nodes': [{'node': 'ipv4', 'properties': ['gatewayIp', 'resolvedGatewayMac'], 'where': []} - ]} - queryResponse = self.ixnObj.query(data=queryData, silentMode=False) - response = self.ixnObj.get(self.ixnObj.httpHeader+ipv4Href+'?includes=resolvedGatewayMac') - gatewayMacAddress = response.json()['resolvedGatewayMac'] - self.ixnObj.logInfo('gatewayIpMacAddress: %s' % gatewayMacAddress) - if 'Unresolved' in gatewayMacAddress: - raise IxNetRestApiException('Gateway Mac Address is unresolved.') - return gatewayMacAddress[0] - - except: - pass - return 0 + ipv4Obj = None + ipv4Obj = self.ixNetwork.Topology.find().DeviceGroup.find().Ipv4.find( + gatewayip=gatewayIp) + if ipv4Obj is not None: + return ipv4Obj.ResolvedGatewayMac + else: + return None def getDeviceGroupSrcIpGatewayIp(self, srcIpAddress): """ @@ -2920,30 +2301,14 @@ def getDeviceGroupSrcIpGatewayIp(self, srcIpAddress): 0: Failed. No srcIpAddress found in any Device Group. Gateway IP address """ - queryData = {'from': '/', - 'nodes': [{'node': 'topology', 'properties': [], 'where': []}, - {'node': 'deviceGroup', 'properties': [], 'where': []}, - {'node': 'ethernet', 'properties': [], 'where': []}, - {'node': 'ipv4', 'properties': ['address', 'gatewayIp'], 'where': []}, - ]} - - queryResponse = self.ixnObj.query(data=queryData, silentMode=False) - for topology in queryResponse.json()['result'][0]['topology']: - for deviceGroup in topology['deviceGroup']: - try: - srcIpMultivalue = deviceGroup['ethernet'][0]['ipv4'][0]['address'] - gatewayIpMultivalue = deviceGroup['ethernet'][0]['ipv4'][0]['gatewayIp'] - response = self.ixnObj.getMultivalueValues(srcIpMultivalue) - srcIp = response[0] - if srcIpAddress == srcIp: - self.ixnObj.logInfo('Found srcIpAddress: %s. Getting Gatway IP address ...' % srcIpAddress) - response = self.ixnObj.getMultivalueValues(gatewayIpMultivalue) - gatewayIp = response[0] - self.ixnObj.logInfo('Gateway IP address: %s' % gatewayIp) - return gatewayIp - except: - pass - return 0 + ipv4ObjSessionList = self.ixNetwork.Topology.find.DeviceGroup.find().Ethernet.find() \ + .Ipv4.find() + ipv4Obj = [ipv4Obj for ipv4Obj in ipv4ObjSessionList if + ipv4Obj.Address.Values == srcIpAddress] + if ipv4Obj is not None: + return ipv4Obj.gatewayip + else: + return None def getDeviceGroupObjAndIpObjBySrcIp(self, srcIpAddress): """ @@ -2952,7 +2317,7 @@ def getDeviceGroupObjAndIpObjBySrcIp(self, srcIpAddress): If found, return the Device Group object and the IPv4|Ipv6 objects. if srcIpAddress is IPv6, the format must match what is shown - in the GUI or API server. Please verify how the configured + in the GUI or API server. Please verify how the configured IPv6 format looks like on either the IxNetwork API server when you are testing your script during development. @@ -2963,46 +2328,35 @@ def getDeviceGroupObjAndIpObjBySrcIp(self, srcIpAddress): None: If no srcIpAddress is found. deviceGroup Object and IPv4|IPv6 object """ - queryData = {'from': '/', - 'nodes': [{'node': 'topology', 'properties': [], 'where': []}, - {'node': 'deviceGroup', 'properties': [], 'where': []}, - {'node': 'ethernet', 'properties': [], 'where': []}, - {'node': 'ipv4', 'properties': ['address'], 'where': []}, - {'node': 'ipv6', 'properties': ['address'], 'where': []} - ]} - - queryResponse = self.ixnObj.query(data=queryData, silentMode=False) - for topology in queryResponse.json()['result'][0]['topology']: - for deviceGroup in topology['deviceGroup']: - for ethernet in deviceGroup['ethernet']: - try: - if bool(re.match(r'[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+', srcIpAddress)): - srcIpMultivalue = ethernet['ipv4'][0]['address'] - ipObj = ethernet['ipv4'][0]['href'] - else: - # IPv6 format: ['2000:0:0:1:0:0:0:2', '2000:0:0:2:0:0:0:2', '2000:0:0:3:0:0:0:2', '2000:0:0:4:0:0:0:2'] - srcIpMultivalue = ethernet['ipv6'][0]['address'] - ipObj = ethernet['ipv6'][0]['href'] - - response = self.ixnObj.getMultivalueValues(srcIpMultivalue) - if srcIpAddress in response: - self.ixnObj.logInfo('Found srcIpAddress: %s' % srcIpAddress) - return deviceGroup['href'],ipObj - except: - pass - + ipv4ObjSessionList = self.ixNetwork.Topology.find.DeviceGroup.find().Ethernet.find() \ + .Ipv4.find() + ipv4Obj = [ipv4Obj for ipv4Obj in ipv4ObjSessionList if + ipv4Obj.Address.Values == srcIpAddress] + if ipv4Obj is not None: + return [ipv4Obj.parent.parent, ipv4Obj] + else: + return None + def getInnerDeviceGroup(self, deviceGroupObj): - response = self.ixnObj.get(self.ixnObj.httpHeader + deviceGroupObj + '/deviceGroup') - if response.json(): - for innerDeviceGroup in response.json()[0]['links']: - innerDeviceGroupObj = innerDeviceGroup['href'] - deviceGroupList.append(innerDeviceGroupObj) + deviceGroupList = [] + if deviceGroupObj is not None: + while True: + try: + innerDevGroupObj = deviceGroupObj.DeviceGroup.find() + if innerDevGroupObj != " ": + print("added innerdeviceGroup Obj to list value is", innerDevGroupObj) + deviceGroupList.append(innerDevGroupObj) + deviceGroupObj = innerDevGroupObj + except Exception as e: + print(e) + break + return deviceGroupList def getTopologyObjAndDeviceGroupObjByPortName(self, portName): """ Description Search each Topology Group vport for the portName. - If found, return the topology object and a list of + If found, return the topology object and a list of all its device groups and inner device group within a device group. Parameter @@ -3012,32 +2366,17 @@ def getTopologyObjAndDeviceGroupObjByPortName(self, portName): None: If no portName found in any Topology Group. Topology object + Device Group list - Ex 1: ['/api/v1/sessions/1/ixnetwork/topology/2', ['/api/v1/sessions/1/ixnetwork/topology/2/deviceGroup/1']] - Ex 2: ('/api/v1/sessions/1/ixnetwork/topology/1', ['/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1', - '/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/deviceGroup/3']) """ - response = self.ixnObj.get(self.ixnObj.sessionUrl + '/topology') - for eachTopology in response.json(): - topologyObj = eachTopology['links'][0]['href'] - vportList = eachTopology['vports'] - response = self.ixnObj.get(self.ixnObj.httpHeader + topologyObj + '/deviceGroup') + devGrphrefList = [] + for topology in self.ixNetwork.Topology.find(): + if self.ixNetwork.Vport.find(Name=portName).href in topology.Vports: + devGrpList = topology.DeviceGroup.find() + break - deviceGroupList = [] - for eachDeviceGroup in response.json(): - deviceGroupObj = eachDeviceGroup['links'][0]['href'] - deviceGroupList.append(deviceGroupObj) + for devGrpObj in devGrpList: + devGrphrefList.append(devGrpObj.href) - # Verify if there are additional device groups within a device group. - response = self.ixnObj.get(self.ixnObj.httpHeader + deviceGroupObj + '/deviceGroup') - if response.json(): - for response in response.json(): - deviceGroupList.append(response['links'][0]['href']) - - for eachVport in vportList: - response = self.ixnObj.get(self.ixnObj.httpHeader+eachVport) - vportName = response.json()['name'] - if portName == vportName: - return topologyObj, deviceGroupList + return (topology.href, devGrphrefList) def getNetworkGroupObjByIp(self, networkGroupIpAddress): """ @@ -3056,29 +2395,20 @@ def getNetworkGroupObjByIp(self, networkGroupIpAddress): None: No ipAddress found in any NetworkGroup. network group Object: The Network Group object. """ - queryData = {'from': '/', - 'nodes': [{'node': 'topology', 'properties': [], 'where': []}, - {'node': 'deviceGroup', 'properties': [], 'where': []}, - {'node': 'networkGroup', 'properties': [], 'where': []}, - {'node': 'ipv4PrefixPools', 'properties': ['networkAddress'], 'where': []}, - {'node': 'ipv6PrefixPools', 'properties': ['networkAddress'], 'where': []} - ]} - - queryResponse = self.ixnObj.query(data=queryData, silentMode=False) - + grpObjList = None if '.' in networkGroupIpAddress: - prefixPoolType = 'ipv4PrefixPools' + grpObjList = self.ixNetwork.Topology.find().DeviceGroup.find().NetworkGroup.find() \ + .Ipv4PrefixPools.find() if ':' in networkGroupIpAddress: - prefixPoolType = 'ipv6PrefixPools' - - for topology in queryResponse.json()['result'][0]['topology']: - for deviceGroup in topology['deviceGroup']: - for networkGroup in deviceGroup['networkGroup']: - for prefixPool in networkGroup[prefixPoolType]: - prefixPoolRangeMultivalue = prefixPool['networkAddress'] - response = self.ixnObj.getMultivalueValues(prefixPoolRangeMultivalue) - if networkGroupIpAddress in response: - return networkGroup['href'] + grpObjList = self.ixNetwork.Topology.find().DeviceGroup.find().NetworkGroup.find() \ + .Ipv6PrefixPools.find() + + if grpObjList is not None: + for grpObj in grpObjList: + netAddrList = grpObj.NetworkAddress.Values + if networkGroupIpAddress in netAddrList: + return grpObj.parent + return None def getIpAddrIndexNumber(self, ipAddress): """ @@ -3091,32 +2421,20 @@ def getIpAddrIndexNumber(self, ipAddress): Return None or the IP address index number (based one) """ - topologyList = self.ixnObj.get(self.ixnObj.sessionUrl + '/topology') - for topology in topologyList.json(): - topologyObj = topology['links'][0]['href'] - deviceGroupList = self.ixnObj.get(self.ixnObj.httpHeader + topologyObj + '/deviceGroup') - for deviceGroup in deviceGroupList.json(): - deviceGroupObj = deviceGroup['links'][0]['href'] - ethernetList = self.ixnObj.get(self.ixnObj.httpHeader + deviceGroupObj + '/ethernet') - for ethernet in ethernetList.json(): - ethernetObj = ethernet['links'][0]['href'] - if '.' in ipAddress: - ipList = self.ixnObj.get(self.ixnObj.httpHeader + ethernetObj + '/ipv4') - if ':' in ipAddress: - ipList = self.ixnObj.get(self.ixnObj.httpHeader + ethernetObj + '/ipv6') - - for ip in ipList.json(): - ipObj = ip['links'][0]['href'] - response = self.ixnObj.get(self.ixnObj.httpHeader + ipObj) - ipMultivalue = response.json()['address'] - response = self.ixnObj.get(self.ixnObj.httpHeader + ipMultivalue + '?includes=values') - ipValueList = response.json()['values'] - for index, ip in enumerate(ipValueList): - if ipAddress in ipValueList: - index = ipValueList.index(ipAddress) - print(index, ipAddress) - # Return index number using based one. Not based zero. - return index + 1 + ipObjList = None + if '.' in ipAddress: + ipObjList = self.ixNetwork.Topology.find().DeviceGroup.find().Ethernet.find() \ + .Ipv4.find() + if ':' in ipAddress: + ipObjList = self.ixNetwork.Topology.find().DeviceGroup.find().Ethernet.find() \ + .Ipv6.find() + + if ipObjList is not None: + for ipObj in ipObjList: + ipAddrList = ipObj.Address.Values + if ipAddress in ipAddrList: + return ipAddrList.index(ipAddress) + 1 + return None def getIpv4ObjByPortName(self, portName=None): """ @@ -3126,83 +2444,55 @@ def getIpv4ObjByPortName(self, portName=None): Parameter portName: : Optional: The name of the port. Default=None. """ - # Step 1 of 3: Get the Vport by the portName. - queryData = {'from': '/', - 'nodes': [{'node': 'vport', 'properties': ['name'], 'where': [{'property': 'name', 'regex': portName}]}]} - - queryResponse = self.ixnObj.query(data=queryData, silentMode=False) - if queryResponse.json()['result'][0]['vport'] == []: - raise IxNetRestApiException('\nNo such vport name: %s\n' % portName) - - # /api/v1/sessions/1/ixnetwork/vport/2 - vport = queryResponse.json()['result'][0]['vport'][0]['href'] - self.ixnObj.logInfo(vport) - - # Step 2 of 3: Query the API tree for the IPv4 object - queryData = {'from': '/', - 'nodes': [{'node': 'topology', 'properties': ['vports'], 'where': []}, - {'node': 'deviceGroup', 'properties': [], 'where': []}, - {'node': 'ethernet', 'properties': [], 'where': []}, - {'node': 'ipv4', 'properties': [], 'where': []}, - ]} - - queryResponse = self.ixnObj.query(data=queryData, silentMode=False) - - # Step 3 of 3: Loop through each Topology looking for the vport. - # If found, get its IPv4 object - for topology in queryResponse.json()['result'][0]['topology']: - if vport in topology['vports']: - # Get the IPv4 object: /api/v1/sessions/1/ixnetwork/topology/2/deviceGroup/1/ethernet/1/ipv4/1 - ipv4Obj = topology['deviceGroup'][0]['ethernet'][0]['ipv4'][0]['href'] - return ipv4Obj + topologyObj = None + for topology in self.ixNetwork.Topology.find(): + if self.ixNetwork.Vport.find(Name=portName).href in topology.Ports: + topologyObj = topology + break + else: + raise IxNetRestApiException('\nNo such vport name: %s\n' % portName) + ipv4Obj = topologyObj.DeviceGroup.find().Ethernet.find().Ipv4.find()[0] + if ipv4Obj: + return ipv4Obj + return None - def activateIgmpHostSession(self, portName=None, ipAddress=None, activate=True): + def activateIgmpHostSession(self, portName=None, ipAddress=None, + activate=True): """ Description Active or deactivate the IGMP host session ID by the portName and IPv4 host address. Parameters: - portName: : The name of the port in which this API will search in all the Topology Groups. + portName: : The name of the port in which this API will search in all the Topology + Groups. ipAddress: : Within the Topology Group, the IPv4 address for the IGMP host. activate: : To activate or not to activate. """ - # Get the IPv4 address index. This index position is the same index position for the IGMP host sessionID. - # Will use this variable to change the value of the IGMP host object's active valueList. ipv4AddressIndex = self.getIpAddrIndexNumber(ipAddress) - - # Get the IPv4 object by the port name. This will search through all the Topology Groups for the portName. ipv4Obj = self.getIpv4ObjByPortName(portName=portName) - - # With the ipv4Obj, get the IGMP host object's "active" multivalue so we could modify the active valueList. - queryData = {'from': ipv4Obj, - 'nodes': [{'node': 'igmpHost', 'properties': ['active'], 'where': []}]} - - queryResponse = self.ixnObj.query(data=queryData, silentMode=False) - if queryResponse.json()['result'][0]['igmpHost'] == []: + igmpHostObj = ipv4Obj.IgmpHost.find() + if not igmpHostObj: raise IxNetRestApiException('\nNo IGMP HOST found\n') - igmpHostActiveMultivalue = queryResponse.json()['result'][0]['igmpHost'][0]['active'] - - response = self.ixnObj.get(self.ixnObj.httpHeader+igmpHostActiveMultivalue) - valueList = response.json()['values'] - # Using the ipv4 address index, activate the IGMP session ID which is the same index position. - valueList[ipv4AddressIndex] = activate - self.ixnObj.configMultivalue(igmpHostActiveMultivalue, multivalueType='valueList', data={'values': valueList}) + igmpHostActiveMultivalue = igmpHostObj.Active + valueList = self.getMultivalueValues(igmpHostActiveMultivalue) + valueList[ipv4AddressIndex - 1] = activate + self.ixnObj.configMultivalue(igmpHostActiveMultivalue, multivalueType='valueList', + data={'values': valueList}) def enableDeviceGroup(self, deviceGroupObj=None, enable=True): """ Description - Enable or disable a Device Group by the object handle. A Device Group could contain many interfaces. - This API will enable or disable all the interfaces. + Enable or disable a Device Group by the object handle. A Device Group could contain + many interfaces. This API will enable or disable all the interfaces. Parameters - deviceGroupObj: The Device Group object handle: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1 - + deviceGroupObj: The Device Group object handle enable: True|False """ - response = self.ixnObj.get(self.ixnObj.httpHeader + deviceGroupObj) - enabledMultivalue = response.json()['enabled'] - self.ixnObj.configMultivalue(enabledMultivalue, multivalueType='singleValue', data={'value': enable}) + enabledMultivalue = deviceGroupObj.Enabled + self.ixnObj.configMultivalue(enabledMultivalue, multivalueType='singleValue', + data={'value': enable}) def getRouteRangeAddressProtocolAndPort(self, routeRangeAddress): """ @@ -3215,36 +2505,25 @@ def getRouteRangeAddressProtocolAndPort(self, routeRangeAddress): Returns [portList, protocolList] -> (['192.168.70.11:2:1'], ['ospf', 'isisL3']) """ - queryData = {'from': '/', - 'nodes': [{'node': 'topology', 'properties': ['vports'], 'where': []}, - {'node': 'deviceGroup', 'properties': [], 'where': []}, - {'node': 'networkGroup', 'properties': [], 'where': []}, - {'node': 'ipv4PrefixPools', 'properties': ['networkAddress'], 'where': []}, - {'node': 'bgpIPRouteProperty', 'properties': [], 'where': []}, - {'node': 'ospfRouteProperty', 'properties': [], 'where': []}, - {'node': 'isisL3RouteProperty', 'properties': ['active'], 'where': []}, - {'node': 'ldpFECProperty', 'properties': ['active'], 'where': []} - ]} - queryResponse = self.ixnObj.query(data=queryData, silentMode=False) - discoveryFlag = 0 protocolList = [] portList = [] - for topology in queryResponse.json()['result'][0]['topology']: - portList = self.ixnObj.getPhysicalPortFromVport(topology['vports']) - for networkGroup in topology['deviceGroup'][0]['networkGroup']: - for ipv4PrefixPool in networkGroup['ipv4PrefixPools']: - networkAddressList = self.ixnObj.getMultivalueValues(ipv4PrefixPool['networkAddress']) + for topology in self.ixNetwork.Topology.find(): + portList = self.ixnObj.getPhysicalPortFromVport(topology.Vports) + for networkGroup in topology.DeviceGroup.find().NetworkGroup.find(): + for ipv4PrefixPool in networkGroup.Ipv4PrefixPools.find(): + networkAddressList = self.ixnObj.getMultivalueValues( + ipv4PrefixPool.NetworkAddress) if routeRangeAddress in networkAddressList: - if ipv4PrefixPool['bgpIPRouteProperty'] != []: + if ipv4PrefixPool.BgpIPRouteProperty.find(): protocolList.append('bgp') - if ipv4PrefixPool['ospfRouteProperty'] != []: + if ipv4PrefixPool.OspfRouteProperty.find(): protocolList.append('ospf') - if ipv4PrefixPool['isisL3RouteProperty'] != []: + if ipv4PrefixPool.IsisL3RouteProperty.find(): protocolList.append('isisL3') - if ipv4PrefixPool['ldpFECProperty'] != []: + if ipv4PrefixPool.LdpFECProperty.find(): protocolList.append('ldp') - return portList,protocolList + return portList, protocolList def activateRouterIdProtocol(self, routerId, protocol=None, activate=True): """ @@ -3262,75 +2541,49 @@ def activateRouterIdProtocol(self, routerId, protocol=None, activate=True): """ if type(routerId) is list: routerId = routerId[0] - queryData = {'from': '/', - 'nodes': [{'node': 'topology', 'properties': [], 'where': []}, - {'node': 'deviceGroup', 'properties': [], 'where': []}, - {'node': 'routerData', 'properties': ['routerId'], 'where': []}, - {'node': 'ethernet', 'properties': [], 'where': []}, - {'node': 'ipv4', 'properties': [], 'where': []}, - {'node': 'ipv6', 'properties': [], 'where': []}, - {'node': protocol, 'properties': ['active'], 'where': []} - ]} - - queryResponse = self.ixnObj.query(data=queryData, silentMode=False) - - # Get the Device Group object that contains the RouterId - # and search for configured protocols. + protocol = protocol[0:1].capitalize() + protocol[1:] protocolList = [] foundRouterIdFlag = 0 - for topology in queryResponse.json()['result'][0]['topology']: - for deviceGroup in topology['deviceGroup']: - deviceGroupHref = deviceGroup['href'] - routerIdMultivalue = deviceGroup['routerData'][0]['routerId'] - routerIdList = self.ixnObj.getMultivalueValues(routerIdMultivalue, silentMode=True) - self.ixnObj.logInfo('activateRouterIdProtocols: Querying DeviceGroup for routerId %s: %s' % (routerId, protocol)) - self.ixnObj.logInfo('routerIdList: {0}'.format(routerIdList)) - # response: ["192.0.0.1", "192.0.0.2", "192.0.0.3", "192.0.0.4","192.1.0.1"] - if routerId in routerIdList: - foundRouterIdFlag = 1 - self.ixnObj.logInfo('Found routerId %s' % routerId) - routerIdIndex = routerIdList.index(routerId) - self.ixnObj.logInfo('routerId index: %s' % routerIdIndex) - - if protocol == 'isisL3' and deviceGroup['ethernet'][0]['isisL3'] != []: - protocolList.append(deviceGroup['ethernet'][0]['isisL3'][0]['active']) - - if deviceGroup['ethernet'][0]['ipv4'] != []: - if protocol == 'igmpHost' and deviceGroup['ethernet'][0]['ipv4'][0]['igmpHost'] != []: - protocolList.append(deviceGroup['ethernet'][0]['ipv4'][0]['igmpHost'][0]['active']) - if protocol == 'igmpQuerier' and deviceGroup['ethernet'][0]['ipv4'][0]['igmpQuerier'] != []: - protocolList.append(deviceGroup['ethernet'][0]['ipv4'][0]['igmpQuerier'][0]['active']) - if protocol == 'bgpIpv4Peer' and deviceGroup['ethernet'][0]['ipv4'][0]['bgpIpv4Peer'] != []: - protocolList.append(deviceGroup['ethernet'][0]['ipv4'][0]['bgpIpv4Peer'][0]['active']) - if protocol == 'ospfv2' and deviceGroup['ethernet'][0]['ipv4'][0]['ospfv2'] != []: - protocolList.append(deviceGroup['ethernet'][0]['ipv4'][0]['ospfv2'][0]['active']) - - if deviceGroup['ethernet'][0]['ipv6'] != []: - if protocol == 'pimV6Interface' and deviceGroup['ethernet'][0]['ipv6'][0]['pimV6Interface'] != []: - protocolList.append(deviceGroup['ethernet'][0]['ipv6'][0]['pimV6Interface'][0]['active']) - if protocol == 'bgpIpv6Peer' and deviceGroup['ethernet'][0]['ipv6'][0]['bgpIpv6Peer'] != []: - protocolList.append(deviceGroup['ethernet'][0]['ipv6'][0]['bgpIpv6Peer'][0]['active']) - if protocol == 'ospfv3' and deviceGroup['ethernet'][0]['ipv6'][0]['ospfv3'] != []: - protocolList.append(deviceGroup['ethernet'][0]['ipv6'][0]['ospfv3'][0]['active']) - if protocol == 'mldHost' and deviceGroup['ethernet'][0]['ipv6'][0]['mldHost'] != []: - protocolList.append(deviceGroup['ethernet'][0]['ipv6'][0]['mldHost'][0]['active']) - if protocol == 'mldQuerier' and deviceGroup['ethernet'][0]['ipv6'][0]['mldQuerier'] != []: - protocolList.append(deviceGroup['ethernet'][0]['ipv6'][0]['mldQuerier'][0]['active']) - - for protocolActiveMultivalue in protocolList: - try: - protocolActiveList = self.ixnObj.getMultivalueValues(protocolActiveMultivalue) - self.ixnObj.logInfo('currentValueList: %s' % protocolActiveList) - protocolActiveList[routerIdIndex] = str(activate).lower() - self.ixnObj.logInfo('updatedValueList: %s' % protocolActiveList) - self.ixnObj.configMultivalue(protocolActiveMultivalue, multivalueType='valueList', - data={'values': protocolActiveList}) - except: - pass - return - + deviceGroupObj = self.getDeviceGroupByRouterId(routerId) + routerIdMultivalue = deviceGroupObj.RouterData.find()[0].RouterId + routerIdList = self.ixnObj.getMultivalueValues(routerIdMultivalue, silentMode=True) + self.ixnObj.logInfo('activateRouterIdProtocols: Querying DeviceGroup for routerId %s: %s' % + (routerId, protocol)) + self.ixnObj.logInfo('routerIdList: {0}'.format(routerIdList)) + if routerId in routerIdList: + self.ixnObj.logInfo('Found routerId %s' % routerId) + routerIdIndex = routerIdList.index(routerId) + self.ixnObj.logInfo('routerId index: %s' % routerIdIndex) + if protocol == 'IsisL3': + protocolResponse = getattr(deviceGroupObj.Ethernet.find()[0], protocol) + if protocolResponse.find(): + protocolList.append(protocolResponse.find()[0].Active) + try: + ipv4ProtocolResponse = getattr(deviceGroupObj.Ethernet.find().Ipv4.find(), protocol) + if ipv4ProtocolResponse.find(): + protocolList.append(ipv4ProtocolResponse.find().Active) + ipv6ProtocolResponse = getattr(deviceGroupObj.Ethernet.find().Ipv6.find(), protocol) + if ipv6ProtocolResponse.find(): + protocolList.append(ipv6ProtocolResponse.find().Active) + except Exception as e: + print(e) + pass + + for protocolActiveMultivalue in protocolList: + try: + protocolActiveList = self.ixnObj.getMultivalueValues(protocolActiveMultivalue) + self.ixnObj.logInfo('currentValueList: %s' % protocolActiveList) + protocolActiveList[routerIdIndex] = str(activate).lower() + self.ixnObj.logInfo('updatedValueList: %s' % protocolActiveList) + self.ixnObj.configMultivalue(protocolActiveMultivalue, + multivalueType='valueList', + data={'values': protocolActiveList}) + except Exception as e: + print(e) + pass + return if foundRouterIdFlag == 0: - raise Exception ('\nNo RouterID found in any Device Group: %s' % routerId) + raise Exception('\nNo RouterID found in any Device Group: %s' % routerId) def activateRouterIdRouteRanges(self, protocol=None, routeRangeAddressList=None, activate=True): """ @@ -3347,38 +2600,31 @@ def activateRouterIdRouteRanges(self, protocol=None, routeRangeAddressList=None, activate: True|False Examples: - 1> activateRouterIdRouteRanges(routeRangeAddressList=[[['all'], ['all']]], protocol='ospf', activate=True) + 1> activateRouterIdRouteRanges(routeRangeAddressList=[[['all'], ['all']]], + protocol='ospf', activate=True) - 2> activateRouterIdRouteRanges(routeRangeAddressList=[[['all'], ['202.13.0.0', '202.23.0.0', '203.5.0.0']]], - protocol='isis', activate=False) + 2> activateRouterIdRouteRanges(routeRangeAddressList=[[['all'], ['202.13.0.0', + '202.23.0.0', '203.5.0.0']]], protocol='isis', activate=False) - 3> activateRouterIdRouteRanges(routeRangeAddressList=[[['192.0.0.2', '192.0.0.3'], ['202.11.0.0', '202.21.0.0']], - [['192.0.0.1'], ['all']]], protocol='ospf', activate=False) + 3> activateRouterIdRouteRanges(routeRangeAddressList=[[['192.0.0.2', '192.0.0.3'], + ['202.11.0.0', '202.21.0.0']], [['192.0.0.1'], ['all']]], + protocol='ospf', activate=False) - 4> activateRouterIdRouteRanges(routeRangeAddressList=[[['192.0.0.1', '192.0.0.3'], ['202.3.0.0', '202.23.0.0']]], - protocol='ospf', activate=False) + 4> activateRouterIdRouteRanges(routeRangeAddressList=[[['192.0.0.1', '192.0.0.3'], + ['202.3.0.0', '202.23.0.0']]], protocol='ospf', activate=False) """ - if protocol == 'bgp': protocol = 'bgpIPRouteProperty' - if protocol == 'ospf': protocol = 'ospfRouteProperty' - if protocol == 'isis': protocol = 'isisL3RouteProperty' - if protocol == 'ldp': protocol = 'ldpFECProperty' + protocolDict = {'bgp': 'BgpIPRouteProperty', 'ospf': 'OspfRouteProperty', + 'isis': 'IsisL3RouteProperty', 'ldp': 'LdpFECProperty'} # 1: Get all the Device Group objects with the user specified router IDs. - queryData = {'from': '/', - 'nodes': [{'node': 'topology', 'properties': [], 'where': []}, - {'node': 'deviceGroup', 'properties': ['multiplier'], 'where': []}, - {'node': 'routerData', 'properties': ['routerId', 'count'], 'where': []} - ]} deviceGroupObjList = [] allRouterIdList = [] - queryResponse = self.ixnObj.query(data=queryData, silentMode=False) - for topology in queryResponse.json()['result'][0]['topology']: - for deviceGroup in topology['deviceGroup']: - deviceGroupObj = deviceGroup['href'] - deviceGroupMultiplier = deviceGroup['multiplier'] - routerIdMultivalue = deviceGroup['routerData'][0]['routerId'] - routerIdList = self.ixnObj.getMultivalueValues(routerIdMultivalue, silentMode=True) - deviceGroupObjList.append((deviceGroupObj, deviceGroupMultiplier, routerIdList, routerIdMultivalue)) + for topology in self.ixNetwork.Topology.find(): + for deviceGroup in topology.DeviceGroup.find(): + deviceGroupMultiplier = deviceGroup.Multiplier + routerIdMultivalue = deviceGroup.RouterData.find()[0].RouterId + routerIdList = self.getMultivalueValues(routerIdMultivalue, silentMode=True) + deviceGroupObjList.append((deviceGroup, deviceGroupMultiplier, routerIdList)) for rId in routerIdList: if rId not in allRouterIdList: @@ -3390,28 +2636,22 @@ def activateRouterIdRouteRanges(self, protocol=None, routeRangeAddressList=None, deviceGroupObj = deviceGroup[0] deviceGroupMultiplier = deviceGroup[1] deviceGroupRouterIdList = deviceGroup[2] - routerIdMultivalue = deviceGroup[3] self.ixnObj.logInfo('Searching Device Group: %s' % deviceGroupObj) - queryData = {'from': deviceGroupObj, - 'nodes': [{'node': 'networkGroup', 'properties': [], 'where': []}, - {'node': 'ipv4PrefixPools', 'properties': ['networkAddress', 'count'], 'where': []}, - {'node': protocol, 'properties': ['active'], 'where': []} - ]} - queryResponse = self.ixnObj.query(data=queryData, silentMode=False) - - # Note: A device group could have multiple network groups. - # Loop through all configured network groups for the ipv4PrefixPools with the user specified protocol. - for networkGroup in queryResponse.json()['result'][0]['networkGroup']: - networkGroupObj = networkGroup['href'] - for ipv4Prefix in networkGroup['ipv4PrefixPools']: - if ipv4Prefix[protocol] != []: - ipv4PrefixPoolMultivalue = ipv4Prefix['networkAddress'] - ipv4PrefixPool = self.ixnObj.getMultivalueValues(ipv4PrefixPoolMultivalue, silentMode=True) - protocolMultivalue = ipv4Prefix[protocol][0]['active'] - protocolActiveList = self.ixnObj.getMultivalueValues(protocolMultivalue, silentMode=True) - totalCountForEachRouterId = ipv4Prefix['count'] // deviceGroupMultiplier - totalRouteRangeCount = ipv4Prefix['count'] + for networkGroup in deviceGroupObj.NetworkGroup.find(): + networkGroupObj = networkGroup + for ipv4Prefix in networkGroup.Ipv4PrefixPools.find(): + protocolResponse = getattr(ipv4Prefix, protocolDict[protocol]) + if protocolResponse.find(): + protocolObj = protocolResponse.find() + ipv4PrefixPoolMultivalue = ipv4Prefix.NetworkAddress + ipv4PrefixPool = self.getMultivalueValues(ipv4PrefixPoolMultivalue, + silentMode=True) + protocolMultivalue = protocolObj.Active + protocolActiveList = self.getMultivalueValues(protocolMultivalue, + silentMode=True) + totalCountForEachRouterId = ipv4Prefix.Count // deviceGroupMultiplier + totalRouteRangeCount = ipv4Prefix.Count # Create a dictionary containing routerID starting/ending indexes. routerIdIndexes = {} @@ -3425,7 +2665,7 @@ def activateRouterIdRouteRanges(self, protocol=None, routeRangeAddressList=None, startingIndex += totalCountForEachRouterId endingIndex += totalCountForEachRouterId - for key,value in routerIdIndexes.items(): + for key, value in routerIdIndexes.items(): print('', key, value) self.ixnObj.logInfo('Current active list: %s' % protocolActiveList) @@ -3442,17 +2682,22 @@ def activateRouterIdRouteRanges(self, protocol=None, routeRangeAddressList=None, continue if 'all' in currentUserDefinedRouteRangeList: - for index in range(routerIdIndexes[eachRouterId,'startingIndex'], routerIdIndexes[eachRouterId,'endingIndex']): + for index in range(routerIdIndexes[ + eachRouterId, 'startingIndex'], + routerIdIndexes[ + eachRouterId, 'endingIndex']): protocolActiveList[index] = activate if 'all' not in currentUserDefinedRouteRangeList: for index in range(startingIndex, totalRouteRangeCount): - currentIpv4PrefixPoolsIndex = ipv4PrefixPool[index] - if ipv4PrefixPool[index] in currentUserDefinedRouteRangeList: + if ipv4PrefixPool[index] in \ + currentUserDefinedRouteRangeList: protocolActiveList[index] = activate self.ixnObj.logInfo('Modifying: %s' % networkGroupObj) - self.ixnObj.configMultivalue(protocolMultivalue, multivalueType='valueList', data={'values': protocolActiveList}) + self.ixnObj.configMultivalue(protocolMultivalue, + multivalueType='valueList', + data={'values': protocolActiveList}) def modifyProtocolRoutes(self, **kwargs): """ @@ -3471,57 +2716,50 @@ def modifyProtocolRoutes(self, **kwargs): 'step': '0.0.0.1', 'direction': 'increment'}, prefixLength = 24) + + Note: + There are not enough inputs provided. """ - response = self.ixnObj.get(self.ixnObj.sessionUrl+networkGroupPrefixPoolObj) + response = self.ixnObj.get( + self.ixnObj.sessionUrl + networkGroupPrefixPoolObj) print(response.json()) prefixPoolAddressMultivalue = response.json()['networkAddress'] print('modifyProtocolRoutes:', prefixPoolAddressMultivalue) - #self.ixnObj.patch(self.ixnObj.httpHeader+/networkGroupObj, data=data) - + prefixPoolObj = None if 'networkGroupObj' not in kwargs: - response = self.ixnObj.post(self.ixnObj.httpHeader+deviceGroupObj+'/networkGroup') - networkGroupObj = response.json()['links'][0]['href'] + networkGroupObj = deviceGroupObj.NetworkGroup.add() if 'networkGroupObj' in kwargs: networkGroupObj = kwargs['networkGroupObj'] self.ixnObj.logInfo('configNetworkGroup: %s' % networkGroupObj) if 'name' in kwargs: - self.ixnObj.patch(self.ixnObj.httpHeader+networkGroupObj, data={'name': kwargs['name']}) + networkGroupObj.Name = kwargs['name'] if 'multiplier' in kwargs: - self.ixnObj.patch(self.ixnObj.httpHeader+networkGroupObj, data={'multiplier': kwargs['multiplier']}) + networkGroupObj.Multiplier = kwargs['multiplier'] if 'networkAddress' in kwargs: - response = self.ixnObj.post(self.ixnObj.httpHeader+networkGroupObj+'/ipv4PrefixPools') - prefixPoolObj = self.ixnObj.httpHeader + response.json()['links'][0]['href'] - - # prefixPoolId = /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/networkGroup/3/ipv4PrefixPools/1 - ipv4PrefixResponse = self.ixnObj.get(prefixPoolObj) + prefixPoolObj = networkGroupObj.Ipv4PrefixPools.add() if 'networkAddress' in kwargs: - multiValue = ipv4PrefixResponse.json()['networkAddress'] - self.ixnObj.patch(self.ixnObj.httpHeader+multiValue+"/counter", - data={'start': kwargs['networkAddress']['start'], - 'step': kwargs['networkAddress']['step'], - 'direction': kwargs['networkAddress']['direction']}) - + multiValue = prefixPoolObj.NetworkAddress + self.configMultivalue(multiValue, "counter", data={ + 'start': kwargs['networkAddress']['start'], + 'step': kwargs['networkAddress']['step'], + 'direction': kwargs['networkAddress']['direction']}) if 'prefixLength' in kwargs: - multiValue = ipv4PrefixResponse.json()['prefixLength'] - self.ixnObj.patch(self.ixnObj.httpHeader+multiValue+"/singleValue", - data={'value': kwargs['prefixLength']}) - + multiValue = prefixPoolObj.PrefixLength + self.configMultivalue(multiValue, "singleValue", + data={'value': kwargs['prefixLength']}) return prefixPoolObj - def applyOnTheFly(self): """ Description Apply NGPF configuration changes on the fly while Topology protocols are running. """ - response = self.ixnObj.post(self.ixnObj.sessionUrl+'/globals/topology/operations/applyonthefly', - data={'arg1': '{0}/globals/topology'.format(self.ixnObj.sessionUrl)}) - self.ixnObj.waitForComplete(response, self.ixnObj.sessionUrl+'/globals/topology/operations/applyonthefly'+response.json()['id']) + self.ixNetwork.Globals.Topology.ApplyOnTheFly() def getProtocolListByPort(self, port): """ @@ -3532,36 +2770,21 @@ def getProtocolListByPort(self, port): Parameter port: (chassisIp, cardNumber, portNumber) -> ('10.10.10.1', '2', '8') """ + protocolList = ['bfd', 'bgp', 'cfm', 'eigrp', 'elmi', 'igmp', 'isis', 'lacp', 'ldp', + 'linkOam', 'lisp', 'mld', 'mplsOam', 'mplsTp', 'openFlow', 'ospf', + 'ospfV3', 'pimsm', 'ping', 'rip', 'ripng', 'rsvp', 'stp'] self.ixnObj.logInfo('\ngetProtocolListByPort...') chassis = str(port[0]) card = str(port[1]) port = str(port[2]) - specifiedPort = (chassis, card, port) + portObj = chassis + ":" + card + ":" + port enabledProtocolList = [] - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/vport') - vportList = ['%s/%s/%s' % (self.ixnObj.sessionUrl, 'vport', str(i["id"])) for i in response.json()] - for vport in vportList: - response = self.ixnObj.get(vport, 'assignedTo') - # 10.219.117.101:1:5 - assignedTo = response.json()['assignedTo'] - currentChassisIp = str(assignedTo.split(':')[0]) - currentCardNumber = str(assignedTo.split(':')[1]) - currentPortNumber = str(assignedTo.split(':')[2]) - currentPort = (currentChassisIp, currentCardNumber, currentPortNumber) - if currentPort != specifiedPort: - continue - else: - response = self.ixnObj.get(vport+'/protocols?links=true') - if response.status_code == 200: - #print 'json', response.json()['links'] - for protocol in response.json()['links']: - currentProtocol = protocol['href'] - url = self.ixnObj.httpHeader+currentProtocol - response = self.ixnObj.get(url) - if 'enabled' in response.json() and response.json()['enabled'] == True: - # Exclude ARP object - if 'arp' not in currentProtocol: - enabledProtocolList.append(str(currentProtocol)) + vport = self.ixNetwork.Vport.find(AssignedTo=portObj) + for protocol in protocolList: + currentProtocol = protocol[0].capitalize() + protocol[1:] + protocolResponse = getattr(vport.Protocols.find(), currentProtocol) + if protocolResponse and protocolResponse.Enabled: + enabledProtocolList.append(str(protocol)) return enabledProtocolList @@ -3569,7 +2792,7 @@ def getProtocolListByPortNgpf(self, port=None, portName=None): """ Description Based on either the vport name or the physical port, get the Topology - Group object and all the protocols in each Device Group within the same + Group object and all the protocols in each Device Group within the same Topology Group. Parameter @@ -3582,119 +2805,59 @@ def getProtocolListByPortNgpf(self, port=None, portName=None): protocolObj = Protocol(mainObj) protocolList = protocolObj.getProtocolListByPortNgpf(port=['192.168.70.120', '1', '2']) - Subsequently, you could call getProtocolObjFromProtocolList to get any protocol object handle: - obj = protocolObj.getProtocolObjFromProtocolList(protocolList['deviceGroup'], 'bgpIpv4Peer') - - Returns - {'topology': '/api/v1/sessions/1/ixnetwork/topology/2', - 'deviceGroup': [['/api/v1/sessions/1/ixnetwork/topology/2/deviceGroup/2', - '/api/v1/sessions/1/ixnetwork/topology/2/deviceGroup/2/ethernet/1', - '/api/v1/sessions/1/ixnetwork/topology/2/deviceGroup/2/ethernet/1/ipv4/1', - '/api/v1/sessions/1/ixnetwork/topology/2/deviceGroup/2/ethernet/1/ipv4/1/bgpIpv4Peer'], - - ['/api/v1/sessions/1/ixnetwork/topology/2/deviceGroup/3', - '/api/v1/sessions/1/ixnetwork/topology/2/deviceGroup/3/ethernet/1', - '/api/v1/sessions/1/ixnetwork/topology/2/deviceGroup/3/ethernet/1/ipv4/1', - '/api/v1/sessions/1/ixnetwork/topology/2/deviceGroup/3/ethernet/1/ipv4/1/ospfv2'] - ]} - """ - self.ixnObj.logInfo('{0}...'.format('\ngetProtocolListByPortNgpf'), timestamp=False) - if port: - chassisIp = str(port[0]) - cardNum = str(port[1]) - portNum = str(port[2]) - specifiedPort = chassisIp+':'+cardNum+':'+portNum - - loopFlag = 0 + Subsequently, you could call getProtocolObjFromProtocolList to get any protocol + object handle: + obj = protocolObj.getProtocolObjFromProtocolList(protocolList['deviceGroup'], + 'bgpIpv4Peer') - # Loop each Topology and search for matching port or portName - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/topology', silentMode=True) - topologyList = ['%s/%s/%s' % (self.ixnObj.sessionUrl, 'topology', str(i["id"])) for i in response.json()] - for topology in topologyList: - response = self.ixnObj.get(topology, silentMode=True) - topologyObj = response.json()['links'][0]['href'] - vportList = response.json()['vports'] - - for eachVport in vportList: - response = self.ixnObj.get(self.ixnObj.httpHeader+eachVport, silentMode=True) - vportName = response.json()['name'] - - if portName != None: - if portName != vportName: - continue - else: - loopFlag = 1 - break - - if port != None: - # actualPort: ['192.168.70.3:1:2'] - actualPort = self.portMgmtObj.getPhysicalPortFromVport([eachVport])[0] - if actualPort != specifiedPort: - continue - else: - loopFlag = 1 - break + """ + l3ProtocolList = ['ancp', 'bfdv4Interface', 'bgpIpv4Peer', 'bgpIpv6Peer', + 'dhcpv4relayAgent', 'dhcpv6relayAgent', 'geneve', 'greoipv4', + 'greoipv6', 'igmpHost', 'igmpQuerier', 'lac', 'ldpBasicRouter', + 'ldpBasicRouterV6', 'ldpConnectedInterface', 'ldpv6ConnectedInterface', + 'ldpTargetedRouter', 'ldpTargetedRouterV6', 'lns', 'mldHost', + 'mldQuerier', 'ptp', 'ipv6sr', 'openFlowController', 'openFlowSwitch', + 'ospfv2', 'ospfv3', 'ovsdbcontroller', 'ovsdbserver', 'pcc', 'pce', + 'pcepBackupPCEs', 'pimV4Interface', 'pimV6Interface', 'ptp', 'rsvpteIf', + 'rsvpteLsps', 'tag', 'vxlan'] - if loopFlag == 0: - # The port or portName is not found. - continue + outputDict = {'topology': "", 'deviceGroup': []} - enabledProtocolList = {'topology': topologyObj} - response = self.ixnObj.get(topology+'/deviceGroup', silentMode=True) - deviceGroupList = ['%s/%s/%s' % (topology, 'deviceGroup', str(i["id"])) for i in response.json()] + if port is not None and portName is None: + portName = str(port[1]) + '/' + str(port[2]) - deviceGroupObjects = [] - enabledProtocolList = {'topology': topologyObj, 'deviceGroup': []} - for deviceGroup in deviceGroupList: - deviceGroupObj = '/api' + deviceGroup.split('/api')[1] - deviceGroupObjects.append(deviceGroupObj) + for topology in self.ixNetwork.Topology.find(): + if self.ixNetwork.Vport.find(Name=portName).href in topology.Vports: + devGrpList = topology.DeviceGroup.find() + outputDict['topology'] = topology.href + break - response = self.ixnObj.get(deviceGroup+'/ethernet', silentMode=True) - ethernetList = ['%s/%s/%s' % (deviceGroup, 'ethernet', str(i["id"])) for i in response.json()] - for ethernet in ethernetList: - deviceGroupObjects.append('/api'+ethernet.split('/api')[1]) - response = self.ixnObj.get(ethernet+'/ipv4', silentMode=True) - ipv4List = ['%s/%s/%s' % (ethernet, 'ipv4', str(i["id"])) for i in response.json()] - if ipv4List: - deviceGroupObjects.append('/api'+ipv4List[0].split('/api')[1]) - response = self.ixnObj.get(ethernet+'/ipv6', silentMode=True) - ipv6List = ['%s/%s/%s' % (ethernet, 'ipv6', str(i["id"])) for i in response.json()] - if ipv6List: - deviceGroupObjects.append('/api'+ipv6List[0].split('/api')[1]) - for layer3Ip in ipv4List+ipv6List: - url = layer3Ip+'?links=true' - response = self.ixnObj.get(url, silentMode=True) - for protocol in response.json()['links']: - currentProtocol = protocol['href'] - if (bool(re.match('^/api/.*(ipv4|ipv6)/[0-9]+$', currentProtocol))): - continue - if (bool(re.match('^/api/.*(ipv4|ipv6)/[0-9]+/port$', currentProtocol))): - continue - url = self.ixnObj.httpHeader+currentProtocol - response = self.ixnObj.get(url, silentMode=True) - if response.json() == []: - # The currentProtocol is not configured. - continue - else: - response = self.ixnObj.get(url, silentMode=True) - currentProtocol =response.json()[0]['links'][0]['href'] - deviceGroupObjects.append(currentProtocol) - - enabledProtocolList['deviceGroup'].insert(len(enabledProtocolList), deviceGroupObjects) - deviceGroupObjects = [] - - # Getting here means either the port or portName is found and the object is obtained. - # Break and return the object handle. - break - - if loopFlag == 0: - if port != None: - raise IxNetRestApiException('\nError: No port found: {0}'.format(port)) - if portName != None: - raise IxNetRestApiException('\nError: No portName found: {0}'.format(portName)) - - self.ixnObj.logInfo('\ngetProtocolListByPortNgpf: {0}'.format(str(enabledProtocolList)), timestamp=False) - return enabledProtocolList + for devGrpObj in devGrpList: + outPutList = [] + for currentProtocol in l3ProtocolList: + currentProtocol = currentProtocol[0].capitalize() + currentProtocol[1:] + try: + ethernetResponse = getattr(devGrpObj, 'Ethernet') + if ethernetResponse.find(): + outPutList.append(ethernetResponse.find().href) + ipv4Response = getattr(ethernetResponse.find(), 'Ipv4') + if ipv4Response.find(): + outPutList.append(ipv4Response.find().href) + currentProtocolResponse = getattr(ipv4Response.find(), currentProtocol) + if currentProtocolResponse.find(): + outPutList.append(currentProtocolResponse.find().href) + ipv6Response = getattr(ethernetResponse.find(), 'Ipv6') + if ipv6Response.find(): + outPutList.append(ipv6Response.find().href) + currentProtocolResponse = getattr(ipv6Response.find(), currentProtocol) + if currentProtocolResponse.find(): + outPutList.append(currentProtocolResponse.find().href) + except Exception as e: + print(e) + pass + if outPutList != []: + outputDict['deviceGroup'].append(outPutList) + return outputDict def getProtocolListByHostIpNgpf(self, hostIp): """ @@ -3709,97 +2872,85 @@ def getProtocolListByHostIpNgpf(self, hostIp): protocolObj = Protocol(mainObj) objectList = protocolObj.getProtocolListByHostIpNgpf('1.1.1.1') - Subsequently, you could call getProtocolObjFromProtocolList to get any protocol object handle: - obj = protocolObj.getProtocolObjFromProtocolList(protocolList['deviceGroup'], 'bgpIpv4Peer') - + Subsequently, you could call getProtocolObjFromProtocolList to get any protocol + object handle: + obj = protocolObj.getProtocolObjFromProtocolList(protocolList['deviceGroup'], + 'bgpIpv4Peer') + Returns - # This return example shows that the hostIp was found in one topology group and the hostIP - # was found in two of the device groups within this topology group. - - [{'topology': '/api/v1/sessions/1/ixnetwork/topology/1', - 'deviceGroup': [['/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1', - '/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1', - '/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1', - '/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/bgpIpv4Peer/1'], - - ['/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/2', - '/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/2/ethernet/1', - '/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/2/ethernet/1/ipv4/1', - '/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/2/ethernet/1/ipv4/1/ospfv2/1'] - ] - }] + # This return example shows that the hostIp was found in one topology group and the + # hostIP was found in two of the device groups within this topology group. + """ - self.ixnObj.logInfo('{0}...'.format('\ngetProtocolListByIpHostNgpf'), timestamp=False) container = [] - - # Loop each Topology and search for matching port or portName - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/topology', silentMode=True) - topologyList = ['%s/%s/%s' % (self.ixnObj.sessionUrl, 'topology', str(i["id"])) for i in response.json()] + l3ProtocolList = ['ancp', 'bfdv4Interface', 'bgpIpv4Peer', 'bgpIpv6Peer', + 'dhcpv4relayAgent', 'dhcpv6relayAgent', 'geneve', 'greoipv4', 'greoipv6', + 'igmpHost', 'igmpQuerier', 'lac', 'ldpBasicRouter', 'ldpBasicRouterV6', + 'ldpConnectedInterface', 'ldpv6ConnectedInterface', + 'ldpTargetedRouter', 'ldpTargetedRouterV6', 'lns', 'mldHost', + 'mldQuerier', 'ptp', 'ipv6sr', 'openFlowController', 'openFlowSwitch', + 'ospfv2', 'ospfv3', 'ovsdbcontroller', 'ovsdbserver', 'pcc', 'pce', + 'pcepBackupPCEs', 'pimV4Interface', 'pimV6Interface', 'ptp', 'rsvpteIf', + 'rsvpteLsps', 'tag', 'vxlan' + ] + + topologyList = self.ixNetwork.Topology.find() for topology in topologyList: - response = self.ixnObj.get(topology, silentMode=True) - topologyObj = response.json()['links'][0]['href'] - response = self.ixnObj.get(topology+'/deviceGroup', silentMode=True) - deviceGroupList = ['%s/%s/%s' % (topology, 'deviceGroup', str(i["id"])) for i in response.json()] + topologyObj = topology + deviceGroupList = topologyObj.DeviceGroup.find() topologyDict = {} topology = [] deviceGroupObjects = [] for deviceGroup in deviceGroupList: - deviceGroupObj = '/api' + deviceGroup.split('/api')[1] - response = self.ixnObj.get(deviceGroup+'/ethernet', silentMode=True) - ethernetList = ['%s/%s/%s' % (deviceGroup, 'ethernet', str(i["id"])) for i in response.json()] + deviceGroupObj = deviceGroup + ethernetList = deviceGroup.Ethernet.find() isHostIpFound = False for ethernet in ethernetList: ipList = [] + ethernetObj = ethernet # IPv4 if '.' in hostIp: - response = self.ixnObj.get(ethernet+'/ipv4', silentMode=True) - ipList = ['%s/%s/%s' % (ethernet, 'ipv4', str(i["id"])) for i in response.json()] + ipList = ethernet.Ipv4.find() if ':' in hostIp: - response = self.ixnObj.get(ethernet+'/ipv6', silentMode=True) - ipList = ['%s/%s/%s' % (ethernet, 'ipv6', str(i["id"])) for i in response.json()] + ipList = ethernet.Ipv6.find() if ipList: for ipObj in ipList: - response = self.ixnObj.get(ipObj) - multivalue = response.json()['address'] + multivalue = ipObj.Address ipHostList = self.getMultivalueValues(multivalue) if hostIp in ipHostList: if 'topology' not in topologyDict: - topologyDict = {'topology': topologyObj, 'deviceGroup': []} + topologyDict = {'topology': topologyObj.href, 'deviceGroup': []} - deviceGroupObjects.append(deviceGroupObj) - deviceGroupObjects.append('/api'+ethernet.split('/api')[1]) - deviceGroupObjects.append('/api'+ipList[0].split('/api')[1]) + deviceGroupObjects.append(deviceGroupObj.href) + deviceGroupObjects.append(ethernetObj.href) + deviceGroupObjects.append(ipObj.href) isHostIpFound = True - if isHostIpFound == False: + if not isHostIpFound: continue for layer3Ip in ipList: - url = layer3Ip+'?links=true' - response = self.ixnObj.get(url, silentMode=True) - for protocol in response.json()['links']: - currentProtocol = protocol['href'] - if (bool(re.match('^/api/.*(ipv4|ipv6)/[0-9]+$', currentProtocol))): - continue - if (bool(re.match('^/api/.*(ipv4|ipv6)/[0-9]+/port$', currentProtocol))): - continue - - url = self.ixnObj.httpHeader+currentProtocol - response = self.ixnObj.get(url, silentMode=True) - if response.json() == []: - # The currentProtocol is not configured. - continue - else: - deviceGroupObjects.append(response.json()[0]['links'][0]['href']) + for currentProtocol in l3ProtocolList: + currentProtocol = currentProtocol[0].capitalize() + currentProtocol[ + 1:] + try: + currentProtocolResponse = getattr(layer3Ip, currentProtocol) + if currentProtocolResponse.find(): + deviceGroupObjects.append( + currentProtocolResponse.find().href) + except Exception as e: + print(e) + pass # Done with the current Device Group. Reset deviceGroupObjects for the next DG. if isHostIpFound: - topologyDict['deviceGroup'].insert(len(topologyDict['deviceGroup']), deviceGroupObjects) + topologyDict['deviceGroup'].insert(len(topologyDict['deviceGroup']), + deviceGroupObjects) deviceGroupObjects = [] # 'deviceGroup' exists if the ipHost is found. @@ -3813,116 +2964,112 @@ def getEndpointObjByDeviceGroupName(self, deviceGroupName, endpointObj): """ Description Based on the Device Group name, return the specified endpointObj object handle. - The endpointObj is the NGPF endpoint: topology, deviceGroup, networkGroup, ethernet, ipv4|ipv6, - bgpIpv4Peer, ospfv2, igmpHost, etc. The exact endpoint name could be found in the - IxNetwork API Browser. + The endpointObj is the NGPF endpoint: topology, deviceGroup, networkGroup, ethernet, + ipv4|ipv6, bgpIpv4Peer, ospfv2, igmpHost, etc. The exact endpoint name could be found + in the IxNetwork API Browser. Parameter deviceGroupName: : The Device Group name. endpointObj: : The NGPF endpoint object handle to get. - - Example usage: - # This example shows how to get the bgp object handle from the Device Group named DG-2. - - protocolObj = Protocol(mainObj) - obj = protocolObj.getEndpointObjByDeviceGroupName('DG-2', 'bgpIpv4Peer') - returns: ['/api/v1/sessions/1/ixnetwork/topology/2/deviceGroup/1/ethernet/1/ipv4/1/bgpIpv4Peer'] - - obj = protocolObj.getEndpointObjByDeviceGroupName('DG-2', 'topology') - returns: ['/api/v1/sessions/1/ixnetwork/topology/2'] Returns []|The NGPF endpoint object handle(s) in a list. """ + ngpfMainObjectList = ['topology', 'deviceGroup', 'ethernet', 'networkGroup', + 'ipv4PrefixPools', 'ipv6PrefixPools'] + + ngpfL2ObjectList = ['isisL3', 'lacp', 'mpls', 'esmc', 'bondedGRE', 'mka', 'staticMacsec', + 'dotOneX', 'eCpriRec', 'eCpriRe', 'cfmBridge', 'lagportstaticlag', + 'staticLag', 'lagportlacp', 'ptp', 'streams', 'pppoxclient', + 'lightweightDhcpv6relayAgent', 'dhcpv6client', 'dhcpv4client', + 'isisTrill', 'msrpTalker', 'msrpListener', 'isisTrillSimRouter', + 'isisSpbSimRouter', 'pppoxserver', 'isisSpbBeb', 'isisSpbBcb', + 'isisDceSimRouter', 'isisFabricPath', 'ipv6Autoconfiguration', + 'vlan', 'vpnParameter', 'pbbEVpnParameter', 'connector', 'tag', + 'ipv4', 'ipv6'] + + ngpfL3ObjectList = ['ancp', 'bfdv4Interface', 'bgpIpv4Peer', 'bgpIpv6Peer', + 'dhcpv4relayAgent', 'dhcpv6relayAgent', 'geneve', 'greoipv4', + 'greoipv6', 'igmpHost', 'igmpQuerier', 'lac', 'ldpBasicRouter', + 'ldpBasicRouterV6', 'ldpConnectedInterface', 'ldpv6ConnectedInterface', + 'ldpTargetedRouter', 'ldpTargetedRouterV6', 'lns', 'mldHost', + 'mldQuerier', 'ptp', 'ipv6sr', 'openFlowController', + 'openFlowSwitch', 'ospfv2', 'ospfv3', 'ovsdbcontroller', + 'ovsdbserver', 'pcc', 'pce', 'pcepBackupPCEs', 'pimV4Interface', + 'pimV6Interface', 'ptp', 'rsvpteIf', 'rsvpteLsps', 'tag', 'vxlan' + ] + if endpointObj not in ngpfL2ObjectList + ngpfL3ObjectList + ngpfMainObjectList: + return None returnList = [] self.ixnObj.logInfo('{0}...'.format('\ngetEndpointObjByDeviceGroupName'), timestamp=False) - # Loop each Topology and search for matching port or portName - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/topology', silentMode=False) - topologyList = ['%s/%s/%s' % (self.ixnObj.sessionUrl, 'topology', str(i["id"])) for i in response.json()] - for topology in topologyList: - response = self.ixnObj.get(topology, silentMode=False) - topologyObj = response.json()['links'][0]['href'] - response = self.ixnObj.get(topology+'/deviceGroup', silentMode=False) - + for topology in self.ixNetwork.Topology.find(): deviceGroupList = [] - for response in response.json(): - deviceGroupObj = response['links'][0]['href'] + for deviceGroupObj in topology.DeviceGroup.find(): deviceGroupList.append(deviceGroupObj) - - # Get inner device group objects also. Verify if there are additional device groups within a device group. - response = self.ixnObj.get(self.ixnObj.httpHeader + deviceGroupObj + '/deviceGroup') - if response.json(): - for response in response.json(): - deviceGroupList.append(response['links'][0]['href']) + innerDeviceGroupObj = deviceGroupObj.DeviceGroup.find() + if innerDeviceGroupObj: + for innerDeviceGroup in innerDeviceGroupObj: + deviceGroupList.append(innerDeviceGroup) for deviceGroupObj in deviceGroupList: - response = self.ixnObj.get(self.ixnObj.httpHeader+deviceGroupObj) - - if response.json()['name'] == deviceGroupName: + + if deviceGroupObj.Name == deviceGroupName: if endpointObj == 'topology': - return [topologyObj] + return [topology] if endpointObj == 'deviceGroup': return [deviceGroupObj] - response = self.ixnObj.get(self.ixnObj.httpHeader+deviceGroupObj+'/ethernet', silentMode=False) - ethernetList = ['%s/%s/%s' % (deviceGroupObj, 'ethernet', str(i["id"])) for i in response.json()] - if ethernetList == []: + ethernetList = deviceGroupObj.Ethernet.find() + if not ethernetList: continue if endpointObj == 'ethernet': headlessEthernetList = [] for eachEthernetObj in ethernetList: - match = re.match('http.*(/api.*)', eachEthernetObj) + match = re.match('(/api.*)', eachEthernetObj.href) if match: - headlessEthernetList.append(match.group(1)) + headlessEthernetList.append(eachEthernetObj) return headlessEthernetList if endpointObj == 'networkGroup': - response = self.ixnObj.get(deviceGroup+'/networkGroup', silentMode=False) - networkGroupList = ['%s/%s/%s' % (deviceGroup, 'networkGroup', str(i["id"])) for i in response.json()] + networkGroupList = deviceGroupObj.NetworkGroup.find() headlessNetworkGroupList = [] for eachNetworkGroupObj in networkGroupList: - match = re.match('http.*(/api.*)', eachNetworkGroupObj) + match = re.match('(/api.*)', eachNetworkGroupObj.href) if match: - headlessNetworkGroupList.append(match.group(1)) + headlessNetworkGroupList.append(eachNetworkGroupObj) return headlessNetworkGroupList for ethernet in ethernetList: # Dynamically get all Ethernet child endpoints - response = self.ixnObj.get(self.ixnObj.httpHeader+ethernet+'?links=true', silentMode=False) - for ethernetChild in response.json()['links']: - print('Ethernet child:', ethernetChild['href']) - currentChildName = ethernetChild['href'].split('/')[-1] - if currentChildName == endpointObj: - response = self.ixnObj.get(self.ixnObj.httpHeader+ethernetChild['href']) - if response.json() == []: - raise IxNetRestApiException('getEndpointObjByDeviceGroupName: The endpointObj you specified "{0}" is not configured. No endpointObj found'.format(endpointObj)) - - returnList.append(response.json()[0]['links'][0]['href']) - - # Search IPv4/IPv6 - if currentChildName in ['ipv4'] or currentChildName in ['ipv6']: - l3Obj = currentChildName - response = self.ixnObj.get(self.ixnObj.httpHeader+ethernet+'/'+l3Obj+'?links=true', silentMode=True) - if response.json() == []: - # L3 is not configured - continue - - for child in response.json(): - for l3Child in child['links']: - print('L3Child:', l3Child['href']) - currentL3ChildName = l3Child['href'].split('/')[-1] - if currentL3ChildName == endpointObj: - response = self.ixnObj.get(self.ixnObj.httpHeader+l3Child['href'], silentMode=True) - if response.json() == []: - raise IxNetRestApiException('getEndpointObjByDeviceGroupName: The endpointObj you specified "{0}" is not configured. No endpointObj found.'.format(endpointObj)) - - returnList.append(l3Child['href']) - + if endpointObj in ngpfL2ObjectList: + endpointObject = endpointObj[0:1].capitalize() + endpointObj[1:] + endpointObjectResponse = getattr(ethernet, endpointObject) + Obj = endpointObjectResponse.find() + self.ixnObj.logInfo('getEndpointObjByDeviceGroupName: %s' % Obj) + returnList.append(Obj) + elif endpointObj in ngpfL3ObjectList: + endpointObject = endpointObj[0:1].capitalize() + endpointObj[1:] + nodesIpv4ObjList = ethernet.Ipv4.find() + nodesIpv6ObjList = ethernet.Ipv6.find() + try: + endpointObjectResponse = getattr(nodesIpv4ObjList, endpointObject) + Obj = endpointObjectResponse.find() + self.ixnObj.logInfo('getEndpointObjByDeviceGroupName: %s' % Obj) + returnList.append(Obj) + except Exception as e: + print(e) + endpointObjectResponse = getattr(nodesIpv6ObjList, endpointObject) + Obj = endpointObjectResponse.find() + self.ixnObj.logInfo('getEndpointObjByDeviceGroupName: %s' % Obj) + returnList.append(Obj) + else: + returnList.append(None) return returnList - def getProtocolObjFromProtocolList(self, protocolList, protocol, deviceGroupName=None): + def getProtocolObjFromProtocolList(self, protocolList, protocol, + deviceGroupName=None): """ Description This is an internal API used after calling self.getProtocolListByPortNgpf(). @@ -3939,68 +3086,74 @@ def getProtocolObjFromProtocolList(self, protocolList, protocol, deviceGroupName the Device Group by its name. NGPF endpoint protocol names: - 'ancp', 'bfdv4Interface', 'bgpIpv4Peer', 'bgpIpv6Peer', 'dhcpv4relayAgent', 'dhcpv6relayAgent', - 'dhcpv4server', 'dhcpv6server', 'geneve', 'greoipv4', 'greoipv6', 'igmpHost', 'igmpQuerier', - 'lac', 'ldpBasicRouter', 'ldpBasicRouterV6', 'ldpConnectedInterface', 'ldpv6ConnectedInterface', - 'ldpTargetedRouter', 'ldpTargetedRouterV6', 'lns', 'mldHost', 'mldQuerier', 'ptp', - 'ipv6sr', 'openFlowController', 'openFlowSwitch', 'ospfv2', 'ospfv3', 'ovsdbcontroller', - 'ovsdbserver', 'pcc', 'pce', 'pcepBackupPCEs', 'pimV4Interface', 'pimV6Interface', 'ptp', - 'rsvpteIf', 'rsvpteLsps', 'tag', 'vxlan' + 'ancp', 'bfdv4Interface', 'bgpIpv4Peer', 'bgpIpv6Peer', 'dhcpv4relayAgent', + 'dhcpv6relayAgent', 'dhcpv4server', 'dhcpv6server', 'geneve', 'greoipv4', 'greoipv6', + 'igmpHost', 'igmpQuerier', 'lac', 'ldpBasicRouter', 'ldpBasicRouterV6', + 'ldpConnectedInterface', 'ldpv6ConnectedInterface', 'ldpTargetedRouter', + 'ldpTargetedRouterV6', 'lns', 'mldHost', 'mldQuerier', 'ptp', 'ipv6sr', + 'openFlowController', 'openFlowSwitch', 'ospfv2', 'ospfv3', 'ovsdbcontroller', + 'ovsdbserver', 'pcc', 'pce', 'pcepBackupPCEs', 'pimV4Interface', 'pimV6Interface', + 'ptp', 'rsvpteIf', 'rsvpteLsps', 'tag', 'vxlan' Example usage: protocolObj = Protocol(mainObj) protocolList = protocolObj.getProtocolListByPortNgpf(port=['192.168.70.120', '1', '2']) - obj = protocolObj.getProtocolObjFromProtocolList(protocolList['deviceGroup'], 'bgpIpv4Peer') + obj = protocolObj.getProtocolObjFromProtocolList(protocolList['deviceGroup'], + 'bgpIpv4Peer') - If you expect multiple Device Groups in your Topology, you could filter by the Device Group name: - obj = protocolObj.getProtocolObjFromProtocolList(protocolList['deviceGroup'], 'ethernet', deviceGroupName='DG2') + If you expect multiple Device Groups in your Topology, you could filter by the + Device Group name: + obj = protocolObj.getProtocolObjFromProtocolList(protocolList['deviceGroup'], + 'ethernet', deviceGroupName='DG2') Returns - The protocol object handle in a list. For example: - ['/api/v1/sessions/1/ixnetwork/topology/2/deviceGroup/2/ethernet/1/ipv4/1/bgpIpv4Peer'] - """ - self.ixnObj.logInfo('\n{0}...'.format('\ngetProtocolObjFromProtocolList'), timestamp=False) - protocolObjectHandleList = [] - - for protocols in protocolList: - if protocol in ['deviceGroup', 'ethernet', 'ipv4', 'ipv6']: - for endpointObj in protocols: - if protocol == 'deviceGroup': - # Include the deviceGroup object handle also - match = re.search( - r'(/api/v1/sessions/[0-9]+/ixnetwork/topology/[0-9]+/deviceGroup/[0-9]+)$', endpointObj) - - if match: - # A topology could have multiple Device Groups. Filter by the Device Group name. - if deviceGroupName: - deviceGroupObj = match.group(1) - response = self.ixnObj.get(self.ixnObj.httpHeader + deviceGroupObj, silentMode=True) - if deviceGroupName == response.json()['name']: - self.ixnObj.logInfo(str([endpointObj]), timestamp=False) - return [endpointObj] - else: - protocolObjectHandleList.append(endpointObj) - - # Search for the protocol after the deviceGroup endpoint. - match = re.search(r'(/api/v1/sessions/[0-9]+/ixnetwork/topology/[0-9]+/deviceGroup/[0-9]+).*/%s/[0-9]+$' % protocol, endpointObj) - if match: - # A topology could have multiple Device Groups. Filter by the Device Group name. - if deviceGroupName: - deviceGroupObj = match.group(1) - response = self.ixnObj.get(self.ixnObj.httpHeader + deviceGroupObj, silentMode=True) - if deviceGroupName == response.json()['name']: - self.ixnObj.logInfo(str([endpointObj]), timestamp=False) - return [endpointObj] - else: - protocolObjectHandleList.append(endpointObj) - else: - if any(protocol in x for x in protocols): - index = [index for index, item in enumerate(protocols) if protocol in item] - protocolObjectHandle = protocols[index[0]] - self.ixnObj.logInfo('Appending protocol: %s' % str([protocolObjectHandle]), timestamp=False) - protocolObjectHandleList.append(protocolObjectHandle) - - return protocolObjectHandleList + The protocol object handle in a list. + """ + protoReturnList = [] + protocol = protocol[0:1].capitalize() + protocol[1:] + if deviceGroupName is None: + topoObjList = self.getAllTopologyList() + for topoObj in topoObjList: + deviceGroupList = topoObj.DeviceGroup.find() + for deviceGroupObj in deviceGroupList: + try: + ipv4ProtocolResponse = getattr(deviceGroupObj.Ethernet.find().Ipv4.find(), + protocol) + if ipv4ProtocolResponse.find(): + protoObj = ipv4ProtocolResponse.find() + protoReturnList.append(protoObj) + + ipv6ProtocolResponse = getattr(deviceGroupObj.Ethernet.find().Ipv6.find(), + protocol) + if ipv6ProtocolResponse.find(): + protoObj = ipv6ProtocolResponse.find() + protoReturnList.append(protoObj) + l2ProtocolResponse = getattr(deviceGroupObj.Ethernet.find(), protocol) + if l2ProtocolResponse.find(): + protoObj = l2ProtocolResponse.find() + protoReturnList.append(protoObj) + except Exception as e: + print(e) + if deviceGroupObj.Ethernet.find(): + protoObj = deviceGroupObj.Ethernet.find() + protoReturnList.append(protoObj) + else: + ethernetObj = self.ixNetwork.Topology.find().DeviceGroup.find( + Name=deviceGroupName).Ethernet.find() + ipv4ProtocolResponse = getattr(ethernetObj.Ipv4.find(), protocol) + if ipv4ProtocolResponse.find(): + protoObj = ipv4ProtocolResponse.find() + protoReturnList.append(protoObj) + ipv6ProtocolResponse = getattr(ethernetObj.Ipv6.find(), protocol) + if ipv6ProtocolResponse.find(): + protoObj = ipv6ProtocolResponse.find() + protoReturnList.append(protoObj) + l2ProtocolResponse = getattr(ethernetObj, protocol) + if l2ProtocolResponse.find(): + protoObj = l2ProtocolResponse.find() + protoReturnList.append(protoObj) + + return protoReturnList def getProtocolObjFromHostIp(self, topologyList, protocol): """ @@ -4008,21 +3161,23 @@ def getProtocolObjFromHostIp(self, topologyList, protocol): This is an internal API used after calling self.getProtocolListByHostIpNgpf(). self.getProtocolListByHostIpNgpf() returns a list of Dicts containing all the topologies and its device group(s) that has a hostIp configured. - - Use this API to get the protocol object handle by passing in the NGPF endpoint protocol name. + + Use this API to get the protocol object handle by passing in the NGPF endpoint protocol + name. Parameters topologyList: : A returned list of Dicts from self.getProtocolListByHostIpNgpf(. protocol: : The NGPF endpoint protocol name. View below: - + protocol (These are the NGPF endpoint objects): - 'ancp', 'bfdv4Interface', 'bgpIpv4Peer', 'bgpIpv6Peer', 'dhcpv4relayAgent', 'dhcpv6relayAgent', - 'dhcpv4server', 'dhcpv6server', 'geneve', 'greoipv4', 'greoipv6', 'igmpHost', 'igmpQuerier', - 'lac', 'ldpBasicRouter', 'ldpBasicRouterV6', 'ldpConnectedInterface', 'ldpv6ConnectedInterface', - 'ldpTargetedRouter', 'ldpTargetedRouterV6', 'lns', 'mldHost', 'mldQuerier', 'ptp', - 'ipv6sr', 'openFlowController', 'openFlowSwitch', 'ospfv2', 'ospfv3', 'ovsdbcontroller', - 'ovsdbserver', 'pcc', 'pce', 'pcepBackupPCEs', 'pimV4Interface', 'pimV6Interface', 'ptp', - 'rsvpteIf', 'rsvpteLsps', 'tag', 'vxlan' + 'ancp', 'bfdv4Interface', 'bgpIpv4Peer', 'bgpIpv6Peer', 'dhcpv4relayAgent', + 'dhcpv6relayAgent', 'dhcpv4server', 'dhcpv6server', 'geneve', 'greoipv4', 'greoipv6', + 'igmpHost', 'igmpQuerier', 'lac', 'ldpBasicRouter', 'ldpBasicRouterV6', + 'ldpConnectedInterface', 'ldpv6ConnectedInterface', 'ldpTargetedRouter', + 'ldpTargetedRouterV6', 'lns', 'mldHost', 'mldQuerier', 'ptp', 'ipv6sr', + 'openFlowController', 'openFlowSwitch', 'ospfv2', 'ospfv3', 'ovsdbcontroller', + 'ovsdbserver', 'pcc', 'pce', 'pcepBackupPCEs', 'pimV4Interface', 'pimV6Interface', + 'ptp', 'rsvpteIf', 'rsvpteLsps', 'tag', 'vxlan' Example usage: protocolObj = Protocol(mainObj) @@ -4033,37 +3188,24 @@ def getProtocolObjFromHostIp(self, topologyList, protocol): This API returns a list of object handle(s). Example 1: - The protocol object handle in a list. For example: - ['/api/v1/sessions/1/ixnetwork/topology/2/deviceGroup/2/ethernet/1/ipv4/1/bgpIpv4Peer'] + The protocol object handle in a list. Example 2: - If there are multiple device groups and you want to get all the IPv4 endpoints that has the hostIp, - this API will return you a list: - ['/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1', - '/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/2/ethernet/1/ipv4/1'] + If there are multiple device groups and you want to get all the IPv4 endpoints that + has the hostIp, """ - self.ixnObj.logInfo('{0}...'.format('\ngetProtocolObjFromHostIp'), timestamp=False) objectHandle = [] - for element in topologyList: if protocol == 'topology': - return element['topology'] - - self.ixnObj.logInfo('\nTopologyGroup: {0}'.format(element['topology']), timestamp=False) - - for eachDeviceGroup in element['deviceGroup']: - self.ixnObj.logInfo('\n{0}'.format(eachDeviceGroup), timestamp=False) - - # Example: deviceGroupEndpoint are: - # /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1 - # /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1 - # /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1 - # /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/bgpIpv4Peer/1 - # /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv6/2/ldpv6ConnectedInterface/1 + objectHandle.append(element['topology']) + return objectHandle + + for eachDeviceGroup in element['deviceGroup']: for deviceGroupEndpoint in eachDeviceGroup: if protocol in ['deviceGroup', 'networkGroup', 'ethernet', 'ipv4', 'ipv6']: - match = re.search(r'(/api/v1/sessions/[0-9]+/ixnetwork/topology/[0-9]+.*%s/[0-9]+)$' % protocol, - deviceGroupEndpoint) + match = re.search( + r'(/api/v1/sessions/[0-9]+/ixnetwork/topology/[0-9]+.*%s/[0-9]+)$' + % protocol, deviceGroupEndpoint.href) if match: objectHandle.append(deviceGroupEndpoint) else: @@ -4071,14 +3213,14 @@ def getProtocolObjFromHostIp(self, topologyList, protocol): objectHandle.append(deviceGroupEndpoint) if objectHandle: - self.ixnObj.logInfo('\nObject handles: {0}'.format(str(objectHandle)), timestamp=False) return objectHandle def getPortsByProtocolNgpf(self, ngpfEndpointName): """ Description For IxNetwork NGPF only: - Based on the specified NGPF endpoint name, return all ports associated with the protocol. + Based on the specified NGPF endpoint name, return all ports associated with the + protocol. Parameter ngpfEndpointName: : See below for all the NGPF endpoint protocol names. @@ -4088,51 +3230,38 @@ def getPortsByProtocolNgpf(self, ngpfEndpointName): Example: [['10.219.117.101', '1', '1'], ['10.219.117.101', '1', '2']] Returns [] if no port is configured with the specified ngpfEndpointName - - ngpfEndpointName options: - 'ancp', 'bfdv4Interface', 'bgpIpv4Peer', 'bgpIpv6Peer', 'dhcpv4relayAgent', 'dhcpv6relayAgent', - 'dhcpv4server', 'dhcpv6server', 'geneve', 'greoipv4', 'greoipv6', 'igmpHost', 'igmpQuerier', - 'lac', 'ldpBasicRouter', 'ldpBasicRouterV6', 'ldpConnectedInterface', 'ldpv6ConnectedInterface', - 'ldpTargetedRouter', 'ldpTargetedRouterV6', 'lns', 'mldHost', 'mldQuerier', 'ptp', - 'ipv6sr', 'openFlowController', 'openFlowSwitch', 'ospfv2', 'ospfv3', 'ovsdbcontroller', - 'ovsdbserver', 'pcc', 'pce', 'pcepBackupPCEs', 'pimV4Interface', 'pimV6Interface', 'ptp', - 'rsvpteIf', 'rsvpteLsps', 'tag', 'vxlan' """ portList = [] - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/topology') - topologyList = ['%s/%s/%s' % (self.ixnObj.sessionUrl, 'topology', str(i["id"])) for i in response.json()] + topologyList = self.ixNetwork.Topology.find() for topology in topologyList: - response = self.ixnObj.get(topology+'/deviceGroup') - deviceGroupList = ['%s/%s/%s' % (topology, 'deviceGroup', str(i["id"])) for i in response.json()] + deviceGroupList = topology.DeviceGroup.find() for deviceGroup in deviceGroupList: - response = self.ixnObj.get(deviceGroup+'/ethernet') - ethernetList = ['%s/%s/%s' % (deviceGroup, 'ethernet', str(i["id"])) for i in response.json()] + ethernetList = deviceGroup.Ethernet.find() for ethernet in ethernetList: - response = self.ixnObj.get(ethernet+'/ipv4') - ipv4List = ['%s/%s/%s' % (ethernet, 'ipv4', str(i["id"])) for i in response.json()] - response = self.ixnObj.get(ethernet+'/ipv6') - ipv6List = ['%s/%s/%s' % (ethernet, 'ipv6', str(i["id"])) for i in response.json()] - for layer3Ip in ipv4List+ipv6List: - url = layer3Ip+'/'+ngpfEndpointName - print('\nProtocol URL:', url) - response = self.ixnObj.get(url) - if response.json() == []: + ipv4List = ethernet.Ipv4.find() + ipv6List = ethernet.Ipv6.find() + for layer3Ip in ipv4List + ipv6List: + ngpfEndpointName = ngpfEndpointName[0].capitalize() + ngpfEndpointName[1:] + ngpfEndpointResponse = getattr(layer3Ip, ngpfEndpointName) + ngpfEndpointObj = ngpfEndpointResponse.find() + if not ngpfEndpointObj: continue - - response = self.ixnObj.get(topology) - vportList = response.json()['vports'] - for vport in vportList: - response = self.ixnObj.get(self.ixnObj.httpHeader+vport) - assignedTo = response.json()['assignedTo'] - currentChassisIp = str(assignedTo.split(':')[0]) - currentCardNumber = str(assignedTo.split(':')[1]) - currentPortNumber = str(assignedTo.split(':')[2]) - currentPort = [currentChassisIp, currentCardNumber, currentPortNumber] - portList.append(currentPort) - self.ixnObj.logInfo('\tFound port configured: %s' % currentPort) + vportList = topology.Vports + vports = self.ixNetwork.Vport.find() + for vport in vports: + if vport.href == vportList[0]: + assignedTo = vport.AssignedTo + currentChassisIp = assignedTo.split(':')[0] + currentCardNumber = assignedTo.split(':')[1] + currentPortNumber = assignedTo.split(':')[2] + currentPort = [currentChassisIp, currentCardNumber, + currentPortNumber] + portList.append(currentPort) + self.ixnObj.logInfo('\tFound port configured: %s' % currentPort) return portList - def flapBgp(self, topologyName=None, bgpName=None, enable=True, ipInterfaceList='all', upTimeInSeconds=0, downTimeInSeconds=0): + def flapBgp(self, topologyName=None, bgpName=None, enable=True, ipInterfaceList='all', + upTimeInSeconds=0, downTimeInSeconds=0): """ Description Enable/Disable BGP flapping. @@ -4143,35 +3272,30 @@ def flapBgp(self, topologyName=None, bgpName=None, enable=True, ipInterfaceList= enable: : To enable or disable BGP flapping. ipInterfaceList: : A list of the local BGP IP interface to configure for flapping. upTimeInSeconds: : The up time for BGP to remain up before flapping it down. - downTimeInSeconds: : The down time for BGP to remain down before flapping it back up. + downTimeInSeconds: : The down time for BGP to remain down before flapping it backup. """ bgpObject = None - queryData = {'from': '/', - 'nodes': [{'node': 'topology', 'properties': ['name'], 'where': [{'property': 'name', 'regex': topologyName}]}, - {'node': 'deviceGroup', 'properties': [], 'where': []}, - {'node': 'ethernet', 'properties': [], 'where': []}, - {'node': 'ipv4', 'properties': [], 'where': []}, - {'node': 'ipv6', 'properties': [], 'where': []}, - {'node': 'bgpIpv4Peer', 'properties': ['name'], 'where': []}, - {'node': 'bgpIpv6Peer', 'properties': ['name'], 'where': []} - ]} - - queryResponse = self.ixnObj.query(data=queryData) - if queryResponse.json()['result'][0]['topology'][0]['name'] != topologyName: + + topologyObj = self.ixNetwork.Topology.find(Name=topologyName) + + if topologyObj is None: raise IxNetRestApiException('\nNo such Topology Group name found %s' % topologyName) - + try: - discoveredBgpName = queryResponse.json()['result'][0]['topology'][0]['deviceGroup'][0]['ethernet'][0]['ipv4'][0]['bgpIpv4Peer'][0]['name'] - if bgpName == discoveredBgpName: - bgpObject = queryResponse.json()['result'][0]['topology'][0]['deviceGroup'][0]['ethernet'][0]['ipv4'][0]['bgpIpv4Peer'][0]['href'] - except: - discoveredBgpName = queryResponse.json()['result'][0]['topology'][0]['deviceGroup'][0]['ethernet'][0]['ipv6'][0]['bgpIpv6Peer'][0]['name'] - if bgpName == discoveredBgpName: - bgpObject = queryResponse.json()['result'][0]['topology'][0]['deviceGroup'][0]['ethernet'][0]['ipv6'][0]['bgpIpv6Peer'][0]['href'] - - if bgpObject == None: + bgpIpv4PeerObj = topologyObj.DeviceGroup.find().Ethernet.find().Ipv4.find() \ + .BgpIpv4Peer.find() + if bgpName == bgpIpv4PeerObj.Name: + bgpObject = bgpIpv4PeerObj + except Exception as e: + print(e) + bgpIpv6PeerObj = topologyObj.DeviceGroup.find().Ethernet.find().Ipv4.find() \ + .BgpIpv6Peer.find() + if bgpName == bgpIpv6PeerObj.Name: + bgpObject = bgpIpv6PeerObj + + if bgpObject is None: raise IxNetRestApiException('\nNo such bgp name found %s' % bgpName) - + self.flapBgpPeerNgpf(bgpObjHandle=bgpObject, enable=enable, flapList=ipInterfaceList, uptime=upTimeInSeconds, downtime=downTimeInSeconds) @@ -4182,26 +3306,22 @@ def flapBgpPeerNgpf(self, bgpObjHandle, enable=True, flapList='all', uptime=0, d Parameters bgpObjHandle: The bgp object handle. - /api/v1/sessions//ixnetwork/topology//deviceGroup//ethernet//ipv4//bgpIpv4Peer/ enable: : Default = True flapList: 'all' or a list of IP addresses to enable/disable flapping. [['10.10.10.1', '10.10.10.8', ...] Default = 'all' uptime: : In seconds. Defaults = 0 downtime: : In seconds. Defaults = 0 - - Syntax - POST = /api/v1/sessions//ixnetwork/topology//deviceGroup//ethernet//ipv4//bgpIpv4Peer/ """ if flapList != 'all' and type(flapList) != list: - ipRouteListToFlap = flapList.split(' ') - - response = self.ixnObj.get(self.ixnObj.httpHeader+bgpObjHandle) - + flapList = flapList.split(' ') # Get the IP object from the bgpObjHandle - match = re.match('(/api.*)/bgp', bgpObjHandle) + match = re.match('(/api.*)/bgp', bgpObjHandle.href) ipObj = match.group(1) - + for eachIpObj in self.ixNetwork.Topology.find().DeviceGroup.find().Ethernet.find() \ + .Ipv4.find(): + if eachIpObj.href == ipObj: + ipObj = eachIpObj ipAddressList = self.getIpAddresses(ipObj) count = len(ipAddressList) @@ -4209,20 +3329,18 @@ def flapBgpPeerNgpf(self, bgpObjHandle, enable=True, flapList='all', uptime=0, d indexToFlapList = [] if flapList != 'all': for ipAddress in flapList: - # A custom list of indexes to enable/disable flapping based on the IP address index number. + # A custom list of indexes to enable/disable flapping based + # on the IP address index number. indexToFlapList.append(ipAddressList.index(ipAddress)) # Copy the same index list for uptime and downtime - indexUptimeList = indexToFlapList - indexDowntimeList = indexToFlapList - response = self.ixnObj.get(self.ixnObj.httpHeader+bgpObjHandle) - enableFlappingMultivalue = response.json()['flap'] - upTimeMultivalue = response.json()['uptimeInSec'] - downTimeMultivalue = response.json()['downtimeInSec'] + enableFlappingMultivalue = bgpObjHandle.Flap + upTimeMultivalue = bgpObjHandle.UptimeInSec + downTimeMultivalue = bgpObjHandle.DowntimeInSec - flappingResponse = self.ixnObj.getMultivalueValues(enableFlappingMultivalue) - uptimeResponse = self.ixnObj.getMultivalueValues(upTimeMultivalue) - downtimeResponse = self.ixnObj.getMultivalueValues(downTimeMultivalue) + flappingResponse = self.getMultivalueValues(enableFlappingMultivalue) + uptimeResponse = self.getMultivalueValues(upTimeMultivalue) + downtimeResponse = self.getMultivalueValues(downTimeMultivalue) # Flapping IP addresses flapOverlayList = [] @@ -4230,10 +3348,10 @@ def flapBgpPeerNgpf(self, bgpObjHandle, enable=True, flapList='all', uptime=0, d downtimeOverlayList = [] # Build a valueList of either "true" or "false" if flapList == 'all': - for counter in range(0,count): - if enable == True: + for counter in range(0, count): + if enable: flapOverlayList.append("true") - if enable == False: + if not enable: flapOverlayList.append("false") uptimeOverlayList.append(str(uptime)) downtimeOverlayList.append(str(downtime)) @@ -4242,21 +3360,20 @@ def flapBgpPeerNgpf(self, bgpObjHandle, enable=True, flapList='all', uptime=0, d # ['true', 'true', 'true'] currentFlappingValueList = flappingResponse # ['10', '10', '10'] - currentUptimeValueList = uptimeResponse + currentUptimeValueList = uptimeResponse # ['20', '20', '20'] currentDowntimeValueList = downtimeResponse indexCounter = 0 - for (eachFlapValue, eachUptimeValue, eachDowntimeValue) in zip(currentFlappingValueList, currentUptimeValueList, - currentDowntimeValueList): - # Leave the setting alone on this index position. User did not care to change this value. + for (eachFlapValue, eachUptimeValue, eachDowntimeValue) in zip( + currentFlappingValueList, currentUptimeValueList, currentDowntimeValueList): if indexCounter not in indexToFlapList: flapOverlayList.append(eachFlapValue) uptimeOverlayList.append(eachUptimeValue) downtimeOverlayList.append(eachDowntimeValue) else: # Change the value on this index position. - if enable == True: + if enable: flapOverlayList.append("true") else: flapOverlayList.append("false") @@ -4264,20 +3381,22 @@ def flapBgpPeerNgpf(self, bgpObjHandle, enable=True, flapList='all', uptime=0, d uptimeOverlayList.append(str(uptime)) downtimeOverlayList.append(str(downtime)) indexCounter += 1 + self.configMultivalue(enableFlappingMultivalue, 'valueList', + data={'values': flapOverlayList}) + self.configMultivalue(upTimeMultivalue, 'valueList', data={'values': uptimeOverlayList}) + self.configMultivalue(downTimeMultivalue, 'valueList', data={'values': downtimeOverlayList}) - self.ixnObj.patch(self.ixnObj.httpHeader + enableFlappingMultivalue+'/valueList', data={'values': flapOverlayList}) - self.ixnObj.patch(self.ixnObj.httpHeader + upTimeMultivalue+'/valueList', data={'values': uptimeOverlayList}) - self.ixnObj.patch(self.ixnObj.httpHeader + downTimeMultivalue+'/valueList', data={'values': downtimeOverlayList}) - - def flapBgpRoutesNgpf(self, prefixPoolObj, enable=True, ipRouteListToFlap='all', uptime=0, downtime=0, ip='ipv4'): + def flapBgpRoutesNgpf(self, prefixPoolObj, enable=True, ipRouteListToFlap='all', uptime=0, + downtime=0, ip='ipv4'): """ Description This API will enable or disable flapping on either all or a list of BGP IP routes. - If you are configuring routes to enable, you could also set the uptime and downtime in seconds. + If you are configuring routes to enable, you could also set the uptime and downtime in + seconds. Parameters - prefixPoolObj = The Network Group PrefixPool object that was returned by configNetworkGroup() - /api/v1/sessions//ixnetwork/topology//deviceGroup//networkGroup//ipv4PrefixPools/ + prefixPoolObj = The Network Group PrefixPool object that was returned by + configNetworkGroup() enable: True or False - Default = True ipRouteListToFlap: 'all' or a list of IP route addresses to enable/disable. @@ -4289,85 +3408,66 @@ def flapBgpRoutesNgpf(self, prefixPoolObj, enable=True, ipRouteListToFlap='all', - Defaults = 0 ip: ipv4 or ipv6 - Defaults = ipv4 - - Syntax - POST = For IPv4: http://{apiServerIp:port}/api/v1/sessions//ixnetwork/topology//deviceGroup//networkGroup//ipv4PrefixPools//bgpIPRouteProperty - - For IPv6: http://{apiServerIp:port}/api/v1/sessions//ixnetwork/topology//deviceGroup//networkGroup//ipv4PrefixPools//bgpV6IPRouteProperty """ - + routePropertyObj = None if ipRouteListToFlap != 'all' and type(ipRouteListToFlap) != list: ipRouteListToFlap = ipRouteListToFlap.split(' ') - # Get a list of configured IP route addresses - response = self.ixnObj.get(self.ixnObj.httpHeader+prefixPoolObj) - networkAddressList = response.json()['lastNetworkAddress'] + networkAddressList = prefixPoolObj.LastNetworkAddress count = len(networkAddressList) - - # Recreate an index list based on user defined ip route to enable/disable indexToFlapList = [] if ipRouteListToFlap != 'all': for ipRouteAddress in ipRouteListToFlap: - # A custom list of indexes to enable/disable flapping based on the IP address index number. indexToFlapList.append(networkAddressList.index(ipRouteAddress)) - # Copy the same index list for uptime and downtime - indexUptimeList = indexToFlapList - indexDowntimeList = indexToFlapList - if ip == 'ipv4': - response = self.ixnObj.get(self.ixnObj.httpHeader+prefixPoolObj+'/bgpIPRouteProperty') + routePropertyObj = prefixPoolObj.BgpIPRouteProperty.find() if ip == 'ipv6': - response = self.ixnObj.get(self.ixnObj.httpHeader+prefixPoolObj+'/bgpV6IPRouteProperty') + routePropertyObj = prefixPoolObj.BgpV6IPRouteProperty.find() - enableFlappingMultivalue = response.json()[0]['enableFlapping'] - upTimeMultivalue = response.json()[0]['uptime'] - downTimeMultivalue = response.json()[0]['downtime'] + enableFlappingMultivalue = routePropertyObj.EnableFlapping + upTimeMultivalue = routePropertyObj.Uptime + downTimeMultivalue = routePropertyObj.Downtime flappingResponse = self.ixnObj.getMultivalueValues(enableFlappingMultivalue) uptimeResponse = self.ixnObj.getMultivalueValues(upTimeMultivalue) downtimeResponse = self.ixnObj.getMultivalueValues(downTimeMultivalue) - # Flapping IP addresses flapOverlayList = [] uptimeOverlayList = [] downtimeOverlayList = [] - # Build a valueList of either "true" or "false" if ipRouteListToFlap == 'all': - for counter in range(0,count): - if enable == True: + for counter in range(0, count): + if enable: flapOverlayList.append("true") - if enable == False: + if not enable: flapOverlayList.append("false") uptimeOverlayList.append(str(uptime)) downtimeOverlayList.append(str(downtime)) if ipRouteListToFlap != 'all': currentFlappingValueList = flappingResponse[0] - currentUptimeValueList = uptimeResponse[0] + currentUptimeValueList = uptimeResponse[0] currentDowntimeValueList = downtimeResponse[0] indexCounter = 0 - for (eachFlapValue, eachUptimeValue, eachDowntimeValue) in zip(currentFlappingValueList, - currentUptimeValueList, currentDowntimeValueList): - # Leave the setting alone on this index position. User did not care to change this value. + for (eachFlapValue, eachUptimeValue, eachDowntimeValue) in zip( + currentFlappingValueList, currentUptimeValueList, currentDowntimeValueList): if indexCounter not in indexToFlapList: flapOverlayList.append(eachFlapValue) uptimeOverlayList.append(eachUptimeValue) downtimeOverlayList.append(eachDowntimeValue) else: - # Change the value on this index position. - if enable == True: + if enable: flapOverlayList.append("true") else: flapOverlayList.append("false") uptimeOverlayList.append(str(uptime)) downtimeOverlayList.append(str(downtime)) indexCounter += 1 - - # /topology/[1]/deviceGroup - self.ixnObj.patch(self.ixnObj.httpHeader + enableFlappingMultivalue+'/valueList', data={'values': flapOverlayList}) - self.ixnObj.patch(self.ixnObj.httpHeader + upTimeMultivalue+'/valueList', data={'values': uptimeOverlayList}) - self.ixnObj.patch(self.ixnObj.httpHeader + downTimeMultivalue+'/valueList', data={'values': downtimeOverlayList}) + self.configMultivalue(enableFlappingMultivalue, 'valueList', + data={'values': flapOverlayList}) + self.configMultivalue(upTimeMultivalue, 'valueList', data={'values': uptimeOverlayList}) + self.configMultivalue(downTimeMultivalue, 'valueList', data={'values': downtimeOverlayList}) def enableProtocolRouteRange(self, routerId, protocol, enable=False): """ @@ -4378,14 +3478,34 @@ def enableProtocolRouteRange(self, routerId, protocol, enable=False): routerId: all|List of routerId enable: True|False """ + topologyObj = None + vport = None deviceGroupObj = self.getDeviceGroupByRouterId(routerId) - response = self.ixnObj.get(self.ixnObj.httpHeader+deviceGroupObj+'/routerData') - routerIdMultivalue = response.json()[0]['routerId'] + for topology in self.ixNetwork.Topology.find(): + for deviceGroup in topology.DeviceGroup.find(): + if deviceGroup.href == deviceGroupObj.href: + topologyObj = topology + break + for eachVport in self.ixNetwork.Vport.find(): + if eachVport.href in topologyObj.Ports: + vport = eachVport + break + + RouterInstanceList = self.classicProtocolObj.getRouterInstanceByPortAndProtocol( + protocol=protocol, vport=vport) + if not RouterInstanceList: + raise IxNetRestApiException('No Router instance exists in protocol {0}'.format( + protocol)) + routerDataObj = deviceGroupObj.RouterData.find() + routerIdMultivalue = routerDataObj.RouterId routerIdList = self.ixnObj.getMultivalueValues(routerIdMultivalue) + for eachRouterInstance in RouterInstanceList: + RouteRangeInstanceList = eachRouterInstance.RouteRange.find() + for eachRouteRange in RouteRangeInstanceList: + eachRouteRange.Enabled = enable print(routerIdList) print(deviceGroupObj) - def startStopIpv4Ngpf(self, ipv4ObjList, action='start'): """ Description @@ -4393,18 +3513,17 @@ def startStopIpv4Ngpf(self, ipv4ObjList, action='start'): Parameters ipv4ObjList: Provide a list of one or more IPv4 object handles to start or stop. - Ex: ["/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1", ...] - action: start or stop """ if type(ipv4ObjList) != list: - raise IxNetRestApiException('startStopIpv4Ngpf error: The parameter ipv4ObjList must be a list of objects.') - - url = self.ixnObj.sessionUrl+'/topology/deviceGroup/ethernet/ipv4/operations/'+action - data = {'arg1': ipv4ObjList} + raise IxNetRestApiException('startStopIpv4Ngpf error: The parameter ipv4ObjList must ' + 'be a list of objects.') self.ixnObj.logInfo('startStopIpv4Ngpf: {0}'.format(action)) - response = self.ixnObj.post(url, data=data) - self.ixnObj.waitForComplete(response, url+'/'+response.json()['id']) + for eachIpv4Obj in ipv4ObjList: + if action == 'start': + eachIpv4Obj.Start() + if action == 'stop': + eachIpv4Obj.Stop() def startStopBgpNgpf(self, bgpObjList, action='start'): """ @@ -4413,18 +3532,17 @@ def startStopBgpNgpf(self, bgpObjList, action='start'): Parameters bgpObjList: Provide a list of one or more BGP object handles to start or stop. - Ex: ["/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/bgpIpv4Peer/1", ...] - action: start or stop """ if type(bgpObjList) != list: - raise IxNetRestApiException('startStopBgpNgpf error: The parameter bgpObjList must be a list of objects.') - - url = self.ixnObj.sessionUrl+'/topology/deviceGroup/ethernet/ipv4/bgpIpv4Peer/operations/'+action - data = {'arg1': bgpObjList} + raise IxNetRestApiException('startStopBgpNgpf error: The parameter bgpObjList must be a' + ' list of objects.') self.ixnObj.logInfo('startStopBgpNgpf: {0}'.format(action)) - response = self.ixnObj.post(url, data=data) - self.ixnObj.waitForComplete(response, url+'/'+response.json()['id']) + for eachBgpObj in bgpObjList: + if action == 'start': + eachBgpObj.Start() + if action == 'stop': + eachBgpObj.Stop() def startStopOspfNgpf(self, ospfObjList, action='start'): """ @@ -4432,19 +3550,19 @@ def startStopOspfNgpf(self, ospfObjList, action='start'): Start or stop OSPF protocol Parameters - bgpObjList: Provide a list of one or more OSPF object handles to start or stop. - Ex: ["/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/ospfv2/1", ...] - + bgpObjList: Provide a list of one or more OSPF object handles to + start or stop. action: start or stop """ if type(ospfObjList) != list: - raise IxNetRestApiException('startStopOspfNgpf error: The parameter ospfObjList must be a list of objects.') - - url = self.ixnObj.sessionUrl+'/topology/deviceGroup/ethernet/ipv4/ospfv2/operations/'+action - data = {'arg1': ospfObjList} + raise IxNetRestApiException('startStopOspfNgpf error: The parameter ospfObjList must ' + 'be a list of objects.') self.ixnObj.logInfo('startStopOspfNgpf: {0}'.format(action)) - response = self.ixnObj.post(url, data=data) - self.ixnObj.waitForComplete(response, url+'/'+response.json()['id']) + for eachOspfObj in ospfObjList: + if action == 'start': + eachOspfObj.Start() + if action == 'stop': + eachOspfObj.Stop() def startStopIgmpHostNgpf(self, igmpHostObjList, action='start'): """ @@ -4452,19 +3570,19 @@ def startStopIgmpHostNgpf(self, igmpHostObjList, action='start'): Start or stop IGMP Host protocol Parameters - igmpHostObjList: Provide a list of one or more IGMP host object handles to start or stop. - Ex: ["/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/igmpHost/1", ...] - - action: start or stop + igmpHostObjList: Provide a list of one or more IGMP host object handles to start or + stop. + action: start or stop """ if type(igmpHostObjList) != list: - raise IxNetRestApiException('igmpHostObjNgpf error: The parameter igmpHostObjList must be a list of objects.') - - url = self.ixnObj.sessionUrl+'/topology/deviceGroup/ethernet/ipv4/igmpHost/operations/'+action - data = {'arg1': igmpHostObjList} + raise IxNetRestApiException('igmpHostObjNgpf error: The parameter igmpHostObjList ' + 'must be a list of objects.') self.ixnObj.logInfo('startStopIgmpHostNgpf: {0}'.format(action)) - response = self.ixnObj.post(url, data=data) - self.ixnObj.waitForComplete(response, url+'/'+response.json()['id']) + for eachIgmpHostObj in igmpHostObjList: + if action == 'start': + eachIgmpHostObj.Start() + if action == 'stop': + eachIgmpHostObj.Stop() def startStopPimV4InterfaceNgpf(self, pimV4ObjList, action='start'): """ @@ -4473,19 +3591,18 @@ def startStopPimV4InterfaceNgpf(self, pimV4ObjList, action='start'): Parameters pimV4ObjList: Provide a list of one or more PIMv4 object handles to start or stop. - Ex: ["/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/pimV4Interface/1", ...] - action: start or stop """ if type(pimV4ObjList) != list: - raise IxNetRestApiException('startStopPimV4InterfaceNgpf error: The parameter pimv4ObjList must be a list of objects.') - - url = self.ixnObj.sessionUrl+'/topology/deviceGroup/ethernet/ipv4/pimV4Interface/operations/'+action - data = {'arg1': pimV4ObjList} + raise IxNetRestApiException('startStopPimV4InterfaceNgpf error: The parameter ' + 'pimv4ObjList must be a list of objects.') self.ixnObj.logInfo('startStopPimV4InterfaceNgpf: {0}'.format(action)) self.ixnObj.logInfo('\t%s' % pimV4ObjList) - response = self.ixnObj.post(url, data=data) - self.ixnObj.waitForComplete(response, url+'/'+response.json()['id']) + for eachPimV4Obj in pimV4ObjList: + if action == 'start': + eachPimV4Obj.Start() + if action == 'stop': + eachPimV4Obj.Stop() def startStopMldHostNgpf(self, mldHostObjList, action='start'): """ @@ -4494,19 +3611,18 @@ def startStopMldHostNgpf(self, mldHostObjList, action='start'): Parameters mldHostObjList: Provide a list of one or more mldHost object handles to start or stop. - Ex: ["/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv6/2/mldHost/1", ...] - action: start or stop """ if type(mldHostObjList) != list: - raise IxNetRestApiException('startStopMldHostNgpf error: The parameter mldHostObjList must be a list of objects.') - - url = self.ixnObj.sessionUrl+'/topology/deviceGroup/ethernet/ipv6/mldHost/operations/'+action - data = {'arg1': mldHostObjList} + raise IxNetRestApiException('startStopMldHostNgpf error: The parameter mldHostObjList ' + 'must be a list of objects.') self.ixnObj.logInfo('startStopMldHostNgpf: {0}'.format(action)) self.ixnObj.logInfo('\t%s' % mldHostObjList) - response = self.ixnObj.post(url, data=data) - self.ixnObj.waitForComplete(response, url+'/'+response.json()['id']) + for eachMldHostObj in mldHostObjList: + if action == 'start': + eachMldHostObj.Start() + if action == 'stop': + eachMldHostObj.Stop() def startStopIsisL3Ngpf(self, isisObjList, action='start'): """ @@ -4515,19 +3631,18 @@ def startStopIsisL3Ngpf(self, isisObjList, action='start'): Parameters isisObjList: Provide a list of one or more mldHost object handles to start or stop. - Ex: ["/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/isisL3/3", ...] - - action = start or stop + action = start or stop """ if type(isisObjList) != list: - raise IxNetRestApiException('startStopIsisL3Ngpf error: The parameter isisObjList must be a list of objects.') - - url = self.ixnObj.sessionUrl+'/topology/deviceGroup/ethernet/isisL3/operations/'+action - data = {'arg1': isisObjList} + raise IxNetRestApiException('startStopIsisL3Ngpf error: The parameter isisObjList ' + 'must be a list of objects.') self.ixnObj.logInfo('startStopIsisL3Ngpf: {0}'.format(action)) self.ixnObj.logInfo('\t%s' % isisObjList) - response = self.ixnObj.post(url, data=data) - self.ixnObj.waitForComplete(response, url+'/'+response.json()['id']) + for eachIsisObj in isisObjList: + if action == 'start': + eachIsisObj.Start() + if action == 'stop': + eachIsisObj.Stop() def startStopLdpBasicRouterNgpf(self, ldpObjList, action='start'): """ @@ -4535,20 +3650,18 @@ def startStopLdpBasicRouterNgpf(self, ldpObjList, action='start'): Start or stop LDP Basic Router protocol. Parameters - ldpObjList: Provide a list of one or more ldpBasicRouter object handles to start or stop. - Ex: ["/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ldpBasicRouter/3", ...] - - action = start or stop + ldpObjList: Provide a list of one or more ldpBasicRouter object handles to start or + stop. + action = start or stop """ if type(ldpObjList) != list: - raise IxNetRestApiException('startStopLdpBasicRouterNgpf error: The parameter ldpObjList must be a list of objects.') - - url = self.ixnObj.sessionUrl+'/topology/deviceGroup/ldpBasicRouter/operations/'+action - data = {'arg1': ldpObjList} - self.ixnObj.logInfo('startStopLdpBasicRouterNgpf: {0}'.format(action)) - self.ixnObj.logInfo('\t%s' % ldpObjList) - response = self.ixnObj.post(url, data=data) - self.ixnObj.waitForComplete(response, url+'/'+response.json()['id']) + raise IxNetRestApiException('startStopLdpBasicRouterNgpf error: The parameter ' + 'ldpObjList must be a list of objects.') + for eachLdpObj in ldpObjList: + if action == 'start': + eachLdpObj.Start() + if action == 'stop': + eachLdpObj.Stop() def enableDisableIgmpGroupRangeNgpf(self, protocolSessionUrl, groupRangeList, action='disable'): """ @@ -4557,8 +3670,8 @@ def enableDisableIgmpGroupRangeNgpf(self, protocolSessionUrl, groupRangeList, ac 1> Get a list of all the Multicast group range IP addresses. 2> Get the multivalue list of ACTIVE STATE group ranges. - 3> Loop through the user list "groupRangeList" and look - for the index position of the specified group range IP address. + 3> Loop through the user list "groupRangeList" and look for the index position of + the specified group range IP address. 4> Using overlay to enable|disable the index value. Note: If an overlay is not created, then create one by: @@ -4566,7 +3679,7 @@ def enableDisableIgmpGroupRangeNgpf(self, protocolSessionUrl, groupRangeList, ac - And add an Overlay. Parameters - protocolSessionUrl: http://{apiServerIp:port}/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/igmpHost/1 + protocolSessionUrl groupRangeList: A list of multicast group range addresses to disable. Example: ['225.0.0.1', '225.0.0.5'] action: disable or enable @@ -4576,22 +3689,10 @@ def enableDisableIgmpGroupRangeNgpf(self, protocolSessionUrl, groupRangeList, ac enableDisable = 'false' else: enableDisable = 'true' - - url = protocolSessionUrl+'/igmpMcastIPv4GroupList' - response = self.ixnObj.get(url) - # /api/v1/sessions/1/ixnetwork/multivalue/59 - - # Get startMcastAddr multivalue to get a list of all the configured Group Range IP addresses. - groupRangeAddressMultivalue = response.json()['startMcastAddr'] - # Get the active multivalue to do the overlay on top of. - activeMultivalue = response.json()['active'] - - # Getting the list of Group Range IP addresses. - response = self.ixnObj.get(self.ixnObj.httpHeader+groupRangeAddressMultivalue) - - # groupRangeValues are multicast group ranges: - # [u'225.0.0.1', u'225.0.0.2', u'225.0.0.3', u'225.0.0.4', u'225.0.0.5'] - groupRangeValues = response.json()['values'] + igmpMcastIPv4GroupListObj = protocolSessionUrl.IgmpMcastIPv4GroupList + groupRangeAddressMultivalue = igmpMcastIPv4GroupListObj.StartMcastAddr + activeMultivalue = igmpMcastIPv4GroupListObj.Active + groupRangeValues = self.ixnObj.getMultivalueValues(groupRangeAddressMultivalue) print('\nConfigured groupRangeValues:', groupRangeValues) listOfIndexesToDisable = [] @@ -4600,26 +3701,25 @@ def enableDisableIgmpGroupRangeNgpf(self, protocolSessionUrl, groupRangeList, ac index = groupRangeValues.index(groupRangeIp) listOfIndexesToDisable.append(index) - if listOfIndexesToDisable == []: - raise IxNetRestApiException('disableIgmpGroupRangeNgpf Error: No multicast group range ip address found on your list') + if not listOfIndexesToDisable: + raise IxNetRestApiException('disableIgmpGroupRangeNgpf Error: No multicast group ' + 'range ip address found on your list') for index in listOfIndexesToDisable: - currentOverlayUrl = self.ixnObj.httpHeader+activeMultivalue+'/overlay' - # http://192.168.70.127:11009/api/v1/sessions/1/ixnetwork/multivalue/5/overlay - # NOTE: Index IS NOT zero based. - self.ixnObj.logInfo('enableDisableIgmpGroupRangeNgpf: %s: %s' % (action, groupRangeValues[index])) - response = self.ixnObj.post(currentOverlayUrl, data={'index': index+1, 'value': enableDisable}) + self.ixnObj.logInfo('enableDisableIgmpGroupRangeNgpf: %s: %s' % + (action, groupRangeValues[index])) + activeMultivalue.Overlay(index + 1, enableDisable) def enableDisableMldGroupNgpf(self, protocolSessionUrl, groupRangeList, action='disable'): """ Description: - For IPv6 only. To enable or disable specific multicast group range IP addresses by using - overlay. + For IPv6 only. To enable or disable specific multicast group range IP addresses by + using overlay. 1> Get a list of all the Multicast group range IP addresses. 2> Get the multivalue list of ACTIVE STATE group ranges. - 3> Loop through the user list "groupRangeList" and look - for the index position of the specified group range IP address. + 3> Loop through the user list "groupRangeList" and look for the index position of + the specified group range IP address. 4> Using overlay to enable|disable the index value. Note: If an overlay is not created, then create one by: @@ -4627,7 +3727,7 @@ def enableDisableMldGroupNgpf(self, protocolSessionUrl, groupRangeList, action=' - And add an Overlay. Parameters - protocolSessionUrl: http://{apiServerIp:port}/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/igmpHost/1 + protocolSessionUrl groupRangeList: A list of multicast group range addresses to disable. Example: ['ff03::1', 'ff03::2'] action: disable or enable @@ -4636,22 +3736,11 @@ def enableDisableMldGroupNgpf(self, protocolSessionUrl, groupRangeList, action=' enableDisable = 'false' else: enableDisable = 'true' + mldMcastIPv6GroupListObj = protocolSessionUrl.MldMcastIPv6GroupList + groupRangeAddressMultivalue = mldMcastIPv6GroupListObj.StartMcastAddr + activeMultivalue = mldMcastIPv6GroupListObj.Active + groupRangeValues = self.getMultivalueValues(groupRangeAddressMultivalue) - url = protocolSessionUrl+'/mldMcastIPv6GroupList' - response = self.ixnObj.get(url) - # /api/v1/sessions/1/ixnetwork/multivalue/59 - - # Get startMcastAddr multivalue to get a list of all the configured Group Range IP addresses. - groupRangeAddressMultivalue = response.json()['startMcastAddr'] - # Get the active multivalue to do the overlay on top of. - activeMultivalue = response.json()['active'] - - # Getting the list of Group Range IP addresses. - response = self.ixnObj.get(self.ixnObj.httpHeader+groupRangeAddressMultivalue) - - # groupRangeValues are multicast group ranges: - # ['ff03::1', 'ff03::2'] - groupRangeValues = response.json()['values'] self.ixnObj.logInfo('Configured groupRangeValues: %s' % groupRangeValues) listOfIndexesToDisable = [] @@ -4660,71 +3749,53 @@ def enableDisableMldGroupNgpf(self, protocolSessionUrl, groupRangeList, action=' index = groupRangeValues.index(groupRangeIp) listOfIndexesToDisable.append(index) - if listOfIndexesToDisable == []: - raise IxNetRestApiException('disableMldGroupNgpf Error: No multicast group range ip address found on your list') + if not listOfIndexesToDisable: + raise IxNetRestApiException('disableMldGroupNgpf Error: No multicast group range ip ' + 'address found on your list') for index in listOfIndexesToDisable: - currentOverlayUrl = self.ixnObj.httpHeader+activeMultivalue+'/overlay' - # http://192.168.70.127:11009/api/v1/sessions/1/ixnetwork/multivalue/5/overlay - # NOTE: Index IS NOT zero based. - self.ixnObj.logInfo('enableDisableMldGroupNgpf: %s: %s' % (action, groupRangeValues[index])) - response = self.ixnObj.post(currentOverlayUrl, data={'index': index+1, 'value': enableDisable}) + self.ixnObj.logInfo('enableDisableMldGroupNgpf: %s: %s' % (action, + groupRangeValues[index])) + activeMultivalue.Overlay(index + 1, enableDisable) - def sendIgmpJoinLeaveNgpf(self, routerId=None, igmpHostUrl=None, multicastIpAddress=None, action='join'): + def sendIgmpJoinLeaveNgpf(self, routerId=None, igmpHostUrl=None, multicastIpAddress=None, + action='join'): """ Description Send IGMP joins or leaves. - A IGMP host object is acceptable. If you don't know the IGMP host object, use Device Group RouterID. - Since a Device Group could have many routerID, you could state one of them. + A IGMP host object is acceptable. If you don't know the IGMP host object, use + Device Group RouterID. Since a Device Group could have many routerID, you could state + one of them. If multicastIpAddress is 'all', this will send IGMP join on all multicast addresses. Else, provide a list of multicast IP addresses to send join. Parameters routerId: The Device Group Router ID address. - igmpHostUrl: '/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/igmpHost/1' + igmpHostUrl multicastIpAddress: 'all' or a list of multicast IP addresses to send join. Example: ['225.0.0.3', '225.0.0.4'] action: join|leave """ - if action == 'join': - action = 'igmpjoingroup' - if action == 'leave': - action = 'igmpleavegroup' - - # In case somebody passes in http://{ip:port}. All this function needs is the Rest API. - if igmpHostUrl: - match = re.match('http://.*(/api.*)', igmpHostUrl) - if match: - igmpHostUrl = match.group(1) if routerId: deviceGroupObj = self.getDeviceGroupByRouterId(routerId=routerId) if deviceGroupObj == 0: raise IxNetRestApiException('No Device Group found for router ID: %s' % routerId) - queryData = {'from': deviceGroupObj, - 'nodes': [{'node': 'routerData', 'properties': [], 'where': []}, - {'node': 'ethernet', 'properties': [], 'where': []}, - {'node': 'ipv4', 'properties': [], 'where': []}, - {'node': 'igmpHost', 'properties': [], 'where': []}, - ]} - queryResponse = self.ixnObj.query(data=queryData) - routerIdObj = queryResponse.json()['result'][0]['routerData'][0]['href'] - response = self.ixnObj.get(self.ixnObj.httpHeader+routerIdObj) - routerIdMultivalue = response.json()['routerId'] - routerIdList = self.ixnObj.getMultivalueValues(routerIdMultivalue, silentMode=True) + routerDataObj = deviceGroupObj.RouterData.find() + routerIdMultivalue = routerDataObj.RouterId + routerIdList = self.getMultivalueValues(routerIdMultivalue) if routerId in routerIdList: - igmpHostUrl = queryResponse.json()['result'][0]['ethernet'][0]['ipv4'][0]['igmpHost'][0]['href'] - - # Based on the list of multicastIpAddress, get all their indexes. - response = self.ixnObj.get(self.ixnObj.httpHeader+igmpHostUrl+'/igmpMcastIPv4GroupList') - startMcastAddrMultivalue = response.json()['startMcastAddr'] + igmpHostUrl = deviceGroupObj.Ethernet.find().Ipv4.find().IgmpHost.find() + igmpMcastIPv4GroupListObj = igmpHostUrl.IgmpMcastIPv4GroupList + startMcastAddrMultivalue = igmpMcastIPv4GroupListObj.StartMcastAddr listOfConfiguredMcastIpAddresses = self.ixnObj.getMultivalueValues(startMcastAddrMultivalue) - self.ixnObj.logInfo('sendIgmpJoinNgpf: List of configured Mcast IP addresses: %s' % listOfConfiguredMcastIpAddresses) - if listOfConfiguredMcastIpAddresses == []: + self.ixnObj.logInfo('sendIgmpJoinNgpf: List of configured Mcast IP addresses: %s' % + listOfConfiguredMcastIpAddresses) + if not listOfConfiguredMcastIpAddresses: raise IxNetRestApiException('sendIgmpJoinNgpf: No Mcast IP address configured') if multicastIpAddress == 'all': @@ -4736,70 +3807,56 @@ def sendIgmpJoinLeaveNgpf(self, routerId=None, igmpHostUrl=None, multicastIpAddr indexListToSend = [] for eachMcastAddress in listOfMcastAddresses: index = listOfConfiguredMcastIpAddresses.index(eachMcastAddress) - indexListToSend.append(index+1) - - url = igmpHostUrl+'/igmpMcastIPv4GroupList/operations/%s' % action - data = {'arg1': [igmpHostUrl+'/igmpMcastIPv4GroupList'], 'arg2': indexListToSend} - self.ixnObj.logInfo('sendIgmpJoinNgpf: %s' % url) + indexListToSend.append(index + 1) self.ixnObj.logInfo('\t%s' % multicastIpAddress) - response = self.ixnObj.post(self.ixnObj.httpHeader+url, data=data) - self.ixnObj.waitForComplete(response, url+response.json()['id']) + if action == 'join': + igmpMcastIPv4GroupListObj.IgmpJoinGroup(indexListToSend) + if action == 'leave': + igmpMcastIPv4GroupListObj.IgmpLeaveGroup(indexListToSend) - def sendPimV4JoinLeaveNgpf(self, routerId=None, pimObj=None, multicastIpAddress=None, action='join'): + def sendPimV4JoinLeaveNgpf(self, routerId=None, pimObj=None, multicastIpAddress=None, + action='join'): """ Description Send PIMv4 joins or leaves. - A PIM host object is acceptable. If you don't know the PIM host object, use Device Group RouterID. - Since a Device Group could have many routerID, you could state one of them. + A PIM host object is acceptable. If you don't know the PIM host object, use Device + Group RouterID. Since a Device Group could have many routerID, you could state one of + them. If multicastIpAddress is 'all', this will send join on all multicast addresses. Else, provide a list of multicast IP addresses to send join|leave. NOTE: - Current support: Each IP host multicast group address must be unique. IP hosts could send the same - multicast group address, but this API only supports unique multicast group address. - + Current support: Each IP host multicast group address must be unique. IP hosts could + send the same multicast group address, but this API only supports + unique multicast group address. + Parameters routerId: The Device Group Router ID address. - pimObj: '/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/pimV4Interface/1/pimV4JoinPruneList' + pimObj multicastIpAddress: 'all' or a list of multicast IP addresses to send join. Example: ['225.0.0.3', '225.0.0.4'] action: join|leave """ - # In case somebody passes in http://{ip:port}. All this function needs is the Rest API. - if pimObj: - match = re.match('http://.*(/api.*)', pimObj) - if match: - pimObj = match.group(1) - if routerId: deviceGroupObj = self.getDeviceGroupByRouterId(routerId=routerId) if deviceGroupObj == 0: raise IxNetRestApiException('No Device Group found for router ID: %s' % routerId) - queryData = {'from': deviceGroupObj, - 'nodes': [{'node': 'routerData', 'properties': [], 'where': []}, - {'node': 'ethernet', 'properties': [], 'where': []}, - {'node': 'ipv4', 'properties': [], 'where': []}, - {'node': 'pimV4Interface', 'properties': [], 'where': []} - ]} - queryResponse = self.ixnObj.query(data=queryData) - routerIdObj = queryResponse.json()['result'][0]['routerData'][0]['href'] - response = self.ixnObj.get(self.ixnObj.httpHeader+routerIdObj) - routerIdMultivalue = response.json()['routerId'] - routerIdList = self.ixnObj.getMultivalueValues(routerIdMultivalue, silentMode=True) + routerDataObj = deviceGroupObj.RouterData.find() + routerIdMultivalue = routerDataObj.RouterId + routerIdList = self.getMultivalueValues(routerIdMultivalue) if routerId in routerIdList: - pimObj = queryResponse.json()['result'][0]['ethernet'][0]['ipv4'][0]['pimV4Interface'][0]['href'] + pimObj = deviceGroupObj.Ethernet.find().Ipv4.find().PimV4Interface.find() + pimV4JoinPruneList = pimObj.PimV4JoinPruneList - # Based on the list of multicastIpAddress, get all their indexes. - response = self.ixnObj.get(self.ixnObj.httpHeader+pimObj+'/pimV4JoinPruneList') - - startMcastAddrMultivalue = response.json()['groupV4Address'] + startMcastAddrMultivalue = pimV4JoinPruneList.groupV4Address listOfConfiguredMcastIpAddresses = self.ixnObj.getMultivalueValues(startMcastAddrMultivalue) - self.ixnObj.logInfo('sendPimV4JoinNgpf: List of configured Mcast IP addresses: %s' % listOfConfiguredMcastIpAddresses) - if listOfConfiguredMcastIpAddresses == []: + self.ixnObj.logInfo('sendPimV4JoinNgpf: List of configured Mcast IP addresses: %s' % + listOfConfiguredMcastIpAddresses) + if not listOfConfiguredMcastIpAddresses: raise IxNetRestApiException('sendPimV4JoinNgpf: No Mcast IP address configured') if multicastIpAddress == 'all': @@ -4811,52 +3868,37 @@ def sendPimV4JoinLeaveNgpf(self, routerId=None, pimObj=None, multicastIpAddress= indexListToSend = [] for eachMcastAddress in listOfMcastAddresses: index = listOfConfiguredMcastIpAddresses.index(eachMcastAddress) - indexListToSend.append(index+1) - - url = pimObj+'/pimV4JoinPruneList/operations/%s' % action - data = {'arg1': [pimObj+'/pimV4JoinPruneList'], 'arg2': indexListToSend} - self.ixnObj.logInfo('sendPimv4JoinNgpf: %s' % url) + indexListToSend.append(index + 1) self.ixnObj.logInfo('\t%s' % multicastIpAddress) - response = self.ixnObj.post(self.ixnObj.httpHeader+url, data=data) - self.ixnObj.waitForComplete(response, url+response.json()['id']) + if action == 'join': + pimV4JoinPruneList.Join(indexListToSend) + if action == 'leave': + pimV4JoinPruneList.Leave(indexListToSend) def sendMldJoinNgpf(self, mldObj, ipv6AddressList): """ Description For IPv6 only. - This API will take the MLD object and loop through all the configured ports - looking for the specified ipv6Address to send a join. + This API will take the MLD object and loop through all the configured ports looking + for the specified ipv6Address to send a join. Parameter - ipv6AddressList: 'all' or a list of IPv6 addresses that must be EXACTLY how it is configured on the GUI. - """ - # Loop all port objects to get user specified IPv6 address to send the join. - portObjectList = mldObj+'/mldMcastIPv6GroupList/port' - response = self.ixnObj.get(portObjectList) - - for eachPortIdDetails in response.json(): - currentPortId = eachPortIdDetails['id'] - # For each ID, get the 'startMcastAddr' multivalue - startMcastAddrMultivalue = eachPortIdDetails['startMcastAddr'] - - # Go to the multivalue and get the 'values' - response = self.ixnObj.get(self.ixnObj.httpHeader+startMcastAddrMultivalue) - listOfConfiguredGroupIpAddresses = response.json()['values'] - if ipv6AddressList == 'all': - listOfGroupAddresses = listOfConfiguredGroupIpAddresses - else: - listOfGroupAddresses = ipv6AddressList - - for eachSpecifiedIpv6Addr in listOfGroupAddresses: - if eachSpecifiedIpv6Addr in listOfConfiguredGroupIpAddresses: - # if 'values' match ipv4Address, do a join on: - # http://192.168.70.127.:11009/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv6/2/mldHost/1/mldMcastIPv6GroupList/port/1/operations/mldjoingroup - # arg1: port/1 object - url = mldObj+'/mldMcastIPv6GroupList/port/%s/operations/mldjoingroup' % currentPortId - portIdObj = mldObj+'/mldMcastIPv6GroupList/port/%s' % currentPortId - # portIdObj = http:/{apiServerIp:port}/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv6/2/mldHost/1/mldMcastIPv6GroupList/port/1 - response = self.ixnObj.post(url, data={'arg1': [portIdObj]}) - self.ixnObj.waitForComplete(response, url+response.json()['id']) + ipv6AddressList: 'all' or a list of IPv6 addresses that must be EXACTLY how it is + configured on the GUI. + """ + mldMcastIPv6GroupListObj = mldObj.MldMcastIPv6GroupList + startMcastAddrMultivalue = mldMcastIPv6GroupListObj.StartMcastAddr + listOfConfiguredGroupIpAddresses = self.getMultivalueValues(startMcastAddrMultivalue) + if ipv6AddressList == 'all': + listOfGroupAddresses = listOfConfiguredGroupIpAddresses + else: + listOfGroupAddresses = ipv6AddressList + + indexListToSend = [] + for eachSpecifiedIpv6Addr in listOfGroupAddresses: + index = listOfConfiguredGroupIpAddresses.index(eachSpecifiedIpv6Addr) + indexListToSend.append(index + 1) + mldMcastIPv6GroupListObj.MldJoinGroup(indexListToSend) def sendMldLeaveNgpf(self, mldObj, ipv6AddressList): """ @@ -4866,35 +3908,23 @@ def sendMldLeaveNgpf(self, mldObj, ipv6AddressList): looking for the specified ipv6Address to send a leave. Parameters - mldObj: http://{apiServerIp:port}/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv6/2/mldHost/1 - ipv6AddressList: 'all' or a list of IPv6 addresses that must be EXACTLY how it is configured on the GUI. - """ - # Loop all port objects to get user specified IPv6 address to send the leave. - portObjectList = mldObj+'/mldMcastIPv6GroupList/port' - response = post.get(portObjectList) - for eachPortIdDetails in response.json(): - currentPortId = eachPortIdDetails['id'] - # For each ID, get the 'startMcastAddr' multivalue - startMcastAddrMultivalue = eachPortIdDetails['startMcastAddr'] - - # Go to the multivalue and get the 'values' - response = self.ixnObj.get(self.ixnObj.httpHeader+startMcastAddrMultivalue) - listOfConfiguredGroupIpAddresses = response.json()['values'] - if ipv6AddressList == 'all': - listOfGroupAddresses = listOfConfiguredGroupIpAddresses - else: - listOfGroupAddresses = ipv6AddressList - - for eachSpecifiedIpv6Addr in listOfGroupAddresses: - if eachSpecifiedIpv6Addr in listOfConfiguredGroupIpAddresses: - # if 'values' match ipv4Address, do a join on: - # http://{apiServerIp:port}/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv6/2/mldHost/1/mldMcastIPv6GroupList/port/1/operations/mldjoingroup - # arg1: port/1 object - url = mldObj+'/mldMcastIPv6GroupList/port/%s/operations/mldleavegroup' % currentPortId - portIdObj = mldObj+'/mldMcastIPv6GroupList/port/%s' % currentPortId - # portIdObj = http://{apiServerIp:port}/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv6/2/mldHost/1/mldMcastIPv6GroupList/port/1 - response = self.ixnObj.post(url, data={'arg1': [portIdObj]}) - self.ixnObj.waitForComplete(response, url+response.json()['id']) + mldObj + ipv6AddressList: 'all' or a list of IPv6 addresses that must be EXACTLY how it is + configured on the GUI. + """ + mldMcastIPv6GroupListObj = mldObj.MldMcastIPv6GroupList + startMcastAddrMultivalue = mldMcastIPv6GroupListObj.StartMcastAddr + listOfConfiguredGroupIpAddresses = self.getMultivalueValues(startMcastAddrMultivalue) + if ipv6AddressList == 'all': + listOfGroupAddresses = listOfConfiguredGroupIpAddresses + else: + listOfGroupAddresses = ipv6AddressList + + indexListToSend = [] + for eachSpecifiedIpv6Addr in listOfGroupAddresses: + index = listOfConfiguredGroupIpAddresses.index(eachSpecifiedIpv6Addr) + indexListToSend.append(index + 1) + mldMcastIPv6GroupListObj.MldLeaveGroup(indexListToSend) def getSessionStatus(self, protocolObj): """ @@ -4903,25 +3933,23 @@ def getSessionStatus(self, protocolObj): Parameter protocolObj: (str): The protocol object. - /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/bgpIpv4Peer/1 + Returns Success: A list of up|down session status. Failed: An empty list """ - response = self.ixnObj.get(self.ixnObj.httpHeader+protocolObj+'?includes=sessionStatus', silentMode=True) - return response.json()['sessionStatus'] + return protocolObj.SessionStatus def getIpAddresses(self, ipObj): """ Description Get the configured ipv4|ipv6 addresses in a list. - + Parameter - ipObj: : The IPv4|Ipv6 object: /api/v1/sessions/1/ixnetwork/topology/2/deviceGroup/1/ethernet/1/ipv4/1 + ipObj """ - response = self.ixnObj.get(self.ixnObj.httpHeader+ipObj) - multivalueObj = response.json()['address'] - response = self.ixnObj.getMultivalueValues(multivalueObj) + multivalueObj = ipObj.Address + response = self.getMultivalueValues(multivalueObj) return response def showTopologies(self): @@ -4930,250 +3958,240 @@ def showTopologies(self): Show the NGPF configuration: Topology Groups, Device Groups, Mac Addreseses, VLAN ID, IPv4, IPv6, protocol sessions. """ - queryData = {'from': '/', - 'nodes': [{'node': 'topology', 'properties': ['name', 'status', 'vports', 'ports'], 'where': []}, - {'node': 'deviceGroup', 'properties': ['name', 'status'], 'where': []}, - {'node': 'networkGroup','properties': ['name', 'multiplier'], 'where': []}, - {'node': 'ethernet', 'properties': ['name', 'status', 'sessionStatus', 'enableVlans', 'mac'], 'where': []}, - {'node': 'vlan', 'properties': ['name', 'vlanId', 'priority'], 'where': []}, - {'node': 'ipv4', 'properties': ['name', 'status', 'sessionStatus', 'address', 'gatewayIp', 'prefix'], 'where': []}, - {'node': 'ipv6', 'properties': ['name', 'status', 'sessionStatus', 'address', 'gatewayIp', 'prefix'], 'where': []}, - {'node': 'bgpIpv4Peer', 'properties': ['name', 'status', 'sessionStatus', 'dutIp', 'type', 'localIpv4Ver2', 'localAs2Bytes', - 'holdTimer', 'flap', 'uptimeInSec', 'downtimeInSec'], 'where': []}, - {'node': 'bgpIpv6Peer', 'properties': ['name', 'status', 'sessionStatus'], 'where': []}, - {'node': 'ospfv2', 'properties': ['name', 'status', 'sessionStatus'], 'where': []}, - {'node': 'ospfv3', 'properties': ['name', 'status', 'sessionStatus'], 'where': []}, - {'node': 'igmpHost', 'properties': ['name', 'status', 'sessionStatus'], 'where': []}, - {'node': 'igmpQuerier', 'properties': ['name', 'status', 'sessionStatus'], 'where': []}, - {'node': 'vxlan', 'properties': ['name', 'status', 'sessionStatus'], 'where': []}, - ] - } - - queryResponse = self.ixnObj.query(data=queryData, silentMode=True) - self.ixnObj.logInfo('', timestamp=False) - for topology in queryResponse.json()['result'][0]['topology']: - self.ixnObj.logInfo('TopologyGroup: {0} Name: {1}'.format(topology['id'], topology['name']), timestamp=False) - self.ixnObj.logInfo(' Status: {0}'.format(topology['status']), timestamp=False) - - buildNumber = float(self.ixnObj.getIxNetworkVersion()[:3]) - if buildNumber >= 8.5: - vportObjList = topology['ports'] - else: - vportObjList = topology['vports'] - - for vportObj in vportObjList: - vportResponse = self.ixnObj.get(self.ixnObj.httpHeader+vportObj, silentMode=True) - self.ixnObj.logInfo(' VportId: {0} Name: {1} AssignedTo: {2} State: {3}'.format(vportResponse.json()['id'], - vportResponse.json()['name'], - vportResponse.json()['assignedTo'], - vportResponse.json()['state']), timestamp=False) + self.ixnObj.logInfo('Display all configs from the topology', timestamp=False) + for topoObj in self.ixNetwork.Topology.find(): + self.ixnObj.logInfo('TopologyGroup: {0} Name: {1}'.format( + topoObj.href.split('/')[-1], topoObj.DescriptiveName), timestamp=False) + self.ixnObj.logInfo(' Status: {0}'.format(topoObj.Status), timestamp=False) + for vportObj in self.ixNetwork.Vport.find(): + self.ixnObj.logInfo(' VportId: {0} Name: {1} AssignedTo: {2} State: {3}'. + format(vportObj.href.split('/')[-1], vportObj.Name, + vportObj.AssignedTo, vportObj.State), timestamp=False) self.ixnObj.logInfo('\n', end='', timestamp=False) - - for deviceGroup in topology['deviceGroup']: - self.ixnObj.logInfo(' DeviceGroup:{0} Name:{1}'.format(deviceGroup['id'], deviceGroup['name']), timestamp=False) - self.ixnObj.logInfo('\tStatus: {0}'.format(deviceGroup['status']), end='\n\n', timestamp=False) - for ethernet in deviceGroup['ethernet']: - ethernetObj = ethernet['href'] - ethernetSessionStatus = self.getSessionStatus(ethernetObj) - self.ixnObj.logInfo('\tEthernet:{0} Name:{1}'.format(ethernet['id'], ethernet['name']), timestamp=False) - self.ixnObj.logInfo('\t Status: {0}'.format(ethernet['status']), timestamp=False) - enableVlansResponse = self.ixnObj.get(self.ixnObj.httpHeader+ethernet['enableVlans'], silentMode=True) - enableVlansMultivalue = enableVlansResponse.json()['links'][0]['href'] - enableVlansValues = self.getMultivalueValues(enableVlansMultivalue, silentMode=True)[0] - self.ixnObj.logInfo('\t Vlan enabled: %s\n' % enableVlansValues, timestamp=False) - - if ethernet['ipv6'] == []: - ethernet['ipv6'].insert(0, None) - - for mac,vlan,ipv4,ipv6 in zip(ethernet['mac'], ethernet['vlan'], ethernet['ipv4'], ethernet['ipv6']): - ipv4Obj = ipv4['href'] - ipv4SessionStatus = self.getSessionStatus(ipv4Obj) - - self.ixnObj.logInfo('\tIPv4:{0} Status: {1}'.format(ipv4['id'], ipv4['status']), timestamp=False) - macResponse = self.ixnObj.get(self.ixnObj.httpHeader+ethernet['mac'], silentMode=True) - macAddress = self.getMultivalueValues(macResponse.json()['links'][0]['href'], silentMode=True) - - vlanResponse = self.ixnObj.get(self.ixnObj.httpHeader+vlan['vlanId'], silentMode=True) - vlanId = self.getMultivalueValues(vlanResponse.json()['links'][0]['href'], silentMode=True) - - priorityResponse = self.ixnObj.get(self.ixnObj.httpHeader+vlan['priority'], silentMode=True) - vlanPriority = self.getMultivalueValues(priorityResponse.json()['links'][0]['href'], - silentMode=True) - - ipResponse = self.ixnObj.get(self.ixnObj.httpHeader+ipv4['address'], silentMode=True) - ipAddress = self.getMultivalueValues(ipResponse.json()['links'][0]['href'], silentMode=True) - - gatewayResponse = self.ixnObj.get(self.ixnObj.httpHeader+ipv4['gatewayIp'], silentMode=True) - gateway = self.getMultivalueValues(gatewayResponse.json()['links'][0]['href'], silentMode=True) - - prefixResponse = self.ixnObj.get(self.ixnObj.httpHeader+ipv4['prefix'], silentMode=True) - prefix = self.getMultivalueValues(prefixResponse.json()['links'][0]['href'], silentMode=True) - + for deviceGroup in topoObj.DeviceGroup.find(): + self.ixnObj.logInfo(' DeviceGroup:{0} Name:{1}'.format( + deviceGroup.href.split('/')[-1], deviceGroup.DescriptiveName), timestamp=False) + self.ixnObj.logInfo('\tStatus: {0}'.format(deviceGroup.Status), end='\n\n', + timestamp=False) + for ethernet in deviceGroup.Ethernet.find(): + ethernetSessionStatus = ethernet.Status + self.ixnObj.logInfo('\tEthernet:{0} Name:{1}'.format( + ethernet.href.split('/')[-1], ethernet.Name), timestamp=False) + self.ixnObj.logInfo('\t Status: {0}'.format(ethernet.Status), + timestamp=False) + ipv6Obj = [] + if not (ethernet.Ipv6.find()): + ipv6Obj.insert(0, None) + else: + ipv6Obj = ethernet.Ipv6.find() + for vlan, ipv4, ipv6 in zip(ethernet.Vlan.find(), ethernet.Ipv4.find(), + ipv6Obj): + self.ixnObj.logInfo('\tIPv4:{0} Status: {1}'.format( + ipv4.href.split('/')[-1], ipv4.Status), timestamp=False) + ipv4SessionStatus = ipv4.Status index = 1 - self.ixnObj.logInfo('\t {0:8} {1:14} {2:7} {3:9} {4:12} {5:16} {6:12} {7:7} {8:7}'.format('Index', 'MacAddress', 'VlanId', 'VlanPri', 'EthSession', - 'IPv4Address', 'Gateway', 'Prefix', 'Ipv4Session'), timestamp=False) - self.ixnObj.logInfo('\t {0}'.format('-'*104), timestamp=False) - for mac,vlanId,vlanPriority,ethSession,ip,gateway,prefix,ipv4Session in zip(macAddress, - vlanId, - vlanPriority, - ethernetSessionStatus, - ipAddress, - gateway, - prefix, - ipv4SessionStatus): - self.ixnObj.logInfo('\t {0:^5} {1:18} {2:^6} {3:^9} {4:13} {5:<15} {6:<13} {7:6} {8:7}'.format(index, mac, vlanId, vlanPriority, - ethSession, ip, gateway, prefix, ipv4Session), timestamp=False) + self.ixnObj.logInfo('\t {0:8} {1:14} {2:7} {3:9} {4:12} {5:16} {6:12} ' + '{7:7} {8:7}'.format('Index', 'MacAddress', 'VlanId', + 'VlanPri', 'EthSession', + 'IPv4Address', 'Gateway', 'Prefix', + 'Ipv4Session'), timestamp=False) + self.ixnObj.logInfo('\t {0}'.format('-' * 104), timestamp=False) + + for mac, vlanId, vlanPriority, ip, gateway, prefix, in zip( + ethernet.Mac.Values, vlan.VlanId.Values, vlan.Priority.Values, + ipv4.Address.Values, ipv4.GatewayIp.Values, ipv4.Prefix.Values): + self.ixnObj.logInfo('\t {0:^5} {1:18} {2:^6} {3:^9} {4:13} {5:<15} ' + '{6:<13} {7:6} {8:7}'.format(index, mac, vlanId, + vlanPriority, + ethernetSessionStatus, + ip, gateway, prefix, + ipv4SessionStatus), + timestamp=False) index += 1 - # IPv6 - if None not in ethernet['ipv6']: - ipResponse = self.ixnObj.get(self.ixnObj.httpHeader+ipv6['address'], silentMode=True) - gatewayResponse = self.ixnObj.get(self.ixnObj.httpHeader+ipv6['gatewayIp'], silentMode=True) - prefixResponse = self.ixnObj.get(self.ixnObj.httpHeader+ipv6['prefix'], silentMode=True) - self.ixnObj.logInfo('\tIPv6:{0} Status: {1}'.format(ipv6['id'], ipv6['status']), timestamp=False) - self.ixnObj.logInfo('\t {0:8} {1:14} {2:7} {3:9} {4:12} {5:19} {6:18} {7:7} {8:7}'.format('Index', 'MacAddress', 'VlanId', 'VlanPri', 'EthSession', - 'IPv6Address', 'Gateway', 'Prefix', 'Ipv6Session'), timestamp=False) - self.ixnObj.logInfo('\t %s' % '-'*113) - for mac,vlanId,vlanPriority,ethSession,ip,gateway,prefix,ipv4Session in zip(macResponse.json()['values'], - vlanResponse.json()['values'], - priorityResponse.json()['values'], - ethernet['sessionStatus'], - ipResponse.json()['values'], gatewayResponse.json()['values'], - prefixResponse.json()['values'], ipv6['sessionStatus']): - self.ixnObj.logInfo('\t {0:^5} {1:18} {2:^6} {3:^9} {4:13} {5:<15} {6:<13} {7:8} {8:7}'.format(index, mac, vlanId, vlanPriority, - ethSession, ip, gateway, prefix, ipv4Session), timestamp=False) + if None not in ipv6Obj: + self.ixnObj.logInfo('\tIPv6:{0} Status: {1}'.format( + ipv6.href.split('/')[-1], ipv6.Status), timestamp=False) + self.ixnObj.logInfo('\t {0:8} {1:14} {2:7} {3:9} {4:12} {5:19} ' + '{6:18} {7:7} {8:7}'.format('Index', 'MacAddress', + 'VlanId', 'VlanPri', + 'EthSession', + 'IPv6Address', + 'Gateway', 'Prefix', + 'Ipv6Session'), + timestamp=False) + self.ixnObj.logInfo('\t %s' % '-' * 113) + for mac, vlanId, vlanPriority, ip, gateway, prefix, in zip( + ethernet.Mac.Values, vlan.VlanId.Values, vlan.Priority.Values, + ipv6.Address.Values, ipv6.GatewayIp.Values, ipv6.Prefix.Values): + self.ixnObj.logInfo('\t {0:^5} {1:18} {2:^6} {3:^9} {4:13} ' + '{5:<15} {6:<13} {7:8} {8:7}'. + format(index, mac, vlanId, vlanPriority, + ethernetSessionStatus, ip, gateway, + prefix, ipv6.Status), + timestamp=False) index += 1 self.ixnObj.logInfo('\n', end='', timestamp=False) - if ipv4['bgpIpv4Peer'] != []: - for bgpIpv4Peer in ipv4['bgpIpv4Peer']: - bgpIpv4PeerHref = bgpIpv4Peer['href'] - bgpIpv4PeerSessionStatus = self.getSessionStatus(bgpIpv4PeerHref) - - self.ixnObj.logInfo('\tBGPIpv4Peer:{0} Name:{1}'.format(bgpIpv4Peer['id'], bgpIpv4Peer['name'], - bgpIpv4Peer['status']), timestamp=False) - dutIpResponse = self.ixnObj.get(self.ixnObj.httpHeader+bgpIpv4Peer['dutIp'], silentMode=True) - dutIp = self.getMultivalueValues(dutIpResponse.json()['links'][0]['href'], silentMode=True) - - typeResponse = self.ixnObj.get(self.ixnObj.httpHeader+bgpIpv4Peer['type'], silentMode=True) - typeMultivalue = typeResponse.json()['links'][0]['href'] - bgpType = self.getMultivalueValues(typeMultivalue, silentMode=True) - - localAs2BytesResponse = self.ixnObj.get(self.ixnObj.httpHeader+bgpIpv4Peer['localAs2Bytes'], - silentMode=True) - localAs2BytesMultivalue = localAs2BytesResponse.json()['links'][0]['href'] - localAs2Bytes = self.getMultivalueValues(localAs2BytesMultivalue, silentMode=True) - - flapResponse = self.ixnObj.get(self.ixnObj.httpHeader+bgpIpv4Peer['flap'], silentMode=True) - flap = self.getMultivalueValues(flapResponse.json()['links'][0]['href'], silentMode=True) - - uptimeResponse = self.ixnObj.get(self.ixnObj.httpHeader+bgpIpv4Peer['uptimeInSec'], - silentMode=True) - uptime = self.getMultivalueValues(uptimeResponse.json()['links'][0]['href'], silentMode=True) - downtimeResponse = self.ixnObj.get(self.ixnObj.httpHeader+bgpIpv4Peer['downtimeInSec'], - silentMode=True) - downtime = self.getMultivalueValues(downtimeResponse.json()['links'][0]['href'], - silentMode=True) - self.ixnObj.logInfo('\t Type: {0} localAs2Bytes: {1}'.format(bgpType[0], - localAs2Bytes[0]), timestamp=False) - self.ixnObj.logInfo('\t Status: {0}'.format(bgpIpv4Peer['status']), timestamp=False) + if ipv4.BgpIpv4Peer.find() != []: + for bgpIpv4Peer in ipv4.BgpIpv4Peer.find(): + self.ixnObj.logInfo('\tBGPIpv4Peer:{0} Name:{1}'.format( + bgpIpv4Peer.href.split('/')[-1], bgpIpv4Peer.Name), + timestamp=False) + + bgpType = bgpIpv4Peer.Type.Values + localAs2Bytes = bgpIpv4Peer.LocalAs2Bytes.Values + + self.ixnObj.logInfo('\t Type: {0} localAs2Bytes: {1}'.format( + bgpType[0], localAs2Bytes[0]), timestamp=False) + self.ixnObj.logInfo('\t Status: {0}'.format(bgpIpv4Peer.Status), + timestamp=False) index = 1 - for dutIp,bgpSession,flap,uptime,downtime in zip(dutIp, - bgpIpv4PeerSessionStatus, - flap, - uptime, - downtime): - self.ixnObj.logInfo('\t\t{0}: DutIp:{1} SessionStatus:{2} Flap:{3} upTime:{4} downTime:{5}'.format(index, dutIp, bgpSession, flap, uptime, downtime), timestamp=False) + for dutIp, bgpSession, flap, uptime, downtime in zip( + bgpIpv4Peer.DutIp.Values, + bgpIpv4Peer.SessionStatus, + bgpIpv4Peer.Flap.Values, + bgpIpv4Peer.UptimeInSec.Values, + bgpIpv4Peer.DowntimeInSec.Values): + self.ixnObj.logInfo('\t\t{0}: DutIp:{1} SessionStatus:{2} ' + 'Flap:{3} upTime:{4} downTime:{5}'. + format(index, dutIp, bgpSession, flap, + uptime, downtime), + timestamp=False) index += 1 - for ospfv2 in ipv4['ospfv2']: - self.ixnObj.logInfo('\t OSPFv2:{0} Name:{1}'.format(ospfv2['id'], ospfv2['name'], ospfv2['status']), timestamp=False) - self.ixnObj.logInfo('\t\tStatus: {0}'.format(ospfv2['status']), end='\n\n', timestamp=False) - - for igmpHost in ipv4['igmpHost']: - self.ixnObj.logInfo('\t igmpHost:{0} Name:{1}'.format(igmpHost['id'], igmpHost['name'], igmpHost['status']), timestamp=False) - self.ixnObj.logInfo('\t\tStatus: {0}'.format(igmpHost['status']), end='\n\n', timestamp=False) - for igmpQuerier in ipv4['igmpQuerier']: - self.ixnObj.logInfo('\t igmpQuerier:{0} Name:{1}'.format(igmpQuerier['id'], igmpQuerier['name'], igmpQuerier['status']), timestamp=False) - self.ixnObj.logInfo('\t\tStatus: {0}'.format(igmpQuerier['status']), end='\n\n', timestamp=False) - for vxlan in ipv4['vxlan']: - self.ixnObj.logInfo('\t vxlan:{0} Name:{1}'.format(vxlan['id'], vxlan['name'], vxlan['status']), timestamp=False) - self.ixnObj.logInfo('\tStatus: {0}'.format(vxlan['status']), end='\n\n, timestamp=False') - - for networkGroup in deviceGroup['networkGroup']: - self.ixnObj.logInfo('\n\tNetworkGroup:{0} Name:{1}'.format(networkGroup['id'], networkGroup['name']), timestamp=False) - self.ixnObj.logInfo('\t Multiplier: {0}'.format(networkGroup['multiplier']), timestamp=False) - response = self.ixnObj.get(self.ixnObj.httpHeader+networkGroup['href']+'/ipv4PrefixPools', silentMode=True) - prefixPoolHref = response.json()[0]['links'][0]['href'] - - response = self.ixnObj.get(self.ixnObj.httpHeader+response.json()[0]['networkAddress'], silentMode=True) - startingAddressMultivalue = response.json()['links'][0]['href'] - startingAddress = self.getMultivalueValues(startingAddressMultivalue, silentMode=True)[0] - endingAddress = self.getMultivalueValues(startingAddressMultivalue, silentMode=True)[-1] - - prefixPoolResponse = self.ixnObj.get(self.ixnObj.httpHeader+prefixPoolHref, silentMode=True) - self.ixnObj.logInfo('\t StartingAddress:{0} EndingAddress:{1} Prefix:{2}'.format(startingAddress, - endingAddress, - response.json()['formatLength']), timestamp=False) - if None not in ethernet['ipv6']: - for ipv6 in ethernet['ipv6']: - self.ixnObj.logInfo('\t IPv6:{0} Name:{1}'.format(ipv6['id'], ipv6['name']), timestamp=False) - for bgpIpv6Peer in ipv6['bgpIpv6Peer']: - self.ixnObj.logInfo('\t BGPIpv6Peer:{0} Name:{1}'.format(bgpIpv6Peer['id'], bgpIpv6Peer['name']), timestamp=False) - for ospfv3 in ipv6['ospfv3']: - self.ixnObj.logInfo('\t OSPFv3:{0} Name:{1}'.format(ospfv3['id'], ospfv3['name']), timestamp=False) - for mldHost in ipv6['mldHost']: - self.ixnObj.logInfo('\t mldHost:{0} Name:{1}'.format(mldHost['id'], mldHost['name']), timestamp=False) - for mldQuerier in ipv6['mldQuerier']: - self.ixnObj.logInfo('\t mldQuerier:{0} Name:{1}'.format(mldQuerier['id'], mldQuerier['name']), timestamp=False) + for ospfv2 in ipv4.Ospfv2.find(): + self.ixnObj.logInfo('\t OSPFv2:{0} Name:{1}'.format( + ospfv2.href.split('/')[-1], ospfv2.Name), timestamp=False) + self.ixnObj.logInfo('\t\tStatus: {0}'.format(ospfv2.Status), end='\n\n', + timestamp=False) + + for igmpHost in ipv4.IgmpHost.find(): + self.ixnObj.logInfo('\t igmpHost:{0} Name:{1}'.format( + igmpHost.href.split('/')[-1], igmpHost.Name), timestamp=False) + self.ixnObj.logInfo('\t\tStatus: {0}'.format(igmpHost.Status), + end='\n\n', timestamp=False) + for igmpQuerier in ipv4.IgmpQuerier.find(): + self.ixnObj.logInfo('\t igmpQuerier:{0} Name:{1}'.format( + igmpQuerier.href.split('/')[-1], igmpQuerier.Name), timestamp=False) + self.ixnObj.logInfo('\t\tStatus: {0}'.format(igmpQuerier.Status), + end='\n\n', timestamp=False) + for vxlan in ipv4.Vxlan.find(): + self.ixnObj.logInfo('\t vxlan:{0} Name:{1}'.format( + vxlan.href.split('/')[-1], vxlan.Name), timestamp=False) + self.ixnObj.logInfo('\tStatus: {0}'.format(vxlan.Status), + end='\n\n', timestamp=False) + + for networkGroup in deviceGroup.NetworkGroup.find(): + self.ixnObj.logInfo('\n\tNetworkGroup:{0} Name:{1}'.format( + networkGroup.href.split('/')[-1], networkGroup.Name), timestamp=False) + self.ixnObj.logInfo('\t Multiplier: {0}'.format(networkGroup.Multiplier), + timestamp=False) + try: + startingAddress = \ + networkGroup.Ipv4PrefixPools.find()[0].NetworkAddress.Values[0] + endingAddress = \ + networkGroup.Ipv4PrefixPools.find()[0].NetworkAddress.Values[-1] + prefixPoolLength = \ + networkGroup.Ipv4PrefixPools.find()[0].PrefixLength.Values[0] + self.ixnObj.logInfo('\t NetworkGroup Type: ipv4PrefixPools', + timestamp=False) + self.ixnObj.logInfo('\t StartingAddress:{0} EndingAddress:{1} ' + 'Prefix:{2}'.format(startingAddress, endingAddress, + prefixPoolLength), timestamp=False) + except Exception as e: + print(e) + pass + + try: + startingAddress = \ + networkGroup.Ipv6PrefixPools.find()[0].NetworkAddress.Values[0] + endingAddress = \ + networkGroup.Ipv6PrefixPools.find()[0].NetworkAddress.Values[-1] + prefixPoolLength = \ + networkGroup.Ipv6PrefixPools.find()[0].PrefixLength.Values[0] + self.ixnObj.logInfo('\t NetworkGroup Type: ipv6PrefixPools', + timestamp=False) + self.ixnObj.logInfo('\t StartingAddress:{0} EndingAddress:{1} ' + 'Prefix:{2}'.format(startingAddress, endingAddress, + prefixPoolLength), timestamp=False) + except Exception as e: + print(e) + pass + + if None not in ipv6Obj: + for ipv6 in ethernet.ipv6.find(): + self.ixnObj.logInfo('\t IPv6:{0} Name:{1}'.format( + ipv6.href.split('/')[-1], ipv6.Name), timestamp=False) + for bgpIpv6Peer in ipv6.BgpIpv6Peer.find(): + self.ixnObj.logInfo('\t BGPIpv6Peer:{0} Name:{1}'.format( + bgpIpv6Peer.href.split('/')[-1], bgpIpv6Peer.Name), + timestamp=False) + for ospfv3 in ipv6.Ospfv3.find(): + self.ixnObj.logInfo('\t OSPFv3:{0} Name:{1}'.format( + ospfv3.href.split('/')[-1], ospfv3.Name), timestamp=False) + for mldHost in ipv6.MldHost.find(): + self.ixnObj.logInfo('\t mldHost:{0} Name:{1}'.format( + mldHost.href.split('/')[-1], mldHost.Name), timestamp=False) + for mldQuerier in ipv6.MldQuerier.find(): + self.ixnObj.logInfo('\t mldQuerier:{0} Name:{1}'.format( + mldQuerier.href.split('/')[-1], mldQuerier.Name), + timestamp=False) self.ixnObj.logInfo('\n', timestamp=False) def getBgpObject(self, topologyName=None, bgpAttributeList=None): """ Description - Get the BGP object from the specified Topology Group name and return the specified attributes + Get the BGP object from the specified Topology Group name and return the specified + attributes Parameters topologyName: The Topology Group name bgpAttributeList: The BGP attributes to get. - Example: - bgpAttributeMultivalue = restObj.getBgpObject(topologyName='Topo1', bgpAttributeList=['flap', 'uptimeInSec', 'downtimeInSec']) - restObj.configMultivalue(bgpAttributeMultivalue['flap'], multivalueType='valueList', data={'values': ['true', 'true']}) - restObj.configMultivalue(bgpAttributeMultivalue['uptimeInSec'], multivalueType='singleValue', data={'value': '60'}) - restObj.configMultivalue(bgpAttributeMultivalue['downtimeInSec'], multivalueType='singleValue', data={'value': '30'}) - """ - queryData = {'from': '/', - 'nodes': [{'node': 'topology', 'properties': ['name'], 'where': [{'property': 'name', 'regex': topologyName}]}, - {'node': 'deviceGroup', 'properties': [], 'where': []}, - {'node': 'ethernet', 'properties': [], 'where': []}, - {'node': 'ipv4', 'properties': [], 'where': []}, - {'node': 'bgpIpv4Peer', 'properties': bgpAttributeList, 'where': []}] - } - queryResponse = self.ixnObj.query(data=queryData) - try: - bgpHostAttributes = queryResponse.json()['result'][0]['topology'][0]['deviceGroup'][0]['ethernet'][0]['ipv4'][0]['bgpIpv4Peer'][0] - return bgpHostAttributes - except IndexError: - raise IxNetRestApiException('\nVerify the topologyName and bgpAttributeList input: {0} / {1}\n'.format(topologyName, bgpAttributeList)) + bgpAttributeMultivalue = restObj.getBgpObject(topologyName='Topo1', + bgpAttributeList=['flap', 'uptimeInSec', 'downtimeInSec']) + restObj.configMultivalue(bgpAttributeMultivalue['flap'], + multivalueType='valueList', data={'values': ['true', 'true']}) + restObj.configMultivalue(bgpAttributeMultivalue['uptimeInSec'], + multivalueType='singleValue', data={'value': '60'}) + restObj.configMultivalue(bgpAttributeMultivalue['downtimeInSec'], + multivalueType='singleValue', data={'value': '30'}) + """ + bgpAttributeDict = {} + if (self.ixNetwork.Topology.find(Name=topologyName).DeviceGroup.find().Ethernet.find(). + Ipv4.find().BgpIpv4Peer.find()): + bgpObj = self.ixNetwork.Topology.find(Name=topologyName).DeviceGroup.find() \ + .Ethernet.find().Ipv4.find().BgpIpv4Peer.find()[0] + if bgpAttributeList is not None: + for attribute in bgpAttributeList: + newattribute = attribute[0].upper() + attribute[1:] + bgpAttributeDict[attribute] = getattr(bgpObj, newattribute) + return bgpAttributeDict + else: + raise Exception("No bgp config found on the specified topology {}".format(topologyName)) def isRouterIdInDeviceGroupObj(self, routerId, deviceGroupObj): - routerIdMultivalue = deviceGroup['routerData'][0]['routerId'] - routerIdList = self.ixnObj.getMultivalueValues(routerIdMultivalue, silentMode=True) + routerIdList = deviceGroupObj.RouterData.find().RouterId.find().RouterId.Values + if routerId in routerIdList: + return True + else: + return False def configBgpNumberOfAs(self, routerId, numberOfAs): """ Description Set the total number of BGP AS # List. - In the GUI, under NetworkGroup, BGP Route Range tab, bottom tab ASPathSegments, enter number of AS # Segments. + In the GUI, under NetworkGroup, BGP Route Range tab, bottom tab ASPathSegments, enter + number of AS Segments. - NOTE! - Currently, this API will get the first Network Group object even if there are multiple - Network Groups. Network Groups could be filtered by the name or by the first route range - address. Haven't decided yet. Don't want to filter by name because in a situation - where customers are also using Spirent, Spirent doesn't go by name. + NOTE! + Currently, this API will get the first Network Group object even if there are + multiple Network Groups. Network Groups could be filtered by the name or by the + first route range address. Haven't decided yet. Don't want to filter by name because + in a situation where customers are also using Spirent, Spirent doesn't go by name. Parameters routerId: The Device Group router ID @@ -5183,53 +4201,46 @@ def configBgpNumberOfAs(self, routerId, numberOfAs): getDeviceGroupByRouterId() """ deviceGroupObj = self.getDeviceGroupByRouterId(routerId=routerId) - if deviceGroupObj == 0: - raise IxNetRestApiException('No Device Group found for router ID: %s' % routerId) - - queryData = {'from': deviceGroupObj, - 'nodes': [{'node': 'networkGroup', 'properties': [], 'where': []}, - {'node': 'ipv4PrefixPools', 'properties': [], 'where': []}, - {'node': 'bgpIPRouteProperty', 'properties': [], 'where': []}, - {'node': 'bgpAsPathSegmentList', 'properties': [], 'where': []} - ]} - queryResponse = self.ixnObj.query(data=queryData) + if deviceGroupObj is None: + raise Exception('No Device Group found for router ID: %s' % routerId) try: - bgpStack = queryResponse.json()['result'][0]['networkGroup'][0]['ipv4PrefixPools'][0]['bgpIPRouteProperty'][0]['bgpAsPathSegmentList'] - except: - raise IxNetRestApiException('No object found in DeviceGroup object: deviceGroup/networkGroup/ipv4PrefixPools/bgpIPRouteProperty/bgpAsPathSegmentList: %s' % deviceGroupObj) - - if bgpStack == []: - return IxNetRestApiException('No ipv4PrefixPools bgpIPRouteProperty object found.') - - bgpRouteObj = bgpStack[0]['href'] - response = self.ixnObj.get(self.ixnObj.httpHeader+bgpRouteObj) - asNumberInSegmentMultivalue = response.json()['numberOfAsNumberInSegment'] - self.ixnObj.patch(self.ixnObj.httpHeader+bgpRouteObj, data={'numberOfAsNumberInSegment': numberOfAs}) - - def configBgpAsPathSegmentListNumber(self, routerId, asNumber, indexAndAsNumber): + for bgpSegObj in deviceGroupObj.NetworkGroup.find().Ipv4PrefixPools.find() \ + .BgpIPRouteProperty.find().BgpAsPathSegmentList.find(): + bgpSegObj.NumberOfAsNumberInSegment = numberOfAs + except Exception as e: + print(e) + for bgpSegObj in deviceGroupObj.NetworkGroup.find().Ipv6PrefixPools.find() \ + .BgpIPRouteProperty.find().BgpAsPathSegmentList.find(): + bgpSegObj.NumberOfAsNumberInSegment = numberOfAs + + def configBgpAsPathSegmentListNumber(self, routerId, asNumber, + indexAndAsNumber): """ Description - Set BGP AS numbers in the route range. + Set BGP AS numbers in the route range. If there are 5 AS# created under "Number of AS# In Segment-1", the asNumberList is - the AS# that you want to modify for all route ranges (Device Group multiplier). + the AS# that you want to modify for all route ranges (Device Group multiplier). The indexAndAsNumber is the route range index and value: [3, 300]. 3 = the 2nd route range (zero based) and 300 is the value. - NOTE! - Currently, this API will get the first Network Group object even if there are multiple - Network Groups. Network Groups could be filtered by the name or by the first route range - address. Haven't decided yet. Don't want to filter by name because in a situation - where customers are also using Spirent, Spirent doesn't go by name. + NOTE! + Currently, this API will get the first Network Group object even if there are + multiple Network Groups. Network Groups could be filtered by the name or by the + first route range address. Haven't decided yet. Don't want to filter by name + because in a situation where customers are also using Spirent, + Spirent doesn't go by name. Parameters routerId: The Device Group router ID where the BGP is configured. asListNumber: 1|2|3|...|6|..: The AS# to modify. (On GUI, click NetworkGroup, on bottom tab asPathSegment, - and on top tab, use the "Number of AS# In Segment-1" to set number of AS#1 or AS#2 or AS#3.) + and on top tab, use the "Number of AS# In Segment-1" to set number of + AS#1 or AS#2 or AS#3.) indexAndAsNumber: all|a list of indexes with as# -> [[1, 100], [3, 300], ...] Example: - protocolObj.configBgpAsPathSegmentListNumber(routerid='195.0.0.2', 3, [[0,28], [3,298], [4, 828]]) + protocolObj.configBgpAsPathSegmentListNumber(routerid='195.0.0.2', 3, [[0,28], [3,298], + [4, 828]]) Requirements: getDeviceGroupByRouterId() @@ -5237,39 +4248,20 @@ def configBgpAsPathSegmentListNumber(self, routerId, asNumber, indexAndAsNumber) configMultivalues() """ deviceGroupObj = self.getDeviceGroupByRouterId(routerId=routerId) - if deviceGroupObj == 0: + if not deviceGroupObj: raise IxNetRestApiException('No Device Group found for router ID: %s' % routerId) - - queryData = {'from': deviceGroupObj, - 'nodes': [{'node': 'networkGroup', 'properties': [], 'where': []}, - {'node': 'ipv4PrefixPools', 'properties': [], 'where': []}, - {'node': 'bgpIPRouteProperty', 'properties': [], 'where': []}, - {'node': 'bgpAsPathSegmentList', 'properties': [], 'where': []}, - {'node': 'bgpAsNumberList', 'properties': [], 'where': []} - ]} - queryResponse = self.ixnObj.query(data=queryData) - try: - bgpStack = queryResponse.json()['result'][0]['networkGroup'][0]['ipv4PrefixPools'][0]['bgpIPRouteProperty'][0]['bgpAsPathSegmentList'][0]['bgpAsNumberList'][int(asNumber)-1] - except: - raise IxNetRestApiException('No object found in DeviceGroup object: deviceGroup/networkGroup/ipv4PrefixPools/bgpIPRouteProperty/bgpAsPathSegmentList/bgpAsNumberlist: %s' % deviceGroupObj) - - if bgpStack == []: - return IxNetRestApiException('No ipv4PrefixPools bgpIPRouteProperty object found.') - - bgpRouteObj = bgpStack['href'] - response = self.ixnObj.get(self.ixnObj.httpHeader+bgpRouteObj) - asNumberMultivalue = response.json()['asNumber'] - asNumberValueList = self.ixnObj.getMultivalueValues(asNumberMultivalue) - try: + asIndex = asNumber - 1 + asObj = deviceGroupObj.NetworkGroup.find().Ipv4PrefixPools.find() \ + .BgpIPRouteProperty.find().BgpAsPathSegmentList.find().BgpAsNumberList.find()[asIndex] + if asObj: + asNumberValueList = asObj.AsNumber.Values for eachIndexAsNumber in indexAndAsNumber: index = eachIndexAsNumber[0] asNumber = eachIndexAsNumber[1] asNumberValueList[index] = str(asNumber) - except: - raise IxNetRestApiException('The index that you indicated is out of range for the current AS list') - - self.ixnObj.logInfo('Configuruing: %s' % bgpRouteObj) - self.ixnObj.configMultivalue(asNumberMultivalue, 'valueList', {'values': asNumberValueList}) + self.configMultivalue(asObj.AsNumber, 'valueList', {'values': asNumberValueList}) + else: + return IxNetRestApiException('No ipv4PrefixPools bgpIPRouteProperty object found.') def configBgpAsSetMode(self, routerId, asSetMode): """ @@ -5288,44 +4280,25 @@ def configBgpAsSetMode(self, routerId, asSetMode): "prependlocalastofirstsegment" """ deviceGroupObj = self.getDeviceGroupByRouterId(routerId=routerId) - if deviceGroupObj == 0: + if not deviceGroupObj: raise IxNetRestApiException('No Device Group found for router ID: %s' % routerId) - queryData = {'from': deviceGroupObj, - 'nodes': [{'node': 'networkGroup', 'properties': [], 'where': []}, - {'node': 'ipv4PrefixPools', 'properties': [], 'where': []}, - {'node': 'bgpIPRouteProperty', 'properties': [], 'where': []}] - } - queryResponse = self.ixnObj.query(data=queryData) - bgpStack = queryResponse.json()['result'][0]['networkGroup'][0]['ipv4PrefixPools'][0]['bgpIPRouteProperty'] - if bgpStack == []: - return IxNetRestApiException('No ipv4PrefixPools bgpIPRouteProperty object found.') - - bgpRouteObj = bgpStack[0]['href'] - response = self.ixnObj.get(self.ixnObj.httpHeader+bgpRouteObj) - asSetModeMultivalue = response.json()['asSetMode'] - count = response.json()['count'] - newList = [asSetMode for counter in range(0,count)] - self.ixnObj.configMultivalue(asSetModeMultivalue, 'valueList', {'values': newList}) + if deviceGroupObj.NetworkGroup.find().Ipv4PrefixPools.find().BgpIPRouteProperty.find(): + bgpObj = deviceGroupObj.NetworkGroup.find().Ipv4PrefixPools.find() \ + .BgpIPRouteProperty.find() + asModeList = [] + for i in range(len(bgpObj.AsSetMode.Values)): + asModeList.append(asSetMode) + self.configMultivalue(bgpObj.AsSetMode, 'valueList', {'values': asModeList}) + else: + raise IxNetRestApiException('No BGP config found for this router ID: ') def getObject(self, keys, ngpfEndpointName=None): """ Description This is an internal function usage for getNgpfObjectHandleByName() only. """ - object = None - for key,value in keys.items(): - # All the Topology Groups - if type(value) is list: - for keyValue in value: - for key,value in keyValue.items(): - if key == 'name' and value == ngpfEndpointName: - return keyValue['href'] - - object = self.getObject(keys=keyValue, ngpfEndpointName=ngpfEndpointName) - if object != None: - return object - return None + pass def getNgpfObjectHandleByName(self, ngpfEndpointObject=None, ngpfEndpointName=None): """ @@ -5335,218 +4308,187 @@ def getNgpfObjectHandleByName(self, ngpfEndpointObject=None, ngpfEndpointName=No Stack meaning: topology, deviceGroup, ethernet, ipv44, bgpIpv4Peer, etc Parameters - ngpfEndpointObject: See below ngpfL2ObjectList and ngpfL3ObjectList. + ngpfEndpointObject: See below ngpfL2ObjectList and ngpfL3ObjectList. ngpfEndpointName: The name of the NGPF component object. Examples: - protocolObj.getNgpfObjectHandleByName(ngpfEndpointObject='topology', ngpfEndpointName='Topo2') - return objectHandle: /api/v1/sessions/1/ixnetwork/topology/2 - - protocolObj.getNgpfObjectHandleByName(ngpfEndpointObject='ipv4', ngpfEndpointName='IPv4 1') - return objectHandle: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1 - - protocolObj.getNgpfObjectHandleByName(ngpfEndpointObject='bgpIpv4Peer', ngpfEndpointName='bgp_2') - return objectHandle: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1/bgpIpv4Peer/2 - - protocolObj.getNgpfObjectHandleByName(ngpfEndpointObject='networkGroup', ngpfEndpointName='networkGroup1') - return objectHandle: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/networkGroup/1 - - protocolObj.getNgpfObjectHandleByName(ngpfEndpointObject='ipv4PrefixPools', ngpfEndpointName='Basic IPv4 Addresses 1') - return objectHandle: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/networkGroup1/ipv4PrefixPools/1 + protocolObj.getNgpfObjectHandleByName(ngpfEndpointObject='topology', + ngpfEndpointName='Topo2') + protocolObj.getNgpfObjectHandleByName(ngpfEndpointObject='ipv4', + ngpfEndpointName='IPv4 1') + protocolObj.getNgpfObjectHandleByName(ngpfEndpointObject='bgpIpv4Peer', + ngpfEndpointName='bgp_2') + protocolObj.getNgpfObjectHandleByName(ngpfEndpointObject='networkGroup', + ngpfEndpointName='networkGroup1') + protocolObj.getNgpfObjectHandleByName(ngpfEndpointObject='ipv4PrefixPools', + ngpfEndpointName='Basic IPv4 Addresses 1') """ ngpfMainObjectList = ['topology', 'deviceGroup', 'ethernet', 'ipv4', 'ipv6', 'networkGroup', 'ipv4PrefixPools', 'ipv6PrefixPools'] - ngpfL2ObjectList = ['isisL3', 'lacp', 'mpls'] - - ngpfL3ObjectList = ['ancp', 'bfdv4Interface', 'bgpIpv4Peer', 'bgpIpv6Peer', 'dhcpv4relayAgent', 'dhcpv6relayAgent', - 'geneve', 'greoipv4', 'greoipv6', 'igmpHost', 'igmpQuerier', - 'lac', 'ldpBasicRouter', 'ldpBasicRouterV6', 'ldpConnectedInterface', 'ldpv6ConnectedInterface', - 'ldpTargetedRouter', 'ldpTargetedRouterV6', 'lns', 'mldHost', 'mldQuerier', 'ptp', 'ipv6sr', - 'openFlowController', 'openFlowSwitch', 'ospfv2', 'ospfv3', 'ovsdbcontroller', 'ovsdbserver', - 'pcc', 'pce', 'pcepBackupPCEs', 'pimV4Interface', 'pimV6Interface', 'ptp', 'rsvpteIf', + ngpfL3ObjectList = ['ancp', 'bfdv4Interface', 'bgpIpv4Peer', 'bgpIpv6Peer', + 'dhcpv4relayAgent', 'dhcpv6relayAgent', 'geneve', 'greoipv4', + 'greoipv6', 'igmpHost', 'igmpQuerier', 'lac', 'ldpBasicRouter', + 'ldpBasicRouterV6', 'ldpConnectedInterface', 'ldpv6ConnectedInterface', + 'ldpTargetedRouter', 'ldpTargetedRouterV6', 'lns', 'mldHost', + 'mldQuerier', 'ptp', 'ipv6sr', 'openFlowController', 'openFlowSwitch', + 'ospfv2', 'ospfv3', 'ovsdbcontroller', 'ovsdbserver', 'pcc', 'pce', + 'pcepBackupPCEs', 'pimV4Interface', 'pimV6Interface', 'ptp', 'rsvpteIf', 'rsvpteLsps', 'tag', 'vxlan' - ] - - if ngpfEndpointObject not in ngpfL2ObjectList+ngpfL3ObjectList+ngpfMainObjectList: - raise IxNetRestApiException('\nError: No such ngpfEndpointObject: %s' % ngpfEndpointObject) - - if ngpfEndpointObject in ngpfL2ObjectList + ngpfL3ObjectList: - if ngpfEndpointObject in ngpfL2ObjectList: - nodesList = [{'node': 'topology', 'properties': [], 'where': []}, - {'node': 'deviceGroup', 'properties': [], 'where': []}, - {'node': 'ethernet', 'properties': [], 'where': []} - ] - - if ngpfEndpointObject in ngpfL3ObjectList: - nodesList = [{'node': 'topology', 'properties': [], 'where': []}, - {'node': 'deviceGroup', 'properties': [], 'where': []}, - {'node': 'ethernet', 'properties': [], 'where': []}, - {'node': 'ipv4', 'properties': [], 'where': []}, - {'node': 'ipv6', 'properties': [], 'where': []} - ] - - nodesList.insert(len(nodesList), {'node': ngpfEndpointObject, 'properties': ['name'], - 'where': [{'property': 'name', 'regex': ngpfEndpointName}]}) - - # Get the NGPF top level objects that are not a protocol: - # topology, deviceGroup, ethernet, ipv4, ipv6, networkGroup ... - if ngpfEndpointObject not in ngpfL2ObjectList + ngpfL3ObjectList: - nodesList = [] - # Get the index position of the ngptEndpointObject in the ngpfMainObjectList - ngpfEndpointIndex = ngpfMainObjectList.index(ngpfEndpointObject) - # Example: - # If ngpfEndpointObject is 'ethernet', - # then do a for loop from the topology level to the ethernet level. - for eachNgpfEndpoint in ngpfMainObjectList[:ngpfEndpointIndex+1]: - # topology, deviceGroup, ethernet, ipv4, ipv6, networkGroup ... - if eachNgpfEndpoint == ngpfEndpointObject: - nodesList.append({'node': eachNgpfEndpoint, 'properties': ['name'], - 'where': [{'property': 'name', 'regex': ngpfEndpointName}]}) - else: - nodesList.append({'node': eachNgpfEndpoint, 'properties': [], 'where': []}) + ] - queryData = {'from': '/', 'nodes': nodesList} - queryResponse = self.ixnObj.query(data=queryData) + if ngpfEndpointObject not in ngpfL2ObjectList + ngpfL3ObjectList + ngpfMainObjectList: + raise IxNetRestApiException('\nError: No such ngpfEndpointObject: %s' % + ngpfEndpointObject) + + if ngpfEndpointObject in ngpfL2ObjectList: + ngpfEndpointObject = ngpfEndpointObject[0].capitalize() + ngpfEndpointObject[1:] + nodesObjList = self.ixNetwork.Topology.find().DeviceGroup.find().Ethernet.find() + ngpfEndpointResponse = getattr(nodesObjList, ngpfEndpointObject) + Obj = ngpfEndpointResponse.find(Name=ngpfEndpointName) + self.ixnObj.logInfo('getNgpfObjectHandleByName: %s' % Obj) + return Obj + elif ngpfEndpointObject in ngpfL3ObjectList: + ngpfEndpointObject = ngpfEndpointObject[0].capitalize() + ngpfEndpointObject[1:] + nodesIpv4ObjList = self.ixNetwork.Topology.find().DeviceGroup.find().Ethernet.find() \ + .Ipv4.find() + nodesIpv6ObjList = self.ixNetwork.Topology.find().DeviceGroup.find().Ethernet.find() \ + .Ipv6.find() + try: + ngpfEndpointResponse = getattr(nodesIpv4ObjList, ngpfEndpointObject) + Obj = ngpfEndpointResponse.find(Name=ngpfEndpointName) + self.ixnObj.logInfo('getNgpfObjectHandleByName: %s' % Obj) + return Obj + except Exception as e: + print(e) + ngpfEndpointResponse = getattr(nodesIpv6ObjList, ngpfEndpointObject) + Obj = ngpfEndpointResponse.find(Name=ngpfEndpointName) + self.ixnObj.logInfo('getNgpfObjectHandleByName: %s' % Obj) + return Obj + else: + obj = self.ixNetwork + ngpfEndpointIndex = ngpfMainObjectList.index(ngpfEndpointObject) - # Get a list of all the nested keys - objectHandle = self.getObject(keys=queryResponse.json()['result'][0], ngpfEndpointName=ngpfEndpointName) - self.ixnObj.logInfo('getNgpfObjectHandleByName: %s' % objectHandle) - return objectHandle + for eachNgpfEndpoint in ngpfMainObjectList[:ngpfEndpointIndex + 1]: + if eachNgpfEndpoint != ngpfEndpointObject: + eachNgpfEndpoint = eachNgpfEndpoint[0].capitalize() + eachNgpfEndpoint[1:] + eachNgpfEndpointResponse = getattr(obj, eachNgpfEndpoint) + obj = eachNgpfEndpointResponse.find() + else: + eachNgpfEndpoint = eachNgpfEndpoint[0].capitalize() + eachNgpfEndpoint[1:] + eachNgpfEndpointResponse = getattr(obj, eachNgpfEndpoint) + obj = eachNgpfEndpointResponse.find(Name=ngpfEndpointName) + return obj def getNgpfObjectHandleByRouterId(self, ngpfEndpointObject, routerId): """ Description Get the NGPF object handle filtering by the routerId. - All host interface has a router ID by default and the router ID is located in the - Device Group in the IxNetwork GUI. The API endpoint is: /topology/deviceGroup/routerData - + All host interface has a router ID by default and the router ID is + located in the Device Group in the IxNetwork GUI. + Note: Router ID exists only if there are protocols configured. Parameters - ngpfEndpointObject: : The NGPF endpoint. Example: - deviceGroup, ethernet, ipv4, ipv6, bgpIpv4Peer, ospfv2, etc. - These endpoint object names are the IxNetwork API endpoints and you could - view them in the IxNetwork API browser. - + ngpfEndpointObject: : The NGPF endpoint. Example: deviceGroup, + ethernet, ipv4, ipv6, bgpIpv4Peer, ospfv2, etc. routerId: : The router ID IP address. Example: protocolObj.getNgpfObject(ngpfEndpointObject='ipv4', routerId='192.0.0.1') - return objectHandle: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv4/1 - protocolObj.getNgpfObject(ngpfEndpointObject='bgpIpv4Peer', routerId='193.0.0.1') - return objectHandle: /api/v1/sessions/1/ixnetwork/topology/2/deviceGroup/1/ethernet/1/ipv4/1/bgpIpv4Peer/2 - protocolObj.getNgpfObject(ngpfEndpointObject='networkGroup', routerId='193.0.0.1') - return objectHandle: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/networkGroup/1 - protocolObj.getNgpfObject(ngpfEndpointObject='ipv4PrefixPools', routerId='193.0.0.1') - return objectHandle: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/networkGroup1/ipv4PrefixPools/1 """ - ngpfMainObjectList = ['topology', 'deviceGroup', 'ethernet', 'ipv4', 'ipv6', - 'networkGroup', 'ipv4PrefixPools', 'ipv6PrefixPools'] + ngpfMainObjectList = ['topology', 'deviceGroup', 'ethernet', 'networkGroup', + 'ipv4PrefixPools', 'ipv6PrefixPools'] - ngpfL2ObjectList = ['isisL3', 'lacp', 'mpls'] + ngpfL2ObjectList = ['isisL3', 'lacp', 'mpls', 'ipv4', 'ipv6', ] + + ngpfL3ObjectList = ['ancp', 'bfdv4Interface', 'bgpIpv4Peer', 'bgpIpv6Peer', + 'dhcpv4relayAgent', 'dhcpv6relayAgent', 'geneve', 'greoipv4', + 'greoipv6', 'igmpHost', 'igmpQuerier', 'lac', 'ldpBasicRouter', + 'ldpBasicRouterV6', 'ldpConnectedInterface', 'ldpv6ConnectedInterface', + 'ldpTargetedRouter', 'ldpTargetedRouterV6', 'lns', 'mldHost', + 'mldQuerier', 'ptp', 'ipv6sr', 'openFlowController', + 'openFlowSwitch', 'ospfv2', 'ospfv3', 'ovsdbcontroller', 'ovsdbserver', + 'pcc', 'pce', 'pcepBackupPCEs', 'pimV4Interface', 'pimV6Interface', + 'ptp', 'rsvpteIf', 'rsvpteLsps', 'tag', 'vxlan' + ] - ngpfL3ObjectList = ['ancp', 'bfdv4Interface', 'bgpIpv4Peer', 'bgpIpv6Peer', 'dhcpv4relayAgent', 'dhcpv6relayAgent', - 'geneve', 'greoipv4', 'greoipv6', 'igmpHost', 'igmpQuerier', - 'lac', 'ldpBasicRouter', 'ldpBasicRouterV6', 'ldpConnectedInterface', 'ldpv6ConnectedInterface', - 'ldpTargetedRouter', 'ldpTargetedRouterV6', 'lns', 'mldHost', 'mldQuerier', 'ptp', 'ipv6sr', - 'openFlowController', 'openFlowSwitch', 'ospfv2', 'ospfv3', 'ovsdbcontroller', 'ovsdbserver', - 'pcc', 'pce', 'pcepBackupPCEs', 'pimV4Interface', 'pimV6Interface', 'ptp', 'rsvpteIf', - 'rsvpteLsps', 'tag', 'vxlan' - ] - if ngpfEndpointObject not in ngpfL2ObjectList + ngpfL3ObjectList + ngpfMainObjectList: - raise IxNetRestApiException('\nError: No such ngpfEndpointObject: %s' % ngpfEndpointObject) - - if ngpfEndpointObject in ngpfL2ObjectList + ngpfL3ObjectList: - if ngpfEndpointObject in ngpfL2ObjectList: - nodesList = [{'node': 'topology', 'properties': [], 'where': []}, - {'node': 'deviceGroup', 'properties': [], 'where': []}, - {'node': 'routerData', 'properties': ['routerId'], 'where': []}, - {'node': 'ethernet', 'properties': [], 'where': []} - ] - - if ngpfEndpointObject in ngpfL3ObjectList: - nodesList = [{'node': 'topology', 'properties': [], 'where': []}, - {'node': 'deviceGroup', 'properties': [], 'where': []}, - {'node': 'routerData', 'properties': ['routerId'], 'where': []}, - {'node': 'ethernet', 'properties': [], 'where': []}, - {'node': 'ipv4', 'properties': [], 'where': []}, - {'node': 'ipv6', 'properties': [], 'where': []} - ] - - # Add the protocol level to the end of the list. - nodesList.insert(len(nodesList), {'node': ngpfEndpointObject, 'properties': [], 'where': []}) - - # User is looking for non protocol object handle such as deviceGroup, ethernet, ipv4 or ipv6 - if ngpfEndpointObject not in ngpfL2ObjectList + ngpfL3ObjectList: - nodesList = [{'node': 'topology', 'properties': [], 'where': []}, - {'node': 'deviceGroup', 'properties': [], 'where': []}, - {'node': 'networkGroup', 'properties': [], 'where': []}, - {'node': 'ethernet', 'properties': [], 'where': []}, - {'node': 'ipv4PrefixPools', 'properties': [], 'where': []}, - {'node': 'ipv6Prefixpools', 'properties': [], 'where': []}, - {'node': 'routerData', 'properties': ['routerId'], 'where': []}, - {'node': 'ethernet', 'properties': [], 'where': []}, - {'node': 'ipv4', 'properties': [], 'where': []}, - {'node': 'ipv6', 'properties': [], 'where': []} - ] - - queryData = {'from': '/', 'nodes': nodesList} - queryResponse = self.ixnObj.query(data=queryData) - - # This is for getObject out of scope variable tracking - class getObjectVar: - protocolObjHandle= None - foundRouterId = False - - def __getObject(keys): - """ - This is an internal function usage for getNgpfObjectHandleByRouterId() only. - """ - object = None - for key,value in keys.items(): - # All the Topology Groups - if type(value) is list: - for keyValue in value: - for key,value in keyValue.items(): - if key == ngpfEndpointObject and value != []: - getObjectVar.protocolObjHandle = value[0]['href'] - - if key == 'routerId': - routerIdMultivalue = value - routerIdList = self.getMultivalueValues(routerIdMultivalue) - if routerId in routerIdList: - getObjectVar.foundRouterId = True - return - - object = __getObject(keyValue) - if getObjectVar.foundRouterId == True: - return getObjectVar.protocolObjHandle - - objectHandle = __getObject(queryResponse.json()['result'][0]) - self.ixnObj.logInfo('getNgpfObject: %s' % objectHandle) - return objectHandle + raise IxNetRestApiException('\nError: No such ngpfEndpointObject: %s' % + ngpfEndpointObject) + deviceGroupObjByRouterId = self.getDeviceGroupByRouterId(routerId=routerId) + for topology in self.ixNetwork.Topology.find(): + deviceGroupList = [] + for deviceGroupObj in topology.DeviceGroup.find(): + deviceGroupList.append(deviceGroupObj) + + for deviceGroupObj in deviceGroupList: + if deviceGroupObj == deviceGroupObjByRouterId: + if ngpfEndpointObject == 'topology': + return topology + if ngpfEndpointObject == 'deviceGroup': + return deviceGroupObj + ethernetList = deviceGroupObj.Ethernet.find() + if not ethernetList: + continue + + if ngpfEndpointObject == 'ethernet': + for eachEthernetObj in ethernetList: + match = re.match('(/api.*)', eachEthernetObj.href) + if match: + return eachEthernetObj + + if ngpfEndpointObject == 'networkGroup': + networkGroupList = deviceGroupObj.NetworkGroup.find() + for eachNetworkGroupObj in networkGroupList: + match = re.match('(/api.*)', eachNetworkGroupObj.href) + if match: + return eachNetworkGroupObj + + for ethernet in ethernetList: + # Dynamically get all Ethernet child endpoints + if ngpfEndpointObject in ngpfL2ObjectList: + endpointObject = ngpfEndpointObject[0].capitalize() + \ + ngpfEndpointObject[1:] + endpointObjectResponse = getattr(ethernet, endpointObject) + Obj = endpointObjectResponse.find() + return Obj + elif ngpfEndpointObject in ngpfL3ObjectList: + endpointObject = ngpfEndpointObject[0].capitalize() + \ + ngpfEndpointObject[1:] + nodesIpv4ObjList = ethernet.Ipv4.find() + nodesIpv6ObjList = ethernet.Ipv6.find() + try: + endpointObjectResponse = getattr(nodesIpv4ObjList, endpointObject) + Obj = endpointObjectResponse.find() + return Obj + except Exception as e: + print(e) + endpointObjectResponse = getattr(nodesIpv6ObjList, endpointObject) + Obj = endpointObjectResponse.find() + return Obj + else: + return None def getDeviceGroupByRouterId(self, routerId=None, queryDict=None, runQuery=True): """ Description Get the Device Group object handle for the routerId. - + Note: - A Device Group could have many IP host (sessions). This is configured as multipliers in - a Device Group. If multiplier = 5, there will be 5 IP host. Each host will + A Device Group could have many IP host (sessions). This is configured as multipliers + in a Device Group. If multiplier = 5, there will be 5 IP host. Each host will have a unique router ID identifier. To get the Device Group that has a specific router ID, pass in the router ID for the parameter routerId. Parameter routerId: : The router ID in the format of 192.0.0.1. - queryDict: : Ignore this parameter. This parameter is only used internally. - runQuery: Ignore this parameter. : This parameter is only used internally. + queryDict: : Ignore this parameter. This parameter is only used internally. + runQuery: Ignore this parameter. : This parameter is only used internally. Example: obj = mainObj.getDeviceGroupByRouterId(routerId='192.0.0.3') @@ -5560,85 +4502,65 @@ def getDeviceGroupByRouterId(self, routerId=None, queryDict=None, runQuery=True) return self.getObjAttributeValue(ethernetObjHandle, 'mac') Return - - deviceGroup object handle: /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1 + - deviceGroup object handle - None if routerid is not found """ - if runQuery: - queryData = {'from': '/', - 'nodes': [{'node': 'topology', 'properties': ['name'], 'where': []}, - {'node': 'deviceGroup', 'properties': [], 'where': []}, - {'node': 'routerData', 'properties': ['routerId'], 'where': []} - ] - } - queryResponse = self.ixnObj.query(data=queryData) - queryDict = queryResponse.json()['result'][0] - - object = None - for key,value in queryDict.items(): - # All the Topology Groups - if type(value) is list: - for keyValue in value: - print() - - for deepKey,deepValue in keyValue.items(): - if deepKey == 'routerId': - # deepValue = /api/v1/sessions/1/ixnetwork/multivalue/1054 - # ['192.0.0.1', '192.0.0.2', '192.0.0.3'] - multivalueObj = deepValue - value = self.ixnObj.getMultivalueValues(multivalueObj) - if routerId in value: - # /api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/routerData/1 - match = re.match('(/api.*)/routerData', keyValue['href']) - deviceGroupObj = match.group(1) - self.ixnObj.logInfo('deviceGroupHandle for routerId: {0}\n\t{1}'.format(routerId, deviceGroupObj), timestamp=False) - return deviceGroupObj - - object = self.getDeviceGroupByRouterId(queryDict=keyValue, routerId=routerId, runQuery=False) - if object is not None: - return object + deviceGroupObj = None + routerDataObj = self.ixNetwork.Topology.find().DeviceGroup.find().RouterData.find() + for eachRouterDataObj in routerDataObj: + routerIdValues = self.getMultivalueValues(eachRouterDataObj.RouterId) + if routerId in routerIdValues: + match = re.match('(/api.*)/routerData', eachRouterDataObj.href) + deviceGroupObj = match.group(1) + deviceGroupObjectList = self.ixNetwork.Topology.find().DeviceGroup.find() + for eachDeviceGroupObject in deviceGroupObjectList: + if eachDeviceGroupObject.href == deviceGroupObj: + return eachDeviceGroupObject + return deviceGroupObj def getEthernetPropertyValue(self, routerId=None, ngpfEndpointName=None, property=None): """ Description - Get any NGPF Ethernet property value based on the router ID or by the NGPF - component name. + Get any NGPF Ethernet property value based on the router ID or by the NGPF component + name. Parameters routerId: : The router ID IP address. ngpfEndpointName: : The NGPF endpoint name. property: : The NGPF Ethernet property. - Choices: name, mac, mtu, status, vlanCount, enableVlans + Choices: name, mac, mtu, status, vlanCount, enableVlans """ + ethernetObj = None ethernetProperties = ['name', 'mac', 'mtu', 'status', 'vlanCount', 'enableVlans'] if property not in ethernetProperties: - raise IxNetRestApiException('\nError: No such Ethernet property: %s.\n\nAvailable NGPF Ethernet properies: %s' % (property, ethernetProperties)) + raise IxNetRestApiException('\nError: No such Ethernet property: %s.\n\nAvailable NGPF ' + 'Ethernet properies: %s' % (property, ethernetProperties)) if routerId: - ethernetObj = self.getNgpfObjectHandleByRouterId(routerId=routerId, ngpfEndpointObject='ethernet') - - if ngpfEndpointName: - ethernetObj = self.getNgpfObjectHandleByName(ngpfEndpointName=ngpfEndpointName, ngpfEndpointObject='ethernet') + ethernetObj = self.getNgpfObjectHandleByRouterId(routerId=routerId, + ngpfEndpointObject='ethernet') - return self.ixnObj.getObjAttributeValue(ethernetObj, property) + if ngpfEndpointName: + ethernetObj = self.getNgpfObjectHandleByName(ngpfEndpointName=ngpfEndpointName, + ngpfEndpointObject='ethernet') + attribute = property[0].capitalize() + property[1:] + return self.ixnObj.getObjAttributeValue(ethernetObj, attribute) def sendNsNgpf(self, ipv6ObjList): """ Description Send NS out of all the IPv6 objects that you provide in a list. - + Parameter ipv6ObjList: : Provide a list of one or more IPv6 object handles to send arp. - Ex: ["/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv6/1"] """ if type(ipv6ObjList) != list: - raise IxNetRestApiException('sendNsNgpf error: The parameter ipv6ObjList must be a list of objects.') - - url = self.ixnObj.sessionUrl + '/topology/deviceGroup/ethernet/ipv6/operations/sendns' - data = {'arg1': ipv6ObjList} - response = self.ixnObj.post(url, data=data) - self.ixnObj.waitForComplete(response, url + '/' + response.json()['id']) + raise IxNetRestApiException( + 'sendNsNgpf error: The parameter ipv6ObjList must be a list of objects.') + self.ixNetwork.Topology.DeviceGroup.Ethernet.Ipv6.SendNs(ipv6ObjList) - def configIpv6Ngpf(self, obj=None, port=None, portName=None, ngpfEndpointName=None, **kwargs): + def configIpv6Ngpf(self, obj=None, port=None, portName=None, + ngpfEndpointName=None, **kwargs): """ Description Create or modify NGPF IPv6. @@ -5651,29 +4573,26 @@ def configIpv6Ngpf(self, obj=None, port=None, portName=None, ngpfEndpointName=No 4> Set NGPF IP name that you configured. Parameters - obj: : None or Ethernet obj: '/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1' - IPv6 obj: '/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ethernet/1/ipv6/1' - + obj: : None or Ethernet obj or IPv6 obj port: : Format: [ixChassisIp, str(cardNumber), str(portNumber)] portName: : The virtual port name. ngpfEndpointName: : The name that you configured for the NGPF BGP. kwargs: - ipv6Address: : {'start': '2000:0:0:1:0:0:0:1', 'direction': 'increment', 'step': '0:0:0:0:0:0:0:1'}, + ipv6Address: : {'start': '2000:0:0:1:0:0:0:1', 'direction': 'increment', + 'step': '0:0:0:0:0:0:0:1'}, ipv6AddressPortStep: |: disable|0:0:0:0:0:0:0:1 Incrementing the IP address on each port based on your input. 0:0:0:0:0:0:0:1 means to increment the last octet on each port. - gateway: : {'start': '2000:0:0:1:0:0:0:2', 'direction': 'increment', 'step': '0:0:0:0:0:0:0:1'}, + gateway: : {'start': '2000:0:0:1:0:0:0:2', 'direction': 'increment', + 'step': '0:0:0:0:0:0:0:1'}, gatewayPortStep: |: disable|0:0:0:0:0:0:0:1 Incrementing the IP address on each port based on your input. 0:0:0:0:0:0:0:1 means to increment the last octet on each port. prefix: : Example: 64 resolveGateway: - Syntax - POST: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv6 - PATCH: /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv6/{id} Example to create a new IPv6 object: ipv6Obj = configIpv4Ngpf(ethernetObj1, @@ -5688,131 +4607,110 @@ def configIpv6Ngpf(self, obj=None, port=None, portName=None, ngpfEndpointName=No prefix=64, resolveGateway=True) - Return - /api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv6/{id} """ - createNewIpv6Obj = True - - if obj != None: - if 'ipv6' in obj: - # To modify IPv6 + if obj is not None: + if 'ipv6' in obj.href: ipv6Obj = obj - createNewIpv6Obj = False else: - # To create a new IPv6 object - ipv6Url = self.ixnObj.httpHeader+obj+'/ipv6' self.ixnObj.logInfo('Creating new IPv6 in NGPF') - response = self.ixnObj.post(ipv6Url) - ipv6Obj = response.json()['links'][0]['href'] - + ipv6Obj = obj.Ipv6.add() + # To modify if ngpfEndpointName: - ipv6Obj = self.getNgpfObjectHandleByName(ngpfEndpointName=ngpfEndpointName, ngpfEndpointObject='ipv6') - createNewIpv6Obj = False + ipv6Obj = self.getNgpfObjectHandleByName(ngpfEndpointName=ngpfEndpointName, + ngpfEndpointObject='ipv6') # To modify if port: x = self.getProtocolListByPortNgpf(port=port) ipv6Obj = self.getProtocolObjFromProtocolList(x['deviceGroup'], 'ipv6')[0] - createNewIpv6Obj = False # To modify if portName: x = self.getProtocolListByPortNgpf(portName=portName) ipv6Obj = self.getProtocolObjFromProtocolList(x['deviceGroup'], 'ipv6')[0] - createNewIpv6Obj = False - - ipv6Response = self.ixnObj.get(self.ixnObj.httpHeader+ipv6Obj) if 'name' in kwargs: - self.ixnObj.patch(self.ixnObj.httpHeader+ipv6Obj, data={'name': kwargs['name']}) + ipv6Obj.Name = kwargs['name'] if 'multiplier' in kwargs: - self.configDeviceGroupMultiplier(objectHandle=ipv6Obj, multiplier=kwargs['multiplier'], applyOnTheFly=False) + ipv6Obj.Multiplier = kwargs['multiplier'] # Config IPv6 address if 'ipv6Address' in kwargs: - multivalue = ipv6Response.json()['address'] - self.ixnObj.logInfo('Configuring IPv6 address. Attribute for multivalueId = jsonResponse["address"]') - - # Default to counter + self.ixnObj.logInfo( + 'Configuring IPv6 address. Attribute for multivalueId = jsonResponse["address"]') + addrObj = ipv6Obj.Address multivalueType = 'counter' - + data = kwargs['ipv6Address'] if 'ipv6AddressMultivalueType' in kwargs: multivalueType = kwargs['ipv6AddressMultivalueType'] - if multivalueType == 'random': - self.ixnObj.patch(self.ixnObj.httpHeader+multivalue, data={'pattern': 'random'}) + addrObj.Random() else: - self.configMultivalue(multivalue, multivalueType, data=kwargs['ipv6Address']) - - # Config IPv6 port step + self.configMultivalue(addrObj, multivalueType, data) if 'ipv6AddressPortStep' in kwargs: - portStepMultivalue = self.ixnObj.httpHeader+multivalue+'/nest/1' + portStepMultivalue = addrObj.Steps.find() self.ixnObj.logInfo('Configure IPv6 address port step') if kwargs['ipv6AddressPortStep'] != 'disabled': - self.ixnObj.patch(portStepMultivalue, data={'step': kwargs['ipv6AddressPortStep']}) - + portStepMultivalue.Step = kwargs['ipv6AddressPortStep'] if kwargs['ipv6AddressPortStep'] == 'disabled': - self.ixnObj.patch(portStepMultivalue, data={'enabled': False}) - + portStepMultivalue.Enabled = False # Config Gateway if 'gateway' in kwargs: - multivalue = ipv6Response.json()['gatewayIp'] - self.ixnObj.logInfo('Configure IPv6 gateway. Attribute for multivalueId = jsonResponse["gatewayIp"]') - # Default to counter + gatewayObj = ipv6Obj.find().GatewayIp + self.ixnObj.logInfo( + 'Configure IPv6 gateway. Attribute for multivalueId = jsonResponse["gatewayIp"]') multivalueType = 'counter' - + data = kwargs['gateway'] if 'gatewayMultivalueType' in kwargs: multivalueType = kwargs['ipv6AddressMultivalueType'] - if multivalueType == 'random': - self.ixnObj.patch(self.ixnObj.httpHeader+multivalue, data={'pattern': 'random'}) + gatewayObj.Random() else: - self.configMultivalue(multivalue, multivalueType, data=kwargs['gateway']) - - # Config Gateway port step - if 'gatewayPortStep' in kwargs: - portStepMultivalue = self.ixnObj.httpHeader+multivalue+'/nest/1' - self.ixnObj.logInfo('Configure IPv6 gateway port step') - if kwargs['gatewayPortStep'] != 'disabled': - self.ixnObj.patch(portStepMultivalue, data={'step': kwargs['gatewayPortStep']}) - - if kwargs['gatewayPortStep'] == 'disabled': - self.ixnObj.patch(portStepMultivalue, data={'enabled': False}) - - # Config resolve gateway + self.configMultivalue(gatewayObj, multivalueType, data) + if 'gatewayPortStep' in kwargs: + portStepMultivalue = gatewayObj.Steps.find() + self.ixnObj.logInfo('Configure IPv6 gateway port step') + if kwargs['gatewayPortStep'] != 'disabled': + portStepMultivalue.Step = kwargs['gatewayPortStep'] + if kwargs['gatewayPortStep'] == 'disabled': + portStepMultivalue.Enabled = False if 'resolveGateway' in kwargs: - multivalue = ipv6Response.json()['resolveGateway'] - self.ixnObj.logInfo('Configure IPv6 gateway to resolve gateway. Attribute for multivalueId = jsonResponse["resolveGateway"]') - self.configMultivalue(multivalue, 'singleValue', data={'value': kwargs['resolveGateway']}) - + resolveGatewayObj = ipv6Obj.find().ResolveGateway + self.configMultivalue(resolveGatewayObj, 'singleValue', + data={'value': kwargs['resolveGateway']}) if 'prefix' in kwargs: - multivalue = ipv6Response.json()['prefix'] - self.ixnObj.logInfo('Configure IPv6 prefix. Attribute for multivalueId = jsonResponse["prefix"]') - self.configMultivalue(multivalue, 'singleValue', data={'value': kwargs['prefix']}) + prefixObj = ipv6Obj.find().Prefix + self.ixnObj.logInfo( + 'Configure IPv6 prefix. Attribute for multivalueId = jsonResponse["prefix"]') + self.configMultivalue(prefixObj, 'singleValue', data={'value': kwargs['prefix']}) - if createNewIpv6Obj == True: + if ipv6Obj not in self.configuredProtocols: self.configuredProtocols.append(ipv6Obj) - return ipv6Obj def configDeviceGroupMultiplier(self, objectHandle, multiplier, applyOnTheFly=False): """ Description - Configure a Device Group multiplier. Pass in a NGPF object handle and - this API will parse out the Device Group object to use for configuring - the multiplier. - + Configure a Device Group multiplier. Pass in a NGPF object handle and this API will + parse out the Device Group object to use for configuring the multiplier. + Parameter objectHandle: : A NGPF object handle. multiplier: : The number of multiplier. applyOnTheFly: : Default to False. applyOnTheFly is for protocols already running. """ - deviceGroupObject = re.search("(.*deviceGroup/\d).*", objectHandle) - deviceGroupObjectUrl = self.ixnObj.httpHeader+deviceGroupObject.group(1) - self.ixnObj.patch(deviceGroupObjectUrl, data={"multiplier": int(multiplier)}) - if applyOnTheFly: self.applyOnTheFly() + deviceGroup = None + deviceGroupObject = re.search('(.*deviceGroup/[0-9]+).*', objectHandle.href) + deviceGroupObjectList = self.ixNetwork.Topology.find().DeviceGroup.find() + for eachDeviceGroupObject in deviceGroupObjectList: + if eachDeviceGroupObject.href == deviceGroupObject.group(1): + deviceGroup = eachDeviceGroupObject + break + deviceGroup.Multiplier = int(multiplier) + if applyOnTheFly: + self.applyOnTheFly() def startStopLdpBasicRouterV6Ngpf(self, ldpV6ObjList, action='start'): """ @@ -5820,17 +4718,18 @@ def startStopLdpBasicRouterV6Ngpf(self, ldpV6ObjList, action='start'): Start or stop LDP Basic Router V6 protocol. Parameters - ldpV6ObjList: : Provide a list of one or more ldpBasicRouterV6 object handles to start or stop. - Ex: ["/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/1/ldpBasicRouterV6/1", ...] + ldpV6ObjList: : Provide a list of one or more ldpBasicRouterV6 object handles to + start or stop. action: : start or stop """ if type(ldpV6ObjList) != list: - raise IxNetRestApiException('startStopLdpBasicRouterV6Ngpf error: The parameter ldpV6ObjList must be a list of objects.') - - url = self.ixnObj.sessionUrl+'/topology/deviceGroup/ldpBasicRouterV6/operations/'+action - data = {'arg1': ldpV6ObjList } - response = self.ixnObj.post(url, data=data) - self.ixnObj.waitForComplete(response, url+'/'+response.json()['id']) + raise IxNetRestApiException('startStopLdpBasicRouterV6Ngpf error: The parameter ' + 'ldpV6ObjList must be a list of objects.') + for eachLdpV6Obj in ldpV6ObjList: + if action == 'start': + eachLdpV6Obj.Start() + if action == 'stop': + eachLdpV6Obj.Stop() def startStopLdpConnectedInterfaceNgpf(self, ldpConnectedIntObjList, action='start'): """ @@ -5838,18 +4737,18 @@ def startStopLdpConnectedInterfaceNgpf(self, ldpConnectedIntObjList, action='sta Start or stop LDP Basic Router Connected Interface protocol. Parameters - ldpConnectedIntObjList: : Provide a list of one or more ldpBasicRouter - object handles to start or stop. - Ex: ["/api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv4/{id}/ldpConnectedInterface/{id}", ...] + ldpConnectedIntObjList: : Provide a list of one or more + ldpBasicRouter object handles to start or stop. action: : start or stop """ if type(ldpConnectedIntObjList) != list: - raise IxNetRestApiException('startStopLdpConnectedInterfaceNgpf error: The parameter ldpObjList must be a list of objects.') - - url = self.ixnObj.sessionUrl + '/topology/deviceGroup/ethernet/ipv4/ldpConnectedInterface/operations/'+action - data = {'arg1': ldpConnectedIntObjList} - response = self.ixnObj.post(url, data=data) - self.ixnObj.waitForComplete(response, url + '/' + response.json()['id']) + raise IxNetRestApiException('startStopLdpConnectedInterfaceNgpf error: The parameter ' + 'ldpObjList must be a list of objects.') + for eachLdpConnectedIntObj in ldpConnectedIntObjList: + if action == 'start': + eachLdpConnectedIntObj.Start() + if action == 'stop': + eachLdpConnectedIntObj.Stop() def startStopLdpV6ConnectedInterfaceNgpf(self, ldpV6ConnectedIntObjList, action='start'): """ @@ -5857,19 +4756,22 @@ def startStopLdpV6ConnectedInterfaceNgpf(self, ldpV6ConnectedIntObjList, action= Start or stop LDP Basic Router V6 Connected Interface protocol. Parameters - ldpV6ConnectedIntObjList: : Provide a list of one or more ldpBasicRouter object handles to start or stop. - Ex: ["/api/v1/sessions/{id}/ixnetwork/topology/{id}/deviceGroup/{id}/ethernet/{id}/ipv6/{id}/ldpConnectedInterface/{id}", ...] + ldpV6ConnectedIntObjList: : Provide a list of one or more + ldpBasicRouter object handles to start or stop. action = start or stop """ if type(ldpV6ConnectedIntObjList) != list: - raise IxNetRestApiException('startStopLdpV6ConnectedInterfaceNgpf error: The parameter ldpV6ConnectedIntObjList must be a list of objects.') + raise IxNetRestApiException('startStopLdpV6ConnectedInterfaceNgpf error: The parameter ' + 'ldpV6ConnectedIntObj List must be a list of objects.') - url = self.ixnObj.sessionUrl + '/topology/deviceGroup/ethernet/ipv6/ldpv6ConnectedInterface/operations/'+action - data = {'arg1': ldpV6ConnectedIntObjList} - response = self.ixnObj.post(url, data=data) - self.ixnObj.waitForComplete(response, url + '/' + response.json()['id']) + for eachLdpV6ConnectedIntObj in ldpV6ConnectedIntObjList: + if action == 'start': + eachLdpV6ConnectedIntObj.Start() + if action == 'stop': + eachLdpV6ConnectedIntObj.Stop() - def verifyDhcpClientBind(self, deviceGroupName=None, protocol=None, **kwargs): + def verifyDhcpClientBind(self, deviceGroupName=None, protocol=None, + **kwargs): """ Description Check DHCP Client Bound/Idle and DHCP Client Bound Count. @@ -5885,47 +4787,53 @@ def verifyDhcpClientBind(self, deviceGroupName=None, protocol=None, **kwargs): Examples: protocolObj.verifyDhcpClientBind(deviceGroupName="DHCPv6 Client") - protocolObj.verifyDhcpClientBind(protocol="ipv4") - protocolObj.verifyDhcpClientBind(portName="1/2/9") + protocolObj.verifyDhcpClientBind(protocol="ipv4") + protocolObj.verifyDhcpClientBind(portName="1/2/9") Returns: - Dictionary {'Idle': {'Device Group 4': {'Client2': [1, 2, 3, 4]}, 'DHCPv6 Client': {'Client1': [3]}}, + Dictionary {'Idle': {'Device Group 4': {'Client2': [1, 2, 3, 4]}, 'DHCPv6 Client': + {'Client1': [3]}}, 'Bound': {'DHCPv6 Client': {'Client1': [1, 2, 4]}}, 'boundCount': 3} """ - portName = kwargs.get('portName',None) - if protocol == None: - protocols = ['ipv4','ipv6'] + portName = kwargs.get('portName', None) + if protocol is None: + protocols = ['ipv4', 'ipv6'] else: protocols = [protocol] boundCount = 0 idleBoundDict = {} ibList = [] + deviceGroupObjList = None for protocol in protocols: - self.ixnObj.logInfo('Verifying DHCP IDLE/BOUND/NOTSTARTED for {0} protocol'.format(protocol)) + self.ixnObj.logInfo('Verifying DHCP IDLE/BOUND/NOTSTARTED for {0} protocol'.format( + protocol)) deviceList = [] if portName: - #Get all deviceGroups configured with Port - ProtocolList = self.getProtocolListByPortNgpf(portName=portName) - topology = ProtocolList['deviceGroup'][0][0].split("deviceGroup")[0] - response = self.ixnObj.get(self.ixnObj.httpHeader + topology + '/deviceGroup') - for deviceGroupObj in response.json(): - deviceList.append(deviceGroupObj['name']) - elif deviceGroupName == None: - # Get all deviceGroups in all topology lists + protocolList = self.getProtocolListByPortNgpf(portName=portName) + topologyHref = protocolList['topology'] + topologyList = self.getAllTopologyList() + for topology in topologyList: + if topologyHref == topology.href: + deviceGroupObjList = topology.DeviceGroup.find() + break + + if deviceGroupObjList is not None: + for deviceGroupObj in deviceGroupObjList: + deviceList.append(deviceGroupObj.Name) + elif deviceGroupName is None: topologyList = self.getAllTopologyList() - #['/api/v1/sessions/1/ixnetwork/topology/1', '/api/v1/sessions/1/ixnetwork/topology/2'] for topology in topologyList: - response = self.ixnObj.get(topology + '/deviceGroup') - for deviceGroupObj in response.json(): - deviceList.append(deviceGroupObj['name']) + deviceGroupObjList = topology.DeviceGroup.find() + for deviceGroupObj in deviceGroupObjList: + deviceList.append(deviceGroupObj.Name) else: deviceList.append(deviceGroupName) ethObjList = self.getEndpointObjByDeviceGroupName(deviceGroupName, 'ethernet') - if ethObjList == []: + if not ethObjList: raise IxNetRestApiException("Device Group not configured") for eachDevice in deviceList: @@ -5933,28 +4841,25 @@ def verifyDhcpClientBind(self, deviceGroupName=None, protocol=None, **kwargs): ethObjList = self.getEndpointObjByDeviceGroupName(eachDevice, 'ethernet') for ethObj in ethObjList: - ethObj = '/api'+ ethObj.split('/api')[1] if protocol == 'ipv6': - response = self.ixnObj.get(self.ixnObj.httpHeader + ethObj + '/dhcpv6client?includes=count') + dhcpClientList = ethObj.Dhcpv6client.find() else: - response = self.ixnObj.get(self.ixnObj.httpHeader + ethObj + '/dhcpv4client?includes=count') + dhcpClientList = ethObj.Dhcpv4client.find() - for dhcpClient in response.json(): - dhcpClientObjList.append(dhcpClient['links'][0]['href']) + for dhcpClient in dhcpClientList: + dhcpClientObjList.append(dhcpClient) for dhcpClientObj in dhcpClientObjList: idleDhcpDict = {} boundDhcpDict = {} - #dhcpClientObj = '/api/v1/sessions/1/ixnetwork/topology/1/deviceGroup/2/ethernet/1/dhcpv4client/1' - response = self.ixnObj.get(self.ixnObj.httpHeader + dhcpClientObj + '?includes=name') - dhcpObjName = str(response.json()['name']) - response = self.ixnObj.get(self.ixnObj.httpHeader + dhcpClientObj + '?includes=count') - dhcpClientObjDeviceCount = response.json()['count'] - response = self.ixnObj.get(self.ixnObj.httpHeader + dhcpClientObj + '?includes=discoveredAddresses') - discoveredAddressList = response.json()['discoveredAddresses'] + dhcpObjName = str(dhcpClientObj.Name) + dhcpClientObjDeviceCount = dhcpClientObj.Count + discoveredAddressList = dhcpClientObj.DiscoveredAddresses - idleList = [count+1 for count in range(dhcpClientObjDeviceCount) if('[Unresolved]' in discoveredAddressList[count])] - boundList = [count+1 for count in range(dhcpClientObjDeviceCount) if('[Unresolved]' not in discoveredAddressList[count])] + idleList = [count + 1 for count in range(dhcpClientObjDeviceCount) if + ('[Unresolved]' in discoveredAddressList[count])] + boundList = [count + 1 for count in range(dhcpClientObjDeviceCount) if + ('[Unresolved]' not in discoveredAddressList[count])] if idleList: idleDhcpDict[dhcpObjName] = idleList @@ -5965,9 +4870,10 @@ def verifyDhcpClientBind(self, deviceGroupName=None, protocol=None, **kwargs): boundCount += len(boundList) - idleBoundDict['Idle'] = {str(ele[1]):ele[2] for ele in filter(lambda x:x[0]=='Idle',ibList)} - idleBoundDict['Bound'] = {str(ele[1]):ele[2] for ele in filter(lambda x:x[0]=='Bound',ibList)} + idleBoundDict['Idle'] = {str(ele[1]): ele[2] for ele in + filter(lambda x: x[0] == 'Idle', ibList)} + idleBoundDict['Bound'] = {str(ele[1]): ele[2] for ele in + filter(lambda x: x[0] == 'Bound', ibList)} idleBoundDict['boundCount'] = boundCount return idleBoundDict - diff --git a/RestApi/Python/Modules/IxNetRestApiQuickTest.py b/RestApi/Python/Modules/IxNetRestApiQuickTest.py index afefdb85..867f43ce 100644 --- a/RestApi/Python/Modules/IxNetRestApiQuickTest.py +++ b/RestApi/Python/Modules/IxNetRestApiQuickTest.py @@ -1,17 +1,19 @@ -import re, time +import re +import time from IxNetRestApi import IxNetRestApiException from IxNetRestApiFileMgmt import FileMgmt + 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): - # For Python Robot Framework support self.ixnObj = mainObject self.fileMgmtObj.setMainObject(mainObject) @@ -21,57 +23,80 @@ def getAllQuickTestHandles(self): 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 + [ ] + """ + 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(): - response = self.ixnObj.get(self.ixnObj.httpHeader+eachQtHandle) - quickTestNameList.append(response.json()['name']) + 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(): - response = self.ixnObj.get(self.ixnObj.httpHeader+quickTestHandle) - currentQtName = response.json()['name'] - if (bool(re.match(quickTestName, currentQtName, re.I))): + 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): """ - quickTestHandle = /api/v1/sessions/1/ixnetwork/quickTest/rfc2544throughput/2 + Description : + Get the Quick Test Name by quick test Handle + Parameter : + quickTestHandle = """ - response = self.ixnObj.get(self.ixnObj.httpHeader + quickTestHandle) - return response.json()['name'] + if quickTestHandle.Name: + return quickTestHandle.Name + else: + raise Exception("Unable to find quicktest name for given handle") def getQuickTestDuration(self, quickTestHandle): """ - quickTestHandle = /api/v1/sessions/1/ixnetwork/quickTest/rfc2544throughput/2 + Description : + Get Quick Test Test Duration Time in Sec + Parameter : + quickTestHandle = """ - response = self.ixnObj.get(self.ixnObj.httpHeader + quickTestHandle + '/testConfig') - return response.json()['duration'] + + return quickTestHandle.TestConfig.Duration def getQuickTestTotalFrameSizesToTest(self, quickTestHandle): """ - quickTestHandle = /api/v1/sessions/1/ixnetwork/quickTest/rfc2544throughput/2 + Description : + Get Quick Test Test Total Frame Sizes + Parameter : + quickTestHandle = """ - response = self.ixnObj.get(self.ixnObj.httpHeader + quickTestHandle + '/testConfig') - return response.json()['framesizeList'] + + return quickTestHandle.TestConfig.FramesizeList def applyQuickTest(self, qtHandle): """ @@ -81,92 +106,92 @@ def applyQuickTest(self, qtHandle): 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') + try: + qtHandle.Apply() + except Exception as err: + raise Exception("Operation apply quicktest failed with error :\n {}".format(err)) 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') + Description : + Returns current action like 'InitializingTest', 'ApplyFlowGroups', + 'SetupStatisticsCollection', etc. + Parameter : + quickTestHandle = + """ + 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 response.json()['currentActions'][-1]['arg2'] - else: - response = self.ixnObj.get(self.ixnObj.httpHeader+quickTestHandle+'/results') - return response.json()['progress'] + return currentActions[-1]['arg2'] def verifyQuickTestInitialization(self, quickTestHandle): """ - quickTestHandle = /api/v1/sessions/1/ixnetwork/quickTest/rfc2544throughput/2 + Parameter : + quickTestHandle = """ - for timer in range(1,20+1): + + for timer in range(1, 20+1): currentAction = self.getQuickTestCurrentAction(quickTestHandle) - print('verifyQuickTestInitialization currentState: %s' % currentAction) + 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)) + 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'] + for counter in range(1, applyQuickTestCounter+1): currentAction = self.getQuickTestCurrentAction(quickTestHandle) - if currentAction == None: + if currentAction is 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') + 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 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)) + 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): """ @@ -175,18 +200,14 @@ def startQuickTest(self, quickTestHandle): 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 + 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): """ @@ -195,26 +216,22 @@ def stopQuickTest(self, quickTestHandle): 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 + 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. (Classic Framework is not supported in REST) + For Linux API server only, it must be a NGPF configuration. Parameters - quickTestHandle: /api/v1/sessions/{1}/ixnetwork/quickTest/rfc2544throughput/2 + quickTestHandle: quick test handle """ isRunningBreakFlag = 0 trafficStartedFlag = 0 @@ -222,14 +239,14 @@ def monitorQuickTestRunningProgress(self, quickTestHandle, getProgressInterval=1 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: + 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)) + self.ixnObj.logInfo('isRunning=True. Waiting for trial runs {0}/30 ' + 'seconds'.format(waitForRunningProgressCounter)) waitForRunningProgressCounter += 1 time.sleep(1) if waitForRunningProgressCounter == 30: @@ -247,20 +264,22 @@ def monitorQuickTestRunningProgress(self, quickTestHandle, getProgressInterval=1 self.ixnObj.logInfo('\nisRunning=False. Quick Test is complete') return 0 if isRunningBreakFlag < 20: - print('isRunning=False. Wait {0}/20 seconds'.format(isRunningBreakFlag)) + 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:', response.json()['status']) + raise IxNetRestApiException('Quick Test failed to start:') def getQuickTestResultPath(self, quickTestHandle): """ - quickTestHandle = /api/v1/sessions/1/ixnetwork/quickTest/rfc2544throughput/2 + quickTestHandle = The quick test handle """ - 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'] + 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): """ @@ -273,7 +292,8 @@ def getQuickTestResult(self, quickTestHandle, attribute): 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 + 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 @@ -283,8 +303,9 @@ def getQuickTestResult(self, quickTestHandle, attribute): duration - Returns 00:01:03 currentViews """ - response = self.ixnObj.get(quickTestHandle+'/results') - return response.json()[attribute] + attribute = attribute[0].upper() + attribute[1:] + result = getattr(quickTestHandle.Results, attribute) + return result def getQuickTestCsvFiles(self, quickTestHandle, copyToPath, csvFile='all'): """ @@ -301,10 +322,12 @@ def getQuickTestCsvFiles(self, quickTestHandle, copyToPath, csvFile='all'): 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) + resultsPath = quickTestHandle.Results.ResultPath self.ixnObj.logInfo('\ngetQuickTestCsvFiles: %s' % resultsPath) + if csvFile == 'all': - getCsvFiles = ['AggregateResults.csv', 'iteration.csv', 'results.csv', 'logFile.txt', 'portMap.csv'] + getCsvFiles = ['AggregateResults.csv', + 'iteration.csv', 'results.csv', 'logFile.txt', 'portMap.csv'] else: if type(csvFile) is not list: getCsvFiles = [csvFile] @@ -314,15 +337,18 @@ def getQuickTestCsvFiles(self, quickTestHandle, copyToPath, csvFile='all'): 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) + windowsSource = resultsPath + '\\{0}'.format(eachCsvFile) + if '\\' in copyToPath: + self.fileMgmtObj.copyFileWindowsToLocalWindows(windowsSource, copyToPath) else: - self.fileMgmtObj.copyFileWindowsToLocalLinux(resultsPath+'\\{0}'.format(eachCsvFile), copyToPath) + self.fileMgmtObj.copyFileWindowsToLocalLinux(windowsSource, copyToPath) + else: - # TODO: Copy from Linux to Windows and Linux to Linux. - pass + linuxSource = resultsPath + '/{0}'.format(eachCsvFile) + self.fileMgmtObj.copyFileLinuxToLocalLinux(linuxSource, copyToPath) - def getQuickTestPdf(self, quickTestHandle, copyToLocalPath, where='remoteLinux', renameDestinationFile=None, includeTimestamp=False): + def getQuickTestPdf(self, quickTestHandle, copyToLocalPath, where='remoteLinux', + renameDestinationFile=None, includeTimestamp=False): """ Description Generate Quick Test result to PDF and retrieve the PDF result file. @@ -331,26 +357,24 @@ def getQuickTestPdf(self, quickTestHandle, copyToLocalPath, where='remoteLinux', 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']) + 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): """ @@ -359,7 +383,7 @@ def runQuickTest(self, quickTestName, timeout=90): Parameter quickTestName: : name of the quick test to run - timeout: : duration for quick test to run. Default=90 seconds + timeout: : timeout duration handles internally in Restpy Example runQuickTest("Macro_17_57_14_294", timeout=180) @@ -369,11 +393,10 @@ def runQuickTest(self, quickTestName, timeout=90): Note: operation run will keep checking the status of execution for the specified timeout """ eventSchedulerHandle = self.getQuickTestHandleByName(quickTestName) - - url = self.ixnObj.sessionUrl + '/quickTest/eventScheduler/operations/run' - data = {"arg1": eventSchedulerHandle} - response = self.ixnObj.post(url, data=data) - self.ixnObj.waitForComplete(response, url + '/' + response.json()['id'], timeout=timeout) + try: + eventSchedulerHandle.Run() + except Exception as err: + raise Exception("Run quicktest operation failed with error : \n {}".format(err)) def deleteQuickTest(self, quickTestName): """ @@ -389,10 +412,11 @@ def deleteQuickTest(self, quickTestName): Return """ eventSchedulerHandle = self.getQuickTestHandleByName(quickTestName) - - #delete the quick test - url = self.ixnObj.httpHeader + eventSchedulerHandle - self.ixnObj.delete(url) + 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): """ @@ -410,14 +434,12 @@ def configQuickTest(self, quickTestName, numOfTrials=1): Return event scheduler handle on success or exception on failure """ - url = self.ixnObj.sessionUrl + '/quickTest/eventScheduler' - response = self.ixnObj.post(url, data={"forceApplyQTConfig": "true", "mode": "existingMode", "name": quickTestName}) - - eventSchedulerHandle = response.json()["links"][0]["href"] - url = self.ixnObj.httpHeader + eventSchedulerHandle + '/eventScheduler' - self.ixnObj.post(url, data={"enabled": "true", "itemId": quickTestName, "itemName": quickTestName}) - - url = self.ixnObj.httpHeader + eventSchedulerHandle + '/testConfig' - self.ixnObj.patch(url, data={"numTrials": numOfTrials}) - - return eventSchedulerHandle \ No newline at end of file + 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)) diff --git a/RestApi/Python/Modules/IxNetRestApiStatistics.py b/RestApi/Python/Modules/IxNetRestApiStatistics.py index 2a65e287..7d17be67 100644 --- a/RestApi/Python/Modules/IxNetRestApiStatistics.py +++ b/RestApi/Python/Modules/IxNetRestApiStatistics.py @@ -1,13 +1,15 @@ -import re, time -from IxNetRestApi import IxNetRestApiException +import csv +import datetime + from IxNetRestApiFileMgmt import FileMgmt +from ixnetwork_restpy.assistants.statistics.statviewassistant import StatViewAssistant + class Statistics(object): def __init__(self, ixnObj=None): self.ixnObj = ixnObj - - # For takesnapshot() self.fileMgmtObj = FileMgmt(self.ixnObj) + self.ixNetwork = ixnObj.ixNetwork def setMainObject(self, mainObject): """ @@ -16,15 +18,14 @@ def setMainObject(self, mainObject): """ self.ixnObj = mainObject - def getStats(self, viewObject=None, viewName='Flow Statistics', csvFile=None, csvEnableFileTimestamp=False, - displayStats=True, silentMode=True, ignoreError=False): + 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 . @@ -32,31 +33,30 @@ def getStats(self, viewObject=None, viewName='Flow Statistics', csvFile=None, cs Provide a .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. + 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 + 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. + 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): + + 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. - This method uses deprecated APIs effective IxNetwork version 8.50: /statistics/statView//page - Starting 8.50, the new API to use is: /statistics/statView//data, which is in getStatsData() Parameters csvFile = None or . @@ -64,18 +64,20 @@ def getStatsPage(self, viewObject=None, viewName='Flow Statistics', csvFile=None Provide a .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. + 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 + 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. + You could get the statistic viewName directly from the IxNetwork GUI in the + statistics. 'Port Statistics' 'Tx-Rx Frame Rate Statistics' @@ -105,117 +107,55 @@ def getStatsPage(self, viewObject=None, viewName='Flow Statistics', csvFile=None 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 + 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: - 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 + csvFileName = csvFileNameTemp + '_' + timestamp + '.' + csvFileNameExtension else: - csvFileName = csvFileName+'_'+timestamp + 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() - # 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]) - + 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('\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 + 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): + 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 . @@ -223,15 +163,17 @@ def getStatsData(self, viewObject=None, viewName='Flow Statistics', csvFile=None Provide a .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. + 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 + 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. + You could get the statistic viewName directly from the IxNetwork GUI + in the statistics. 'Port Statistics' 'Tx-Rx Frame Rate Statistics' @@ -260,155 +202,79 @@ def getStatsData(self, viewObject=None, viewName='Flow Statistics', csvFile=None 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 + """ - 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 + 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: - 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 + csvFileName = csvFileNameTemp + '_' + timestamp + '.' + csvFileNameExtension else: - csvFileName = csvFileName+'_'+timestamp + 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() - 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]) - + 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('\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 + 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. """ - removeAllTclViewsUrl = self.ixnObj.sessionUrl+'/operations/removealltclviews' - response = self.ixnObj.post(removeAllTclViewsUrl) - self.ixnObj.waitForComplete(response, self.ixnObj.httpHeader + response.json()['url']) + 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'): + 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. + 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.. + 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: : Defaults to False. Set to True if you're getting the snapshot from Linux chassis. + isLinux: : 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. @@ -419,12 +285,16 @@ def takeSnapshot(self, viewName='Flow Statistics', windowsPath=None, isLinux=Fal Example: For Windows: - statObj.takeSnapshot(viewName='Flow Statistics', windowsPath='C:\\Results', localLinuxPath='/home/hgee', - renameDestinationFile='my_renamed_stat_file.csv', includeTimestamp=True) + 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') + statObj.takeSnapshot(viewName='Flow Statistics', + isLinux=True, localLinuxPath='/home/hgee') """ + location = None if mode == 'append': mode = 'kAppendCSVFile' @@ -436,8 +306,7 @@ def takeSnapshot(self, viewName='Flow Statistics', windowsPath=None, isLinux=Fal if isLinux: location = '/home/ixia_logs' - - data = {'arg1': [viewName], 'arg2': [ + self.ixNetwork.TakeViewCSVSnapshot(Arg1=[viewName], Arg2=[ "Snapshot.View.Contents: \"allPages\"", "Snapshot.View.Csv.Location: \"{0}\"".format(location), "Snapshot.View.Csv.GeneratingMode: \"%s\"" % mode, @@ -446,30 +315,28 @@ def takeSnapshot(self, viewName='Flow Statistics', windowsPath=None, isLinux=Fal "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) + 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) + 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. + Mainly used by internal APIs such as takeCsvSnapshot that requires the statistics + view object handle. Parameter viewName: Options (case sensitive): @@ -486,24 +353,16 @@ def getViewObject(self, viewName='Flow 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 + for viewObj in self.ixNetwork.Statistics.View.find(): + if viewObj.Caption == viewName: return viewObj - return None + 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. """ - url = self.ixnObj.sessionUrl + '/operations/clearstats' - response = self.ixnObj.post(url, data={'arg1': ['waitForPortStatsRefresh']}) - self.ixnObj.waitForComplete(response, self.ixnObj.httpHeader + response.json()['url']) + self.ixnObj.logInfo("Clearing all statistics") + self.ixNetwork.ClearStats(Arg1=['waitForPortStatsRefresh']) diff --git a/RestApi/Python/Modules/IxNetRestApiTraffic.py b/RestApi/Python/Modules/IxNetRestApiTraffic.py index 68ba944d..48fda1b5 100644 --- a/RestApi/Python/Modules/IxNetRestApiTraffic.py +++ b/RestApi/Python/Modules/IxNetRestApiTraffic.py @@ -1,62 +1,59 @@ -import re, time +import re +import time from IxNetRestApi import IxNetRestApiException + class Traffic(object): + def __init__(self, ixnObj=None): self.ixnObj = ixnObj + self.ixNetwork = ixnObj.ixNetwork def setMainObject(self, mainObject): # For Python Robot Framework support self.ixnObj = mainObject - - def configTrafficItem(self, mode=None, obj=None, trafficItem=None, endpoints=None, configElements=None): + + def configTrafficItem(self, mode=None, obj=None, trafficItem=None, endpoints=None, + configElements=None): """ Description Create or modify a Traffic Item. When creating a new Traffic Item, this API will return 3 object handles: - trafficItemObj, endpointSetObjList and configElementObjList + trafficItemObj, endpointSetObjList and configElementObjList. NOTE: Each Traffic Item could create multiple endpoints and for each endpoint. you could provide a list of configElements for each endpoint. The endpoints and configElements must be in a list. - - Each endpointSet allows you to configure the highLevelStream, which overrides configElements. - - If you set bi-directional to True, then there will be two highLevelStreams that you could configure. - - Including highLevelStream is optional. Set highLevelStream to None to use configElements. + - Each endpointSet allows you to configure the highLevelStream, which overrides + configElements. + - If you set bi-directional to True, then there will be two highLevelStreams that + you could configure. + - Including highLevelStream is optional. Set highLevelStream to None to use + configElements. Parameters mode: craete|modify - obj: For "mode=modify" only. Provide the object to modify: trafficItemObj|configElementObj|endpointObj + obj: For "mode=modify" only. Provide the object to modify: trafficItemObj| + configElementObj|endpointObj trafficItem: Traffic Item kwargs. - endpoints: [list]: A list: [{name: sources:[], destionations:[], highLevelStreams: None, (add more endpoints)... ] - Scroll down to see example. + endpoints: [list]: A list: [{name: sources:[], destionations:[], highLevelStreams: None, + (add more endpoints)... ] - configElements: [list]: Config Element kwargs. - Each item in this list is aligned to the sequential order of your endpoint list. + configElements: [list]: Config Element kwargs. Each item in this list is aligned to the + sequential order of your endpoint list. If mode is create: The required parameters are: mode, trafficItem, endpoints and configElements If mode is modify: - The required parameters are: mode, obj, and one of the objects to modify (trafficIemObj, endpointObj or configElementObj). - - You need to provide the right object handle. - - To modify trafficItem: - Ex: /api/v1/sessions/1/ixnetwork/traffic/trafficItem/ - - To modify endpointSet: - Ex: /api/v1/sessions/1/ixnetwork/traffic/trafficItem/1/endpointSet/ - - To modify configElements = configElement object handlex - Ex: /api/v1/sessions/1/ixnetwork/traffic/trafficItem/1/configElement/ - - Look at sample script l2l3RestNgpy.py + The required parameters are: mode, obj, and one of the objects to modify (trafficIemObj, + endpointObj or configElementObj). Traffic Item Parameters trafficType options: @@ -71,9 +68,10 @@ def configTrafficItem(self, mode=None, obj=None, trafficItem=None, endpoints=Non allowSelfDestined: True or False - trackBy: [list]: trackingenabled0, ethernetIiSourceaddress0, ethernetIiDestinationaddress0, ethernetIiPfcQueue0, - vlanVlanId0, vlanVlanUserPriority0, ipv4SourceIp0, sourceDestValuePair0, sourceDestEndpointPair0, - ipv4Precedence0, ipv4SourceIp0, flowGroup0, frameSize0 + trackBy: [list]: trackingenabled0, ethernetIiSourceaddress0, ethernetIiPfcQueue0, + ethernetIiDestinationaddress0, vlanVlanId0, vlanVlanUserPriority0, ipv4SourceIp0, + sourceDestValuePair0, sourceDestEndpointPair0, ipv4Precedence0, ipv4SourceIp0, + flowGroup0, frameSize0 ConfigElement Parameters transmissionType: @@ -84,16 +82,19 @@ def configTrafficItem(self, mode=None, obj=None, trafficItem=None, endpoints=Non burstPacketCount: (For bursty traffic) frameSizeType: fixed|random frameSize: The packet size. - + frameRate: The rate to transmit packets frameRateType: bitsPerSecond|framesPerSecond|interPacketGap|percentLineRate - frameRateBitRateUnitsType: bitsPerSec|bytesPerSec|kbitsPerSec|kbytesPerSec|mbitsPerSec|mbytesPerSec + frameRateBitRateUnitsType: bitsPerSec|bytesPerSec|kbitsPerSec|kbytesPerSec| + mbitsPerSec|mbytesPerSec duration: Set fixedDuration - portDistribution: applyRateToAll|splitRateEvenly. Default=applyRateToAll - streamDistribution: splitRateEvenly|applyRateToAll. Default=splitRateEvently - trackBy: : Some options: flowGroup0, vlanVlanId0, ethernetIiDestinationaddress0, ethernetIiSourceaddress0, - sourcePort0, sourceDestPortPair0, ipv4DestIp0, ipv4SourceIp0, ipv4Precedence0, - ethernetIiPfcQueue0, frameSize0 + portDistribution: applyRateToAll|splitRateEvenly. + Default=applyRateToAll + streamDistribution: splitRateEvenly|applyRateToAll. + Default=splitRateEvently + trackBy: : Some options: flowGroup0, vlanVlanId0, ethernetIiDestinationaddress0, + ethernetIiSourceaddress0, sourcePort0, sourceDestPortPair0, ipv4DestIp0, + ipv4SourceIp0, ipv4Precedence0, ethernetIiPfcQueue0, frameSize0 If frameSizeType == random incrementFrom: Frame size increment from. @@ -108,27 +109,10 @@ def configTrafficItem(self, mode=None, obj=None, trafficItem=None, endpoints=Non sources: Object in a list. destinations: Object in a lsit. - Example: - ['/api/v1/sessions/1/ixnetwork/topology/8'] - or a list ['.../topology/1', '.../topology/3'] - ['.../topology/1/deviceGroup/1', '.../topology/2/deviceGroup/1/ethernet/1/ipv4/1'] - - - USAGE EXAMPLE: - To modify: - trafficObj.configTrafficItem(mode='modify', - obj='/api/v1/sessions/1/ixnetwork/traffic/trafficItem/1/configElement/1', - configElements={'transmissionType': 'continuous'}) - - trafficObj.configTrafficItem(mode='modify', - obj='/api/v1/sessions/1/ixnetwork/traffic/trafficItem/1', - trafficItem={'trackBy': ['frameSize0', 'ipv4SourceIp0']}) - To create new Traffic Item: configTrafficItem(mode='create', - trafficItem = { - 'name':'Topo1 to Topo2', + trafficItem = {'name':'Topo1 to Topo2', 'trafficType':'ipv4', 'biDirectional':True, 'srcDestMesh':'one-to-one', @@ -138,272 +122,244 @@ def configTrafficItem(self, mode=None, obj=None, trafficItem=None, endpoints=Non endpoints = [{'name':'Flow-Group-1', 'sources': [topologyObj1], - 'destinations': [topologyObj2], + 'destinations': [topologyObj2], 'highLevelStreamElements': None}], - configElements = [{'transmissionType': 'fixedFrameCount', + configElements = [{'transmissionType': + 'fixedFrameCount', 'frameCount': 50000, 'frameRate': 88, - 'frameRateType': 'percentLineRate', + 'frameRateType':'percentLineRate', 'frameSize': 128, - 'portDistribution': 'applyRateToAll', - 'streamDistribution': 'splitRateEvenly' + 'portDistribution':'applyRateToAll', + 'streamDistribution':'splitRateEvenly' }] ) To create a new Traffic Item and configure the highLevelStream: trafficObj.configTrafficItem(mode='create', - trafficItem = {'name':'Topo3 to Topo4', + trafficItem ={'name':'Topo3 to Topo4', 'trafficType':'ipv4', 'biDirectional':True, 'srcDestMesh':'one-to-one', 'routeMesh':'oneToOne', 'allowSelfDestined':False, - 'trackBy': ['flowGroup0', 'vlanVlanId0']}, + 'trackBy':['flowGroup0', + 'vlanVlanId0']}, endpoints = [{'name':'Flow-Group-1', - 'sources': [topologyObj1], - 'destinations': [topologyObj2], - 'highLevelStreamElements': [ + 'sources':[topologyObj1], + 'destinations':[topologyObj2], + 'highLevelStreamElements': + [ { + 'transmissionType':'fixedFrameCount', + 'frameCount':10000, + 'frameRate': 18, + 'frameRateType':'percentLineRate', + 'frameSize': 128}, { - 'transmissionType': 'fixedFrameCount', - 'frameCount': 10000, - 'frameRate': 18, - 'frameRateType': 'percentLineRate', - 'frameSize': 128}, - { - 'transmissionType': 'fixedFrameCount', - 'frameCount': 20000, + 'transmissionType':'fixedFrameCount', + 'frameCount':20000, 'frameRate': 28, - 'frameRateType': 'percentLineRate', - 'frameSize': 228} + 'frameRateType':'percentLineRate', + 'frameSize':228} ] }], configElements = None) - + Return: trafficItemObj, endpointSetObjList, configElementObjList """ - if mode == 'create': - trafficItemUrl = self.ixnObj.sessionUrl+'/traffic/trafficItem' + + configElementObj = None + trafficItemObj = None + endPointSetObj = None if mode == 'modify' and obj is None: raise IxNetRestApiException('Modifying Traffic Item requires a Traffic Item object') if mode == 'create' and trafficItem is None: raise IxNetRestApiException('Creating Traffic Item requires trafficItem kwargs') - if mode == None: - raise IxNetRestApiException('configTrafficItem Error: Must include mode: config or modify') - - # Don't configure config elements if user is configuring highLevelStreams - isHighLevelStreamTrue = False + if mode is None: + raise IxNetRestApiException('configTrafficItem Error: Must include mode: config or ' + 'modify') - # Create a new Traffic Item - if mode == 'create' and trafficItem != None: - if 'trackBy' in trafficItem: - trackBy = trafficItem['trackBy'] - del trafficItem['trackBy'] + if mode == 'create' and trafficItem is not None: + trafficItemObj = self.ixNetwork.Traffic.TrafficItem.add() - self.ixnObj.logInfo('configTrafficItem: %s : %s' % (trafficItemUrl, trafficItem), timestamp=False) - response = self.ixnObj.post(trafficItemUrl, data=trafficItem) - trafficItemObj = response.json()['links'][0]['href'] - - if mode == 'modify' and trafficItem != None: + for item, value in trafficItem.items(): + if item != 'trackBy': + itemObj = item[0:1].capitalize() + item[1:] + setattr(trafficItemObj, itemObj, value) + else: + trafficItemObj.Tracking.find().TrackBy = value + + if endpoints is not None and trafficItemObj is not None: + for endPoint in endpoints: + endPointSetObj = trafficItemObj.EndpointSet.add( + Name=endPoint['name'], + Sources=endPoint['sources'], + Destinations=endPoint['destinations'] + ) + + if configElements != "" and trafficItemObj is not None: + configElementObj = trafficItemObj.ConfigElement.find() + + for configEle in configElements: + if 'transmissionType' in configEle: + configElementObj.TransmissionControl.Type = configEle['transmissionType'] + del configEle['transmissionType'] + + if 'frameCount' in configEle: + configElementObj.TransmissionControl.FrameCount = configEle['frameCount'] + del configEle['frameCount'] + + if 'frameRate' in configEle: + configElementObj.FrameRate.Rate = configEle['frameRate'] + del configEle['frameRate'] + + if 'frameRateType' in configEle: + configElementObj.FrameRate.Type = configEle['frameRateType'] + del configEle['frameRateType'] + + if 'frameSize' in configEle: + configElementObj.FrameSize.FixedSize = configEle['frameSize'] + del configEle['frameSize'] + + if 'portDistribution' in configEle: + configElementObj.FrameRateDistribution.PortDistribution \ + = configEle['portDistribution'] + del configEle['portDistribution'] + + if 'streamDistribution' in configEle: + configElementObj.FrameRateDistribution.StreamDistribution \ + = configEle['streamDistribution'] + del configEle['streamDistribution'] + + elif mode == 'modify': trafficItemObj = obj - if 'trackBy' in trafficItem: - trackBy = trafficItem['trackBy'] - del trafficItem['trackBy'] - self.ixnObj.patch(self.ixnObj.httpHeader+trafficItemObj, data=trafficItem) - - # Create Endpoints - if mode == 'create' and endpoints != None: - if type(endpoints) != list: - raise IxNetRestApiException('configTrafficItem error: Provide endpoints in a list') - - endpointSetObjList = [] - if 'trafficItemObj' not in locals(): - # Expect the user to pass in the endpoint object handle correctly and parse - # out the traffic item object handle. - trafficItemObj = self.ixnObj.sessionUrl.split('/endpointSet')[0] - - # endpoints = [{'name':'Flow-Group-1', 'sources': [topologyObj1], 'destinations': [topologyObj2], 'highLevelStreamElements': None}] - for endPoint in endpoints: - endpointSrcDst = {} - # {'name':'Flow-Group-1', 'sources': [topologyObj1], 'destinations': [topologyObj2]} - if 'name' in endPoint: - endpointSrcDst['name'] = endPoint['name'] - - if 'sources' in endPoint: - endpointSrcDst['sources'] = endPoint['sources'] - - if 'destinations' in endPoint: - endpointSrcDst['destinations'] = endPoint['destinations'] - - if 'multicastDestinations' in endPoint: - endpointSrcDst['multicastDestinations'] = endPoint['multicastDestinations'] - - if 'multicastReceivers' in endPoint: - endpointSrcDst['multicastReceivers'] = endPoint['multicastReceivers'] - - if 'scalableDestinations' in endPoint: - endpointSrcDst['scalableDestinations'] = endPoint['scalableDestinations'] - - if 'scalableSources' in endPoint: - endpointSrcDst['scalableSources'] = endPoint['scalableSources'] - - response = self.ixnObj.post(self.ixnObj.httpHeader+trafficItemObj+'/endpointSet', data=endpointSrcDst) - - if 'highLevelStreamElements' in endPoint: - highLevelStream = endPoint['highLevelStreamElements'] - # JSON doesn't support None. In case user passed in {} instead of None. - if highLevelStream == {}: - highLevelStream = None + + if trafficItem is not None: + for item, value in trafficItem.item(): + if item != 'trackBy': + itemObj = item[0:1].capitalize() + item[1:] + setattr(trafficItemObj, itemObj, trafficItem[item]) + else: + trafficItemObj.Tracking.find().Values = trafficItem['trackBy'] + + endPointSetObj = trafficItemObj.EndpointSet.find() + if endpoints is not None and trafficItemObj is not None: + if 'name' in endpoints: + endPointSetObj = trafficItemObj.EndpointSet.find(Name=endpoints['name']) + endPointSetObj.Sources = endpoints['sources'] + endPointSetObj.Destinations = endpoints['destinations'] else: - highLevelStream = None - - # Get the RETURNED endpointSet/# object - endpointSetObj = response.json()['links'][0]['href'] - response = self.ixnObj.get(self.ixnObj.httpHeader+endpointSetObj) - - # This endpontSet ID is used for getting the corresponding Config Element ID - # in case there are multiple endpoint sets created. - endpointSetId = response.json()['id'] - endpointSetObjList.append(endpointSetObj) - - # An endpoint flow group could have two highLevelStream if bi-directional is enabled.x - if highLevelStream != None: - isHighLevelStreamTrue = True - configElementObjList = None ;# Don't configure config elements if user is configuring highLevelStreams - streamNum = 1 - for eachHighLevelStream in highLevelStream: - self.configConfigElements(self.ixnObj.httpHeader+trafficItemObj+'/highLevelStream/'+str(streamNum), eachHighLevelStream) - streamNum += 1 - - if mode == 'modify' and endpoints != None: - endpointSrcDst = {} - if 'name' in endpoints: - endpointSrcDst['name'] = endpoints['name'] - if 'sources' in endpoints: - endpointSrcDst['sources'] = endpoints['sources'] - if 'destinations' in endpoints: - endpointSrcDst['destinations'] = endpoints['destinations'] - - endpointSetObj = obj - self.ixnObj.patch(self.ixnObj.httpHeader+endpointSetObj, data=endpointSrcDst) - - if isHighLevelStreamTrue == False and configElements != None: - if mode == 'create' and type(configElements) != list: - raise IxNetRestApiException('configTrafficItem error: Provide configElements in a list') - - if mode == 'modify': - configElementObj = obj - self.configConfigElements(self.ixnObj.httpHeader+configElementObj, configElements) - - if mode == 'create': - endpointResponse = self.ixnObj.get(self.ixnObj.httpHeader+trafficItemObj+'/endpointSet') - - index = 0 - configElementCounter = 1 - configElementObjList = [] - for eachEndpoint in endpointResponse.json(): - configElementObj = trafficItemObj+'/configElement/'+str(configElementCounter) - configElementObjList.append(configElementObj) - self.configConfigElements(self.ixnObj.httpHeader+configElementObj, configElements[index]) - if len(endpointSetObjList) == len(configElements): - index += 1 - configElementCounter += 1 - - if configElements is None: - configElementObjList = [] - - # Cannot configure tracking until endpoints are created. This is why - # tracking config is at the end here. - if mode in ['create', 'modify'] and 'trackBy' in locals(): - self.ixnObj.logInfo('Config Traffic Item statistic trackings', timestamp=False) - self.ixnObj.patch(self.ixnObj.httpHeader+trafficItemObj+'/tracking', data={'trackBy': trackBy}) - - # API server needs some time to complete processing the highlevel stream configuration before entering regenerate. - if mode == 'create' and trafficItem != None: - return [trafficItemObj, endpointSetObjList, configElementObjList] + endPointSetObj = trafficItemObj.EndpointSet.add( + Name=endpoints['name'], + Sources=endpoints['sources'], + Destinations=endpoints['destinations']) + configElementObj = trafficItemObj.ConfigElement.find() + if configElements is not None and trafficItemObj is not None: + configElementObj = trafficItemObj.ConfigElement.find() + + if 'transmissionType' in configElements: + configElementObj.TransmissionControl.Type = configElements['transmissionType'] + del configElements['transmissionType'] + + if 'frameCount' in configElements: + configElementObj.TransmissionControl.FrameCount = configElements['frameCount'] + del configElements['frameCount'] + + if 'frameRate' in configElements: + configElementObj.FrameRate.Rate = configElements['frameRate'] + del configElements['frameRate'] + + if 'frameRateType' in configElements: + configElementObj.FrameRate.Type = configElements['frameRateType'] + del configElements['frameRateType'] + + if 'frameSize' in configElements: + configElementObj.FrameSize.FixedSize = configElements['frameSize'] + del configElements['frameSize'] + + if 'portDistribution' in configElements: + configElementObj.FrameRateDistribution.PortDistribution \ + = configElements['portDistribution'] + del configElements['portDistribution'] + + if 'streamDistribution' in configElements: + configElementObj.FrameRateDistribution.StreamDistribution \ + = configElements['streamDistribution'] + del configElements['streamDistribution'] + + return [trafficItemObj, endPointSetObj, configElementObj] def configConfigElements(self, configElementObj, configElements): """ Description - Configure Traffic Item Config Elements. This function will collect all the ReST API's attributes - and execute a PATCH in one single command instead of sending a a PATCH for each attribute. - This avoids dependency breakage because some APIs require the type to be configured first. + Configure Traffic Item Config Elements. This function will collect all the ReST API's + attributes and execute a PATCH in one single command instead of sending a a PATCH for + each attribute.This avoids dependency breakage because some APIs require the type to be + configured first. - This function also handles high level stream configurations since the attributes are the same. - Pass in the highLevelStream obj for the parameter configElementObj + This function also handles high level stream configurations since the attributes are the + same. Pass in the highLevelStream obj for the parameter configElementObj Parameters configElementObj: : The config element object: - Ex: /api/v1/sessions/{1}/ixnetwork/traffic/trafficItem/{1}/configElement/{1} - highLevelStream obj Ex: /api/v1/sessions/{1}/ixnetwork/traffic/trafficItem/{1}/highLevelStream/{1} - - configElements: : This could also be highLevelStream elements. - configElements = {'transmissionType': 'fixedFrameCount', - 'frameCount': 50000, - 'frameRate': 88, - 'frameRateType': 'percentLineRate', - 'frameSize': 128, - 'portDistribution': 'applyRateToAll', - 'streamDistribution': 'splitRateEvenly' + configElements: : This could also be highLevelStream elements. + configElements = { + 'transmissionType':'fixedFrameCount', + 'frameCount': 50000, + 'frameRate': 88, + 'frameRateType':'percentLineRate', + 'frameSize': 128, + 'portDistribution':'applyRateToAll', + 'streamDistribution':'splitRateEvenly' } transmissionType: fixedFrameCount|continuous|fixedDuration - incrementFrom: For frameSizeType = random. Frame size from size. - incrementTo: For frameSizeType = random. Frame size to size. - frameRateType: bitsPerSecond|percentLineRate|framesPerSecond - frameRateBitRateUnitsType: bitsPerSec|bytesPerSec|kbitsPerSec|kbytesPerSec|mbitsPerSec|mbytesPerSec - portDistribution: applyRateToAll|splitRateEvenly. Default=applyRateToAll - streamDistribution: splitRateEvenly|applyRateToAll. Default=splitRateEvently - """ - transmissionControlData = {} - frameRateData = {} - frameRateDistribution = {} - for item in configElements.keys() : - # These attributes are int type - if item in ['burstPacketCount', 'duration', 'frameCount', 'interBurstGap', 'interStreamGap', - 'iterationCount', 'minGapBytes', 'repeatBurst', 'startDelay']: - transmissionControlData.update({item: int(configElements[item])}) - - if item in ['enableInterBurstGap', 'enableInterStreamGap','interBurstGapUnits', - 'startDelayUnits', 'type']: - transmissionControlData.update({item: str(configElements[item])}) - - if item == 'frameRateType': - frameRateData.update({'type': str(configElements[item])}) - - if item == 'frameRate': - frameRateData.update({'rate': float(configElements[item])}) - - if item == 'frameRateBitRateUnitsType': - frameRateData.update({'bitRateUnitsType': str(configElements[item])}) - - if item == 'portDistribution': - frameRateDistribution.update({'portDistribution': configElements[item]}) - - if item == 'streamDistribution': - frameRateDistribution.update({'streamDistribution': configElements[item]}) - - # Note: transmissionType is not an attribute in configElement. It is created to be more descriptive than 'type'. + incrementFrom:For frameSizeType = random. Frame size from size. + incrementTo:For frameSizeType = random. Frame size to size. + frameRateType: bitsPerSecond|percentLineRate|framesPerSecond + frameRateBitRateUnitsType:bitsPerSec|bytesPerSec|kbitsPerSec|kbytesPerSec| + mbitsPerSec|mbytesPerSec + portDistribution:applyRateToAll|splitRateEvenly.Default=applyRateToAll + streamDistribution: splitRateEvenly|applyRateToAll. + Default=splitRateEvently + """ + for item in configElements.keys(): + if item in ['enableInterBurstGap', 'enableInterStreamGap', 'interBurstGapUnits', + 'startDelayUnits', 'type', 'burstPacketCount', 'duration', 'frameCount', + 'interBurstGap', 'interStreamGap', 'iterationCount', 'minGapBytes', + 'repeatBurst', 'startDelay']: + itemObj = item[0:1].capitalize() + item[1:] + setattr(configElementObj.TransmissionControl, itemObj, str(configElements[item])) + + if item == 'frameRateType': + configElementObj.FrameRate.Type = str(configElements[item]) + + if item == 'frameRate': + configElementObj.FrameRate.Rate = float(configElements[item]) + + if item == 'frameRateBitRateUnitsType': + configElementObj.FrameRate.BitRateUnitsType = str(configElements[item]) + + if item == 'portDistribution': + configElementObj.FrameRateDistribution.PortDistribution = configElements[item] + + if item == 'streamDistribution': + configElementObj.FrameRateDistribution.StreamDistribution = configElements[item] + + # Note: transmissionType is not an attribute in configElement. + # It is created to be more descriptive than 'type'. if 'transmissionType' in configElements: - self.ixnObj.patch(configElementObj+'/transmissionControl', data={'type': configElements['transmissionType']}) - - if transmissionControlData != {}: - self.ixnObj.patch(configElementObj+'/transmissionControl', data=transmissionControlData) - - if frameRateData != {}: - self.ixnObj.patch(configElementObj+'/frameRate', data=frameRateData) - + configElementObj.TransmissionControl.Type = configElements['transmissionType'] if 'frameSize' in configElements: - self.ixnObj.patch(configElementObj+'/frameSize', data={'fixedSize': int(configElements['frameSize'])}) + configElementObj.FrameSize.FixedSize = int(configElements['frameSize']) if 'frameSizeType' in configElements: - self.ixnObj.patch(configElementObj+'/frameSize', data={'type': configElements['frameSizeType']}) + configElementObj.FrameSize.Type = configElements['frameSizeType'] if configElements['frameSizeType'] == 'random': - self.ixnObj.patch(configElementObj+'/frameSize', data={'incrementFrom': configElements['incrementFrom'], - 'incrementTo': configElements['incrementTo']}) - if frameRateDistribution != {}: - self.ixnObj.patch(configElementObj+'/frameRateDistribution', data=frameRateDistribution) + configElementObj.FrameSize.IncrementFrom = configElements['incrementFrom'] + configElementObj.FrameSize.IncrementTo = configElements['incrementTo'] def getConfigElementObj(self, trafficItemObj=None, trafficItemName=None, endpointSetName=None): """ @@ -413,11 +369,12 @@ def getConfigElementObj(self, trafficItemObj=None, trafficItemName=None, endpoin Use case #1: trafficItemName + endpointSetName Use case #2: trafficItemObj + endpointSetName - Use case #3: trafficItemName only (Will assume there is only one configElement object which will be returned) - Use case #4: trafficItemObj only (Will assume there is only one configElement object which will be returned) + Use case #3: trafficItemName only (Will assume there is + only one configElement object which will be returned) + Use case #4: trafficItemObj only (Will assume there is + only one configElement object which will be returned) Parameters - trafficItemObj: : The Traffic Item object. trafficItemName: : The Traffic Item name. endpointSetName: : The Traffic Item's EndpointSet name. @@ -427,72 +384,39 @@ def getConfigElementObj(self, trafficItemObj=None, trafficItemName=None, endpoin - Each EndpointSet has a unique object ID by default. - For each EndpointSet is created, a config element object is also created. - Each config element object handle is associated with an EndpointSet ID. - - To be able to get the right config element object handle, we need to query - for the EndpointSet that you need for modifying. + - To be able to get the right config element object handle, we need to query for + the EndpointSet that you need for modifying. - Another terminology for EndpointSet is FlowGroup. - - If you have multiple EndpointSets, you should give each EndpointSet a name - to make querying possible. - - Otherwise, this function will assume there is only one EndpointSet created which will be returned. + - If you have multiple EndpointSets, you should give each EndpointSet a name to + make querying possible. + - Otherwise, this function will assume there is only one EndpointSet created which + will be returned. Usage examples: - trafficObj.getConfigElementObj(trafficItemName='Raw MPLS/UDP', endpointSetName='EndpointSet-2') - + trafficObj.getConfigElementObj(trafficItemName='Raw MPLS/UDP', + endpointSetName='EndpointSet-2') trafficObj.getConfigElementObj(trafficItemName='Raw MPLS/UDP', endpointSetName=None) - trafficObj.getConfigElementObj(trafficItemObj='/api/v1/sessions/1/ixnetwork/traffic/trafficItem/1', - trafficItemName=None, endpointSetName=None) - - trafficObj.getConfigElementObj(trafficItemObj='/api/v1/sessions/1/ixnetwork/traffic/trafficItem/1', - trafficItemName=None, endpointSetName='EndpointSet-2') - - Return - configElement: /api/v1/sessions/{id}/ixnetwork/traffic/trafficItem/{id}/configElement/{id} """ + endpointSetObj = None if trafficItemObj: trafficItemName = self.getTrafficItemName(trafficItemObj) - if trafficItemName: + trafficItemObj = self.ixNetwork.Traffic.TrafficItem.find(Name=trafficItemName) + if not trafficItemObj: + raise IxNetRestApiException('\nError: No trafficitem name found: {0}'.format( + trafficItemName)) if endpointSetName: - queryData = {'from': '/traffic', - 'nodes': [{'node': 'trafficItem', 'properties': ['name'], - 'where': [{'property': 'name', 'regex': trafficItemName}]}, - {'node': 'endpointSet', 'properties': ['name'], - 'where': [{'property': 'name', 'regex': endpointSetName}]}, - ]} - - if endpointSetName == None: - queryData = {'from': '/traffic', - 'nodes': [{'node': 'trafficItem', 'properties': ['name'], - 'where': [{'property': 'name', 'regex': trafficItemName}]}, - {'node': 'endpointSet', 'properties': [], - 'where': []}, - ]} - - queryResponse = self.ixnObj.query(data=queryData) - - trafficItemList = queryResponse.json()['result'][0]['trafficItem'] - if trafficItemList == []: - raise IxNetRestApiException('\nError: No traffic item name found: {0}'.format(trafficItemName)) - - endpointSetList = queryResponse.json()['result'][0]['trafficItem'][0]['endpointSet'] - if endpointSetList == []: - raise IxNetRestApiException('\nError: No endpointSet name: {0} found in Traffic Item name: {1}'.format( - endpointSetName, trafficItemName)) - - endpointSetObj = queryResponse.json()['result'][0]['trafficItem'][0]['endpointSet'][0]['href'] - endpointSetId = endpointSetObj.split('/')[-1] - - # With the traffic item name and endpointSetId, get the Traffic Item's config element object handle. - queryData = {'from': '/traffic', - 'nodes': [{'node': 'trafficItem', 'properties': ['name'], - 'where': [{'property': 'name', 'regex': trafficItemName}]}, - {'node': 'configElement', 'properties': ['endpointSetId'], - 'where': [{'property': 'endpointSetId', 'regex': endpointSetId}]} - ]} - - queryResponse = self.ixnObj.query(data=queryData) - configElementObj = queryResponse.json()['result'][0]['trafficItem'][0]['configElement'][0]['href'] - print(configElementObj) + endpointSetObj = trafficItemObj.EndpointSet.find(Name=endpointSetName) + if not endpointSetObj: + raise IxNetRestApiException('\nError: No endpointSet name: {0} found in ' + 'Traffic Item name: {1}'.format(endpointSetName, + trafficItemName)) + if endpointSetName is None: + endpointSetObj = trafficItemObj.EndpointSet.find() + endpointSetId = endpointSetObj.href.split('/')[-1] + configElementObj = trafficItemObj.ConfigElement.find(EndpointSetId=endpointSetId)[0] + print(configElementObj.href) return configElementObj def getAllConfigElementObj(self, trafficItemObj): @@ -500,45 +424,32 @@ def getAllConfigElementObj(self, trafficItemObj): Description Get all config element objects from a traffic item object. - Parameter - trafficItemObj: /api/v1/sessions/{id}/ixnetwork/traffic/trafficItem/{id} - Return A list of configElement objects """ - trafficItemUrl = self.ixnObj.httpHeader + trafficItemObj - response = self.ixnObj.get(trafficItemUrl + '/configElement') - configElementObjList = [] - for id in response.json(): - configElementObjList.append(id['links'][0]['href']) - - return configElementObjList + configElementObj = trafficItemObj.ConfigElement.find() + return configElementObj def getTransmissionType(self, configElement): - # configElement: /api/v1/sessions/1/ixnetwork/traffic/trafficItem/1/configElement/1 - # Returns: fixedFrameCount, continuous - - response = self.ixnObj.get(self.ixnObj.httpHeader+configElement+'/transmissionControl') - return response.json()['type'] + return configElement.TransmissionControl.Type def configTrafficLatency(self, enabled=True, mode='storeForward'): - # enabled = True|False - # mode = storeForward|cutThrough|forwardDelay|mef - self.ixnObj.patch(self.ixnObj.sessionUrl+'/traffic/statistics/latency', data={'enabled':enabled, 'mode':mode}) + latencyObj = self.ixNetwork.Traffic.Statistics.Latency + latencyObj.Enabled = enabled + latencyObj.Mode = mode def showProtocolTemplates(self, configElementObj): """ Description - To show all the protocol template options. Mainly used for adding a protocol header + To show all the protocol template options. + Mainly used for adding a protocol header to Traffic Item packets. - Parameters - configElementObj: /api/v1/sessions/1/ixnetwork/traffic/trafficItem/{id}/configElement/{id} """ - # Get a list of all the protocol templates: - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/traffic/protocolTemplate?skip=0&take=end') - for eachProtocol in response.json()['data']: - self.ixnObj.logInfo('%s: %s' % (eachProtocol['id'], eachProtocol['displayName']), timestamp=False) + protocolTemplateObj = self.ixNetwork.Traffic.ProtocolTemplate.find() + for (index, eachProtocol) in enumerate(protocolTemplateObj): + self.ixnObj.logInfo('%s: %s' % (str(index + 1), eachProtocol.DisplayName), + timestamp=False) def showTrafficItemPacketStack(self, configElementObj): """ @@ -551,100 +462,90 @@ def showTrafficItemPacketStack(self, configElementObj): 4: UDP 5: Frame Check Sequence CRC-32 - Parameters - configElementObj: /api/v1/sessions/1/ixnetwork/traffic/trafficItem/{id}/configElement/{id} """ print() - response = self.ixnObj.get(self.ixnObj.httpHeader+configElementObj+'/stack') + stackObj = configElementObj.Stack.find() self.ixnObj.logInfo('\n', timestamp=False) - for (index, eachHeader) in enumerate(response.json()): - self.ixnObj.logInfo('%s: %s' % (str(index+1), eachHeader['displayName']), timestamp=False) + for (index, eachStackObj) in enumerate(stackObj): + self.ixnObj.logInfo('%s: %s' % (str(index + 1), eachStackObj.DisplayName), + timestamp=False) - def addTrafficItemPacketStack(self, configElementObj, protocolStackNameToAdd, stackNumber, action='append'): + def addTrafficItemPacketStack(self, configElementObj, protocolStackNameToAdd, stackNumber, + action='append'): """ Description To either append or insert a protocol stack to an existing packet. You must know the exact name of the protocolTemplate to add by calling - showProtocolTemplates() API and get the exact name as a value for the parameter protocolStackNameToAdd. + showProtocolTemplates() API and get the exact name as a value for the parameter + protocolStackNameToAdd. - You must also know where to add the new packet header stack. Use showTrafficItemPacketStack() to see - your current stack numbers. + You must also know where to add the new packet header stack. + Use showTrafficItemPacketStack() to see your current stack numbers. - This API returns the protocol stack object handle so you could use it to config its settings. - - Parameters - configElementObj: /api/v1/sessions/1/ixnetwork/traffic/trafficItem/{id}/configElement/{id} + This API returns the protocol stack object handle so you could use it to config its + settings. action: append: To add after the specified stackNumber insert: To add before the specified stackNumber - protocolStackNameToAdd: The name of the protocol stack to add. To get a list of options, - use API showProtocolTemplates(). - Some common ones: MPLS, IPv4, TCP, UDP, VLAN, IGMPv1, IGMPv2, DHCP, VXLAN + protocolStackNameToAdd: The name of the protocol stack to add. + To get a list of options, use API showProtocolTemplates(). + Some common ones: MPLS, IPv4, TCP, UDP, VLAN, IGMPv1, IGMPv2, DHCP, VXLAN stackNumber: The stack number to append or insert into. - Use showTrafficItemPacketStack() to view the packet header stack in order to know - which stack number to insert your new stack before or after the stack number. + Use showTrafficItemPacketStack() to view the packet header stack in order to + know which stack number to insert your new stack before or after the + stack number. Example: - addTrafficItemPacketStack(configElement, protocolStackNameToAdd='UDP', - stackNumber=3, action='append', apiKey=apiKey, verifySslCert=False + addTrafficItemPacketStack(configElement, + protocolStackNameToAdd='UDP', + stackNumber=3, action='append', + apiKey=apiKey, verifySslCert=False) - Returns: - /api/v1/sessions/1/ixnetwork/traffic/trafficItem/{id}/configElement/{id}/stack/{id} """ - if action == 'append': - action = 'appendprotocol' - if action == 'insert': - action = 'insertprotocol' - - # /api/v1/sessions/1 - match = re.match('http.*(/api.*sessions/[0-9]).*', self.ixnObj.sessionUrl) - if match: - apiHeader = match.group(1) - - # /api/v1/sessions/1/ixnetwork/traffic/trafficItem/1/configElement/1 - arg1 = configElementObj+'/stack/' + str(stackNumber) - - # Display a list of the current packet stack - response = self.ixnObj.get(self.ixnObj.httpHeader+configElementObj+'/stack') - for (index, eachHeader) in enumerate(response.json()): - self.ixnObj.logInfo('{0}: {1}'.format(index+1, eachHeader['displayName']), timestamp=False) - - # Get a list of all the protocol templates: - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/traffic/protocolTemplate?skip=0&take=end') - + protocolTemplateObj = None + newStackObj = None + stackObj = configElementObj.Stack.find()[stackNumber - 1] + self.showTrafficItemPacketStack(configElementObj) + protocolTemplatesObj = self.ixNetwork.Traffic.ProtocolTemplate.find() protocolTemplateId = None - for eachProtocol in response.json()['data']: - if bool(re.match('^%s$' % protocolStackNameToAdd, eachProtocol['displayName'].strip(), re.I)): - # /api/v1/sessions/1/traffic/protocolTemplate/30 - protocolTemplateId = eachProtocol['links'][0]['href'] - - if protocolTemplateId == None: - raise IxNetRestApiException('No such protocolTemplate name found: {0}'.format(protocolStackNameToAdd)) + for eachProtocol in protocolTemplatesObj: + if bool(re.match('^%s$' % protocolStackNameToAdd, eachProtocol.DisplayName.strip(), + re.I)): + protocolTemplateId = eachProtocol.href + protocolTemplateObj = eachProtocol + + if protocolTemplateId is None: + raise IxNetRestApiException('No such protocolTemplate name found: {0}'.format( + protocolStackNameToAdd)) self.ixnObj.logInfo('protocolTemplateId: %s' % protocolTemplateId, timestamp=False) - data = {'arg1': arg1, 'arg2': protocolTemplateId} - response = self.ixnObj.post(self.ixnObj.httpHeader+configElementObj+'/stack/operations/%s' % action, data=data) - - self.ixnObj.waitForComplete(response, self.ixnObj.httpHeader+configElementObj+'/stack/operations/appendprotocol/'+response.json()['id']) - - # /api/v1/sessions/1/ixnetwork/traffic/trafficItem/1/configElement/1/stack/4 - self.ixnObj.logInfo('addTrafficItemPacketStack: Returning: %s' % response.json()['result'], timestamp=False) - return response.json()['result'] - - def getTrafficItemPktHeaderStackObj(self, configElementObj=None, trafficItemName=None, packetHeaderName=None): + if action == 'append': + newStackObj = stackObj.AppendProtocol(protocolTemplateObj) + if action == 'insert': + newStackObj = stackObj.InsertProtocol(protocolTemplateObj) + self.ixnObj.logInfo('addTrafficItemPacketStack: Returning: %s' % newStackObj, + timestamp=False) + allStackObj = configElementObj.Stack.find() + for eachStack in allStackObj: + if eachStack.href == newStackObj: + newStackObj = eachStack + return newStackObj + + def getTrafficItemPktHeaderStackObj(self, configElementObj=None, trafficItemName=None, + packetHeaderName=None): """ Description - Get the Traffic Item packet header stack object based on the displayName. - To get the displayName, you could call this function: self.showTrafficItemPacketStack(configElementObj) + Get the Traffic Item packet header stack object based on the displayName. To get the + displayName, you could call this function: self.showTrafficItemPacketStack( + configElementObj) + + For this function, you could either pass in a configElement object or Traffic Item name. - For this function, you could either pass in a configElement object or the Traffic Item name. - Parameters configElementObj: : Optional: The configElement object. - Example: /api/v1/sessions/1/ixnetwork/traffic/trafficItem/1/configElement/1 trafficItemName: : Optional: The Traffic Item name. @@ -654,34 +555,28 @@ def getTrafficItemPktHeaderStackObj(self, configElementObj=None, trafficItemName Return The stack object """ - if configElementObj == None: - # Expect user to pass in the Traffic Item name if user did not pass in a configElement object. - queryData = {'from': '/traffic', - 'nodes': [{'node': 'trafficItem', 'properties': ['name'], - 'where': [{'property': 'name', 'regex': trafficItemName}]}]} - - queryResponse = self.ixnObj.query(data=queryData) - - if queryResponse.json()['result'][0]['trafficItem'] == []: - raise IxNetRestApiException('\nNo such Traffic Item name found: %s' % trafficItemName) - - trafficItemObj = queryResponse.json()['result'][0]['trafficItem'][0]['href'] - configElementObj = trafficItemObj+'/configElement/1' - - response = self.ixnObj.get(self.ixnObj.httpHeader+configElementObj+'/stack') - - for eachStack in response.json(): - currentStackDisplayName = eachStack['displayName'].strip() - self.ixnObj.logInfo('Packet header name: {0}'.format(currentStackDisplayName), timestamp=False) + if configElementObj is None: + trafficItem = self.ixNetwork.Traffic.TrafficItem.find( + Name=trafficItemName) + if trafficItem is None: + raise IxNetRestApiException('\nNo such Traffic Item name found: %s' % + trafficItemName) + configElementObj = trafficItem[0].ConfigElement.find()[0] + stacks = configElementObj.Stack.find() + for eachStack in stacks: + currentStackDisplayName = eachStack.DisplayName.strip() + self.ixnObj.logInfo('Packet header name: {0}' .format(currentStackDisplayName), + timestamp=False) if bool(re.match('^{0}$'.format(packetHeaderName), currentStackDisplayName, re.I)): - self.ixnObj.logInfo('\nstack: {0}: {1}'.format(eachStack, currentStackDisplayName), timestamp=False) - stackObj = eachStack['links'][0]['href'] - return stackObj - - raise IxNetRestApiException('\nError: No such stack name found. Verify stack name existence and spelling: %s' % packetHeaderName) + self.ixnObj.logInfo('\nstack: {0}: {1}'.format(eachStack, currentStackDisplayName), + timestamp=False) + return eachStack + raise IxNetRestApiException('\nError: No such stack name found. Verify stack name ' + 'existence and spelling: %s' % packetHeaderName) def showTrafficItemStackLink(self, configElementObj): - # Return a list of configured Traffic Item packet header in sequential order. + # Return a list of configured Traffic Item packet header + # in sequential order. # 1: Ethernet II # 2: MPLS # 3: MPLS @@ -692,18 +587,19 @@ def showTrafficItemStackLink(self, configElementObj): # 8: Frame Check Sequence CRC-32 stackList = [] - response = self.ixnObj.get(self.ixnObj.httpHeader+configElementObj+'/stackLink') + stackLinkObj = configElementObj.StackLink.find() self.ixnObj.logInfo('\n', timestamp=False) - for eachStackLink in response.json(): - if eachStackLink['linkedTo'] != 'null': - self.ixnObj.logInfo(eachStackLink['linkedTo'], timestamp=False) - stackList.append(eachStackLink['linkedTo']) + for eachStackLink in stackLinkObj: + if eachStackLink.LinkedTo != 'null': + self.ixnObj.logInfo(eachStackLink.LinkedTo, timestamp=False) + stackList.append(eachStackLink.LinkedTo) return stackList def getPacketHeaderStackIdObj(self, configElementObj, stackId): """ Desciption - This API should be called after calling showTrafficItemPacketStack(configElementObj) in + This API should be called after calling + showTrafficItemPacketStack(configElementObj) in order to know the stack ID number to use. Such as ... Stack1: Ethernet II @@ -716,18 +612,16 @@ def getPacketHeaderStackIdObj(self, configElementObj, stackId): Stack8: Frame Check Sequence CRC-32 Parameters - configElementObj: /api/v1/sessions/1/ixnetwork/traffic/trafficItem/{id}/configElement/{id} stackId: In this example, IPv4 stack ID is 6. - Return stack ID object: /api/v1/sessions/1/ixnetwork/traffic/trafficItem/{id}/configElement/{id}/stack/{id} """ - response = self.ixnObj.get(self.ixnObj.httpHeader+configElementObj+'/stack') + stackObj = configElementObj.Stack.find() self.ixnObj.logInfo('\n', timestamp=False) - for (index, eachHeader) in enumerate(response.json()): - self.ixnObj.logInfo('{0}: {1}'.format(index+1, eachHeader['displayName']), timestamp=False) - if stackId == index+1: - self.ixnObj.logInfo('\tReturning: %s' % self.ixnObj.httpHeader+eachHeader['links'][0]['href'], timestamp=False) - return eachHeader['links'][0]['href'] + for (index, eachStackObj) in enumerate(stackObj): + self.ixnObj.logInfo('{0}: {1}'.format(index + 1, eachStackObj.DisplayName), + timestamp=False) + if stackId == index + 1: + return eachStackObj def modifyTrafficItemPacketHeader(self, configElementObj, packetHeaderName, fieldName, values): """ @@ -735,99 +629,107 @@ def modifyTrafficItemPacketHeader(self, configElementObj, packetHeaderName, fiel Modify any Traffic Item packet header. You will need to use the IxNetwor API browser to understand the packetHeaderName, fieldName and data to modify. - Since a Traffic Item could contain many endpointSet (Flow Groups), a Traffic Item could - have multiple configElement objects. A configElementObj is the object handle for an - endpointSet. You have to get the configElement object first. To get the ConfigElement - object, you call getConfigElementObj(). + Since a Traffic Item could contain many endpointSet (Flow Groups), a Traffic Item + could have multiple configElement objects.A configElementObj is the object handle for an + endpointSet.You have to get the configElement object first. + To get the ConfigElement object, you call getConfigElementObj(). - self.getConfigElementObj(self, trafficItemObj=None, trafficItemName=None, endpointSetName=None): + self.getConfigElementObj(self, trafficItemObj=None, trafficItemName=None, + endpointSetName=None): Use case #1: trafficItemName + endpointSetName Use case #2: trafficItemObj + endpointSetName - Use case #3: trafficItemName only (Will assume there is only one configElement object which will be returned) - Use case #4: trafficItemObj only (Will assume there is only one configElement object which will be returned) + Use case #3: trafficItemName only (Will assume there is only one configElement object + which will be returned) + Use case #4: trafficItemObj only (Will assume there is only one configElement object + which will be returned) Parameters configElementObj: : The Traffic Item's Config Element object handle. - packetHeaderName: : The packet header name. You could get the list of names from the - IxNetwork API browser under trafficItem/{id}/configElement/{id}/stack. - fieldName: : The packet header field name. View API browser under: - trafficItem/{id}/configElement/{id}/stack/{id}/field - values: : Any amount of attributes from the /stack/{id}/field/{id} to modify. + packetHeaderName: : The packet header name. + fieldName: : The packet header field name. + values: : Any amount of attributes - Example: For IP Precedence TOS + Example: For IP Precedence TOS packetHeaderName='ipv4' fieldName='Precedence' values={'fieldValue': '011 Flash'} """ - # /api/v1/sessions/1/ixnetwork/traffic/trafficItem/1/configElement/1/stack/6 stackIdObj = self.getTrafficItemPktHeaderStackObj(configElementObj=configElementObj, packetHeaderName=packetHeaderName) - self.configPacketHeaderField(stackIdObj, fieldName, values) - def modifyTrafficItemIpPriorityTos(self, trafficItemObj=None, trafficItemName=None, endpointSetName=None, - packetHeaderName='ipv4', fieldName='Precedence', values=None): + def modifyTrafficItemIpPriorityTos(self, trafficItemObj=None, trafficItemName=None, + endpointSetName=None, packetHeaderName='ipv4', + fieldName='Precedence', values=None): """ Description Modify a Traffic Item Flow group IP Priority TOS fields. Parameters - value: : {'fieldValue': '000 Routine'|'001 Priority'|'010 Immediate'|'011 Flash'|'100 Flash Override' + value: : {'fieldValue': '000 Routine'| + '001 Priority'|'010 Immediate'| + '011 Flash'|'100 Flash Override' '101 CRITIC/ECP'|'110 Internetwork Control'} - trafficItemObj: : The Traffic Item object handle. trafficItemName: : The Traffic Item name. endpointSetName: : The endpointSet name (Flow-Group). Option #1: trafficItemName + endpointSetName Option #2: trafficItemObj + endpointSetName - Option #3: trafficItemName only (Will assume there is only one configElement object) - Option #4: trafficItemObj only (Will assume there is only one configElement object) + Option #3: trafficItemName only (Will assume there + is only one configElement object) + Option #4: trafficItemObj only (Will assume there + is only one configElement object) Requirement Call self.getConfigElementObj() to get the config element object first. Example - trafficObj.modifyTrafficItemIpPriorityTos(trafficItemName='Raw MPLS/UDP', values={'fieldValue': '001 Priority'}) + trafficObj.modifyTrafficItemIpPriorityTos( + trafficItemName='Raw MPLS/UDP', + values={'fieldValue': '001 Priority'}) """ - configElementObj = self.getConfigElementObj(trafficItemObj=trafficItemObj, trafficItemName=trafficItemName, + configElementObj = self.getConfigElementObj(trafficItemObj=trafficItemObj, + trafficItemName=trafficItemName, endpointSetName=endpointSetName) - self.modifyTrafficItemPacketHeader(configElementObj, packetHeaderName=packetHeaderName, fieldName=fieldName, values=values) - def modifyTrafficItemDestMacAddress(self, trafficItemObj=None, trafficItemName=None, endpointSetName=None, values=None): + def modifyTrafficItemDestMacAddress(self, trafficItemObj=None, trafficItemName=None, + endpointSetName=None, values=None): """ Description Modify a Traffic Item Flow group IP Priority TOS fields. Parameters - value: <'str'|dict>: + value: <'str'|dict>: If str: The mac address address If dict: Any or all the properties and the values: - {'valueType': 'increment', 'startValue': destMacAddress, 'stepValue': '00:00:00:00:00:00', 'countValue': 1, 'auto': False} - + trafficItemObj: : The Traffic Item object handle. trafficItemName: : The Traffic Item name. endpointSetName: : The endpointSet name (Flow-Group). Option #1: trafficItemName + endpointSetName Option #2: trafficItemObj + endpointSetName - Option #3: trafficItemName only (Will assume there is only one configElement object) - Option #4: trafficItemObj only (Will assume there is only one configElement object) + Option #3: trafficItemName only (Will assume there + is only one configElement object) + Option #4: trafficItemObj only (Will assume there + is only one configElement object) Requirement Call self.getConfigElementObj() to get the config element object first. Example - trafficObj.modifyTrafficItemDestMacAddress(trafficItemName='Raw MPLS/UDP', values='00:01:01:02:00:01') + trafficObj.modifyTrafficItemDestMacAddress(trafficItemName='Raw MPLS/UDP', + values='00:01:01:02:00:01') """ - + if type(values) == str: values = {'valueType': 'increment', 'startValue': values, @@ -835,10 +737,10 @@ def modifyTrafficItemDestMacAddress(self, trafficItemObj=None, trafficItemName=N 'countValue': 1, 'auto': False} - configElementObj = self.getConfigElementObj(trafficItemObj=trafficItemObj, trafficItemName=trafficItemName, + configElementObj = self.getConfigElementObj(trafficItemObj=trafficItemObj, + trafficItemName=trafficItemName, endpointSetName=endpointSetName) - - self.modifyTrafficItemPacketHeader(configElementObj, packetHeaderName='ethernet', + self.modifyTrafficItemPacketHeader(configElementObj, packetHeaderName='ethernet II', fieldName='Destination MAC Address', values=values) def showPacketHeaderFieldNames(self, stackObj): @@ -846,31 +748,19 @@ def showPacketHeaderFieldNames(self, stackObj): Description Get all the packet header field names. - Parameters - stackObj = /api/v1/sessions/1/ixnetwork/traffic/trafficItem/{id}/configElement/{id}/stack/{id} - Example for Ethernet stack field names 1: Destination MAC Address 2: Source MAC Address 3: Ethernet-Type 4: PFC Queue """ - self.ixnObj.logInfo('showPacketHeaderFieldNames: %s' % stackObj+'/field', timestamp=False) - response = self.ixnObj.get(self.ixnObj.httpHeader+stackObj+'/field?skip=0&take=end') - - for eachField in response.json(): - if 'id' in eachField: - id = eachField['id'] - fieldName = eachField['displayName'] - self.ixnObj.logInfo('\t{0}: {1}'.format(id, fieldName), timestamp=False) - - if 'data' in response.json(): - for eachDataField in response.json()['data']: - if 'id' in eachDataField: - id = eachDataField['id'] - fieldName = eachDataField['displayName'] - self.ixnObj.logInfo('\t{0}: {1}'.format(id, fieldName), timestamp=False) - + self.ixnObj.logInfo('showPacketHeaderFieldNames: %s' % stackObj.href + '/field', + timestamp=False) + stackFieldObj = stackObj.Field.find() + for (index, eachField) in enumerate(stackFieldObj): + self.ixnObj.logInfo('\t{0}: {1}'.format(index + 1, eachField.DisplayName), + timestamp=False) + def convertTrafficItemToRaw(self, trafficItemName): """ Description @@ -880,29 +770,41 @@ def convertTrafficItemToRaw(self, trafficItemName): trafficItemObj = self.getTrafficItemObjByName(trafficItemName) if trafficItemObj == 0: raise IxNetRestApiException('\nNo such Traffic Item name: %s' % trafficItemName) - self.ixnObj.post(self.ixnObj.sessionUrl+'/traffic/trafficItem/operations/converttoraw', data={'arg1': trafficItemObj}) + trafficItemObj.ConvertToRaw() def configPacketHeaderField(self, stackIdObj, fieldName, data): """ Desciption Configure raw packets in a Traffic Item. - In order to know the field names to modify, use showPacketHeaderFieldNames() to display the names: - - stackIdObj: /api/v1/sessions/1/ixnetwork/traffic/trafficItem/{id}/configElement/{id}/stack/{id} + In order to know the field names to modify, use showPacketHeaderFieldNames() to + display the names: fieldName: The field name in the packet header to modify. - Example. In a MPLS packet header, the fields would be "Label value", "MPLS Exp", etc. - + Example. In a MPLS packet header, the fields would be "Label value", + "MPLS Exp", etc. Note: Use showPacketHeaderFieldNames(stackObj) API to dispaly your options. data: Example: - data={'valueType': 'valueList', 'valueList': ['1001', '1002'], auto': False} - data={'valueType': 'increment', 'startValue': '1.1.1.1', 'stepValue': '0.0.0.1', 'countValue': 2} - data={'valueType': 'increment', 'startValue': '00:01:01:01:00:01', 'stepValue': '00:00:00:00:00:01'} - data={'valueType': 'increment', 'startValue': 1001, 'stepValue': 1, 'countValue': 2, 'auto': False} - + data={'valueType': 'valueList', + 'valueList': ['1001', '1002'], + auto': False} + data={'valueType': 'increment', + 'startValue': '1.1.1.1', + 'stepValue': '0.0.0.1', + 'countValue': 2} + data={'valueType': 'increment', + 'startValue': '00:01:01:01:00:01', + 'stepValue': '00:00:00:00:00:01'} + data={'valueType': 'increment', + 'startValue': 1001, + 'stepValue': 1, + 'countValue': 2, + 'auto': False} + Example: To modify MPLS field: - packetHeaderObj = trafficObj.getTrafficItemPktHeaderStackObj(trafficItemName='Raw MPLS/UDP', packetHeaderName='mpls') + packetHeaderObj = trafficObj.getTrafficItemPktHeaderStackObj( + trafficItemName='Raw MPLS/UDP', + packetHeaderName='mpls') trafficObj.configPacketHeaderField(packetHeaderObj, fieldName='MPLS Exp', data={'valueType': 'increment', @@ -912,80 +814,91 @@ def configPacketHeaderField(self, stackIdObj, fieldName, data): 'auto': False}) """ fieldId = None - # Get the field ID object by the user defined fieldName - #response = self.ixnObj.get(self.ixnObj.httpHeader+stackIdObj+'/field') - response = self.ixnObj.get(self.ixnObj.httpHeader+stackIdObj+'/field?skip=0&take=end') - - for eachFieldId in response.json(): - if 'displayName' in eachFieldId: - if bool(re.match(fieldName, eachFieldId['displayName'], re.I)): - fieldId = eachFieldId['id'] - - if 'data' in eachFieldId: - for dataFieldId in response.json()['data']: - if bool(re.match(fieldName, dataFieldId['displayName'], re.I)): - fieldId = dataFieldId['id'] - - if fieldId == None: + fieldObj = None + stackFieldObj = stackIdObj.Field.find() + for (index, eachFieldId) in enumerate(stackFieldObj): + if bool(re.match(fieldName, eachFieldId.DisplayName, re.I)): + fieldId = index + 1 + fieldObj = eachFieldId + break + if fieldId is None: raise IxNetRestApiException('Failed to located your provided fieldName:', fieldName) - - self.ixnObj.logInfo('configPacketHeaderFieldId: fieldIdObj: %s' % stackIdObj+'/field/'+str(fieldId), timestamp=False) - response = self.ixnObj.patch(self.ixnObj.httpHeader+stackIdObj+'/field/'+str(fieldId), data=data) + self.ixnObj.logInfo('configPacketHeaderFieldId: fieldIdObj: %s' % stackIdObj.href + + '/field/' + str(fieldId), timestamp=False) + if data.get('valueType'): + fieldObj.ValueType = data.get('valueType') + else: + fieldObj.ValueType = 'singleValue' + data['valueType'] = 'singleValue' + if data.get('auto'): + fieldObj.Auto = data['auto'] + if data.get('valueType') == 'singleValue': + fieldObj.SingleValue = data['fieldValue'] if data.get('fieldValue') else 0 + elif data.get('valueType') in ['increment', 'decrement']: + for item, value in data.items(): + if item in ['startValue', 'stepValue', 'countValue']: + itemObj = item[0:1].capitalize() + item[1:] + setattr(fieldObj, itemObj, value) + elif data.get('valueType') == 'valueList': + if data.get('valueList'): + fieldObj.ValueList = data['valueList'] + elif data.get('valueType') == 'random': + for item, value in data.items(): + if item in ['countValue', 'seed', 'randomMask', 'fixedBits']: + itemObj = item[0:1].capitalize() + item[1:] + setattr(fieldObj, itemObj, value) + elif data.get('valueType') == 'repeatableRandomRange': + for item, value in data.items(): + if item in ['countValue', 'seed', 'stepValue', 'maxValue', 'minValue']: + itemObj = item[0:1].capitalize() + item[1:] + setattr(fieldObj, itemObj, value) + elif data.get('valueType') == 'nonRepeatableRandom': + for item, value in data.items(): + if item in ['randomMask', 'fixedBits']: + itemObj = item[0:1].capitalize() + item[1:] + setattr(fieldObj, itemObj, value) def getPacketHeaderAttributesAndValues(self, streamObj, packetHeaderName, fieldName): """ Parameters - streamObj: : configElementObj|highLevelStreamObj - Ex: /api/v1/sessions/{id}/ixnetwork/traffic/trafficItem/{1}/configElement/{id} - or /api/v1/sessions/{id}/ixnetwork/traffic/trafficItem/{1}/highLevelStream/{id} + streamObj: : configElementObj|highLevelStreamObj - packetHeaderName: : Display Name of the stack. Example: Ethernet II, VLAN, IPv4, TCP, etc. + packetHeaderName: : Display Name of the stack. + Example: Ethernet II, VLAN, IPv4, TCP, etc. - fieldName: : Display Name of the field. Example: If packetHeaderName is Ethernet II, field names could be - Destination MAC Address, Source MAC Address, Ethernet-Type and PFC Queue. - You will have to know these field names. To view them, make your configurations - and then go on the API browser and go to: - - /api/v1/sessions/{id}/ixnetwork/traffic/trafficItem/{1}/configElement/{id}/stack/{id}/field - - Example: - streamObj = '/api/v1/sessions/{id}/ixnetwork/traffic/trafficItem/{id}/configElement/{id}' - data= trafficObj.getPacketHeaderAttributesAndValues(streamObj, - 'Ethernet II', 'Source MAC Address') + fieldName: : Display Name of the field. + Example: If packetHeaderName is Ethernet II, field names could be Destination MAC + Address, Source MAC Address, Ethernet-Type and PFC Queue. + data= trafficObj.getPacketHeaderAttributesAndValues(streamObj, 'Ethernet II', + 'Source MAC Address') data['singleValue'] = For single value. data['startValue'] = If it is configured to increment. Returns All the attributes and values in JSON format. """ - response = self.ixnObj.get(self.ixnObj.httpHeader+streamObj+'/stack') - for eachStack in response.json(): - stackHref = eachStack['links'][0]['href'] - response = self.ixnObj.get(self.ixnObj.httpHeader+stackHref) - # need to do strip() to response.json()['displayName'] because some displayName has trailing spaces. - # for example: "IPv4 " - if packetHeaderName == response.json()['displayName'].strip(): - response = self.ixnObj.get(self.ixnObj.httpHeader+stackHref+'/field') - for eachField in response.json(): - if fieldName == eachField['displayName']: + stackObj = streamObj.Stack.find() + for eachStack in stackObj: + if packetHeaderName == eachStack.DisplayName.strip(): + fieldObj = eachStack.Field.find() + for eachField in fieldObj: + if fieldName in eachField.DisplayName: return eachField def configEgressCustomTracking(self, trafficItemObj, offsetBits, widthBits): """ Description - Configuring custom egress tracking. User must know the offset and the bits width to track. - In most use cases, packets ingressing the DUT gets modified by the DUT and to track the - correctness of the DUT's packet modification, use this API to verify the receiving port's packet - offset and bit width. + Configuring custom egress tracking. User must know the offset and the bits width to + track. In most use cases, packets ingressing the DUT gets modified by the DUT and to + track the correctness of the DUT's packet modification, use this API to verify the + receiving port's packet offset and bit width. """ - # Safety check: Apply traffic or else configuring egress tracking won't work. self.applyTraffic() - self.ixnObj.patch(self.ixnObj.httpHeader+trafficItemObj+'/tracking/egress', - data={'encapsulation': 'Any: Use Custom Settings', - 'customOffsetBits': offsetBits, - 'customWidthBits': widthBits - }) - self.ixnObj.patch(self.ixnObj.httpHeader+trafficItemObj, data={'egressEnabled': True}) + egressObj = trafficItemObj.Tracking.find().Egress + egressObj.Encapsulation = 'Any: Use Custom Settings' + egressObj.CustomOffsetBits = offsetBits + egressObj.CustomWidthBits = widthBits + trafficItemObj.EgressEnabled = True self.regenerateTrafficItems() self.applyTraffic() @@ -996,129 +909,114 @@ def createEgressStatView(self, trafficItemObj, egressTrackingPort, offsetBit, bi Create egress statistic view for egress stats. """ - egressTrackingOffsetFilter = 'Custom: ({0}bits at offset {1})'.format(int(bitWidth), int(offsetBit)) + egressTrackingOffsetFilter = 'Custom: ({0}bits at offset {1})'.format(int(bitWidth), + int(offsetBit)) trafficItemName = self.getTrafficItemName(trafficItemObj) - - # Get EgressStats - # Create Egress Stats self.ixnObj.logInfo('Creating new statview for egress stats...') - response = self.ixnObj.post(self.ixnObj.sessionUrl+'/statistics/view', - data={'caption': egressStatViewName, - 'treeViewNodeName': 'Egress Custom Views', - 'type': 'layer23TrafficFlow', - 'visible': True}) - - egressStatView = response.json()['links'][0]['href'] - self.ixnObj.logInfo('egressStatView Object: %s' % egressStatView) - # /api/v1/sessions/1/ixnetwork/statistics/view/12 + self.ixNetwork.Statistics.View.add(Caption=egressStatViewName, + TreeViewNodeName='Egress Custom Views', + Type='layer23TrafficFlow', + Visible=True) self.ixnObj.logInfo('Creating layer23TrafficFlowFilter') - # Dynamically get the PortFilterId - response = self.ixnObj.get(self.ixnObj.httpHeader+egressStatView+'/availablePortFilter') + egressStatViewObj = self.ixNetwork.Statistics.View.find(Caption=egressStatViewName) + self.ixnObj.logInfo('egressStatView Object: %s' % egressStatViewObj.href) + availablePortFilterObj = egressStatViewObj.AvailablePortFilter.find() portFilterId = [] - for eachPortFilterId in response.json(): - #192.168.70.10/Card2/Port1 - self.ixnObj.logInfo('\tAvailable PortFilterId: %s' % eachPortFilterId['name'], timestamp=False) - if eachPortFilterId['name'] == egressTrackingPort: - self.ixnObj.logInfo('\tLocated egressTrackingPort: %s' % egressTrackingPort, timestamp=False) - portFilterId.append(eachPortFilterId['links'][0]['href']) + for eachPortFilterId in availablePortFilterObj: + self.ixnObj.logInfo('\tAvailable PortFilterId: %s' % eachPortFilterId.Name, + timestamp=False) + if eachPortFilterId.Name == egressTrackingPort: + self.ixnObj.logInfo('\tLocated egressTrackingPort: %s' % egressTrackingPort, + timestamp=False) + portFilterId.append(eachPortFilterId.href) break - if portFilterId == []: + if not portFilterId: raise IxNetRestApiException('No port filter ID found') self.ixnObj.logInfo('PortFilterId: %s' % portFilterId) - - # Dynamically get the Traffic Item Filter ID - response = self.ixnObj.get(self.ixnObj.httpHeader+egressStatView+'/availableTrafficItemFilter') + availableTrafficItemFilterObj = egressStatViewObj.AvailableTrafficItemFilter.find() availableTrafficItemFilterId = [] - for eachTrafficItemFilterId in response.json(): - if eachTrafficItemFilterId['name'] == trafficItemName: - availableTrafficItemFilterId.append(eachTrafficItemFilterId['links'][0]['href']) + for eachTrafficItemFilterId in availableTrafficItemFilterObj: + if eachTrafficItemFilterId.Name == trafficItemName: + availableTrafficItemFilterId.append(eachTrafficItemFilterId.href) break - if availableTrafficItemFilterId == []: + if not availableTrafficItemFilterId: raise IxNetRestApiException('No traffic item filter ID found.') - - self.ixnObj.logInfo('availableTrafficItemFilterId: %s' % availableTrafficItemFilterId, timestamp=False) - # /api/v1/sessions/1/ixnetwork/statistics/view/12 - self.ixnObj.logInfo('egressStatView: %s' % egressStatView, timestamp=False) - layer23TrafficFlowFilter = self.ixnObj.httpHeader+egressStatView+'/layer23TrafficFlowFilter' - self.ixnObj.logInfo('layer23TrafficFlowFilter: %s' % layer23TrafficFlowFilter, timestamp=False) - response = self.ixnObj.patch(layer23TrafficFlowFilter, - data={'egressLatencyBinDisplayOption': 'showEgressRows', - 'trafficItemFilterId': availableTrafficItemFilterId[0], - 'portFilterIds': portFilterId, - 'trafficItemFilterIds': availableTrafficItemFilterId}) - - # Get the egress tracking filter + self.ixnObj.logInfo('availableTrafficItemFilterId: %s' % availableTrafficItemFilterId, + timestamp=False) + self.ixnObj.logInfo('egressStatView: %s' % egressStatViewObj.href, timestamp=False) + layer23TrafficFlowFilterObj = egressStatViewObj.Layer23TrafficFlowFilter.find() + self.ixnObj.logInfo('layer23TrafficFlowFilter: %s' % layer23TrafficFlowFilterObj, + timestamp=False) + layer23TrafficFlowFilterObj.EgressLatencyBinDisplayOption = 'showEgressRows' + layer23TrafficFlowFilterObj.TrafficItemFilterId = availableTrafficItemFilterId[0] + layer23TrafficFlowFilterObj.PortFilterIds = portFilterId + layer23TrafficFlowFilterObj.TrafficItemFilterIds = availableTrafficItemFilterId egressTrackingFilter = None ingressTrackingFilter = None - response = self.ixnObj.get(self.ixnObj.httpHeader+egressStatView+'/availableTrackingFilter') - self.ixnObj.logInfo('Available tracking filters for both ingress and egress...', timestamp=False) - for eachTrackingFilter in response.json(): - self.ixnObj.logInfo('\tFilter Name: {0}: {1}'.format(eachTrackingFilter['id'], eachTrackingFilter['name']), timestamp=False) - if bool(re.match('Custom: *\([0-9]+ bits at offset [0-9]+\)', eachTrackingFilter['name'])): - egressTrackingFilter = eachTrackingFilter['links'][0]['href'] + availableTrackingFilterObj = egressStatViewObj.AvailableTrackingFilter.find() + self.ixnObj.logInfo('Available tracking filters for both ingress and egress...', + timestamp=False) + for (index, eachTrackingFilter) in enumerate(availableTrackingFilterObj): + self.ixnObj.logInfo('\tFilter Name: {0}: {1}'.format(str(index + 1), + eachTrackingFilter.Name), + timestamp=False) + if bool(re.match('Custom: *\\([0-9]+ bits at offset [0-9]+\\)', + eachTrackingFilter.Name)): + egressTrackingFilter = eachTrackingFilter.href if ingressTrackingFilterName is not None: - if eachTrackingFilter['name'] == ingressTrackingFilterName: - ingressTrackingFilter = eachTrackingFilter['links'][0]['href'] - + if eachTrackingFilter.Name == ingressTrackingFilterName: + ingressTrackingFilter = eachTrackingFilter.href if egressTrackingFilter is None: - raise IxNetRestApiException('Failed to locate your defined custom offsets: {0}'.format(egressTrackingOffsetFilter)) - - # /api/v1/sessions/1/ixnetwork/statistics/view/23/availableTrackingFilter/3 - self.ixnObj.logInfo('Located egressTrackingFilter: %s' % egressTrackingFilter, timestamp=False) - enumerationFilter = layer23TrafficFlowFilter+'/enumerationFilter' - response = self.ixnObj.post(enumerationFilter, - data={'sortDirection': 'ascending', - 'trackingFilterId': egressTrackingFilter}) - + raise IxNetRestApiException('Failed to locate your defined custom offsets: {0}'. + format(egressTrackingOffsetFilter)) + self.ixnObj.logInfo('Located egressTrackingFilter: %s' % egressTrackingFilter, + timestamp=False) + layer23TrafficFlowFilterObj.EnumerationFilter.add(SortDirection='ascending', + TrackingFilterId=egressTrackingFilter) if ingressTrackingFilterName is not None: - self.ixnObj.logInfo('Located ingressTrackingFilter: %s' % egressTrackingFilter, timestamp=False) - response = self.ixnObj.post(enumerationFilter, - data={'sortDirection': 'ascending', - 'trackingFilterId': ingressTrackingFilter}) - - # Must enable one or more egress statistic counters in order to enable the - # egress tracking stat view object next. - # Enabling: ::ixNet::OBJ-/statistics/view:"EgressStats"/statistic:"Tx Frames" - # Enabling: ::ixNet::OBJ-/statistics/view:"EgressStats"/statistic:"Rx Frames" - # Enabling: ::ixNet::OBJ-/statistics/view:"EgressStats"/statistic:"Frames Delta" - # Enabling: ::ixNet::OBJ-/statistics/view:"EgressStats"/statistic:"Loss %" - response = self.ixnObj.get(self.ixnObj.httpHeader+egressStatView+'/statistic') - for eachEgressStatCounter in response.json(): - eachStatCounterObject = eachEgressStatCounter['links'][0]['href'] - eachStatCounterName = eachEgressStatCounter['caption'] - self.ixnObj.logInfo('\tEnabling egress stat counter: %s' % eachStatCounterName, timestamp=False) - self.ixnObj.patch(self.ixnObj.httpHeader+eachStatCounterObject, data={'enabled': True}) - - self.ixnObj.patch(self.ixnObj.httpHeader+egressStatView, data={'enabled': True}) + self.ixnObj.logInfo('Located ingressTrackingFilter: %s' % ingressTrackingFilter, + timestamp=False) + layer23TrafficFlowFilterObj.EnumerationFilter.add( + SortDirection='ascending', TrackingFilterId=ingressTrackingFilter) + statisticObj = egressStatViewObj.Statistic.find() + for eachEgressStatCounter in statisticObj: + eachStatCounterObject = eachEgressStatCounter + eachStatCounterName = eachEgressStatCounter.Caption + self.ixnObj.logInfo('\tEnabling egress stat counter: %s' % eachStatCounterName, + timestamp=False) + eachStatCounterObject.Enabled = True + egressStatViewObj.Enabled = True self.ixnObj.logInfo('createEgressCustomStatView: Done') - return egressStatView + return egressStatViewObj def enableTrafficItem(self, trafficItemNumber): - url = self.ixnObj.sessionUrl+'/traffic/trafficItem/%s' % str(trafficItemNumber) - response = self.ixnObj.patch(url, data={"enabled": "true"}) + trafficItemObj = self.ixNetwork.Traffic.TrafficItem.find() + if trafficItemNumber > len(trafficItemObj): + raise IxNetRestApiException("Please provide correct traffic item number") + trafficItemObj[trafficItemNumber - 1].Enabled = True def disableTrafficItem(self, trafficItemNumber): - url = self.ixnObj.sessionUrl+'/traffic/trafficItem/%s' % str(trafficItemNumber) - response = self.ixnObj.patch(url, data={"enabled": "false"}) + trafficItemObj = self.ixNetwork.Traffic.TrafficItem.find() + if trafficItemNumber > len(trafficItemObj): + raise IxNetRestApiException("Please provide correct traffic item number") + trafficItemObj[trafficItemNumber - 1].Enabled = False def enableAllTrafficItems(self, mode=True): """ Description Enable or Disable all Traffic Items. - + Parameter mode: True|False True: Enable all Traffic Items False: Disable all Traffic Items """ - queryData = {'from': '/traffic', - 'nodes': [{'node': 'trafficItem', 'properties': [], 'where': []}]} - queryResponse = self.ixnObj.query(data=queryData) - for trafficItem in queryResponse.json()['result'][0]['trafficItem']: - self.ixnObj.patch(self.ixnObj.httpHeader + trafficItem['href'], data={'enabled': mode}) + trafficItemsObj = self.ixNetwork.Traffic.TrafficItem.find() + for trafficItem in trafficItemsObj: + trafficItem.Enabled = mode def isTrafficItemNameExists(self, trafficItemName): """ @@ -1128,25 +1026,22 @@ def isTrafficItemNameExists(self, trafficItemName): Parameter trafficItemName: The Traffic Item name to verify """ - trafficItemNameExists = False - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/traffic/trafficItem') - for eachTrafficItem in response.json(): - if eachTrafficItem['name'] == trafficItemName: - return True + trafficItemObj = self.getTrafficItemObjByName(trafficItemName) + if trafficItemObj != 0: + return True return False def enablePacketLossDuration(self): - self.ixnObj.patch(self.ixnObj.sessionUrl+'/traffic/statistics/packetLossDuration', data={'enabled': 'true'}) + self.ixNetwork.Traffic.Statistics.PacketLossDuration.Enabled = True def disablePacketLossDuration(self): - self.ixnObj.patch(self.ixnObj.sessionUrl+'/traffic/statistics/packetLossDuration', data={'enabled': 'false'}) + self.ixNetwork.Traffic.Statistics.PacketLossDuration.Enabled = False def getTrafficItemStatus(self, trafficItemObj): - response = self.ixnObj.get(self.ixnObj.httpHeader + trafficItemObj, silentMode=True) - currentTrafficState = response.json()['state'] - return currentTrafficState - - def checkTrafficItemState(self, trafficItemList=None, expectedState=['stopped'], timeout=60, ignoreException=False): + return trafficItemObj.State + + def checkTrafficItemState(self, trafficItemList=None, expectedState=['stopped'], timeout=60, + ignoreException=False): """ Description Check the traffic item expected state. @@ -1157,59 +1052,58 @@ def checkTrafficItemState(self, trafficItemList=None, expectedState=['stopped'], stoppedWaitingForStats, txStopWatchExpected, locked, unapplied Parameters - trafficItemList: : A list of traffic item objects: - Ex: ['/api/v1/sessions/1/ixnetwork/traffic/trafficItem/1'] + trafficItemList: : A list of traffic item objects expectedState: : Input a list of expected traffic state. - Example: ['started', startedWaitingForStats'] <-- This will wait until stats has arrived. + Example: ['started', startedWaitingForStats'] \ + <-- This will wait until stats has arrived. - timeout: : The amount of seconds you want to wait for the expected traffic state. - Defaults to 45 seconds. - In a situation where you have more than 10 pages of stats, you will - need to increase the timeout time. + timeout: : The amount of seconds you want to wait for the expected traffic + state. Defaults to 45 seconds. + In a situation where you have more than 10 pages of stats, you will need to increase + the timeout time. ignoreException: : If True, return 1 as failed, and don't raise an Exception. Return 1: If failed. """ - if type(expectedState) != list: - expectedState.split(' ') self.ixnObj.logInfo('checkTrafficState: Expecting state: {0}\n'.format(expectedState)) + if trafficItemList is None: + trafficItemList = self.ixNetwork.Traffic.TrafficItem.find() - for trafficItemObj in trafficItemList: - for counter in range(1,timeout+1): - response = self.ixnObj.get(self.ixnObj.httpHeader + trafficItemObj, silentMode=True) - currentTrafficState = response.json()['state'] + for eachTrafficItem in trafficItemList: + for counter in range(1, timeout + 1): + currentTrafficState = eachTrafficItem.State if currentTrafficState == 'unapplied': - self.ixnObj.logWarning('\nCheckTrafficState: Traffic is UNAPPLIED') + self.ixnObj.logWarning('\nCheckTrafficState:Traffic is UNAPPLIED') + eachTrafficItem.Generate() self.applyTraffic() + trafficItemName = eachTrafficItem.Name + eachTrafficItem = self.getTrafficItemObjByName(trafficItemName=trafficItemName) - self.ixnObj.logInfo('\ncheckTrafficState: {}'.format(trafficItemObj)) - self.ixnObj.logInfo('\t{trafficState}: Expecting: {expectedStates}.'.format(trafficState=currentTrafficState, - expectedStates=expectedState), - timestamp=False) - - self.ixnObj.logInfo('\tWaited {counter}/{timeout} seconds'.format(counter=counter, timeout=timeout), timestamp=False) - - if counter <= timeout and currentTrafficState not in expectedState: + if (counter <= timeout) and (currentTrafficState not in expectedState): time.sleep(1) continue if counter <= timeout and currentTrafficState in expectedState: - #time.sleep(8) - self.ixnObj.logInfo('checkTrafficState: {}: Done\n'.format(trafficItemObj)) + self.ixnObj.logInfo('checkTrafficState: {}: Done\n'.format(eachTrafficItem)) break - if counter == timeout and currentTrafficState not in expectedState: - if ignoreException == False: - raise IxNetRestApiException('checkTrafficState: Traffic item state did not reach the expected state(s): {0}: {1}. It is at: {2}'.format( - trafficItemObj, expectedState, currentTrafficState)) + if (counter == timeout) and (currentTrafficState not in expectedState): + if not ignoreException: + raise IxNetRestApiException('checkTrafficState: Traffic item state did ' + 'not reach the expected state(s): {0}: {1}. ' + 'It is at: {2}'.format(eachTrafficItem, + expectedState, + currentTrafficState) + ) else: return 1 - def checkTrafficState(self, expectedState=['stopped'], timeout=60, ignoreException=False): + def checkTrafficState(self, expectedState=['stopped'], + timeout=60, ignoreException=False): """ Description Check the traffic state for the expected state. @@ -1221,66 +1115,59 @@ def checkTrafficState(self, expectedState=['stopped'], timeout=60, ignoreExcepti Parameters expectedState: : Input a list of expected traffic state. - Example: ['started', startedWaitingForStats'] <-- This will wait until stats has arrived. + Example: ['started', startedWaitingForStats'] + <-- This will wait until stats has arrived. - timeout: : The amount of seconds you want to wait for the expected traffic state. - Defaults to 45 seconds. - In a situation where you have more than 10 pages of stats, you will - need to increase the timeout time. + timeout: : The amount of seconds you want to wait for the expected traffic + state. Defaults to 45 seconds. + In a situation where you have more than 10 pages of stats, you will need to increase + the timeout time. ignoreException: : If True, return 1 as failed, and don't raise an Exception. Return 1: If failed. """ - if type(expectedState) != list: - expectedState.split(' ') - - self.ixnObj.logInfo('checkTrafficState: Expecting state: {0}\n'.format(expectedState)) - for counter in range(1,timeout+1): - response = self.ixnObj.get(self.ixnObj.sessionUrl+'/traffic', silentMode=True) - currentTrafficState = response.json()['state'] + currentTrafficState = None + for counter in range(1, timeout + 1): + currentTrafficState = self.ixNetwork.Traffic.State if currentTrafficState == 'unapplied': self.ixnObj.logWarning('\nCheckTrafficState: Traffic is UNAPPLIED') - self.applyTraffic() + if self.ixNetwork.Traffic.IsApplicationTrafficRunning: + self.ixNetwork.Traffic.ApplyOnTheFlyTrafficChanges() + else: + self.ixNetwork.Traffic.Apply() - self.ixnObj.logInfo('\ncheckTrafficState: {trafficState}: Expecting: {expectedStates}.'.format(trafficState=currentTrafficState, - expectedStates=expectedState), - timestamp=False) - self.ixnObj.logInfo('\tWaited {counter}/{timeout} seconds'.format(counter=counter, timeout=timeout), timestamp=False) - if counter <= timeout and currentTrafficState not in expectedState: time.sleep(1) continue if counter <= timeout and currentTrafficState in expectedState: time.sleep(8) - self.ixnObj.logInfo('checkTrafficState: Done\n') return 0 - - if ignoreException == False: - raise IxNetRestApiException('checkTrafficState: Traffic state did not reach the expected state(s): {0}. It is at: {1}'.format( - expectedState, currentTrafficState)) + + if ignoreException is False: + raise IxNetRestApiException('checkTrafficState: Traffic state did\ + not reach the expected state(s): {0}. It is at: {1}'.format(expectedState, + currentTrafficState)) else: return 1 def getRawTrafficItemSrcIp(self, trafficItemName): """ Description - Get the Raw Traffic Item source IP address. Mainly to look up each Device Group - IPv4 that has the source IP address to get the gateway IP address. + Get the Raw Traffic Item source IP address.Mainly to look up each Device Group IPv4 that + has the source IP address to get the gateway IP address. Parameter trafficItemName: The Raw Traffic Item name """ trafficItemObj = self.getTrafficItemObjByName(trafficItemName) - queryData = { - "from": trafficItemObj+"/configElement/1", - "nodes": [{"node": "stack", "properties": ["*"], "where": [{"property": "stackTypeId", "regex": "ipv4"}]}, - {"node": "field", "properties": ["*"], "where": [{"property": "fieldTypeId", "regex": "ipv4.header.srcIp"}]}] - } - queryResponse = self.ixnObj.query(data=queryData) - sourceIp = queryResponse.json()['result'][0]['stack'][1]['field'][26]['fieldValue'] + if trafficItemObj == 0: + raise IxNetRestApiException('\nNo such Traffic Item name: %s' % trafficItemName) + fieldObj = trafficItemObj.ConfigElement.find().Stack.find(StackTypeId="ipv4").Field.find( + FieldTypeId="ipv4.header.srcIp") + sourceIp = fieldObj.FieldValue return sourceIp def getTrafficItemType(self, trafficItemName): @@ -1294,13 +1181,10 @@ def getTrafficItemType(self, trafficItemName): Return The traffic type """ - queryData = {'from': '/traffic', - 'nodes': [{'node': 'trafficItem', 'properties': ['name', 'trafficType'], 'where': [{'property': 'name', 'regex': trafficItemName}]}, - ]} - queryResponse = self.ixnObj.query(data=queryData) - if queryResponse.json()['result'][0]['trafficItem'] == []: - raise IxNetRestApiException('getTrafficItemType: No such Traffic Item Name found: %s' % trafficItemName) - return (queryResponse.json()['result'][0]['trafficItem'][0]['trafficType']) + trafficItemObj = self.getTrafficItemObjByName(trafficItemName) + if trafficItemObj == 0: + raise IxNetRestApiException('\nNo such Traffic Item name: %s' % trafficItemName) + return trafficItemObj.TrafficType def enableTrafficItemByName(self, trafficItemName, enable=True): """ @@ -1315,8 +1199,8 @@ def enableTrafficItemByName(self, trafficItemName, enable=True): """ trafficItemObj = self.getTrafficItemObjByName(trafficItemName) if trafficItemObj == 0: - raise IxNetRestApiException('No such Traffic Item name: %s' % trafficItemName) - self.ixnObj.patch(self.ixnObj.httpHeader+trafficItemObj, data={"enabled": enable}) + raise IxNetRestApiException('\nNo such Traffic Item name: %s' % trafficItemName) + trafficItemObj.Enabled = enable def getTrafficItemName(self, trafficItemObj): """ @@ -1325,55 +1209,41 @@ def getTrafficItemName(self, trafficItemObj): Parameter trafficItemObj: The Traffic Item object. - /api/v1/sessions/1/ixnetwork/traffic/trafficItem/1 """ - response = self.ixnObj.get(self.ixnObj.httpHeader+trafficItemObj) - return response.json()['name'] + return trafficItemObj.Name def getAllTrafficItemObjects(self, getEnabledTrafficItemsOnly=False): """ Description - Get all the Traffic Item objects. - Due to the 100 items limit on REST call, using skip and take to break down the large list. - + Get all the Traffic Item objects. + Parameter getEnabledTrafficItemOnly: Return A list of Traffic Items """ - trafficItemObjList = [] - numOfTrafficItem = 0 - response = self.ixnObj.get(self.ixnObj.sessionUrl + '/traffic/trafficItem' + "?skip=" + str(numOfTrafficItem) + "&take=100") - - while numOfTrafficItem < response.json()['count']: - for eachTrafficItem in response.json()['data']: - if getEnabledTrafficItemsOnly == True: - if eachTrafficItem['enabled'] == True: - trafficItemObjList.append(eachTrafficItem['links'][0]['href']) - else: - trafficItemObjList.append(eachTrafficItem['links'][0]['href']) - numOfTrafficItem += 100 - response = self.ixnObj.get(self.ixnObj.sessionUrl + '/traffic/trafficItem' + "?skip=" + str(numOfTrafficItem) + "&take=100") - - return trafficItemObjList + trafficItemObjList = self.ixNetwork.Traffic.TrafficItem.find() + trafficItemObj = [] + if getEnabledTrafficItemsOnly: + for eachTrafficItem in trafficItemObjList: + if eachTrafficItem.Enabled: + trafficItemObj.append(eachTrafficItem) + return trafficItemObj + else: + return trafficItemObjList def getAllTrafficItemNames(self): """ Description Return all of the Traffic Item names. """ - numOfTrafficItem = 0 trafficItemNameList = [] - trafficItemUrl = self.ixnObj.sessionUrl+'/traffic/trafficItem' - response = self.ixnObj.get(trafficItemUrl+ "?skip=" + str(numOfTrafficItem) + "&take=100") - while numOfTrafficItem < response.json()['count']: - for eachTrafficItemId in response.json()['data']: - trafficItemNameList.append(eachTrafficItemId['name']) - numOfTrafficItem += 100 - response = self.ixnObj.get(trafficItemUrl+ "?skip=" + str(numOfTrafficItem) + "&take=100") + trafficItemObj = self.ixNetwork.Traffic.TrafficItem.find() + for eachTrafficItem in trafficItemObj: + trafficItemNameList.append(eachTrafficItem.Name) return trafficItemNameList - def getTrafficItemObjByName_backup(self, trafficItemName): + def getTrafficItemObjByName(self, trafficItemName): """ Description Get the Traffic Item object by the Traffic Item name. @@ -1383,51 +1253,19 @@ def getTrafficItemObjByName_backup(self, trafficItemName): Return 0: No Traffic Item name found. Return 0. - traffic item object: /api/v1/sessions/1/ixnetwork/traffic/trafficItem/2 """ - queryData = {'from': '/traffic', - 'nodes': [{'node': 'trafficItem', 'properties': ['name'], 'where': [{"property": "name", "regex": trafficItemName}]} - ]} - - queryResponse = self.ixnObj.query(data=queryData, silentMode=False) - - try: - return queryResponse.json()['result'][0]['trafficItem'][0]['href'] - except: + trafficItemObj = self.ixNetwork.Traffic.TrafficItem.find(Name=trafficItemName) + if trafficItemObj: + return trafficItemObj + else: return 0 - def getTrafficItemObjByName(self, trafficItemName): - """ - Description - Get the Traffic Item object by the Traffic Item name. - - Parameter - trafficItemName: Name of the Traffic Item. - - Return - 0: No Traffic Item name found. Return 0. - traffic item object: /api/v1/sessions/1/ixnetwork/traffic/trafficItem/2 - """ - # /api/v1/sessions//ixnetwork/traffic - fromObj = self.ixnObj.apiSessionId + '/traffic' - queryData = {"selects": [{"from": fromObj, "properties": [], - "children": [{"child": "trafficItem", "properties": ["*"], - "filters": [{"property": "name", "regex": trafficItemName}]}], "inlines": []}]} - - queryResponse = self.ixnObj.select(queryData) - try: - return queryResponse.json()['result'][0]['trafficItem'][0]['href'] - except: - return 0 - def applyTraffic(self): """ Description Apply the configured traffic. """ - restApiHeader = '/api'+self.ixnObj.sessionUrl.split('/api')[1] - response = self.ixnObj.post(self.ixnObj.sessionUrl+'/traffic/operations/apply', data={'arg1': restApiHeader+'/traffic'}) - self.ixnObj.waitForComplete(response, self.ixnObj.sessionUrl+'/traffic/operations/apply/'+response.json()['id']) + self.ixNetwork.Traffic.Apply() def regenerateTrafficItems(self, trafficItemList='all'): """ @@ -1436,29 +1274,19 @@ def regenerateTrafficItems(self, trafficItemList='all'): Parameter trafficItemList: 'all' will automatically regenerate from all Traffic Items. - Or provide a list of Traffic Items. - ['/api/v1/sessions/1/ixnetwork/traffic/trafficItem/1', ...] + Or provide a list of Traffic Items. """ + trafficItemObjList = [] if trafficItemList == 'all': - trafficItemList = [] - numOfTrafficItem = 0 - response = self.ixnObj.get(self.ixnObj.sessionUrl + '/traffic/trafficItem' + "?skip=" + str(numOfTrafficItem) + "&take=100") - while numOfTrafficItem < response.json()['count']: - for eachTrafficItem in response.json()['data']: - trafficItemList.append(eachTrafficItem['links'][0]['href']) - numOfTrafficItem += 100 - response = self.ixnObj.get(self.ixnObj.sessionUrl + '/traffic/trafficItem' + "?skip=" + str(numOfTrafficItem) + "&take=100") - else: - if type(trafficItemList) != list: - trafficItemList = trafficItemList.split(' ') - - url = self.ixnObj.sessionUrl+"/traffic/trafficItem/operations/generate" - data = {"arg1": trafficItemList} + trafficItemsObj = self.ixNetwork.Traffic.TrafficItem.find() + for eachTrafficItem in trafficItemsObj: + trafficItemObjList.append(eachTrafficItem) self.ixnObj.logInfo('Regenerating traffic items: %s' % trafficItemList) - response = self.ixnObj.post(url, data=data) - self.ixnObj.waitForComplete(response, url+'/'+response.json()['id']) + for eachTrafficItem in trafficItemObjList: + eachTrafficItem.Generate() - def startTraffic(self, regenerateTraffic=True, applyTraffic=True, blocking=False): + def startTraffic(self, regenerateTraffic=True, + applyTraffic=True, blocking=False): """ Description Start traffic and verify traffic is started. @@ -1466,23 +1294,14 @@ def startTraffic(self, regenerateTraffic=True, applyTraffic=True, blocking=False Parameter regenerateTraffic: - - applyTraffic: - In a situation like packet capturing, you cannot apply traffic after - starting packet capture because this will stop packet capturing. - You need to set applyTraffic to False in this case. + applyTraffic: + In a situation like packet capturing, you cannot apply traffic after starting + packet capture because this will stop packet capturing. You need to set + applyTraffic to False in this case. blocking: If True, API server doesn't return until it has - started traffic and ready for stats. Unblocking is the opposite. - - Syntax - For blocking state: - POST: /api/v1/sessions/{id}/ixnetwork/traffic/operations/startstatelesstrafficblocking' - DATA: {arg1: ['/api/v1/sessions/{id}/ixnetwork/traffic/trafficItem/{id}' ...]} - - For non blocking state: - POST: /api/v1/sessions/1/ixnetwork/traffic/operations/start - DATA: {arg1: '/api/v1/sessions/{id}/ixnetwork/traffic'} + started traffic and ready for stats. + Unblocking is the opposite. Requirements: For non blocking state only: @@ -1490,28 +1309,28 @@ def startTraffic(self, regenerateTraffic=True, applyTraffic=True, blocking=False # You need to check the traffic state before getting stats. # Note: Use the configElementObj returned by configTrafficItem() if trafficObj.getTransmissionType(configElementObj) == "fixedFrameCount": - trafficObj.checkTrafficState(expectedState=['stopped', 'stoppedWaitingForStats'], timeout=45) + trafficObj.checkTrafficState(expectedState=['stopped', 'stoppedWaitingForStats'], + timeout=45) if trafficObj.getTransmissionType(configElementObj) == "continuous": - trafficObj.checkTrafficState(expectedState=['started', 'startedWaitingForStats'], timeout=45) + trafficObj.checkTrafficState(expectedState=['started', 'startedWaitingForStats'], + timeout=45) """ if regenerateTraffic: - self.regenerateTrafficItems() + self.ixNetwork.Traffic.TrafficItem.find().Generate() + time.sleep(2) if applyTraffic: - self.applyTraffic() + if self.ixNetwork.Traffic.IsApplicationTrafficRunning: + self.ixNetwork.Traffic.ApplyOnTheFlyTrafficChanges() + else: + self.ixNetwork.Traffic.Apply() - if blocking == False: - url = self.ixnObj.sessionUrl+'/traffic/operations/start' - response = self.ixnObj.post(url, data={'arg1': self.ixnObj.sessionUrl+'/traffic'}) - self.ixnObj.waitForComplete(response, url + '/' + response.json()['id'], timeout=120) + if blocking is False: + self.ixNetwork.Traffic.Start() - # Server will go into blocking state until it is ready to accept the next api command. - if blocking == True: - enabledTrafficItemList = self.getAllTrafficItemObjects(getEnabledTrafficItemsOnly=True) - url = self.ixnObj.sessionUrl+'/traffic/trafficItem/operations/startstatelesstrafficblocking' - response = self.ixnObj.post(url, data={'arg1': enabledTrafficItemList}) - self.ixnObj.waitForComplete(response, url + '/' + response.json()['id'], timeout=120) + if blocking is True: + self.ixNetwork.Traffic.StartStatelessTrafficBlocking() def stopTraffic(self, blocking=False): """ @@ -1519,92 +1338,74 @@ def stopTraffic(self, blocking=False): Stop traffic and verify traffic has stopped. Parameters - blocking: : True=Synchronous mode. Server will not accept APIs until the process is complete. - - Syntax - For blocking state: - POST: /api/v1/sessions/{id}/ixnetwork/traffic/operations/stopstatelesstrafficblocking - DATA: {arg1: ['/api/v1/sessions/{id}/ixnetwork/traffic/trafficItem/{id}' ...]} + blocking: : True=Synchronous mode. Server will not accept APIs until the process + is complete. - For non blocking state: - POST: /api/v1/sessions/{id}/ixnetwork/traffic/operations/stop - DATA: {'arg1': '/api/v1/sessions/{id}/ixnetwork/traffic'} """ - if blocking == True: - #queryData = {"from": "/traffic", - # "nodes": [{"node": "trafficItem", "properties": ["enabled"], "where": [{"property": "enabled", "regex": "True"}]}]} - - #queryResponse = self.ixnObj.query(data=queryData, silentMode=False) - #enabledTrafficItemHrefList = [trafficItem['href'] for trafficItem in queryResponse.json()['result'][0]['trafficItem']] - - enabledTrafficItemList = self.getAllTrafficItemObjects(getEnabledTrafficItemsOnly=True) - url = self.ixnObj.sessionUrl+'/traffic/operations/stopstatelesstrafficblocking' - response = self.ixnObj.post(url, data={'arg1': enabledTrafficItemList}) - self.ixnObj.waitForComplete(response, url + '/' + response.json()['id'], timeout=120) - - if blocking == False: - self.ixnObj.logInfo('stopTraffic: %s' % self.ixnObj.sessionUrl+'/traffic/operations/stop') - url = self.ixnObj.sessionUrl+'/traffic/operations/stop' - response = self.ixnObj.post(url, data={'arg1': '{0}/ixnetwork/traffic'.format(self.ixnObj.headlessSessionId)}) - self.ixnObj.waitForComplete(response, url + '/' + response.json()['id'], timeout=120) - - self.checkTrafficState(expectedState=['stopped']) - time.sleep(3) + if blocking is True: + self.ixNetwork.Traffic.StopStatelessTrafficBlocking() + else: + self.ixNetwork.Traffic.Stop() def showTrafficItems(self): """ Description Show All Traffic Item details. """ - queryData = {'from': '/traffic', - 'nodes': [{'node': 'trafficItem', 'properties': ['name', 'enabled', 'state', 'biDirectional', 'trafficType', 'warning', 'errors'], 'where': []}, - {'node': 'endpointSet', 'properties': ['name', 'sources', 'destinations'], 'where': []}, - {'node': 'configElement', 'properties': ['name', 'endpointSetId', ], 'where': []}, - {'node': 'frameSize', 'properties': ['type', 'fixedSize'], 'where': []}, - {'node': 'framePayload', 'properties': ['type', 'customRepeat'], 'where': []}, - {'node': 'frameRate', 'properties': ['type', 'rate'], 'where': []}, - {'node': 'frameRateDistribution', 'properties': ['streamDistribution', 'portDistribution'], 'where': []}, - {'node': 'transmissionControl', 'properties': ['type', 'frameCount', 'burstPacketCount'], 'where': []}, - {'node': 'tracking', 'properties': ['trackBy'], 'where': []}, - ] - } - - queryResponse = self.ixnObj.query(data=queryData, silentMode=True) + frameSize = None + trafficItemsObj = self.ixNetwork.Traffic.TrafficItem.find() self.ixnObj.logInfo('\n', end='', timestamp=False) - for ti in queryResponse.json()['result'][0]['trafficItem']: + for (index, trafficItem) in enumerate(trafficItemsObj): self.ixnObj.logInfo('TrafficItem: {0}\n\tName: {1} Enabled: {2} State: {3}'.format( - ti['id'], ti['name'], ti['enabled'], ti['state']), timestamp=False) - self.ixnObj.logInfo('\tTrafficType: {0} BiDirectional: {1}'.format(ti['trafficType'], - ti['biDirectional']), - timestamp=False) + index + 1, trafficItem.Name, trafficItem.Enabled, trafficItem.State), + timestamp=False) - for tracking in ti['tracking']: - self.ixnObj.logInfo('\tTrackings: {0}'.format(tracking['trackBy']), timestamp=False) + self.ixnObj.logInfo('\tTrafficType: {0} BiDirectional: {1}'.format( + trafficItem.TrafficType, + trafficItem.BiDirectional), + timestamp=False) - for endpointSet, cElement in zip(ti['endpointSet'], ti['configElement']): - self.ixnObj.logInfo('\tEndpointSetId: {0} EndpointSetName: {1}'.format(endpointSet['id'], - endpointSet['name']), timestamp=False) + for tracking in trafficItem.Tracking.find(): + self.ixnObj.logInfo('\tTrackings: {0}'.format(tracking.TrackBy), timestamp=False) + + for endpointSet, cElement in zip(trafficItem.EndpointSet.find(), + trafficItem.ConfigElement.find()): + self.ixnObj.logInfo('\tEndpointSetId: {0} EndpointSetName: {1}'.format( + endpointSet.index, endpointSet.Name), timestamp=False) srcList = [] - for src in endpointSet['sources']: + for src in endpointSet.Sources: srcList.append(src.split('/ixnetwork')[1]) dstList = [] - for dest in endpointSet['destinations']: + for dest in endpointSet.Destinations: dstList.append(dest.split('/ixnetwork')[1]) - self.ixnObj.logInfo('\t Sources: {0}'.format(srcList), timestamp=False) - self.ixnObj.logInfo('\t Destinations: {0}'.format(dstList), timestamp=False) - self.ixnObj.logInfo('\t FrameType: {0} FrameSize: {1}'.format(cElement['frameSize']['type'], - cElement['frameSize']['fixedSize']), - timestamp=False) - self.ixnObj.logInfo('\t TranmissionType: {0} FrameCount: {1} BurstPacketCount: {2}'.format( - cElement['transmissionControl']['type'], - cElement['transmissionControl']['frameCount'], - cElement['transmissionControl']['burstPacketCount']), + if cElement.FrameSize.Type == 'fixed': + frameSize = cElement.FrameSize.FixedSize + elif cElement.FrameSize.Type == 'increment': + frameSize = (cElement.FrameSize.IncrementFrom, cElement.FrameSize.IncrementTo, + cElement.FrameSize.IncrementStep) + elif cElement.FrameSize.Type == 'random': + frameSize = (cElement.FrameSize.RandomMin, cElement.FrameSize.RandomMax) + elif cElement.FrameSize.Type == 'presetDistribution': + frameSize = cElement.FrameSize.PresetDistribution + elif cElement.FrameSize.Type == 'quadGaussian': + frameSize = cElement.FrameSize.QuadGaussian + elif cElement.FrameSize.Type == 'weightedPairs': + frameSize = cElement.FrameSize.WeightedPairs + + self.ixnObj.logInfo('\tSources: {0}'.format(srcList), timestamp=False) + self.ixnObj.logInfo('\tDestinations: {0}'.format(dstList), timestamp=False) + self.ixnObj.logInfo('\tFrameType: {0} FrameSize: {1}'.format( + cElement.FrameSize.Type, frameSize), timestamp=False) + self.ixnObj.logInfo('\tTranmissionType: {0} FrameCount: {1} BurstPacketCount: {2}' + .format(cElement.TransmissionControl.Type, + cElement.TransmissionControl.FrameCount, + cElement.TransmissionControl.BurstPacketCount), timestamp=False) - self.ixnObj.logInfo('\t FrameRateType: {0} FrameRate: {1}'.format( - cElement['frameRate']['type'], cElement['frameRate']['rate']), timestamp=False) + self.ixnObj.logInfo('\tFrameRateType: {0} FrameRate: {1}'.format( + cElement.FrameRate.Type, cElement.FrameRate.Rate), timestamp=False) self.ixnObj.logInfo('\n', end='', timestamp=False) @@ -1615,36 +1416,81 @@ def setFrameSize(self, trafficItemName, **kwargs): Parameters type: : fixed|increment|presetDistribution|quadGaussian|random|weightedPairs - + trafficItemName: : The name of the Traffic Item.. Example: trafficObj.setFrameSize('Topo1 to Topo2', type='fxied', fixedSize=128) - trafficObj.setFrameSize('Topo1 to Topo2', type='increment', incrementFrom=68, incrementStep=2, incrementTo=1200) + trafficObj.setFrameSize('Topo1 to Topo2', type='increment', incrementFrom=68, + incrementStep=2, incrementTo=1200) """ - queryData = {'from': '/traffic', - 'nodes': [{'node': 'trafficItem', 'properties': ['name'], 'where': [{'property': 'name', 'regex': trafficItemName}]}, - {'node': 'configElement', 'properties': [], 'where': []}]} - queryResponse = self.ixnObj.query(data=queryData) - if queryResponse.json()['result'][0]['trafficItem'] == []: + trafficItemObj = self.ixNetwork.Traffic.TrafficItem.find(Name=trafficItemName) + if not trafficItemObj: raise IxNetRestApiException('\nNo such Traffic Item name found: %s' % trafficItemName) - - configElementObj = queryResponse.json()['result'][0]['trafficItem'][0]['configElement'][0]['href'] - self.ixnObj.patch(self.ixnObj.httpHeader+configElementObj+'/frameSize', data=kwargs) - - def configFramePayload(self, configElementObj, payloadType='custom', customRepeat=True, customPattern=None): + frameSizeObj = trafficItemObj.ConfigElement.find().FrameSize + frameSizeObj.Type = kwargs.get('type') + frameSizeType = kwargs.get('type') + if frameSizeType == 'fixed': + frameSizeObj.FixedSize = kwargs['fixedSize'] if kwargs.get('fixedSize') else 128 + elif frameSizeType == 'increment': + if kwargs.get('incrementFrom'): + frameSizeObj.IncrementFrom = kwargs['incrementFrom'] + else: + frameSizeObj.IncrementFrom = 64 + + if kwargs.get('incrementTo'): + frameSizeObj.IncrementTo = kwargs.get('incrementTo') + else: + frameSizeObj.IncrementTo = 1518 + + if kwargs.get('incrementStep'): + frameSizeObj.IncrementStep = kwargs.get('incrementStep') + else: + frameSizeObj.IncrementStep = 1 + + elif frameSizeType == 'random': + if kwargs.get('randomMin'): + frameSizeObj.RandomMin = kwargs.get('randomMin') + else: + frameSizeObj.RandomMin = 64 + if kwargs.get('randomMax'): + frameSizeObj.RandomMax = kwargs.get('randomMax') + else: + frameSizeObj.RandomMax = 1518 + elif frameSizeType == 'presetDistribution': + if kwargs.get('presetDistribution'): + frameSizeObj.PresetDistribution = kwargs.get('presetDistribution') + else: + frameSizeObj.PresetDistribution = 'cisco' + elif frameSizeType == 'quadGaussian': + if kwargs.get('quadGaussian'): + frameSizeObj.QuadGaussian = kwargs['quadGaussian'] + elif frameSizeType == 'weightedPairs': + if kwargs.get('weightedPairs'): + frameSizeObj.WeightedPairs = kwargs.get('weightedPairs') + else: + frameSizeObj.WeightedPairs = [61, 1] + + if kwargs.get('weightedRangePairs'): + frameSizeObj.WeightedRangePairs = kwargs['weightedRangePairs'] + + def configFramePayload(self, configElementObj, payloadType='custom', customRepeat=True, + customPattern=None): """ Description Configure the frame payload. Parameters - payloadType: : Options: - custom, decrementByte, decrementWord, incrementByte, incrementWord, random + payloadType: : Options: custom, decrementByte, decrementWord, incrementByte, + incrementWord, random customRepeat: customPattern: : Enter a custom payload pattern """ - data = {'type': payloadType, 'customRepeat': customRepeat, 'customPattern': customPattern} - self.ixnObj.patch(self.ixnObj.httpHeader+configElementObj+'/framePayload', data=data) + framePayloadObj = configElementObj.FramePayload + framePayloadObj.Type = payloadType + if payloadType.lower() == 'custom': + framePayloadObj.CustomRepeat = customRepeat + framePayloadObj.CustomPattern = customPattern def enableMinFrameSize(self, enable=True): """ @@ -1654,22 +1500,14 @@ def enableMinFrameSize(self, enable=True): Parameter enable: : True to enable it. """ - self.ixnObj.patch(self.ixnObj.sessionUrl+'/traffic', data={'enableMinFrameSize': enable}) + self.ixNetwork.Traffic.EnableMinFrameSize = enable def suspendTrafficItem(self, trafficItemObj, suspend=True): """ Description Suspend the Traffic Item from sending traffic. - Parameter trafficItemObj: : The Traffic Item object. suspend: : True=suspend traffic. - - Syntax - PATCH: /api/v1/sessions/{id}/ixnetwork/traffic/trafficItem/{id} - DATA: {'suspend': True} """ - self.ixnObj.patch(self.ixnObj.httpHeader+trafficItemObj, data={'suspend': suspend}) - - - + trafficItemObj.Suspend = suspend