package lazycontrolplane ¶
import "golazy.dev/lazycontrolplane"
Constants ¶
const PanelsPath ¶
PanelsPath is the control-plane discovery endpoint for developer-panel contributions registered by the running application and its add-ons.
const PanelsPath = "/_golazy/panels"
Variables ¶
var ErrSealed ¶
ErrSealed is returned when code tries to extend a control plane that has already been prepared for serving.
var ErrSealed = errors.New("lazycontrolplane: registrations are sealed")
Types ¶
type Builder ¶
Builder creates a control plane for lazyapp.
Config and *ControlPlane implement Builder. This keeps lazyapp.Config's ControlPlane field optional while still allowing ControlPlane: Config{}.
type Builder interface {
BuildControlPlane() *ControlPlane
}
type Config ¶
Config describes the operational endpoints exposed by a control plane.
The zero Config exposes /livez, /readyz, and panel discovery.
type Config struct {
Readiness []ReadinessCheck
Metrics http.Handler
Pprof bool
}
func (config Config) BuildControlPlane ¶
BuildControlPlane implements Builder.
func (config Config) BuildControlPlane() *ControlPlane
type ControlPlane ¶
ControlPlane routes operational endpoints.
type ControlPlane struct {
// contains filtered or unexported fields
}
func New ¶
New builds a control plane from config.
func New(config Config) *ControlPlane
func (plane *ControlPlane) AddReadinessCheck ¶
AddReadinessCheck appends a readiness check to /readyz.
AddReadinessCheck is the compatibility API. New integrations should use RegisterReadinessCheck so validation errors can be handled by the caller.
func (plane *ControlPlane) AddReadinessCheck(check ReadinessCheck)
func (plane *ControlPlane) BuildControlPlane ¶
BuildControlPlane implements Builder.
func (plane *ControlPlane) BuildControlPlane() *ControlPlane
func (plane *ControlPlane) EnablePprof ¶
EnablePprof registers the standard net/http/pprof handlers.
It is safe to call EnablePprof more than once.
func (plane *ControlPlane) EnablePprof()
func (plane *ControlPlane) Endpoints ¶
Endpoints returns a deterministic snapshot of registered endpoint metadata.
func (plane *ControlPlane) Endpoints() []EndpointInfo
func (plane *ControlPlane) Handle ¶
Handle registers an exact control-plane endpoint.
Handle is the compatibility API for registrations without ownership metadata. New integrations should use Register so validation errors can be handled by the caller.
func (plane *ControlPlane) Handle(pattern string, handler http.Handler)
func (plane *ControlPlane) Handler ¶
Handler mounts the control plane in front of next.
func (plane *ControlPlane) Handler(next http.Handler) http.Handler
func (plane *ControlPlane) HandlesPath ¶
HandlesPath reports whether path belongs to the control plane.
func (plane *ControlPlane) HandlesPath(path string) bool
func (plane *ControlPlane) Panels ¶
Panels returns a deterministic snapshot of registered developer-panel entries. Lower Order values sort first, followed by title and stable ID.
func (plane *ControlPlane) Panels() []PanelInfo
func (plane *ControlPlane) Register ¶
Register adds an owned endpoint to the control plane.
Registration is concurrency-safe. It fails when ID or Pattern is already registered, when the endpoint is invalid, or after the control plane has been sealed for serving.
func (plane *ControlPlane) Register(endpoint Endpoint) error
func (plane *ControlPlane) RegisterPanel ¶
RegisterPanel adds a developer-panel entry backed by an endpoint registered on this control plane. The endpoint must belong to the same owner, support GET requests, and use an exact path. Prefix and wildcard patterns are rejected so a panel host cannot proxy into another endpoint's namespace.
func (plane *ControlPlane) RegisterPanel(panel Panel) error
func (plane *ControlPlane) RegisterReadinessCheck ¶
RegisterReadinessCheck appends a readiness check to /readyz.
func (plane *ControlPlane) RegisterReadinessCheck(check ReadinessCheck) error
func (plane *ControlPlane) Seal ¶
Seal closes endpoint and readiness registration. It is safe to call Seal more than once. The application lifecycle calls Seal once all package and add-on registrations are complete.
func (plane *ControlPlane) Seal()
func (plane *ControlPlane) ServeHTTP ¶
ServeHTTP serves control-plane endpoints.
func (plane *ControlPlane) ServeHTTP(w http.ResponseWriter, r *http.Request)
func (plane *ControlPlane) StandaloneHandler ¶
StandaloneHandler serves the control plane on its own listener.
It adds a root HTML index that lists registered endpoints. Use Handler when the control plane shares an application listener so "/" stays owned by the app.
func (plane *ControlPlane) StandaloneHandler() http.Handler
type Endpoint ¶
Endpoint describes an owned control-plane endpoint.
ID must be unique within a control plane. Owner identifies the framework package, application, or add-on responsible for the endpoint. Pattern uses net/http ServeMux syntax.
type Endpoint struct {
ID string
Owner string
Pattern string
Description string
Handler http.Handler
}
type EndpointInfo ¶
EndpointInfo is the public, handler-free description of a registered endpoint.
type EndpointInfo struct {
ID string
Owner string
Pattern string
Description string
Method string
Path string
Prefix bool
}
type Panel ¶
Panel describes one developer-panel entry backed by an owned control-plane endpoint. EndpointID must name a GET-capable endpoint registered by the same Owner. Actions may reference exact POST-only endpoints owned by that Owner. The endpoint handlers continue to run in the application process; panel hosts consume only the metadata returned by PanelsPath.
type Panel struct {
ID string
Owner string
Title string
Description string
EndpointID string
Actions []PanelAction
Order int
}
type PanelAction ¶
PanelAction describes a trusted action rendered by a developer-panel host. EndpointID must name an exact POST endpoint registered by the panel Owner. Add-on content cannot submit this endpoint directly; the host resolves the stable panel and action IDs from discovery before issuing an empty POST.
type PanelAction struct {
ID string
Title string
Description string
EndpointID string
}
type PanelActionInfo ¶
PanelActionInfo is the resolved, handler-free action metadata exposed to developer-panel hosts.
type PanelActionInfo struct {
ID string `json:"id"`
Title string `json:"title"`
Description string `json:"description"`
EndpointID string `json:"endpoint_id"`
Pattern string `json:"pattern"`
Method string `json:"method"`
Path string `json:"path"`
}
type PanelInfo ¶
PanelInfo is the resolved, handler-free description exposed to developer panel hosts.
type PanelInfo struct {
ID string `json:"id"`
Owner string `json:"owner"`
Title string `json:"title"`
Description string `json:"description"`
EndpointID string `json:"endpoint_id"`
Pattern string `json:"pattern"`
Method string `json:"method"`
Path string `json:"path"`
Actions []PanelActionInfo `json:"actions,omitempty"`
Order int `json:"order"`
}
type PanelsResponse ¶
PanelsResponse is the versioned response served from PanelsPath.
type PanelsResponse struct {
Schema int `json:"schema"`
Panels []PanelInfo `json:"panels"`
}
type ReadinessCheck ¶
ReadinessCheck is evaluated by /readyz.
type ReadinessCheck struct {
Name string
Check func(context.Context) error
}
type Registrar ¶
Registrar accepts owned endpoints and readiness checks during control-plane setup. Applications close registration explicitly with ControlPlane.Seal after startup packages and add-ons finish registering.
type Registrar interface {
Register(Endpoint) error
RegisterReadinessCheck(ReadinessCheck) error
RegisterPanel(Panel) error
}
Package lazycontrolplane provides operational HTTP endpoints for GoLazy applications.
Most applications compose the package through lazyapp:
app := lazyapp.New(lazyapp.Config{ ControlPlane: lazycontrolplane.Config{ Readiness: []lazycontrolplane.ReadinessCheck{{ Name: "database", Check: databaseReady, }}, }, })Direct users can register owned endpoints before sealing and serving the standalone handler:
plane := lazycontrolplane.New(lazycontrolplane.Config{}) err := plane.Register(lazycontrolplane.Endpoint{ ID: "example.com/myapp/build", Owner: "example.com/myapp", Pattern: "GET /build", Description: "Application build information", Handler: buildHandler, }) if err != nil { return err } plane.Seal() return http.ListenAndServe(":2001", plane.StandaloneHandler())A control plane owns framework and operations routes that should not be part of the application's route table. The zero Config is useful: it creates GET /livez, GET /readyz, and the empty developer-panel discovery document at GET /_golazy/panels. /livez reports that the process can answer HTTP requests. /readyz runs configured ReadinessCheck functions and returns 503 Service Unavailable when any dependency or runtime state says the app is not ready to receive traffic.
The package can be used directly with net/http, but most applications pass a Config or *ControlPlane to lazyapp.Config.ControlPlane. lazyapp builds the control plane, adds package-owned endpoints for configured jobs and telemetry, and, when built with the lazydev tag, registers development control endpoints from packages such as lazyassets, lazybuildinfo, lazycache, lazycontroller, lazydeps, lazyjobs, lazyroutes, and lazytelemetry.
lazyapp decides where the plane is served. In production builds it does not intercept application requests unless CONTROL_PLANE_ADDR is set to the same listen address as the app. When CONTROL_PLANE_ADDR points at a different address, lazyapp serves ControlPlane.StandaloneHandler on that listener; the standalone handler adds a small root index and keeps application "/" routes separate. In lazydev builds, lazyapp keeps the control plane available on the app handler so the development panel can call it.
Owned operational endpoints, including endpoints contributed by add-ons, can be registered with ControlPlane.Register. Registration records a stable ID, owner, pattern, and description for duplicate detection and the standalone endpoint index. RegisterReadinessCheck provides the matching error-returning readiness API. Registrations are concurrency-safe, including while an early startup control plane is serving, and are closed explicitly with ControlPlane.Seal after application setup is complete.
ControlPlane.Handle and ControlPlane.AddReadinessCheck remain available as panic-on-error compatibility APIs. Use Config.Metrics or a custom handler for /metrics, and use Config.Pprof or ControlPlane.EnablePprof to attach the standard net/http/pprof handlers.