Skip to content

Commit 55adc5e

Browse files
committed
add config viewer
Signed-off-by: JaredforReal <[email protected]>
1 parent b187042 commit 55adc5e

File tree

7 files changed

+998
-52
lines changed

7 files changed

+998
-52
lines changed

dashboard/backend/Dockerfile

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,19 @@ RUN npm run build
1111
# Stage 2: Build backend with Go
1212
FROM golang:1.24 AS backend-builder
1313
WORKDIR /app
14-
COPY dashboard/backend/ /app/dashboard/backend/
14+
15+
# Use Chinese Go proxy to avoid network timeout issues
16+
ENV GOPROXY=https://goproxy.cn,direct
17+
ENV GOSUMDB=sum.golang.google.cn
18+
19+
# Copy go.mod and go.sum first for better caching
20+
COPY dashboard/backend/go.mod dashboard/backend/go.sum /app/dashboard/backend/
1521
WORKDIR /app/dashboard/backend
16-
RUN go mod download || true
17-
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /app/dashboard-backend main.go
22+
RUN go mod download
23+
24+
# Copy source code and build
25+
COPY dashboard/backend/ /app/dashboard/backend/
26+
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o /app/dashboard-backend main.go
1827

1928
# Stage 3: Final runtime image
2029
FROM alpine:3.19

dashboard/backend/go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
module github.com/vllm-project/semantic-router/dashboard/backend
22

33
go 1.21
4+
5+
require gopkg.in/yaml.v3 v3.0.1

dashboard/backend/go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
2+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
3+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
4+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

dashboard/backend/main.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"encoding/json"
45
"flag"
56
"fmt"
67
"log"
@@ -9,7 +10,10 @@ import (
910
"net/url"
1011
"os"
1112
"path"
13+
"path/filepath"
1214
"strings"
15+
16+
yaml "gopkg.in/yaml.v3"
1317
)
1418

1519
// env returns the env var or default
@@ -20,6 +24,41 @@ func env(key, def string) string {
2024
return def
2125
}
2226

27+
// configHandler reads and serves the config.yaml file as JSON
28+
func configHandler(configPath string) http.HandlerFunc {
29+
return func(w http.ResponseWriter, r *http.Request) {
30+
// Only allow GET requests
31+
if r.Method != http.MethodGet {
32+
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
33+
return
34+
}
35+
36+
// Read the config file
37+
data, err := os.ReadFile(configPath)
38+
if err != nil {
39+
log.Printf("Error reading config file: %v", err)
40+
http.Error(w, fmt.Sprintf("Failed to read config file: %v", err), http.StatusInternalServerError)
41+
return
42+
}
43+
44+
// Parse YAML
45+
var config interface{}
46+
if err := yaml.Unmarshal(data, &config); err != nil {
47+
log.Printf("Error parsing config YAML: %v", err)
48+
http.Error(w, fmt.Sprintf("Failed to parse config: %v", err), http.StatusInternalServerError)
49+
return
50+
}
51+
52+
// Convert to JSON and send response
53+
w.Header().Set("Content-Type", "application/json")
54+
if err := json.NewEncoder(w).Encode(config); err != nil {
55+
log.Printf("Error encoding config to JSON: %v", err)
56+
http.Error(w, fmt.Sprintf("Failed to encode config: %v", err), http.StatusInternalServerError)
57+
return
58+
}
59+
}
60+
}
61+
2362
// newReverseProxy creates a reverse proxy to targetBase and strips the given prefix from the incoming path
2463
func newReverseProxy(targetBase, stripPrefix string, forwardAuth bool) (*httputil.ReverseProxy, error) {
2564
targetURL, err := url.Parse(targetBase)
@@ -143,6 +182,7 @@ func main() {
143182
// Flags/env for configuration
144183
port := flag.String("port", env("DASHBOARD_PORT", "8700"), "dashboard port")
145184
staticDir := flag.String("static", env("DASHBOARD_STATIC_DIR", "../frontend"), "static assets directory")
185+
configFile := flag.String("config", env("ROUTER_CONFIG_PATH", "../../config/config.yaml"), "path to config.yaml")
146186

147187
// Upstream targets
148188
grafanaURL := flag.String("grafana", env("TARGET_GRAFANA_URL", ""), "Grafana base URL")
@@ -153,6 +193,13 @@ func main() {
153193

154194
flag.Parse()
155195

196+
// Resolve config file path to absolute path
197+
absConfigPath, err := filepath.Abs(*configFile)
198+
if err != nil {
199+
log.Fatalf("Failed to resolve config path: %v", err)
200+
}
201+
log.Printf("Config file path: %s", absConfigPath)
202+
156203
mux := http.NewServeMux()
157204

158205
// Health check endpoint
@@ -162,6 +209,10 @@ func main() {
162209
w.Write([]byte(`{"status":"healthy","service":"semantic-router-dashboard"}`))
163210
})
164211

212+
// Config endpoint - serve the config.yaml as JSON
213+
mux.HandleFunc("/api/router/config/all", configHandler(absConfigPath))
214+
log.Printf("Config API endpoint registered: /api/router/config/all")
215+
165216
// Router API proxy (forward Authorization) - MUST be registered before Grafana
166217
var routerAPIProxy *httputil.ReverseProxy
167218
if *routerAPI != "" {

0 commit comments

Comments
 (0)