Get networks by country

Solved
Osberg
Here to help

Get networks by country

Hi all,

 

I am stuck in a what seems to be a small python script.. I might be just lost as hell hehe.. (not the first time hehe)

 

But I would like to have a script that do the following:

 

Find all networks in my org.

 

That can be done by this "default" python script:

import requests


payload={}
headers = {
  'X-Cisco-Meraki-API-Key': '*******'
}

response = requests.request("GET", url, headers=headers, data=payload)

print(response.text)
 
But I would like it to find only sites that have the following:
 
id and name
 
And the option only to show by country like DK ... 
 
That way I make out for each country that we have, and I can make script that matches each country. 🙂 
 
Hope it makes sense.
 
I tried to make it in the webapi also, but even do that I try filter with array and id and name it still show all info for each network site. 🙂 

 

Frank Osberg | Domain Architect @ Solar A/S
LinkedIn - Twitter
Found this helpful? Give me some Kudos! Much Thanks
1 Accepted Solution
rhbirkelund
Kind of a big deal
Kind of a big deal

Ah yes, I was a bit quick in the script. 😛

 

If you wan't to write the data to a simple text file, it would be something like

#!/usr/bin/env python3

import meraki


def do_stuff(p_id,p_name):
    with open("filename.txt","a") as fp:
        line = f"id: {p_id} \t name: {p_name}"
        fp.writelines(line)

def main():
    API_KEY = 'aaa'
    dashboard = meraki.DashboardAPI(API_KEY)

    organization_id = 'bbb'

    sites = dashboard.organizations.getOrganizationNetworks(
        organization_id, total_pages='all'
    )

    for site in sites:
        if "DK" in site['name']:
            do_stuff(site['id'],site['name'])

if __name__ == "__main__":
    main()

 

If we're talking about CSV data try something like, where you'd like all sites where the name contains "DK", we can do something like;

#!/usr/bin/env python3

import meraki
import csv


def main():
    API_KEY = 'aaa'
    dashboard = meraki.DashboardAPI(API_KEY)

    organization_id = 'bbb'

    sites = dashboard.organizations.getOrganizationNetworks(
        organization_id, total_pages='all'
    )

    ListOfDkSites = []
    for site in sites:
        if "DK" in site['name']:
            ListOfDkSites.append([site['id'],site['name']])

    header = ["id","name"]
    with open("filename.csv","w") as fp:
        writer = csv.writer(fp)
        writer.writerow(header)
        writer.writerows(ListOfDkSites)


if __name__ == "__main__":
    main()

 

Depending on how much data there is, you'd might want to break the CSV writer up in multiple writes, and append the file, rather than writing it all in one go.

 

I haven't run the code myself, but it's the gist of it.

LinkedIn ::: https://blog.rhbirkelund.dk/

Like what you see? - Give a Kudo ## Did it answer your question? - Mark it as a Solution 🙂

All code examples are provided as is. Responsibility for Code execution lies solely your own.

View solution in original post

10 Replies 10
rhbirkelund
Kind of a big deal
Kind of a big deal

Unfortunately, there isn't any endpoint from Meraki that will tell you exactly what country a given network is in. You'll have to either

1) Rely on information that is configured on the network it self, or

2) Cross-reference your MX WAN IP with whois tools, like ifconfig.co.

 

Ad 1) you can use the endpoint that you already are using, and check the timeZone field, or hope there is some country information in the tags and notes fields.

You can also use the Network Devices endpoint, and read the address field, assuming that also is configured.

 

Ad 2) Using this endpoint, you can cross-reference the WAN1 (or 2) uplink with e.g. ifconfig.co which you can also use to query on the IP address.

LinkedIn ::: https://blog.rhbirkelund.dk/

Like what you see? - Give a Kudo ## Did it answer your question? - Mark it as a Solution 🙂

All code examples are provided as is. Responsibility for Code execution lies solely your own.
Osberg
Here to help

So I can see my description of the problem is a bit unclear. 🙂 

 

So when I run the default "Get Organization Networks"

 

