Palo Alto Create Bulk Address Objects using Pan-OS Python SDK

Palo Alto Create Bulk Address Objects using Pan-OS Python SDK
In: Palo Alto Firewall NetDevOps Python

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.

Palo Alto PAN-OS SDK for Python
Let’s start learning the pan-os-python library with a simple script. This script will be our foundation, and it’s as straightforward as it gets, creating a basic firewall rule on a Palo Alto firewall.

Methods we will use

Here is the official guide for the useful methods

  1. 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.
  2. 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.
  3. 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.
  4. 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 same xpath as this object, recursively searching the entire object tree from the nearest firewall or panorama instance.
  5. 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()
💡
Please note that by using the 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.

💡
Please note that unlike the previous example where we used a single API call to make many objects, 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.

Palo Alto Create Bulk Address Objects using REST API + Python
If you are working with firewalls on a daily basis, at some point you are going to come across having to create multiple address objects at once

References

https://pan-os-python.readthedocs.io/en/latest/index.html

Table of Contents
Written by
Suresh Vina
Tech enthusiast sharing Networking, Cloud & Automation insights. Join me in a welcoming space to learn & grow with simplicity and practicality.
Comments
More from Packetswitch
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to Packetswitch.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.