I was experimenting on adding firewall rules using the Palo Alto REST API. Did a few tries and finally got the result.
This code is very static, the intent is to test how to organize the xml elements so that the rules can be added.
import requests, time from bs4 import BeautifulSoup as BS rule_path = "/config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/rulebase/security/rules" sample_rule = """ <entry name="API_Test_again"> <source> <member>192.168.20.125</member> </source> <destination> <member>pool.ntp.org-128.199.224.229</member> </destination> <service> <member>udp-123</member> </service> <application> <member>any</member> </application> <action>allow</action> <log-end>yes</log-end> <from> <member>any</member> </from> <to> <member>any</member> </to> </entry> """ try: response = requests.get("https://192.168.1.104/api/?type=keygen&user=admin&password=admin", verify=False, timeout=5) response.raise_for_status() except requests.exceptions.RequestException as e: print(e) except requests.exceptions.HTTPError as httperr: print(httperr) except requests.exceptions.Timeout as timeouterr: print(timeouterr) except requests.exceptions.ConnectionError as connerr: print(connerr) except requests.exceptions.ConnectTimeout as conntimeout: print(conntimeout) try: soup = BS(response.content, 'html.parser') key = soup.find('key').text except AttributeError as ae: print("Error while parsing response:",ae) try: r = requests.post("https://192.168.1.104/api/?type=config&action=set&key={}&xpath={}&element={}".format(key,rule_path,sample_rule),verify=False,timeout=5) r.raise_for_status() except requests.exceptions.RequestException as e: print(e) except requests.exceptions.HTTPError as httperr: print(httperr) except requests.exceptions.Timeout as timeouterr: print(timeouterr) except requests.exceptions.ConnectionError as connerr: print(connerr) except requests.exceptions.ConnectTimeout as conntimeout: print(conntimeout) time.sleep(3) try: commit_response = requests.post("https://192.168.1.104/api/?type=commit&key={}&cmd=<commit></commit>".format(key),verify=False,timeout=5) commit_response.raise_for_status() except requests.exceptions.RequestException as e: print(e) except requests.exceptions.HTTPError as httperr: print(httperr) except requests.exceptions.Timeout as timeouterr: print(timeouterr) except requests.exceptions.ConnectionError as connerr: print(connerr) except requests.exceptions.ConnectTimeout as conntimeout: print(conntimeout)
Result