apiserver

package
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 10, 2026 License: Apache-2.0 Imports: 21 Imported by: 0

README

pkg/apiserver — Native REST API Server

A Gin HTTP server listening on :8080, providing tenant-side Sandbox CRUD and API Key management interfaces.

Directory Structure

handlers/
  server.go        # Handler implementation (implements StrictServerInterface)
  server_test.go   # Unit tests for the handler
gen/
  agentbox.gen.go  # Generated by oapi-codegen from openapi.yaml, strictly DO NOT edit manually

API Generation Workflow (OpenAPI-First)

Authoritative specification: pkg/openapi/native/openapi.yaml

make generate-api   # → pkg/apiserver/gen/agentbox.gen.go

Workflow for modifying API fields:

  1. Edit pkg/openapi/native/openapi.yaml
  2. Run make generate-api
  3. Update the conversion functions in handlers/server.go:
    • genSpecToK8sSpec() — HTTP DTO → K8s CRD spec
    • domainTemplateSpecToGen() — K8s CRD spec → HTTP DTO
  4. Add/update tests in handlers/server_test.go

Template Spec Field Mapping

HTTP DTO Field K8s CRD Field Conversion Method
template (YAML string) EmbeddedSandboxTemplate.Template (*corev1.PodTemplateSpec) yaml.Unmarshal / yaml.Marshal
runtimes ([]Runtime) EmbeddedSandboxTemplate.Runtimes 1:1, protocol string ↔ corev1.Protocol
reservation EmbeddedSandboxTemplate.Reservation replicaQuota: resource.ParseQuantity / .String()
visibility SandboxTemplateSpec.Visibility 1:1
version, description, idleImage Direct string fields No conversion

Testing

go test ./pkg/apiserver/... -v

Discovery Endpoints (AI-Friendly)

Since v0.3.0, configuration-related errors will return a list of available resources in ErrorResponse.detail to facilitate self-healing for AI Agents. See docs/api/discovery-endpoints.md for details:

  • GET /v1/clusters — Exposes the cluster catalog, enabling the SDK/CLI to discover valid prefixes for {clusterID}.{uuid} / {clusterID}::{poolName}
  • POST /v1/sandboxes 404 → detail.availablePools
  • POST /v1/sandboxpools 400 (template does not exist) → detail.availableTemplates
  • POST /v1/sandboxpools 400 (missing quotaURL) → detail.availableQuotaURLs

SOP for adding new discovery responses:

  1. Extend a *Detail type in pkg/apiserver/domain/errors.go
  2. Implement a build*Detail(ctx, ...) helper in the corresponding service method
  3. Assign appErr.Detail = ... when returning an AppError
  4. Add an example (including the detail structure) under the corresponding response in pkg/openapi/native/openapi.yaml
  5. Add a new section in docs/api/discovery-endpoints.md

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// BindAddress is the TCP address the HTTP server listens on (e.g. ":8080").
	BindAddress string
	// KeyStore is the API key store used for authentication.
	KeyStore apikey.KeyStore
	// AdminKeyManager validates the shared admin key.  When nil, admin-key
	// authentication is disabled (dev mode).
	AdminKeyManager *apikey.AdminKeyManager
	// IAMService resolves team/user identities to Kubernetes namespaces and
	// handles JWT-based authentication issued by the BFF.
	IAMService service.IAMService
	// JWTSecret is the HS256 secret used to verify IAM JWT tokens issued by the BFF.
	// When empty, JWT-based authentication is disabled.
	JWTSecret string
	// RestConfig is the Kubernetes REST config, used for WebSocket exec (terminal).
	// When nil, the terminal endpoint is disabled.
	RestConfig *rest.Config
	// SyncToken is the shared secret used to authenticate ws-proxy connections on
	// /v1/ws/sync. When empty, the sync endpoint is disabled.
	SyncToken string
	// ClusterConfigSink is called whenever a cluster_config_sync frame arrives from
	// ws-proxy. Typically a cluster.ConfigMapWriter that persists the routing table
	// so ExtProc can read it. May be nil when cluster config sync is not required.
	ClusterConfigSink service.ClusterConfigSink
	// Forwarder is the cross-cluster forwarder. When nil, cross-cluster requests
	// will be rejected. Typically constructed from cluster store + localClusterID.
	// The forwarder already carries the local cluster ID internally.
	Forwarder *service.CrossClusterForwarder
	// ClusterStore is the shared in-memory catalog of known clusters. It is
	// surfaced through GET /v1/clusters so SDK/CLI callers can discover valid
	// cross-cluster prefixes. May be nil in single-cluster deployments.
	ClusterStore *cluster.Store
	// LocalClusterID identifies the cluster serving this API server. Used to mark
	// the `local: true` entry in the /v1/clusters response. Empty in
	// single-cluster deployments where cross-cluster routing is disabled.
	LocalClusterID string
	// QuotaProvider selects the quota backend exposed by GET /v1/quotas and
	// inspected by the /v1/feature-gates endpoint. When nil, a Noop provider
	// is used (feature disabled).
	QuotaProvider quotaplugin.Provider
	// ServerVersion is the build-time version string stamped on every response
	// via X-AgentBox-Server-Version. Set from pkg/version.Version in app.go.
	ServerVersion string
}

Config holds the configuration for the API server.

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server is the HTTP API server.

func New

func New(cfg Config, k8sClient client.Client, clientset kubernetes.Interface, sandboxStore store.SandboxStore,
	pluginManager *plugins.PluginManager, envoyGatewayBaseURL string,
	sandboxSvc service.SandboxService) *Server

New creates and configures the HTTP server with all service layers wired up. pluginManager may be nil (disables lifecycle plugins — open-source mode). sandboxSvc may be nil; when nil a default service is constructed internally. Pass a non-nil sandboxSvc to share the service with other components (e.g. SandboxPoolReconciler for idle-pod notifications).

func (*Server) Start

func (s *Server) Start(ctx context.Context) error

Start runs the server until ctx is cancelled, then gracefully shuts down.

Directories

Path Synopsis
Package gen provides primitives to interact with the openapi HTTP API.
Package gen provides primitives to interact with the openapi HTTP API.
Package handlers implements the StrictServerInterface generated from the OpenAPI spec.
Package handlers implements the StrictServerInterface generated from the OpenAPI spec.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL