myxce/src/frontend/CLAUDE.md

3.1 KiB

XCE Frontend (API Server + CLI)

Overview

Go-based REST API server (Gin) and CLI tool (Cobra) that expose cluster management operations. Two independent Go modules sharing no code at the module level.

Modules

Module Path Entry Point
apiserver src/frontend/apiserver/ cmd/main.go
xcecli src/frontend/xcecli/ cmd/main.go

Build & Test

make build-server       # → /tmp/apiserver
make build-cli          # → /tmp/xce_static (CGO_ENABLED=0, static binary)
make test               # unit tests only (no live server required)
make test-all           # unit + integration (needs XCE_BIN and SRV_URL env vars)

API Server Architecture

cmd/         Entry point — init logger, config, stores, RBAC, auth, then start Gin
router/      Route registration and middleware chain
controllers/ HTTP handlers: one file per resource (jobs, queues, hosts, clusters, users...)
services/    Business logic
store/       Thread-safe in-memory key-value stores (generics-based)
models/      Request/response DTOs and domain structs
middleware/  CORS, rate limiting, IP whitelist, JWT validation
backend/     C library integration stubs
backend/auth Pluggable auth providers (configfile, ldap, oauth2, pam)
utils/       Logger (zap), config parsing, crypto helpers
common/      Global error codes and messages
config/      YAML configs and JSON schemas

Conventions

Controllers

  • Struct: type {Resource}Controller struct{}
  • Handler signature: func (c {Resource}Controller) {Action}{Resource}(ctx *gin.Context)
  • Always return via helpers — never write response directly:
    ReturnSuccess(ctx, common.SUCCESS_CODE, common.SUCCESS_MSG, data)
    ReturnError(ctx, common.ERROR_CODE, err.Error(), nil)
    

Error Handling

  • Early return on every error — no deferred error accumulation
  • Log with zap fields before returning: logger.Error("msg", zap.Error(err))
  • Use preCheck{Resource}Request() helpers for input validation before business logic

RBAC

  • Protect routes with controllers.RequirePermission("action:domain") middleware
  • Permission strings follow action:scope pattern (e.g., job:view:self, queue:submit:all)

Logging

  • Import as: logger "apiserver/utils"
  • Always include context: zap.String("key", val), zap.Error(err)

Models

  • JSON tags use snake_case: json:"field_name"
  • Required fields: binding:"required"
  • YAML tags for config structs: yaml:"field_name,omitempty"

Tests

  • Use t.TempDir() for file fixtures
  • Reset global state with a helper (e.g., resetRBACState() pattern in rbac_check_test.go)
  • Table-driven tests for filter/validation logic

Key Files

  • controllers/response.go — ReturnSuccess / ReturnError helpers
  • controllers/rbac_check.go — RBAC loading, RequirePermission middleware
  • middleware/validatehandler.go — JWT token validation middleware
  • backend/auth/provider.go — AuthProvider interface definition
  • store/store.go — Generic in-memory store implementation
  • config/rbac.yaml — Role and permission definitions
  • config/auth.yaml — Auth provider configuration