I have a script that I have always used to copy the L3 firewall rules from one network to another. This has worked until recently, and the only change I can see is that Security & SD-WAN > Firewall had a bit of an overhaul. I am wondering if this broke the API, or if I just need to change something. I did have to refine how I get the rules a bit as the output changed from getting the rules from a source network.
This is a PowerShell script, however using the Curl template as an example I am using Invoke-RestMethod to PUT the data into Meraki.
Recently, this started throwing (403) Forbidden.
What is actually happening with the above code:
#PowerShell:
$header = @{"X-Cisco-Meraki-API-Key" = $secured_api_key
"Content-Type" = 'application/json'}
#I have also tried adding "Accept" = 'application/json' to the above $header
$body = @{ rules = $FirewallRules } | ConvertTo-Json
$uri = https://api.meraki.com/api/v1/networks/L_123456789012345678/appliance/firewall/l3FirewallRules
$request = Invoke-RestMethod -Method Put -Uri $uri -Headers $header -Body $body
return $request
#This is what is stored in the $body variable from above, with IP addresses modified for use as an example. The format still matches what is in the examples in the Developer Hub.
{
"rules": [
{
"comment": "Deny Guest to Internal VLANS",
"policy": "deny",
"protocol": "any",
"srcPort": "Any",
"srcCidr": "172.24.25.0/24",
"destPort": "Any",
"destCidr": "172.24.24.0/25,172.24.24.128/26,172.24.26.0/23,172.24.25.0/24,172.24.30.0/24,172.24.28.0/23,172.24.24.192/26",
"syslogEnabled": false
},
{
"comment": "Deny Outside to Internal VLANS except itself",
"policy": "deny",
"protocol": "any",
"srcPort": "Any",
"srcCidr": "172.24.24.192/26",
"destPort": "Any",
"destCidr": "172.24.24.0/25,172.24.24.128/26,172.24.26.0/23,172.24.25.0/24,172.24.30.0/24,172.24.28.0/23",
"syslogEnabled": false
}
]
}
The account used with the API has full access.
I am wondering if the format of $body needs to change to accommodate changes made to the dashboard, considering that Inbound and Cellular rules have been added.
I am sort of at a loss of what to do to fix this. I am sure I can switch to using CURL from within PowerShell if anyone who wants to take a stab at it has trouble with PowerShell programming and the Invoke-RestMethod way I was doing it. I got really deep in the weeds programming that way before realizing I could have used curl commands all along in PS (and at the time I was new with API programming).
Solved! Go to solution.
It's throwing an HTTP 403, which smells like it doesn't like your API key or the account associated with it. Can you post or put to any other endpoints with that key without error?
I've had some issues getting Invoke-RestMethod to consistently follow redirects through https://api.meraki.com/ ; However, usually that issue throws HTTP 308 error codes. Just for grins, it might be worth swapping in your node IE https://n263.meraki.com/ in place of that.
It's throwing an HTTP 403, which smells like it doesn't like your API key or the account associated with it. Can you post or put to any other endpoints with that key without error?
I've had some issues getting Invoke-RestMethod to consistently follow redirects through https://api.meraki.com/ ; However, usually that issue throws HTTP 308 error codes. Just for grins, it might be worth swapping in your node IE https://n263.meraki.com/ in place of that.
I tried switching to my node as you suggested, and tried a different test network as a destination. In either case, it did not work.
My API key is at least letting me read data. I'll try regenerating the key, or maybe even try a different admin account's API key to see if that makes any difference.
I do have a hunch that something has changed with the PUT as the data structure coming out of GET has changed.
It turns out that I was using a wrong API key that at least had read-only access. My script pulls the key from an encrypted file that is dependent on the currently logged on user. Somehow the secured file with the associated Windows user had the wrong API key. So, I regenerated the key and recreated the encrypted file, and magically all is well again.
I tried going the Curl route, too. But I was running from a 2012 server, and curl is an alias for Invoke-WebRequest, and not curl.exe, so the Curl example with the -L parameter could not be used in my testing. Windows 10 and later you can install WSL and have Curl.exe.