Fortigate Config version management

In this post, I’m going to configure Google Cloud Function as an interface among Fortigate, Slack and Github. Once all deploy completed, all the configuration changes on Fortigate will be automatically notified to Slack, and it will be uploaded to Github for version control.

I re-use most of the code from my previous posts. And there are some work needs to be done on Fortigate, Slack and Github before you configure Google Cloud Function.

1. Configure Google Cloud Function

When you setup Cloud Functions with my code, you need to configure a few environment variables.

  • SLACK_CHANNEL
  • SLACK_TOKEN
  • FORTIGATE_TOKEN
  • GITHUB_TOKEN
  • REPO_NAME

Main code would be as follows:

import os
import re
import sys

import requests

import fortigate
import github_custom
import slack

SLACK_CHANNEL = os.environ["SLACK_CHANNEL"]
AUTH_KEY = "supersecretkey"
FORTIGATE_TOKEN = os.environ['FORTIGATE_TOKEN']
GITHUB_TOKEN = os.environ['GITHUB_TOKEN']
REPO_NAME = os.environ['REPO_NAME']

def main(request):

    # First, save the latest config in variable
    if not request.headers.get("Auth-key") == AUTH_KEY:
        print(f"Wrong auth_key provided from {request.headers.get('X-Forwarded-For')}")
        sys.exit(1)
    category = request.headers.get("Notif-type")
    if category == "ConfigChange":
        fg_ipaddr = request.headers.get('X-Forwarded-For')
        content = f"Config has been modified\n"
        content += f"WAN IP Address: {fg_ipaddr}\n"
        content += f"Modified by: {request.headers.get('User')} at {request.headers.get('Client')}\n"
        
        latest_config = fortigate.config_copy(fg_ipaddr, FORTIGATE_TOKEN)
        hostname = re.search(r'set hostname\s"(.*)"\n', latest_config).group(1)
        
        if github_custom.update_file(GITHUB_TOKEN, REPO_NAME, f'{hostname}.conf', latest_config):
            content += "config is updated on Github."
        else:
            content += "config update is failed."

        try:
            slack.post(content, SLACK_CHANNEL, "GCP_FortigateNotify")
            print(f"Message posted to {SLACK_CHANNEL}")
        except requests.exceptions.RequestException as e:
            print(f"Request failed: {e}")
    else:
        print(f"Not implemented - requested: {category}")

If you want to replicate the function you can git clone from repository.

Once all the setup complete, and once you make changes on Fortigate, your slack channel should receive notification, as well as the latest config should be uploaded onto the github.