This is one of the scripts I've made that used action batches. Not that much advanced, but it worked when having to create a VLAN across multiple networks.
#! /usr/bin/env python3
from datetime import datetime
import configparser
import meraki
import os
import time
import requests
SIMULATE_API = True
#### Settings file
SETTINGSFILE = "properties.ini"
def LoadSettingsFile(p_filename: str):
returnResults = []
settings = configparser.ConfigParser()
print("## [ LoadSettings ] Reading settings from file:",p_filename)
SettingsFiles = settings.read(p_filename)
if len(SettingsFiles) > 0 and SETTINGSFILE in SettingsFiles:
print("## [ LoadSettings ] Done.")
return settings
else:
print("## [ LoadSettings ] Failed.")
raise SystemError("Settings not loaded")
def GetOrganizationId() -> str:
print("## [ GetOrganizationId ] Setting Organization Id")
p_OrganizationId = "..."
print("## [ GetOrganizationId ] Done.")
return p_OrganizationId
def GetNetworks(p_DashbordInstance: object, p_OrganizationId: str):
print("## [ GetNetworks ] Getting list of Networks")
# Get all the networks for the organizations
l_AllNetworks = p_DashbordInstance.organizations.getOrganizationNetworks(
p_OrganizationId, total_pages='all'
)
print("## [ GetNetworks ] Done.")
return l_AllNetworks
def FilterNetworks(p_AllNetworks,p_TargetTags: list[str], p_IgnoredNetworks: list[str], p_Settings):
# Initialse the list of networks
l_NetworkIds = []
l_NetworkNames = []
# Run though all the networks and test if its name is contained within a list of Ignored networks
print("## [ Checking Names and Tags ] Filtering out networks that are to be ignored")
for network in p_AllNetworks:
# Test if the name is in the list of ignored networks
if network['name'] in p_IgnoredNetworks:
print("## [ Checking Names and Tags ] Name in ignorelist, skipped;",network['name'])
elif not any([x in p_TargetTags for x in network['tags']]):
print("## [ Checking Names and Tags ] Doesn't match any tags, skipped;",network['name'])
else:
# If name is not in the list, the network ID is appended to networks of interest
print("## [ Checking Names and Tags ] Network not filtered, adding to list:",network['name'])
l_NetworkIds.append(network['id'])
l_NetworkNames.append(network['name'])
print("## [ Checking Names and Tags ] Done.")
return l_NetworkIds
def CheckIfNetworkUsesVlans(p_Dashboard,p_NetworkIds):
l_NetworkIds = []
for network_id in p_NetworkIds:
print("## [ Checking Vlans Enabled ] checking network",network_id,"...")
response = p_Dashboard.appliance.getNetworkApplianceVlansSettings(
network_id
)
if response['vlansEnabled'] == True:
print("## [ Checking Vlans Enabled ] Vlans enabled for network",network_id)
l_NetworkIds.append(network_id)
return l_NetworkIds
def main():
dashboard = meraki.DashboardAPI(
simulate=SIMULATE_API,
suppress_logging=True,
)
Settings = LoadSettingsFile(SETTINGSFILE)
#Settings = Settings['MX Settings']
org_id = GetOrganizationId()
IgnoredNetworks = []
TargetTags = ['VLAN']
AllNetworks = GetNetworks(dashboard,org_id)
FilteredNetworks = FilterNetworks(AllNetworks,TargetTags,IgnoredNetworks,Settings)
VlanEnabledNetworks = CheckIfNetworkUsesVlans(dashboard,FilteredNetworks)
##### Check if filtered networks already contain the VLAN to be used. If so, those networks are passed.
NetworksWithVLanInUse = []
TargetNetworks = []
print("## [ xxx1 ] Checking if networks already use Vlan ID",Settings['appliance']['vlanid'])
for network_id in VlanEnabledNetworks:
print("## [ xxx1 ] Getting vlans from network:", network_id)
vlans = dashboard.appliance.getNetworkApplianceVlans(
network_id
)
if any([str(vlans[x]['id']) == Settings['appliance']['vlanid'] for x in range(len(vlans))]):
print("## [ xxx1 ] Vlan already in use, skipping!")
NetworksWithVLanInUse.append(network_id)
else:
print("## [ xxx1 ] Vlan not found, setting vlan details for network and marking as target",network_id)
applianceIp = "10."+vlans[0]['applianceIp'].split('.')[1]+".255.1"
subnet = "10."+vlans[0]['applianceIp'].split('.')[1]+".255.0/24"
TargetNetworks.append({
"network_id": network_id,
"applianceIp":applianceIp,
"subnet":subnet,
# "applianceIp":vlans[0]['applianceIp'],
# "subnet":vlans[0]['subnet'],
})
print("## [ xxx1 ] Done.")
##### List VPN enabled subnets
TempData = []
for network in TargetNetworks:
print("## [ xxx2 ] Getting list of VPN enabled subnets for network", network['network_id'])
SiteToSiteVpn = dashboard.appliance.getNetworkApplianceVpnSiteToSiteVpn(
network['network_id']
)
if SiteToSiteVpn['mode'] == 'none':
print("## [ xxx2 ] Network not in AutoVPN; skipping..")
continue
if Settings["appliance"]['invpn'] == "True":
print("## [ xxx2 ] Adding new subnet to list of VPN enabled subnets.")
SiteToSiteVpn['subnets'].append({
'localSubnet': network['subnet'],
'useVpn': True
})
network.update(SiteToSiteVpn)
TempData.append(network)
print("## [ xxx2 ] Done.")
TargetNetworks = TempData
##### Build actions list of actions for each network
actions = []
for network in TargetNetworks:
action = {
"resource": f"/networks/{network['network_id']}/appliance/vlans",
"operation": "create",
"body": {
"id": Settings['appliance']['vlanid'],
"name": Settings['appliance']['vlanname'],
"applianceIp": network['applianceIp'],
"subnet": network['subnet'],
"groupPolicyId": ""
}
}
actions.append(action)
action = {
"resource": f"/networks/{network['network_id']}/appliance/vpn/siteToSiteVpn",
"operation": "update",
"body": {
"mode": network['mode'],
"hubs": network['hubs'],
"subnets": network['subnets']
},
}
# if network['mode'] == "hub":
# print("hold")
actions.append(action)
##### ACTION BATCHES
next = False
chunk_size = 2
actions_chunks = [actions[n:n+chunk_size] for n in range(0,len(actions),chunk_size)]
url = f"https://api.meraki.com/api/v1/organizations/{org_id}/actionBatches"
headers = {
"Authorization": f"Bearer {os.environ['MERAKI_DASHBOARD_API_KEY']}",
"Content-Type": "application/json",
}
for chunk in actions_chunks:
payload = {
"confirmed": True,
"synchronous": True,
"actions": chunk
}
#print(payload)
response = requests.post(url, json=payload, headers=headers)
print(response.text)
print("#####")
print("#####")
time.sleep(2)
if __name__ == "__main__":
StartTime = datetime.now()
main()
print("\nTime to execute:",datetime.now()-StartTime)
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.