I have written a slightly updated version of this post: http://ciscotom.com/cisco-firepower-api-creating-multiple-network-objects-using-python-csv-updated/

I decided to utilise the script provided by the API explorer and develop it further. I amended it to read data from a CSV file and simulate a bulk creation of network objects and hosts using the API.

The script loops through each object in the CSV file and creates it on the FMC, this script does not update or delete objects.

The CSV file should only contain new objects, as this is a POST (create) and not a PUT (update) call. You will get a status code of 400 if the object already exists, my script hung if I received 10 of these error codes (your experience may differ). You may also receive an error code 400 for invalid query parameters, including unrecognized parameters, missing parameters, or invalid values.

At the end of the script, a log file will be created with JSON dumps inside

Here’s a simple CSV file containing 4 objects and their values

name,value,type,description
zTest1,1.255.255.1,host,test host
zTest2,1.255.255.0/30,network,test network
zTest3,2.255.255.1,host,test host
zTest4,2.255.255.0/30,network,test network

And here is the script used in this demo. You will need to update the FMC server address, username and password and the domain ID in the API_Path to match your environment. (You’re best of viewing the code in a separate window),

import csv
import json
import sys
import requests
import os

server = "https://192.168.99.5"

username = "username"
if len(sys.argv) > 1:
    username = sys.argv[1]
password = "password"
if len(sys.argv) > 2:
    password = sys.argv[2]

r = None
headers = {'Content-Type': 'application/json'}
api_auth_path = "/api/fmc_platform/v1/auth/generatetoken"
auth_url = server + api_auth_path

print('\nAttempting connection to FMC...')
try:
    requests.packages.urllib3.disable_warnings()
    r = requests.post(auth_url, headers=headers, 
    auth=requests.auth.HTTPBasicAuth(username,password), verify=False)
    auth_headers = r.headers
    auth_token = auth_headers.get('X-auth-access-token', default=None)
    if auth_token == None:
        print("auth_token not found. Exiting...")
        sys.exit()
except Exception as err:
    print ("Error in generating auth token --> "+str(err))
    sys.exit()

headers['X-auth-access-token'] = auth_token

print('...Connected! Auth token collected successfully (' + auth_token + (')\n'))
api_path = "/api/fmc_config/v1/domain/e276abec-e0f2-11e3-8169-6d9ed49b625f/object/networks"

url = server + api_path
if (url[-1] == '/'):
    url = url[:-1]

f = open("objects.csv")
objectsfile = csv.DictReader(f)

for object in objectsfile:
    post_data = {
        "name": object["name"],
        "type": object["type"],
        "value": object["value"],
        "description": object["description"],
    }
    print('Creating object ' + object["name"])
    try:
        r = requests.post(url, data=json.dumps(post_data), headers=headers, verify=False)
        status_code = r.status_code
        resp = r.text
        log = open('POST_Create-FMC-Objects.log', 'a')   
        print("Status code: "+str(status_code))
        json_resp = json.loads(resp)
        log.write('\n---------------------------------------------------------------------\n')
        log.write(json.dumps(json_resp,sort_keys=True,indent=4, separators=(',', ': ')))  
        
        if status_code == 201 or status_code == 202:
            print (object["name"] + " was successfully created\n")
        elif status_code == 400:
            print (object["name"] + " already exists!\n")
        else:
            r.raise_for_status()
            print (object["name"] + " encountered an error during POST --> "+ resp +'\n')
            
    except requests.exceptions.HTTPError as err:
        print ("Error in connection --> "+str(err))
    finally:
        if r: r.close()

print('Log file "POST_Create-FMC-Objects.log" updated\n')
os.system('pause')

Here is the script running in Windows,

Whilst the script is running, a log file will be created and updated for every object being created. Here is a snippet from the logs showing data for the ‘zTest1’ object,

