In this blog post, we'll see how to configure bulk Address-Objects at once and then add them to an Address-Group using the pan-os-python Library. If you haven't used the pan-os-python library before, have a look at my other blog post to learn more.
Methods we will use
Here is the official guide for the useful methods
- add() - This method is used to add an object as a child of another object. In our scenario, it's for adding an Address Object to the firewall or panorama object.
- extend() - This method allows you to add a list of objects as children. In our context, it means adding a 'list' of Address objects to the firewall or panorama object.
- create() - Once you've defined an object in the script, the
create()
method is used to push this object to the live device, making the configuration active. - create_similar() - This method pushes objects of the same type to the live device. It's useful when you've multiple similar configurations to push. This is similar to
create()
, except instead of calling create only on this object, it calls create for all objects that share the samexpath
as this object, recursively searching the entire object tree from the nearest firewall or panorama instance. - update() - Update a single attribute on an object.
Creating Bulk Address Objects
from panos.panorama import Panorama #for panorama
from panos.firewall import Firewall #for firewall
from panos.objects import AddressObject, AddressGroup
pan = Panorama('PANORAMA_IP', 'USERNAME', 'PASSWORD' ) #for panorama
# pan = Firewall('FIREWALL_IP', 'USERNAME', 'PASSWORD' ) #for firewall
new_objects = {
'server_1' : '192.168.10.1/32',
'server_2' : '192.168.10.2/32',
'server_3' : '192.168.10.3/32'
}
address_obj = [AddressObject(k,v) for k,v in new_objects.items()]
address_group_obj = AddressGroup('server_group', address_obj)
pan.extend(address_obj)
pan.add(address_group_obj)
pan.find(next(iter(new_objects))).create_similar()
address_group_obj.create()
Starting off, we import necessary classes. The Classes Panorama
and Firewall
represent the types of devices we might connect to. For Address Objects and Address Groups, we import AddressObject
and AddressGroup
Classes.
from panos.panorama import Panorama #for panorama
from panos.firewall import Firewall #for firewall
from panos.objects import AddressObject, AddressGroup
For this example, we target a Panorama by initializing the Panorama
class with the device's IP and the credentials. However, if you're planning to work directly with a firewall, all you have to do is comment out the Panorama line and instead initialize the Firewall
Class.
pan = Panorama('PANORAMA_IP', 'USERNAME', 'PASSWORD' ) #for panorama
# pan = Firewall('FIREWALL_IP', 'USERNAME', 'PASSWORD' ) #for firewall
Next, the code below lists three new address objects we plan to create, with their names as keys and their corresponding IP addresses as values in the new_objects
dictionary. Using a list comprehension, the dictionary's key-value pairs are converted into a list of AddressObject
instances stored in address_obj
. Subsequently, an AddressGroup
object named server_group
is created, which adds the address objects we created.
new_objects = {
'server_1' : '192.168.10.1/32',
'server_2' : '192.168.10.2/32',
'server_3' : '192.168.10.3/32'
}
address_obj = [AddressObject(k,v) for k,v in new_objects.items()]
address_group_obj = AddressGroup('server_group', address_obj)
extend()
method, unlike the add
method which takes a single object, allows the panorama object to take a list of objects - in this case, a list of address objects we created. Following this, the add
method adds our AddressGroup
object to the panorama object.
pan.extend(address_obj)
pan.add(address_group_obj)
A key point to mention on the next block of codes is the usage of next(iter(new_objects))
. It might appear complex, but it's straightforward. new_objects
is a dictionary. iter(new_objects)
yields an iterator over its keys, and next
fetches the first key in this iterator. The .create_similar()
method then pushes all objects of the same type as the specified object (in this case, our address objects) to the live device.
pan.find(next(iter(new_objects))).create_similar()
Concluding the process, the address_group_obj.create()
method pushes our address group to the device.
address_group_obj.create()
iter() Method
If you don't want to use iter()
, you could also hard-code the name of one of the address-object as shown below.
pan.find('server-1').create_similar()
create_similar()
method, we make one API call to create all three address objects. If we had used a for loop with the create()
method, it would have made one API call for each object.Adding Tag to Multiple Address Objects
In this final example, we'll look at how to add Tag to multiple address objects based on a condition. Let's say we want to add a Tag to those that have IP addresses like 192.168.10.x
. If the condition is met, we'll add a tag named 'sdk' to these objects.
from panos.panorama import Panorama, DeviceGroup
from panos.objects import AddressObject
panorama_object = Panorama('PANORAMA_IP', 'USERNAME', 'PASSWORD' )
current_objects = AddressObject.refreshall(panorama_object)
for item in current_objects:
if '192.168.10.' in item.value:
item.tag = 'sdk'
item.update('tag')
To make these changes, we'll use the update()
method from the pan-os-python library. This method is handy when we only want to add/update one attribute to an existing object.
In the script, we first get a list of all current address objects. We then go through each object and check its IP address. If the IP address matches what we're looking for, we add the 'sdk' tag to it. After that, we use the update()
method to change the tag for that object on the device. update()
method is a simple and efficient way to update just one attribute of an object.
update()
method uses one API call per change so, in total 3 API calls.If you want to create bulk addresses using REST-API, please check out my other blog post below.