NAT Rules¶
The NatRule class manages NAT rule objects in Palo Alto Networks' Strata Cloud Manager. It extends from BaseObject and offers methods to create, retrieve, update, list, fetch, and delete NAT rules. Additionally, it provides client-side filtering for listing operations and enforces container requirements using the folder, snippet, or device parameters.
Class Overview¶
from scm.client import Scm
# Initialize client
client = Scm(
client_id="your_client_id",
client_secret="your_client_secret",
tsg_id="your_tsg_id"
)
# Access the NAT Rule service directly through the client
nat_rules = client.nat_rule
| Method | Description | Parameters | Return Type |
|---|---|---|---|
create() |
Creates a new NAT rule object | data: Dict[str, Any], position: str = "pre" |
NatRuleResponseModel |
get() |
Retrieves a NAT rule object by its unique ID | object_id: str |
NatRuleResponseModel |
update() |
Updates an existing NAT rule object | rule: NatRuleUpdateModel, position: str = "pre" |
NatRuleResponseModel |
list() |
Lists NAT rule objects with optional filtering and containers | folder: Optional[str], snippet: Optional[str], device: Optional[str], position: str = "pre", exact_match: bool = False, plus additional filters |
List[NatRuleResponseModel] |
fetch() |
Fetches a single NAT rule by its name within a container | name: str, folder: Optional[str], snippet: Optional[str], device: Optional[str], position: str = "pre" |
NatRuleResponseModel |
delete() |
Deletes a NAT rule object by its ID | object_id: str |
None |
NAT Rule Model Attributes¶
| Attribute | Type | Required | Default | Description |
|---|---|---|---|---|
name |
str | Yes | None | The name of the NAT rule. Pattern: ^[a-zA-Z0-9_ \.-]+$ |
id |
UUID | Yes* | None | Unique identifier (*response/update only) |
description |
str | No | None | Description of the NAT rule |
nat_type |
NatType | No | ipv4 | The type of NAT rule (ipv4, nat64, nptv6) |
from_ |
List[str] | No | ["any"] | Source zone(s) (alias: from) |
to_ |
List[str] | No | ["any"] | Destination zone(s) (alias: to) |
to_interface |
str | No | None | Destination interface of the original packet |
source |
List[str] | No | ["any"] | Source addresses for the NAT rule |
destination |
List[str] | No | ["any"] | Destination addresses for the NAT rule |
service |
str | No | "any" | The TCP/UDP service associated with the NAT translation |
tag |
List[str] | No | [] | Tags associated with the NAT rule |
disabled |
bool | No | False | Indicates whether the NAT rule is disabled |
source_translation |
SourceTranslation | No | None | Source translation configuration |
destination_translation |
DestinationTranslation | No | None | Destination translation configuration |
active_active_device_binding |
str | No | None | Active/Active device binding |
folder |
str | No** | None | The folder container. Max 64 chars |
snippet |
str | No** | None | The snippet container. Max 64 chars |
device |
str | No** | None | The device container. Max 64 chars |
* Only required for update and response models ** Exactly one container (folder/snippet/device) must be provided for create operations
Source Translation Types¶
The NAT rules model supports three different types of source translation methods, following a discriminated union pattern where exactly one type must be provided:
1. Dynamic IP and Port (PAT)¶
This is the most common NAT type, where multiple internal IP addresses are translated to use a single external IP with dynamic ports.
nat_rule_data = {
"name": "dynamic-ip-port-rule",
"source_translation": {
"dynamic_ip_and_port": {
"type": "dynamic_ip_and_port",
"translated_address": ["192.168.1.100"] # Single or multiple IP addresses
}
},
"folder": "NAT Rules"
}
Alternatively, you can use an interface for translation:
nat_rule_data = {
"name": "interface-translation-rule",
"source_translation": {
"dynamic_ip_and_port": {
"type": "dynamic_ip_and_port",
"interface_address": {
"interface": "ethernet1/1",
"ip": "192.168.1.1",
"floating_ip": "192.168.1.100" # Optional
}
}
},
"folder": "NAT Rules"
}
2. Dynamic IP (NAT)¶
Dynamic IP NAT allows multiple internal IPs to be translated to a pool of external IPs without port translation.
nat_rule_data = {
"name": "dynamic-ip-rule",
"source_translation": {
"dynamic_ip": {
"translated_address": ["192.168.1.100", "192.168.1.101"],
"fallback_type": "translated_address", # Optional
"fallback_address": ["10.0.0.100"] # Optional
}
},
"folder": "NAT Rules"
}
3. Static IP¶
This provides a one-to-one mapping between internal and external IPs, optionally with bi-directional support.
nat_rule_data = {
"name": "static-ip-rule",
"source_translation": {
"static_ip": {
"translated_address": "192.168.1.100",
"bi_directional": "yes" # Optional, must be string "yes" or "no"
}
},
"folder": "NAT Rules"
}
Exceptions¶
| Exception | HTTP Code | Description |
|---|---|---|
InvalidObjectError |
400 | Thrown when provided data or parameters are invalid |
MissingQueryParameterError |
400 | Thrown when required query parameters (e.g., name or folder) are missing |
NameNotUniqueError |
409 | NAT rule name already exists in the container |
ObjectNotPresentError |
404 | NAT rule not found |
AuthenticationError |
401 | Authentication failed |
ServerError |
500 | Internal server error |
In addition to these HTTP exceptions, the model validation may raise ValueError for various validation issues, such as:
- Using tags other than strings
- Using DNS rewrite with NAT64 rule type
- Using bi-directional static NAT with destination translation
- Providing invalid source translation configurations
- Violating the container requirements
Methods¶
List NAT Rules¶
# List all NAT rules in a folder
nat_rules_list = client.nat_rule.list(folder="Texas")
# Process results
for rule in nat_rules_list:
print(f"Name: {rule.name}, Service: {rule.service}")
# Check source translation type
if rule.source_translation:
if rule.source_translation.dynamic_ip_and_port:
print(" Translation: Dynamic IP and Port (PAT)")
elif rule.source_translation.dynamic_ip:
print(" Translation: Dynamic IP (NAT)")
elif rule.source_translation.static_ip:
print(" Translation: Static IP")
# List with position parameter
pre_rules = client.nat_rule.list(folder="Texas", position="pre")
post_rules = client.nat_rule.list(folder="Texas", position="post")
Filtering Responses¶
The list() method supports additional filtering parameters:
Parameters:
exact_match (bool): WhenTrue, only objects defined exactly in the specified container are returnedexclude_folders (List[str]): List of folder names to exclude from resultsexclude_snippets (List[str]): List of snippet values to exclude from resultsexclude_devices (List[str]): List of device values to exclude from resultsnat_type (List[str]): Filter by NAT types (e.g.,["ipv4", "nat64"])service (List[str]): Filter by servicesdestination (List[str]): Filter by destination addressessource (List[str]): Filter by source addressestag (List[str]): Filter by tagsdisabled (bool): Filter by disabled status
Examples:
# List with exact match on container
exact_rules = client.nat_rule.list(
folder="Texas",
exact_match=True
)
# Filter by NAT type
ipv4_rules = client.nat_rule.list(
folder="Texas",
nat_type=["ipv4"]
)
# Filter by disabled status
enabled_rules = client.nat_rule.list(
folder="Texas",
disabled=False
)
# Filter by tags
tagged_rules = client.nat_rule.list(
folder="Texas",
tag=["Automation", "Production"]
)
# Exclude specific folders from results
no_shared_rules = client.nat_rule.list(
folder="Texas",
exclude_folders=["Shared"]
)
# Combine multiple filters
filtered_rules = client.nat_rule.list(
folder="Texas",
position="pre",
nat_type=["ipv4"],
disabled=False,
tag=["Automation"]
)
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.
from scm.client import Scm
# Initialize client
client = Scm(
client_id="your_client_id",
client_secret="your_client_secret",
tsg_id="your_tsg_id"
)
# Configure max_limit using the property setter
client.nat_rule.max_limit = 1000
# List all NAT rules - auto-paginates through results
all_rules = client.nat_rule.list(folder="Texas")
Fetch a NAT Rule¶
# Fetch by name and folder
fetched_rule = client.nat_rule.fetch(
name="nat-rule-1",
folder="Texas"
)
print(f"Fetched NAT Rule: {fetched_rule.name}")
# Retrieve a NAT rule by its unique ID
rule_by_id = client.nat_rule.get(fetched_rule.id)
print(f"NAT Rule ID: {rule_by_id.id}, Name: {rule_by_id.name}")
Create a NAT Rule¶
from scm.client import Scm
# Initialize client
client = Scm(
client_id="your_client_id",
client_secret="your_client_secret",
tsg_id="your_tsg_id"
)
# Define NAT rule configuration data with dynamic IP and port translation
nat_rule_data = {
"name": "nat-rule-1",
"nat_type": "ipv4",
"service": "any",
"destination": ["any"],
"source": ["10.0.0.0/24"],
"tag": ["Automation"],
"disabled": False,
"source_translation": {
"dynamic_ip_and_port": {
"type": "dynamic_ip_and_port",
"translated_address": ["192.168.1.100"]
}
},
"folder": "Texas"
}
# Create a new NAT rule (default position is 'pre')
new_nat_rule = client.nat_rule.create(nat_rule_data)
print(f"Created NAT rule with ID: {new_nat_rule.id}")
# Create a static NAT rule with bi-directional translation
static_nat_data = {
"name": "static-nat-rule",
"nat_type": "ipv4",
"service": "any",
"destination": ["any"],
"source": ["10.0.0.10"],
"source_translation": {
"static_ip": {
"translated_address": "192.168.1.100",
"bi_directional": "yes"
}
},
"folder": "Texas"
}
static_nat_rule = client.nat_rule.create(static_nat_data)
print(f"Created static NAT rule with ID: {static_nat_rule.id}")
Update a NAT Rule¶
# Fetch existing NAT rule
existing_rule = client.nat_rule.fetch(
name="nat-rule-1",
folder="Texas"
)
# Modify attributes using dot notation
existing_rule.disabled = True
existing_rule.description = "Updated NAT rule"
existing_rule.source = ["10.0.0.0/24", "10.0.1.0/24"]
existing_rule.source_translation = {
"dynamic_ip": {
"translated_address": ["192.168.1.100", "192.168.1.101"]
}
}
# Perform update
updated_rule = client.nat_rule.update(existing_rule)
print(f"Updated NAT Rule: {updated_rule.name}")
Delete a NAT Rule¶
# Get the rule to delete
rule = client.nat_rule.fetch(name="nat-rule-1", folder="Texas")
# Delete by ID
client.nat_rule.delete(str(rule.id))
print(f"Deleted NAT rule: {rule.name}")
Use Cases¶
Performing Commits¶
# Prepare commit parameters
commit_params = {
"folders": ["Texas"],
"description": "Updated NAT rules",
"sync": True,
"timeout": 300 # 5 minute timeout
}
# Commit the changes
result = client.commit(**commit_params)
print(f"Commit job ID: {result.job_id}")
Monitoring Jobs¶
# Get status of specific job
job_status = client.get_job_status(result.job_id)
print(f"Job status: {job_status.data[0].status_str}")
# List recent jobs
recent_jobs = client.list_jobs(limit=10)
for job in recent_jobs.data:
print(f"Job {job.id}: {job.type_str} - {job.status_str}")
Error Handling¶
from scm.client import Scm
from scm.exceptions import (
InvalidObjectError,
MissingQueryParameterError,
NameNotUniqueError,
ObjectNotPresentError
)
# Initialize client
client = Scm(
client_id="your_client_id",
client_secret="your_client_secret",
tsg_id="your_tsg_id"
)
try:
# Create NAT rule
nat_rule_data = {
"name": "test-nat-rule",
"source": ["10.0.0.0/24"],
"source_translation": {
"dynamic_ip_and_port": {
"type": "dynamic_ip_and_port",
"translated_address": ["192.168.1.100"]
}
},
"folder": "Texas"
}
new_rule = client.nat_rule.create(nat_rule_data)
# Commit changes
result = client.commit(
folders=["Texas"],
description="Added NAT rule",
sync=True
)
# Check job status
status = client.get_job_status(result.job_id)
except InvalidObjectError as e:
print(f"Invalid rule data: {e.message}")
except NameNotUniqueError as e:
print(f"Rule name already exists: {e.message}")
except ObjectNotPresentError as e:
print(f"Rule not found: {e.message}")
except MissingQueryParameterError as e:
print(f"Missing parameter: {e.message}")
Related Topics¶
- NatRuleBaseModel
- NatRuleCreateModel
- NatRuleUpdateModel
- NatRuleResponseModel
- NatRuleMoveModel
- SourceTranslation
- DynamicIpAndPort
- DynamicIp
- StaticIp
- DestinationTranslation
- DnsRewrite
- InterfaceAddress
- NatType
- NatMoveDestination
- NatRulebase
- BiDirectional
- DnsRewriteDirection
Refer to the nat_rule.py example for a complete implementation.