{
    "description": "test network",
    "id": "780CF067-5D5C-0ed3-0000-051539661120",
    "links": {
        "parent": "https://192.168.99.5/api/fmc_config/v1/domain/e276abec-e0f2-11e3-8169-6d9ed49b625f/object/networkaddresses",
        "self": "https://192.168.99.5/api/fmc_config/v1/domain/e276abec-e0f2-11e3-8169-6d9ed49b625f/object/networks/780CF067-5D5C-0ed3-0000-051539661120"
    },
    "metadata": {
        "domain": {
            "id": "e276abec-e0f2-11e3-8169-6d9ed49b625f",
            "name": "Global"
        },
        "ipType": "V_4",
        "lastUser": {
            "name": "api"
        },
        "parentType": "NetworkAddress",
        "timestamp": 0
    },
    "name": "zTest1",
    "overridable": false,
    "type": "Host",
    "value": "1.255.255.1"
}

Checking the Objects in the FMC you can see they have been created successfully,

The Firepower REST API implements rate limiting to reduce network load. It’s important not to exceed more than 120 requests (objects being created) per minute otherwise you will receive a 429 status code (too many requests). It will only allow 10 simultaneous connections per IP address. These are not configurable parameters.


15 Comments

nf · May 10, 2019 at 1:01 pm

Can you please indicate which version of python you’re using ?

    tom · May 10, 2019 at 1:13 pm

    Hey there – I believe this was written and tested with Python 3.7 – Although I’m sure it could be adapted to run on Python 2.7.

    Are you having a particular issue with this?

Nirmal · June 21, 2019 at 4:48 am

I tried using this script, but it’s keep on saying that object already exists with error 400, even though it doesn’t exist. Can you help?

    Tom · June 24, 2019 at 5:14 pm

    Hey there,

    The official documentation for error 400 is:

    400 Bad Request
    – Invalid query parameters, including unrecognized parameters, missing parameters, or invalid values.
    This can indicate that the object was edited or deleted via REST API such that the corresponding policy is invalidated.

    Are you using my example ‘as-is’ or have you made any amendments to anything? My guess is you’re receiving that error due to missing data in the CSV or use of special/invalid characters.

    Also take a look at the generated log file, it may include more details of why it failed.

    Engi · October 22, 2019 at 1:49 pm

    I’ve got the same issue. Turnend out the script was able to create networks but not hosts. I think something is wrong on line 38 of the script. I changed the end of that url from networks to hosts. I was then able to create host objects (but not network object). If you change it to networks again you will be able to create networks again.

      Tom · October 22, 2019 at 1:58 pm

      Hey there, yes please check out the updated version of this post, where I mention this exact problem. I believe this is due to the version of the Fmc, the script in this post used to work just fine in v6.1 but doesn’t in v6.3

Harish Solanki · August 5, 2019 at 9:54 pm

I am getting this error while creating host objects.
{
“error”: {
“category”: “FRAMEWORK”,
“messages”: [
{
“description”: “The request payload contains incorrect value for this resource”
}
],
“severity”: “ERROR”
}
}

    Harish Solanki · August 5, 2019 at 10:50 pm

    fixed it…

      Tom · August 6, 2019 at 11:31 am

      Hey, glad you managed to fix your problem, out of interest what did you do to resolve this?

Patrick Warren · April 29, 2020 at 5:08 pm

Worked great. Thanks

    Tom · July 2, 2020 at 9:05 pm

    Great stuff glad I was able to help you out.

Danish · August 4, 2020 at 6:35 am

Hello Tom,

Really great work! I was looking for the videos if you have any YouTube channel setup for this? As I am stuck on “the domain ID in the API_Path to match your environment”.

    Tom · September 24, 2020 at 10:12 am

    Hello Danish,

    Apologies for the delayed response. Unfortunately I do not have a YouTube channel or any videos to share. The Domain ID can be found in your API Explorer and you need to insert this Domain ID into the variable as below:

    api_path = “/api/fmc_config/v1/domain/INSERT-DOMAIN-ID-HERE/object/networks”

    Hope this helps!

Cisco Firepower API | Creating Multiple Port Objects using Python & CSV – CiscoTom · August 6, 2019 at 12:28 pm

[…] is very similar to my previous post for creating network objects (found here) but in this instance we are going to create some new port objects on the FMC using a Python script […]

Cisco Firepower API | Creating Multiple Network Objects using Python & CSV [UPDATED] – CiscoTom.com · October 4, 2019 at 3:22 pm

[…] This is an updated version of This Post. […]

Leave a Reply

Your email address will not be published. Required fields are marked *