Skip to content

Commit 6b091b9

Browse files
committed
Merge branch 'release/0.3.5'
2 parents a896a3a + 2074ac3 commit 6b091b9

File tree

10 files changed

+114
-72
lines changed

10 files changed

+114
-72
lines changed

HISTORY.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@
33
History
44
=======
55

6+
0.3.5
7+
-----
8+
9+
Released: 2016-07-25
10+
11+
Status: Alpha
12+
13+
Bug fixes and documentation updates
14+
615
0.3.4
716
-----
817

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ device API that is object oriented and conceptually similar to interaction
88
with the device via the GUI or CLI.
99

1010
* Free software: ISC License
11-
* Documentation: http://pandevice.readthedocs.org.
11+
* Documentation: http://pandevice.readthedocs.org
1212

1313
-----
1414

pandevice/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
__author__ = 'Brian Torres-Gil'
2626
__email__ = '[email protected]'
27-
__version__ = '0.3.4'
27+
__version__ = '0.3.5'
2828

2929

3030
import logging

pandevice/base.py

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ def __init__(self, *args, **kwargs):
8080
variables = kwargs.pop("variables", None)
8181
if variables is None:
8282
variables = type(self).variables()
83+
# Sort the variables by order
84+
variables = sorted(variables, key=lambda x: x.order)
8385
for idx, var in enumerate(variables):
8486
varname = var.variable
8587
try:
@@ -101,6 +103,9 @@ def __init__(self, *args, **kwargs):
101103
def __str__(self):
102104
return str(getattr(self, self.NAME, None))
103105