import requests

 

 

payload={}
headers = {
  'X-Cisco-Meraki-API-Key': '*******'
}

 

response = requests.request("GET", url, headers=headers, data=payload)

 

print(response.text)
 
I will get ALL networks in my org. 
But what I would like to get here is ONLY : ID and name 
 
"id": "L_********", "name": "DK - *******",
 
This is the hole idea here 🙂 
 
So what would I do with this afterwords... See when I do deployment for countries only like DK I would be able to use this list and take either the ID or Name and provide into my script like this: 
 

import requests
import json

sites = ["L_*********"]


payload = json.dumps({
"mode": "enabled"
})
headers = {
'X-Cisco-Meraki-API-Key': '*********',
'Content-Type': 'application/json'
}


for site in sites:
print (site)
url = "https://api.meraki.com/api/v1/networks/" + site + "/appliance/security/malware"

response = requests.request("PUT", url, headers=headers, data=payload)

print(response.text)

 

There might be a easier way on doing this, and hope you can guide me in some "smarter" direction 🙂 

 

Does this makes sense?? 

 

I know that I can take the hole list out of the GET Orginazation function, but if this could be more specific it would be great, but I don´t know if there is a way to filter things here?? (I am NOT an expert in python, still learning) 

 

Thanks for all your guides here.

 

Frank

Frank Osberg | Domain Architect @ Solar A/S
LinkedIn - Twitter
Found this helpful? Give me some Kudos! Much Thanks
rhbirkelund
Kind of a big deal
Kind of a big deal

Ah, it's just that? Try somthing like this;

 

 

#!/usr/bin/env python3

import meraki

def do_stuff(p_id,p_name):
    print("id: ",p_id,"\t name: ",p_name)


def main():
    API_KEY = 'aaa'
    dashboard = meraki.DashboardAPI(API_KEY)

    organization_id = 'bbb'

    sites = dashboard.organizations.getOrganizationNetworks(
        organization_id, total_pages='all'
    )

    for site in sites:
        if "DK" in site['name']:
            do_stuff(site[id],site['name'])

if __name__ == "__main__":
    main()

 

Edit: fixed two small typos in the example.

 

LinkedIn ::: https://blog.rhbirkelund.dk/

Like what you see? - Give a Kudo ## Did it answer your question? - Mark it as a Solution 🙂

All code examples are provided as is. Responsibility for Code execution lies solely your own.
Osberg
Here to help

Hi Rasmus,

 

When I edit your script and run it in my powershell on windows I am getting this error:

 

PS C:\Python\Python310\Scripts> python .\GET-Org-DK.py
2022-09-09 08:12:35 meraki: INFO > Meraki dashboard API session initialized with these parameters: {'version': '1.24.0', 'api_key': '************************************fb59', 'base_url': 'https://api.meraki.com/api/v1', 'single_request_timeout': 60, 'certificate_path': '', 'requests_proxy': '', 'wait_on_rate_limit': True, 'nginx_429_retry_wait_time': 60, 'action_batch_retry_wait_time': 60, 'retry_4xx_error': False, 'retry_4xx_error_wait_time': 60, 'maximum_retries': 2, 'simulate': False, 'be_geo_id': None, 'caller': None, 'use_iterator_for_get_pages': False}
2022-09-09 08:12:35 meraki: INFO > GET https://api.meraki.com/api/v1/organizations/*********/networks
2022-09-09 08:12:35 meraki: INFO > organizations, getOrganizationNetworks; page 1 - 200 OK
Traceback (most recent call last):
File "C:\Python\Python310\Scripts\GET-Org-DK.py", line 22, in <module>
main()
File "C:\Python\Python310\Scripts\GET-Org-DK.py", line 19, in main
do_stuff(site[id],site['name'])
KeyError: <built-in function id>
PS C:\Python\Python310\Scripts>

 

Something in line 19 and 22. 

 

I am guessing your have made your script to run on mac? 🙂 But it should be the same for windows right?^:) 

