|
@@ -7,20 +7,26 @@
|
|
|
#
|
|
|
# Firewall admin with superuser and IP address is required.
|
|
|
#
|
|
|
-# REQURED:
|
|
|
+# REQUIRED:
|
|
|
# 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
|
|
|
}
|