Newer
Older
EnvoyControlPlane / 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