Getting Started with pan-scm-sdk
Welcome to the pan-scm-sdk
! This guide will walk you through the initial setup and basic usage of the SDK to interact
with Palo Alto Networks Strata Cloud Manager.
Installation
Requirements:
- Python 3.10 or higher
Install the package via pip:
Authentication
Before using the SDK, you need to authenticate with Strata Cloud Manager using your client credentials.
Example:
# Initialize the SCM client with your credentialsclient = ScmClient(
client_id="your_client_id",
client_secret="your_client_secret",
tsg_id="your_tsg_id",
)
# The SCM client is now ready to use
client_id
: Your OAuth2 client ID.client_secret
: Your OAuth2 client secret.tsg_id
: Your Tenant Service Group ID.
Basic Usage
The SDK provides two ways to interact with Strata Cloud Manager: the unified client interface (recommended) and the traditional service instantiation pattern.
Unified Client Interface (Recommended)
Starting with version 0.3.14, you can access all service objects directly through the client instance. This approach is more intuitive and streamlined:
# Initialize the clientclient = ScmClient(
client_id="your_client_id",
client_secret="your_client_secret",
tsg_id="your_tsg_id",
)
# Create a new address using the unified client interfaceaddress_data = {
"name": "test-address",
"fqdn": "test.example.com",
"description": "Created via unified client",
"folder": "Texas",
}
new_address = client.address.create(address_data)
print(f"Created address with ID: {new_address.id}")
# List addressesaddresses = client.address.list(folder='Prisma Access')
for addr in addresses:
print(f"Address Name: {addr.name}, IP: {addr.ip_netmask or addr.fqdn}")
# Create a tagtag_data = {
"name": "Development",
"color": "blue",
"folder": "Texas"
}
new_tag = client.tag.create(tag_data)
print(f"Created tag: {new_tag.name}")
# Create a security rulerule_data = {
"name": "allow-dev-traffic",
"folder": "Texas",
"source": {"address": ["test-address"]},
"destination": {"address": ["any"]},
"application": ["web-browsing"],
"service": ["application-default"],
"action": "allow",
"tag": ["Development"]
}
new_rule = client.security_rule.create(rule_data)
print(f"Created rule: {new_rule.name}")
# Commit changesresult = client.commit(
folders=["Texas"],
description="Added new objects via unified client",
sync=True
)
print(f"Commit job ID: {result.job_id}")
Traditional Service Instantiation (Legacy)
You can also use the traditional pattern where service objects are explicitly instantiated. While this approach is still supported for backward compatibility, it's recommended to use the unified client interface for new development.
from scm.config.objects import Address, AddressGroup, Application
# Initialize the clientclient = Scm(
client_id="your_client_id",
client_secret="your_client_secret",
tsg_id="your_tsg_id",
)
# Create service instances manuallyaddress = Address(client)
address_group = AddressGroup(client)
application = Application(client)
# Create a new addressaddress_data = {
"name": "test-address",
"fqdn": "test.example.com",
"description": "Created via pan-scm-sdk",
"folder": "Texas",
}
new_address = address.create(address_data)
print(f"Created address with ID: {new_address.id}")
# List addressesaddresses = address.list(folder='Prisma Access')
for addr in addresses:
print(f"Address Name: {addr.name}, IP: {addr.ip_netmask or addr.fqdn}")
Warning
Using the traditional approach requires manually creating service instances for each service type you want to use, which can lead to code duplication and more complex management. It also doesn't automatically handle token refreshing across all service instances.
Common Operations
Managing Address Objects
"name": "internal-network",
"ip_netmask": "192.168.1.0/24",
"description": "Internal network segment",
"folder": "Texas",
"tag": ["Network", "Internal"]
}
ip_address = client.address.create(ip_address_data)
# Update an addressip_address.description = "Updated network description"
updated_address = client.address.update(ip_address)
# Fetch address by namefound_address = client.address.fetch(name="internal-network", folder="Texas")
# Delete an addressclient.address.delete(ip_address.id)
Managing Tags
{"name": "Production", "color": "red", "folder": "Texas"},
{"name": "Testing", "color": "green", "folder": "Texas"},
{"name": "Development", "color": "blue", "folder": "Texas"}
]
for tag_data in tags_to_create:
tag = client.tag.create(tag_data)
print(f"Created tag: {tag.name} with color: {tag.color}")
# List all tagsall_tags = client.tag.list(folder="Texas")
for tag in all_tags:
print(f"Tag: {tag.name}, Color: {tag.color}")
Managing Security Rules
"name": "allow-internal-web",
"folder": "Texas",
"description": "Allow internal web browsing",
"source": {"address": ["internal-network"]},
"destination": {"address": ["any"]},
"application": ["web-browsing", "ssl"],
"service": ["application-default"],
"action": "allow",
"log_setting": None,
"log_start": False,
"log_end": True,
"disabled": False,
"tag": ["Production"]
}
rule = client.security_rule.create(rule_data)
print(f"Created rule: {rule.name}")
# List security rulesrules = client.security_rule.list(folder="Texas")
for r in rules:
print(f"Rule: {r.name}, Action: {r.action}")
Committing Changes
folders=["Texas"],
description="Configuration changes via SDK",
sync=True,
timeout=300
)
if result.success:
print(f"Successfully committed changes. Job ID: {result.job_id}")
else:
print(f"Commit failed: {result.error_message}")
# Check the status of a specific jobjob_status = client.get_job_status(result.job_id)
print(f"Job status: {job_status.data[0].status_str}")
Error Handling
Always implement proper error handling in your code to manage API errors gracefully:
APIError,
AuthenticationError,
InvalidObjectError,
NameNotUniqueError,
ObjectNotPresentError
)
try:
# Attempt to create an address
address_data = {
"name": "example-server",
"fqdn": "server.example.com",
"folder": "Texas"
}
new_address = client.address.create(address_data)
print(f"Created address: {new_address.name}")
except AuthenticationError as e:
print(f"Authentication failed: {e.message}")
except NameNotUniqueError as e:
print(f"Address name already exists: {e.message}")
except InvalidObjectError as e:
print(f"Invalid address data: {e.message}")
if e.details:
print(f"Details: {e.details}")
except APIError as e:
print(f"API error: {e.message}")
Next Steps
- Explore the SDK Reference Documentation for detailed information on all available services and methods.
- Check out the Client Module documentation for more information on the unified client interface.
- Refer to the examples directory for complete script examples.