OpenIxia / IxNetwork

A central location for IxNetwork sample scripts and utilities. Please also visit http://openixia.com
MIT License
50 stars 59 forks source link

Non-existent dictionary key referenced in 'getTrafficItemPktHeaderStackObj' #16

Closed NickKeating closed 6 years ago

NickKeating commented 6 years ago

Hi,

I am using the 'modifyTrafficItemIpPriorityTos' function in IxNetRestApiTraffic.py to configure different ToS values across a number of traffic streams..

In the function 'getTrafficItemPktHeaderStackObj', the following call is made:

response = self.ixnObj.get(self.ixnObj.httpHeader+configElementObj+'/stack')

The subsequent 'for' loop then references the dictionary key 'stackTypeId' (eachStack['stackTypeId']) which is not a valid key in the response of this call, resulting in a KeyError.

for eachStack in response.json():
            self.ixnObj.logInfo('\nstack: {0}: {1}'.format(eachStack, eachStack['stackTypeId']), timestamp=False)
            if bool(re.match(packetHeaderName, eachStack['stackTypeId'], re.I)):
                stackObj = eachStack['links'][0]['href']
                break
        else:
            raise IxNetRestApiException('\nError: No such stack name found: %s' % stackName)

return stackObj

Sample of dictionaries returned in the list:

[
    {
        "id": 1,
        "displayName": "Ethernet II",
        "templateName": "ethernet-template.xml",
        "links": [
            {
                "rel": "meta",
                "method": "OPTIONS",
                "href": "/api/v1/sessions/1/ixnetwork/traffic/trafficItem/1/configElement/1/stack/1"
            }
        ]
    },
    {
        "id": 2,
        "displayName": "VLAN",

<<  output cut  >>

I have the following patch file that is applied during my packaging process that modifies the eachStack['stackTypeId'] to eachStack['displayName'] within this snippet to get the function to work as I think it is intended.

diff --git a/RestApi/Python/Modules/IxNetRestApiTraffic.py b/RestApi/Python/Modules/IxNetRestApiTraffic.py
index 50532fd..b022f46 100644
--- a/RestApi/Python/Modules/IxNetRestApiTraffic.py
+++ b/RestApi/Python/Modules/IxNetRestApiTraffic.py
@@ -620,8 +620,8 @@ class Traffic(object):
         print('\n--- packetHeaderName:', packetHeaderName)

         for eachStack in response.json():
-            self.ixnObj.logInfo('\nstack: {0}: {1}'.format(eachStack, eachStack['stackTypeId']), timestamp=False)
-            if bool(re.match(packetHeaderName, eachStack['stackTypeId'], re.I)):
+            self.ixnObj.logInfo('\nstack: {0}: {1}'.format(eachStack, eachStack['displayName']), timestamp=False)
+            if bool(re.match(packetHeaderName, eachStack['displayName'], re.I)):
                 stackObj = eachStack['links'][0]['href']
                 break
         else:

Thanks, Nick

hubertgee commented 6 years ago

Hi Nick,

I think you're using an older version of IxNetwork, which doesn't have the stackTypeId key. I analyzed the API and I agree displayName is better to use and I enhanced this API so it prints all the packet header names out to show users the spelling so they could enter it properly in order to get the stack object handle. Please pull an update.

Thanks, Hubert