Error when updating L3 Firewall rules

Solved
CBurkhead
Building a reputation

Error when updating L3 Firewall rules

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?

1 Accepted Solution
CBurkhead
Building a reputation

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.

View solution in original post

9 Replies 9
CBurkhead
Building a reputation

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?

NolanHerring
Kind of a big deal

Shouldn't it be " be after the 's' in rules

"rules" where you have "rules\"

Not a python guy really, just looking at how it looks in Postman
Nolan Herring | nolanwifi.com
TwitterLinkedIn
CBurkhead
Building a reputation

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.

SoCalRacer
Kind of a big deal

The syslog parameter is only used if you actually have one configured I believe. You might try removing that.

CBurkhead
Building a reputation

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.

CBurkhead
Building a reputation

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.

NolanHerring
Kind of a big deal

No worries, glad you got it fixed
Nolan Herring | nolanwifi.com
TwitterLinkedIn
RaphaelL
Kind of a big deal
Kind of a big deal

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 

CBurkhead
Building a reputation

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

Get notified when there are additional replies to this discussion.