My code try to resolve a client problem : he put 1000 switchs into one network but he have already one network per site with the mx. So my code :
1 - find the mx network with the site id
2 - get the list port of the switch
3 - create a network for the switch
4 - Remove the switch of the big network
5 - put in the switch network i create
6 - Bind it to the global template (Combined template, mx network already in)
7 - Combine the two networks
8 - push the port config on switch to avoid problems on site
My code is still under construction, but if you find the combine problems, it's help me a lot :
#Migration_Switchs_Meraki
import json
import sys
import requests
import csv
#Déclaration des variables pour l'ensemble des Requests
headers = {
'Content-Type' : 'application.json',
'X-Cisco-Meraki-API-Key': "*"
}
serveur = "https://api.meraki.com/api/v0/"
#Déclaration des variables globales
OrgID = "*"
switch_networkid = "N_69186549275482820"
switch_info = []
#Récupération des informations de l'inventaire
with open('inventory.csv') as csvfile:
inventory = csv.reader(csvfile, delimiter=',')
for line in inventory:
info = {
"serial" : line[1],
"name" : line[7],
}
switch_info.append(info)
csvfile.close()
del switch_info[0]
#récupération_des_premiers_caractères_du nom
#print (switch_info[0]['name'][:4])
#Récupération des networks pour recherche du network MX Magasin
api_path_mx_network = "organizations/" + OrgID + "/networks"
url_mx_network = serveur + api_path_mx_network
mx_networks = requests.request("GET", url_mx_network, headers=headers)
if mx_networks.status_code == 200:
print ("Liste des reseaux : [OK]")
else:
print ("Liste des reseaux : [NOK]")
sys.exit()
networks_data = mx_networks.json()
#Départ de déclaration des fonctions
#Fonction de recherche de l'ID Site dans les noms de Network Meraki MX
def find_mx_network(mag_id):
for n in networks_data:
if mag_id in n['name']:
mx_networkid = n['id']
templateid = n['configTemplateId']
print ("Le nom du réseau MX Magasin : " + n['name'])
break
return mx_networkid,templateid;
#Fonction de listing de configuration des ports du switch migré
def listport(switch_serial):
api_path_list_port = "devices/" + str(switch_serial) + "/switchPorts"
url_list_port = serveur + api_path_list_port
s_list_port = requests.request("GET", url_list_port, headers=headers)
if s_list_port.status_code == 200:
print ("Liste des ports switch : [OK]")
else:
sys.exit()
s_list_port_data = s_list_port.json()
return s_list_port_data;
#Fonction de création du network temporaire du switch migré
def create_network(switch_id_name):
params_create_net = {"name" : switch_id_name,
"type" : "switch",
"timeZone" : "Europe/Paris"
}
api_path_cnet = "organizations/" + OrgID + "/networks"
url_cnet = serveur + api_path_cnet
cnet = requests.request("POST", url_cnet, headers=headers, params=params_create_net)
if cnet.status_code == 201:
print ("Creation network temporaire : [OK]")
else:
print ("Creation network temporaire : [NOK]")
sys.exit()
cnet_data = cnet.json()
return cnet_data;
#Fonction de suppression du switch du network SWITCH
def remove_switch(switch_serial):
api_path_remove = "networks/" + switch_networkid + "/devices/" + switch_serial + "/remove"
url_remove = serveur + api_path_remove
r_remove_switch = requests.request("POST", url_remove, headers=headers)
print ("le switch est supprimé du network global")
print (r_remove_switch)
return;
#Fonction d'ajout dans le network temporaire
def add_switch(temp_networkid,switch_serial):
params_addswitch = {"serial" : switch_serial}
api_path_addswitch = "networks/" + temp_networkid + "/devices/claim"
url_add = serveur + api_path_addswitch
r_add_switch = requests.request("POST", url_add, headers=headers, params=params_addswitch)
print ("le switch est ajoute au network temporaire")
print (r_add_switch)
return;
#Fonction de liaison du network temporaire avec le template global
def Template_bind(templateid, networkid):
params_btemp = {"configTemplateId" : templateid,
"autoBind": "True"
}
api_path_btemp = "networks/" + networkid + "/bind"
url_btemp = serveur + api_path_btemp
btemp = requests.request("POST", url_btemp, headers=headers, params=params_btemp)
print ("le reseau temporaire est binde :")
print (btemp)
return;
#Fonction de combinaison du network temporaire avec le network MX
def combine_networks(mx_networkid,temp_networkid,dest_network_name):
params_combine = {"name" : dest_network_name,
"networkIds" : [
mx_networkid,
temp_networkid
]
}
params_combine_json = json.dumps(params_combine)
api_path_combine = "organizations/" + OrgID + "/networks/combine"
url_combine = serveur + api_path_combine
r_combine = requests.request("POST", url_combine, headers=headers, data=params_combine_json)
print(str(r_combine.status_code) + " - " + r_combine.text)
return r_combine.status_code;
#Ajout de la config initial au switch migré
def update_config(list_port,switch_serial):
for p in list_port:
api_path_update_config = "devices/" + switch_serial + "/switchPorts/" + str(p['number'])
url_update_config = serveur + api_path_update_config
params_update_config = {"name" : p['name'],
"tags" : p['tags'],
"enabled" : p['enabled'],
"type" : p['type'],
"vlan" : p['vlan'],
"voiceVlan" : p['voiceVlan'],
"allowedVlans" : p['allowedVlans'],
"poeEnabled" : p['poeEnabled'],
"isolationEnabled" : p['isolationEnabled'],
"rstpEnabled" : p['rstpEnabled'],
"stpGuard" : p['stpGuard'],
"accessPolicyNumber" : p['accessPolicyNumber'],
"linkNegotiation" : p['linkNegotiation'],
"portScheduleId" : p['portScheduleId'],
"udld" : p['udld'],
"macWhitelist" : p['macWhitelist'],
"stickyMacWhitelist" : p['stickyMacWhitelist'],
"stickyMacWhitelistLimit" : p['stickyMacWhitelistLimit']
}
r_update = requests.request("PUT", url_update_config, headers=headers, params=params_update_config)
print ("Interface " + str(p['number']) + " est mise à jour")
print (r_update)
return;
for device in switch_info:
mag_id = device['name'][:4]
dest_network_name = mag_id + "-Magasins"
#récupération de l'ID du network MX
mx_networkid, templateid = find_mx_network(mag_id)
#Stockage de la liste des ports actuelle
list_port = listport(device['serial'])
#
#Création du network temporaire
cnet_data = create_network(mag_id)
#
#Récupération de l'ID
temp_networkid = cnet_data['id']
#
#Suppression du switch d'un network
remove_switch(device['serial'])
#
#Ajout du switch au network temporaire
add_switch(temp_networkid,device['serial'])
#
#Liaison au template global
Template_bind(templateid, temp_networkid)
#
#Combinaison des réseaux
combine_networks(mx_networkid,temp_networkid,dest_network_name)
#
#Update de la config de ports
update_config(list_port,device['serial'])
Thanks,