106+
def __repr__(self):
107+
return "<%s %s at 0x%x>" % (type(self).__name__, repr(getattr(self, self.NAME, None)), id(self))
108+
104109
@classmethod
105110
def variables(cls):
106111
"""Defines the variables that exist in this object. Override in each subclass."""
@@ -370,7 +375,7 @@ def element(self):
370375
continue
371376
# Create an element containing the value in the instance variable
372377
if var.vartype == "member":
373-
for member in value:
378+
for member in pandevice.string_or_list(value):
374379
ET.SubElement(nextelement, 'member').text = str(member)
375380
elif var.vartype == "entry":
376381
try:
@@ -459,7 +464,7 @@ def apply(self):
459464
460465
"""
461466
pandevice = self.pandevice()
462-
logger.debug(pandevice.hostname + ": apply called on %s object \"%s\"" % (type(self), getattr(self, self.NAME)))
467+
logger.debug(pandevice.id + ": apply called on %s object \"%s\"" % (type(self), getattr(self, self.NAME)))
463468
pandevice.set_config_changed()
464469
if self.HA_SYNC:
465470
pandevice.active().xapi.edit(self.xpath(), self.element_str(), retry_on_peer=self.HA_SYNC)
@@ -480,7 +485,7 @@ def create(self):
480485
481486
"""
482487
pandevice = self.pandevice()
483-
logger.debug(pandevice.hostname + ": create called on %s object \"%s\"" % (type(self), getattr(self, self.NAME)))
488+
logger.debug(pandevice.id + ": create called on %s object \"%s\"" % (type(self), getattr(self, self.NAME)))
484489
pandevice.set_config_changed()
485490
element = self.element_str()
486491
if self.HA_SYNC:
@@ -497,7 +502,7 @@ def delete(self):
497502
498503
"""
499504
pandevice = self.pandevice()
500-
logger.debug(pandevice.hostname + ": delete called on %s object \"%s\"" % (type(self), getattr(self, self.NAME)))
505+
logger.debug(pandevice.id + ": delete called on %s object \"%s\"" % (type(self), getattr(self, self.NAME)))
501506
pandevice.set_config_changed()
502507
for child in self.children:
503508
child._check_child_methods("delete")
@@ -520,11 +525,10 @@ def update(self, variable):
520525
variable (str): The name of an instance variable to update on the device
521526
522527
"""
523-
import ha
524-
pandevice = self.pandevice()
525-
logger.debug(pandevice.hostname + ": update called on %s object \"%s\" and variable \"%s\"" %
528+
pan_device = self.pandevice()
529+
logger.debug(pan_device.id + ": update called on %s object \"%s\" and variable \"%s\"" %
526530
(type(self), getattr(self, self.NAME), variable))
527-
pandevice.set_config_changed()
531+
pan_device.set_config_changed()
528532
variables = type(self).variables()
529533
value = getattr(self, variable)
530534
# Get the requested variable from the class' variables tuple
@@ -562,19 +566,19 @@ def update(self, variable):
562566
# Not an 'entry' variable
563567
varpath = re.sub(regex, getattr(self, matchedvar.variable), varpath)
564568
if value is None:
565-
pandevice.xapi.delete(self.xpath() + "/" + varpath, retry_on_peer=self.HA_SYNC)
569+
pan_device.xapi.delete(self.xpath() + "/" + varpath, retry_on_peer=self.HA_SYNC)
566570
else:
567571
element_tag = varpath.split("/")[-1]
568572
element = ET.Element(element_tag)
569573
if var.vartype == "member":
570-
for member in value:
574+
for member in pandevice.string_or_list(value):
571575
ET.SubElement(element, 'member').text = str(member)
572576
xpath = self.xpath() + "/" + varpath
573577
else:
574578
# Regular text variables
575579
element.text = value
576580
xpath = self.xpath() + "/" + varpath
577-
pandevice.xapi.edit(xpath, ET.tostring(element), retry_on_peer=self.HA_SYNC)
581+
pan_device.xapi.edit(xpath, ET.tostring(element), retry_on_peer=self.HA_SYNC)
578582

579583
def refresh(self, running_config=False, xml=None, refresh_children=True, exceptions=True):
580584
"""Refresh all variables and child objects from the device
@@ -589,7 +593,7 @@ def refresh(self, running_config=False, xml=None, refresh_children=True, excepti
589593
# Get the root of the xml to parse
590594
if xml is None:
591595
pandevice = self.pandevice()
592-
logger.debug(pandevice.hostname + ": refresh called on %s object \"%s\"" % (type(self), getattr(self, self.NAME)))
596+
logger.debug(pandevice.id + ": refresh called on %s object \"%s\"" % (type(self), getattr(self, self.NAME)))
593597
if running_config:
594598
api_action = pandevice.xapi.show
595599
else:
@@ -647,7 +651,7 @@ def refresh_variable(self, variable, running_config=False, xml=None, exceptions=
647651
raise err.PanDeviceError("Variable %s does not exist in variable tuple" % variable)
648652
if xml is None:
649653
pandevice = self.pandevice()
650-
logger.debug(pandevice.hostname + ": refresh_variable called on %s object \"%s\" with variable %s" % (type(self), getattr(self, self.NAME), variable))
654+
logger.debug(pandevice.id + ": refresh_variable called on %s object \"%s\" with variable %s" % (type(self), getattr(self, self.NAME), variable))
651655
if running_config:
652656
api_action = pandevice.xapi.show
653657
else:
@@ -725,7 +729,7 @@ def _refresh_children(self, running_config=False, xml=None):
725729
def refresh_xml(self, running_config=False, refresh_children=True, exceptions=True):
726730
# Get the root of the xml to parse
727731
pandevice = self.pandevice()
728-
logger.debug(pandevice.hostname + ": refresh_xml called on %s object \"%s\"" % (type(self), getattr(self, self.NAME)))
732+
logger.debug(pandevice.id + ": refresh_xml called on %s object \"%s\"" % (type(self), getattr(self, self.NAME)))
729733
if running_config:
730734
api_action = pandevice.xapi.show
731735
else:
@@ -905,7 +909,7 @@ def find_index(cls, list_of_panobjects, name, class_type=None):
905909
@classmethod
906910
def applyall(cls, parent):
907911
pandevice = parent.pandevice()
908-
logger.debug(pandevice.hostname + ": applyall called on %s type" % cls)
912+
logger.debug(pandevice.id + ": applyall called on %s type" % cls)
909913
objects = parent.findall(cls)
910914
if not objects:
911915
return
@@ -960,7 +964,7 @@ class for each item this class represents in the xml config. For example,
960964
else:
961965
pandevice = parent.pandevice()
962966
parent_xpath = parent.xpath()
963-
logger.debug(pandevice.hostname + ": refreshall called on %s type" % cls)
967+
logger.debug(pandevice.id + ": refreshall called on %s type" % cls)
964968
if running_config:
965969
api_action = pandevice.xapi.show
966970
else:
@@ -1181,14 +1185,21 @@ class VarPath(object):
11811185
xmldefault (bool): The default value if no value exists in the xml from a device
11821186
condition (str): In the format othervariable:value where this variable is only
11831187
considered if othervariable equals value
1188+
order (int): The order of this variable relative to other variables in this constructor of the
1189+
class that contains this variables. Defaults to 100, set variable order to less than or
1190+
greater than 100 to alter the order of the variables.
11841191
"""
1185-
def __init__(self, path, variable=None, vartype=None, default=None, xmldefault=None, condition=None):
1192+
def __init__(self, path, variable=None, vartype=None, default=None, xmldefault=None, condition=None, order=100):
11861193
self.path = path
11871194
self._variable = variable
11881195
self.vartype = vartype
11891196
self.default = default
11901197
self.xmldefault = xmldefault
11911198
self.condition = condition
1199+
self.order = order
1200+
1201+
def __repr__(self):
1202+
return "<%s %s at 0x%x>" % (type(self).__name__, repr(self.variable), id(self))
11921203

11931204
@property
11941205
def variable(self):
@@ -1551,7 +1562,7 @@ def method(self, *args, **kwargs):
15511562
new_active = self.pan_device.set_failed()
15521563
if retry_on_peer and new_active is not None:
15531564
logger.debug("Connection to device '%s' failed, using HA peer '%s'" %
1554-
(self.pan_device.hostname, new_active.hostname))
1565+
(self.pan_device.id, new_active.hostname))
15551566
# The active failed, apply on passive (which is now active)
15561567
kwargs["retry_on_peer"] = False
15571568
getattr(new_active.xapi, super_method_name)(*args, **kwargs)
@@ -1619,6 +1630,10 @@ def classify_exception(self, e):
16191630

