feat(zerotier): add ZeroTier network governance module

Add comprehensive ZeroTier integration for managing network access:

- Portal networks: manager-created ZeroTier network bindings
- Device registration: user-owned ZeroTier node endpoints
- Approval workflows: request/approve/revoke network access
- Activation sessions: time-limited network authorization
- Kill switch: emergency access revocation
- Reconciliation job: sync portal state with ZeroTier controller

Includes ZeroTier client SDK supporting both Central and self-hosted
controller APIs, with full CRUD operations for networks and members.
This commit is contained in:
2026-03-20 21:50:20 +10:30
parent 49e724222f
commit 1789590167
27 changed files with 4862 additions and 4 deletions
+24
View File
@@ -34,6 +34,19 @@ from gatehouse_app.exceptions.ssh_exceptions import (
DepartmentError,
DepartmentNotFoundError,
)
from gatehouse_app.exceptions.zerotier_exceptions import (
ZeroTierAPIError,
ZeroTierAuthError,
ZeroTierNotFoundError,
NetworkNotFoundError,
DeviceNotFoundError,
ApprovalNotFoundError,
MembershipNotFoundError,
DeviceAlreadyExistsError,
ApprovalAlreadyExistsError,
InvalidNodeIdError,
InvalidNetworkIdError,
)
__all__ = [
"BaseAPIException",
@@ -65,5 +78,16 @@ __all__ = [
"PrincipalNotFoundError",
"DepartmentError",
"DepartmentNotFoundError",
"ZeroTierAPIError",
"ZeroTierAuthError",
"ZeroTierNotFoundError",
"NetworkNotFoundError",
"DeviceNotFoundError",
"ApprovalNotFoundError",
"MembershipNotFoundError",
"DeviceAlreadyExistsError",
"ApprovalAlreadyExistsError",
"InvalidNodeIdError",
"InvalidNetworkIdError",
]
@@ -0,0 +1,69 @@
"""ZeroTier-specific exceptions."""
from gatehouse_app.exceptions.base import BaseAPIException
class ZeroTierAPIError(BaseAPIException):
status_code = 502
error_type = "ZEROTIER_API_ERROR"
message = "ZeroTier API error"
class ZeroTierAuthError(ZeroTierAPIError):
status_code = 401
error_type = "ZEROTIER_AUTH_ERROR"
message = "ZeroTier API authentication failed"
class ZeroTierNotFoundError(ZeroTierAPIError):
status_code = 404
error_type = "ZEROTIER_NOT_FOUND"
message = "ZeroTier network or member not found"
class NetworkNotFoundError(ZeroTierAPIError):
status_code = 404
error_type = "NETWORK_NOT_FOUND"
message = "Portal network not found"
class DeviceNotFoundError(ZeroTierAPIError):
status_code = 404
error_type = "DEVICE_NOT_FOUND"
message = "Device not found"
class ApprovalNotFoundError(ZeroTierAPIError):
status_code = 404
error_type = "APPROVAL_NOT_FOUND"
message = "Network approval not found"
class MembershipNotFoundError(ZeroTierAPIError):
status_code = 404
error_type = "MEMBERSHIP_NOT_FOUND"
message = "Device network membership not found"
class DeviceAlreadyExistsError(ZeroTierAPIError):
status_code = 409
error_type = "DEVICE_ALREADY_EXISTS"
message = "A device with this node ID already exists"
class ApprovalAlreadyExistsError(ZeroTierAPIError):
status_code = 409
error_type = "APPROVAL_ALREADY_EXISTS"
message = "An approval already exists for this user and network"
class InvalidNodeIdError(ZeroTierAPIError):
status_code = 400
error_type = "INVALID_NODE_ID"
message = "Invalid ZeroTier node ID"
class InvalidNetworkIdError(ZeroTierAPIError):
status_code = 400
error_type = "INVALID_NETWORK_ID"
message = "Invalid ZeroTier network ID"