FortiManager TCL scripts

I had a request sent to me the other day to make a script push some config with the hostname of the node included. Pretty basic thing to do. I was further constrained to use the FortiManager script runner to make this work. As usual, CLI-like scripting sucks and the magic behind the scenes made things more difficult.

FortiManager's Role

Big HA pile of shit to sync configs with templates. Also has a script runner (used by the config pushes).

The scripts are handled through a component called "deployment manager". Relevant debugs:

diagnose debug application depmanager -1 -> Not so useful for TCL, good under-the-hood look
diagnose debug dpm conf-trace enable -> Will show you SSH connection stuff. More useful IMO.

FortiManager holds SSH credentials for the device. It isn't like, even though FortiManager is trusted to play with config, FortiManager can magically login via SSH. This seems like quite a stupid design, but that is the situation we're playing with.

Note: SSH connection issues, including bad user/password require debugs to see this problem!

TCL scripting

Deployment manager will kick off the script in a sandbox. This sandbox allows the TCL script to ignore connecting to the box, the ins-and-outs of expect, etc.

The core component is the "exec" procedure. It looks like this:

exec <command> <expect token> <timeout>

This proc is basically undocumented outside of examples. It never discusses the timeout (or the importance of timeouts).

Some notes:
  • The command must have "\n" to send the command for running
  • The expect token is usually "# " (that is, hash space). This locates the prompt
  • exec returns a string with the output results.
  • If you don't set a timeout, it will gladly HANG FOREVER. Set a timeout.
  • Running a TCL script will always report SUCCESSFUL on the GUI. The logs MUST be checked (and you should add in proper error handling as FortiManager doesn't interpret the CLI output other than to find the expect token and return what it found.

Comments

Popular posts from this blog

Linux unnumbered interface source IP behavior

But Ansible does it all!!