From 4b2f7c774fbb8ebafb6197d88b71f1ed043d1dc0 Mon Sep 17 00:00:00 2001 From: Calvin Remsburg Date: Sat, 7 Dec 2024 14:27:15 -0600 Subject: [PATCH] Add External Dynamic Lists documentation and models This commit introduces new documentation and models for managing External Dynamic Lists (EDLs) in the SDK, enhancing capabilities to handle IP, domain, URL, IMSI, and IMEI lists. Updates include new md files, index entries, and release notes detailing EDLs configuration, methods, and best practices. --- docs/about/release-notes.md | 5 + .../config/objects/external_dynamic_lists.md | 374 ++++++++++++++++++ docs/sdk/config/objects/index.md | 4 + docs/sdk/index.md | 2 + .../objects/external_dynamic_lists_models.md | 235 +++++++++++ docs/sdk/models/objects/index.md | 1 + mkdocs.yml | 2 + pyproject.toml | 2 +- 8 files changed, 624 insertions(+), 1 deletion(-) create mode 100644 docs/sdk/config/objects/external_dynamic_lists.md create mode 100644 docs/sdk/models/objects/external_dynamic_lists_models.md diff --git a/docs/about/release-notes.md b/docs/about/release-notes.md index 99cd82f..3927116 100644 --- a/docs/about/release-notes.md +++ b/docs/about/release-notes.md @@ -1,3 +1,8 @@ +## Version 0.3.4 + +- Added support for External Dynamic Lists +- Added support for Auto Tag Actions (not yet supported by API) + ## Version 0.3.3 - Added support for URL Categories diff --git a/docs/sdk/config/objects/external_dynamic_lists.md b/docs/sdk/config/objects/external_dynamic_lists.md new file mode 100644 index 0000000..71266ef --- /dev/null +++ b/docs/sdk/config/objects/external_dynamic_lists.md @@ -0,0 +1,374 @@ +# External Dynamic Lists Configuration Object + +## Table of Contents + +1. [Overview](#overview) +2. [Core Methods](#core-methods) +3. [EDL Model Attributes](#edl-model-attributes) +4. [Exceptions](#exceptions) +5. [Basic Configuration](#basic-configuration) +6. [Usage Examples](#usage-examples) + - [Creating EDLs](#creating-edls) + - [Retrieving EDLs](#retrieving-edls) + - [Updating EDLs](#updating-edls) + - [Listing EDLs](#listing-edls) + - [Deleting EDLs](#deleting-edls) +7. [Managing Configuration Changes](#managing-configuration-changes) + - [Performing Commits](#performing-commits) + - [Monitoring Jobs](#monitoring-jobs) +8. [Error Handling](#error-handling) +9. [Best Practices](#best-practices) +10. [Full Script Examples](#full-script-examples) +11. [Related Models](#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 + +
+ + +```python +from scm.client import Scm +from scm.config.objects import ExternalDynamicLists + +# Initialize client +client = Scm( + client_id="your_client_id", + client_secret="your_client_secret", + tsg_id="your_tsg_id" +) + +# Initialize EDL object +edls = ExternalDynamicLists(client) +``` + +
+ +## Usage Examples + +### Creating EDLs + +
+ + +```python +# IP-based EDL with daily updates +ip_edl_config = { + "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 EDL +ip_edl = edls.create(ip_edl_config) + +# Domain-based EDL with hourly updates +domain_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 EDL +domain_edl = edls.create(domain_edl_config) +``` + +
+ +### Retrieving EDLs + +
+ + +```python +# Fetch by name and folder +edl = edls.fetch(name="malicious-ips", folder="Texas") +print(f"Found EDL: {edl.name}") + +# Get by ID +edl_by_id = edls.get(edl.id) +print(f"Retrieved EDL: {edl_by_id.name}") +``` + +
+ +### Updating EDLs + +
+ + +```python +# Fetch existing EDL +existing_edl = edls.fetch(name="malicious-ips", folder="Texas") + +# Update attributes +existing_edl.description = "Updated malicious IP list" +existing_edl.type.ip.recurring = { + "five_minute": {} +} + +# Perform update +updated_edl = edls.update(existing_edl) +``` + +
+ +### Listing EDLs + +
+ + +```python +# List with direct filter parameters +filtered_edls = edls.list( + folder='Texas', + types=['ip', 'domain'] +) + +# Process results +for 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 dictionary +list_params = { + "folder": "Texas", + "types": ["url"] +} + +# List with filters as kwargs +filtered_edls = edls.list(**list_params) +``` + +
+ +### Deleting EDLs + +
+ + +```python +# Delete by ID +edl_id = "123e4567-e89b-12d3-a456-426655440000" +edls.delete(edl_id) +``` + +
+ +## Managing Configuration Changes + +### Performing Commits + +
+ + +```python +# Prepare commit parameters +commit_params = { + "folders": ["Texas"], + "description": "Updated EDL configurations", + "sync": True, + "timeout": 300 # 5 minute timeout +} + +# Commit the changes +result = edls.commit(**commit_params) + +print(f"Commit job ID: {result.job_id}") +``` + +
+ +### Monitoring Jobs + +
+ + +```python +# Get status of specific job +job_status = edls.get_job_status(result.job_id) +print(f"Job status: {job_status.data[0].status_str}") + +# List recent jobs +recent_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 + +
+ + +```python +from scm.exceptions import ( + InvalidObjectError, + MissingQueryParameterError, + NameNotUniqueError, + ObjectNotPresentError, + ReferenceNotZeroError +) + +try: + # Create EDL configuration + edl_config = { + "name": "test-edl", + "folder": "Texas", + "type": { + "ip": { + "url": "https://example.com/ips.txt", + "description": "Test IP list", + "recurring": { + "daily": { + "at": "03" + } + } + } + } + } + + # Create the EDL + new_edl = edls.create(edl_config) + + # Commit changes + result = edls.commit( + folders=["Texas"], + description="Added test EDL", + sync=True + ) + + # Check job status + status = 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 + +1. **EDL Configuration** + - Use descriptive names + - Set appropriate update intervals + - Configure authentication when needed + - Validate source URLs + - Monitor update status + +2. **Container Management** + - Always specify exactly one container + - Use consistent container names + - Validate container existence + - Group related EDLs + +3. **Update Scheduling** + - Choose appropriate intervals + - Consider source update frequency + - Stagger updates for multiple EDLs + - Monitor update success + - Handle failures gracefully + +4. **Performance** + - Use appropriate pagination + - Cache frequently accessed EDLs + - Monitor EDL sizes + - Consider update impact + - Implement retry logic + +5. **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](https://github.com/cdot65/pan-scm-sdk/blob/main/examples/scm/config/objects/external_dynamic_lists.py). + +## Related Models + +- [ExternalDynamicListsCreateModel](../../models/objects/external_dynamic_lists_models.md#Overview) +- [ExternalDynamicListsUpdateModel](../../models/objects/external_dynamic_lists_models.md#Overview) +- [ExternalDynamicListsResponseModel](../../models/objects/external_dynamic_lists_models.md#Overview) diff --git a/docs/sdk/config/objects/index.md b/docs/sdk/config/objects/index.md index 2edb704..a7ed553 100644 --- a/docs/sdk/config/objects/index.md +++ b/docs/sdk/config/objects/index.md @@ -36,6 +36,10 @@ Manage application filters definitions, including their characteristics and asso Manage application group definitions, including their characteristics and associated members. +### [External Dynamic Lists](external_dynamic_lists.md) + +Manage EDLs. + ### [Service](service.md) Manage service definitions, including their characteristics and associated protocols / ports. diff --git a/docs/sdk/index.md b/docs/sdk/index.md index c155ee5..915f355 100644 --- a/docs/sdk/index.md +++ b/docs/sdk/index.md @@ -15,6 +15,7 @@ configuration objects and data models used to interact with Palo Alto Networks S - [Application](config/objects/application.md) - [Application Filters](config/objects/application_filters.md) - [Application Group](config/objects/application_group.md) + - [External Dynamic Lists](config/objects/external_dynamic_lists.md) - [Service](config/objects/service.md) - [Service Group](config/objects/service_group.md) - [Tag](config/objects/tag.md) @@ -33,6 +34,7 @@ configuration objects and data models used to interact with Palo Alto Networks S - [Application Models](models/objects/application_models.md) - [Application Filters Models](models/objects/application_filters_models.md) - [Application Group Models](models/objects/application_group_models.md) + - [External Dynamic Lists Models](models/objects/external_dynamic_lists_models.md) - [Service Models](models/objects/service_models.md) - [Service Group Models](models/objects/service_group_models.md) - [Tag Models](models/objects/tag_models.md) diff --git a/docs/sdk/models/objects/external_dynamic_lists_models.md b/docs/sdk/models/objects/external_dynamic_lists_models.md new file mode 100644 index 0000000..81a8f9c --- /dev/null +++ b/docs/sdk/models/objects/external_dynamic_lists_models.md @@ -0,0 +1,235 @@ +# External Dynamic Lists Models + +## Overview + +The External Dynamic Lists models provide a structured way to manage external dynamic lists in Palo Alto Networks' Strata +Cloud Manager. These models support various types of dynamic lists including IP, domain, URL, IMSI, and IMEI lists, with +configurable update intervals and authentication options. + +## Attributes + +| Attribute | Type | Required | Default | Description | +|---------------------|---------------|----------|------------|-----------------------------------------------------------------------| +| name | str | Yes | None | Name of the list. Max length: 63 chars. Must match pattern: ^[ a-zA-Z\d.\-_]+$ | +| type | TypeUnion | Yes* | None | Type of dynamic list (predefined_ip, predefined_url, ip, domain, url, imsi, imei) | +| folder | str | No** | None | Folder where list is defined. Max length: 64 chars | +| snippet | str | No** | None | Snippet where list is defined. Max length: 64 chars | +| device | str | No** | None | Device where list is defined. Max length: 64 chars | +| id | UUID | Yes*** | None | UUID of the list (response only) | +| description | str | No | None | Description of the list. Max length: 255 chars | +| url | str | Yes | "http://" | URL for fetching list content | +| exception_list | List[str] | No | None | List of exceptions | +| certificate_profile | str | No | None | Client certificate profile name | +| auth | AuthModel | No | None | Username/password authentication | +| recurring | RecurringUnion | Yes | None | Update interval configuration | +| expand_domain | bool | No | False | Enable domain expansion (domain type only) | + +\* Required for non-predefined lists +\** Exactly one container type (folder/snippet/device) must be provided for create operations +\*** Required for response model when snippet is not "predefined" + +## Exceptions + +The External Dynamic Lists models can raise the following exceptions during validation: + +- **ValueError**: Raised in several scenarios: + - When no container type or multiple container types are specified for create operations + - When ID is missing for non-predefined response models + - When type is missing for non-predefined response models + - When invalid recurring interval configuration is provided + - When invalid URL format is provided + - When name pattern validation fails + +## Model Validators + +### Container Type Validation + +For create operations, exactly one container type must be specified: + +
+ + +```python +from scm.models.objects import ExternalDynamicListsCreateModel + +# This will raise a validation error +try: + edl = ExternalDynamicListsCreateModel( + name="blocked-ips", + folder="Shared", + device="fw01", # Can't specify both folder and device + type={"ip": { + "url": "http://example.com/blocked.txt", + "recurring": {"hourly": {}} + }} + ) +except ValueError as e: + print(e) # "Exactly one of 'folder', 'snippet', or 'device' must be provided." +``` + +
+ +### Recurring Interval Validation + +The models support various recurring update intervals: + +
+ + +```python +# Five minute interval +edl = ExternalDynamicListsCreateModel( + name="blocked-ips", + folder="Shared", + type={"ip": { + "url": "http://example.com/blocked.txt", + "recurring": {"five_minute": {}} + }} +) + +# Daily at specific hour +edl = ExternalDynamicListsCreateModel( + name="blocked-ips", + folder="Shared", + type={"ip": { + "url": "http://example.com/blocked.txt", + "recurring": {"daily": {"at": "23"}} + }} +) + +# Weekly on specific day and time +edl = ExternalDynamicListsCreateModel( + name="blocked-ips", + folder="Shared", + type={"ip": { + "url": "http://example.com/blocked.txt", + "recurring": {"weekly": {"day_of_week": "monday", "at": "12"}} + }} +) +``` + +
+ +## Usage Examples + +### Creating an IP List + +
+ + +```python +from scm.config.objects import ExternalDynamicLists + +# Using dictionary +ip_list = { + "name": "blocked-ips", + "folder": "Shared", + "type": { + "ip": { + "description": "Blocked IP addresses", + "url": "http://example.com/blocked.txt", + "auth": { + "username": "user1", + "password": "pass123" + }, + "recurring": {"hourly": {}} + } + } +} + +edl = ExternalDynamicLists(api_client) +response = edl.create(ip_list) +``` + +
+ +### Creating a Domain List + +
+ + +```python +# Using model directly +from scm.models.objects import ( + ExternalDynamicListsCreateModel, + DomainType, + DomainModel, + AuthModel, + HourlyRecurringModel +) + +domain_list = ExternalDynamicListsCreateModel( + name="blocked-domains", + folder="Shared", + type=DomainType( + domain=DomainModel( + description="Blocked domains", + url="http://example.com/domains.txt", + auth=AuthModel( + username="user1", + password="pass123" + ), + recurring=HourlyRecurringModel(hourly={}), + expand_domain=True + ) + ) +) + +payload = domain_list.model_dump(exclude_unset=True) +response = edl.create(payload) +``` + +
+ +### Updating a List + +
+ + +```python +# Using dictionary +update_dict = { + "id": "123e4567-e89b-12d3-a456-426655440000", + "name": "blocked-ips-updated", + "type": { + "ip": { + "description": "Updated blocked IPs", + "url": "http://example.com/blocked-new.txt", + "recurring": {"daily": {"at": "12"}} + } + } +} + +response = edl.update(update_dict) +``` + +
+ +## Best Practices + +1. **List Management** + - Use descriptive names for lists + - Document list purposes in descriptions + - Configure appropriate update intervals + - Monitor list update status + - Review exception lists regularly + +2. **Security** + - Use HTTPS URLs when possible + - Implement proper authentication + - Use client certificates when available + - Regularly rotate credentials + - Monitor list content changes + +3. **Performance** + - Choose appropriate update intervals + - Monitor bandwidth usage + - Use exception lists efficiently + - Consider list size impacts + - Monitor update job status + +## Related Models + +- [AuthModel](../../models/objects/external_dynamic_lists_models.md#Overview) +- [RecurringModels](../../models/objects/external_dynamic_lists_models.md#Overview) +- [TypeModels](../../models/objects/external_dynamic_lists_models.md#Overview) \ No newline at end of file diff --git a/docs/sdk/models/objects/index.md b/docs/sdk/models/objects/index.md index 23f08ef..649b202 100644 --- a/docs/sdk/models/objects/index.md +++ b/docs/sdk/models/objects/index.md @@ -21,6 +21,7 @@ For each configuration object, there are corresponding request and response mode - [Application Models](application_models.md) - [Application Filters Models](application_filters_models.md) - [Application Group Models](application_group_models.md) +- [External Dynamic Lists](external_dynamic_lists_models.md) - [Service Models](service_models.md) - [Service Group Models](service_group_models.md) - [Tag Models](tag_models.md) diff --git a/mkdocs.yml b/mkdocs.yml index a0ca7a1..eb59714 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -42,6 +42,7 @@ nav: - Application: sdk/config/objects/application.md - Application Filters: sdk/config/objects/application_filters.md - Application Group: sdk/config/objects/application_group.md + - External Dynamic Lists: sdk/config/objects/external_dynamic_lists.md - Service: sdk/config/objects/service.md - Service Group: sdk/config/objects/service_group.md - Tag: sdk/config/objects/tag.md @@ -62,6 +63,7 @@ nav: - Application Models: sdk/models/objects/application_models.md - Application Filter Models: sdk/models/objects/application_filters_models.md - Application Group Models: sdk/models/objects/application_group_models.md + - External Dynamic Lists Models: sdk/models/objects/external_dynamic_lists_models.md - Service Models: sdk/models/objects/service_models.md - Service Group Models: sdk/models/objects/service_group_models.md - Tag Models: sdk/models/objects/tag_models.md diff --git a/pyproject.toml b/pyproject.toml index 6511714..f743d3e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "pan-scm-sdk" -version = "0.3.3" +version = "0.3.4" description = "Python SDK for Palo Alto Networks Strata Cloud Manager." authors = ["Calvin Remsburg "] license = "Apache 2.0"