Quick Start Guide¶
Get up and running with the PAN Config Viewer API in minutes!
Prerequisites¶
- Python 3.8 or higher
- PAN-OS Panorama configuration backup file (XML)
- 2GB RAM minimum
- 10GB disk space for large configurations
Installation¶
Using pip¶
Using Docker¶
docker pull pan-config-viewer:latest
docker run -p 8000:8000 -v /path/to/configs:/configs pan-config-viewer
From Source¶
git clone https://github.com/fahadysf/pan-config-viewer.git
cd pan-config-viewer
pip install -r requirements.txt
Configuration¶
1. Set Configuration Path¶
Create a .env
file or set environment variables:
# .env file
CONFIG_FILES_PATH=/path/to/panorama/configs
DEFAULT_CONFIG=panorama-backup.xml
API_PORT=8000
API_HOST=0.0.0.0
2. Place Configuration Files¶
Copy your Panorama XML backup files to the configuration directory:
Starting the Server¶
Development Mode¶
Production Mode¶
Using Docker¶
docker run -d \
--name pan-config-viewer \
-p 8000:8000 \
-v /path/to/configs:/configs \
-e CONFIG_FILES_PATH=/configs \
pan-config-viewer
Verify Installation¶
1. Check API Health¶
Expected response:
2. List Available Configurations¶
Expected response:
3. Access API Documentation¶
Open your browser and navigate to: - Swagger UI: http://localhost:8000/docs - ReDoc: http://localhost:8000/redoc
Your First API Calls¶
1. List All Address Objects¶
2. Search for Specific Addresses¶
3. Filter by IP Range¶
curl -X GET "http://localhost:8000/api/v1/configs/panorama/addresses?\
filter.ip.starts_with=10.&\
filter.type.equals=ip-netmask"
4. Query Security Rules¶
curl -X GET "http://localhost:8000/api/v1/configs/panorama/rules/security?\
filter.action.equals=allow&\
limit=10"
5. Find Services by Port¶
curl -X GET "http://localhost:8000/api/v1/configs/panorama/services?\
filter.port.equals=443&\
filter.protocol.equals=tcp"
Using the Web Interface¶
The API includes a web-based viewer at http://localhost:8000/viewer
Features: - Visual configuration browser - Real-time filtering - Export to CSV/JSON - Advanced search capabilities
Common Filtering Patterns¶
Basic Contains Filter (Default)¶
# Find addresses containing "web"
curl "http://localhost:8000/api/v1/configs/panorama/addresses?filter.name=web"
Exact Match¶
# Find exact address by name
curl "http://localhost:8000/api/v1/configs/panorama/addresses?filter.name.equals=web-server-01"
Numeric Comparison¶
# Find services on high ports
curl "http://localhost:8000/api/v1/configs/panorama/services?filter.port.gt=8000"
Multiple Filters (AND Logic)¶
# Find production servers in DMZ
curl "http://localhost:8000/api/v1/configs/panorama/addresses?\
filter.tag.in=production&\
filter.parent_device_group.equals=DMZ"
Working with Pagination¶
Basic Pagination¶
# Get first 20 items
curl "http://localhost:8000/api/v1/configs/panorama/addresses?limit=20&offset=0"
# Get next 20 items
curl "http://localhost:8000/api/v1/configs/panorama/addresses?limit=20&offset=20"
Pagination Response¶
{
"items": [...],
"total_items": 1250,
"page": 1,
"page_size": 20,
"total_pages": 63,
"has_next": true,
"has_previous": false
}
Python Quick Start¶
import requests
import json
class PanConfigClient:
def __init__(self, base_url="http://localhost:8000"):
self.base_url = base_url
self.api_base = f"{base_url}/api/v1"
def get_addresses(self, **filters):
"""Get address objects with optional filters"""
params = {f"filter.{k}": v for k, v in filters.items()}
response = requests.get(
f"{self.api_base}/configs/panorama/addresses",
params=params
)
return response.json()
def get_security_rules(self, **filters):
"""Get security rules with optional filters"""
params = {f"filter.{k}": v for k, v in filters.items()}
response = requests.get(
f"{self.api_base}/configs/panorama/rules/security",
params=params
)
return response.json()
def search_by_ip(self, ip_prefix):
"""Search for addresses by IP prefix"""
return self.get_addresses(
**{"ip.starts_with": ip_prefix, "type.equals": "ip-netmask"}
)
# Usage
client = PanConfigClient()
# Find all web servers
web_servers = client.get_addresses(**{"name.contains": "web"})
print(f"Found {web_servers['total_items']} web servers")
# Find allow rules from trust zone
trust_rules = client.get_security_rules(
**{"from.in": "trust", "action.equals": "allow"}
)
print(f"Found {trust_rules['total_items']} allow rules from trust zone")
# Search by IP
subnet_addresses = client.search_by_ip("10.0.0")
for addr in subnet_addresses["items"][:5]:
print(f"- {addr['name']}: {addr['ip-netmask']}")
JavaScript Quick Start¶
class PanConfigAPI {
constructor(baseUrl = 'http://localhost:8000') {
this.baseUrl = baseUrl;
this.apiBase = `${baseUrl}/api/v1`;
}
async getAddresses(filters = {}) {
const params = new URLSearchParams();
Object.entries(filters).forEach(([key, value]) => {
params.append(`filter.${key}`, value);
});
const response = await fetch(
`${this.apiBase}/configs/panorama/addresses?${params}`
);
return response.json();
}
async getSecurityRules(filters = {}) {
const params = new URLSearchParams();
Object.entries(filters).forEach(([key, value]) => {
params.append(`filter.${key}`, value);
});
const response = await fetch(
`${this.apiBase}/configs/panorama/rules/security?${params}`
);
return response.json();
}
}
// Usage
const api = new PanConfigAPI();
// Find all FQDN addresses
api.getAddresses({ 'type.equals': 'fqdn' })
.then(data => {
console.log(`Found ${data.total_items} FQDN addresses`);
data.items.slice(0, 5).forEach(addr => {
console.log(`- ${addr.name}: ${addr.fqdn}`);
});
});
// Find high-risk rules
api.getSecurityRules({
'source.in': 'any',
'destination.in': 'any',
'action.equals': 'allow'
}).then(data => {
console.log(`Found ${data.total_items} high-risk rules`);
});
cURL Examples¶
With Pretty Output¶
# Using jq for JSON formatting
curl -s "http://localhost:8000/api/v1/configs/panorama/addresses?limit=5" | jq '.'
# Using python for formatting
curl -s "http://localhost:8000/api/v1/configs/panorama/addresses?limit=5" | python -m json.tool
Save to File¶
# Save all addresses to file
curl -s "http://localhost:8000/api/v1/configs/panorama/addresses" > addresses.json
# Save filtered results
curl -s "http://localhost:8000/api/v1/configs/panorama/addresses?\
filter.tag.in=production" > production_addresses.json
Using Variables¶
# Set base URL
BASE_URL="http://localhost:8000/api/v1/configs/panorama"
# Query with variables
curl -s "$BASE_URL/addresses?filter.type.equals=fqdn"
curl -s "$BASE_URL/services?filter.port.gt=8000"
curl -s "$BASE_URL/rules/security?filter.disabled.equals=true"
Troubleshooting¶
Server Not Starting¶
# Check if port is in use
lsof -i :8000
# Check Python version
python --version # Should be 3.8+
# Check dependencies
pip list | grep -E "fastapi|uvicorn|pydantic"
No Configuration Found¶
# Verify config path
echo $CONFIG_FILES_PATH
# Check file permissions
ls -la /path/to/configs/
# Verify XML format
xmllint --noout /path/to/configs/panorama.xml
Slow Performance¶
# Increase workers
gunicorn main:app -w 8 -k uvicorn.workers.UvicornWorker
# Enable caching
export ENABLE_CACHE=true
export CACHE_TTL=3600
Next Steps¶
- Explore Filtering - Master the powerful filtering system
- Operator Reference - All operators with examples
- Complex Examples - Real-world usage examples
- API Endpoints - Detailed endpoint documentation