How CasaOS Implements Gateway Route Creation for API Paths

CasaOS delegates gateway route creation to the CasaOS-Common ManagementService interface, which it instantiates at startup and exposes through a service container, allowing HTTP handlers to create network routes by calling Gateway().AddRoute() while keeping the API layer decoupled from underlying network implementations like ZeroTier or Docker.

CasaOS is an open-source home server operating system that manages network routing through a centralized gateway service. Understanding how it implements gateway route creation for API paths reveals a clean separation between the HTTP API layer and network backend implementations. The architecture relies on the CasaOS-Common library to handle the actual route manipulation while the main application focuses on request routing and business logic.

Management Service Architecture

CasaOS initializes its gateway capabilities through the external package from CasaOS-Common. When the service container starts in service/service.go, it creates a management service instance that provides the interface for route manipulation.

Instantiating the Gateway Service

During service initialization, the application calls external.NewManagementService() with the runtime path to create the gateway manager:

// service/service.go L48-L51
gatewayManagement, err := external.NewManagementService(RuntimePath)
if err != nil && len(RuntimePath) > 0 {
    panic(err)
}

This gatewayManagement object implements the external.ManagementService interface and is stored in the service container's store struct at lines 78-80:

// service/service.go L78-L80
type store struct {
    gateway external.ManagementService
    // ... other fields
}

The gateway is exposed to the rest of the application through a simple accessor method at lines 97-99:

// service/service.go L97-L99
func (c *store) Gateway() external.ManagementService {
    return c.gateway
}

This pattern ensures that any component requiring gateway functionality accesses it through the service container's Gateway() method, maintaining a consistent dependency injection pattern throughout the codebase.

HTTP Layer Integration

The API layer uses the Echo framework to handle HTTP requests, with route definitions located in route/v2/route.go. While these routes define the API surface, they delegate network operations to the gateway service stored in the container.

Accessing the Gateway in Handlers

HTTP handlers obtain the gateway service by instantiating the service container and calling Gateway(). This pattern appears consistently across the v2 API routes:

// General pattern used in route handlers
gw := service.NewService(db, runtimePath).Gateway()
// Then use gw.AddRoute(), gw.Health(), etc.

This approach keeps the HTTP handlers thin, focusing only on request validation and response formatting, while the actual route creation logic remains encapsulated in the CasaOS-Common implementation.

Example: ZeroTier Network Routing

The ZeroTier integration in route/v2/zerotier.go demonstrates the practical implementation of gateway route creation. When managing ZeroTier networks, handlers fetch network information and then use the gateway service to create or modify routes.

Creating Routes for ZeroTier Networks

The handler pattern follows this structure:

// route/v2/zerotier.go - conceptual example
func (s *CasaOS) EnableZerotierNetwork(ctx echo.Context, networkID string) error {
    // Obtain the gateway manager from the global service container
    gw := service.NewService(nil, config.CommonInfo.RuntimePath).Gateway()

    // Ask the gateway to add a route for the ZeroTier network
    if err := gw.AddRoute(codegen.GatewayRoute{
        NetworkID:   networkID,
        Destination: "10.0.0.0/24",
    }); err != nil {
        return ctx.JSON(http.StatusInternalServerError,
            codegen.BaseResponse{Message: utils.Ptr(err.Error())})
    }
    return ctx.JSON(http.StatusOK, codegen.BaseResponse{Message: utils.Ptr("route added")})
}

The concrete AddRoute implementation resides in the CasaOS-Common external package, but the call pattern in CasaOS follows the consistent c.Gateway().<method>(...) convention.

End-to-End Request Flow

The complete flow for gateway route creation for API paths follows a clear delegation pattern:

  1. Client Request - A request hits an API path like /api/v2/zerotier/info
  2. Echo Handler - The handler in route/v2/zerotier.go validates the request and extracts parameters
  3. Service Container - The handler calls service.NewService().Gateway() to retrieve the ManagementService instance
  4. Gateway Operation - The handler invokes gw.AddRoute() or similar methods, passing codegen.GatewayRoute objects
  5. Backend Implementation - The CasaOS-Common external package translates these calls into specific operations for ZeroTier, Docker networks, or other backends
  6. Response - Results flow back through the handler to the client

This architecture allows CasaOS to support multiple networking backends without modifying the API layer. The ManagementService interface abstracts the specific implementation details, whether the underlying technology is ZeroTier, Docker bridge networking, or future protocols.

Summary

  • CasaOS-Common Delegation: Gateway functionality is implemented in the separate CasaOS-Common repository through the external.ManagementService interface, not in the main CasaOS repository.
  • Service Container Pattern: The store struct in service/service.go holds the gateway instance and exposes it via the Gateway() accessor method.
  • Echo Framework Integration: API routes in route/v2/ use Echo handlers that retrieve the gateway service from the container to perform network operations.
  • ZeroTier Example: The file route/v2/zerotier.go demonstrates practical usage of gw.AddRoute() to manage network routes based on API requests.
  • Runtime Path Dependency: The external.NewManagementService() function requires a RuntimePath parameter to initialize the connection to underlying network services.

Frequently Asked Questions

What is the CasaOS-Common ManagementService?

The ManagementService is an interface defined in the CasaOS-Common repository that provides methods like AddRoute(), DeleteRoute(), and Health() for managing network gateway operations. CasaOS imports this interface and stores an implementation in its service container, allowing the main application to manipulate network routes without knowing the specific backend technology being used.

How does CasaOS handle different network backends?

CasaOS achieves backend independence through the external.ManagementService interface. Whether the underlying network uses ZeroTier, Docker bridge networks, or other technologies, the CasaOS-Common implementation handles the specific API calls. The main CasaOS codebase only interacts with the abstract interface, making it possible to switch or add network backends by updating the CasaOS-Common library without changing the HTTP API layer.

Where are API routes defined in CasaOS?

API routes are defined in the route/v2/ directory (and route/v1/ for legacy endpoints), specifically in files like route/v2/route.go for general routing and route/v2/zerotier.go for network-specific endpoints. These files use the Echo framework to register handlers, but the actual gateway route creation logic is delegated to the service container's Gateway() method.

How do I create a custom gateway route in CasaOS?

To create a custom gateway route, you need to obtain the ManagementService from the service container using service.NewService(db, runtimePath).Gateway(), then call AddRoute() with a codegen.GatewayRoute struct containing the network ID and destination. This follows the same pattern used in route/v2/zerotier.go, where handlers validate input parameters before passing them to the gateway service.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →