External Dynamic Lists Configuration Object
Table of Contents
- Overview
- Core Methods
- EDL Model Attributes
- Exceptions
- Basic Configuration
- Usage Examples
- Managing Configuration Changes
- Error Handling
- Best Practices
- Full Script Examples
- Related Models
Overview
The ExternalDynamicLists
class provides functionality to manage External Dynamic Lists (EDLs) in Palo Alto Networks' Strata
Cloud Manager. This class inherits from BaseObject
and provides methods for creating, retrieving, updating, and deleting
EDLs of various types including IP, Domain, URL, IMSI, and IMEI lists with configurable update intervals.
Core Methods
Method | Description | Parameters | Return Type |
---|---|---|---|
create() |
Creates a new EDL | data: Dict[str, Any] |
ExternalDynamicListsResponseModel |
get() |
Retrieves an EDL by ID | edl_id: str |
ExternalDynamicListsResponseModel |
update() |
Updates an existing EDL | edl: ExternalDynamicListsUpdateModel |
ExternalDynamicListsResponseModel |
delete() |
Deletes an EDL | edl_id: str |
None |
list() |
Lists EDLs with filtering | folder: str , **filters |
List[ExternalDynamicListsResponseModel] |
fetch() |
Gets EDL by name | name: str , folder: str |
ExternalDynamicListsResponseModel |
EDL Model Attributes
Attribute | Type | Required | Description |
---|---|---|---|
name |
str | Yes | Name of EDL (max 63 chars) |
id |
UUID | Yes* | Unique identifier (*response only) |
type |
TypeUnion | Yes | EDL type configuration |
url |
str | Yes | Source URL for EDL content |
description |
str | No | Description (max 255 chars) |
exception_list |
List[str] | No | List of exceptions |
auth |
AuthModel | No | Authentication credentials |
recurring |
RecurringUnion | Yes | Update schedule configuration |
folder |
str | Yes** | Folder location (**one container required) |
snippet |
str | Yes** | Snippet location (**one container required) |
device |
str | Yes** | Device location (**one container required) |
Exceptions
Exception | HTTP Code | Description |
---|---|---|
InvalidObjectError |
400 | Invalid EDL data or format |
MissingQueryParameterError |
400 | Missing required parameters |
NameNotUniqueError |
409 | EDL name already exists |
ObjectNotPresentError |
404 | EDL not found |
ReferenceNotZeroError |
409 | EDL still referenced |
AuthenticationError |
401 | Authentication failed |
ServerError |
500 | Internal server error |
Basic Configuration
from scm.config.objects import ExternalDynamicLists
# Initialize clientclient = Scm(
client_id="your_client_id",
client_secret="your_client_secret",
tsg_id="your_tsg_id"
)
# Initialize EDL objectedls = ExternalDynamicLists(client)
Usage Examples
Creating EDLs
"name": "malicious-ips",
"folder": "Texas",
"type": {
"ip": {
"url": "https://threatfeeds.example.com/ips.txt",
"description": "Known malicious IPs",
"recurring": {
"daily": {
"at": "03"
}
},
"auth": {
"username": "user123",
"password": "pass123"
}
}
}
}
# Create IP EDLip_edl = edls.create(ip_edl_config)
# Domain-based EDL with hourly updatesdomain_edl_config = {
"name": "blocked-domains",
"folder": "Texas",
"type": {
"domain": {
"url": "https://threatfeeds.example.com/domains.txt",
"description": "Blocked domains list",
"recurring": {
"hourly": {}
},
"expand_domain": True
}
}
}
# Create domain EDLdomain_edl = edls.create(domain_edl_config)
Retrieving EDLs
print(f"Found EDL: {edl.name}")
# Get by IDedl_by_id = edls.get(edl.id)
print(f"Retrieved EDL: {edl_by_id.name}")
Updating EDLs
# Update attributesexisting_edl.description = "Updated malicious IP list"
existing_edl.type.ip.recurring = {
"five_minute": {}
}
# Perform updateupdated_edl = edls.update(existing_edl)
Listing EDLs
folder='Texas',
types=['ip', 'domain']
)
# Process resultsfor edl in filtered_edls:
print(f"Name: {edl.name}")
if hasattr(edl.type, 'ip'):
print(f"Type: IP, URL: {edl.type.ip.url}")
elif hasattr(edl.type, 'domain'):
print(f"Type: Domain, URL: {edl.type.domain.url}")
# Define filter parameters as dictionarylist_params = {
"folder": "Texas",
"types": ["url"]
}
# List with filters as kwargsfiltered_edls = edls.list(**list_params)
Filtering Responses
folder='Texas',
exact_match=True
)
for app in exact_edls:
print(f"Exact match: {app.name} in {app.folder}")
# Exclude all edls from the 'All' folderno_all_edls = edls.list(
folder='Texas',
exclude_folders=['All']
)
for app in no_all_edls:
assert app.folder != 'All'
print(f"Filtered out 'All': {app.name}")
# Exclude edls that come from 'default' snippetno_default_snippet = edls.list(
folder='Texas',
exclude_snippets=['default']
)
for app in no_default_snippet:
assert app.snippet != 'default'
print(f"Filtered out 'default' snippet: {app.name}")
# Exclude edls associated with 'DeviceA'no_deviceA = edls.list(
folder='Texas',
exclude_devices=['DeviceA']
)
for app in no_deviceA:
assert app.device != 'DeviceA'
print(f"Filtered out 'DeviceA': {app.name}")
# Combine exact_match with multiple exclusionscombined_filters = edls.list(
folder='Texas',
exact_match=True,
exclude_folders=['All'],
exclude_snippets=['default'],
exclude_devices=['DeviceA']
)
for app in combined_filters:
print(f"Combined filters result: {app.name} in {app.folder}")
Controlling Pagination with max_limit
The SDK supports pagination through the max_limit
parameter, which defines how many objects are retrieved per API call. By default, max_limit
is set to 2500. The API itself imposes a maximum allowed value of 5000. If you set max_limit
higher than 5000, it will be capped to the API's maximum. The list()
method will continue to iterate through all objects until all results have been retrieved. Adjusting max_limit
can help manage retrieval performance and memory usage when working with large datasets.
# Now when we call list(), it will use the specified max_limit for each request# while auto-paginating through all available objects.all_edls = edls_client.list(folder='Texas')
# 'all_edls' contains all objects from 'Texas', fetched in chunks of up to 4321 at a time.
Deleting EDLs
edls.delete(edl_id)
Managing Configuration Changes
Performing Commits
"folders": ["Texas"],
"description": "Updated EDL configurations",
"sync": True,
"timeout": 300 # 5 minute timeout
}
# Commit the changesresult = edls.commit(**commit_params)
print(f"Commit job ID: {result.job_id}")
Monitoring Jobs
print(f"Job status: {job_status.data[0].status_str}")
# List recent jobsrecent_jobs = edls.list_jobs(limit=10)
for job in recent_jobs.data:
print(f"Job {job.id}: {job.type_str} - {job.status_str}")
Error Handling
InvalidObjectError,
MissingQueryParameterError,
NameNotUniqueError,
ObjectNotPresentError,
ReferenceNotZeroError
)
try:# Create EDL configurationedl_config = {
"name": "test-edl",
"folder": "Texas",
"type": {
"ip": {
"url": "https://example.com/ips.txt",
"description": "Test IP list",
"recurring": {
"daily": {
"at": "03"
}
}
}
}
}
# Create the EDLnew_edl = edls.create(edl_config)
# Commit changesresult = edls.commit(
folders=["Texas"],
description="Added test EDL",
sync=True
)
# Check job statusstatus = edls.get_job_status(result.job_id)
except InvalidObjectError as e:
print(f"Invalid EDL data: {e.message}")
except NameNotUniqueError as e:
print(f"EDL name already exists: {e.message}")
except ObjectNotPresentError as e:
print(f"EDL not found: {e.message}")
except ReferenceNotZeroError as e:
print(f"EDL still in use: {e.message}")
except MissingQueryParameterError as e:
print(f"Missing parameter: {e.message}")
Best Practices
-
EDL Configuration
- Use descriptive names
- Set appropriate update intervals
- Configure authentication when needed
- Validate source URLs
- Monitor update status
-
Container Management
- Always specify exactly one container
- Use consistent container names
- Validate container existence
- Group related EDLs
-
Update Scheduling
- Choose appropriate intervals
- Consider source update frequency
- Stagger updates for multiple EDLs
- Monitor update success
- Handle failures gracefully
-
Performance
- Use appropriate pagination
- Cache frequently accessed EDLs
- Monitor EDL sizes
- Consider update impact
- Implement retry logic
-
Security
- Validate source URLs
- Use HTTPS where possible
- Secure credentials
- Monitor for malicious content
- Regular audits
Full Script Examples
Refer to the external_dynamic_lists.py example.