A Python client library for both OPNsense and pfSense.
Project description
Routers
Project Overview
The Routers project is a Python-based tool designed to manage firewall aliases across different routers, specifically pfSense (v1 and v2) and OPNsense. It provides a unified interface for creating, updating, deleting, and renaming firewall aliases, while abstracting away the differences between the APIs of these platforms.
This tool leverages client libraries for pfSense and OPNsense APIs, allowing seamless interaction with their
respective firewall alias management functionalities. The core of the project is the Router class which handles
connection to different router types, and the alias adapters which convert between internal data structures and
router-specific models.
Features
- Unified Router Management: Connect to pfSense v1, pfSense v2, and OPNsense routers using a common interface.
- Advanced Alias Operations: Create, update, delete, and rename firewall aliases without needing to know the details of the underlying API.
- Secure Configuration Storage: Store router connection details securely using Redis with encryption.
- Adapter Architecture: Flexible adapter system to handle different router types and API versions.
- Difference Detection: Identify differences between aliases across routers to help with synchronization.
- Comprehensive Testing: Includes a robust test suite with mock objects to ensure code correctness without needing live routers.
Installation
Prerequisites
- Python 3.14 or higher
- Core dependencies:
pyfsense-client- Client library for pfSenseopn-api- Client library for OPNsenseredis[hiredis]- For configuration storagecryptography- For secure configuration storage- Additional dependencies specified in pyproject.toml
Steps
-
Clone this repository:
git clone https://github.com/devinbarry/routers.git cd routers
-
Install dependencies:
uv sync
Project Structure
routers/
│
├── src/routers/
│ ├── __init__.py
│ ├── settings.py # Environment configuration
│ ├── firewall.py # Firewall utilities
│ ├── alias/ # Alias management
│ │ ├── types.py # Alias dataclass, AliasType enum
│ │ ├── operations.py # High-level sync operations
│ │ ├── loader.py # JSON alias loading & reference lookup
│ │ ├── adapter_factory.py # Creates adapter for a given router
│ │ ├── type_conversions.py # Router-specific format conversions
│ │ ├── exceptions.py # Alias exceptions
│ │ └── adapter/ # Platform-specific adapters
│ │ ├── base.py # Abstract adapter interface
│ │ ├── pfsense_v1.py # pfSense v1 adapter
│ │ ├── pfsense_v2.py # pfSense v2 adapter
│ │ └── opnsense.py # OPNsense adapter
│ ├── client/
│ │ └── pfsense_v2.py # PfSenseV2MetaClient wrapper
│ └── router/
│ ├── core.py # Router dataclass, RouterType, ClientFactory
│ ├── exceptions.py # Router exceptions
│ └── config/
│ ├── encrypt.py # Fernet-encrypted Redis wrapper
│ └── store.py # ConfigLoader & CredentialStore
│
├── tests/ # Test suite organized by module
├── pyproject.toml
└── README.md
Usage
Initialize a Router
from routers import Router, RouterType
router = Router(name="MyRouter", type=RouterType.PFSENSE_V2)
Router credentials are loaded from encrypted Redis via ConfigLoader. See router/config/ for setup.
Direct Alias Operations (Adapter)
Use the adapter for direct CRUD on individual aliases:
from routers.alias.adapter_factory import get_alias_adapter
from routers.alias.types import Alias, AliasType
adapter = get_alias_adapter(router)
# List all aliases
aliases = adapter.get_all_aliases()
# Create
alias = Alias(
name="BlockList",
alias_type=AliasType.HOST,
description="Block list of IPs",
content=["192.168.1.1", "192.168.1.2"],
detail=["IP1", "IP2"],
)
adapter.create_alias(alias)
# Update
alias.description = "Updated block list"
adapter.update_alias(alias)
# Delete
adapter.delete_alias("BlockList")
# Rename
adapter.rename_alias(alias, "NewBlockList")
Sync Operations (Reference-Based)
The operations module syncs router aliases against reference definitions:
from routers.alias.operations import (
print_differing_client_aliases,
update_differences_on_client,
create_new_on_client,
delete_missing_reference_aliases,
)
# Show differences between router state and reference aliases
print_differing_client_aliases(router)
# Sync: update differing aliases, create missing ones
update_differences_on_client(router)
# Create only missing aliases (no updates)
create_new_on_client(router)
# Delete aliases not in the reference list
delete_missing_reference_aliases(router)
Test Suite
Run the tests with pytest:
uv run pytest
Tests use mock objects -- no live routers required.
Contributing
Contributions are welcome. Fork the repository, submit a pull request, and include tests where applicable.
License
This project is licensed under the AGPLv3 License. See the LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file routers-0.1.3.tar.gz.
File metadata
- Download URL: routers-0.1.3.tar.gz
- Upload date:
- Size: 42.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4c224265148d3393f73c96d755e25677916e356cfb1d8b21e24e775e11c8352e
|
|
| MD5 |
05c08fd65a8031d04878967440fb0a2f
|
|
| BLAKE2b-256 |
e9d188cf23d46688731f5ab7398903b4450e22bb042d2f538e070d2eeabad65c
|
File details
Details for the file routers-0.1.3-py3-none-any.whl.
File metadata
- Download URL: routers-0.1.3-py3-none-any.whl
- Upload date:
- Size: 47.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0ba995358d0840b333d56a2cf742e7d1738de0a12e6018e3fb337ca50545de1e
|
|
| MD5 |
1221f5d5cd41635ecd9c6c5132a132c8
|
|
| BLAKE2b-256 |
db557f61464d9831114ac4dd0424e6cadbebc5d51722640832facea0f2a6fe29
|