Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions AddStaticRoute.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Test YML looks like:
# ---
# NetworkID: Z_9512345678
# API_Key: c1234567890abcdef01234
# Gateway:
# - GW: "1.2.3.4"
# Networks:
# - Network: "10.1.1.0/24"
# Name: "Net 10.1.1.0-24"
# - Network: "10.1.2.0/24"
# Name: "Net 10.1.2.0-24"
# - GW: "2.3.4.5"
# Networks:
# - Network: "10.2.1.0/24"
# Name: "10.2.1.0-24"
# - Network: "10.2.2.0/24"
# Name: "10.2.2.0-24"
import yaml, requests, json
with open ("StaticRoutes.yml") as file1:
config = yaml.load (file1)
url = "https://dashboard.meraki.com/api/v0/networks/%s/staticRoutes" % config["NetworkID"]
headers = {
'X-Cisco-Meraki-API-Key': "%s" %config["API_Key"],
'Content-Type': "application/json",
'Cache-Control': "no-cache",
}
for gateway in config["Gateway"]:
GatewayIP=gateway["GW"]
for network in gateway["Networks"]:
payload = {
"name" : network["Name"],
"subnet": network["Network"],
"gatewayIp": gateway["GW"],
"enabled":"true"
}
response = requests.request("POST", url, data=json.dumps(payload), headers=headers)
print(response.status_code, response.text)
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ Files contained in this repository:

**Installing Python on Windows.txt:** General info for installing Python 3 on Windows

**AddStaticRoute.py:** This simple script reads a list of static routes from a YAML file and adds them to a Network.

**copymxvlans.py:** This script can be used to export MX VLAN configuration of a source org to a file and import it to a destination org. The script will look for the exact same network names as they were in the source org. Use copynetworks.py and movedevices.py to migrate networks and devices if needed.

**copynetworks.py:** Copies networks and their base attributes from one organization to another. Does not move devices over or copy individual device configuration. Combined networks will be copied as "wireless switch appliance".
Expand Down
115 changes: 115 additions & 0 deletions meraki-export.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#!/usr/bin/env python3
# Before running this script you need to install these three modules:
# pip install meraki yaml argparse
from meraki import meraki
import argparse
import yaml

config={} #Define config as a dictionary
config["Organization"]={} #Define organization as a dictionary
config["Organization"]["Network"]=[] #but Network is a list
def get_org_id(apikey,orgName,suppressprint): #Turns an org name into an org ID
result = meraki.myorgaccess(apikey, suppressprint)
for row in result:
if row['name'] == orgName:
return row['id']

raise ValueError('The organization name does not exist')

def admins(apikey, orgid, suppressprint): # Retrieves a list of admins
myOrgAdmins=meraki.getorgadmins(apikey, orgid, suppressprint)
config["Organization"]["Admins"]=myOrgAdmins
print("Got admins")

def mx_l3_fw_rules(apikey,networkid,suppressprint): #Retrieves the Layer 3 firewall rules on the MX
myRules=meraki.getmxl3fwrules(apikey, networkid, suppressprint)[0:-1]
network["L3-Firewall-Rules"]=myRules
print("Got Layer 3 firewall rules")

def mx_cellular_fw_rules(apikey,networkid,suppressprint): # Retrieves the mobile firewall rules
myRules=meraki.getmxcellularfwrules(apikey, networkid, suppressprint)[0:-1]
network["Cell-Firewall-Rules"]=myRules
print("Got mobile firewall rules")

def mx_vpn_fw_rules(apikey,orgid,suppressprint): # Retrieves the VPN firewall rules
myRules=meraki.getmxvpnfwrules(apikey, orgid, suppressprint)[0:-1]
config["Organization"]["MX-VPN-Firewall-Rules"]=myRules
print("Got VPN firewall rules")

def vpn_settings(apikey,networkid,suppressprint): # Retrieves Meraki S2S VPN settings
myVPN=meraki.getvpnsettings(apikey, networkid, suppressprint)
network["VPN-Settings"]=myVPN
print("Got VPN settings")

def snmp_settings(apikey,orgid,suppressprint): # Retrieves SNMP settings
mySNMP=meraki.getsnmpsettings(apikey, orgid, suppressprint)
config["Organization"]["SNMP"]=mySNMP
print("Got SNMP settings")

def non_meraki_vpn_peers(apikey,orgid,suppressprint): # Retrieves non-Meraki site-to-site
myPeers=meraki.getnonmerakivpnpeers(apikey,orgid,suppressprint)
config["Organization"]["Non-Meraki-VPN"]=myPeers
print("Got non-Meraki VPN peers")

def static_routes(apikey,networkid,suppressprint): # Retrieve any static routes
myRoutes=meraki.getstaticroutes(apikey,networkid,suppressprint)
if myRoutes is None:
return
network["Routes"]=myRoutes
print("Got static routes")

def ssid_settings(apikey,networkid,suppressprint): # Retrieve all SSID settings
mySSIDs=meraki.getssids(apikey, networkid, suppressprint)
if mySSIDs is None:
return
for row in mySSIDs:
myRules=meraki.getssidl3fwrules(apikey, networkid, row['number'], suppressprint)[0:-2]
row["rules"]=myRules
network["SSID"].append(row)
print("Got SSID "+str(row["number"]))
####################################################
# Main program
# ##################################################
parser = argparse.ArgumentParser(description='Backup a Meraki config to an offline file.')
parser.add_argument('-v', help='Enable verbose mode',action='store_true')
parser.add_argument('apiKey', help='The API Key')
parser.add_argument('orgName', help='The name of a Meraki organisation')
args = parser.parse_args() # Defines arguments passed on the command line when running program

suppressprint=True
if args.v:
suppressprint=False

apikey=args.apiKey
orgid=get_org_id(apikey,args.orgName,suppressprint)
file="%s.yml"%args.orgName # set the filename from the network name
config["Organization"]["Name"]=args.orgName
config["Organization"]["ID"]=orgid
admins(apikey, orgid, suppressprint)
mx_vpn_fw_rules(apikey,orgid,suppressprint)
snmp_settings(apikey,orgid,suppressprint)
non_meraki_vpn_peers(apikey,orgid,suppressprint)
myNetworks = meraki.getnetworklist(apikey, orgid, None, suppressprint)
for row in myNetworks: # Iterate through the networks in the org
tags=row['tags']
if tags == None:
tags = ""
networkType=row['type']
if networkType == 'combined': # Combined is not valid to upload!
networkType = 'wireless switch appliance phone'
if networkType == 'systems manager': # We don't care about MDM networks
continue
print("Processing network "+row['name'])
network={"name": row["name"], "networkType": networkType, "tags": tags, "timeZone":row["timeZone"]}
mx_cellular_fw_rules(apikey,row['id'],suppressprint)
mx_l3_fw_rules(apikey,row['id'],suppressprint)
vpn_settings(apikey,row['id'],suppressprint)
static_routes(apikey,row["id"],suppressprint)
network["SSID"]=[]
ssid_settings(apikey,row['id'],suppressprint)
config["Organization"]["Network"].append(network)
with open(file, 'w') as file: # open the file we defined earlier to write to
file.write("---\n")
file.write(yaml.dump(config)) # convert the config dict to yaml and save
file.flush()
file.close()