Documentation
¶
Overview ¶
Package api provides the HTTP API for dispatchoor.
@title Dispatchoor API
@version 1.0
@description GitHub Actions workflow dispatch queue management API.
@description Dispatchoor helps you manage and schedule GitHub Actions workflow dispatches
@description across multiple runner pools with fine-grained control.
@description
@description ## Rate Limiting
@description When enabled, the API enforces per-IP rate limits on three tiers:
@description - **Auth endpoints** (`/auth/*`): 10 requests/minute (protects against brute force)
@description - **Public endpoints** (`/health`, `/metrics`): 60 requests/minute
@description - **Authenticated endpoints**: 120 requests/minute
@description
@description When rate limited, the API returns HTTP 429 with a `Retry-After` header.
@contact.name ethPandaOps
@contact.url https://github.com/ethpandaops/dispatchoor
@license.name MIT
@license.url https://github.com/ethpandaops/dispatchoor/blob/main/LICENSE
@host localhost:9090
@BasePath /api/v1
@securityDefinitions.apikey BearerAuth
@in header
@name Authorization
@description Bearer token authentication. Format: "Bearer {token}"
@tag.name auth
@tag.description Authentication endpoints
@tag.name groups
@tag.description Runner group management
@tag.name templates
@tag.description Job template management
@tag.name queue
@tag.description Job queue operations
@tag.name jobs
@tag.description Job management
@tag.name history
@tag.description Job history and statistics
@tag.name runners
@tag.description GitHub Actions runner information
@tag.name system
@tag.description System health and status
@tag.name websocket
@tag.description Real-time event streaming
Index ¶
- func ServeWs(hub *Hub, authSvc auth.Service, allowedOrigins []string, w http.ResponseWriter, ...)
- func SyncGroupsFromConfig(ctx context.Context, log logrus.FieldLogger, st store.Store, ...) error
- type AddJobRequest
- type Client
- type ComponentStatus
- type DatabaseStatus
- type ErrorResponse
- type GitHubClientStatus
- type GitHubClientsStatus
- type GroupWithStats
- type HealthAuthConfig
- type HealthConfig
- type HealthResponse
- type HistoryResponse
- type HistoryStatsBucket
- type HistoryStatsRange
- type HistoryStatsResponse
- type HistoryStatsTotals
- type Hub
- func (h *Hub) Broadcast(msg *Message)
- func (h *Hub) BroadcastDispatch(job *store.Job)
- func (h *Hub) BroadcastJobState(job *store.Job)
- func (h *Hub) BroadcastQueueUpdate(groupID string, jobs []*store.Job)
- func (h *Hub) BroadcastRunnerStatus(runner *store.Runner, groupID string)
- func (h *Hub) BroadcastToGroup(groupID string, msg *Message)
- func (h *Hub) ClientCount() int
- func (h *Hub) Run(ctx context.Context)
- func (h *Hub) Subscribe(client *Client, groupID string)
- func (h *Hub) Unsubscribe(client *Client, groupID string)
- type IPRateLimiter
- type LoginRequest
- type LoginResponse
- type Message
- type MessageType
- type QueueStats
- type RateLimitErrorResponse
- type ReorderQueueRequest
- type Server
- type SystemStatusResponse
- type UpdateAutoRequeueRequest
- type UpdateJobRequest
- type VersionInfo
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type AddJobRequest ¶
type AddJobRequest struct {
TemplateID string `json:"template_id,omitempty" example:"my-template"`
Inputs map[string]string `json:"inputs"`
AutoRequeue bool `json:"auto_requeue" example:"false"`
RequeueLimit *int `json:"requeue_limit" example:"3"`
// Manual job fields (used when template_id is empty).
Name string `json:"name,omitempty" example:"Manual Job"`
Owner string `json:"owner,omitempty" example:"ethpandaops"`
Repo string `json:"repo,omitempty" example:"dispatchoor"`
WorkflowID string `json:"workflow_id,omitempty" example:"deploy.yml"`
Ref string `json:"ref,omitempty" example:"main"`
Labels map[string]string `json:"labels,omitempty"`
}
AddJobRequest is the request body for adding a job to the queue.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client represents a WebSocket client connection.
type ComponentStatus ¶
type ComponentStatus string
ComponentStatus represents health status of a component.
const ( ComponentStatusHealthy ComponentStatus = "healthy" ComponentStatusDegraded ComponentStatus = "degraded" ComponentStatusUnhealthy ComponentStatus = "unhealthy" )
type DatabaseStatus ¶
type DatabaseStatus struct {
Status ComponentStatus `json:"status"`
Latency string `json:"latency,omitempty"`
Error string `json:"error,omitempty"`
}
DatabaseStatus contains database health information.
type ErrorResponse ¶
type ErrorResponse struct {
Error string `json:"error" example:"Something went wrong"`
}
ErrorResponse is the standard error response format.
type GitHubClientStatus ¶ added in v0.1.3
type GitHubClientStatus struct {
Status ComponentStatus `json:"status"`
Connected bool `json:"connected"`
Error string `json:"error,omitempty"`
RateLimitRemaining int `json:"rate_limit_remaining"`
RateLimitReset string `json:"rate_limit_reset,omitempty"`
ResetIn string `json:"reset_in,omitempty"`
}
GitHubClientStatus contains status and rate limit information for a single GitHub client.
type GitHubClientsStatus ¶ added in v0.1.3
type GitHubClientsStatus struct {
Runners *GitHubClientStatus `json:"runners,omitempty"`
Dispatch *GitHubClientStatus `json:"dispatch,omitempty"`
}
GitHubClientsStatus contains status for both GitHub clients.
type GroupWithStats ¶
type GroupWithStats struct {
*store.Group
QueuedJobs int `json:"queued_jobs" example:"5"`
RunningJobs int `json:"running_jobs" example:"2"`
IdleRunners int `json:"idle_runners" example:"3"`
BusyRunners int `json:"busy_runners" example:"2"`
TotalRunners int `json:"total_runners" example:"5"`
TemplateCount int `json:"template_count" example:"10"`
}
GroupWithStats is a group with additional statistics.
type HealthAuthConfig ¶ added in v0.1.3
type HealthAuthConfig struct {
Basic bool `json:"basic" example:"true"`
GitHub bool `json:"github" example:"false"`
}
HealthAuthConfig indicates which authentication methods are enabled.
type HealthConfig ¶ added in v0.1.3
type HealthConfig struct {
Auth HealthAuthConfig `json:"auth"`
}
HealthConfig contains public configuration information.
type HealthResponse ¶
type HealthResponse struct {
Status string `json:"status" example:"ok"`
Config HealthConfig `json:"config"`
}
HealthResponse is the response for the health check endpoint.
type HistoryResponse ¶
type HistoryResponse struct {
Jobs []*store.Job `json:"jobs"`
HasMore bool `json:"has_more" example:"true"`
NextCursor string `json:"next_cursor,omitempty" example:"2024-01-15T10:30:00Z"`
TotalCount int `json:"total_count" example:"150"`
}
HistoryResponse wraps the paginated history response.
type HistoryStatsBucket ¶
type HistoryStatsBucket struct {
Timestamp string `json:"timestamp" example:"2024-01-15T10:00:00Z"`
Completed int `json:"completed" example:"5"`
Failed int `json:"failed" example:"1"`
Cancelled int `json:"cancelled" example:"0"`
}
HistoryStatsBucket represents job counts in a time bucket.
type HistoryStatsRange ¶
type HistoryStatsRange struct {
Start string `json:"start" example:"2024-01-15T00:00:00Z"`
End string `json:"end" example:"2024-01-16T00:00:00Z"`
BucketDuration string `json:"bucket_duration" example:"1h0m0s"`
}
HistoryStatsRange describes the time range of the statistics.
type HistoryStatsResponse ¶
type HistoryStatsResponse struct {
Buckets []HistoryStatsBucket `json:"buckets"`
Range HistoryStatsRange `json:"range"`
Totals HistoryStatsTotals `json:"totals"`
}
HistoryStatsResponse wraps the aggregated history statistics.
type HistoryStatsTotals ¶
type HistoryStatsTotals struct {
Completed int `json:"completed" example:"120"`
Failed int `json:"failed" example:"15"`
Cancelled int `json:"cancelled" example:"5"`
}
HistoryStatsTotals contains total counts across all buckets.
type Hub ¶
type Hub struct {
// contains filtered or unexported fields
}
Hub maintains the set of active clients and broadcasts messages to them.
func (*Hub) BroadcastDispatch ¶
BroadcastDispatch broadcasts a dispatch event.
func (*Hub) BroadcastJobState ¶
BroadcastJobState broadcasts a job state change.
func (*Hub) BroadcastQueueUpdate ¶
BroadcastQueueUpdate broadcasts a queue update.
func (*Hub) BroadcastRunnerStatus ¶
BroadcastRunnerStatus broadcasts a runner status update.
func (*Hub) BroadcastToGroup ¶
BroadcastToGroup sends a message to all clients subscribed to a group.
func (*Hub) ClientCount ¶
ClientCount returns the number of connected clients.
func (*Hub) Unsubscribe ¶
Unsubscribe removes a client from a group's subscription list.
type IPRateLimiter ¶ added in v0.1.3
type IPRateLimiter struct {
// contains filtered or unexported fields
}
IPRateLimiter provides per-IP rate limiting middleware.
func NewIPRateLimiter ¶ added in v0.1.3
func NewIPRateLimiter(requestsPerMinute int) *IPRateLimiter
NewIPRateLimiter creates a new IP-based rate limiter.
func (*IPRateLimiter) Middleware ¶ added in v0.1.3
func (l *IPRateLimiter) Middleware(next http.Handler) http.Handler
Middleware returns an HTTP middleware that enforces rate limiting per IP.
type LoginRequest ¶
type LoginRequest struct {
Username string `json:"username" example:"admin"`
Password string `json:"password" example:"password123"`
}
LoginRequest is the request body for username/password login.
type LoginResponse ¶
type LoginResponse struct {
Token string `json:"token" example:"eyJhbGciOiJIUzI1NiIs..."`
User *store.User `json:"user"`
}
LoginResponse is the response for successful authentication.
type Message ¶
type Message struct {
Type MessageType `json:"type"`
GroupID string `json:"group_id,omitempty"`
Payload any `json:"payload,omitempty"`
}
Message represents a WebSocket message.
type MessageType ¶
type MessageType string
MessageType represents the type of WebSocket message.
const ( // Server -> Client messages. MessageTypeRunnerStatus MessageType = "runner_status" MessageTypeQueueUpdate MessageType = "queue_update" MessageTypeJobState MessageType = "job_state" MessageTypeDispatch MessageType = "dispatch" MessageTypeSystemStatus MessageType = "system_status" MessageTypeError MessageType = "error" MessageTypeSubscribed MessageType = "subscribed" MessageTypeUnsubscribed MessageType = "unsubscribed" // Client -> Server messages. MessageTypeSubscribe MessageType = "subscribe" MessageTypeUnsubscribe MessageType = "unsubscribe" MessageTypePing MessageType = "ping" )
type QueueStats ¶
type QueueStats struct {
PendingJobs int `json:"pending_jobs"`
TriggeredJobs int `json:"triggered_jobs"`
RunningJobs int `json:"running_jobs"`
}
QueueStats contains queue statistics.
type RateLimitErrorResponse ¶ added in v0.1.3
type RateLimitErrorResponse struct {
Error string `json:"error" example:"rate limit exceeded"`
}
RateLimitErrorResponse is returned when rate limit is exceeded.
type ReorderQueueRequest ¶
type ReorderQueueRequest struct {
JobIDs []string `json:"job_ids" example:"job-1,job-2,job-3"`
}
ReorderQueueRequest is the request body for reordering the job queue.
type Server ¶
type Server interface {
Start(ctx context.Context) error
Stop() error
BroadcastRunnerChange(runner *store.Runner)
}
Server is the HTTP API server.
type SystemStatusResponse ¶
type SystemStatusResponse struct {
Status ComponentStatus `json:"status"`
Timestamp string `json:"timestamp"`
Database DatabaseStatus `json:"database"`
GitHub GitHubClientsStatus `json:"github"`
Queue QueueStats `json:"queue"`
Version VersionInfo `json:"version"`
}
SystemStatusResponse is the comprehensive status response.
type UpdateAutoRequeueRequest ¶
type UpdateAutoRequeueRequest struct {
AutoRequeue bool `json:"auto_requeue" example:"true"`
RequeueLimit *int `json:"requeue_limit" example:"5"`
}
UpdateAutoRequeueRequest is the request body for updating auto-requeue settings.
type UpdateJobRequest ¶
type UpdateJobRequest struct {
Inputs map[string]string `json:"inputs"`
Name *string `json:"name,omitempty" example:"Updated Job"`
Owner *string `json:"owner,omitempty" example:"ethpandaops"`
Repo *string `json:"repo,omitempty" example:"dispatchoor"`
WorkflowID *string `json:"workflow_id,omitempty" example:"deploy.yml"`
Ref *string `json:"ref,omitempty" example:"main"`
Labels map[string]string `json:"labels,omitempty"`
}
UpdateJobRequest is the request body for updating a job.
type VersionInfo ¶
type VersionInfo struct {
Version string `json:"version"`
GitCommit string `json:"git_commit"`
BuildDate string `json:"build_date"`
}
VersionInfo contains build version information.