Frank Osberg | Domain Architect @ Solar A/S
LinkedIn - Twitter
Found this helpful? Give me some Kudos! Much Thanks
sungod
Kind of a big deal

From looking at the example script, change...

 

do_stuff(site[id],site['name'])

 

...to...

 

do_stuff(site['id'],site['name'])

 

Osberg
Here to help

Nice that worked. 🙂 

 

If I want the output to be put into a file what then? 🙂 

 

Thanks for all your help on this. 🙂 (I need to learn more Python... any good links that I should study??)

 

Frank

Frank Osberg | Domain Architect @ Solar A/S
LinkedIn - Twitter
Found this helpful? Give me some Kudos! Much Thanks
sungod
Kind of a big deal

There are loads of websites, try...

https://www.python.org/

https://www.python.org/about/gettingstarted/

https://www.w3schools.com/python/default.asp

 

Aside from just redirecting the script's output, you could open/create a file and write direct to it, for instance...

https://www.w3schools.com/python/python_file_write.asp

 

Osberg
Here to help

Thanks for the links I will dig more into them. 🙂 

 

I found a solution for point the print info into a file. 🙂 

 

Thanks for all the help 🙂 

Frank Osberg | Domain Architect @ Solar A/S
LinkedIn - Twitter
Found this helpful? Give me some Kudos! Much Thanks
rhbirkelund
Kind of a big deal
Kind of a big deal

Ah yes, I was a bit quick in the script. 😛

 

If you wan't to write the data to a simple text file, it would be something like

#!/usr/bin/env python3

import meraki


def do_stuff(p_id,p_name):
    with open("filename.txt","a") as fp:
        line = f"id: {p_id} \t name: {p_name}"
        fp.writelines(line)

def main():
    API_KEY = 'aaa'
    dashboard = meraki.DashboardAPI(API_KEY)

    organization_id = 'bbb'

    sites = dashboard.organizations.getOrganizationNetworks(
        organization_id, total_pages='all'
    )

    for site in sites:
        if "DK" in site['name']:
            do_stuff(site['id'],site['name'])

if __name__ == "__main__":
    main()

 

If we're talking about CSV data try something like, where you'd like all sites where the name contains "DK", we can do something like;

#!/usr/bin/env python3

import meraki
import csv


def main():
    API_KEY = 'aaa'
    dashboard = meraki.DashboardAPI(API_KEY)

    organization_id = 'bbb'

    sites = dashboard.organizations.getOrganizationNetworks(
        organization_id, total_pages='all'
    )

    ListOfDkSites = []
    for site in sites:
        if "DK" in site['name']:
            ListOfDkSites.append([site['id'],site['name']])

    header = ["id","name"]
    with open("filename.csv","w") as fp:
        writer = csv.writer(fp)
        writer.writerow(header)
        writer.writerows(ListOfDkSites)


if __name__ == "__main__":
    main()

 

Depending on how much data there is, you'd might want to break the CSV writer up in multiple writes, and append the file, rather than writing it all in one go.

 

I haven't run the code myself, but it's the gist of it.

LinkedIn ::: https://blog.rhbirkelund.dk/

Like what you see? - Give a Kudo ## Did it answer your question? - Mark it as a Solution 🙂

All code examples are provided as is. Responsibility for Code execution lies solely your own.
Osberg
Here to help

Option 2 works for a csv file, but not the first one. 🙂 

 

I can do it when I run the command with a > command: 

python .\GET-Org-NL.py > Get-Org-NL.txt fx. 

 

When running option 1 I get this error: 

 

PS C:\Python\Python310\Scripts> python .\GET-Org-DK.py
File "C:\Python\Python310\Scripts\GET-Org-DK.py", line 5
line = f"id: {p_id} \t name: {p_name}"

 

But I can fix this with the above command 🙂 

 

I will mark your idea / solution here Rasmus 

 

Thanks to all, here for your help. 🙂 

Frank Osberg | Domain Architect @ Solar A/S
LinkedIn - Twitter
Found this helpful? Give me some Kudos! Much Thanks
Get notified when there are additional replies to this discussion.