I wrote a Python script a number of months ago that allowed you to copy layer 3 firewall rules from one network to another. It worked just fine. I ran it today and I am getting an error 400 with a message that the "rules" parameter is required. Below is the data that I am submitting to the PUT. The API endpoint is PUT /networks/[networkId]/l3FirewallRules
"{\"rules\":[{'comment': 'Crypto', 'policy': 'deny', 'protocol': 'any', 'srcPort': 'Any', 'srcCidr': 'Any', 'destPort': 'Any', 'destCidr': '93.174.89.116/32', 'syslogEnabled': False}, {'comment': 'Back Orifice', 'policy': 'deny', 'protocol': 'any', 'srcPort': 'Any', 'srcCidr': 'Any', 'destPort': 'Any', 'destCidr': '63.241.38.212/32', 'syslogEnabled': False}]}"
The "rules" parameter seems to be there from what I can tell. The sample code on documenter.getpostman.com does not shed any light on this, either. Has anyone use this endpoint recently with success? Does anyone see anything that looks wrong in the data I am trying to submit?
Solved! Go to solution.
OK, I have found the problem. It was my own fault. Somewhere along the line, I made a change so that I was building a string for the data that would be used in the PUT, instead of a dictionary, and then running it through json.dumps() to convert it to a JSON compatible string. This conversion made data that is not JSON compatible, and thus is errored out.
That being said, the error message from the endpoint was not at all helpful in figuring out what the actual problem was.
Thanks for the suggestions and I'm sorry I took up your time with something that I should have found on my own, relating to a change I never should have made.
As an addendum, I tried passing the following data and still received the message, "Missing parameter - the "rules" parameter is required".
"{\"rules\":[]}"
From what I can see, the endpoint seems to be broken. Meraki, any thoughts?
The \" is telling Python that I want the " character, since " can be used to indicate the beginning or ending of a string in Python. If I use the other string character (') to start and end the string and just use the " around the rules tag:
'{"rules":[]}'
I get the same message.
The syslog parameter is only used if you actually have one configured I believe. You might try removing that.
I did not need to remove it previously, but I gave that a try. It did not make a difference. It still tells me that I am missing the rules parameter.
OK, I have found the problem. It was my own fault. Somewhere along the line, I made a change so that I was building a string for the data that would be used in the PUT, instead of a dictionary, and then running it through json.dumps() to convert it to a JSON compatible string. This conversion made data that is not JSON compatible, and thus is errored out.
That being said, the error message from the endpoint was not at all helpful in figuring out what the actual problem was.
Thanks for the suggestions and I'm sorry I took up your time with something that I should have found on my own, relating to a change I never should have made.
Do you mind sharing your source code or a part of it.
I'm having the same exact issue as you and it was working in the past. I was so close to open a ticket / post here about this issue , but I figured out that my code might be in cause , although it was working in the past...
Thanks
I can easily share the function that is taking the data and then making the API call. The whole program is pretty large. This where my coding problem was. You will be able to see where I am building the dictionary with the "rules" tag in the dictionary and then the conversion to a JSON string and the API call. If you have any question about this, let me know.
def SetL3Rules(Id,ruleslist):
# Copy the global header and add the content information.
header = g_header
header.update({'Content-Type':'application/json'})
url = g_baseURL+'networks/'+Id+'/l3FirewallRules'
# Add the "rules" key to make a dictionary with the L3 rules as the data.
L3rules = {'rules':ruleslist}
# Convert the dictionary to JSON. This will replace False with false, True with true, and the ' with ".
payload = json.dumps(L3rules)
try:
ret = requests.request("PUT", url, data=payload, headers=header)
except requests.exceptions.ConnectionError:
print('A connection error has occurred while writing the layer 3 information.')
print('The layer 3 rules were NOT updated.\n')
return None
rules = ErrorCheck(ret)
return rules