Help us shape the future of Go! Take the 2026 Go Developer Survey

api

package
v1.3.8 Latest Latest
Warning

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

Go to latest
Published: Oct 19, 2026 License: AGPL-3.0 Imports: 72 Imported by: 0

Documentation

Overview

Package api is Zoomies' HTTP surface: the REST API described by api/openapi.yaml, the Server-Sent Events streams the UI lives on, the Prometheus endpoint, the GitHub webhook receiver, and the embedded operator UI.

Everything here is transport. Decisions about the fleet belong to internal/controller, authorisation policy to internal/auth and SQL to internal/store; a handler in this package reads a request, asks one of those three, and renders the answer in the shape the OpenAPI document promises. Keeping it that thin is what makes the contract checkable: the surface can be walked route by route in a test, and nothing behind it has an opinion about HTTP.

Index

Constants

View Source
const SessionCookie = "zoomies_session"

SessionCookie is the name of the cookie a browser session lives in. It is exported because the OpenAPI document names it and the CLI's browser-login helper has to read it back.

View Source
const SignInCookie = "zoomies_sign_in"

SignInCookie carries a sign-in that has passed the password and waits for its second step. It is scoped to the auth routes, lives as long as the pending sign-in does, and is Strict: nothing but this UI's own requests should ever send it.

Variables

This section is empty.

Functions

func ClientIP

func ClientIP(ctx context.Context) string

clientIP returns the address a request came from, resolved through the proxies the operator has said to trust.

func Identity

func Identity(ctx context.Context) *auth.Identity

Identity returns the authenticated caller, or nil on an unauthenticated route. Handlers use it for audit attribution and for the checks that depend on who is asking rather than on the route alone.

func RequestID

func RequestID(ctx context.Context) string

RequestID returns the identifier this request is logged under, which is what an internal error hands back so an operator can find the log line.

Types

type CheckoutCollectionView added in v1.3.8

type CheckoutCollectionView struct {
	Version       string `json:"version"`
	Basis         string `json:"basis"`
	StepNumber    int64  `json:"step_number"`
	BlobSHA       string `json:"blob_sha"`
	SourceFunding string `json:"source_funding"`
}

type CheckoutInspectionRequest added in v1.3.8

type CheckoutInspectionRequest struct {
	InstallationID string                `json:"installation_id"`
	Repository     string                `json:"repository"`
	Selection      CheckoutSelectionBody `json:"selection"`
}

type CheckoutInspectionView added in v1.3.8

type CheckoutInspectionView struct {
	InstallationID string                `json:"installation_id"`
	Repository     string                `json:"repository"`
	Selection      CheckoutSelectionBody `json:"selection"`
	HeadSHA        string                `json:"head_sha"`
	Path           string                `json:"path"`
	Mode           string                `json:"mode"`
	Content        string                `json:"content"`
	SourceSHA256   string                `json:"source_sha256"`
	StepNumber     int64                 `json:"step_number"`
	JobName        string                `json:"job_name"`
	StepName       string                `json:"step_name"`
	CheckoutMS     int64                 `json:"checkout_ms"`
	EvidenceID     string                `json:"evidence_id"`
	Basis          string                `json:"basis"`
	InspectedAt    time.Time             `json:"inspected_at"`
}

type CheckoutPreviewDetail added in v1.3.8

type CheckoutPreviewDetail struct {
	Version      string `json:"version"`
	Kind         string `json:"kind"`
	State        string `json:"state"`
	HeadSHA      string `json:"head_sha"`
	SourceSHA256 string `json:"source_sha256"`
	AfterSHA256  string `json:"after_sha256"`
	EvidenceID   string `json:"evidence_id"`
	RunID        string `json:"run_id"`
	Attempt      int    `json:"attempt"`
	JobIndex     int    `json:"job_index"`
	StepIndex    int    `json:"step_index"`
	Line         int    `json:"line"`
	CheckoutMS   int64  `json:"checkout_ms"`
	Path         string `json:"path"`
	Before       string `json:"before"`
	After        string `json:"after"`
	Verification string `json:"verification"`
	Explanation  string `json:"explanation"`
}

type CheckoutPreviewRequest added in v1.3.8

type CheckoutPreviewRequest struct {
	InstallationID  string                `json:"installation_id"`
	Repository      string                `json:"repository"`
	Selection       CheckoutSelectionBody `json:"selection"`
	HeadSHA         string                `json:"head_sha"`
	SourceSHA256    string                `json:"source_sha256"`
	HistoryReviewed bool                  `json:"history_reviewed"`
}

CheckoutPreviewRequest carries the operator's declaration. The scope of that declaration is fixed by the server; the request supplies only the head and digest of the source the operator was shown, so a file that moved since is refused rather than approved by accident.

type CheckoutPreviewView added in v1.3.8

type CheckoutPreviewView struct {
	ID             string                  `json:"id"`
	InstallationID string                  `json:"installation_id"`
	Repository     string                  `json:"repository"`
	ReviewedBy     string                  `json:"reviewed_by"`
	SHA256         string                  `json:"sha256"`
	CreatedAt      time.Time               `json:"created_at"`
	Currentness    string                  `json:"currentness"`
	Collection     *CheckoutCollectionView `json:"collection"`
	Preview        CheckoutPreviewDetail   `json:"preview"`
}

