meraki / dashboard-api-python

Official Dashboard API library (SDK) for Python
MIT License
292 stars 152 forks source link

Filter on Org Devices Statuses List or Uplinks Statuses limited #182

Closed gsauvage6hat closed 2 years ago

gsauvage6hat commented 2 years ago

Problem

When using networkIds to filter the list of Organization Devices Statuses or Uplink Statuses, if the network ids list provided is too long, it's not working, the result is : WARNING > appliance, getOrganizationApplianceUplinkStatuses - 502 Bad Gateway, retrying in 1 second

I tried with different lists : 43 elements, 991 chars : OK 44 elements, 1014 chars : KO

Also tried to provide the list directly or as full json, same result. I guess the issue may be the same on other functions.

If I do classic calls with requests, it works correctly.

Versions

Python : 3.8.3 Library : 1.18.2

Code sample

    dev_list = []
    uplinkStatus_list = []
    netIdList = []

    net_list = dashboard.organizations.getOrganizationNetworks(org_id, tags="TagToFilter", tagsFilterType="withAllTags", total_pages='all')

    for network in net_list:
        netIdList.append(network['id'])

    netIdListFilter = {"networkIds":netIdList}

    dev_list = dashboard.organizations.getOrganizationDevicesStatuses(organizationId=org_id,networkIds=netIdList,total_pages='all')
    uplinkStatus_list = dashboard.appliance.getOrganizationApplianceUplinkStatuses(organizationId=org_id,**netIdListFilter,total_pages='all')

    print(dev_list)
    print(uplinkStatus_list)
TKIPisalegacycipher commented 2 years ago

Thanks for reporting this. Does 43 elements mean 43 different network IDs provided in the networkIds[] query param?

Are you able to provide a code sample using the requests library, where you don't have this issue using the same number of elements?

gsauvage6hat commented 2 years ago

Yes, this is with 43 different network IDs. I just tried to do the same with serials, and here is the limit for the list: 58 serials / 988 chars : KO 57 serials / 971 chars : OK

Sure, here is a code sample

dev_list = []
netIdList = []

net_list = dashboard.organizations.getOrganizationNetworks(org_id, tags="TagToFilter", tagsFilterType="withAllTags", total_pages='all')

for network in net_list:
    netIdList.append(network['id'])

netIdListFilter = {"networkIds":netIdList}

url = 'https://api.meraki.com/api/v1/organizations/%s/devices/statuses' % (org_id)
r = requests.get(url, data=json.dumps(netIdListFilter), headers={'X-Cisco-Meraki-API-Key': api_key, 'Content-Type': 'application/json'})
dev_list = r.json()

print(dev_list)
TKIPisalegacycipher commented 2 years ago

This sounds very similar to this question, however, I'm not able to reproduce this on my end.

Here's a script example, inspired by yours but using this repo's library. If you have an org with enough networks, and it's the only one with that name, then you should be able to run this just by changing the TEST_ORG_NAME constant.

import meraki

TEST_ORG_NAME = 'TestOrg'
TEST_ORG_ID = None

dashboard = meraki.DashboardAPI(suppress_logging=True)

orgs = dashboard.organizations.getOrganizations()
org_found = False

while not org_found:
    for org in orgs:
        print('checking for test org')
        if org['name'] == TEST_ORG_NAME:
            print(f'Checking {org["id"]}')
            TEST_ORG_ID = org['id']
            org_found = True
            break

net_id_list = []

net_list = dashboard.organizations.getOrganizationNetworks(TEST_ORG_ID)

for network in net_list:
    net_id_list.append(network['id'])

devices_statuses = dashboard.organizations.getOrganizationDevicesStatuses(TEST_ORG_ID, networkIds=net_id_list)

print(devices_statuses)

I found that this operation completes successfully with 101 network IDs, which seems long (20 per ID x 101 = 2020 characters). Let me know if you find the same.

TKIPisalegacycipher commented 2 years ago

I hope my last message was helpful. While we're not aware of any limits on the API end, this could be a limitation of Python or web proxies in between your client and api.meraki.com. In any case, I'm closing this considering no response. If you are able to reproduce this issue, you should be able to work around this by either filtering based on a tag (where supported) or by splitting the request into multiple API calls.