@ -7,20 +7,26 @@
#
# Firewall admin with superuser and IP address is required.
#
# REQURED:
# REQUI RED:
# export PANOS_HOST=""
# export PANOS_USER="" #User *MUST* have Commit and Import Permissions in XML API for Admin Role
# export PANOS_PASS=""
#
# OPTIONAL
# export PANOS_TEMPLATE="" #Template Name of panorama managed devices
# export PANOS_TEMPLATE="" # Template Name of panorama managed devices
# export PANOS_TEMPLATE_STACK="" # set a Template Stack if certificate should also be pushed automatically
# export PANOS_VSYS="Shared" # name of the vsys to import the certificate
#
# The script will automatically generate a new API key if
# no key is found, or if a saved key has expired or is invalid.
_COMMIT_WAIT_INTERVAL = 30 # query commit status every 30 seconds
_COMMIT_WAIT_ITERATIONS = 20 # query commit status 20 times (20*30 = 600 seconds = 10 minutes)
# This function is to parse the XML response from the firewall
parse_response( ) {
type = $2
_debug " API Response: $1 "
if [ " $type " = 'keygen' ] ; then
status = $( echo " $1 " | sed 's/^.*\([' \' ']\)\([a-z]*\)' \' '.*/\2/g' )
if [ " $status " = "success" ] ; then
@ -30,6 +36,13 @@ parse_response() {
message = "PAN-OS Key could not be set."
fi
else
if [ " $type " = 'commit' ] ; then
job_id = $( echo " $1 " | sed 's/^.*\(<job>\)\(.*\)<\/job>.*/\2/g' )
_commit_job_id = $job_id
elif [ " $type " = 'job_status' ] ; then
job_status = $( echo " $1 " | tr -d '\n' | sed 's/^.*<result>\([^<]*\)<\/result>.*/\1/g' )
_commit_job_status = $job_status
fi
status = $( echo " $1 " | tr -d '\n' | sed 's/^.*"\([a-z]*\)".*/\1/g' )
message = $( echo " $1 " | tr -d '\n' | sed 's/.*\(<result>\|<msg>\|<line>\)\([^<]*\).*/\2/g' )
_debug " Firewall message: $message "
@ -44,13 +57,13 @@ parse_response() {
#This function is used to deploy to the firewall
deployer( ) {
content = ""
type = $1 # Types are keytest, keygen, cert, key, commit
type = $1 # Types are keytest, keygen, cert, key, commit, job_status, push
panos_url = " https:// $_panos_host /api/ "
export _H1 = "Content-Type: application/x-www-form-urlencoded"
#Test API Key by performing a lookup
if [ " $type " = 'keytest' ] ; then
_debug "**** Testing saved API Key ****"
_H1 = "Content-Type: application/x-www-form-urlencoded"
# Get Version Info to test key
content = " type=version&key= $_panos_key "
## Exclude all scopes for the empty commit
@ -61,7 +74,6 @@ deployer() {
# Generate API Key
if [ " $type " = 'keygen' ] ; then
_debug "**** Generating new API Key ****"
_H1 = "Content-Type: application/x-www-form-urlencoded"
content = " type=keygen&user= $_panos_user &password= $_panos_pass "
# content="$content${nl}--$delim${nl}Content-Disposition: form-data; type=\"keygen\"; user=\"$_panos_user\"; password=\"$_panos_pass\"${nl}Content-Type: application/octet-stream${nl}${nl}"
fi
@ -84,6 +96,9 @@ deployer() {
if [ " $_panos_template " ] ; then
content = " $content ${ nl } -- $delim ${ nl } Content-Disposition: form-data; name=\"target-tpl\"\r\n\r\n $_panos_template "
fi
if [ " $_panos_vsys " ] ; then
content = " $content ${ nl } -- $delim ${ nl } Content-Disposition: form-data; name=\"target-tpl-vsys\"\r\n\r\n $_panos_vsys "
fi
fi
if [ " $type " = 'key' ] ; then
panos_url = " ${ panos_url } ?type=import "
@ -96,6 +111,9 @@ deployer() {
if [ " $_panos_template " ] ; then
content = " $content ${ nl } -- $delim ${ nl } Content-Disposition: form-data; name=\"target-tpl\"\r\n\r\n $_panos_template "
fi
if [ " $_panos_vsys " ] ; then
content = " $content ${ nl } -- $delim ${ nl } Content-Disposition: form-data; name=\"target-tpl-vsys\"\r\n\r\n $_panos_vsys "
fi
fi
#Close multipart
content = " $content ${ nl } -- $delim -- ${ nl } ${ nl } "
@ -106,7 +124,6 @@ deployer() {
# Commit changes
if [ " $type " = 'commit' ] ; then
_debug "**** Committing changes ****"
export _H1 = "Content-Type: application/x-www-form-urlencoded"
#Check for force commit - will commit ALL uncommited changes to the firewall. Use with caution!
if [ " $FORCE " ] ; then
_debug "Force switch detected. Committing ALL changes to the firewall."
@ -118,6 +135,20 @@ deployer() {
content = " type=commit&action=partial&key= $_panos_key &cmd= $cmd "
fi
# Query job status
if [ " $type " = 'job_status' ] ; then
echo " **** Querying job $_commit_job_id status **** "
cmd = $( printf "%s" " <show><jobs><id> $_commit_job_id </id></jobs></show> " | _url_encode)
content = " type=op&key= $_panos_key &cmd= $cmd "
fi
# Push changes
if [ " $type " = 'push' ] ; then
echo "**** Pushing changes ****"
cmd = $( printf "%s" " <commit-all><template-stack><name> $_panos_template_stack </name><admin><member> $_panos_user </member></admin></template-stack></commit-all> " | _url_encode)
content = " type=commit&action=all&key= $_panos_key &cmd= $cmd "
fi
response = $( _post " $content " " $panos_url " "" "POST" )
parse_response " $response " " $type "
# Saving response to variables
@ -126,6 +157,8 @@ deployer() {
if [ " $response_status " = "success" ] ; then
_debug " Successfully deployed $type "
return 0
elif [ " $_commit_job_status " ] ; then
_debug " Commit Job Status = $_commit_job_status "
else
_err " Deploy of type $type failed. Try deploying with --debug to troubleshoot. "
_debug " $message "
@ -191,11 +224,31 @@ panos_deploy() {
_getdeployconf PANOS_TEMPLATE
fi
# PANOS_TEMPLATE_STACK
if [ " $PANOS_TEMPLATE_STACK " ] ; then
_debug "Detected ENV variable PANOS_TEMPLATE_STACK. Saving to file."
_savedeployconf PANOS_TEMPLATE_STACK " $PANOS_TEMPLATE_STACK " 1
else
_debug "Attempting to load variable PANOS_TEMPLATE_STACK from file."
_getdeployconf PANOS_TEMPLATE_STACK
fi
# PANOS_TEMPLATE_STACK
if [ " $PANOS_VSYS " ] ; then
_debug "Detected ENV variable PANOS_VSYS. Saving to file."
_savedeployconf PANOS_VSYS " $PANOS_VSYS " 1
else
_debug "Attempting to load variable PANOS_VSYS from file."
_getdeployconf PANOS_VSYS
fi
#Store variables
_panos_host = $PANOS_HOST
_panos_user = $PANOS_USER
_panos_pass = $PANOS_PASS
_panos_template = $PANOS_TEMPLATE
_panos_template_stack = $PANOS_TEMPLATE_STACK
_panos_vsys = $PANOS_VSYS
#Test API Key if found. If the key is invalid, the variable _panos_key will be unset.
if [ " $_panos_host " ] && [ " $_panos_key " ] ; then
@ -229,6 +282,20 @@ panos_deploy() {
deployer cert
deployer key
deployer commit
if [ " $_panos_template_stack " ] ; then
# try to get job status for 20 times in 30 sec interval
i = 0
while [ " $i " -lt $_COMMIT_WAIT_ITERATIONS ] ; do
deployer job_status
if [ " $_commit_job_status " = "OK" ] ; then
echo "Commit finished!"
break
fi
sleep $_COMMIT_WAIT_INTERVAL
i = $(( i + 1 ))
done
deployer push
fi
fi
fi
}