By Manny Fernandez

April 28, 2025

Mass Create Objects in FortiGate with Python

Had a customer with over 200 static routes on their Cisco Nexus core switch.  We are deploying FortiGates as Internal Segmentation Firewall (ISFW).   I wanted to help them out with the creation of those static routes.  From the Nexus config file, I was able to get the static routes and massage them into a CSV file.  I created a template file with a sample FortiGate config object and then used the list csv as a source.

The Template File

 edit 0
    set dst $VAR_SUBNET
    set gateway $VAR_GATEWAY
    set device $VAR_INTERFACE
    set comment $VAR_DESC
next

The CSV Looked something like this (but over 200 lives)

"10.32.10.0/24",10.32.43.1,inside,Static_to_Corp_CallManager
"10.33.118.0/24",10.32.100.2,inside,Test_AZURE-VPN
"10.34.3.0/24",10.32.121.66,inside,CUST_MX_HQ_ServerVlan
"10.34.22.0/28",10.32.121.66,inside,CUST_MX_MediaSurD1
"10.34.23.16/28",10.32.121.66,inside,CUST_MX_MediaSurV1
"10.34.25.32/28",10.32.121.66,inside,CUST_MX_ABCD1
"10.34.27.48/28",10.32.121.66,inside,CUST_MX_ABCV1

Now for the python script that combines both pieces together.

#!/usr/bin/env python3

import os
from string import Template

IMPORT = "./source.cfg"
TEMPLATE = "./template.cfg"
OUTPUT = "./output/output.cfg"

# check for output folder
os.makedirs(os.path.dirname(OUTPUT), exist_ok=True)

# Read template content once, and then create a Template object
with open(TEMPLATE, 'r') as f:
   template_content = Template(f.read())

# Open output file for writing
with open(OUTPUT, 'w') as output_file:
    # Read each line from import file
    with open(IMPORT, 'r') as import_file:
        for line in import_file:
            line = line.strip()
             if not line:
                 continue # skip empty lines
             parts = line.split(',')
             if len(parts) < 4:
                print(f"Skipping malformed line: {line}")
                continue

             VAR_SUBNET, VAR_GATEWAY, VAR_INTERFACE, VAR_DESC = parts[:4]

             # Substitute template components
             filled_template = template_content.substitute(
                VAR_SUBNET=VAR_SUBNET,
                VAR_GATEWAY=VAR_GATEWAY,
                VAR_INTERFACE=VAR_INTERFACE,
                VAR_DESC=VAR_DESC
              )

             # Write to output file
              output_file.write(filled_template)

 

To run the script, you will need to modify the following:

IMPORT = This will contain the name and/or path of the CSV content you want to read from.

TEMPLATE = This will contain the name and/or path of the template file.  This will be part of the output but containing data from INPUT.

OUTPUT = This is the obvious output file you want to have.

Once that is complete, you can either run it with the python command and reference the .py name or you can chmod +x on the .py file and run it from the command line where you are at.

 

 

Recent posts

  • Had a customer with over 200 static routes on... Full Story

  • This is a work in progress, I will be... Full Story

  • I have been playing with the free version of... Full Story