CheckoutPreviewView leaves the retained file out on purpose: the workflow source is shown once, at inspection, and the retained record answers with the one line it would change.

type CheckoutSelectionBody added in v1.3.8

type CheckoutSelectionBody struct {
	RunID       string `json:"run_id"`
	Attempt     int    `json:"attempt"`
	GitHubJobID string `json:"github_job_id"`
	JobIndex    *int   `json:"job_index,omitempty"`
	StepIndex   *int   `json:"step_index,omitempty"`
}

CheckoutSelectionBody names one exact run, attempt, GitHub job and the job and step positions in the workflow file. The two GitHub identities travel as decimal strings so a browser cannot round them.

type ComparisonCaptureRequest added in v1.3.8

type ComparisonCaptureRequest struct {
	InstallationID  string                                  `json:"installation_id"`
	Repository      string                                  `json:"repository"`
	Kind            string                                  `json:"kind"`
	Hypothesis      string                                  `json:"hypothesis"`
	IntendedDelta   string                                  `json:"intended_delta"`
	RevisionDeltaID string                                  `json:"revision_delta_id"`
	Since           time.Time                               `json:"since"`
	Until           time.Time                               `json:"until"`
	Baseline        []controller.ExperimentAttemptSelection `json:"baseline"`
	Candidate       []controller.ExperimentAttemptSelection `json:"candidate"`
}

type FleetStatus added in v1.3.8

type FleetStatus = controller.FleetStatus

FleetStatus is the name-free projection GET /api/v1/status returns. It is the controller's type, aliased, for the reason every view is: one shape, defined once.

type HostRecommendationView added in v1.3.8

type HostRecommendationView struct {
	Available       bool    `json:"available"`
	Capacity        int     `json:"capacity,omitempty"`
	ReserveCPUs     int     `json:"reserve_cpus,omitempty"`
	ReserveMemoryMB int64   `json:"reserve_memory_mb,omitempty"`
	ReserveDiskMB   int64   `json:"reserve_disk_mb,omitempty"`
	LimitedBy       string  `json:"limited_by,omitempty"`
	AskCPUs         float64 `json:"ask_cpus,omitempty"`
	AskMemoryMB     int64   `json:"ask_memory_mb,omitempty"`
	AskPool         string  `json:"ask_pool,omitempty"`
	Reason          string  `json:"reason,omitempty"`
}

HostRecommendationView is what the Adjust dialog shows as the recommendation.

type OptimisationEnablement added in v1.3.8

type OptimisationEnablement struct {
	SourceReads   bool   `json:"source_reads"`
	WorkflowEdits bool   `json:"workflow_edits"`
	Enabled       bool   `json:"enabled"`
	CanChange     bool   `json:"can_change"`
	Reason        string `json:"reason,omitempty"`
}

OptimisationEnablement is whether this instance lets Zoomies read workflow source and keep a proposed edit, and whether the caller can change that. The two settings are separate grants in the registry; the page asks for them together because one is no use without the other, and says so in words.

type OptimisationEnablementRequest added in v1.3.8

type OptimisationEnablementRequest struct {
	Enabled *bool `json:"enabled"`
}

type Options

type Options struct {
	// Controller is the running control plane. Required.
	Controller *controller.Controller
	// Logger is the process logger; nil uses slog's default.
	Logger *slog.Logger
	// StreamHeartbeat is how often a live stream sends a keep-alive and
	// re-checks the credential it was opened with. Zero uses the shipped
	// interval; a test sets it small so it does not have to wait one.
	StreamHeartbeat time.Duration
}

Options are what the API needs to serve. Everything else it uses -- the store, the auth service, the event bus, the configuration -- it takes from the controller, so there is exactly one wiring of those and no way for the API to end up talking to a different database than the fleet does.

type Server

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

Server is the HTTP surface. Build it with New and either hand Handler() to a listener of your own or let ListenAndServe run one.

func New

func New(opts Options) (*Server, error)

New builds the server. It does no I/O beyond loading the encryption key and, when single sign-on is configured, discovering the identity provider.

func (*Server) Addr added in v1.3.8

func (s *Server) Addr() string

Addr is the address ListenAndServe is listening on, or "" until it has bound one. It exists so that a caller can ask for port 0 and learn which port the kernel chose, which is the only way to start a server on a free port without a gap between finding the port and binding it: a test that found a free port, closed it and bound it again lost that gap to another job's test on a busy runner, and failed with "address already in use".

func (*Server) Handler

func (s *Server) Handler() http.Handler

Handler returns the whole surface: API, webhook, metrics and UI. It is safe to serve from a listener of the caller's own, which is what the tests and the installer's health check do.

func (*Server) ListenAndServe

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

ListenAndServe serves until ctx is cancelled, then shuts down gracefully.

It returns nil on a clean shutdown; anything else is a failure worth exiting on. The listener is opened before the readiness notification is sent, so a service manager that starts a dependent unit on READY=1 is not racing the bind.

Jump to

Keyboard shortcuts

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