Skip to content

Instantly share code, notes, and snippets.

@sivert-io
Last active November 23, 2023 09:46
Show Gist options
  • Select an option

  • Save sivert-io/d75a2b6450ee9ec7dbaca07adc4cd406 to your computer and use it in GitHub Desktop.

Select an option

Save sivert-io/d75a2b6450ee9ec7dbaca07adc4cd406 to your computer and use it in GitHub Desktop.
PAN-OS Upgrade firewalls
import requests
import time
import xml.etree.ElementTree as ET
# Replace these constants with your actual data
API_KEY_PAIR_1 = 'API_KEY_FOR_PAIR_1'
API_KEY_PAIR_2 = 'API_KEY_FOR_PAIR_2'
FW1_ACTIVE_IP = 'FW1_ACTIVE_IP'
FW2_PASSIVE_IP = 'FW2_PASSIVE_IP'
FW3_ACTIVE_IP = 'FW3_ACTIVE_IP'
FW4_PASSIVE_IP = 'FW4_PASSIVE_IP'
SOFTWARE_VERSION = 'NEW_SOFTWARE_VERSION_TO_INSTALL'
VERIFY_SSL = False # Set to True in production environments!
# Create a mapping of the HA pairs
FIREWALL_HA_PAIRS = [
(FW1_ACTIVE_IP, FW2_PASSIVE_IP, API_KEY_PAIR_1),
(FW3_ACTIVE_IP, FW4_PASSIVE_IP, API_KEY_PAIR_2),
]
# Function to perform an API request
def panos_api_request(url, api_key, payload):
headers = {'X-PAN-KEY': api_key}
response = requests.get(url, headers=headers, params=payload, verify=VERIFY_SSL)
response.raise_for_status()
return ET.fromstring(response.content)
# Perform the HA failover
def do_failover(active_fw_ip, api_key):
url = f"https://{active_fw_ip}/api/"
payload = {
'type': 'op',
'cmd': '<request><high-availability><control><force-failover></force-failover></control></high-availability></request>',
'key': api_key
}
panos_api_request(url, api_key, payload)
# Check the operational status of the firewall
def check_firewall_status(fw_ip, api_key):
url = f"https://{fw_ip}/api/"
payload = {
'type': 'op',
'cmd': '<show><high-availability><state></state></high-availability></show>',
'key': api_key
}
response = panos_api_request(url, api_key, payload)
# Extract the HA state from the response
return response.find('./result/HA/state').text.strip()
# Upgrade the firewall to the specified version
def upgrade_firewall(fw_ip, api_key, software_version):
# Download the software
url = f"https://{fw_ip}/api/"
payload = {
'type': 'op',
'cmd': f'<request><system><software><download><version>{software_version}</version></software></download></system></request>',
'key': api_key
}
panos_api_request(url, api_key, payload)
# Install the software
payload['cmd'] = f'<request><system><software><install><version>{software_version}</version></software></install></system></request>'
panos_api_request(url, api_key, payload)
# Reboot the firewall
def reboot_firewall(fw_ip, api_key):
url = f"https://{fw_ip}/api/"
payload = {
'type': 'op',
'cmd': '<request><restart><system></system></restart></request>',
'key': api_key
}
panos_api_request(url, api_key, payload)
# Wait for the firewall to become active after failover or reboot
def wait_for_active_status(fw_ip, api_key, timeout=600):
start_time = time.time()
while time.time() - start_time < timeout:
if check_firewall_status(fw_ip, api_key) == 'active':
return
time.sleep(10)
raise TimeoutError(f"Firewall at {fw_ip} did not become active within the timeout period.")
# The main upgrade workflow
def upgrade_ha_pair(active_fw_ip, passive_fw_ip, api_key):
print(f"Starting the upgrade process for {active_fw_ip} and {passive_fw_ip}")
do_failover(active_fw_ip, api_key)
wait_for_active_status(passive_fw_ip, api_key)
upgrade_firewall(passive_fw_ip, api_key, SOFTWARE_VERSION)
reboot_firewall(passive_fw_ip, api_key)
wait_for_active_status(passive_fw_ip, api_key)
print(f"Upgrade completed for {passive_fw_ip}")
do_failover(passive_fw_ip, api_key)
wait_for_active_status(active_fw_ip, api_key)
upgrade_firewall(active_fw_ip, api_key, SOFTWARE_VERSION)
reboot_firewall(active_fw_ip, api_key)
wait_for_active_status(active_fw_ip, api_key)
print(f"Upgrade completed for {active_fw_ip}")
if __name__ == '__main__':
for active_fw_ip, passive_fw_ip, api_key in FIREWALL_HA_PAIRS:
try:
upgrade_ha_pair(active_fw_ip, passive_fw_ip, api_key)
except Exception as e:
print(f"An error occurred during the upgrade of the HA pair: {active_fw_ip}, {passive_fw_ip}")
print(str(e))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment