Skip to content

Commit a48e808

Browse files
committed
Merge branch 'release/0.5.0'
2 parents 557a7fa + f331841 commit a48e808

36 files changed

+4471
-705
lines changed

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ language: python
44

55
python:
66
- "2.7"
7+
- "3.5"
8+
- "3.6"
79
- "pypy"
810

911
# command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors

HISTORY.rst

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

6+
0.5.0
7+
-----
8+
9+
Released 2017-07-14
10+
11+
Status: Alpha
12+
13+
- Add: Support for python3 (3.5+)
14+
- Add: Support for predefined tags
15+
- Add: Support for bulk operations (e.g. - `create_similar()`)
16+
- Add: DHCP support for various data interface objects
17+
- Add: `request_password_hash()` to firewall / panorama devices
18+
- Change: Layer2Subinterface/Layer3Subinterface can be children of vsys or firewalls now
19+
- Fix: `equals()` for objects with list params
20+
21+
22+
Potentially breaking-changes in this version, please update your scripts to account for the following:
23+
24+
- The default vsys for firewalls is changed from "vsys1" to None. This has no effect for scripts that set the vsys on the firewall object directly (vsys is still treated as vsys1 in this situation). This specific change was to better align pandevice with the default behavior of the firewall, which only imports interfaces by default (vsys1 if otherwise unspecified). Thus, virtual wire, virtual routers, and VLANs will only be imported if they are attached to a Vsys object *or* the firewall has a vsys set.
25+
- VsysResources and SystemSettings now have a name of None
26+
- SubinterfaceArp and EthernetInterfaceArp have been replaced with Arp
27+
28+
29+
List of PanObject changes:
30+
31+
- Added: PasswordProfile
32+
- Added: Administrator
33+
- Added: Arp
34+
- Updated: Zone
35+
- Updated: Vsys
36+
- Fixed: StaticRouteV6
37+
- Fixed: OspfNsaaExternalRange
38+
39+
40+
- New example scripts:
41+
42+
- bulk_address_objects.py
43+
- bulk_subinterfaces.py
44+
45+
646
0.4.1
747
-----
848

README.rst

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,35 @@ Some operational commands have methods to refresh the variables in an object::
100100
See more examples in the `Usage Guide`_.
101101

102102

103+
Connect to PAN-OS 8.0 and higher
104+
--------------------------------
105+
106+
PAN-OS 8.0 by default does not allow connections to the API with TLS 1.0. Unfortunately, the
107+
latest OSX and many linux distros come with OpenSSL versions that don't support
108+
TLS 1.1 or 1.2. OpenSSL 1.0.1 or higher is needed to connect to PAN-OS 8.0. If
109+
you try to connect with a lower version of OpenSSL, you'll get a connection error.
110+
There are two solutions:
111+
112+
**Option 1: Upgrade OpenSSL** (more secure)
113+
114+
*Mac OSX:* In Mac OSX you can't upgrade the built-in OpenSSL, but you can install your own python
115+
and OpenSSL using `Homebrew`_. Follow this guide to get set up: `Definitive guide to python on OSX`_
116+
117+
*Linux:* Use the instructions for your distribution's package manager to upgrade OpenSSL to 1.0.1 or higher.
118+
119+
**Option 2: Enable TLS 1.0 on PAN-OS** (less secure)
120+
121+
Follow the direction in the PAN-OS Administrator Guide:
122+
`Replace the Certificate for Inbound Management Traffic`_
123+
124+
103125
Contributors
104126
------------
105127

106128
- Brian Torres-Gil - `github <https://github.com/btorresgil>`__
107129
- Garfield Freeman - `github <https://github.com/shinmog>`__
108130
- John Anderson - `github <https://github.com/lampwins>`__
131+
- Aditya Sripal - `github <https://github.com/AdityaSripal>`__
109132

110133
Thank you to Kevin Steves, creator of the pan-python library:
111134
https://github.com/kevinsteves/pan-python
@@ -114,6 +137,9 @@ Thank you to Kevin Steves, creator of the pan-python library:
114137
.. _pan-python: http://github.com/kevinsteves/pan-python
115138
.. _Configuration Tree: http://pandevice.readthedocs.io/en/latest/configtree.html
116139
.. _Usage Guide: http://pandevice.readthedocs.io/en/latest/usage.html
140+
.. _Homebrew: https://brew.sh/
141+
.. _Definitive guide to python on OSX: https://medium.com/@briantorresgil/definitive-guide-to-python-on-mac-osx-65acd8d969d0
142+
.. _Replace the Certificate for Inbound Management Traffic: https://www.paloaltonetworks.com/documentation/80/pan-os/pan-os/certificate-management/replace-the-certificate-for-inbound-management-traffic
117143

118144
.. |pypi| image:: https://img.shields.io/pypi/v/pandevice.svg
119145
:target: https://pypi.python.org/pypi/pandevice

