Python script to update lockdown rules fails with '99998: unknown error'

Hi all,

I’ve tried to create a python script that would update my lockdown rules. I want to add new IPs to a rule automatically, not by hand via the web interface.

However, I keep getting 99998 zonelockdown.api.unknown_error messages. #sob

I’ve tried to add the new IP to the existing lockdown object and put that through in json form, but that fails. Copying the data into a new object and sending that also fails.

Does anyone have an idea?

Thanks for helping out an annoyed devops-dude!

Cheers,
Eelko

Here’s my script:

#!/usr/bin/python3                                                                                                                                                                                                                                                       

import CloudFlare
import json

def main():
    cf = CloudFlare.CloudFlare(profile='my_profile', debug=True)
    my_zone = 'some_zone'
    my_lockdown_desc = 'my lockdown rule'
    my_ip = '1.1.1.1'

    try:
        zones = cf.zones.get(params = {'name': my_zone})
    except CloudFlare.exceptions.CloudFlareAPIError as e:
        exit('Zone %s not found' % my_zone)

    zone=zones[0]
    zone_id = zone['id']
    zone_name = zone['name']
    if ( zone_name == my_zone):
        print ("ZONE: ")
        print (zone_id, zone_name)
        for lockdown in cf.zones.firewall.lockdowns.get(zone_id):
            if (lockdown['description'] == my_lockdown_desc ):
                # Add the IP to the configurations                                                                                                                                                                                                                       
                lockdown['configurations'].append({'target': 'ip', 'value': my_ip})

                newlockdown = {
                    'paused': 'false',
                    'description': lockdown['description'],
                    'urls': lockdown['urls'],
                    'configurations': lockdown['configurations']
                }

                lockdown_str = json.dumps(newlockdown)
                print ('The updated lockdown rule is: %s' % newlockdown)

                try:
                    cf.zones.firewall.lockdowns.put(zone_id, lockdown['id'], data=lockdown_str)

                except CloudFlare.exceptions.CloudFlareAPIError as e:
                    if len(e) > 0:
                        sys.stderr.write('api error - more than one error value returned!\n')
                    for x in e:
                        sys.stderr.write('api error: %d %s\n' % (x, x))
                        exit('api error: %d %s' % (e, e))
                    exit('/zones.firewall.lockdowns.put fails with error: %d %s' % (e, e))

if __name__ == '__main__':
    main()

Update!

I’ve found that the python cloudflare call uses content-type ‘application/javascript’ while it should be ‘application/json’. When I look at the debug info, retrieve this curl call and change it manually to application/json, it works.

I’ll see if I can fix it in the CloudFlare python module and share it with you and the developers.

Cheers,
Eelko

1 Like

Well, since you read this issue up to here I imagine you’re also interested in the solution I found?

The CloudFlare python module set the content-type to application/javascript when it detects a data parameter of type string. No matter what’s in there, it sets the content-type to javascript. Even if it’s json data.

I’ve put this to the creators of python’s CloudFlare module.
See https://github.com/cloudflare/python-cloudflare/issues/105

Cheers,
Eelko

1 Like

That was so helpful, Eelko! Thanks! :wink:

Thanks for letting us know about the details @edv2 :smile:

1 Like