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 add function to load filter chain from yaml 13 days ago
internal implementation creation flow 13 days ago
static fix deployment issue 15 days ago
.gitignore add deployment code and modify 18 days ago
Dockerfile fix deployment issue 15 days ago
Makefile add deployment code and modify 18 days ago
README.md inital commit 18 days ago
docker-compose.yml fix deployment issue 15 days ago
go.mod split the code 13 days ago
go.sum split the code 13 days ago
main.go implementation creation flow 13 days ago
save.json Add database persistence and consistency check between in-memory cache and DB. 15 days 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