16201631
# Properties
16211632

1633+
@property
1634+
def id(self):
1635+
return getattr(self, self.NAME, '<no-id>')
1636+
16221637
@property
16231638
def api_key(self):
16241639
if self._api_key is None:
@@ -2442,7 +2457,7 @@ def syncreboot(self, interval=5.0, timeout=600):
24422457
# Connection errors (URLError) are ok
24432458
# Invalid cred errors are ok because FW auth system takes longer to start up
24442459
# Other errors should be raised
2445-
if not e.msg.startswith("URLError:") and not e.msg.startswith("Invalid credentials."):
2460+
if not str(e).startswith("URLError:") and not str(e).startswith("Invalid credentials."):
24462461
# Error not related to connection issue. Raise it.
24472462
raise e
24482463
else:

pandevice/firewall.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,14 @@ def __init__(self,
9090
port=443,
9191
vsys='vsys1', # vsys# or 'shared'
9292
is_virtual=None,
93+
multi_vsys=None,
9394
*args,
9495
**kwargs
9596
):
9697
"""Initialize PanDevice"""
98+
vsys_name = kwargs.pop('vsys_name', None)
99+
serial_ha_peer = kwargs.pop('serial_ha_peer', None)
100+
management_ip = kwargs.pop('management_ip', None)
97101
super(Firewall, self).__init__(hostname, api_username, api_password, api_key,
98102
port=port,
99103
is_virtual=is_virtual,
@@ -105,10 +109,10 @@ def __init__(self,
105109

106110
self.serial = serial
107111
self._vsys = vsys
108-
self.vsys_name = None
109-
self.multi_vsys = None
110-
self.serial_ha_peer = None
111-
self.management_ip = None
112+
self.vsys_name = vsys_name
113+
self.multi_vsys = multi_vsys
114+
self.serial_ha_peer = serial_ha_peer
115+
self.management_ip = management_ip
112116

113117
self.shared = False
114118
"""Set to True to act on the shared part of this firewall"""
@@ -124,6 +128,14 @@ def __init__(self,
124128
125129
"""
126130

131+
def __repr__(self):
132+
return "<%s %s %s at 0x%x>" % (type(self).__name__, repr(self.id), repr(self.vsys), id(self))
133+
134+
@property
135+
def id(self):
136+
id = self.serial if self.serial is not None else self.hostname
137+
return id if id is not None else '<no-id>'
138+
127139
@property
128140
def vsys(self):
129141
# Check if attribute exists because this could be called during

0 commit comments

Comments
 (0)