examples/bulk_address_objects.py

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright (c) 2017, Palo Alto Networks
4+
#
5+
# Permission to use, copy, modify, and/or distribute this software for any
6+
# purpose with or without fee is hereby granted, provided that the above
7+
# copyright notice and this permission notice appear in all copies.
8+
#
9+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10+
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11+
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12+
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13+
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14+
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15+
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16+
17+
"""
18+
bulk_address_objects.py
19+
==========================
20+
21+
Use bulk operations to create / delete hundreds of firewall Address Objects.
22+
23+
NOTE: Please update the hostname and auth credentials variables
24+
before running.
25+
26+
This script will create a large number of address objects on the firewall
27+
and then delete them. The intent is to show how to use the new bulk
28+
operations available in pandevice, both how to properly use them and what
29+
to be careful of.
30+
"""
31+
32+
import datetime
33+
import sys
34+
35+
import pandevice
36+
import pandevice.firewall
37+
import pandevice.objects
38+
39+
40+
HOSTNAME = '127.0.0.1'
41+
USERNAME = 'admin'
42+
PASSWORD = 'admin'
43+
PREFIX = 'BulkAddressObject'
44+
45+
46+
def num_as_ip(num, offset=0):
47+
'''Returns a number as a 192.168 IP address.'''
48+
return '192.168.{0}.{1}'.format(
49+
num // 200 + 1 + offset,
50+
num % 200 + 2)
51+
52+
53+
def main():
54+
# Before we begin, you'll need to use the pandevice documentation both
55+
# for this example and for any scripts you may write for yourself. The
56+
# docs can be found here:
57+
#
58+
# http://pandevice.readthedocs.io/en/latest/reference.html
59+
#
60+
# First, let's create the firewall object that we want to modify.
61+
fw = pandevice.firewall.Firewall(HOSTNAME, USERNAME, PASSWORD)
62+
print('Firewall system info: {0}'.format(fw.refresh_system_info()))
63+
64+
# Get the list of current address objects, as we'll need this later. We
65+
# don't want these address objects in our firewall tree yet, so let's set
66+
# the `add` flag in the refreshall method to False.
67+
original_objects = pandevice.objects.AddressObject.refreshall(
68+
fw, add=False)
69+
70+
# As a sanity check, make sure no currently configured address objects
71+
# have the same name prefix as what this script uses. If so, quit.
72+
for x in original_objects:
73+
if x.uid.startswith(PREFIX):
74+
print('Error: prefix {0} shared with address object {1}'.format(
75+
PREFIX, x.uid))
76+
return
77+
78+
# Just print out how many address objects were there beforehand.
79+
print('* There are {0} address object(s) currently *'.format(
80+
len(original_objects)))
81+
82+
# Create each address object and add it to the firewall. You'll notice
83+
# that we don't call `create()` on each object as you'd expect. This is
84+
# because we'll do a bulk create after we've finished creating everything.
85+
bulk_objects = []
86+
for num in range(1, 601):
87+
ao = pandevice.objects.AddressObject(
88+
'{0}{1:03}'.format(PREFIX, num),
89+
num_as_ip(num))
90+
bulk_objects.append(ao)
91+
fw.add(ao)
92+
93+
# Now we can bulk create all the address objects. This is accomplished by
94+
# invoking `create_similar()` on any of the address objects in our tree,
95+
# turning what would have been 600 individual API calls and condensing it
96+
# into a single API call.
97+
start = datetime.datetime.now()
98+
bulk_objects[0].create_similar()
99+
print('Creating {0} address objects took: {1}'.format(
100+
len(bulk_objects), datetime.datetime.now() - start))
101+
102+
# We've done a bulk create, now let's look at bulk apply.
103+
#
104+
# Some care is needed when using apply with pandevice. All "apply" methods
105+
# are doing a PANOS API `type=edit` under the hood, which does a replace of
106+
# the current config with what is specified.
107+
#
108+
# So what does this mean? This means that if we wanted to do a mass
109+
# update of the address objects we just created, we need to make sure that
110+
# our object tree contains the address objects that existed before this
111+
# script started. So let's add in the pre-existing address objects to
112+
# the firewall's object tree. We'll do this first so we don't forget
113+
# later on.
114+
for x in original_objects:
115+
fw.add(x)
116+
117+
# With that out of the way, we're ready to update or bulk address objects
118+
# by incrementing the third octet of each IP address by 10.
119+
for num, x in enumerate(bulk_objects, 1):
120+
x.value = num_as_ip(num, 10)
121+
122+
# Now we can do our bulk apply, invoking `apply_similar()`. As before,
123+
# we invoke this on any of the related children in our pandevice
124+
# object tree. Most important of all, since our firewall object has all
125+
# the pre-existing address objects in its tree, we won't accidentally
126+
# truncate them from the firewall config.
127+
start = datetime.datetime.now()
128+
bulk_objects[0].apply_similar()
129+
print('Bulk apply {0} address objects took: {1}'.format(
130+
len(bulk_objects) + len(original_objects),
131+
datetime.datetime.now() - start))
132+
133+
# We've done create, we've done edit, that leaves bulk delete. We only
134+
# want to delete the bulk address objects we created in this script, so
135+
# let's remove all the pre-existing address objects from the firewall
136+
# object.
137+
for x in original_objects:
138+
fw.remove(x)
139+
140+
# Finally, let's invoke `delete_similar()` from the firewall. As should be
141+
# expected, we invoke this from any of the objects currently in our
142+
# pandevice object tree.
143+
start = datetime.datetime.now()
144+
bulk_objects[0].delete_similar()
145+
print('Deleting {0} address objects took: {1}'.format(
146+
len(bulk_objects), datetime.datetime.now() - start))
147+
148+
# At this point, we've now used all the bulk operations. If performance
149+
# is a bottleneck for you, consider if any of your automation could be
150+
# refactored to use any of the bulk operations pandevice offers.
151+
print('Done!')
152+
153+
154+
if __name__ == '__main__':
155+
# This script doesn't take command line arguments. If any are passed in,
156+
# then print out the script's docstring and exit.
157+
if len(sys.argv) != 1:
158+
print __doc__
159+
else:
160+
# No CLI args, so run the main function.
161+
main()

0 commit comments

Comments
 (0)