From dd5ee0a7b2c4f11fd0bb73c27a1f9663403b8af7 Mon Sep 17 00:00:00 2001 From: alexortize Date: Thu, 27 Jan 2022 16:55:50 -0700 Subject: [PATCH 01/14] Squashed commit of the following: commit 6adf81665145df4139308aea6805b8ebf637949c Merge: 2925d20 a290b31 Author: alexortize Date: Thu Jan 27 14:09:25 2022 -0700 Merge branch 'develop' into origin/fix commit 2925d2071f652f7f8a79b72a09a9ecaee04ce7aa Merge: e97033a 07acc06 Author: alexortize Date: Thu Jan 27 13:30:00 2022 -0700 Merge branch 'bugfix' of https://github.com/alexortize/pan-os-python into origin/fix commit e97033afff2aec29a7399f75e682c0c7ed3b4d28 Author: alexortize Date: Thu Jan 27 13:21:44 2022 -0700 Update policies.py file to use Unix style EOL. commit 07acc0618131445a3406e9749e2766d6a3684314 Author: alexortize Date: Thu Jan 27 13:21:44 2022 -0700 Update policies.py commit 889020a58c5dce5b0e6568f13c1715f542227de4 Author: alexortize Date: Thu Jan 27 12:52:13 2022 -0700 clean up done moved some things around and removed whitespace causing test to fail. commit f2ca3efd7380156dcefc654cc6749d56461f701e Author: alexortize Date: Wed Jan 26 15:34:33 2022 -0700 feat: Added negate and negate_target to DecryptionRule feat: Added negate and negate_target to DecryptionRule commit d0964a981876f587beb6dcc242b05ae2b4787d87 Author: alexortize Date: Wed Jan 26 13:46:41 2022 -0700 bug: DecryptionRule wrong xpath. DecryptionRule _setup method was referencing wrong xpath for decryption rules. --- panos/policies.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/panos/policies.py b/panos/policies.py index 751f43e2..b2b1be62 100644 --- a/panos/policies.py +++ b/panos/policies.py @@ -834,6 +834,10 @@ class DecryptionRule(VersionedPanObject): handshakes. log_failed_tls_handshakes (bool): (PAN-OS 10.0+) Log failed TLS handshakes. log_setting (str): (PAN-OS 10.0+) Log setting. + negate_target (bool): Target all but the listed target firewalls + (applies to panorama/device groups only) + target (list): Apply this policy to the listed firewalls only + (applies to panorama/device groups only) """ @@ -843,7 +847,7 @@ class DecryptionRule(VersionedPanObject): def _setup(self): # xpaths - self._xpaths.add_profile(value="/pbf/rules") + self._xpaths.add_profile(value="/decryption/rules") # params params = [] @@ -940,6 +944,12 @@ def _setup(self): params[-1].add_profile( "10.0.0", path="log-setting", ) + params.append( + VersionedParamPath("negate_target", path="target/negate", vartype="yesno") + ) + params.append( + VersionedParamPath("target", path="target/devices", vartype="entry") + ) self._params = tuple(params) From 0c344756a891a07f238230d7d9ac06fd8382122e Mon Sep 17 00:00:00 2001 From: alexortize Date: Thu, 27 Jan 2022 16:56:29 -0700 Subject: [PATCH 02/14] Squashed commit of the following: commit a0ce81f861d0a1ad196563f8038bf5ff72ca9104 Author: alexortize Date: Thu Jan 27 16:07:51 2022 -0700 fixed parameters fixed parameters so it matched order during testing commit ce71ffafa95c2f859b2951e6d352bce705e09d51 Merge: df2cb56 a290b31 Author: alexortize Date: Thu Jan 27 14:10:07 2022 -0700 Merge branch 'develop' into origin/feat commit df2cb56a67f0b422fd71d3763754efffdef65229 Author: alexortize Date: Thu Jan 27 13:14:00 2022 -0700 removed extra whitespace removed extra whitespace commit e07328438b3eecc1c770f6c74f9337565e3f4304 Author: alexortize Date: Wed Jan 26 14:36:05 2022 -0700 Updated comment commit 05f4aa435d26bf7399290de22569023e5c9ce1f1 Author: alexortize Date: Wed Jan 26 14:32:57 2022 -0700 feat: Added ApplicationOverride object Added ApplicationOverride object. --- panos/policies.py | 79 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/panos/policies.py b/panos/policies.py index b2b1be62..314e4331 100644 --- a/panos/policies.py +++ b/panos/policies.py @@ -44,6 +44,7 @@ class Rulebase(VersionedPanObject): "policies.PolicyBasedForwarding", "policies.SecurityRule", "policies.DecryptionRule", + "policies.ApplicationOverride", ) def _setup(self): @@ -607,6 +608,84 @@ def _setup_opstate(self): self.opstate = RuleOpState(self) +class ApplicationOverride(VersionedPanObject): + """ApplicationOverride + + Args: + name (str): Name of the rule + fromzone (list): From zones + tozone (list): To zones + source (list): Source addresses + destination (list): Destination addresses + application (str): Applications + description (str): Description of this rule + tag (list): Administrative tags + negate_source (bool): Match on the reverse of the 'source' attribute + negate_destination (bool): Match on the reverse of the 'destination' + attribute + disabled (bool): Disable this rule + negate_target (bool): Target all but the listed target firewalls + (applies to panorama/device groups only) + target (list): Apply this policy to the listed firewalls only + (applies to panorama/device groups only) + port (str): Destination port + protocol (str): Protocol used + group_tag (str): (PAN-OS 9.0+) The group tag. + + """ + + SUFFIX = ENTRY + ROOT = Root.VSYS + HIT_COUNT_STYLE = "application-override" + + def _setup(self): + # xpaths + self._xpaths.add_profile(value="/application-override/rules") + + # params + params = [] + + any_defaults = ( + ("fromzone", "from"), + ("tozone", "to"), + ("source", "source"), + ("destination", "destination"), + ) + for var_name, path in any_defaults: + params.append( + VersionedParamPath( + var_name, default=["any",], vartype="member", path=path + ) + ) + params.append(VersionedParamPath("application", path="application")) + params.append(VersionedParamPath("description", path="description")) + params.append(VersionedParamPath("tag", path="tag", vartype="member")) + params.append( + VersionedParamPath("negate_source", path="negate-source", vartype="yesno") + ) + params.append( + VersionedParamPath( + "negate_destination", path="negate-destination", vartype="yesno" + ) + ) + params.append(VersionedParamPath("disabled", path="disabled", vartype="yesno")) + params.append( + VersionedParamPath("negate_target", path="target/negate", vartype="yesno") + ) + params.append( + VersionedParamPath("target", path="target/devices", vartype="entry") + ) + params.append(VersionedParamPath("port", path="port")) + params.append(VersionedParamPath("protocol", path="protocol")) + params.append(VersionedParamPath("group_tag", exclude=True)) + params[-1].add_profile("9.0.0", path="group-tag") + + self._params = tuple(params) + + def _setup_opstate(self): + self.opstate = RuleOpState(self) + + class PolicyBasedForwarding(VersionedPanObject): """PBF rule. From 894b7616e6a11c8afb99497244609bbf2dc9b5d1 Mon Sep 17 00:00:00 2001 From: alexortize Date: Tue, 15 Mar 2022 16:36:31 -0700 Subject: [PATCH 03/14] modified show_highavailability state method --- panos/base.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/panos/base.py b/panos/base.py index 6a9bcf76..c04f3ccb 100644 --- a/panos/base.py +++ b/panos/base.py @@ -4584,12 +4584,20 @@ def map_ha(self, method_name, *args, **kwargs): return result1, result2 def show_highavailability_state(self): - ha_state = self.op("show high-availability state") + from panos.firewall import Firewall + from panos.panorama import Panorama + + ha_state = self.op("show high-availability state" enabled = ha_state.findtext("result/enabled") + p = self if enabled is None or enabled == "no": return "disabled", None else: - return ha_state.findtext("result/group/local-info/state"), ha_state + if isinstance(p, Panorama): + xpath = "result/local-info/state" + else: + xpath = "result/group/local-info/state" + return ha_state.findtext(xpath), ha_state def refresh_ha_active(self): """Refresh which device is active using the live device From b6eb3128cf7a47c17ee47571206e099b20540f09 Mon Sep 17 00:00:00 2001 From: alexortize Date: Tue, 15 Mar 2022 16:50:59 -0700 Subject: [PATCH 04/14] modified show_highavailability_state method --- panos/base.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/panos/base.py b/panos/base.py index 6a9bcf76..4aeb16fc 100644 --- a/panos/base.py +++ b/panos/base.py @@ -4584,12 +4584,19 @@ def map_ha(self, method_name, *args, **kwargs): return result1, result2 def show_highavailability_state(self): + from panos.panorama import Panorama + ha_state = self.op("show high-availability state") enabled = ha_state.findtext("result/enabled") + p = self if enabled is None or enabled == "no": return "disabled", None else: - return ha_state.findtext("result/group/local-info/state"), ha_state + if isinstance(p, Panorama): + xpath = "result/local-info/state" + else: + xpath = "result/group/local-info/state" + return ha_state.findtext(xpath), ha_state def refresh_ha_active(self): """Refresh which device is active using the live device From e1019abc70e7acd10d78df93ad5f0d4abf393db7 Mon Sep 17 00:00:00 2001 From: alexortize Date: Tue, 15 Mar 2022 17:22:43 -0700 Subject: [PATCH 05/14] Update base.py Removed some automatic changes generated by VS Code. --- panos/base.py | 74 +++++++++++++-------------------------------------- 1 file changed, 18 insertions(+), 56 deletions(-) diff --git a/panos/base.py b/panos/base.py index c356c14c..4aeb16fc 100644 --- a/panos/base.py +++ b/panos/base.py @@ -1631,13 +1631,7 @@ def _set_reference( if var_type == "list": if var is None: update_needed = True - setattr( - obj, - reference_var, - [ - self, - ], - ) + setattr(obj, reference_var, [self,]) if update: obj.update(reference_var) elif not isinstance(var, list): @@ -2099,13 +2093,14 @@ def hierarchy_info(self): dict: Hierarchy information about this object. """ from panos.firewall import Firewall - from panos.panorama import DeviceGroup, Panorama, Template, TemplateStack + from panos.panorama import DeviceGroup + from panos.panorama import Panorama + from panos.panorama import Template + from panos.panorama import TemplateStack classes = panos.object_classes() configs = [ - [ - self.__class__, - ], + [self.__class__,], ] updated_configs = [] @@ -2117,10 +2112,7 @@ def hierarchy_info(self): configs.pop(num) for p in parents: configs.append( - chain - + [ - p, - ] + chain + [p,] ) break else: @@ -2772,8 +2764,7 @@ def __getattr__(self, name): raise AttributeError( "'{0}' object has no attribute '{1}'".format( - self.__class__.__name__, - str(name), + self.__class__.__name__, str(name), ) ) @@ -2858,7 +2849,9 @@ def __repr__(self): class ValueEntry(VersionedPanObject): - """Base class for objects that only have a value element.""" + """Base class for objects that only have a value element. + + """ ROOT = Root.VSYS SUFFIX = ENTRY @@ -3692,12 +3685,7 @@ def get_device_version(self): @classmethod def create_from_device( - cls, - hostname, - api_username=None, - api_password=None, - api_key=None, - port=443, + cls, hostname, api_username=None, api_password=None, api_key=None, port=443, ): """Factory method to create a :class:`panos.firewall.Firewall` or :class:`panos.panorama.Panorama` object from a live device @@ -3719,33 +3707,18 @@ def create_from_device( # Create generic PanDevice to connect and get information from panos import firewall, panorama - device = PanDevice( - hostname, - api_username, - api_password, - api_key, - port, - ) + device = PanDevice(hostname, api_username, api_password, api_key, port,) system_info = device.refresh_system_info() version = system_info[0] model = system_info[1] if model == "Panorama" or model.startswith("M-"): instance = panorama.Panorama( - hostname, - api_username, - api_password, - device.api_key, - port, + hostname, api_username, api_password, device.api_key, port, ) else: serial = system_info[2] instance = firewall.Firewall( - hostname, - api_username, - api_password, - device.api_key, - serial, - port, + hostname, api_username, api_password, device.api_key, serial, port, ) instance._set_version_and_version_info(version) return instance @@ -3893,16 +3866,10 @@ def method(self, *args, **kwargs): def classify_exception(self, e): if str(e) == "Invalid credentials.": - return err.PanInvalidCredentials( - str(e), - pan_device=self.pan_device, - ) + return err.PanInvalidCredentials(str(e), pan_device=self.pan_device,) elif str(e).startswith("URLError:"): if str(e).endswith("timed out"): - return err.PanConnectionTimeout( - str(e), - pan_device=self.pan_device, - ) + return err.PanConnectionTimeout(str(e), pan_device=self.pan_device,) else: # This could be that we have an old version of OpenSSL # that doesn't support TLSv1.1, so check for that and give @@ -4828,12 +4795,7 @@ def _commit( logger.debug( self.id + ": commit requested: commit_all:%s sync:%s sync_all:%s cmd:%s" - % ( - str(commit_all), - str(sync), - str(sync_all), - cmd, - ) + % (str(commit_all), str(sync), str(sync_all), cmd,) ) if commit_all: action = "all" From 7b4086945b104f0013a4c9ee88d08ae92ac36c1a Mon Sep 17 00:00:00 2001 From: Brian Torres-Gil Date: Mon, 14 Feb 2022 20:29:15 -0800 Subject: [PATCH 06/14] feat: ApplicationTag - tag predefined applications (#414) modified show_highavailability_state method --- panos/base.py | 9 ++++++++- panos/device.py | 1 + panos/firewall.py | 1 + panos/objects.py | 26 ++++++++++++++++++++++++++ panos/panorama.py | 2 ++ 5 files changed, 38 insertions(+), 1 deletion(-) diff --git a/panos/base.py b/panos/base.py index 6a9bcf76..4aeb16fc 100644 --- a/panos/base.py +++ b/panos/base.py @@ -4584,12 +4584,19 @@ def map_ha(self, method_name, *args, **kwargs): return result1, result2 def show_highavailability_state(self): + from panos.panorama import Panorama + ha_state = self.op("show high-availability state") enabled = ha_state.findtext("result/enabled") + p = self if enabled is None or enabled == "no": return "disabled", None else: - return ha_state.findtext("result/group/local-info/state"), ha_state + if isinstance(p, Panorama): + xpath = "result/local-info/state" + else: + xpath = "result/group/local-info/state" + return ha_state.findtext(xpath), ha_state def refresh_ha_active(self): """Refresh which device is active using the live device diff --git a/panos/device.py b/panos/device.py index 9302ddbe..d3b6f2a2 100644 --- a/panos/device.py +++ b/panos/device.py @@ -130,6 +130,7 @@ class Vsys(VersionedPanObject): "objects.Tag", "objects.ApplicationObject", "objects.ApplicationGroup", + "objects.ApplicationTag", "objects.ApplicationFilter", "objects.ApplicationContainer", "objects.ScheduleObject", diff --git a/panos/firewall.py b/panos/firewall.py index ad0f98df..49c8ae3a 100644 --- a/panos/firewall.py +++ b/panos/firewall.py @@ -84,6 +84,7 @@ class Firewall(PanDevice): "objects.Tag", "objects.ApplicationObject", "objects.ApplicationGroup", + "objects.ApplicationTag", "objects.ApplicationFilter", "objects.ApplicationContainer", "objects.ScheduleObject", diff --git a/panos/objects.py b/panos/objects.py index dd7a4425..3c3b34da 100644 --- a/panos/objects.py +++ b/panos/objects.py @@ -484,6 +484,32 @@ def _setup(self): self._params = tuple(params) +class ApplicationTag(VersionedPanObject): + """ApplicationTag Object + + Applies an administrative tag to a predefined application + + Args: + name (str): Name of predefined application + tags (list): Administrative tags + + """ + + ROOT = Root.VSYS + SUFFIX = ENTRY + + def _setup(self): + # xpaths + self._xpaths.add_profile(value="/application-tag") + + # params + params = [] + + params.append(VersionedParamPath("tags", path="tag", vartype="member")) + + self._params = tuple(params) + + class ApplicationFilter(VersionedPanObject): """ApplicationFilter Object diff --git a/panos/panorama.py b/panos/panorama.py index d41535f6..cc446290 100644 --- a/panos/panorama.py +++ b/panos/panorama.py @@ -111,6 +111,7 @@ class DeviceGroup(VersionedPanObject): "objects.ServiceGroup", "objects.ApplicationObject", "objects.ApplicationGroup", + "objects.ApplicationTag", "objects.ApplicationFilter", "objects.ScheduleObject", "objects.SecurityProfileGroup", @@ -428,6 +429,7 @@ class Panorama(base.PanDevice): "objects.Tag", "objects.ApplicationObject", "objects.ApplicationGroup", + "objects.ApplicationTag", "objects.ApplicationFilter", "objects.ApplicationContainer", "objects.ScheduleObject", From 9a1fed704cd70184a755b5a1a9201b0bd593dee9 Mon Sep 17 00:00:00 2001 From: alexortize Date: Fri, 22 Jul 2022 12:17:25 -0700 Subject: [PATCH 07/14] Update panorama.py Updated DeviceGroup class to support Tag objects at device group level. --- panos/panorama.py | 1 + 1 file changed, 1 insertion(+) diff --git a/panos/panorama.py b/panos/panorama.py index cc446290..d3d7b4ad 100644 --- a/panos/panorama.py +++ b/panos/panorama.py @@ -118,6 +118,7 @@ class DeviceGroup(VersionedPanObject): "objects.CustomUrlCategory", "objects.LogForwardingProfile", "objects.Region", + "objects.Tag", "objects.Edl", "policies.PreRulebase", "policies.PostRulebase", From 423740f185c043d2f7090f3452e5c88567e3f3b4 Mon Sep 17 00:00:00 2001 From: alexortize Date: Mon, 8 Aug 2022 16:21:03 -0700 Subject: [PATCH 08/14] added UrlFilteringProfile class added UrlFilteringProfile class --- panos/firewall.py | 1 + panos/objects.py | 120 ++++++++++++++++++++++++++++++++++++++++++++++ panos/panorama.py | 2 + 3 files changed, 123 insertions(+) diff --git a/panos/firewall.py b/panos/firewall.py index 49c8ae3a..af824e4e 100644 --- a/panos/firewall.py +++ b/panos/firewall.py @@ -94,6 +94,7 @@ class Firewall(PanDevice): "objects.DynamicUserGroup", "objects.Region", "objects.Edl", + "objects.UrlFilteringProfile", "policies.Rulebase", "network.EthernetInterface", "network.AggregateInterface", diff --git a/panos/objects.py b/panos/objects.py index 3c3b34da..915cee05 100644 --- a/panos/objects.py +++ b/panos/objects.py @@ -1274,3 +1274,123 @@ def _setup(self): ) self._params = tuple(params) + +class UrlFilteringProfile(VersionedPanObject): + """Administrator object + + Args: + name (str): URL-Filtering name + description (str): Profile description + allow (list): Allowed categories + alert (list): Alert categories + categorychange (list): Category change categories + block (list): Block categories + continue (list): Continue categories + override (list): Override categories + mode (str): Credential enforcement mode. Valid values are "disabled", + "ip-user", "domain-credentials". Default value is "disabled". + group_mapping (str): Group mapping used + log_severity (str): Log severity. Default value is "medium" + ce_allow (list): Credential enforcement allow categories + ce_alert (list): Credential enforcement alert categories + ce_block (list): Credential enforcement block categories + ce_continue (list): Credential enforcement continue categories + + """ + + ROOT = Root.VSYS + SUFFIX = ENTRY + + def _setup(self): + # xpaths + self._xpaths.add_profile(value="/profiles/url-filtering") + + # params + params = [] + + params.append(VersionedParamPath("description", path="description")) + + params.append( + VersionedParamPath("allow", path="allow", vartype="member") + ) + + params.append( + VersionedParamPath("alert", path="alert", vartype="member") + ) + + params.append( + VersionedParamPath("categorychange", path="categorychange", vartype="member") + ) + + params.append( + VersionedParamPath("block", path="block", vartype="member") + ) + + params.append( + VersionedParamPath("continue", path="continue", vartype="member") + ) + + params.append( + VersionedParamPath("override", path="override", vartype="member") + ) + + params.append(VersionedParamPath("mode", path="{type}")) + params.append( + VersionedParamPath( + "type", + values=["disabled", "ip-user", "domain-credentials"], + default="disabled", + path="credential-enforcement/mode/{type}", + ) + ) + + params.append( + VersionedParamPath( + "group_mapping", + path="credential-enforcement/mode/group-mapping", + vartype="string" + ) + ) + + params.append( + VersionedParamPath( + "log_severity", + path="credential-enforcement/log-severity", + vartype="string", + default="medium", + ) + ) + + params.append( + VersionedParamPath( + "ce_allow", + path="credential-enforcement/allow", + vartype="member", + ) + ) + + params.append( + VersionedParamPath( + "ce_alert", + path="credential-enforcement/alert", + vartype="member", + ) + ) + + params.append( + VersionedParamPath( + "ce_block", + path="credential-enforcement/block", + vartype="member", + ) + ) + + params.append( + VersionedParamPath( + "ce_continue", + path="credential-enforcement/continue", + vartype="member", + ) + ) + + self._params = tuple(params) diff --git a/panos/panorama.py b/panos/panorama.py index d3d7b4ad..cd6dd755 100644 --- a/panos/panorama.py +++ b/panos/panorama.py @@ -120,6 +120,7 @@ class DeviceGroup(VersionedPanObject): "objects.Region", "objects.Tag", "objects.Edl", + "objects.UrlFilteringProfile", "policies.PreRulebase", "policies.PostRulebase", ) @@ -440,6 +441,7 @@ class Panorama(base.PanDevice): "objects.DynamicUserGroup", "objects.Region", "objects.Edl", + "objects.UrlFilteringProfile", "firewall.Firewall", "panorama.DeviceGroup", "panorama.Template", From b7e293837fcecd5b9fffb4ed926ac7eb5e8428ff Mon Sep 17 00:00:00 2001 From: alexortize Date: Mon, 8 Aug 2022 16:29:29 -0700 Subject: [PATCH 09/14] After running black --- docs/configtree.py | 6 +- examples/dyn_address_group.py | 6 +- examples/upgrade.py | 6 +- examples/userid.py | 6 +- panos/__init__.py | 10 +- panos/base.py | 69 ++++-- panos/device.py | 144 ++++++++++--- panos/ha.py | 3 +- panos/network.py | 74 +++++-- panos/objects.py | 139 ++++++++---- panos/plugins.py | 4 +- panos/policies.py | 320 +++++++++++++++++++++++----- panos/predefined.py | 14 +- panos/userid.py | 16 +- tests/live/conftest.py | 5 +- tests/live/test_network.py | 55 +++-- tests/live/test_objects.py | 10 +- tests/live/test_userid.py | 6 +- tests/live/testlib.py | 4 +- tests/test_base.py | 58 ++++- tests/test_device_profile_xpaths.py | 15 +- tests/test_firewall.py | 8 +- tests/test_init.py | 6 +- tests/test_integration.py | 43 +++- tests/test_opstate.py | 4 +- tests/test_params.py | 81 +++++-- tests/test_predefined.py | 26 ++- tests/test_userid.py | 28 ++- tests/test_versioning.py | 9 +- 29 files changed, 936 insertions(+), 239 deletions(-) diff --git a/docs/configtree.py b/docs/configtree.py index bb7a3214..85a382c9 100755 --- a/docs/configtree.py +++ b/docs/configtree.py @@ -70,8 +70,10 @@ def node_style(cls): style = "style=filled " + nodestyle[module] + " " except: pass - result = ' {0} [{1}URL="../module-{2}.html#panos.{3}" target="_top"];\n'.format( - cls_name, style, module, cls + result = ( + ' {0} [{1}URL="../module-{2}.html#panos.{3}" target="_top"];\n'.format( + cls_name, style, module, cls + ) ) else: if style: diff --git a/examples/dyn_address_group.py b/examples/dyn_address_group.py index 248769ca..20d4cd41 100755 --- a/examples/dyn_address_group.py +++ b/examples/dyn_address_group.py @@ -111,7 +111,11 @@ def main(): logging.basicConfig(format=logging_format, level=logging_level) # Connect to the device and determine its type (Firewall or Panorama). - device = PanDevice.create_from_device(args.hostname, args.username, args.password,) + device = PanDevice.create_from_device( + args.hostname, + args.username, + args.password, + ) # Panorama does not have a userid API, so exit. # You can use the userid API on a firewall with the Panorama 'target' diff --git a/examples/upgrade.py b/examples/upgrade.py index 12e55236..e1162337 100755 --- a/examples/upgrade.py +++ b/examples/upgrade.py @@ -95,7 +95,11 @@ def main(): # Connect to the device and determine its type (Firewall or Panorama). # This is important to know what version to upgrade to next. - device = PanDevice.create_from_device(args.hostname, args.username, args.password,) + device = PanDevice.create_from_device( + args.hostname, + args.username, + args.password, + ) # Perform the upgrades in sequence with reboots between each upgrade device.software.upgrade_to_version(args.version, args.dryrun) diff --git a/examples/userid.py b/examples/userid.py index 0ba04887..b8aa942a 100755 --- a/examples/userid.py +++ b/examples/userid.py @@ -90,7 +90,11 @@ def main(): logging.basicConfig(format=logging_format, level=logging_level) # Connect to the device and determine its type (Firewall or Panorama). - device = PanDevice.create_from_device(args.hostname, args.username, args.password,) + device = PanDevice.create_from_device( + args.hostname, + args.username, + args.password, + ) logging.debug("Detecting type of device") diff --git a/panos/__init__.py b/panos/__init__.py index e9c0afa0..3fc19205 100755 --- a/panos/__init__.py +++ b/panos/__init__.py @@ -241,7 +241,9 @@ def tree_legend_dot(): result += ( '{module} [style=filled fillcolor={color} URL="{url}' '/module-{module}.html" target="_blank"];'.format( - module=module, color=node_color(module), url=DOCUMENTATION_URL, + module=module, + color=node_color(module), + url=DOCUMENTATION_URL, ) ) result += "}" @@ -286,7 +288,11 @@ def string_or_list(value): value, ] return ( - list(value) if "__iter__" in dir(value) else [value,] + list(value) + if "__iter__" in dir(value) + else [ + value, + ] ) diff --git a/panos/base.py b/panos/base.py index 4aeb16fc..9477ec3a 100644 --- a/panos/base.py +++ b/panos/base.py @@ -1631,7 +1631,13 @@ def _set_reference( if var_type == "list": if var is None: update_needed = True - setattr(obj, reference_var, [self,]) + setattr( + obj, + reference_var, + [ + self, + ], + ) if update: obj.update(reference_var) elif not isinstance(var, list): @@ -2100,7 +2106,9 @@ def hierarchy_info(self): classes = panos.object_classes() configs = [ - [self.__class__,], + [ + self.__class__, + ], ] updated_configs = [] @@ -2112,7 +2120,10 @@ def hierarchy_info(self): configs.pop(num) for p in parents: configs.append( - chain + [p,] + chain + + [ + p, + ] ) break else: @@ -2764,7 +2775,8 @@ def __getattr__(self, name): raise AttributeError( "'{0}' object has no attribute '{1}'".format( - self.__class__.__name__, str(name), + self.__class__.__name__, + str(name), ) ) @@ -2849,9 +2861,7 @@ def __repr__(self): class ValueEntry(VersionedPanObject): - """Base class for objects that only have a value element. - - """ + """Base class for objects that only have a value element.""" ROOT = Root.VSYS SUFFIX = ENTRY @@ -3685,7 +3695,12 @@ def get_device_version(self): @classmethod def create_from_device( - cls, hostname, api_username=None, api_password=None, api_key=None, port=443, + cls, + hostname, + api_username=None, + api_password=None, + api_key=None, + port=443, ): """Factory method to create a :class:`panos.firewall.Firewall` or :class:`panos.panorama.Panorama` object from a live device @@ -3707,18 +3722,33 @@ def create_from_device( # Create generic PanDevice to connect and get information from panos import firewall, panorama - device = PanDevice(hostname, api_username, api_password, api_key, port,) + device = PanDevice( + hostname, + api_username, + api_password, + api_key, + port, + ) system_info = device.refresh_system_info() version = system_info[0] model = system_info[1] if model == "Panorama" or model.startswith("M-"): instance = panorama.Panorama( - hostname, api_username, api_password, device.api_key, port, + hostname, + api_username, + api_password, + device.api_key, + port, ) else: serial = system_info[2] instance = firewall.Firewall( - hostname, api_username, api_password, device.api_key, serial, port, + hostname, + api_username, + api_password, + device.api_key, + serial, + port, ) instance._set_version_and_version_info(version) return instance @@ -3866,10 +3896,16 @@ def method(self, *args, **kwargs): def classify_exception(self, e): if str(e) == "Invalid credentials.": - return err.PanInvalidCredentials(str(e), pan_device=self.pan_device,) + return err.PanInvalidCredentials( + str(e), + pan_device=self.pan_device, + ) elif str(e).startswith("URLError:"): if str(e).endswith("timed out"): - return err.PanConnectionTimeout(str(e), pan_device=self.pan_device,) + return err.PanConnectionTimeout( + str(e), + pan_device=self.pan_device, + ) else: # This could be that we have an old version of OpenSSL # that doesn't support TLSv1.1, so check for that and give @@ -4795,7 +4831,12 @@ def _commit( logger.debug( self.id + ": commit requested: commit_all:%s sync:%s sync_all:%s cmd:%s" - % (str(commit_all), str(sync), str(sync_all), cmd,) + % ( + str(commit_all), + str(sync), + str(sync_all), + cmd, + ) ) if commit_all: action = "all" diff --git a/panos/device.py b/panos/device.py index d3b6f2a2..ec8c3f20 100644 --- a/panos/device.py +++ b/panos/device.py @@ -1276,7 +1276,11 @@ def _setup(self): ) ) params.append( - VersionedParamPath("disabled", vartype="yesno", path="disabled",), + VersionedParamPath( + "disabled", + vartype="yesno", + path="disabled", + ), ) self._params = tuple(params) @@ -1422,7 +1426,10 @@ def _setup(self): "facility", default="LOG_USER", path="facility", - values=["LOG_USER",] + ["LOG_LOCAL{0}".format(x) for x in range(8)], + values=[ + "LOG_USER", + ] + + ["LOG_LOCAL{0}".format(x) for x in range(8)], ) ) @@ -2148,12 +2155,28 @@ def _setup(self): ) params.append( VersionedParamPath( - "username_field_value", path="username-field/{username_field}", + "username_field_value", + path="username-field/{username_field}", + ) + ) + params.append( + VersionedParamPath( + "domain", + path="domain", + ) + ) + params.append( + VersionedParamPath( + "use_crl", + path="use-crl", + ) + ) + params.append( + VersionedParamPath( + "use_ocsp", + path="use-ocsp", ) ) - params.append(VersionedParamPath("domain", path="domain",)) - params.append(VersionedParamPath("use_crl", path="use-crl",)) - params.append(VersionedParamPath("use_ocsp", path="use-ocsp",)) params.append( VersionedParamPath( "crl_receive_timeout", @@ -2180,27 +2203,50 @@ def _setup(self): ) params.append( VersionedParamPath( - "block_unknown_certificate", vartype="yesno", path="block-unknown-cert", + "block_unknown_certificate", + vartype="yesno", + path="block-unknown-cert", ) ) params.append( VersionedParamPath( - "block_certificate_timeout", vartype="yesno", path="block-timeout-cert", + "block_certificate_timeout", + vartype="yesno", + path="block-timeout-cert", ) ) params.append( - VersionedParamPath("block_unauthenticated_certificate", exclude=True,) + VersionedParamPath( + "block_unauthenticated_certificate", + exclude=True, + ) ) params[-1].add_profile( - "7.1.0", vartype="yesno", path="block-unauthenticated-cert", + "7.1.0", + vartype="yesno", + path="block-unauthenticated-cert", + ) + params.append( + VersionedParamPath( + "block_expired_certificate", + exclude=True, + ) ) - params.append(VersionedParamPath("block_expired_certificate", exclude=True,)) params[-1].add_profile( - "8.1.0", vartype="yesno", path="block-expired-cert", + "8.1.0", + vartype="yesno", + path="block-expired-cert", + ) + params.append( + VersionedParamPath( + "ocsp_exclude_nonce", + exclude=True, + ) ) - params.append(VersionedParamPath("ocsp_exclude_nonce", exclude=True,)) params[-1].add_profile( - "9.0.0", path="ocsp-exclude-nonce", vartype="yesno", + "9.0.0", + path="ocsp-exclude-nonce", + vartype="yesno", ) self._params = tuple(params) @@ -2227,13 +2273,27 @@ def _setup(self): # params params = [] - params.append(VersionedParamPath("default_ocsp_url", path="default-ocsp-url",)) params.append( - VersionedParamPath("ocsp_verify_certificate", path="ocsp-verify-cert",) + VersionedParamPath( + "default_ocsp_url", + path="default-ocsp-url", + ) + ) + params.append( + VersionedParamPath( + "ocsp_verify_certificate", + path="ocsp-verify-cert", + ) + ) + params.append( + VersionedParamPath( + "template_name", + exclude=True, + ) ) - params.append(VersionedParamPath("template_name", exclude=True,)) params[-1].add_profile( - "9.0.0", path="template-name", + "9.0.0", + path="template-name", ) self._params = tuple(params) @@ -2268,7 +2328,8 @@ def _setup(self): params.append( VersionedParamPath( - "forward_trust_certificate_rsa", path="forward-trust-certificate/rsa", + "forward_trust_certificate_rsa", + path="forward-trust-certificate/rsa", ) ) params.append( @@ -2291,13 +2352,17 @@ def _setup(self): ) params.append( VersionedParamPath( - "root_ca_excludes", vartype="member", path="root-ca-exclude-list", + "root_ca_excludes", + vartype="member", + path="root-ca-exclude-list", ) ) # Only option present on Panorama. params.append( VersionedParamPath( - "trusted_root_cas", vartype="member", path="trusted-root-CA", + "trusted_root_cas", + vartype="member", + path="trusted-root-CA", ) ) params.append( @@ -2332,8 +2397,19 @@ def _setup(self): # params params = [] - params.append(VersionedParamPath("description", path="description",)) - params.append(VersionedParamPath("exclude", vartype="yesno", path="exclude",)) + params.append( + VersionedParamPath( + "description", + path="description", + ) + ) + params.append( + VersionedParamPath( + "exclude", + vartype="yesno", + path="exclude", + ) + ) self._params = tuple(params) @@ -2363,9 +2439,19 @@ def _setup(self): params = [] params.append( - VersionedParamPath("password_hash", vartype="encrypted", path="phash",) + VersionedParamPath( + "password_hash", + vartype="encrypted", + path="phash", + ) + ) + params.append( + VersionedParamPath( + "disabled", + vartype="yesno", + path="disabled", + ) ) - params.append(VersionedParamPath("disabled", vartype="yesno", path="disabled",)) self._params = tuple(params) @@ -2406,6 +2492,12 @@ def _setup(self): # params params = [] - params.append(VersionedParamPath("users", vartype="member", path="user",)) + params.append( + VersionedParamPath( + "users", + vartype="member", + path="user", + ) + ) self._params = tuple(params) diff --git a/panos/ha.py b/panos/ha.py index 824d9734..9a072e66 100644 --- a/panos/ha.py +++ b/panos/ha.py @@ -560,5 +560,6 @@ def _setup(self): # stubs self._stubs.add_profile( - "0.0.0", "interface/ha1", + "0.0.0", + "interface/ha1", ) diff --git a/panos/network.py b/panos/network.py index 566a6dcc..01c09d8f 100644 --- a/panos/network.py +++ b/panos/network.py @@ -153,22 +153,48 @@ def _setup(self): ) ) params.append( - VersionedParamPath("enable_packet_buffer_protection", exclude=True,) + VersionedParamPath( + "enable_packet_buffer_protection", + exclude=True, + ) ) params[-1].add_profile( - "8.0.0", path="network/enable-packet-buffer-protection", vartype="yesno", + "8.0.0", + path="network/enable-packet-buffer-protection", + vartype="yesno", + ) + params.append( + VersionedParamPath( + "enable_device_identification", + exclude=True, + ) ) - params.append(VersionedParamPath("enable_device_identification", exclude=True,)) params[-1].add_profile( - "10.0.0", path="enable-device-identification", vartype="yesno", + "10.0.0", + path="enable-device-identification", + vartype="yesno", + ) + params.append( + VersionedParamPath( + "device_include_acl", + exclude=True, + ) ) - params.append(VersionedParamPath("device_include_acl", exclude=True,)) params[-1].add_profile( - "10.0.0", path="device-acl/include-list", vartype="member", + "10.0.0", + path="device-acl/include-list", + vartype="member", + ) + params.append( + VersionedParamPath( + "device_exclude_acl", + exclude=True, + ) ) - params.append(VersionedParamPath("device_exclude_acl", exclude=True,)) params[-1].add_profile( - "10.0.0", path="device-acl/exclude-acl", vartype="member", + "10.0.0", + path="device-acl/exclude-acl", + vartype="member", ) self._params = tuple(params) @@ -1376,7 +1402,12 @@ def _setup(self): "mode", path="{mode}", default="layer3", - values=["layer3", "layer2", "virtual-wire", "ha",], + values=[ + "layer3", + "layer2", + "virtual-wire", + "ha", + ], ) ) params.append( @@ -2170,7 +2201,11 @@ def _setup(self): VersionedParamPath("enable", path="enable", default=True, vartype="yesno") ) params.append( - VersionedParamPath("reject_default_route", default=True, vartype="yesno",) + VersionedParamPath( + "reject_default_route", + default=True, + vartype="yesno", + ) ) params.append( VersionedParamPath( @@ -4202,7 +4237,11 @@ def _setup(self): ) params[-1].add_profile( "8.1.0", - values=("ip", "dynamic", "fqdn",), + values=( + "ip", + "dynamic", + "fqdn", + ), path="peer-address/{peer_ip_type}", ) params.append( @@ -4608,7 +4647,14 @@ def _setup(self): params.append( VersionedParamPath( "mk_esp_encryption", - values=("des", "3des", "aes128", "aes192", "aes256", "null",), + values=( + "des", + "3des", + "aes128", + "aes192", + "aes256", + "null", + ), path="{type}/{mk_protocol}/encryption/algorithm", ) ) @@ -5448,6 +5494,8 @@ def _setup(self): params = [] - params.append(VersionedParamPath("interface", path="interface"),) + params.append( + VersionedParamPath("interface", path="interface"), + ) self._params = tuple(params) diff --git a/panos/objects.py b/panos/objects.py index 915cee05..61a5bdd1 100644 --- a/panos/objects.py +++ b/panos/objects.py @@ -319,7 +319,8 @@ def _setup(self): # xpaths self._xpaths.add_profile(value="/application") self._xpaths.add_profile( - value='//*[contains(local-name(), "application")]', parents=("Predefined",), + value='//*[contains(local-name(), "application")]', + parents=("Predefined",), ) # params @@ -615,7 +616,8 @@ def _setup(self): # xpaths self._xpaths.add_profile(value="/application-container") self._xpaths.add_profile( - value='//*[contains(local-name(), "application")]', parents=("Predefined",), + value='//*[contains(local-name(), "application")]', + parents=("Predefined",), ) # params @@ -859,7 +861,9 @@ def _setup(self): VersionedParamPath( "action_type", default="tagging", - values=["tagging",], + values=[ + "tagging", + ], path="type/{action_type}", ) ) @@ -1149,7 +1153,10 @@ def _setup(self): params.append( VersionedParamPath( - "edl_type", default="ip", path="type", values=("ip", "domain", "url"), + "edl_type", + default="ip", + path="type", + values=("ip", "domain", "url"), ), ) params[-1].add_profile( @@ -1162,38 +1169,77 @@ def _setup(self): path="type/{edl_type}", values=("ip", "domain", "url", "predefined-ip", "predefined-url"), ) - params.append(VersionedParamPath("description", path="description",),) + params.append( + VersionedParamPath( + "description", + path="description", + ), + ) params[-1].add_profile( - "8.0.0", path="type/{edl_type}/description", + "8.0.0", + path="type/{edl_type}/description", + ) + params.append( + VersionedParamPath( + "source", + path="url", + ), ) - params.append(VersionedParamPath("source", path="url",),) params[-1].add_profile( - "8.0.0", path="type/{edl_type}/url", + "8.0.0", + path="type/{edl_type}/url", + ) + params.append( + VersionedParamPath( + "exceptions", + exclude=True, + ), ) - params.append(VersionedParamPath("exceptions", exclude=True,),) params[-1].add_profile( - "8.0.0", vartype="member", path="type/{edl_type}/exception-list", + "8.0.0", + vartype="member", + path="type/{edl_type}/exception-list", + ) + params.append( + VersionedParamPath( + "certificate_profile", + exclude=True, + ) ) - params.append(VersionedParamPath("certificate_profile", exclude=True,)) params[-1].add_profile( "8.0.0", path="type/{edl_type}/certificate-profile", condition={"edl_type": ["ip", "domain", "url"]}, ) - params.append(VersionedParamPath("username", exclude=True,)) + params.append( + VersionedParamPath( + "username", + exclude=True, + ) + ) params[-1].add_profile( "8.0.0", path="type/{edl_type}/auth/username", condition={"edl_type": ["ip", "domain", "url"]}, ) - params.append(VersionedParamPath("password", exclude=True,)) + params.append( + VersionedParamPath( + "password", + exclude=True, + ) + ) params[-1].add_profile( "8.0.0", path="type/{edl_type}/auth/password", vartype="encrypted", condition={"edl_type": ["ip", "domain", "url"]}, ) - params.append(VersionedParamPath("expand_domain", exclude=True,),) + params.append( + VersionedParamPath( + "expand_domain", + exclude=True, + ), + ) params[-1].add_profile( "9.0.0", path="type/{edl_type}/expand-domain", @@ -1256,7 +1302,10 @@ def _setup(self): "friday", "saturday", ), - condition={"edl_type": ["ip", "domain", "url"], "repeat": "weekly",}, + condition={ + "edl_type": ["ip", "domain", "url"], + "repeat": "weekly", + }, ) params.append( VersionedParamPath( @@ -1270,11 +1319,15 @@ def _setup(self): "8.0.0", vartype="int", path="type/{edl_type}/recurring/{repeat}/day-of-month", - condition={"edl_type": ["ip", "domain", "url"], "repeat": "monthly",}, + condition={ + "edl_type": ["ip", "domain", "url"], + "repeat": "monthly", + }, ) self._params = tuple(params) + class UrlFilteringProfile(VersionedPanObject): """Administrator object @@ -1288,7 +1341,7 @@ class UrlFilteringProfile(VersionedPanObject): continue (list): Continue categories override (list): Override categories mode (str): Credential enforcement mode. Valid values are "disabled", - "ip-user", "domain-credentials". Default value is "disabled". + "ip-user", "domain-credentials". Default value is "disabled". group_mapping (str): Group mapping used log_severity (str): Log severity. Default value is "medium" ce_allow (list): Credential enforcement allow categories @@ -1309,31 +1362,23 @@ def _setup(self): params = [] params.append(VersionedParamPath("description", path="description")) - - params.append( - VersionedParamPath("allow", path="allow", vartype="member") - ) - - params.append( - VersionedParamPath("alert", path="alert", vartype="member") - ) - - params.append( - VersionedParamPath("categorychange", path="categorychange", vartype="member") - ) - - params.append( - VersionedParamPath("block", path="block", vartype="member") - ) - - params.append( - VersionedParamPath("continue", path="continue", vartype="member") - ) - + + params.append(VersionedParamPath("allow", path="allow", vartype="member")) + + params.append(VersionedParamPath("alert", path="alert", vartype="member")) + params.append( - VersionedParamPath("override", path="override", vartype="member") + VersionedParamPath( + "categorychange", path="categorychange", vartype="member" + ) ) - + + params.append(VersionedParamPath("block", path="block", vartype="member")) + + params.append(VersionedParamPath("continue", path="continue", vartype="member")) + + params.append(VersionedParamPath("override", path="override", vartype="member")) + params.append(VersionedParamPath("mode", path="{type}")) params.append( VersionedParamPath( @@ -1343,15 +1388,15 @@ def _setup(self): path="credential-enforcement/mode/{type}", ) ) - + params.append( VersionedParamPath( "group_mapping", path="credential-enforcement/mode/group-mapping", - vartype="string" + vartype="string", ) ) - + params.append( VersionedParamPath( "log_severity", @@ -1360,7 +1405,7 @@ def _setup(self): default="medium", ) ) - + params.append( VersionedParamPath( "ce_allow", @@ -1368,7 +1413,7 @@ def _setup(self): vartype="member", ) ) - + params.append( VersionedParamPath( "ce_alert", @@ -1376,7 +1421,7 @@ def _setup(self): vartype="member", ) ) - + params.append( VersionedParamPath( "ce_block", @@ -1384,7 +1429,7 @@ def _setup(self): vartype="member", ) ) - + params.append( VersionedParamPath( "ce_continue", diff --git a/panos/plugins.py b/panos/plugins.py index aec89bd8..991378e6 100644 --- a/panos/plugins.py +++ b/panos/plugins.py @@ -373,7 +373,9 @@ def _setup(self): params.append( VersionedParamPath( - "same_as_primary", vartype="yesno", path="same-as-primary", + "same_as_primary", + vartype="yesno", + path="same-as-primary", ) ) params.append(VersionedParamPath("peer_ip_address", path="peer-ip-address")) diff --git a/panos/policies.py b/panos/policies.py index b947a6fa..c1f7b1bb 100644 --- a/panos/policies.py +++ b/panos/policies.py @@ -48,7 +48,10 @@ def _setup(self, name=None, elm=None): def refresh(self, elm=None): if elm is None and self.obj is not None: self.obj.parent.opstate.hit_count.refresh( - self.obj.HIT_COUNT_STYLE, [self.name,], + self.obj.HIT_COUNT_STYLE, + [ + self.name, + ], ) else: self._refresh_xml(elm) @@ -264,7 +267,8 @@ def current(self): ET.SubElement(sub, "xpath").text = self.obj.xpath() ans = self.obj.nearest_pandevice().op( - ET.tostring(cmd, encoding="utf-8"), cmd_xml=False, + ET.tostring(cmd, encoding="utf-8"), + cmd_xml=False, ) resp = ans.find("./result/entry/comment") @@ -284,7 +288,8 @@ def update(self, comment): ET.SubElement(sub, "comment").text = comment self.obj.nearest_pandevice().op( - ET.tostring(cmd, encoding="utf-8"), cmd_xml=False, + ET.tostring(cmd, encoding="utf-8"), + cmd_xml=False, ) @@ -370,7 +375,12 @@ def _setup(self): for var_name, path in any_defaults: params.append( VersionedParamPath( - var_name, default=["any",], vartype="member", path=path + var_name, + default=[ + "any", + ], + vartype="member", + path=path, ) ) @@ -384,7 +394,12 @@ def _setup(self): ) params.append( VersionedParamPath( - "category", default=["any",], vartype="member", path="category" + "category", + default=[ + "any", + ], + vartype="member", + path="category", ) ) params.append(VersionedParamPath("action", path="action")) @@ -447,11 +462,23 @@ def _setup(self): params.append(VersionedParamPath("uuid", exclude=True)) params[-1].add_profile("9.0.0", vartype="attrib", path="uuid") params.append( - VersionedParamPath("source_devices", default=["any",], exclude=True) + VersionedParamPath( + "source_devices", + default=[ + "any", + ], + exclude=True, + ) ) params[-1].add_profile("10.0.0", vartype="member", path="source-hip") params.append( - VersionedParamPath("destination_devices", default=["any",], exclude=True) + VersionedParamPath( + "destination_devices", + default=[ + "any", + ], + exclude=True, + ) ) params[-1].add_profile("10.0.0", vartype="member", path="destination-hip") params.append(VersionedParamPath("group_tag", exclude=True)) @@ -555,7 +582,12 @@ def _setup(self): ) params.append( VersionedParamPath( - "fromzone", default=["any",], vartype="member", path="from" + "fromzone", + default=[ + "any", + ], + vartype="member", + path="from", ) ) params.append(VersionedParamPath("tozone", vartype="member", path="to")) @@ -563,12 +595,22 @@ def _setup(self): params.append(VersionedParamPath("service", default="any", path="service")) params.append( VersionedParamPath( - "source", default=["any",], vartype="member", path="source" + "source", + default=[ + "any", + ], + vartype="member", + path="source", ) ) params.append( VersionedParamPath( - "destination", default=["any",], vartype="member", path="destination" + "destination", + default=[ + "any", + ], + vartype="member", + path="destination", ) ) params.append( @@ -872,7 +914,12 @@ def _setup(self): for var_name, path in any_defaults: params.append( VersionedParamPath( - var_name, default=["any",], vartype="member", path=path + var_name, + default=[ + "any", + ], + vartype="member", + path=path, ) ) params.append(VersionedParamPath("application", path="application")) @@ -1155,43 +1202,103 @@ def _setup(self): params.append(VersionedParamPath("uuid", exclude=True)) params[-1].add_profile("9.0.0", vartype="attrib", path="uuid") params.append( - VersionedParamPath("source_zones", vartype="member", path="from",) + VersionedParamPath( + "source_zones", + vartype="member", + path="from", + ) ) params.append( - VersionedParamPath("source_addresses", vartype="member", path="source",) + VersionedParamPath( + "source_addresses", + vartype="member", + path="source", + ) ) params.append( - VersionedParamPath("negate_source", vartype="yesno", path="negate-source",) + VersionedParamPath( + "negate_source", + vartype="yesno", + path="negate-source", + ) ) params.append( - VersionedParamPath("source_users", vartype="member", path="source-user",) + VersionedParamPath( + "source_users", + vartype="member", + path="source-user", + ) + ) + params.append( + VersionedParamPath( + "source_hip", + exclude=True, + ) ) - params.append(VersionedParamPath("source_hip", exclude=True,)) params[-1].add_profile( - "10.0.0", path="source-hip", vartype="member", + "10.0.0", + path="source-hip", + vartype="member", ) params.append( - VersionedParamPath("destination_zones", vartype="member", path="to",) + VersionedParamPath( + "destination_zones", + vartype="member", + path="to", + ) + ) + params.append( + VersionedParamPath( + "destination_addresses", + vartype="member", + path="destination", + ) ) params.append( VersionedParamPath( - "destination_addresses", vartype="member", path="destination", + "negate_destination", + vartype="yesno", + path="negate-destination", ) ) params.append( VersionedParamPath( - "negate_destination", vartype="yesno", path="negate-destination", + "destination_hip", + exclude=True, ) ) - params.append(VersionedParamPath("destination_hip", exclude=True,)) params[-1].add_profile( - "10.0.0", path="destination-hip", vartype="member", + "10.0.0", + path="destination-hip", + vartype="member", + ) + params.append( + VersionedParamPath( + "tags", + vartype="member", + path="tag", + ) ) - params.append(VersionedParamPath("tags", vartype="member", path="tag",)) - params.append(VersionedParamPath("disabled", vartype="yesno", path="disabled",)) - params.append(VersionedParamPath("services", vartype="member", path="service",)) params.append( - VersionedParamPath("url_categories", vartype="member", path="category",) + VersionedParamPath( + "disabled", + vartype="yesno", + path="disabled", + ) + ) + params.append( + VersionedParamPath( + "services", + vartype="member", + path="service", + ) + ) + params.append( + VersionedParamPath( + "url_categories", + vartype="member", + path="category", + ) ) params.append( VersionedParamPath( @@ -1210,38 +1317,79 @@ def _setup(self): VersionedParamPath( "decryption_type", path="type/{decryption_type}", - values=("ssl-forward-proxy", "ssh-proxy", "ssl-inbound-inspection",), + values=( + "ssl-forward-proxy", + "ssh-proxy", + "ssl-inbound-inspection", + ), ) ) params.append( VersionedParamPath( "ssl_certificate", path="type/{decryption_type}", - condition={"decryption_type": "ssl-inbound-inspection",}, + condition={ + "decryption_type": "ssl-inbound-inspection", + }, + ) + ) + params.append( + VersionedParamPath( + "decryption_profile", + path="profile", + ) + ) + params.append( + VersionedParamPath( + "forwarding_profile", + exclude=True, ) ) - params.append(VersionedParamPath("decryption_profile", path="profile",)) - params.append(VersionedParamPath("forwarding_profile", exclude=True,)) params[-1].add_profile( - "8.1.0", path="forwarding-profile", + "8.1.0", + path="forwarding-profile", + ) + params.append( + VersionedParamPath( + "group_tag", + exclude=True, + ) ) - params.append(VersionedParamPath("group_tag", exclude=True,)) params[-1].add_profile( - "9.0.0", path="group-tag", + "9.0.0", + path="group-tag", ) params.append( - VersionedParamPath("log_successful_tls_handshakes", exclude=True,) + VersionedParamPath( + "log_successful_tls_handshakes", + exclude=True, + ) ) params[-1].add_profile( - "10.0.0", path="log-success", vartype="yesno", + "10.0.0", + path="log-success", + vartype="yesno", + ) + params.append( + VersionedParamPath( + "log_failed_tls_handshakes", + exclude=True, + ) ) - params.append(VersionedParamPath("log_failed_tls_handshakes", exclude=True,)) params[-1].add_profile( - "10.0.0", path="log-fail", vartype="yesno", + "10.0.0", + path="log-fail", + vartype="yesno", + ) + params.append( + VersionedParamPath( + "log_setting", + exclude=True, + ) ) - params.append(VersionedParamPath("log_setting", exclude=True,)) params[-1].add_profile( - "10.0.0", path="log-setting", + "10.0.0", + path="log-setting", ) params.append( VersionedParamPath("negate_target", path="target/negate", vartype="yesno") @@ -1306,55 +1454,117 @@ def _setup(self): params.append(VersionedParamPath("uuid", exclude=True)) params[-1].add_profile("9.0.0", vartype="attrib", path="uuid") params.append( - VersionedParamPath("source_zones", vartype="member", path="from",) + VersionedParamPath( + "source_zones", + vartype="member", + path="from", + ) ) params.append( VersionedParamPath( - "source_addresses", default=["any",], vartype="member", path="source" + "source_addresses", + default=[ + "any", + ], + vartype="member", + path="source", ) ) params.append( - VersionedParamPath("negate_source", vartype="yesno", path="negate-source",) + VersionedParamPath( + "negate_source", + vartype="yesno", + path="negate-source", + ) ) params.append( - VersionedParamPath("destination_zones", vartype="member", path="to",) + VersionedParamPath( + "destination_zones", + vartype="member", + path="to", + ) ) params.append( VersionedParamPath( "destination_addresses", - default=["any",], + default=[ + "any", + ], vartype="member", path="destination", ) ) params.append( VersionedParamPath( - "negate_destination", vartype="yesno", path="negate-destination", + "negate_destination", + vartype="yesno", + path="negate-destination", + ) + ) + params.append( + VersionedParamPath( + "tag", + vartype="member", + path="tag", + ) + ) + params.append( + VersionedParamPath( + "disabled", + vartype="yesno", + path="disabled", + ) + ) + params.append( + VersionedParamPath( + "service", + vartype="member", + path="service", + ) + ) + params.append( + VersionedParamPath( + "source_hip", + exclude=True, ) ) - params.append(VersionedParamPath("tag", vartype="member", path="tag",)) - params.append(VersionedParamPath("disabled", vartype="yesno", path="disabled",)) - params.append(VersionedParamPath("service", vartype="member", path="service",)) - params.append(VersionedParamPath("source_hip", exclude=True,)) params[-1].add_profile( - "10.0.0", path="source-hip", vartype="member", + "10.0.0", + path="source-hip", + vartype="member", ) params.append( VersionedParamPath("source_users", vartype="member", path="source-user") ) params.append( - VersionedParamPath("url_categories", vartype="member", path="category",) + VersionedParamPath( + "url_categories", + vartype="member", + path="category", + ) + ) + params.append( + VersionedParamPath( + "group_tag", + exclude=True, + ) ) - params.append(VersionedParamPath("group_tag", exclude=True,)) params[-1].add_profile( - "9.0.0", path="group-tag", + "9.0.0", + path="group-tag", + ) + params.append( + VersionedParamPath( + "authentication_enforcement", + path="authentication-enforcement", + ) ) params.append( VersionedParamPath( - "authentication_enforcement", path="authentication-enforcement", + "timeout", + path="timeout", ) ) - params.append(VersionedParamPath("timeout", path="timeout",)) params.append( VersionedParamPath("negate_target", path="target/negate", vartype="yesno") ) diff --git a/panos/predefined.py b/panos/predefined.py index c522792d..3c8fd28d 100644 --- a/panos/predefined.py +++ b/panos/predefined.py @@ -111,10 +111,20 @@ def _refresh_application(self, name=None): ) def _refresh_service(self, name=None): - return self._refresh([(objects.ServiceObject, "service_objects", None),], name,) + return self._refresh( + [ + (objects.ServiceObject, "service_objects", None), + ], + name, + ) def _refresh_tag(self, name=None): - return self._refresh([(objects.Tag, "tag_objects", None),], name,) + return self._refresh( + [ + (objects.Tag, "tag_objects", None), + ], + name, + ) def refresh_application(self, name): """Refresh a Single Predefined Application diff --git a/panos/userid.py b/panos/userid.py index f8865ed1..4e42580f 100644 --- a/panos/userid.py +++ b/panos/userid.py @@ -718,7 +718,13 @@ def tag_user(self, user, tags, timeout=None, prefix=None): te = entry.find("./tag") break else: - entry = ET.SubElement(ru, "entry", {"user": user,}) + entry = ET.SubElement( + ru, + "entry", + { + "user": user, + }, + ) te = ET.SubElement(entry, "tag") # Now add in the tags with the specified timeout. @@ -761,7 +767,13 @@ def untag_user(self, user, tags=None, prefix=None): if entry.attrib["user"] == user: break else: - entry = ET.SubElement(uu, "entry", {"user": user,}) + entry = ET.SubElement( + uu, + "entry", + { + "user": user, + }, + ) # Do tag removal. te = entry.find("./tag") diff --git a/tests/live/conftest.py b/tests/live/conftest.py index d324367c..8d379d35 100644 --- a/tests/live/conftest.py +++ b/tests/live/conftest.py @@ -122,7 +122,10 @@ def init(): fw = random.choice(fws) panorama_fw_combinations.append( - ((pano, fw), desc(pano_version, fw_version),) + ( + (pano, fw), + desc(pano_version, fw_version), + ) ) diff --git a/tests/live/test_network.py b/tests/live/test_network.py index e62238df..f3f3ba69 100644 --- a/tests/live/test_network.py +++ b/tests/live/test_network.py @@ -6,7 +6,10 @@ class TestZoneBasic(testlib.FwFlow): def setup_state_obj(self, fw, state): - state.obj = network.Zone(testlib.random_name(), mode="layer3",) + state.obj = network.Zone( + testlib.random_name(), + mode="layer3", + ) fw.add(state.obj) def update_state_obj(self, fw, state): @@ -65,7 +68,10 @@ def create_dependencies(self, fw, state): state.parent.create() def setup_state_obj(self, fw, state): - state.obj = network.StaticMac(testlib.random_mac(), state.eths[0],) + state.obj = network.StaticMac( + testlib.random_mac(), + state.eths[0], + ) state.parent.add(state.obj) def update_state_obj(self, fw, state): @@ -102,7 +108,9 @@ def create_dependencies(self, fw, state): def setup_state_obj(self, fw, state): state.obj = network.Vlan( - testlib.random_name(), state.eths[0], state.vlan_interface.uid, + testlib.random_name(), + state.eths[0], + state.vlan_interface.uid, ) fw.add(state.obj) @@ -324,7 +332,9 @@ def create_dependencies(self, fw, state): state.eth = testlib.get_available_interfaces(fw)[0] state.parent = network.EthernetInterface( - state.eth, "layer3", ip=testlib.random_ip("/24"), + state.eth, + "layer3", + ip=testlib.random_ip("/24"), ) fw.add(state.parent) state.parent.create() @@ -368,7 +378,10 @@ def create_dependencies(self, fw, state): state.eth = None state.eth = testlib.get_available_interfaces(fw)[0] - state.parent = network.EthernetInterface(state.eth, "layer2",) + state.parent = network.EthernetInterface( + state.eth, + "layer2", + ) fw.add(state.parent) state.parent.create() @@ -376,7 +389,9 @@ def setup_state_obj(self, fw, state): tag = random.randint(1, 4000) name = "{0}.{1}".format(state.eth, tag) state.obj = network.Layer2Subinterface( - name, tag, comment="This is my L2 subinterface", + name, + tag, + comment="This is my L2 subinterface", ) state.parent.add(state.obj) @@ -861,14 +876,16 @@ def create_dependencies(self, fw, state): if self.WITH_BGP_IMPORT_RULE: state.import_rule = network.BgpPolicyImportRule( - name=testlib.random_name(), enable=True, + name=testlib.random_name(), + enable=True, ) state.bgp.add(state.import_rule) state.bgp.apply() if self.WITH_BGP_EXPORT_RULE: state.export_rule = network.BgpPolicyExportRule( - name=testlib.random_name(), enable=True, + name=testlib.random_name(), + enable=True, ) state.bgp.add(state.export_rule) state.bgp.apply() @@ -1409,7 +1426,9 @@ def setup_state_obj(self, fw, state): # 'match_afi': 'ip', # 'match_safi': 'ip', "match_route_table": "unicast", - "match_nexthop": [testlib.random_ip("/32"),], + "match_nexthop": [ + testlib.random_ip("/32"), + ], "match_from_peer": state.peer.name, "match_med": random.randint(0, 4294967295), "match_as_path_regex": "as-path-regex", @@ -1491,7 +1510,8 @@ class MakeBgpPolicyAddressPrefix(MakeVirtualRouter): def setup_state_obj(self, fw, state): state.obj = network.BgpPolicyAddressPrefix( - name=testlib.random_netmask(), exact=True, + name=testlib.random_netmask(), + exact=True, ) if self.WITH_BGP_IMPORT_RULE: state.import_rule.add(state.obj) @@ -1547,7 +1567,9 @@ def setup_state_obj(self, fw, state): ) advert.extend(prefixes) state.obj = network.BgpPolicyConditionalAdvertisement( - name=testlib.random_name(), enable=True, used_by=state.pg.name, + name=testlib.random_name(), + enable=True, + used_by=state.pg.name, ) state.obj.add(non_exist) state.obj.add(advert) @@ -1654,8 +1676,12 @@ class TestIkeCryptoProfile(testlib.FwFlow): def setup_state_obj(self, fw, state): state.obj = network.IkeCryptoProfile( testlib.random_name(), - authentication=["sha256",], - dh_group=["group1",], + authentication=[ + "sha256", + ], + dh_group=[ + "group1", + ], lifetime_minutes=42, ) fw.add(state.obj) @@ -1741,7 +1767,8 @@ def create_dependencies(self, fw, state): raise ValueError("IkeGateway not supported for version < 7.0") state.lbi = network.LoopbackInterface( - "loopback.{0}".format(random.randint(5, 20)), ipv6_enabled=True, + "loopback.{0}".format(random.randint(5, 20)), + ipv6_enabled=True, ) state.lbi.add(network.IPv6Address(testlib.random_ipv6())) state.lbi.add(network.IPv6Address(testlib.random_ipv6())) diff --git a/tests/live/test_objects.py b/tests/live/test_objects.py index c0bd5993..daa4dad9 100644 --- a/tests/live/test_objects.py +++ b/tests/live/test_objects.py @@ -29,7 +29,8 @@ def create_dependencies(self, dev, state): def setup_state_obj(self, dev, state): state.obj = objects.AddressGroup( - testlib.random_name(), [x.name for x in state.aos[:2]], + testlib.random_name(), + [x.name for x in state.aos[:2]], ) dev.add(state.obj) @@ -71,7 +72,8 @@ def setup_state_obj(self, dev, state): def update_state_obj(self, dev, state): state.obj.dynamic_value = "'{0}' and '{1}'".format( - state.tags[2].name, state.tags[3].name, + state.tags[2].name, + state.tags[3].name, ) state.obj.tag = state.tags[1].name @@ -86,7 +88,9 @@ def cleanup_dependencies(self, dev, state): class TestTag(testlib.DevFlow): def setup_state_obj(self, dev, state): state.obj = objects.Tag( - testlib.random_name(), color="color1", comments="My new tag", + testlib.random_name(), + color="color1", + comments="My new tag", ) dev.add(state.obj) diff --git a/tests/live/test_userid.py b/tests/live/test_userid.py index ead99456..7e2adc5a 100644 --- a/tests/live/test_userid.py +++ b/tests/live/test_userid.py @@ -67,7 +67,11 @@ def test_08_get_registered_ip(self, fw, state_map): test4 = set(fw.userid.get_registered_ip(ips, tags[0:5])) assert test4 == set(ips) test5 = set(fw.userid.get_registered_ip(ips[0], tags[0])) - assert test5 == set([ips[0],]) + assert test5 == set( + [ + ips[0], + ] + ) tests = [test1, test2, test3, test4, test5] assert len(test5) != 0 assert all([test1 >= x for x in tests]) diff --git a/tests/live/testlib.py b/tests/live/testlib.py index 3a23f20b..9138ea33 100644 --- a/tests/live/testlib.py +++ b/tests/live/testlib.py @@ -21,7 +21,9 @@ def random_ip(netmask=None): def random_netmask(): return "{0}.{1}.{2}.0/24".format( - random.randint(11, 150), random.randint(1, 200), random.randint(1, 200), + random.randint(11, 150), + random.randint(1, 200), + random.randint(1, 200), ) diff --git a/tests/test_base.py b/tests/test_base.py index 2ff5907b..c4fc911d 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -83,7 +83,13 @@ def test_add_without_children(self): ret_value = self.obj.add(child) self.assertEqual(child, ret_value) - self.verify_object(self.obj, name=OBJECT_NAME, children=[child,]) + self.verify_object( + self.obj, + name=OBJECT_NAME, + children=[ + child, + ], + ) self.verify_object(child, name=CHILD_NAME, parent=self.obj) def test_add_with_children(self): @@ -112,7 +118,13 @@ def test_insert_without_children(self): ret_val = self.obj.insert(0, child) self.assertEqual(child, ret_val) - self.verify_object(self.obj, name=OBJECT_NAME, children=[child,]) + self.verify_object( + self.obj, + name=OBJECT_NAME, + children=[ + child, + ], + ) self.verify_object(child, name=CHILD_NAME, parent=self.obj) def test_insert_with_children(self): @@ -214,7 +226,13 @@ def test_remove(self): ret_val = self.obj.remove(child2) self.assertIsNone(ret_val) - self.verify_object(self.obj, name=OBJECT_NAME, children=[child1,]) + self.verify_object( + self.obj, + name=OBJECT_NAME, + children=[ + child1, + ], + ) self.verify_object(child1, name=CHILD1_NAME, parent=self.obj) self.verify_object(child2, name=CHILD2_NAME) @@ -454,7 +472,9 @@ def test_apply_with_ha_sync(self, m_uid): self.assertIsNone(ret_val) m_panos.set_config_changed.assert_called_once_with() m_panos.active().xapi.edit.assert_called_once_with( - PanDeviceXpath, PanDeviceElementStr, retry_on_peer=self.obj.HA_SYNC, + PanDeviceXpath, + PanDeviceElementStr, + retry_on_peer=self.obj.HA_SYNC, ) self.obj.xpath.assert_called_once_with() self.obj.element_str.assert_called_once_with() @@ -486,7 +506,9 @@ def test_apply_without_ha_sync(self, m_uid): self.assertIsNone(ret_val) m_panos.set_config_changed.assert_called_once_with() m_panos.xapi.edit.assert_called_once_with( - PanDeviceXpath, PanDeviceElementStr, retry_on_peer=self.obj.HA_SYNC, + PanDeviceXpath, + PanDeviceElementStr, + retry_on_peer=self.obj.HA_SYNC, ) self.obj.xpath.assert_called_once_with() self.obj.element_str.assert_called_once_with() @@ -516,7 +538,9 @@ def test_create_with_ha_sync(self, m_uid): self.assertIsNone(ret_val) m_panos.set_config_changed.assert_called_once_with() m_panos.active().xapi.set.assert_called_once_with( - PanDeviceXpath, PanDeviceElementStr, retry_on_peer=self.obj.HA_SYNC, + PanDeviceXpath, + PanDeviceElementStr, + retry_on_peer=self.obj.HA_SYNC, ) self.obj.xpath_short.assert_called_once_with() self.obj.element_str.assert_called_once_with() @@ -548,7 +572,9 @@ def test_create_without_ha_sync(self, m_uid): self.assertIsNone(ret_val) m_panos.set_config_changed.assert_called_once_with() m_panos.xapi.set.assert_called_once_with( - PanDeviceXpath, PanDeviceElementStr, retry_on_peer=self.obj.HA_SYNC, + PanDeviceXpath, + PanDeviceElementStr, + retry_on_peer=self.obj.HA_SYNC, ) self.obj.xpath_short.assert_called_once_with() self.obj.element_str.assert_called_once_with() @@ -576,7 +602,8 @@ def test_delete_with_ha_sync_no_parent(self, m_uid): self.assertIsNone(ret_val) m_panos.set_config_changed.assert_called_once_with() m_panos.active().xapi.delete.assert_called_once_with( - PanDeviceXpath, retry_on_peer=self.obj.HA_SYNC, + PanDeviceXpath, + retry_on_peer=self.obj.HA_SYNC, ) self.obj.xpath.assert_called_once_with() for c in self.obj.children: @@ -606,7 +633,8 @@ def test_delete_with_ha_sync_and_parent(self, m_uid): self.obj.parent.remove.assert_called_once_with(self.obj) m_panos.set_config_changed.assert_called_once_with() m_panos.active().xapi.delete.assert_called_once_with( - PanDeviceXpath, retry_on_peer=self.obj.HA_SYNC, + PanDeviceXpath, + retry_on_peer=self.obj.HA_SYNC, ) self.obj.xpath.assert_called_once_with() for c in self.obj.children: @@ -1151,7 +1179,8 @@ def test_no_fallback_raises_value_error(self): parent = None obj = Base.ParentAwareXpath() obj.add_profile( - parents=("ParentClass1",), value="/some/path", + parents=("ParentClass1",), + value="/some/path", ) self.assertRaises(ValueError, obj._get_versioned_value, (1, 0, 0), parent) @@ -1279,7 +1308,14 @@ def test_values_are_unchanged_after_comparison(self): self.assertEqual(o2.members, ["d", "c"]) def test_str_list_field_is_equal(self): - o1 = MyVersionedObject("a", ["a",], ["c", "d"], 5) + o1 = MyVersionedObject( + "a", + [ + "a", + ], + ["c", "d"], + 5, + ) o2 = MyVersionedObject("a", "a", ["c", "d"], 5) self.assertTrue(o1.equal(o2)) diff --git a/tests/test_device_profile_xpaths.py b/tests/test_device_profile_xpaths.py index 87a14424..05bcc01a 100644 --- a/tests/test_device_profile_xpaths.py +++ b/tests/test_device_profile_xpaths.py @@ -60,9 +60,18 @@ OBJECTS = { SnmpServerProfile: [None, SnmpV2cServer, SnmpV3Server], - EmailServerProfile: [None, EmailServer,], - LdapServerProfile: [None, LdapServer,], - SyslogServerProfile: [None, SyslogServer,], + EmailServerProfile: [ + None, + EmailServer, + ], + LdapServerProfile: [ + None, + LdapServer, + ], + SyslogServerProfile: [ + None, + SyslogServer, + ], HttpServerProfile: [ None, HttpServer, diff --git a/tests/test_firewall.py b/tests/test_firewall.py index fa6d1162..e883dcb0 100644 --- a/tests/test_firewall.py +++ b/tests/test_firewall.py @@ -22,7 +22,9 @@ class TestFirewall(unittest.TestCase): def test_id_returns_serial(self): expected = "serial#" - fw = panos.firewall.Firewall(serial=expected,) + fw = panos.firewall.Firewall( + serial=expected, + ) ret_val = fw.id @@ -31,7 +33,9 @@ def test_id_returns_serial(self): def test_id_returns_hostname(self): expected = "hostName" - fw = panos.firewall.Firewall(hostname=expected,) + fw = panos.firewall.Firewall( + hostname=expected, + ) ret_val = fw.id diff --git a/tests/test_init.py b/tests/test_init.py index 722ae38d..00ea2e16 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -177,7 +177,8 @@ def test_base_is_single_key_value(self): for x in self.quotes(): self.assertEqual( - panos.string_to_xml("hello {0}world{0}".format(x), x), self._str(root), + panos.string_to_xml("hello {0}world{0}".format(x), x), + self._str(root), ) def test_base_root_with_one_key_value(self): @@ -187,7 +188,8 @@ def test_base_root_with_one_key_value(self): for x in self.quotes(): self.assertEqual( - panos.string_to_xml("foo bar {0}baz{0}".format(x), x), self._str(root), + panos.string_to_xml("foo bar {0}baz{0}".format(x), x), + self._str(root), ) def test_base_root_with_two_key_values(self): diff --git a/tests/test_integration.py b/tests/test_integration.py index 654de5c3..3dabf0e2 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -89,11 +89,26 @@ def setUp(self): self.assertEqual(self.firewall, self.address_object.parent) self.assertEqual([], self.address_object.children) self.assertEqual(self.device_group, self.firewall.parent) - self.assertEqual([self.address_object,], self.firewall.children) + self.assertEqual( + [ + self.address_object, + ], + self.firewall.children, + ) self.assertEqual(self.panorama, self.device_group.parent) - self.assertEqual([self.firewall,], self.device_group.children) + self.assertEqual( + [ + self.firewall, + ], + self.device_group.children, + ) self.assertEqual(None, self.panorama.parent) - self.assertEqual([self.device_group,], self.panorama.children) + self.assertEqual( + [ + self.device_group, + ], + self.panorama.children, + ) def test_nearest_pandevice_from_addressobject_in_pano_dg_fw_ao_chain(self): """Runs nearest_pandevice() on the AddressObject. @@ -325,7 +340,10 @@ def test_element_str_from_ethernetinterface_for_aggregate_group(self): def test_element_str_from_firewall_with_pano_parent_and_systemsettings_child(self): expected = b"".join( - [b'', b'',] + [ + b'', + b'', + ] ) fw = panos.firewall.Firewall( @@ -357,7 +375,10 @@ def test_element_str_from_firewall_without_serial_number_raises_error(self): def test_element_str_from_firewall_with_dg_pano_parents_and_multi_vsys(self): expected = b"".join( - [b'', b"",] + [ + b'', + b"", + ] ) fw = panos.firewall.Firewall( @@ -615,7 +636,11 @@ def test_set_xpath_from_arp_with_l3s_ei_fw_parents(self): def test_edit_xpath_from_firewall(self): # This is not a valid xpath, but its what should happen # if there is no parent - expected = "".join(["/devices/entry[@name='serial']",]) + expected = "".join( + [ + "/devices/entry[@name='serial']", + ] + ) fw = panos.firewall.Firewall("foo", vsys="vsys2", serial="serial") @@ -626,7 +651,11 @@ def test_edit_xpath_from_firewall(self): def test_set_xpath_from_firewall(self): # This is not a valid xpath, but its what should happen # if there is no parent - expected = "".join(["/devices",]) + expected = "".join( + [ + "/devices", + ] + ) fw = panos.firewall.Firewall("foo", vsys="vsys2", serial="serial") diff --git a/tests/test_opstate.py b/tests/test_opstate.py index f99d3276..bf579e2f 100644 --- a/tests/test_opstate.py +++ b/tests/test_opstate.py @@ -48,7 +48,9 @@ def _hit_count_fw_setup(*args): inner = "".join(ET.tostring(x, encoding="utf-8").decode("utf-8") for x in args) fw.op = mock.Mock( - return_value=ET.fromstring(HIT_COUNT_PREFIX + inner + HIT_COUNT_SUFFIX,) + return_value=ET.fromstring( + HIT_COUNT_PREFIX + inner + HIT_COUNT_SUFFIX, + ) ) rb = Rulebase() diff --git a/tests/test_params.py b/tests/test_params.py index 4073ae2e..e2231514 100644 --- a/tests/test_params.py +++ b/tests/test_params.py @@ -17,22 +17,74 @@ def _setup(self): params = [] - params.append(VersionedParamPath("uuid", vartype="attrib", path="uuid",),) - params.append(VersionedParamPath("size", vartype="int", path="size",),) - params.append(VersionedParamPath("listing", vartype="member", path="listing",),) - params.append(VersionedParamPath("pb1", vartype="exist", path="pb1",),) - params.append(VersionedParamPath("pb2", vartype="exist", path="pb2",),) - params.append(VersionedParamPath("live", vartype="yesno", path="live",),) params.append( - VersionedParamPath("disabled", vartype="yesno", path="disabled",), + VersionedParamPath( + "uuid", + vartype="attrib", + path="uuid", + ), + ) + params.append( + VersionedParamPath( + "size", + vartype="int", + path="size", + ), + ) + params.append( + VersionedParamPath( + "listing", + vartype="member", + path="listing", + ), + ) + params.append( + VersionedParamPath( + "pb1", + vartype="exist", + path="pb1", + ), + ) + params.append( + VersionedParamPath( + "pb2", + vartype="exist", + path="pb2", + ), + ) + params.append( + VersionedParamPath( + "live", + vartype="yesno", + path="live", + ), + ) + params.append( + VersionedParamPath( + "disabled", + vartype="yesno", + path="disabled", + ), + ) + params.append( + VersionedParamPath( + "uuid2", + vartype="attrib", + path="level-2/uuid", + ), ) params.append( - VersionedParamPath("uuid2", vartype="attrib", path="level-2/uuid",), + VersionedParamPath( + "age", + vartype="int", + path="level-2/age", + ), ) - params.append(VersionedParamPath("age", vartype="int", path="level-2/age",),) params.append( VersionedParamPath( - "interfaces", vartype="member", path="level-2/interface", + "interfaces", + vartype="member", + path="level-2/interface", ), ) @@ -84,7 +136,8 @@ def _refresh_xml(): # int at base level def test_render_int(): _verify_render( - FakeObject("test", size=5), '5', + FakeObject("test", size=5), + '5', ) @@ -111,7 +164,8 @@ def test_parse_member(): # exist at base level def test_render_exist(): _verify_render( - FakeObject("test", pb1=True), '', + FakeObject("test", pb1=True), + '', ) @@ -139,7 +193,8 @@ def test_parse_yesno(): # attrib def test_render_attrib(): _verify_render( - FakeObject("test", uuid="123-456"), '', + FakeObject("test", uuid="123-456"), + '', ) diff --git a/tests/test_predefined.py b/tests/test_predefined.py index 9ea6eded..1a1b913a 100644 --- a/tests/test_predefined.py +++ b/tests/test_predefined.py @@ -45,9 +45,13 @@ ( """//*[contains(local-name(), "application")]/entry[@name='{0}']""", '//*[contains(local-name(), "application")]/entry', - ApplicationContainer(name="ap container 1", applications=["func1", "func2"],), ApplicationContainer( - name="application container deux", applications=["a", "la", "mode"], + name="ap container 1", + applications=["func1", "func2"], + ), + ApplicationContainer( + name="application container deux", + applications=["a", "la", "mode"], ), ), ( @@ -97,8 +101,16 @@ ( None, "/tag/entry", - Tag(name="foo", color="color1", comments="First color",), - Tag(name="bar", color="color42", comments="Another color for another time",), + Tag( + name="foo", + color="color1", + comments="First color", + ), + Tag( + name="bar", + color="color42", + comments="Another color for another time", + ), ), ) @@ -142,7 +154,11 @@ def _fw(*args): prefix = "" suffix = "" inner = "".join(x.element_str().decode("utf-8") for x in args) - fw.xapi.get = mock.Mock(return_value=ET.fromstring(prefix + inner + suffix,)) + fw.xapi.get = mock.Mock( + return_value=ET.fromstring( + prefix + inner + suffix, + ) + ) return fw diff --git a/tests/test_userid.py b/tests/test_userid.py index 0f4af6a1..a3a2052a 100644 --- a/tests/test_userid.py +++ b/tests/test_userid.py @@ -67,8 +67,18 @@ def test_batch_tag_user(self): ) fw.xapi fw.userid.batch_start() - fw.userid.tag_user("user1", ["tag1",]) - fw.userid.tag_user("user2", ["tag1",]) + fw.userid.tag_user( + "user1", + [ + "tag1", + ], + ) + fw.userid.tag_user( + "user2", + [ + "tag1", + ], + ) def test_batch_untag_user(self): fw = panos.firewall.Firewall( @@ -76,8 +86,18 @@ def test_batch_untag_user(self): ) fw.xapi fw.userid.batch_start() - fw.userid.untag_user("user1", ["tag1",]) - fw.userid.untag_user("user2", ["tag1",]) + fw.userid.untag_user( + "user1", + [ + "tag1", + ], + ) + fw.userid.untag_user( + "user2", + [ + "tag1", + ], + ) if __name__ == "__main__": diff --git a/tests/test_versioning.py b/tests/test_versioning.py index 317df1b5..b498fffb 100644 --- a/tests/test_versioning.py +++ b/tests/test_versioning.py @@ -39,7 +39,8 @@ def test_empty_objects_are_equal(self): raise unittest.SkipTest("OLD_CLS does not have element_str()") self.assertEqual( - old.element_str(), new.element_str(), + old.element_str(), + new.element_str(), ) def test_positionally_populated_objects_are_equal(self): @@ -56,7 +57,8 @@ def test_positionally_populated_objects_are_equal(self): raise unittest.SkipTest("OLD_CLS does not have element_str()") self.assertEqual( - old.element_str(), new.element_str(), + old.element_str(), + new.element_str(), ) def test_keyword_populated_objects_are_equal(self): @@ -73,7 +75,8 @@ def test_keyword_populated_objects_are_equal(self): raise unittest.SkipTest("OLD_CLS does not have element_str()") self.assertEqual( - old.element_str(), new.element_str(), + old.element_str(), + new.element_str(), ) def test_parsing_old_elmstring_works(self): From 3198b58f9e3795d4544ca5190a074cf9efdbaf62 Mon Sep 17 00:00:00 2001 From: alexortize Date: Mon, 8 Aug 2022 16:48:28 -0700 Subject: [PATCH 10/14] Fixed UrlFilteringProfile mode Fixed UrlFilteringProfile mode --- panos/objects.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/panos/objects.py b/panos/objects.py index 61a5bdd1..b7474c3b 100644 --- a/panos/objects.py +++ b/panos/objects.py @@ -1379,13 +1379,12 @@ def _setup(self): params.append(VersionedParamPath("override", path="override", vartype="member")) - params.append(VersionedParamPath("mode", path="{type}")) params.append( VersionedParamPath( - "type", + "mode", values=["disabled", "ip-user", "domain-credentials"], default="disabled", - path="credential-enforcement/mode/{type}", + path="credential-enforcement/mode/{mode}", ) ) From 15c30d86c4f53fffeb4ce1546f3200b983df3cf7 Mon Sep 17 00:00:00 2001 From: alexortize Date: Mon, 8 Aug 2022 17:05:31 -0700 Subject: [PATCH 11/14] Updated object description Updated description --- panos/objects.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panos/objects.py b/panos/objects.py index b7474c3b..4126f2bc 100644 --- a/panos/objects.py +++ b/panos/objects.py @@ -1329,7 +1329,7 @@ def _setup(self): class UrlFilteringProfile(VersionedPanObject): - """Administrator object + """UrlFilteringProfile object Args: name (str): URL-Filtering name From 2fc76dd4f11af95d31efa71ea6811eb9c9976ced Mon Sep 17 00:00:00 2001 From: alexortize Date: Tue, 9 Aug 2022 12:15:55 -0700 Subject: [PATCH 12/14] Added objects missing for URLFilteringProfile Added objects missing for URLFilteringProfile --- panos/objects.py | 139 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) diff --git a/panos/objects.py b/panos/objects.py index 4126f2bc..cf007a71 100644 --- a/panos/objects.py +++ b/panos/objects.py @@ -1328,6 +1328,90 @@ def _setup(self): self._params = tuple(params) +class HTTPHeaderInsertionHeaders(VersionedPanObject): + """HTTPHeaderInsertionHeaders object + + Args: + name (str): HTTP Insertion header name + header (str): Header key to be inserted + value (str): Header value to be inserted + log (bool): Enable log + + """ + + ROOT = Root.VSYS + SUFFIX = ENTRY + + def _setup(self): + # xpaths + self._xpaths.add_profile(value="/headers") + + # params + params = [] + + params.append(VersionedParamPath("header", vartype="string", path="/header")) + + params.append(VersionedParamPath("value", vartype="string", path="/value")) + + params.append(VersionedParamPath("log", vartype="yesno", path="/log")) + + self._params = tuple(params) + + +class HTTPHeaderInsertionType(VersionedPanObject): + """HTTPHeaderInsertionType object + + Args: + name (str): HTTP Header Insertion Type name + domains (list): List of domains + + """ + + ROOT = Root.VSYS + SUFFIX = ENTRY + CHILDTYPES = ("objects.HTTPHeaderInsertionHeaders",) + + def _setup(self): + # xpaths + self._xpaths.add_profile(value="/type") + + # params + params = [] + + params.append(VersionedParamPath("domains", vartype="member", path="/domains")) + + self._params = tuple(params) + + +class HTTPHeaderInsertion(VersionedPanObject): + """HTTPHeaderInsertion object + + Args: + name (str): HTTP Header Insertion name + disable_override (bool): Disable override + + """ + + ROOT = Root.VSYS + SUFFIX = ENTRY + CHILDTYPES = ("objects.HTTPHeaderInsertionType",) + + def _setup(self): + # xpaths + self._xpaths.add_profile(value="/http-header-insertion") + + # params + params = [] + + params.append( + VersionedParamPath( + "disable_override", vartype="yesno", path="/disable-override" + ) + ) + + self._params = tuple(params) + + class UrlFilteringProfile(VersionedPanObject): """UrlFilteringProfile object @@ -1348,11 +1432,18 @@ class UrlFilteringProfile(VersionedPanObject): ce_alert (list): Credential enforcement alert categories ce_block (list): Credential enforcement block categories ce_continue (list): Credential enforcement continue categories + enable_container_page (bool): Enable container page + log_container_page_only (bool): Log container page only + safe_search_enforcement (bool): Safe search enforcement + log_http_hdr_xff (bool): Log HTTP HDR XFF + log_http_hdr_user_agent (bool): Log HTTP HDR User-Agent + log_http_hdr_referer (bool): Log HTTP HDR Referer """ ROOT = Root.VSYS SUFFIX = ENTRY + CHILDTYPES = ("objects.HTTPHeaderInsertion",) def _setup(self): # xpaths @@ -1437,4 +1528,52 @@ def _setup(self): ) ) + params.append( + VersionedParamPath( + "enable_container_page", + path="enable-container-page", + vartype="yesno", + ) + ) + + params.append( + VersionedParamPath( + "log_container_page_only", + path="log-container-page-only", + vartype="yesno", + ) + ) + + params.append( + VersionedParamPath( + "safe_search_enforcement", + path="safe-search-enforcement", + vartype="yesno", + ) + ) + + params.append( + VersionedParamPath( + "log_http_hdr_xff", + path="log-http-hdr-xff", + vartype="yesno", + ) + ) + + params.append( + VersionedParamPath( + "log_http_hdr_user_agent", + path="log-http-hdr-user-agent", + vartype="yesno", + ) + ) + + params.append( + VersionedParamPath( + "log_http_hdr_referer", + path="log-http-hdr-referer", + vartype="yesno", + ) + ) + self._params = tuple(params) From 1b4a39e03161db42e9947780628d516060300cac Mon Sep 17 00:00:00 2001 From: alexortize Date: Tue, 9 Aug 2022 12:46:07 -0700 Subject: [PATCH 13/14] Renamed object varible related to credential enforcement Renamed object varible related to credential enforcement --- panos/objects.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/panos/objects.py b/panos/objects.py index cf007a71..e62126c9 100644 --- a/panos/objects.py +++ b/panos/objects.py @@ -1428,10 +1428,10 @@ class UrlFilteringProfile(VersionedPanObject): "ip-user", "domain-credentials". Default value is "disabled". group_mapping (str): Group mapping used log_severity (str): Log severity. Default value is "medium" - ce_allow (list): Credential enforcement allow categories - ce_alert (list): Credential enforcement alert categories - ce_block (list): Credential enforcement block categories - ce_continue (list): Credential enforcement continue categories + credential_enforcement_allow (list): Credential enforcement allow categories + credential_enforcement_alert (list): Credential enforcement alert categories + credential_enforcement_block (list): Credential enforcement block categories + credential_enforcement_continue (list): Credential enforcement continue categories enable_container_page (bool): Enable container page log_container_page_only (bool): Log container page only safe_search_enforcement (bool): Safe search enforcement @@ -1498,7 +1498,7 @@ def _setup(self): params.append( VersionedParamPath( - "ce_allow", + "credential_enforcement_allow", path="credential-enforcement/allow", vartype="member", ) @@ -1506,7 +1506,7 @@ def _setup(self): params.append( VersionedParamPath( - "ce_alert", + "credential_enforcement_alert", path="credential-enforcement/alert", vartype="member", ) @@ -1514,7 +1514,7 @@ def _setup(self): params.append( VersionedParamPath( - "ce_block", + "credential_enforcement_block", path="credential-enforcement/block", vartype="member", ) @@ -1522,7 +1522,7 @@ def _setup(self): params.append( VersionedParamPath( - "ce_continue", + "credential_enforcement_continue", path="credential-enforcement/continue", vartype="member", ) From b7abe21d32934304bb77449850a0f500d7eab637 Mon Sep 17 00:00:00 2001 From: alexortize Date: Thu, 18 Aug 2022 10:21:59 -0700 Subject: [PATCH 14/14] Renamed properties to stop conflict with continue keyword --- panos/objects.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/panos/objects.py b/panos/objects.py index e62126c9..b5cc3706 100644 --- a/panos/objects.py +++ b/panos/objects.py @@ -1454,9 +1454,9 @@ def _setup(self): params.append(VersionedParamPath("description", path="description")) - params.append(VersionedParamPath("allow", path="allow", vartype="member")) + params.append(VersionedParamPath("action_allow", path="allow", vartype="member")) - params.append(VersionedParamPath("alert", path="alert", vartype="member")) + params.append(VersionedParamPath("action_alert", path="alert", vartype="member")) params.append( VersionedParamPath( @@ -1464,9 +1464,9 @@ def _setup(self): ) ) - params.append(VersionedParamPath("block", path="block", vartype="member")) + params.append(VersionedParamPath("action_block", path="block", vartype="member")) - params.append(VersionedParamPath("continue", path="continue", vartype="member")) + params.append(VersionedParamPath("action_continue", path="continue", vartype="member")) params.append(VersionedParamPath("override", path="override", vartype="member"))