A lightweight Envoy xDS control plane with REST API support to dynamically manage clusters and routes. Implemented in Go using Envoy Go Control Plane v3.

data/ config Fix: Corrected syntax error in sqlite.go ScanRawRow function and staged all modified files 21 hours ago
deployment Fix: Corrected syntax error in sqlite.go ScanRawRow function and staged all modified files 21 hours ago
internal Add fallback to fresh issuance if certificate renewal fails 17 hours ago
static Fix certificate parsing and UI display 18 hours ago
test Fix: Corrected syntax error in sqlite.go ScanRawRow function and staged all modified files 21 hours ago
.env Fix: Corrected syntax error in sqlite.go ScanRawRow function and staged all modified files 21 hours ago
.gitignore Fix: Corrected syntax error in sqlite.go ScanRawRow function and staged all modified files 21 hours ago
Dockerfile Fix: Corrected syntax error in sqlite.go ScanRawRow function and staged all modified files 21 hours ago
Makefile Fix: Corrected syntax error in sqlite.go ScanRawRow function and staged all modified files 21 hours ago
README.md Fix: Corrected syntax error in sqlite.go ScanRawRow function and staged all modified files 21 hours ago
build_image.sh Fix: Corrected syntax error in sqlite.go ScanRawRow function and staged all modified files 21 hours ago
docker-compose.yml Fix: Corrected syntax error in sqlite.go ScanRawRow function and staged all modified files 21 hours ago
envoy.yaml Fix: Corrected syntax error in sqlite.go ScanRawRow function and staged all modified files 21 hours ago
go.mod Fix: Corrected syntax error in sqlite.go ScanRawRow function and staged all modified files 21 hours ago
go.sum Fix: Corrected syntax error in sqlite.go ScanRawRow function and staged all modified files 21 hours ago
main.go Fix: Corrected syntax error in sqlite.go ScanRawRow function and staged all modified files 21 hours ago
save.json Fix: Corrected syntax error in sqlite.go ScanRawRow function and staged all modified files 21 hours ago
README.md

Envoy Control Plane

A lightweight Envoy xDS control plane with REST API support to dynamically manage clusters and routes. Implemented in Go using Envoy Go Control Plane v3.


Features

  • Dynamic xDS snapshot management (clusters & routes)
  • REST API to:
    • Add/remove clusters
    • Add/remove routes
    • Load/save snapshot to JSON files
  • Optional initial snapshot from file at startup
  • Runs an xDS gRPC server compatible with Envoy
  • Fully compatible with types.Resource and Envoy v3 snapshot APIs

Prerequisites

  • Go 1.21+
  • Envoy 1.30+ (or compatible)
  • Ensure GOPATH is set and dependencies are downloaded via go mod tidy

Project Structure

├── internal
│   ├── snapshot.go      # SnapshotManager for clusters/routes
│   ├── rest_api.go      # REST API for managing snapshots
│   └── ...              # other helpers
├── main.go              # Main entry: starts gRPC + REST servers
├── go.mod
└── go.sum

Build

# Clone repo
git clone <repo-url>
cd envoy-control-plane

# Download dependencies
go mod tidy

# Build binary
make all

Binary will be located at bin/xds-server.


Run

./bin/xds-server \
    -port=18000 \
    -rest-port=8080 \
    -nodeID=test-node \
    -snapshot-file=snapshot.json

Flags

Flag Description Default
-port xDS gRPC server port 18000
-rest-port REST API port 8080
-nodeID Node ID for snapshot test-id
-snapshot-file Optional JSON file to load initial snapshot ""

REST API

The REST server allows dynamic control over clusters and routes.

Add Cluster

POST /add-cluster

{
  "name": "cluster1"
}

Response:

{
  "cuid": "cluster1"
}

Remove Cluster

POST /remove-cluster

{
  "name": "cluster1"
}

Response: 200 OK


Add Route

POST /add-route

{
  "name": "route1",
  "cluster": "cluster1",
  "path_prefix": "/api"
}

Response:

{
  "route": "route1"
}

Remove Route

POST /remove-route

{
  "name": "route1"
}

Response: 200 OK


Load Snapshot From File

POST /load-snapshot

{
  "path": "snapshot.json"
}

Response: 200 OK


Save Snapshot To File

POST /save-snapshot

{
  "path": "snapshot.json"
}

Response: 200 OK


Snapshot JSON Format

{
  "envoy.config.cluster.v3.Cluster": [
    {
      "name": "cluster1",
      "connect_timeout": "5s",
      "lb_policy": "ROUND_ROBIN",
      "cluster_discovery_type": { "type": "EDS" }
    }
  ],
  "envoy.config.route.v3.RouteConfiguration": [
    {
      "name": "route1",
      "virtual_hosts": [
        {
          "name": "vh-route1",
          "domains": ["*"],
          "routes": [
            {
              "match": { "prefix": "/api" },
              "route": { "cluster": "cluster1" }
            }
          ]
        }
      ]
    }
  ]
}

Each top-level key is the full type URL of the resource. Clusters and routes can be added dynamically via REST or preloaded from a snapshot JSON file.


Connecting Envoy

Configure Envoy with:

dynamic_resources:
  ads_config:
    api_type: GRPC
    grpc_services:
      - envoy_grpc:
          cluster_name: xds_cluster
  cds_config: {}
  lds_config: {}
  • Set xds_cluster to point to your control plane gRPC server (e.g., localhost:18000)
  • Envoy will pull clusters and routes dynamically

License

Apache 2.0 License