Documentation
¶
Overview ¶
Package api implements the HTTP API the web frontend (1.10) and, later, the MCP layer both build on. Scope for this pass: GET /api/v1/brand, apps CRUD, deploy trigger and deploy history, single-admin-user session auth. No teams, no RBAC: explicitly out of scope until Phase 4.
Routing uses the standard library's Go 1.22+ pattern-based http.ServeMux ("GET /api/v1/apps/{name}") rather than a router framework like Chi, per the project's rule against pulling in a heavy framework; the one thing a framework would earn its weight on here is auth middleware, and requireAuth below is a plain http.HandlerFunc-wrapping closure that stdlib's mux composes with directly, so there is no ergonomics gap stdlib doesn't already close.
"App" here is layered directly on store.DesiredService (internal/store/service.go), the closest existing resource, rather than a new, speculative domain type. That surfaces real gaps instead of papering over them with a fuller model this package doesn't actually need to build yet:
- No replicas or strategy fields on an app: internal/spec's app.yaml Service has them, store.DesiredService doesn't yet, so this API can't expose what the store can't hold. Adding them is a store-schema and deploy-pipeline change, not something this package should invent on its own. Domains closed once that column was added: appResource now carries Domains too.
- Deploy trigger (deploys.go) only updates desired_services.image; it doesn't build anything. internal/build and internal/deploy already exist and do that, but they're owned by a different concurrent session as this package was written, so this endpoint takes an already-built image tag as input, the same mechanism used for rollback, run forward instead of backward. POST /api/v1/apps/{name}/builds (builds.go, handleTriggerBuild) closes this gap: it invokes the same internal/deploy.Pipeline the git webhook receiver uses, given a git source (repo_url/ref) in the request body, since no app has a stored git/build config anywhere in this codebase yet (see specServiceFromDesired's own doc comment for what that means for fidelity versus the original app.yaml).
- Deploy history (deploys.go) returns the latest reconcile condition per (controller, condition type) pair, which is genuinely all internal/store.UpsertConditions persists today, not a row-per- deploy-attempt log. A real deploy history table is a store-schema addition this package deliberately didn't invent speculatively.
cmd/levelrail/main.go's reconcile engine closed the gap noted above in an earlier draft of this comment: it now derives a dynamic controller set from the store every pass (reconcile.Engine.Source), so a deploy triggered through this API does reconcile on the next pass.
Secrets: PUT /api/v1/apps/{name}/secrets/{key} sets a value, encrypted at rest via internal/secrets.Manager. Deliberately set-only, no GET: this package never decrypts a value for a response body, only internal/reconcile/application does, immediately before container creation. Available only when the control plane was started with a master key (WithSecretSetter); without one, the route returns 501.
Auth foundation ("Dashboard & auth"): POST /api/v1/auth/register is the interactive first-run counterpart to BootstrapAdmin's env-var path, gated on "no admin row exists yet" at both the route and the mutation layer. Session auth stays exactly what this package was scoped as (single admin user, no teams, no RBAC); API tokens (POST/GET /api/v1/auth/tokens, DELETE .../{id}) are a separate, additive credential type for non-interactive callers (a future CLI, an MCP server), scoped to abilities (abilities.go: read, read:sensitive, write, deploy, root) checked fresh on every call by requireAbility, never a cached decision. Token management itself is session-only via requireAuth: a token can never mint or revoke another token on its own behalf. This shape (not theauth-go, not an all-or-nothing key) was a deliberate choice.
Index ¶
- Constants
- func ApprovalMatch(browserHash string) int
- func AttentionResolvedWindow() time.Duration
- func BootstrapAdmin(ctx context.Context, s AuthStore, username, password string) error
- func DeviceCodeTTL() time.Duration
- func DeviceTokenTTL() time.Duration
- func DockerGuardAuditEntry(d dockerguard.Decision) (store.AuditEntry, error)
- func EnsureSetupToken(ctx context.Context, users UserCounter, dataDir string) (token string, created bool, err error)
- func HostFirewallSSHPorts() []int
- func LoadBetaFeatures(ctx context.Context, s BetaFeatureStore) error
- func MaybeBootstrapDevAdmin(ctx context.Context, s AuthStore, logger *slog.Logger) error
- func MaybeSeedDevFixturesFromFile(ctx context.Context, s TokenStore, logger *slog.Logger, path string) error
- func MintAPIToken(ctx context.Context, tokens TokenStore, name string, abilities []string, ...) (string, store.APIToken, error)
- func MintAgentAPIToken(ctx context.Context, tokens TokenStore, name string, abilities []string, ...) (string, store.APIToken, error)
- func NewDeviceApprovalFromEnv() bool
- func PeerIsTrustedProxy(r *http.Request) bool
- func ReadSetupToken(dataDir string) (string, error)
- func SetupTokenPath(dataDir string) string
- type AIAssistantSecrets
- type AIAssistantSettingsStore
- type AIChatStore
- type AIControlStore
- type AIEngine
- type AccessPolicyStore
- type AccessSource
- type AlertNoise
- type AlertRules
- type AppComposeStore
- type AppGroupLister
- type AppImportStore
- type AppIntegrationStore
- type AppScheduleStore
- type AppSleepStore
- type AppStore
- type AppStreamStore
- type AppVolumeMoveStore
- type ApprovalChatNotifier
- type AuditStore
- type AuthLibOAuth
- type AuthStore
- type BackupDeleter
- type BackupDownloader
- type BackupHistoryStore
- type BackupProtection
- type BackupProtectionStore
- type BackupRunner
- type BackupSecretsSetter
- type BackupTargetStore
- type BackupTargetTester
- type BackupVerificationStore
- type BackupVerifier
- type BaseBackupHistoryStore
- type BaseBackupRunner
- type BetaFeatureStore
- type BitbucketAppClient
- type BitbucketAppSecrets
- type BitbucketAppStore
- type BuildCacheService
- type BuildCacheSettingsStore
- type Builder
- type CanaryStore
- type CertObservationSource
- type CertStore
- type CloneRestoreHistoryStore
- type CloneRestoreRunner
- type CloudflareDNSSecrets
- type CloudflareDNSStore
- type CloudflareDNSTokenResolver
- type CloudflareTunnelSecrets
- type CloudflareTunnelStore
- type ComposeRevisionStore
- type ComposeSecretStore
- type ContainerLister
- type ControlPlaneBackupManager
- type ControlPlaneDR
- type CustomTemplateStore
- type DBPinger
- type DataExportService
- type DataImportStore
- type DatabaseAccessStore
- type DatabaseQueryStore
- type DatabaseStore
- type DatabaseUpgrader
- type DatabaseVersionCatalog
- type DemoConfig
- type DemoStats
- type DeployApprovalStore
- type DeployAttemptStore
- type DeployExitStore
- type DeployGateStore
- type DeployLogQuerier
- type DeployNotifier
- type DeployNotifyTargets
- type DeployQueueStore
- type DeploySafetyStore
- type DeployStore
- type DevFixtureToken
- type DevFixtures
- type DeviceLoginNotifier
- type DockerDiskUsager
- type DockerGuardController
- type DockerHubClient
- type DockerPinger
- type DockerPruner
- type DoctorIngressEdge
- type Document
- type DomainAuthGateStore
- type DomainBasicAuthSecrets
- type DomainBasicAuthStore
- type DomainErrorPagesStore
- type DomainMaintenanceSettingsStore
- type DomainMaintenanceStore
- type DomainRedirectStore
- type DomainSearchVisibilityStore
- type DomainStore
- type DomainTLSCertSecrets
- type DomainTLSCertStore
- type DomainTrafficPolicyStore
- type DomainWAFStore
- type EdgeAccess
- type Effect
- type EmailSecretsStore
- type EmailSettingsStore
- type EnvironmentStore
- type ErrorStore
- type EscrowMaterialReader
- type EventWebhookService
- type ExposureStore
- type ExternalDatabaseStore
- type FeatureFlagStore
- type FirewallRuleStore
- type FixitStore
- type ForgeDeploymentStore
- type GPUHostDiagnoser
- type GateSettings
- type GateStore
- type GitHubAppClient
- type GitHubAppSecrets
- type GitHubAppStore
- type GitLabAppClient
- type GitLabAppSecrets
- type GitLabAppStore
- type GitSourceSecrets
- type GitSourceStore
- type GiteaAppClient
- type GiteaAppSecrets
- type GiteaAppStore
- type HookRunStore
- type HumanVerifier
- type ImageAutoUpdateStore
- type ImageLister
- type IngressPortOwner
- type IngressSettingsStore
- type InviteStore
- type LBAdminStateStore
- type LoadBalancerStore
- type LocalContainerLister
- type LogArchiveStore
- type LogArchiver
- type LogBudgetResource
- type LogBudgetStore
- type LogPipelineStore
- type LogUsageApp
- type LogUsageResponse
- type LoginCodeStore
- type MajorUpgradeStore
- type MajorUpgrader
- type MasterKeyRotator
- type MeshKeyRotator
- type MeshSettingsStore
- type MeshStatusProvider
- type MigrationHubStore
- type ModelPreflightService
- type ModelService
- type NetworkShareSecretsSetter
- type NetworkShareStore
- type NodeHostReports
- type NodeMeshStatusSource
- type NodeProviderConnectionStore
- type NodeProviderSecrets
- type NodeProvisionStore
- type NodeProvisioner
- type NodeProvisionerFactory
- type NodeRuntimeResolver
- type NodeSessionCloser
- type NodeStore
- type NotificationChannelTester
- type NotificationChannels
- type NotificationDeliveryStore
- type OAuthIdentityStore
- type OAuthSecrets
- type OAuthSettingsStore
- type OIDCJWKSProvider
- type OIDCKeyRotator
- type ObjectClientResolver
- type ObservabilityStore
- type OnboardingStore
- type Option
- func WithACMEDefaultDirectory(url string) Option
- func WithAIAssistantSecrets(s AIAssistantSecrets) Option
- func WithAIEngine(e AIEngine) Option
- func WithAPIRateLimit(readPerMinute, writePerMinute int) Option
- func WithAccessSource(s AccessSource) Option
- func WithAgentCAFingerprint(fp string) Option
- func WithAlertNoise(a AlertNoise) Option
- func WithAlertRules(a AlertRules) Option
- func WithAllowInsecureLogin(allow bool) Option
- func WithAppTeardownOptions(opts ...application.Option) Option
- func WithApprovalChatNotifier(n ApprovalChatNotifier) Option
- func WithAuditLogRetention(d time.Duration) Option
- func WithAuthEngine(e *authengine.Engine) Option
- func WithAuthEngineMFA(m *authengine.MFA) Option
- func WithAutoPlacement(enabled bool) Option
- func WithBackupDeleter(d BackupDeleter) Option
- func WithBackupDownloader(d BackupDownloader) Option
- func WithBackupProtection(p BackupProtection, st BackupProtectionStore) Option
- func WithBackupRunner(r BackupRunner) Option
- func WithBackupSecrets(s BackupSecretsSetter) Option
- func WithBackupTargetTester(t BackupTargetTester) Option
- func WithBackupVerifier(v BackupVerifier) Option
- func WithBaseBackupRunner(r BaseBackupRunner) Option
- func WithBitbucketAppSecrets(s BitbucketAppSecrets) Option
- func WithBuilder(b Builder) Option
- func WithCapacityForecastLookback(d time.Duration) Option
- func WithCertExpiryWarningWindow(d time.Duration) Option
- func WithCertRenewalTracking(src CertObservationSource, stalledThreshold time.Duration) Option
- func WithChangelog(entries []changelog.Entry) Option
- func WithCloneRestoreRunner(r CloneRestoreRunner) Option
- func WithCloudflareDNSSecrets(s CloudflareDNSSecrets) Option
- func WithCloudflareDNSTokenResolver(r CloudflareDNSTokenResolver) Option
- func WithCloudflareTunnelSecrets(s CloudflareTunnelSecrets) Option
- func WithComposeSecrets(s ComposeSecretStore) Option
- func WithContainerLister(l ContainerLister) Option
- func WithControlPlaneBackupScheduleDisabled(disabled bool) Option
- func WithControlPlaneBackups(m ControlPlaneBackupManager) Option
- func WithControlPlaneDR(dr ControlPlaneDR, material EscrowMaterialReader) Option
- func WithDBPinger(p DBPinger) Option
- func WithDashboardCache(ttl, stale time.Duration) Option
- func WithDashboardListenAddr(addr string) Option
- func WithDashboardURL(u string) Option
- func WithDataDir(path string) Option
- func WithDatabaseAccess(s DatabaseAccessStore, ttl dbaccess.TTLLimits) Option
- func WithDatabaseUpgrader(u DatabaseUpgrader) Option
- func WithDeleteTeardownTimeout(d time.Duration) Option
- func WithDemoMode(cfg DemoConfig) Option
- func WithDeployApprovalTTL(d time.Duration) Option
- func WithDeployGate(s DeployGateStore, defaults deploysafety.Effective) Option
- func WithDeployLogQuerier(s DeployLogQuerier) Option
- func WithDeployMaxConcurrent(n int) Option
- func WithDeployNotifier(n DeployNotifier) Option
- func WithDeployNotifyTargets(t DeployNotifyTargets) Option
- func WithDeployRecorder(r *deploylog.Recorder) Option
- func WithDeploySafety(s DeploySafetyStore, resolver docker.ImageResolver) Option
- func WithDeviceLoginNotifier(n DeviceLoginNotifier) Option
- func WithDockerDiskUsager(u DockerDiskUsager) Option
- func WithDockerGuard(c DockerGuardController) Option
- func WithDockerPinger(p DockerPinger) Option
- func WithDockerPruner(p DockerPruner) Option
- func WithDoctorAgentAdvertise(host string, port int) Option
- func WithDoctorClockSkewWarnAge(d time.Duration) Option
- func WithDoctorDiskIOWarnLatency(d time.Duration) Option
- func WithDoctorDiskWarningBytes(n int64) Option
- func WithDoctorIngressPorts(httpPort, httpsPort int) Option
- func WithDoctorMasterKeyRotationWarnAge(d time.Duration) Option
- func WithDoctorMinCPUCount(n int) Option
- func WithDoctorMinRAMBytes(n int64) Option
- func WithDoctorNetworkTimeout(d time.Duration) Option
- func WithDoctorPublicIPEndpoint(url string) Option
- func WithDomainBasicAuthSecrets(s DomainBasicAuthSecrets) Option
- func WithDomainTLSCertSecrets(s DomainTLSCertSecrets) Option
- func WithEmailSecrets(s EmailSecretsStore) Option
- func WithEmailSender(s email.Sender) Option
- func WithErrorStore(s ErrorStore) Option
- func WithExecRuntime(r NodeRuntimeResolver) Option
- func WithExposure(m *exposure.Manager, s ExposureStore) Option
- func WithFirewallRequiredPorts(ports []int) Option
- func WithFixit(s FixitStore) Option
- func WithGPUHostDiagnoser(d GPUHostDiagnoser) Option
- func WithGitHubAppManifestConfig(cfg githubapp.ManifestConfig) Option
- func WithGitHubAppSecrets(s GitHubAppSecrets) Option
- func WithGitLabAppSecrets(s GitLabAppSecrets) Option
- func WithGitSourceSecrets(s GitSourceSecrets) Option
- func WithGiteaAppSecrets(s GiteaAppSecrets) Option
- func WithHSTS(enabled bool) Option
- func WithHTTPSEnableLimits(maxPerHour int, pendingTimeout time.Duration) Option
- func WithHostFirewallRunner(run func(ctx context.Context, name string, args ...string) ([]byte, error), ...) Option
- func WithImageLister(l ImageLister) Option
- func WithIngressPortOwner(o IngressPortOwner) Option
- func WithInviteTTL(d time.Duration) Option
- func WithJobLimits(maxPerApp int) Option
- func WithLoadBalancers(s LoadBalancerStore, registry *loadbalancer.Registry, ...) Option
- func WithLogBroadcaster(b *telemetry.LogBroadcaster) Option
- func WithLogBudgetStore(s LogBudgetStore) Option
- func WithLogPipelineStore(s LogPipelineStore) Option
- func WithLoginCodeKey(key []byte) Option
- func WithMajorUpgrader(u MajorUpgrader) Option
- func WithMasterKeyRotation(r MasterKeyRotator, masterKeyFilePath string) Option
- func WithMasterKeyWrapper(w secrets.KeyWrapper) Option
- func WithMeshSettings(s MeshSettingsStore) Option
- func WithMinAgentVersion(v string) Option
- func WithModels(s ModelService) Option
- func WithMultiNode(s PlacementStore, cfg nodemove.Config, meshPortMin, meshPortMax int) Option
- func WithNetworkShareSecrets(s NetworkShareSecretsSetter) Option
- func WithNewDeviceApproval(on bool) Option
- func WithNodeAlertThresholds(patchStatus, nodeDiskSpace, nodeCPU, nodeMemory float64) Option
- func WithNodeCertThresholds(warning, critical time.Duration) Option
- func WithNodeJoinTokenTTL(d time.Duration) Option
- func WithNodeProviderSecrets(s NodeProviderSecrets) Option
- func WithNodeProvisionerFactory(f NodeProvisionerFactory) Option
- func WithNodeProvisions(s NodeProvisionStore) Option
- func WithNodeSessionCloser(c NodeSessionCloser) Option
- func WithNotificationChannelTester(t NotificationChannelTester) Option
- func WithNotificationChannels(c NotificationChannels) Option
- func WithNotificationDeliveries(d NotificationDeliveryStore) Option
- func WithOAuthSecrets(s OAuthSecrets) Option
- func WithOrphanedContainerManager(m OrphanedContainerManager) Option
- func WithOrphanedVolumeManager(m OrphanedVolumeManager) Option
- func WithPITRRestoreRunner(r PITRRestoreRunner) Option
- func WithPipelines(st PipelineStore, runner PipelineRunner) Option
- func WithPreviewLimits(l PreviewLimits) Option
- func WithPreviewStuckAfter(d time.Duration) Option
- func WithPreviewTTL(d time.Duration) Option
- func WithPublicHost(host string) Option
- func WithPublicHostSource(source string) Option
- func WithPushVAPIDPublicKey(publicKey string) Option
- func WithReadinessProbes(p ReadinessProbes) Option
- func WithReconcileNudger(n ReconcileNudger) Option
- func WithRegistryAuthTester(t RegistryAuthTester) Option
- func WithRegistryCatalogSecrets(s RegistryCatalogSecrets) Option
- func WithRegistryCredentialSecrets(s RegistryCredentialSecretsSetter) Option
- func WithRegistrySecrets(s RegistrySecrets) Option
- func WithRequestLogThresholds(slow, critical time.Duration) Option
- func WithRequestSummaryWindow(d time.Duration) Option
- func WithResourceRecommendationLookback(d time.Duration) Option
- func WithRestoreRunner(r RestoreRunner) Option
- func WithRoute53DNSCredentialResolver(r Route53DNSCredentialResolver) Option
- func WithRoute53DNSSecrets(s Route53DNSSecrets) Option
- func WithSSHNodeProvisions(s SSHNodeProvisionStore) Option
- func WithSSHProvisioner(p SSHProvisioner) Option
- func WithScheduledTaskRunner(r ScheduledTaskRunner) Option
- func WithSecretBinding(b SecretBinder) Option
- func WithSecretRotationWarnAge(d time.Duration) Option
- func WithSecretSetter(s SecretSetter) Option
- func WithSelfUpgrade(s SelfUpgradeStore, launch SelfUpgradeLauncher) Option
- func WithServiceVolumeBackupRunner(r ServiceVolumeBackupRunner) Option
- func WithServiceVolumeRestoreRunner(r ServiceVolumeRestoreRunner) Option
- func WithSessionTTL(d time.Duration) Option
- func WithStaleSecretCounter(c StaleSecretCounter) Option
- func WithStandaloneSafety(s StandaloneSafety) Option
- func WithStaticOrphanGrace(d time.Duration) Option
- func WithStaticRootDir(dir string) Option
- func WithStatusPage(db StatusPageDB, cfg statuspage.Config, perMinute int) Option
- func WithStatusPageViewer(st StatusPageStore, v StatusPageViewer, perMinute int) Option
- func WithStorage(d StorageDeps) Option
- func WithTelemetryQuerier(q TelemetryQuerier) Option
- func WithTokenRedeemRateLimit(perMinute int) Option
- func WithTraceStore(s TraceStore) Option
- func WithUpgradeHistory(s UpgradeHistoryStore) Option
- func WithUpgradeScheduling(s UpgradeScheduleStore, sender dbupgrade.NoticeSender, cfg upgradesched.Config) Option
- func WithVaultSecrets(s VaultSecrets) Option
- func WithVolumeCloneRestoreRunner(r VolumeCloneRestoreRunner) Option
- func WithWakeToken(token string) Option
- func WithWebhookDeliveryRetention(d time.Duration) Option
- func WithWebhookFailedDeliveryLimits(keep, bodyBytes int) Option
- func WithWebhookRateLimit(perMinute int) Option
- type OrganizationStore
- type OrphanSweepResult
- type OrphanedContainerManager
- type OrphanedVolumeManager
- type PITRRestoreHistoryStore
- type PITRRestoreRunner
- type PackageRegistryStore
- type PipelineEvents
- type PipelineOverviewStore
- type PipelineRunner
- type PipelineStore
- type PipelineSyncStore
- type PipelineSyncer
- type PlacementStore
- type PolicyStore
- type PreviewEnvironmentStore
- type PreviewLimits
- type PreviewService
- type ProbeAttemptStore
- type ProjectStore
- type ProxyIntegrationStore
- type PushSubscriptions
- type ReadinessProbes
- type ReconcileNudger
- type RegistryAuthTester
- type RegistryCatalogClient
- type RegistryCatalogSecrets
- type RegistryCredentialSecretsSetter
- type RegistryCredentialStore
- type RegistrySecrets
- type RegistryStore
- type Restarter
- type RestoreHistoryStore
- type RestoreRunner
- type Role
- type RoleStore
- type Route53DNSCredentialResolver
- type Route53DNSSecrets
- type Route53DNSStore
- type Router
- func (rt *Router) BudgetStatuses(ctx context.Context) ([]usagecost.BudgetStatus, error)
- func (rt *Router) CheckDomainStatus(ctx context.Context, domain string) (string, error)
- func (rt *Router) CheckImageUpdate(ctx context.Context, serviceName string) (string, error)
- func (rt *Router) ComplianceSecuritySnapshot(ctx context.Context) (any, error)
- func (rt *Router) ComplianceUserRemover() compliance.UserRemover
- func (rt *Router) DemoStats() DemoStats
- func (rt *Router) DrainDeployQueue(ctx context.Context)
- func (rt *Router) GitSourceCloneToken(ctx context.Context, name, repoURL string) string
- func (rt *Router) Handler() http.Handler
- func (rt *Router) NudgeReconciler()
- func (rt *Router) PipelineRunEnv(ctx context.Context, run store.PipelineRun) map[string]string
- func (rt *Router) PipelineStatusReporter() pipeline.StatusReporter
- func (rt *Router) PurgeOldAuditEntries(ctx context.Context) (int64, error)
- func (rt *Router) PurgeOldWebhookDeliveries(ctx context.Context) (int64, error)
- func (rt *Router) RecordRevoked(ctx context.Context, c dbaccess.TempCredential)
- func (rt *Router) ReleaseHandlers() map[string]deploy.ReleaseHandler
- func (rt *Router) ResumeCutoverRuns(ctx context.Context)
- func (rt *Router) RevokeTemp(ctx context.Context, name, role string) error
- func (rt *Router) RunAuditLogSweeper(ctx context.Context, interval time.Duration) error
- func (rt *Router) RunDeployApprovalExpirySweep(ctx context.Context, interval time.Duration) error
- func (rt *Router) RunDeviceLoginExpirySweeper(ctx context.Context) error
- func (rt *Router) RunGateSweeper(ctx context.Context, interval time.Duration) error
- func (rt *Router) RunNodeMoves(ctx context.Context)
- func (rt *Router) RunPreviewSweeper(ctx context.Context, interval time.Duration) error
- func (rt *Router) RunStatusPageSampler(ctx context.Context) error
- func (rt *Router) RunWebhookDeliverySweeper(ctx context.Context, interval time.Duration) error
- func (rt *Router) SetAppTeardownOptions(opts ...application.Option)
- func (rt *Router) SetCompliance(s *compliance.Service)
- func (rt *Router) SetControlPlaneDR(dr ControlPlaneDR, material EscrowMaterialReader)
- func (rt *Router) SetDataExport(s DataExportService)
- func (rt *Router) SetDatabaseUpgrader(u DatabaseUpgrader)
- func (rt *Router) SetDatabaseVersionCatalog(c DatabaseVersionCatalog)
- func (rt *Router) SetDockerGuard(c DockerGuardController)
- func (rt *Router) SetDoctorIngressEdge(edge DoctorIngressEdge)
- func (rt *Router) SetEventWebhooks(s EventWebhookService)
- func (rt *Router) SetForgeDeployments(s ForgeDeploymentStore)
- func (rt *Router) SetGate(secret string, settings GateSettings)
- func (rt *Router) SetLoadBalancers(s LoadBalancerStore, registry *loadbalancer.Registry, ...)
- func (rt *Router) SetLocalNodeID(id string)
- func (rt *Router) SetMesh(mesh MeshStatusProvider, rotator MeshKeyRotator)
- func (rt *Router) SetMeshPaths(r meshpath.Resolver)
- func (rt *Router) SetMeshPeerStatus(src NodeMeshStatusSource)
- func (rt *Router) SetMeshStartError(err error)
- func (rt *Router) SetMeshZone(zone string)
- func (rt *Router) SetNodeHostReports(src NodeHostReports)
- func (rt *Router) SetOIDCManager(m OIDCJWKSProvider, issuerURL string, ratePerMinute int)
- func (rt *Router) SetOIDCRotator(r OIDCKeyRotator)
- func (rt *Router) SetOrphanReaper(r *orphans.Reaper)
- func (rt *Router) SetPipelineEvents(e PipelineEvents)
- func (rt *Router) SetPipelineSync(syncer PipelineSyncer, st PipelineSyncStore)
- func (rt *Router) SetPipelines(st PipelineStore, runner PipelineRunner)
- func (rt *Router) SetPreview(p PreviewService)
- func (rt *Router) SetProxyIntegration(syncer *proxyroutes.Syncer, st ProxyIntegrationStore, ...)
- func (rt *Router) SetProxyRouteCheck(rc ingress.RouteCheck)
- func (rt *Router) SetRestarter(r Restarter)
- func (rt *Router) SetScheduledMaintenance(s ScheduledMaintenanceStore)
- func (rt *Router) SetSecretRotation(st SecretRotationStore, maxPerPass int, dueSoon time.Duration) *secretrotation.Engine
- func (rt *Router) SetSecretScan(s SecretScanService)
- func (rt *Router) SetStorage(d StorageDeps)
- func (rt *Router) SetSupplyChain(s SupplyChainService)
- func (rt *Router) SetWALShipStatus(src WALShipStatusSource)
- func (rt *Router) StaticOrphanGrace() time.Duration
- func (rt *Router) StatusHostHandler(next http.Handler) http.Handler
- func (rt *Router) StatusPageAppStatus(ctx context.Context, name string) (string, error)
- func (rt *Router) SweepDeviceLoginExpiry(ctx context.Context, now time.Time) (int, error)
- func (rt *Router) SweepOrphanPreviews(ctx context.Context) (OrphanSweepResult, error)
- func (rt *Router) SweepOrphanStaticSites(ctx context.Context) ([]string, error)
- func (rt *Router) SweepSignInExpiry(ctx context.Context, now time.Time) error
- func (rt *Router) SweepStalePreviewEnvironments(ctx context.Context) (swept int, err error)
- func (rt *Router) SweepTokenHygiene(ctx context.Context, now time.Time) error
- func (rt *Router) TriggerScheduledDeploy(ctx context.Context, serviceName, branch string) (string, error)
- func (rt *Router) UpgradeScheduler() *upgradesched.Scheduler
- func (rt *Router) UsageRollupTick(ctx context.Context)
- func (rt *Router) WithHSTS(next http.Handler) http.Handler
- type SSHNodeProvisionStore
- type SSHProvisioner
- type SSOStore
- type ScheduledMaintenanceStore
- type ScheduledTaskRunner
- type ScheduledTaskStarter
- type ScheduledTaskStore
- type SecretBinder
- type SecretRotationStore
- type SecretScanService
- type SecretSetter
- type SecurityStore
- type SelfUpgradeLauncher
- type SelfUpgradeStore
- type ServiceVolumeBackupHistoryStore
- type ServiceVolumeBackupRunner
- type ServiceVolumeBackupScheduleStore
- type ServiceVolumeRestoreHistoryStore
- type ServiceVolumeRestoreRunner
- type SessionLinkTokenStore
- type SetupGuideStore
- type StaleSecretCounter
- type StandaloneSafety
- type Statement
- type StaticSiteStore
- type StatusPageDB
- type StatusPageStore
- type StatusPageViewer
- type StorageDeps
- type StorageOptionsStore
- type Store
- type SupplyChainService
- type TagStore
- type TelemetryQuerier
- type TokenStore
- type TraceStore
- type TrialKeeper
- type UpdateSettingsStore
- type UpgradeHistoryStore
- type UpgradeScheduleStore
- type UserCounter
- type VaultSecrets
- type VaultSettingsStore
- type VolumeCloneRestoreHistoryStore
- type VolumeCloneRestoreRunner
- type WALShipStatusSource
- type WebhookDeliveryStore
Constants ¶
const ( AbilityRead = "read" AbilityReadSensitive = "read:sensitive" AbilityWrite = "write" AbilityWriteSensitive = "write:sensitive" AbilityDeploy = "deploy" AbilityRoot = "root" // AbilitySignInApprove lets a token reveal its owner's sign-in codes and // decide new-browser approvals. Root never implies it. AbilitySignInApprove = "signin:approve" )
Ability strings an api_tokens row can be scoped to, adopted from Coolify's own model: a small, legible permission surface an MCP-issued token can be provably scoped to at the token layer itself, not just by convention in what a caller chooses to call. AbilityRoot is exclusive of the rest (checked at mint time, see validateAbilities), not additive with them.
const ( AIAssistantTokenName = "AI Assistant (internal)" AIAssistantAgentName = "ai-assistant" )
AIAssistantTokenName and AIAssistantAgentName identify the internal token the in-app assistant holds.
const ( HealthScoreStatusPass = "pass" HealthScoreStatusWarn = "warn" HealthScoreStatusFail = "fail" )
Health score statuses. One shared set of constants, referenced by every category computation below and by the CLI's own rendering, so "pass"/"warn"/"fail" is never retyped as a bare string literal in two places that could silently drift.
const ( ClientKindCLI = "cli" ClientKindDashboard = "dashboard" ClientKindMCP = "mcp" ClientKindAPI = "api" // ClientKindSystem is written directly by internal/ingress's // SQLiteStorage for a certificate issuance/renewal it detects, not // derived here: there is no User-Agent, because there is no request. ClientKindSystem = "system" )
Client kind values audit_log.client_kind (migrations/0077) is normalized into: which surface actually made the request, not just which auth method it used (store.AuditEntry.ActorType already covers session-vs-token).
const ( OutcomeInProgress = "in_progress" OutcomeHealthy = "healthy" OutcomeFailed = "failed" OutcomeCanceled = "canceled" OutcomeSuperseded = "superseded" OutcomeBlocked = "blocked" )
Deploy outcomes reported by GET /apps/{name}/deploys/{deployId}.
const ( StatusBuilding = "building" StatusRollingOut = "rolling_out" )
Non-terminal and derived statuses reported by the single-deploy endpoint.
const ( EnvGateSessionTTL = "APP_GATE_SESSION_TTL" EnvGateTokenTTL = "APP_GATE_TOKEN_TTL" //nolint:gosec // env var name, not a credential EnvGateEventRetention = "APP_GATE_EVENT_RETENTION" EnvGateAllowHTTP = "APP_GATE_ALLOW_HTTP" )
Env vars for the built-in auth gate provider.
const ( RoleAdmin = "admin" RoleOperator = "operator" RoleViewer = "viewer" )
Curated role names, roles's own Name values.
const ( TopologyKindApp = "app" TopologyKindDatabase = "database" TopologyKindVolume = "volume" TopologyKindDomain = "domain" TopologyKindLB = "load_balancer" TopologyKindNode = "node" TopologyEdgeDatabaseBinding = "database_binding" TopologyEdgeDependsOn = "depends_on" TopologyEdgeVolume = "volume_attachment" TopologyEdgeEgressAllow = "egress_allow" TopologyEdgeRouting = "routing" TopologyEdgeLoadBalances = "load_balances" TopologyEdgePlacedOn = "placed_on" )
Topology node/edge kinds: the vocabulary GET /api/v1/projects/{id}/topology (topology.go) reports, and web/src/routes/projects/$id/topology.tsx renders. An "app" node is one store.DesiredService, the same unit GET /api/v1/apps already calls an app (appListResource); multi-service apps (store.App) show up as one node per member service, not one collapsed node, since depends_on and database bindings are declared per service, not per App row.
const ACMEStagingDirectoryURL = "https://acme-staging-v02.api.letsencrypt.org/directory"
ACMEStagingDirectoryURL is Let's Encrypt's staging CA: no rate limits that matter, certificates browsers do not trust.
const AbilitySecretsReveal = "secrets:reveal"
AbilitySecretsReveal lets an API token reveal secret values, and only together with read:sensitive, APP_SECRET_REVEAL_TOKENS=on and a proof of its owner's password. Root never implies it.
const AgentClientHeader = "X-Agent-Client"
AgentClientHeader carries the MCP client name and version an agent-side server reports for the request. It is self-reported and informational.
const EnvAITurnTokenTTL = "APP_AI_TURN_TOKEN_TTL" //nolint:gosec // an env var name, not a credential
EnvAITurnTokenTTL overrides how long one assistant turn's token lives.
const EnvGitStatusEnabled = "APP_GIT_STATUS_ENABLED"
EnvGitStatusEnabled is the server kill switch for posting commit statuses and deployments back to git forges. Unset means on.
const ExperimentalDisabledCode = "experimental_feature_disabled"
ExperimentalDisabledCode is the error code returned for a gated route.
const SetupTokenFilename = "setup-token"
SetupTokenFilename is the file under the data dir holding the one-time first-admin token.
Variables ¶
This section is empty.
Functions ¶
func ApprovalMatch ¶
ApprovalMatch is the two digit number a waiting browser shows for its sign-in.
func AttentionResolvedWindow ¶ added in v0.2.0
AttentionResolvedWindow is how long expired, denied and approved device logins stay visible, APP_ATTENTION_RESOLVED_WINDOW.
func BootstrapAdmin ¶
BootstrapAdmin ensures at least one user exists, creating one from username/password if none does yet, with AbilityRoot: it's the only user on the instance, so it has to be. No-op once any user exists, so a restart with the same env vars never resets a changed password. username becomes the new user's email verbatim (no "@" required), matching migrations/0035's backfill leniency for a pre-existing admin_user row.
func DeviceCodeTTL ¶ added in v0.2.0
DeviceCodeTTL is how long a device login request stays approvable, APP_DEVICE_CODE_TTL as a Go duration when set.
func DeviceTokenTTL ¶ added in v0.2.0
DeviceTokenTTL is the lifetime of a device-login token (APP_DEVICE_TOKEN_TTL_DAYS).
func DockerGuardAuditEntry ¶ added in v0.2.0
func DockerGuardAuditEntry(d dockerguard.Decision) (store.AuditEntry, error)
DockerGuardAuditEntry turns a guard decision into an audit_log row. The path carries the container name, never the request body.
func EnsureSetupToken ¶ added in v0.2.0
func EnsureSetupToken(ctx context.Context, users UserCounter, dataDir string) (token string, created bool, err error)
EnsureSetupToken returns the setup token for an instance with no users, creating it (mode 0600) if missing; created reports whether it is new. Once any user exists the file is removed and "" is returned.
func HostFirewallSSHPorts ¶ added in v0.2.0
func HostFirewallSSHPorts() []int
HostFirewallSSHPorts exposes the SSH ports the firewall switch keeps open, so the exposure lockout guard protects the same set.
func LoadBetaFeatures ¶ added in v0.2.0
func LoadBetaFeatures(ctx context.Context, s BetaFeatureStore) error
LoadBetaFeatures applies stored Settings switches at startup.
func MaybeBootstrapDevAdmin ¶
MaybeBootstrapDevAdmin is cmd/levelrail/main.go's entry point, called unconditionally on every startup the same way BootstrapAdmin already is: a no-op unless APP_DEV_MODE=1 in a non -tags embedweb build (see devmode_debug.go/devmode_release.go). BootstrapAdmin itself is a no-op once any admin account exists, so this only ever creates the fixed dev/dev account on a genuinely empty data directory; an operator who already set APP_ADMIN_USERNAME/APP_ADMIN_PASSWORD keeps that account regardless of call order between the two.
func MaybeSeedDevFixturesFromFile ¶
func MaybeSeedDevFixturesFromFile(ctx context.Context, s TokenStore, logger *slog.Logger, path string) error
MaybeSeedDevFixturesFromFile is cmd/levelrail/main.go's entry point, called unconditionally on every startup the same way MaybeBootstrapDevAdmin already is. A missing fixtures file is not an error: dev mode works without one (only the fixed dev/dev admin account), a dev-fixtures.yml is an opt-in convenience layered on top.
func MintAPIToken ¶ added in v0.2.0
func MintAPIToken(ctx context.Context, tokens TokenStore, name string, abilities []string, expiresAt *time.Time) (string, store.APIToken, error)
MintAPIToken generates, hashes, and persists a new API token, returning its plaintext exactly once, same as handleCreateToken's own response. Exported so a non-HTTP caller (cmd/levelrail's own internal AI assistant self-call token, minted once at startup rather than by a human through this handler) can mint through the identical path instead of duplicating it.
func MintAgentAPIToken ¶ added in v0.2.0
func MintAgentAPIToken(ctx context.Context, tokens TokenStore, name string, abilities []string, expiresAt *time.Time, agent agentIdentity, ownerUserID string) (string, store.APIToken, error)
MintAgentAPIToken is MintAPIToken with an agent label and an owning user (empty for system tokens).
func NewDeviceApprovalFromEnv ¶ added in v0.2.0
func NewDeviceApprovalFromEnv() bool
NewDeviceApprovalFromEnv reads APP_AUTH_NEW_DEVICE_APPROVAL: on unless set to a false value, the break-glass switch for a locked-out operator.
func PeerIsTrustedProxy ¶ added in v0.3.0
PeerIsTrustedProxy is peerIsTrustedProxy for wiring outside this package.
func ReadSetupToken ¶ added in v0.2.0
ReadSetupToken returns the current setup token, or "" if none exists.
func SetupTokenPath ¶ added in v0.2.0
SetupTokenPath returns the setup token file path inside dataDir.
Types ¶
type AIAssistantSecrets ¶ added in v0.2.0
type AIAssistantSecrets interface {
SetValue(ctx context.Context, serviceName, envKey, plaintext string) error
Exists(ctx context.Context, serviceName, envKey string) (bool, error)
DeleteAll(ctx context.Context, serviceName string) error
}
AIAssistantSecrets is the internal/secrets.Manager surface PUT/DELETE need to store and clear the BYOK key. nil is valid: both routes return 501 without one configured, the same shape EmailSecretsStore's absence produces; GET works regardless.
type AIAssistantSettingsStore ¶ added in v0.2.0
type AIAssistantSettingsStore interface {
GetAIAssistantSettings(ctx context.Context) (store.AIAssistantSettings, error)
UpdateAIAssistantSettings(ctx context.Context, s store.AIAssistantSettings) error
}
AIAssistantSettingsStore is the core internal/store surface GET/PUT/ DELETE /api/v1/settings/ai-assistant need: always set, the provider/ model row always exists (migrations/0106's own seeded row), the same "core Store interface" shape ingressSettings/emailSettings already establish.
type AIChatStore ¶ added in v0.2.0
type AIChatStore interface {
CreateAIChatSession(ctx context.Context, id, owner string, now time.Time) (store.AIChatSession, error)
GetAIChatSession(ctx context.Context, id string) (store.AIChatSession, error)
ListAIChatSessions(ctx context.Context, owner string) ([]store.AIChatSession, error)
DeleteAIChatSession(ctx context.Context, id, owner string) error
ListAIChatMessages(ctx context.Context, sessionID string) ([]store.AIChatMessage, error)
GetAIChatConfirmation(ctx context.Context, id string) (store.AIChatConfirmation, error)
}
AIChatStore is the core internal/store surface the chat session routes need: always set, the same "core Store interface" shape certs/ staticSites already establish, since a session/message/confirmation row's absence is always a legitimate, queryable "not found", not a "not configured" condition.
type AIControlStore ¶ added in v0.2.0
type AIControlStore interface {
GetAIControlSettings(ctx context.Context) (store.AIControlSettings, error)
UpdateAIControlSettings(ctx context.Context, mode string, kinds []string, updatedBy string) error
RevokeAgentTokens(ctx context.Context, internalName, internalAgent string) (int, error)
CountAgentTokens(ctx context.Context, internalName, internalAgent string) (int, error)
EnvironmentOfApp(ctx context.Context, appName string) (*store.EnvironmentRef, error)
EnvironmentOfDatabase(ctx context.Context, databaseName string) (*store.EnvironmentRef, error)
}
AIControlStore is the store surface the AI control gate and settings routes need.
type AIEngine ¶ added in v0.2.0
type AIEngine interface {
IsConfigured(ctx context.Context) (bool, error)
RunTurn(ctx context.Context, sessionID, userContent string, sink ai.Sink) error
ResolveConfirmation(ctx context.Context, sessionID, confirmationID string, approve bool, sink ai.Sink) error
}
AIEngine is the internal/ai.Engine surface the chat routes need. nil is valid: every /api/v1/ai/... route returns 501 without one configured, the same "not configured" shape secrets/telemetry's absence already produce elsewhere in this package.
type AccessPolicyStore ¶
type AccessPolicyStore interface {
ListSessionPolicies(ctx context.Context) ([]store.SessionPolicy, error)
SessionPoliciesForUser(ctx context.Context, userID string) ([]store.SessionPolicy, error)
GetSessionPolicy(ctx context.Context, teamID string) (store.SessionPolicy, error)
SaveSessionPolicy(ctx context.Context, p store.SessionPolicy) error
DeleteSessionPolicy(ctx context.Context, teamID string) error
GetSessionActivity(ctx context.Context, sessionID string) (store.SessionActivity, error)
TouchSessionActivity(ctx context.Context, sessionID, userID string, now time.Time) error
SetSessionMethod(ctx context.Context, sessionID, userID, method string, now time.Time) error
TeamMemberRole(ctx context.Context, teamID, userID string) (string, error)
}
AccessPolicyStore is the persistence the session policy needs. *store.DB satisfies it.
type AccessSource ¶
type AccessSource interface {
AppAccess(app string, f ingress.AccessFilter) []ingress.AccessRecord
}
AccessSource reads recent edge requests for an app.
type AlertNoise ¶ added in v0.2.0
type AlertNoise interface {
CreateSilence(ctx context.Context, s alerting.Silence) error
GetSilence(ctx context.Context, id string) (*alerting.Silence, error)
ListSilences(ctx context.Context, now time.Time, includeExpired bool, limit int) ([]alerting.Silence, error)
ListActiveSilences(ctx context.Context, now time.Time) ([]alerting.Silence, error)
ExpireSilence(ctx context.Context, id string, now time.Time) (*alerting.Silence, error)
SaveMaintenanceWindow(ctx context.Context, w alerting.MaintenanceWindow) error
GetMaintenanceWindow(ctx context.Context, id string) (*alerting.MaintenanceWindow, error)
ListMaintenanceWindows(ctx context.Context) ([]alerting.MaintenanceWindow, error)
DeleteMaintenanceWindow(ctx context.Context, id string) error
ListHistory(ctx context.Context, f alerting.HistoryFilter) ([]alerting.HistoryEntry, error)
}
AlertNoise is the surface the silence, maintenance window and alert history handlers need from internal/alerting.DB.
type AlertRules ¶
type AlertRules interface {
SaveRule(ctx context.Context, r alerting.Rule) error
GetRule(ctx context.Context, id string) (*alerting.Rule, error)
ListRulesForResource(ctx context.Context, resourceID string) ([]alerting.Rule, error)
DeleteRule(ctx context.Context, id string) error
}
AlertRules is the surface the alert-rule handlers need from internal/alerting.DB. *alerting.DB satisfies this structurally, the same "narrow consumer-defined interface" convention TelemetryQuerier and SecretSetter already establish in this package.
type AppComposeStore ¶
type AppComposeStore interface {
SaveApp(ctx context.Context, a store.App) error
GetAppByName(ctx context.Context, name string) (store.App, error)
SaveDesiredService(ctx context.Context, svc store.DesiredService) error
}
AppComposeStore is the store surface POST /api/v1/apps/{name}/compose needs (apps_compose.go): create-or-reuse the owning store.App, then save each of its member services.
type AppGroupLister ¶
type AppGroupLister interface {
ListServicesByApp(ctx context.Context, appID string) ([]store.DesiredService, error)
DeleteApp(ctx context.Context, id string) error
SaveApp(ctx context.Context, a store.App) error
GetAppByName(ctx context.Context, name string) (store.App, error)
}
AppGroupLister is the store surface GET /api/v1/apps/{name}/group (apps_group.go) and the app-linking write path (apps_multi.go's ensureAppLinked, apps.go's deleteAppIfOrphaned) need: stage 1 of multi-service apps (migrations/0039_apps.sql) started this as a read-only interface; stage 2 (per-app Docker networking) added the store.App CRUD every create/delete path needs to keep that App row's lifecycle in sync with its member services, since internal/reconcile/application.NetworkCleanupController diffs exactly the App rows this interface reports against Docker's own observed networks. *store.DB satisfies this structurally.
type AppImportStore ¶ added in v0.2.0
type AppImportStore interface {
CreateAppImportSession(ctx context.Context, s store.AppImportSession, items []store.AppImportItem) error
GetAppImportSession(ctx context.Context, id string) (store.AppImportSession, error)
ListAppImportSessions(ctx context.Context) ([]store.AppImportSession, error)
UpdateAppImportSession(ctx context.Context, s store.AppImportSession, now time.Time) error
DeleteAppImportSession(ctx context.Context, id string) error
ListAppImportItems(ctx context.Context, sessionID string) ([]store.AppImportItem, error)
SaveAppImportItem(ctx context.Context, it store.AppImportItem, now time.Time) error
}
AppImportStore is the store surface the guided app import routes need.
type AppIntegrationStore ¶ added in v0.2.0
type AppIntegrationStore interface {
SaveAppIntegration(ctx context.Context, ai store.AppIntegration) error
GetAppIntegration(ctx context.Context, id string) (store.AppIntegration, error)
ListAppIntegrationsForService(ctx context.Context, serviceName string) ([]store.AppIntegration, error)
DeleteAppIntegration(ctx context.Context, id string) error
}
AppIntegrationStore is the store surface the app integration handlers need, mirroring ScheduledTaskStore's own shape for a different per-app child resource.
type AppScheduleStore ¶ added in v0.2.0
type AppScheduleStore interface {
GetAppSchedule(ctx context.Context, serviceName string) (*store.AppSchedule, error)
SetAppSchedule(ctx context.Context, serviceName, cron, branch, timezone string, enabled bool) error
ArmAppScheduleNextRun(ctx context.Context, serviceName string, next time.Time) error
ListAppScheduleHistory(ctx context.Context, serviceName string, limit int) ([]store.AppScheduleHistoryEntry, error)
}
AppScheduleStore is the store surface the schedule handlers and internal/scheduledeploy.Scheduler both need. *store.DB satisfies this structurally.
type AppSleepStore ¶ added in v0.2.0
type AppSleepStore interface {
SetAppSleepIdle(ctx context.Context, serviceName string, minutes int, now time.Time) error
SetAppSleeping(ctx context.Context, serviceName string, sleeping bool, now time.Time) error
SetAppSleepHold(ctx context.Context, serviceName string, hold bool, now time.Time) error
GetAppSleep(ctx context.Context, serviceName string) (store.AppSleep, error)
ListAppSleep(ctx context.Context) ([]store.AppSleep, error)
}
AppSleepStore is the store surface the sleep routes need.
type AppStore ¶
type AppStore interface {
SaveDesiredService(ctx context.Context, svc store.DesiredService) error
GetDesiredService(ctx context.Context, name string) (*store.DesiredService, error)
ListDesiredServices(ctx context.Context) ([]store.DesiredService, error)
DeleteDesiredService(ctx context.Context, name string) error
// ListAppStreamsForService backs internal/reconcile/application's
// ServiceStore (the same interface this type satisfies for the
// application controller's own New call): one extra published
// container port per raw TCP stream (migrations/0279_app_streams.sql).
ListAppStreamsForService(ctx context.Context, serviceName string) ([]store.AppStream, error)
// UpdateServiceNode is the placement mutation, separate
// from SaveDesiredService on purpose: see store.DB.SaveDesiredService's
// own doc comment for why an ordinary app update must never be able
// to silently move a service between nodes.
UpdateServiceNode(ctx context.Context, name, nodeID string) error
// ListDesiredServicesByNode is the drain and
// delete-guard primitive (handleDrainNode, handleDeleteNode): find
// what's placed on a node without listing every service.
ListDesiredServicesByNode(ctx context.Context, nodeID string) ([]store.DesiredService, error)
// ListDesiredServicesByProject is ListDesiredServicesByNode's
// project-kind counterpart: handleStopProject/handleStartProject
// (project_stop_start.go) and handleRestartProject
// (project_restart.go) use it to find every app in a project without
// listing every service.
ListDesiredServicesByProject(ctx context.Context, projectID string) ([]store.DesiredService, error)
// ListDesiredServicesByEnvironment is ListDesiredServicesByProject's
// environment-kind counterpart: environment_clone.go's own clone
// preview/execute handlers use it to find every app tagged with the
// environment being cloned.
ListDesiredServicesByEnvironment(ctx context.Context, environmentID string) ([]store.DesiredService, error)
// RestartService is the only way to force a running container to be
// recreated without an image change: a redeploy of the same image
// tag is otherwise a genuine reconciler no-op (see
// internal/reconcile/application.ContainerName's own doc comment).
// See store.DB.RestartService's own doc comment for why this is
// deliberately excluded from SaveDesiredService's full-record-replace
// semantics, the same reasoning UpdateServiceNode already establishes
// for NodeID.
RestartService(ctx context.Context, name string) error
// UpdateServiceProject is UpdateServiceNode's project-kind
// counterpart (projects.go): same separation-from-ordinary-update
// reasoning, see store.DB.UpdateServiceProject's own doc comment.
UpdateServiceProject(ctx context.Context, name, projectID string) error
// UpdateServiceStorageTarget backs PUT/DELETE
// /api/v1/apps/{name}/storage (apps_storage.go): which store.BackupTarget
// (already-established interface, BackupTargetStore below) this app's
// own object-storage credentials resolve from. Same
// separation-from-ordinary-update reasoning as UpdateServiceNode/
// UpdateServiceProject, see store.DB.UpdateServiceStorageTarget's own
// doc comment.
UpdateServiceStorageTarget(ctx context.Context, name, storageTargetID string) error
// UpdateServiceSuspended backs POST /api/v1/apps/{name}/stop and
// .../start (handleStopApp/handleStartApp): same
// separation-from-ordinary-update reasoning as UpdateServiceNode/
// UpdateServiceProject/UpdateServiceStorageTarget, see
// store.DB.UpdateServiceSuspended's own doc comment.
UpdateServiceSuspended(ctx context.Context, name string, suspended bool) error
// UpdateServiceApp is stage 2 of multi-service apps
// (migrations/0039_apps.sql)'s own service-side setter: which
// store.App a service belongs to. Same separation-from-ordinary-
// update reasoning as UpdateServiceNode/UpdateServiceProject/
// UpdateServiceStorageTarget/UpdateServiceSuspended, see
// store.DB.UpdateServiceApp's own doc comment. Called from
// ensureAppLinked (apps_multi.go), the shared create-or-reuse-and-link
// path both handleCreateApp (an ordinary single-service app) and
// handleDeploySpec (a multi-service fan-out) go through.
UpdateServiceApp(ctx context.Context, name, appID string) error
// UpdateServiceLogDrain backs PUT/DELETE
// /api/v1/apps/{name}/log-drain (apps_log_drain.go): which external
// sink (internal/telemetry.DrainForwarder) this app's container logs
// additionally forward to. Same separation-from-ordinary-update
// reasoning as UpdateServiceStorageTarget, see
// store.DB.UpdateServiceLogDrain's own doc comment.
UpdateServiceLogDrain(ctx context.Context, name string, drain *store.LogDrain) error
// UpdateServiceDatabaseAttachment backs PUT/DELETE
// /api/v1/apps/{name}/database (apps_database.go): which managed
// database (DatabaseStore below) this app resolves one connection env
// var from. Same separation-from-ordinary-update reasoning as
// UpdateServiceStorageTarget, see store.DB.UpdateServiceDatabaseAttachment's
// own doc comment.
UpdateServiceDatabaseAttachment(ctx context.Context, name string, att *store.DatabaseAttachment) error
// SetServiceAutoRollbackOnCrashloop backs PUT
// /api/v1/apps/{name}/auto-rollback (deploys.go): whether
// internal/alerting.MaybeAutoRollback rolls this app back
// automatically the next time a KindCrashloop rule fires for it. Same
// separation-from-ordinary-update reasoning as UpdateServiceStorageTarget,
// see store.DB.SetServiceAutoRollbackOnCrashloop's own doc comment.
SetServiceAutoRollbackOnCrashloop(ctx context.Context, name string, enabled bool) error
// SetServiceAutoRollbackOnSLOBurn backs PUT
// /api/v1/apps/{name}/auto-rollback-slo-burn (deploys.go): which mode
// internal/alerting.MaybeAutoRollbackOnSLOBurn acts in the next time a
// KindSLOBurn rule fires for this app. Same separation-from-ordinary-
// update reasoning as SetServiceAutoRollbackOnCrashloop, see
// store.DB.SetServiceAutoRollbackOnSLOBurn's own doc comment.
SetServiceAutoRollbackOnSLOBurn(ctx context.Context, name, mode string) error
// SetServiceExecEnabled backs PUT /api/v1/apps/{name}/exec-access
// (exec.go): whether POST .../exec and GET .../terminal are even
// attempted for this app, independent of the caller's own IAM
// abilities. Same separation-from-ordinary-update reasoning as
// SetServiceAutoRollbackOnCrashloop, see
// store.DB.SetServiceExecEnabled's own doc comment.
SetServiceExecEnabled(ctx context.Context, name string, enabled bool) error
// SetServiceBadgeEnabled backs PUT /api/v1/apps/{name}/badge
// (app_badge.go): whether GET .../badge.svg serves anything for
// this app, or 404s. Same separation-from-ordinary-update reasoning
// as SetServiceAutoRollbackOnCrashloop, see
// store.DB.SetServiceBadgeEnabled's own doc comment.
SetServiceBadgeEnabled(ctx context.Context, name string, enabled bool) error
// SetServiceVaultEnvVar backs PUT/DELETE
// /api/v1/apps/{name}/vault-env/{key} (apps_vault_env.go): the
// UI/CLI-facing way to declare (or remove) one Vault-sourced env var
// on an app that already exists, without going through the general
// PUT /api/v1/apps/{name}, which would silently drop every other
// declarative field (VaultEnv included) it doesn't itself carry
// forward. Same separation-from-ordinary-update reasoning as
// UpdateServiceDatabaseAttachment, see store.DB.SetServiceVaultEnvVar's
// own doc comment.
SetServiceVaultEnvVar(ctx context.Context, name, envVar string, ref *store.VaultEnvRef) error
// SetServiceDatabaseEnvVar backs POST/DELETE
// /api/v1/apps/{name}/connections[/{env_var}] (apps_connections.go):
// the UI/CLI-facing way to declare (or remove) one entry in an app's
// DatabaseEnv map, letting an app connect to more than one managed
// database without app.yaml. Same separation-from-ordinary-update
// reasoning as SetServiceVaultEnvVar, see
// store.DB.SetServiceDatabaseEnvVar's own doc comment.
SetServiceDatabaseEnvVar(ctx context.Context, name, envVar string, ref *store.DatabaseEnvRef) error
// SetServicePreviewEnvOverride backs PUT/DELETE
// /api/v1/apps/{name}/preview-env/{key} (apps_preview_env.go): the
// UI/CLI-facing way to declare (or remove), on an app that already
// exists, a preview-specific value for one env var that replaces
// whatever this app's own Env/SecretEnv/VaultEnv holds for that key,
// applied only when a preview environment is next created from this
// app (deployPreviewSingle, preview_environments.go), never to this
// app's own deploy. Same separation-from-ordinary-update reasoning as
// SetServiceVaultEnvVar, see store.DB.SetServicePreviewEnvOverride's
// own doc comment.
SetServicePreviewEnvOverride(ctx context.Context, name, envVar string, value *string) error
// UpdateServiceEgressPolicy backs GET/PUT/DELETE
// /api/v1/apps/{name}/egress-policy (apps_egress.go): the UI/CLI-
// facing way to set (or clear) an app's outbound network allowlist
// outside a redeploy, mirroring SetServiceVaultEnvVar's own dual
// write path (app.yaml's egress: block also sets this, via the
// ordinary SaveDesiredService full-record-replace). Same
// separation-from-ordinary-update reasoning as
// UpdateServiceStorageTarget, see
// store.DB.UpdateServiceEgressPolicy's own doc comment.
UpdateServiceEgressPolicy(ctx context.Context, name string, policy *store.ServiceEgressPolicy) error
// UpdateServiceHealth backs PUT /api/v1/apps/{name}/health (apps_health.go).
UpdateServiceHealth(ctx context.Context, name string, health *store.ServiceHealth) error
// UpdateServiceVolumes backs PUT /api/v1/apps/{name}/volumes
// (apps_volumes_attach.go): the UI/CLI-facing way to attach or
// remove a named Docker volume outside a redeploy, mirroring
// UpdateServiceEgressPolicy's own dual write path. See
// store.DB.UpdateServiceVolumes's own doc comment.
UpdateServiceVolumes(ctx context.Context, name string, volumes []store.ServiceVolume) error
// SetServiceBranchEnvOverride, DeleteServiceBranchEnvOverride, and
// ListServiceBranchEnvOverrides back POST/DELETE/GET
// /api/v1/apps/{name}/branch-env (apps_branch_env.go): a narrower,
// branch-pattern-matched sibling of SetServicePreviewEnvOverride
// above, applied only when a preview's own branch matches, see
// store.SetServiceBranchEnvOverride's own doc comment.
SetServiceBranchEnvOverride(ctx context.Context, serviceName, branchPattern, key, value string, secret bool) (string, error)
DeleteServiceBranchEnvOverride(ctx context.Context, serviceName, id string) error
ListServiceBranchEnvOverrides(ctx context.Context, serviceName string) ([]store.ServiceBranchEnvOverride, error)
}
AppStore is the store surface the apps and deploys handlers need. *store.DB satisfies this structurally; tests use a real temp-file store the same way internal/store's own tests do, not a mock.
type AppStreamStore ¶ added in v0.2.0
type AppStreamStore interface {
SaveAppStream(ctx context.Context, s store.AppStream) error
ListAppStreamsForService(ctx context.Context, serviceName string) ([]store.AppStream, error)
ListAllAppStreams(ctx context.Context) ([]store.AppStream, error)
DeleteAppStream(ctx context.Context, id string) error
GetAppStream(ctx context.Context, id string) (store.AppStream, error)
}
AppStreamStore is the store surface the app stream handlers need.
type AppVolumeMoveStore ¶ added in v0.2.0
type AppVolumeMoveStore interface {
StartAppVolumeMove(ctx context.Context, m store.AppVolumeMove) error
UpdateAppVolumeMoveSteps(ctx context.Context, id string, steps []store.AppVolumeMoveStep) error
FinishAppVolumeMove(ctx context.Context, id, status, errMsg, finishedAt string) error
GetAppVolumeMove(ctx context.Context, id string) (store.AppVolumeMove, error)
ListAppVolumeMoves(ctx context.Context, serviceName string) ([]store.AppVolumeMove, error)
}
AppVolumeMoveStore is the store surface handleMoveAppWithVolumes and its history endpoints need: recording a "move with volumes" attempt's steps and final outcome as it happens, so a caller can see exactly how far a partially-failed move got instead of a single black-box result. *store.DB satisfies this structurally.
type ApprovalChatNotifier ¶ added in v0.2.0
type ApprovalChatNotifier interface {
SendApprovalRequest(ctx context.Context, c alerting.NotificationChannel, info alerting.ApprovalRequestInfo) error
}
ApprovalChatNotifier is the surface requestDeployApproval needs to post an interactive Approve/Deny message. *alerting.DeployDispatcher satisfies this structurally, the same "one dispatcher, several narrow interfaces" shape NotificationChannelTester already establishes.
type AuditStore ¶
type AuditStore interface {
SaveAuditEntry(ctx context.Context, e store.AuditEntry) error
ListAuditEntries(ctx context.Context, limit int, before *time.Time, filter store.AuditEntryFilter) ([]store.AuditEntry, error)
DeleteAuditEntriesOlderThan(ctx context.Context, cutoff time.Time) (int64, error)
}
AuditStore is the store surface requireAbility's audit hook (internal/api/auth.go), GET /api/v1/audit-log (audit.go), and the retention sweep/manual purge (audit_retention.go) need: insert-only recording, newest-first cursor-paginated reading, and age-based deletion. Always set, the same "core Store interface, not an optional plug-in" shape certs/staticSites/backupTargets already have.
type AuthLibOAuth ¶ added in v0.2.0
type AuthLibOAuth interface {
OAuthEnabled() bool
Prefix() string
OAuthStart(r *http.Request, provider string) authengine.OAuthOutcome
OAuthCallback(r *http.Request, provider string) authengine.OAuthOutcome
ResolveOAuthUser(ctx context.Context, provider, providerUserID string) (string, error)
LinkOAuthIdentity(ctx context.Context, legacyUserID, provider, providerUserID string) error
InvalidateProvider(name string)
}
AuthLibOAuth is the slice of the library auth engine the OAuth sign-in routes drive.
type AuthStore ¶
type AuthStore interface {
GetUserByEmail(ctx context.Context, email string) (*store.User, error)
GetUserByID(ctx context.Context, id string) (*store.User, error)
CreateUser(ctx context.Context, u store.User) error
UpdateUserPasswordHash(ctx context.Context, id string, hash *string) error
UpdateUserLastLogin(ctx context.Context, id string, when time.Time) error
CountUsers(ctx context.Context) (int, error)
ListUsers(ctx context.Context) ([]store.User, error)
DeleteUser(ctx context.Context, id string) error
UpdateUserAbilities(ctx context.Context, id string, abilities []string) error
UpdateUserDisplayName(ctx context.Context, id, name string) error
}
AuthStore is the store surface the auth handlers need.
type BackupDeleter ¶ added in v0.2.0
BackupDeleter is the surface the backup delete handlers need from internal/backup.DeleteRunner: delete one already-recorded backup attempt, both its stored object (best-effort) and its history row. *backup.DeleteRunner satisfies this structurally; internal/api never imports internal/backup directly, the same boundary BackupRunner's own doc comment describes.
type BackupDownloader ¶
type BackupDownloader interface {
Download(ctx context.Context, historyID string) (io.ReadCloser, error)
}
BackupDownloader is the surface the backup download handler needs from internal/backup.DownloadRunner: resolve one already-succeeded backup attempt's live object into a stream, the read-only counterpart of BackupRunner and RestoreRunner. *backup.DownloadRunner satisfies this structurally; internal/api never imports internal/backup directly, the same boundary BackupRunner's own doc comment describes.
type BackupHistoryStore ¶
type BackupHistoryStore interface {
ListBackupHistory(ctx context.Context, databaseName string, limit int, before *time.Time) ([]store.BackupHistory, error)
ListAllBackupHistory(ctx context.Context, limit int, before *time.Time) ([]store.BackupHistory, error)
GetBackupHistory(ctx context.Context, id string) (store.BackupHistory, error)
}
BackupHistoryStore is the store surface the backup history handler needs. GetBackupHistory was added for handleTriggerRestore (restore.go): resolving the one backup attempt a restore names, not just listing every attempt for a database, the same "look up one row by ID" need GetBackupTarget already serves for backup targets.
type BackupProtection ¶ added in v0.2.0
type BackupProtection interface {
Health(ctx context.Context) ([]backup.ResourceHealth, error)
Encryption() backup.EncryptionStatus
StartDrill(ctx context.Context, backupID string) (string, error)
RefreshProtection(ctx context.Context, targetIDs []string) ([]store.BackupTargetProtection, error)
VolumeExists(ctx context.Context, rtm docker.Runtime, name string) (exists, known bool, err error)
RestoreVolumeTo(ctx context.Context, rtm docker.Runtime, historyID, sourceService, sourceVolume, newVolume, backupID string) error
}
BackupProtection is the surface the backup health, drill and restore-to routes need from internal/backup.Protection.
type BackupProtectionStore ¶ added in v0.2.0
type BackupProtectionStore interface {
ListBackupDrills(ctx context.Context, serviceName, volumeName, databaseName string, limit int) ([]store.BackupDrill, error)
GetBackupDrill(ctx context.Context, id string) (store.BackupDrill, error)
GetVolumeBackupPolicy(ctx context.Context, serviceName, volumeName string) (store.VolumeBackupPolicy, error)
SetVolumeBackupPolicy(ctx context.Context, p store.VolumeBackupPolicy) error
ListBackupTargetProtection(ctx context.Context) ([]store.BackupTargetProtection, error)
}
BackupProtectionStore is the store surface the same routes read and write.
type BackupRunner ¶
type BackupRunner interface {
RunBackup(ctx context.Context, historyID, databaseName, engine, containerName, targetID string) error
}
BackupRunner is the surface the backup trigger handler needs from internal/backup.Runner: run one backup attempt end to end, from an already-minted history ID through to a finished store.BackupHistory row. *backup.Runner satisfies this structurally; internal/api never imports internal/backup directly (the same reconciler-internals boundary databaseContainerName's own doc comment describes), only this narrow interface, wired in by cmd/levelrail at startup.
type BackupSecretsSetter ¶
type BackupSecretsSetter interface {
SetValue(ctx context.Context, serviceName, envKey, plaintext string) error
}
BackupSecretsSetter is the surface backup target creation needs from internal/secrets.Manager: store a credential value, the same "set a value, never read one back through this interface" shape SecretSetter already establishes for app secrets. A distinct type from SecretSetter even though both are structurally satisfied by *secrets.Manager, because a backup target's credentials do get resolved back out server-side, just not through this interface or this package: that's internal/backup.Runner's own, separate, narrower internal/backup.SecretsResolver, wired directly in cmd/levelrail, not through the Router at all.
type BackupTargetStore ¶
type BackupTargetStore interface {
SaveBackupTarget(ctx context.Context, t store.BackupTarget) error
GetBackupTarget(ctx context.Context, id string) (store.BackupTarget, error)
ListBackupTargets(ctx context.Context) ([]store.BackupTarget, error)
UpdateBackupTarget(ctx context.Context, id, name, provider, endpoint, region, bucket string) error
DeleteBackupTarget(ctx context.Context, id string) error
}
BackupTargetStore is the store surface the backup target handlers need.
type BackupTargetTester ¶
BackupTargetTester is the surface the test-connection handler needs from internal/backup.TargetTester: probe one target's configured bucket over its stored credentials, without uploading or deleting anything. *backup.TargetTester satisfies this structurally; internal/api never resolves a backup target's credentials directly, the same boundary BackupSecretsSetter's own doc comment describes.
type BackupVerificationStore ¶
type BackupVerificationStore interface {
ListBackupVerifications(ctx context.Context, backupHistoryID string, limit int) ([]store.BackupVerification, error)
}
BackupVerificationStore is the store surface the backup verification handlers need: listing past verification attempts for one backup, the same "core Store interface, no runner configuration needed" shape BackupHistoryStore's own doc comment establishes for backup history itself.
type BackupVerifier ¶
type BackupVerifier interface {
VerifyBackup(ctx context.Context, verificationID, backupHistoryID, engine, checkedBy string) error
}
BackupVerifier is the surface the verify-trigger handler needs from internal/backup.VerifyRunner: run one verification attempt end to end, from an already-minted verification ID through to a finished store.BackupVerification row. *backup.VerifyRunner satisfies this structurally; internal/api never imports internal/backup directly, the same boundary BackupRunner's own doc comment describes.
type BaseBackupHistoryStore ¶ added in v0.2.0
type BaseBackupHistoryStore interface {
ListBaseBackupHistory(ctx context.Context, databaseName string) ([]store.BaseBackupHistory, error)
}
BaseBackupHistoryStore is the store surface the base backup handlers need.
type BaseBackupRunner ¶ added in v0.2.0
type BaseBackupRunner interface {
RunBaseBackup(ctx context.Context, historyID, databaseName, containerName, targetID string) error
}
BaseBackupRunner is the surface the base backup trigger handler needs from internal/backup.BaseBackupRunner: run one physical base backup attempt end to end. *backup.BaseBackupRunner satisfies this structurally; internal/api never imports internal/backup directly (databaseContainerName's own doc comment describes this boundary), only this narrow interface, wired in by cmd/levelrail at startup.
type BetaFeatureStore ¶ added in v0.2.0
BetaFeatureStore persists the Settings switches for beta features.
type BitbucketAppClient ¶
type BitbucketAppClient interface {
ExchangeCode(ctx context.Context, key, secret, code string) (bitbucketapp.Tokens, error)
RefreshToken(ctx context.Context, key, secret, refreshToken string) (bitbucketapp.Tokens, error)
ListRepos(ctx context.Context, accessToken string) ([]bitbucketapp.Repo, error)
GetRepo(ctx context.Context, accessToken, fullName string) (bitbucketapp.Repo, error)
ListBranches(ctx context.Context, accessToken, fullName string) ([]bitbucketapp.Branch, error)
CreateRepoWebhook(ctx context.Context, accessToken, fullName, hookURL, secret string) error
CreatePullRequestComment(ctx context.Context, accessToken, fullName string, prID int, body string) (int64, error)
ListPullRequestComments(ctx context.Context, accessToken, fullName string, prID int) ([]gitprovider.Comment, error)
UpdatePullRequestComment(ctx context.Context, accessToken, fullName string, prID int, commentID int64, body string) error
CreateCommitBuildStatus(ctx context.Context, accessToken, fullName, commit string, state bitbucketapp.BuildStatusState, targetURL, description, key string) error
}
BitbucketAppClient is the surface internal/api needs from internal/bitbucketapp.Client: OAuth code exchange/refresh, and repo listing/lookup/webhook registration once connected. *bitbucketapp.Client satisfies this structurally; tests substitute a hand-written fake.
type BitbucketAppSecrets ¶
type BitbucketAppSecrets interface {
SetValue(ctx context.Context, serviceName, envKey, plaintext string) error
Resolve(ctx context.Context, serviceName, envKey string) (string, error)
Exists(ctx context.Context, serviceName, envKey string) (bool, error)
DeleteAll(ctx context.Context, serviceName string) error
}
BitbucketAppSecrets is the surface the Bitbucket App handlers need from internal/secrets.Manager, the same "writes and reads back through internal/secrets" shape GitLabAppSecrets's own doc comment describes: the consumer's own secret is set once at connect time, access_token/refresh_token/token_expires_at are written and re-read on the same schedule by bitbucketAccessToken.
type BitbucketAppStore ¶
type BitbucketAppStore interface {
GetBitbucketAppConnection(ctx context.Context) (store.BitbucketAppConnection, error)
SaveBitbucketAppConnection(ctx context.Context, c store.BitbucketAppConnection) error
DeleteBitbucketAppConnection(ctx context.Context) error
}
BitbucketAppStore is the store surface the Bitbucket App connection handlers need. *store.DB satisfies this structurally, the same "core store" shape GitHubAppStore/GitLabAppStore's own doc comments establish.
type BuildCacheService ¶ added in v0.2.0
type BuildCacheService interface {
KeyPrefix(app string) (string, error)
Stats(ctx context.Context, app string) (objectstore.CacheStats, error)
Clear(ctx context.Context, app string) (objectstore.ClearResult, error)
}
BuildCacheService runs bucket-side cache hygiene.
type BuildCacheSettingsStore ¶ added in v0.2.0
type BuildCacheSettingsStore interface {
UpsertBuildCacheSetting(ctx context.Context, s store.BuildCacheSetting) error
GetBuildCacheSetting(ctx context.Context, appName string) (store.BuildCacheSetting, error)
ListBuildCacheSettings(ctx context.Context) ([]store.BuildCacheSetting, error)
DeleteBuildCacheSetting(ctx context.Context, appName string) error
}
BuildCacheSettingsStore persists build cache settings.
type Builder ¶
type Builder interface {
Deploy(ctx context.Context, req deploy.Request, progress func(build.ProgressEvent)) (string, error)
// DeploySpec is handleDeploySpec's (apps_multi.go) own narrow need:
// the multi-service fan-out entry point. Same *deploy.Pipeline
// satisfies both methods, so this stays one interface rather than a
// second router field, the same "one concrete type, one interface"
// shape every other narrow store/builder interface in this codebase
// already follows.
DeploySpec(ctx context.Context, req deploy.MultiRequest, progress func(serviceKey string, ev build.ProgressEvent)) ([]deploy.ServiceOutcome, error)
}
Builder is the surface the manual build trigger handler (handleTriggerBuild) needs from internal/deploy.Pipeline, the exact same narrow-interface shape internal/webhook.Deployer already establishes for the identical method, so both call sites can be satisfied by the one real *deploy.Pipeline cmd/levelrail/main.go builds. *deploy.Pipeline satisfies this structurally.
type CanaryStore ¶ added in v0.2.0
type CanaryStore interface {
SetCanaryRelease(ctx context.Context, c store.CanaryRelease) error
GetCanaryRelease(ctx context.Context, serviceName string) (store.CanaryRelease, bool, error)
DeleteCanaryRelease(ctx context.Context, serviceName string) error
ListCanaryReleases(ctx context.Context) ([]store.CanaryRelease, error)
}
CanaryStore is the store surface the canary routes need.
type CertObservationSource ¶ added in v0.2.0
type CertObservationSource interface {
ListAllCertExpiryObservations(ctx context.Context) ([]alerting.CertExpiryObservation, error)
}
CertObservationSource lists the expiry observations kind=cert_expiry rules record; *alerting.DB satisfies it.
type CertStore ¶
type CertStore interface {
ListCertStorageKeys(ctx context.Context, prefix string, recursive bool) ([]string, error)
GetCertStorageValue(ctx context.Context, key string) (*store.CertStorageValue, error)
DeleteCertStorageValue(ctx context.Context, key string) error
}
CertStore is the store surface handleListCertificates and handleRenewDomainCertificate need: the two read methods internal/ingress.SQLiteStorage also uses, plus the delete method renew needs to clear a domain's stored certificate. *store.DB satisfies this structurally, same as every other Store sub-interface in this package.
type CloneRestoreHistoryStore ¶
type CloneRestoreHistoryStore interface {
ListCloneRestores(ctx context.Context, sourceDatabaseName string) ([]store.CloneRestore, error)
}
CloneRestoreHistoryStore is the store surface the clone-restore history handler needs, the "restore as new database" counterpart to RestoreHistoryStore (restore.go).
type CloneRestoreRunner ¶
type CloneRestoreRunner interface {
RunCloneRestore(ctx context.Context, historyID, sourceDatabaseName, newDatabaseName, backupHistoryID, engine, containerName, controllerName string) error
}
CloneRestoreRunner is the surface the clone-restore trigger handler needs from internal/backup.CloneRestoreRunner: wait for a newly created database to come up and restore a backup into it, from an already-minted history ID through to a finished store.CloneRestore row. *backup.CloneRestoreRunner satisfies this structurally; internal/api never imports internal/backup directly, the same boundary RestoreRunner's own doc comment describes.
type CloudflareDNSSecrets ¶
type CloudflareDNSSecrets interface {
SetValue(ctx context.Context, serviceName, envKey, plaintext string) error
Exists(ctx context.Context, serviceName, envKey string) (bool, error)
DeleteAll(ctx context.Context, serviceName string) error
}
CloudflareDNSSecrets is the surface the Cloudflare DNS-01 settings handlers need from internal/secrets.Manager, the same shape CloudflareTunnelSecrets already establishes for a distinct credential (a scoped Cloudflare API token, not the cloudflared connector token).
type CloudflareDNSStore ¶
type CloudflareDNSStore interface {
GetCloudflareDNSSettings(ctx context.Context) (store.CloudflareDNSSettings, error)
UpdateCloudflareDNSSettings(ctx context.Context, s store.CloudflareDNSSettings) error
}
CloudflareDNSStore is the store surface GET/PUT /api/v1/settings/cloudflare-dns need, the same "single platform-wide row" shape CloudflareTunnelStore already establishes.
type CloudflareDNSTokenResolver ¶ added in v0.2.0
type CloudflareDNSTokenResolver interface {
Resolve(ctx context.Context, serviceName, envKey string) (string, error)
}
CloudflareDNSTokenResolver is the narrow surface GET/POST/PUT/DELETE .../dns-records need from internal/secrets.Manager to read back the plaintext Cloudflare DNS-01 token this control plane already stores: CloudflareDNSSecrets (cloudflare_dns.go) only checks presence, it never reads the value back, since the settings resource never needs to. *secrets.Manager satisfies this structurally, the same shape internal/reconcile/ingress's own identically-named interface already establishes for the same credential.
type CloudflareTunnelSecrets ¶
type CloudflareTunnelSecrets interface {
SetValue(ctx context.Context, serviceName, envKey, plaintext string) error
Exists(ctx context.Context, serviceName, envKey string) (bool, error)
DeleteAll(ctx context.Context, serviceName string) error
}
CloudflareTunnelSecrets is the surface the Cloudflare Tunnel settings handlers need from internal/secrets.Manager: set the token (PUT), check whether one exists (GET's has_token, and PUT's "was a token already set" check for the omitted-token case), and clear it (DELETE). *secrets.Manager satisfies this structurally, the same "narrow, consumer-defined interface" shape GitHubAppSecrets already establishes.
type CloudflareTunnelStore ¶
type CloudflareTunnelStore interface {
GetCloudflareTunnelSettings(ctx context.Context) (store.CloudflareTunnelSettings, error)
UpdateCloudflareTunnelSettings(ctx context.Context, s store.CloudflareTunnelSettings) error
}
CloudflareTunnelStore is the store surface GET/PUT/DELETE /api/v1/settings/cloudflare-tunnel need: the single platform-wide row, always present, the same shape EmailSettingsStore has for its own row.
type ComposeRevisionStore ¶ added in v0.2.0
type ComposeRevisionStore interface {
AddComposeRevision(ctx context.Context, rev store.ComposeRevision) (int, error)
ListComposeRevisions(ctx context.Context, appID string, limit int) ([]store.ComposeRevision, error)
GetComposeRevision(ctx context.Context, appID string, revision int) (store.ComposeRevision, error)
ListComposeApps(ctx context.Context) ([]string, error)
DeleteComposeRevisions(ctx context.Context, appID string) error
}
ComposeRevisionStore is the store surface compose stacks need for history and rollback.
type ComposeSecretStore ¶
type ComposeSecretStore interface {
Resolve(ctx context.Context, serviceName, envKey string) (string, error)
SetValue(ctx context.Context, serviceName, envKey, plaintext string) error
}
ComposeSecretStore is the surface POST /api/v1/apps/{name}/compose needs to resolve a compose file's SERVICE_ magic vars (compose.ResolveMagicVars): a canonical generate-once-per-app value (Resolve/SetValue keyed by the app's own name, a synthetic bucket distinct from any real service), plus one SetValue per real service that references it, since internal/secrets.Manager itself is keyed per real service, not per app.
type ContainerLister ¶
type ContainerLister interface {
ListByPrefix(ctx context.Context, prefix string) ([]docker.ContainerState, error)
}
ContainerLister is the surface GET /api/v1/system/containers needs: every container on this node, Levelrail-managed or not, the same "structurally satisfied by *docker.Client, no second divergent surface" reasoning ImageLister above already documents. An empty prefix argument matches every container name (docker.Client's own ListByPrefix implementation), which is exactly this route's point: unlike every other Runtime-backed feature in this codebase, which scopes to one app/database's own containers, this one deliberately wants everything.
type ControlPlaneBackupManager ¶ added in v0.2.0
type ControlPlaneBackupManager interface {
Create(ctx context.Context) (cpbackup.Info, error)
List() ([]cpbackup.Info, error)
Open(name string) (*os.File, cpbackup.Info, error)
Delete(name string) error
Verify(ctx context.Context, name string) (cpbackup.VerifyResult, error)
}
ControlPlaneBackupManager is the surface the /system/backups routes need.
type ControlPlaneDR ¶ added in v0.2.0
type ControlPlaneDR interface {
Status(ctx context.Context) (cpbackup.Status, error)
UpdateConfig(ctx context.Context, u cpbackup.ConfigUpdate) error
ListRemote(ctx context.Context) ([]cpbackup.Remote, error)
StartBackup() error
StartDrill() error
BuildEscrow(ctx context.Context, in cpbackup.EscrowInput) (cpbackup.EscrowBundle, error)
AckEscrow(ctx context.Context) error
}
ControlPlaneDR is the surface the /system/control-plane-dr routes need.
type CustomTemplateStore ¶ added in v0.2.0
type CustomTemplateStore interface {
SaveCustomTemplate(ctx context.Context, t store.CustomTemplate) error
GetCustomTemplate(ctx context.Context, id string) (store.CustomTemplate, error)
ListCustomTemplates(ctx context.Context) ([]store.CustomTemplate, error)
DeleteCustomTemplate(ctx context.Context, id string) error
}
CustomTemplateStore is the store surface save-as-template needs (service_templates_custom.go): CRUD on operator-defined templates, the growth-loop counterpart to internal/catalog's static built-in catalog. See store.CustomTemplate's own doc comment for why a template row never holds a real secret value.
type DBPinger ¶
DBPinger is the surface GET /api/v1/system/doctor needs to report the control plane's own SQLite reachability, the same narrow, single-purpose shape DockerPinger above already establishes. *store.DB satisfies this structurally via its embedded *sql.DB's PingContext method.
type DataExportService ¶ added in v0.2.0
type DataExportService interface {
List(ctx context.Context) ([]store.ExportDestination, error)
Get(ctx context.Context, id string) (store.ExportDestination, error)
Create(ctx context.Context, in dataexport.Input) (store.ExportDestination, error)
Update(ctx context.Context, id string, p dataexport.Patch) (store.ExportDestination, error)
Delete(ctx context.Context, id string) error
Test(ctx context.Context, id string) error
Status(ctx context.Context, id string) (store.ExportStatus, error)
Series(ctx context.Context, allow dataexport.ResourceFilter) ([]dataexport.Series, error)
StreamAudit(ctx context.Context, from, to time.Time, fn func(dataexport.AuditRecord) error) error
}
DataExportService is the surface the export routes need from internal/dataexport; *dataexport.Service satisfies it.
type DataImportStore ¶ added in v0.2.0
type DataImportStore interface {
ClaimDatabaseDataImport(ctx context.Context, name, host string, port int, srcDB string, now time.Time, staleAfter time.Duration) error
FinishDatabaseDataImport(ctx context.Context, name, status, reason string, checked, mismatched int, detail string, now time.Time) error
GetDatabaseDataImport(ctx context.Context, name string) (store.DatabaseDataImport, bool, error)
ListDatabaseDataImports(ctx context.Context) ([]store.DatabaseDataImport, error)
}
DataImportStore is the store surface the live data copy routes need.
type DatabaseAccessStore ¶ added in v0.2.0
type DatabaseAccessStore interface {
RecordDatabaseAccessUser(ctx context.Context, u store.DatabaseAccessUser) error
ListDatabaseAccessUsers(ctx context.Context, database, kind string) ([]store.DatabaseAccessUser, error)
GetDatabaseAccessUser(ctx context.Context, database, role string) (*store.DatabaseAccessUser, error)
GetDatabaseAccessUserByID(ctx context.Context, id string) (*store.DatabaseAccessUser, error)
MarkDatabaseAccessUserRevoked(ctx context.Context, database, role string, now time.Time) error
GetDatabaseAccessSettings(ctx context.Context, database string) (store.DatabaseAccessSettings, error)
SaveDatabaseAccessSettings(ctx context.Context, s store.DatabaseAccessSettings) error
ListDatabaseNetworkRuleNotes(ctx context.Context, database string) (map[string]string, error)
ReplaceDatabaseNetworkRuleNotes(ctx context.Context, database string, notes map[string]string) error
EnvironmentOfDatabase(ctx context.Context, databaseName string) (*store.EnvironmentRef, error)
EnvironmentOfApp(ctx context.Context, appName string) (*store.EnvironmentRef, error)
}
DatabaseAccessStore is the persistence the database access, network and temporary credential handlers need. *store.DB satisfies it.
type DatabaseQueryStore ¶ added in v0.2.0
type DatabaseQueryStore interface {
AddDatabaseQueryHistory(ctx context.Context, h store.DatabaseQueryHistory, keep int) (store.DatabaseQueryHistory, error)
ListDatabaseQueryHistory(ctx context.Context, database, principalType, principalID string, limit int) ([]store.DatabaseQueryHistory, error)
ClearDatabaseQueryHistory(ctx context.Context, database, principalType, principalID string) error
SaveDatabaseQuery(ctx context.Context, q store.DatabaseSavedQuery) (store.DatabaseSavedQuery, error)
ListDatabaseSavedQueries(ctx context.Context, database, principalType, principalID string) ([]store.DatabaseSavedQuery, error)
DeleteDatabaseSavedQuery(ctx context.Context, database, principalType, principalID, id string) error
}
DatabaseQueryStore is the store surface the console's history and saved query routes need.
type DatabaseStore ¶
type DatabaseStore interface {
SaveDesiredDatabase(ctx context.Context, d store.DesiredDatabase) error
GetDesiredDatabase(ctx context.Context, name string) (*store.DesiredDatabase, error)
ListDesiredDatabases(ctx context.Context) ([]store.DesiredDatabase, error)
DeleteDesiredDatabase(ctx context.Context, name string) error
// UpdateDatabaseNode is AppStore.UpdateServiceNode's counterpart,
// same separation-from-ordinary-update reasoning. Originally added
// unexposed by 3.3; handleDrainNode is the first caller with an
// actual route to reuse it through.
UpdateDatabaseNode(ctx context.Context, name, nodeID string) error
// ListDesiredDatabasesByNode is the database-kind counterpart to
// AppStore.ListDesiredServicesByNode.
ListDesiredDatabasesByNode(ctx context.Context, nodeID string) ([]store.DesiredDatabase, error)
// ListDesiredDatabasesByProject is the database-kind counterpart to
// AppStore.ListDesiredServicesByProject.
ListDesiredDatabasesByProject(ctx context.Context, projectID string) ([]store.DesiredDatabase, error)
// UpdateDatabaseSuspended is AppStore.UpdateServiceSuspended's
// counterpart, backing POST /api/v1/projects/{id}/stop and .../start
// (project_stop_start.go) and POST /api/v1/databases/{name}/stop and
// .../start (database_stop_start.go): same separation-from-ordinary-
// update reasoning as UpdateDatabaseNode/UpdateDatabaseProject, see
// store.DB.UpdateDatabaseSuspended's own doc comment.
UpdateDatabaseSuspended(ctx context.Context, name string, suspended bool) error
// UpdateDatabaseProject is AppStore.UpdateServiceProject's
// counterpart (projects.go).
UpdateDatabaseProject(ctx context.Context, name, projectID string) error
// SetDatabaseBackupSchedule backs
// PUT/DELETE /api/v1/databases/{name}/backup-schedule (backups.go):
// wave-2 roadmap item 6, scheduled backups. Same "own endpoint, own
// store method" separation UpdateDatabaseNode/UpdateDatabaseProject
// already establish for their own single-purpose updates.
SetDatabaseBackupSchedule(ctx context.Context, name, targetID, schedule string, retain, retainDays int) error
// SetDatabasePITR backs POST/DELETE /api/v1/databases/{name}/pitr
// (pitr.go): same "own endpoint, own store method" separation
// SetDatabaseBackupSchedule above establishes.
SetDatabasePITR(ctx context.Context, name string, enabled bool, enabledAt string) error
// SetDatabasePublicAccess backs
// PUT/DELETE /api/v1/databases/{name}/public-access
// (database_public_access.go): the same "own endpoint, own store
// method" separation SetDatabaseBackupSchedule already establishes,
// applied to whether this database's container port is bound to a
// host port. requestedBindAddress empty resolves to
// store.DefaultBindAddress; ignored when enabled is false. Returns
// the port actually assigned (0 when disabling).
SetDatabasePublicAccess(ctx context.Context, name string, enabled bool, requestedPort int, requestedBindAddress string) (int, error)
}
DatabaseStore is the store surface the databases handlers need, the database-kind counterpart to AppStore.
type DatabaseUpgrader ¶ added in v0.2.0
type DatabaseUpgrader interface {
Overview(ctx context.Context, name string) (dbupgrade.Overview, error)
EffectivePolicy(ctx context.Context, name string) (dbupgrade.Policy, bool, error)
SetPolicy(ctx context.Context, name string, p dbupgrade.Policy, inherit bool, by string) error
UpgradeNow(ctx context.Context, name, version, by string) (store.DBUpgradeRun, error)
Summary(ctx context.Context, visible func(string) bool) ([]dbupgrade.SummaryItem, error)
}
DatabaseUpgrader is the upgrade advisor, policy store and runner (internal/dbupgrade.Manager).
type DatabaseVersionCatalog ¶
type DatabaseVersionCatalog interface {
Engines() []string
Versions(engine string) (dbupgrade.VersionsView, error)
LiveRefresh(ctx context.Context, engine string) (dbupgrade.VersionsView, bool, error)
Status() dbupgrade.Status
Refresh(ctx context.Context) error
SetRemoteEnabled(enabled bool) error
}
DatabaseVersionCatalog is the remote-refreshed version catalog (internal/dbupgrade.RemoteCatalog).
type DemoConfig ¶
type DemoConfig struct {
// VisitorUserID is the seeded read-only account sessions are minted for.
VisitorUserID string
Username string
Password string
// Verifier is optional; nil means no human check is enforced.
Verifier HumanVerifier
// SessionsPerMinute caps session mints per client IP; zero uses the default.
SessionsPerMinute int
ResetsAt func() time.Time
InstallCommand string
RepoURL string
DocsURL string
Version string
}
DemoConfig turns the Router into the read-only public demo. It is only ever built by the demo entrypoint, never from the ordinary process wiring.
type DemoStats ¶
type DemoStats struct {
SessionsMinted int `json:"sessions_minted"`
CTAClicks map[string]int `json:"cta_clicks"`
}
DemoStats is the aggregate, PII-free counter snapshot the demo host flushes.
type DeployApprovalStore ¶ added in v0.2.0
type DeployApprovalStore interface {
SaveDeployApproval(ctx context.Context, a store.DeployApproval) error
GetDeployApproval(ctx context.Context, id string) (store.DeployApproval, error)
ListDeployApprovals(ctx context.Context, status, serviceName string) ([]store.DeployApproval, error)
DecideDeployApproval(ctx context.Context, id, newStatus, approvedByType, approvedBy, approvedByName, reason, decidedAt string) (bool, error)
}
DeployApprovalStore is the surface deploy_approvals.go needs: create a pending approval gate for a deploy/promote into a protected environment, list/get it, and record a terminal decision (approve, reject, or expire). Always set, the same "core Store interface, not an optional plug-in" shape HookRunStore above establishes.
type DeployAttemptStore ¶
type DeployAttemptStore interface {
SaveDeployAttempt(ctx context.Context, a store.DeployAttempt) error
SetDeployAttemptCommit(ctx context.Context, id, image, commitSHA string) error
FinishDeployAttempt(ctx context.Context, id, status string, finishedAt time.Time, errMsg string) error
GetDeployAttempt(ctx context.Context, id string) (*store.DeployAttempt, error)
ListDeployAttempts(ctx context.Context, serviceName string) ([]store.DeployAttempt, error)
ListFailedDeploysSince(ctx context.Context, since time.Time) ([]store.FailedDeploy, error)
}
DeployAttemptStore is the store surface real deploy-attempt history needs: row-per-attempt CRUD, layered alongside DeployStore above rather than replacing it. See handleDeployHistory's own doc comment for why GET /api/v1/apps/{name}/deploys keeps returning reconcile conditions unchanged (an existing, real frontend consumer, web/src/queries/deploys.ts's useDeployStatus, already depends on that shape) while this interface backs a new, additional endpoint, GET /api/v1/apps/{name}/deploy-attempts, instead of overloading the old one. *store.DB satisfies this structurally.
type DeployExitStore ¶
type DeployExitStore interface {
GetDeployExit(ctx context.Context, serviceName, attemptID string) (*store.DeployExit, error)
LatestDeployExit(ctx context.Context, serviceName string) (*store.DeployExit, error)
}
DeployExitStore reads the exits the application controller captured. *store.DB satisfies it.
type DeployGateStore ¶ added in v0.2.0
type DeployGateStore interface {
ListGateEvents(ctx context.Context, attemptID string) ([]store.DeployGateEvent, error)
GetDeploySafetySettings(ctx context.Context, serviceName string) (store.DeploySafetySettings, error)
SaveDeploySafetySettings(ctx context.Context, s store.DeploySafetySettings) error
ListRollbackPins(ctx context.Context, serviceName string) ([]store.RollbackPin, error)
GetRollbackPin(ctx context.Context, serviceName, attemptID string) (*store.RollbackPin, error)
}
DeployGateStore is the store surface behind the readiness gate timeline, per-app gate settings and rollback pins. *store.DB satisfies it.
type DeployLogQuerier ¶
type DeployLogQuerier interface {
QueryDeployLog(ctx context.Context, attemptID string) ([]telemetry.DeployLogEntry, error)
}
DeployLogQuerier is the telemetry-side read surface handleDeployLogStream needs to serve a full replay once an attempt has already finished (see that handler's own doc comment for the in-progress-vs-finished split). *telemetry.DB satisfies this structurally. Optional (nil is valid, the same "not configured" shape WithTelemetryQuerier's own absence already has): without one, a finished attempt's log route returns 501; an in-progress attempt's live tail (backed by deployRecorder below, a separate optional field) is unaffected by this one being unset.
type DeployNotifier ¶
type DeployNotifier interface {
Dispatch(ctx context.Context, resourceID string, ev alerting.DeployOutcome)
}
DeployNotifier is the narrow surface recordPlainDeployAttempt (deploys.go) and beginBuildDeployAttempt (deploy_attempts.go) need to fire a deploy-outcome notification once a deploy attempt reaches a terminal state. *alerting.DeployDispatcher satisfies this structurally. resourceID is resourceIDForApp(ev.AppName), computed by the caller (see alerting.DeployDispatcher.Dispatch's own doc comment for why it takes resourceID as a parameter rather than importing resourceIDForApp itself).
type DeployNotifyTargets ¶
type DeployNotifyTargets interface {
SaveDeployTarget(ctx context.Context, t alerting.DeployTarget) error
GetDeployTarget(ctx context.Context, id string) (*alerting.DeployTarget, error)
ListDeployTargetsForResource(ctx context.Context, resourceID string) ([]alerting.DeployTarget, error)
DeleteDeployTarget(ctx context.Context, id string) error
}
DeployNotifyTargets is the surface the deploy-notify-target handlers need from internal/alerting.DB. *alerting.DB satisfies this structurally, the same convention AlertRules already establishes.
type DeployQueueStore ¶ added in v0.2.0
type DeployQueueStore interface {
ListQueuedDeployAttempts(ctx context.Context) ([]store.DeployAttempt, error)
ListRunningDeployAttempts(ctx context.Context) ([]store.DeployAttempt, error)
StartQueuedDeployAttempt(ctx context.Context, id string, now time.Time) (bool, error)
FinishRunningDeployAttempt(ctx context.Context, id, status string, finishedAt time.Time, errMsg string) (bool, error)
CancelDeployAttempt(ctx context.Context, id, from, by string, now time.Time) (bool, error)
SupersedeQueuedDeployAttempt(ctx context.Context, id, by string, now time.Time) (bool, error)
GetServiceCancelSuperseded(ctx context.Context, name string) (bool, error)
SetServiceCancelSuperseded(ctx context.Context, name string, enabled bool) error
}
DeployQueueStore is the store surface for queued and canceled deploys. *store.DB satisfies this structurally.
type DeploySafetyStore ¶ added in v0.2.0
type DeploySafetyStore interface {
deploy.OrderedStore
deploy.Sequencer
deploy.FreezeStore
deploy.HeldStore
ReplaceDeployFreezeWindows(ctx context.Context, scope string, windows []store.DeployFreezeWindow) ([]store.DeployFreezeWindow, error)
SetDeployAttemptReason(ctx context.Context, id, reason string) error
DeployQueueStore
}
DeploySafetyStore is the store surface for deploy ordering, freeze windows and digest history. *store.DB satisfies this structurally.
type DeployStore ¶
type DeployStore interface {
GetConditions(ctx context.Context, controllerName string) ([]reconcile.Condition, error)
// GetConditionsForControllers is handleListApps' batched status
// source (apps.go): one query for every app's application
// controller, not a GetConditions call per app.
GetConditionsForControllers(ctx context.Context, controllerNames []string) (map[string][]reconcile.Condition, error)
}
DeployStore is the store surface the deploy-history handler needs.
type DevFixtureToken ¶
type DevFixtureToken struct {
Name string `yaml:"name"`
Plaintext string `yaml:"plaintext"`
Abilities []string `yaml:"abilities"`
}
DevFixtureToken is one entry in a dev-fixtures.yml file: a fixed plaintext API token, minted with a known ability set, so local testing of the auth flow (does a read-only token get 403'd on a write route, does a write:sensitive token reach the secrets handler, and so on) doesn't require registering, logging in, and minting a real token by hand every time. Only ever seeded under dev mode, see devmode_debug.go/devmode_release.go's devModeEnabled gate.
type DevFixtures ¶
type DevFixtures struct {
Tokens []DevFixtureToken `yaml:"tokens"`
}
DevFixtures is the top-level shape of dev-fixtures.yml.
func ParseDevFixtures ¶
func ParseDevFixtures(data []byte) (*DevFixtures, error)
ParseDevFixtures validates as much as validateAbilities already validates a real token mint request: an empty or unrecognized ability list is rejected here too, so a typo in dev-fixtures.yml fails loudly at startup instead of silently minting a token nobody can use as intended.
type DeviceLoginNotifier ¶ added in v0.2.0
type DeviceLoginNotifier interface {
SendNotice(ctx context.Context, c alerting.NotificationChannel, text string) error
}
DeviceLoginNotifier sends one plain-text notice through a channel. *alerting.DeployDispatcher satisfies it.
type DockerDiskUsager ¶
DockerDiskUsager is the surface GET /api/v1/system/status needs for Docker's own storage accounting (images/containers/volumes/build cache), a materially different number from DataDirTotalBytes/ DataDirFreeBytes above: see docker.DiskUsage's own doc comment for why. Narrow and single-purpose like DockerPinger, not docker.Runtime, same "adding to Runtime would ripple into 6+ fakes for one read-only signal" reasoning DockerPinger's own doc comment gives. *docker.Client satisfies this structurally via the DiskUsage method added directly to that concrete type (internal/docker/prune.go).
type DockerGuardController ¶ added in v0.2.0
type DockerGuardController interface {
Status() dockerguard.Status
SetMode(mode dockerguard.Mode, actor string, now time.Time) (dockerguard.Status, error)
}
DockerGuardController is the Docker API guard as the API sees it; *dockerguard.Controller satisfies it.
type DockerHubClient ¶ added in v0.2.0
type DockerHubClient interface {
SearchRepositories(ctx context.Context, query string, pageSize int) ([]dockerhub.Repository, error)
ListTags(ctx context.Context, namespace, repository string, pageSize int) ([]dockerhub.Tag, error)
}
DockerHubClient is the surface GET /api/v1/dockerhub/search and GET /api/v1/dockerhub/repositories/{namespace}/{repo}/tags need: query Docker Hub's public, unauthenticated Hub API for repository search and tag listing. *dockerhub.Client satisfies this structurally.
type DockerPinger ¶
DockerPinger is the surface GET /api/v1/system/status needs to report Docker daemon connectivity: a liveness check, nothing else. *docker.Client satisfies this structurally via the Ping method added directly to that concrete type (internal/docker/client.go), not through docker.Runtime: Runtime has 6+ fake implementations across internal/reconcile's controllers and internal/agent's test files, plus the real client and the agent-side remote transport, so adding a method there for the sake of this one read-only health signal would ripple into all of them. This narrow interface is the actual consumer-defined boundary instead, the same shape SecretSetter and TelemetryQuerier already establish for their own single-purpose surfaces.
type DockerPruner ¶
type DockerPruner interface {
Prune(ctx context.Context, keep []string) docker.PruneResult
}
DockerPruner is the surface POST /api/v1/system/prune needs: run every cleanup stage internal/docker/prune.go supports and report what happened. Unlike DockerDiskUsager (a read), this is a destructive-ish action, gated at AbilityRoot the same way handleDrainNode is (see router.go's own route registration), so it gets its own interface rather than being folded into DockerDiskUsager: a read and a destructive action deserve independently swappable seams, the same split Builder/ImageLister already have. *docker.Client satisfies this structurally via the Prune method (internal/docker/prune.go).
type DoctorIngressEdge ¶ added in v0.2.0
type DoctorIngressEdge struct {
SocketActivation bool
Hardening bool
TrustedProxies int
MaxBodyBytes int64
RetryWindow time.Duration
}
DoctorIngressEdge is the ingress edge policy GET /api/v1/system/doctor reports.
type Document ¶
type Document struct {
Statement []Statement `json:"Statement"`
}
Document is the whole parsed policy body stored as JSON in store.Policy.Document.
func ParseDocument ¶
ParseDocument unmarshals and validates a policy document. A document must have at least one statement, every statement must have an Effect of Allow or Deny, at least one Action (each either "*" or a known ability string from validAbilities), and at least one Resource (each either "*" or a non-empty resource identifier).
type DomainAuthGateStore ¶ added in v0.2.0
type DomainAuthGateStore interface {
GetDomainAuthGate(ctx context.Context, domain string) (store.DomainAuthGate, bool, error)
SetDomainAuthGate(ctx context.Context, g store.DomainAuthGate) error
DeleteDomainAuthGate(ctx context.Context, domain string) error
ListDomainAuthGates(ctx context.Context) ([]store.DomainAuthGate, error)
}
DomainAuthGateStore is the store surface .../domains/{domain}/auth-gate needs.
type DomainBasicAuthSecrets ¶
type DomainBasicAuthSecrets interface {
SetValue(ctx context.Context, serviceName, envKey, plaintext string) error
Exists(ctx context.Context, serviceName, envKey string) (bool, error)
DeleteAll(ctx context.Context, serviceName string) error
}
DomainBasicAuthSecrets is the surface these handlers need from internal/secrets.Manager for a domain's basic-auth password: set it (PUT), check whether one exists (GET's has_password, and PUT's "already set" check for the omitted-password case), and clear it (DELETE). *secrets.Manager satisfies this structurally, the same narrow shape CloudflareTunnelSecrets already establishes.
type DomainBasicAuthStore ¶
type DomainBasicAuthStore interface {
GetDomainBasicAuth(ctx context.Context, domain string) (store.DomainBasicAuth, bool, error)
SetDomainBasicAuth(ctx context.Context, domain, username string) error
DeleteDomainBasicAuth(ctx context.Context, domain string) error
// ListDomainBasicAuth backs GET /api/v1/domains's has_basic_auth
// flag: one bulk read instead of a per-domain GetDomainBasicAuth
// call, avoiding an N+1 query over the domain list.
ListDomainBasicAuth(ctx context.Context) ([]store.DomainBasicAuth, error)
}
DomainBasicAuthStore is the store surface GET/PUT/DELETE .../domains/{domain}/auth need: the username claimed for a domain, always set, same "core Store interface" shape as DomainStore above.
type DomainErrorPagesStore ¶ added in v0.2.0
type DomainErrorPagesStore interface {
ListDomainErrorPages(ctx context.Context, domain string) ([]store.DomainErrorPage, error)
SetDomainErrorPage(ctx context.Context, domain string, statusCode int, body string) error
DeleteDomainErrorPage(ctx context.Context, domain string, statusCode int) error
DeleteDomainErrorPages(ctx context.Context, domain string) error
}
DomainErrorPagesStore is the store surface GET/PUT/DELETE .../domains/{domain}/error-pages need: a domain's status-code-to-HTML mappings, always set, same "core Store interface" shape as DomainRedirectStore above; no secrets dependency either.
type DomainMaintenanceSettingsStore ¶
type DomainMaintenanceSettingsStore interface {
GetDomainMaintenanceSettings(ctx context.Context, domain string, now time.Time) (store.DomainMaintenance, bool, error)
SaveDomainMaintenance(ctx context.Context, m store.DomainMaintenance) error
}
DomainMaintenanceSettingsStore is optional on DomainMaintenanceStore: it carries the page copy, Retry-After, bypass rules and the end time link.
type DomainMaintenanceStore ¶
type DomainMaintenanceStore interface {
GetDomainMaintenance(ctx context.Context, domain string) (bool, error)
SetDomainMaintenance(ctx context.Context, domain string) error
DeleteDomainMaintenance(ctx context.Context, domain string) error
// ListDomainMaintenance backs GET /api/v1/domains's maintenance_enabled
// flag in one bulk read.
ListDomainMaintenance(ctx context.Context) ([]string, error)
}
DomainMaintenanceStore is the store surface GET/PUT/DELETE .../domains/{domain}/maintenance need.
type DomainRedirectStore ¶ added in v0.2.0
type DomainRedirectStore interface {
GetDomainRedirect(ctx context.Context, domain string) (store.DomainRedirect, bool, error)
SetDomainRedirect(ctx context.Context, domain, targetURL string, statusCode int) error
DeleteDomainRedirect(ctx context.Context, domain string) error
// ListDomainRedirects backs GET /api/v1/domains's has_redirect flag:
// one bulk read instead of a per-domain GetDomainRedirect call,
// avoiding an N+1 query over the domain list.
ListDomainRedirects(ctx context.Context) ([]store.DomainRedirect, error)
}
DomainRedirectStore is the store surface GET/PUT/DELETE .../domains/{domain}/redirect need: an opt-in redirect to an arbitrary target URL for a domain, always set, same "core Store interface" shape as DomainMaintenanceStore above; like that store, there is no secrets dependency at all, since neither the target URL nor the status code is credential material.
type DomainSearchVisibilityStore ¶ added in v0.2.0
type DomainSearchVisibilityStore interface {
IsDomainHidden(ctx context.Context, domain string) (bool, error)
SetDomainHidden(ctx context.Context, domain string, hidden bool) error
}
DomainSearchVisibilityStore is the store surface for .../domains/{domain}/search-visibility.
type DomainStore ¶
type DomainStore interface {
ListServiceDomains(ctx context.Context) ([]store.ServiceDomain, error)
}
DomainStore is the store surface GET /api/v1/domains needs: every domain currently claimed by a service, for the centralized cross-app domains list (web/src/routes/domains). Reuses internal/store's existing service_domains table (kept in sync by SaveDesiredService on every write, see that method's own doc comment); this is a plain read of already-tracked state, not a new tracking mechanism.
type DomainTLSCertSecrets ¶
type DomainTLSCertSecrets interface {
SetValue(ctx context.Context, serviceName, envKey, plaintext string) error
DeleteAll(ctx context.Context, serviceName string) error
}
DomainTLSCertSecrets is the surface these handlers need from internal/secrets.Manager for a domain's certificate and private key: set both (PUT) and clear both (DELETE). *secrets.Manager satisfies this structurally, the same narrow shape DomainBasicAuthSecrets already establishes.
type DomainTLSCertStore ¶
type DomainTLSCertStore interface {
GetDomainTLSCert(ctx context.Context, domain string) (store.DomainTLSCert, bool, error)
SetDomainTLSCert(ctx context.Context, domain string, uploadedAt, expiresAt time.Time) error
DeleteDomainTLSCert(ctx context.Context, domain string) error
// ListDomainTLSCerts backs handleListCertificates' Source field (api/
// certificates.go): every domain with a custom cert on file, so the
// certificate center page can tell "custom" apart from "acme" per row.
ListDomainTLSCerts(ctx context.Context) ([]store.DomainTLSCert, error)
}
DomainTLSCertStore is the store surface GET/PUT/DELETE .../domains/{domain}/tls-cert need: the upload/expiry metadata for a domain's BYO certificate, same "core Store interface" shape as DomainBasicAuthStore.
type DomainTrafficPolicyStore ¶ added in v0.2.0
type DomainTrafficPolicyStore interface {
GetDomainTrafficPolicy(ctx context.Context, domain, kind string) (store.DomainTrafficPolicy, bool, error)
ListDomainTrafficPoliciesFor(ctx context.Context, domain string) ([]store.DomainTrafficPolicy, error)
SetDomainTrafficPolicy(ctx context.Context, domain, kind string, spec []byte) error
DeleteDomainTrafficPolicy(ctx context.Context, domain, kind string) error
}
DomainTrafficPolicyStore is the store surface for the per-domain traffic controls (headers, forwarders, geo, cache, redirects).
type DomainWAFStore ¶ added in v0.2.0
type DomainWAFStore interface {
GetDomainWAF(ctx context.Context, domain string) (store.DomainWAF, bool, error)
SetDomainWAF(ctx context.Context, domain string, wafEnabled bool, mode string, rateLimitRPS, rateLimitBurst int) error
DeleteDomainWAF(ctx context.Context, domain string) error
// ListDomainWAF backs GET /api/v1/domains's waf_enabled flag: one
// bulk read instead of a per-domain GetDomainWAF call, avoiding an
// N+1 query over the domain list.
ListDomainWAF(ctx context.Context) ([]store.DomainWAF, error)
}
DomainWAFStore is the store surface GET/PUT/DELETE .../domains/{domain}/waf need: opt-in WAF and rate-limit settings for a domain, always set, same "core Store interface" shape as DomainMaintenanceStore above; like that store, there is no secrets dependency at all, since neither setting involves credential material.
type EdgeAccess ¶
type EdgeAccess struct {
Stats *ingress.RequestStats
Log *ingress.AccessLog
}
EdgeAccess adapts the process-wide stats and access log to AccessSource.
func (EdgeAccess) AppAccess ¶
func (e EdgeAccess) AppAccess(app string, f ingress.AccessFilter) []ingress.AccessRecord
AppAccess implements AccessSource.
type Effect ¶
type Effect string
Effect is a statement's outcome when it matches: Allow or Deny, exactly AWS IAM's own two-value vocabulary.
type EmailSecretsStore ¶
type EmailSecretsStore interface {
SetValue(ctx context.Context, serviceName, envKey, plaintext string) error
Exists(ctx context.Context, serviceName, envKey string) (bool, error)
}
EmailSecretsStore is the surface the email settings handlers need from internal/secrets.Manager. *secrets.Manager satisfies this structurally.
type EmailSettingsStore ¶
type EmailSettingsStore interface {
GetEmailSettings(ctx context.Context) (store.EmailSettings, error)
UpdateEmailSettings(ctx context.Context, s store.EmailSettings) error
}
EmailSettingsStore is the store surface GET/PUT /api/v1/settings/email need: the single platform-wide row, always present, the same shape IngressSettingsStore has for its own row.
type EnvironmentStore ¶
type EnvironmentStore interface {
SaveEnvironment(ctx context.Context, e store.Environment) error
GetEnvironment(ctx context.Context, id string) (store.Environment, error)
GetEnvironmentsByIDs(ctx context.Context, ids []string) (map[string]store.Environment, error)
ListEnvironmentsByProject(ctx context.Context, projectID string) ([]store.Environment, error)
DeleteEnvironment(ctx context.Context, id string) error
SetEnvironmentProtected(ctx context.Context, id string, protected bool) error
UpdateEnvironment(ctx context.Context, id string, patch store.EnvironmentPatch) error
ListAllEnvironments(ctx context.Context) ([]store.EnvironmentWithCounts, error)
EnvironmentMemberCounts(ctx context.Context, envID string) (apps, databases int, err error)
MoveEnvironmentMembers(ctx context.Context, fromID, toID string) error
EnvironmentOfDatabase(ctx context.Context, databaseName string) (*store.EnvironmentRef, error)
SetServiceEnvironment(ctx context.Context, serviceName, envID string) error
// SetEnvironmentEnvVars/ListEnvironmentEnvVars back GET/PUT
// /api/v1/environments/{id}/env (environment_env.go): shared env vars
// every service tagged with this environment inherits, sitting
// between ProjectStore's own project_env_vars tier and a service's
// own env (internal/reconcile/application's resolveEnv), full-replace
// on write, mirroring SetOrganizationEnvVars/ListOrganizationEnvVars.
SetEnvironmentEnvVars(ctx context.Context, environmentID string, vars map[string]string) error
ListEnvironmentEnvVars(ctx context.Context, environmentID string) (map[string]string, error)
// ListEnvironmentEnvVarsDetailed/SetEnvironmentSecretEnvVar/
// DeleteEnvironmentSecretEnvVar/ListEnvironmentSecretEnvKeys back GET
// /api/v1/environments/{id}/env/all and the secret-var sub-resource
// routes (environment_env.go), mirroring ProjectStore/
// OrganizationStore's own secret-capable extension.
ListEnvironmentEnvVarsDetailed(ctx context.Context, environmentID string) ([]store.SharedEnvVar, error)
SetEnvironmentSecretEnvVar(ctx context.Context, environmentID, key string) error
DeleteEnvironmentSecretEnvVar(ctx context.Context, environmentID, key string) error
ListEnvironmentSecretEnvKeys(ctx context.Context, environmentID string) ([]string, error)
}
EnvironmentStore is the store surface the environments handlers need.
type ErrorStore ¶
type ErrorStore interface {
WriteErrorEvent(ctx context.Context, ev telemetry.ErrorEvent, keep int) (bool, error)
ListErrorIssues(ctx context.Context, f telemetry.ErrorFilter) ([]telemetry.ErrorIssue, error)
GetErrorIssue(ctx context.Context, resourceID, fingerprint string) (telemetry.ErrorIssue, []telemetry.ErrorSample, error)
SetErrorIssueStatus(ctx context.Context, resourceID, fingerprint, status string) error
}
ErrorStore is the issue storage the error tracking routes need.
type EscrowMaterialReader ¶ added in v0.2.0
type EscrowMaterialReader func() (cpbackup.EscrowMaterial, error)
EscrowMaterialReader returns the master key and the other recovery files an escrow bundle protects. It is called only to build a bundle and its result is never logged.
type EventWebhookService ¶
type EventWebhookService interface {
Emit(e eventhook.Event)
List(ctx context.Context) ([]store.EventWebhook, error)
Get(ctx context.Context, id string) (store.EventWebhook, error)
Create(ctx context.Context, in eventhook.Input) (store.EventWebhook, string, error)
Update(ctx context.Context, id string, p eventhook.Patch) (store.EventWebhook, error)
Delete(ctx context.Context, id string) error
RotateSecret(ctx context.Context, id string) (string, error)
Test(ctx context.Context, id string) (int, error)
Replay(ctx context.Context, deliveryID string) (store.EventWebhookDelivery, error)
Deliveries(ctx context.Context, webhookID string, limit int) ([]store.EventWebhookDelivery, error)
Summary(ctx context.Context, id string) (eventhook.Counts, error)
}
EventWebhookService is the surface the event webhook routes need from internal/eventhook; *eventhook.Service satisfies it.
type ExposureStore ¶ added in v0.2.0
type ExposureStore interface {
SaveExposureRestriction(ctx context.Context, r store.ExposureRestriction) error
ListExposureRestrictions(ctx context.Context) ([]store.ExposureRestriction, error)
DeleteExposureRestriction(ctx context.Context, port int, protocol string) error
}
ExposureStore is the store surface the exposure handlers need.
type ExternalDatabaseStore ¶ added in v0.2.0
type ExternalDatabaseStore interface {
CreateExternalDatabase(ctx context.Context, d store.ExternalDatabase) error
UpdateExternalDatabase(ctx context.Context, d store.ExternalDatabase) error
GetExternalDatabase(ctx context.Context, name string) (*store.ExternalDatabase, error)
ListExternalDatabases(ctx context.Context) ([]store.ExternalDatabase, error)
DeleteExternalDatabase(ctx context.Context, name string) error
SetExternalDatabaseHealth(ctx context.Context, name, status, reason string, latencyMs int, checkedAt time.Time) error
}
ExternalDatabaseStore is the store surface for databases this platform connects to but does not run.
type FeatureFlagStore ¶
type FeatureFlagStore interface {
SaveFeatureFlag(ctx context.Context, f store.FeatureFlag) error
GetFeatureFlag(ctx context.Context, id string) (store.FeatureFlag, error)
GetFeatureFlagByKey(ctx context.Context, key string) (store.FeatureFlag, error)
ListFeatureFlagsForService(ctx context.Context, serviceName string) ([]store.FeatureFlag, error)
UpdateFeatureFlag(ctx context.Context, id, name, description string, enabled bool, rolloutPercentage int, updatedAt time.Time) error
DeleteFeatureFlag(ctx context.Context, id string) error
}
FeatureFlagStore is the store surface the feature flag handlers need, mirroring ScheduledTaskStore's own shape for a different child resource.
type FirewallRuleStore ¶ added in v0.2.0
type FirewallRuleStore interface {
SaveFirewallRule(ctx context.Context, r store.FirewallRule) error
ListFirewallRules(ctx context.Context) ([]store.FirewallRule, error)
DeleteFirewallRule(ctx context.Context, id string) error
}
FirewallRuleStore is the store surface the firewall rule handlers need.
type FixitStore ¶
type FixitStore interface {
RecentFixitAttempts(ctx context.Context, fixID, subject string, limit int) ([]store.FixitAttempt, error)
CountFixitAttemptsSince(ctx context.Context, fixID string, since time.Time) (int, error)
RecordFixitAttempt(ctx context.Context, a store.FixitAttempt) error
GetFixitSetting(ctx context.Context, key string) (string, bool, error)
SetFixitSetting(ctx context.Context, key, value, actor string, now time.Time) error
}
FixitStore is the persistence the fix engine needs; *store.DB satisfies it.
type ForgeDeploymentStore ¶ added in v0.2.0
type ForgeDeploymentStore interface {
CreateForgeDeployment(ctx context.Context, d store.ForgeDeployment) error
SetForgeDeploymentState(ctx context.Context, id, state, warning string, at time.Time) error
ListForgeDeploymentsByState(ctx context.Context, app, environment, state, excludeID string) ([]store.ForgeDeployment, error)
}
ForgeDeploymentStore persists the deployments created on a git forge. *store.DB satisfies it.
type GPUHostDiagnoser ¶ added in v0.2.0
type GPUHostDiagnoser func(ctx context.Context) gpu.HostDiagnosis
GPUHostDiagnoser inspects the control plane host's GPU stack in detail: driver, toolkit, CDI specs and how containers can attach GPUs.
type GateSettings ¶ added in v0.2.0
type GateSettings struct {
SessionTTL time.Duration
TokenTTL time.Duration
EventRetention time.Duration
// AllowHTTP lets gated apps served over plain http sign in; the session
// cookie then cannot be Secure.
AllowHTTP bool
}
GateSettings tunes the built-in auth gate provider.
func DefaultGateSettings ¶ added in v0.2.0
func DefaultGateSettings() GateSettings
DefaultGateSettings returns the settings used when no env var is set.
func GateSettingsFromEnv ¶ added in v0.2.0
func GateSettingsFromEnv(getenv func(string) string) (GateSettings, error)
GateSettingsFromEnv reads the APP_GATE_* env vars. On a bad value it keeps that setting's default and reports the first error.
type GateStore ¶ added in v0.2.0
type GateStore interface {
GetDomainAuthGate(ctx context.Context, domain string) (store.DomainAuthGate, bool, error)
ListGateRules(ctx context.Context, domain string) ([]store.GateRule, error)
ReplaceGateRules(ctx context.Context, domain string, rules []store.GateRule) error
CreateGateToken(ctx context.Context, t store.GateToken) error
ConsumeGateToken(ctx context.Context, tokenHash string) (store.GateToken, bool, error)
CreateGateSession(ctx context.Context, s store.GateSession) error
GetGateSession(ctx context.Context, tokenHash string) (store.GateSession, bool, error)
RevokeGateSessions(ctx context.Context, domain string) (int64, error)
CountLiveGateSessions(ctx context.Context, domain string) (int, error)
DashboardSessionLive(ctx context.Context, sessionID string) (bool, error)
DomainEnvironmentID(ctx context.Context, domain string) (string, error)
RecordAuthGateEvent(ctx context.Context, e store.GateEvent) error
ListAuthGateEvents(ctx context.Context, domain string, since time.Time, limit int) ([]store.GateEvent, error)
PruneGateData(ctx context.Context, cutoff time.Time) (int64, error)
GetUserByID(ctx context.Context, id string) (*store.User, error)
GetUserByEmail(ctx context.Context, email string) (*store.User, error)
UserTeamRoles(ctx context.Context, userID string) (map[string]string, error)
UserRoleID(ctx context.Context, userID string) (string, error)
UserVisibility(ctx context.Context, userID string) (store.Visibility, error)
GetOrganization(ctx context.Context, id string) (store.Organization, error)
ListOrganizations(ctx context.Context) ([]store.Organization, error)
GetRole(ctx context.Context, id string) (store.Role, error)
ListRoles(ctx context.Context) ([]store.Role, error)
}
GateStore is the store surface the built-in auth gate provider needs.
type GitHubAppClient ¶
type GitHubAppClient interface {
CheckInstanceReachable(ctx context.Context, instanceURL string) error
ExchangeManifestCode(ctx context.Context, instanceURL, code string) (githubapp.Credentials, error)
GetInstallation(ctx context.Context, instanceURL, appJWT string, installationID int64) (githubapp.InstallationInfo, error)
MintInstallationToken(ctx context.Context, instanceURL, appJWT string, installationID int64) (githubapp.InstallationToken, error)
ListInstallationRepos(ctx context.Context, instanceURL, token string) ([]githubapp.Repo, error)
GetRepo(ctx context.Context, instanceURL, token, owner, repo string) (githubapp.Repo, error)
ListBranches(ctx context.Context, instanceURL, token, owner, repo string) ([]githubapp.Branch, error)
CreateRepoWebhook(ctx context.Context, instanceURL, token, owner, repo, hookURL, secret string) error
CreateIssueComment(ctx context.Context, instanceURL, token, owner, repo string, number int, body string) (int64, error)
ListIssueComments(ctx context.Context, instanceURL, token, owner, repo string, number int) ([]gitprovider.Comment, error)
UpdateIssueComment(ctx context.Context, instanceURL, token, owner, repo string, commentID int64, body string) error
CreateCommitStatus(ctx context.Context, instanceURL, token, owner, repo, sha string, state githubapp.CommitStatusState, targetURL, description, statusContext string) error
}
GitHubAppClient is the surface internal/api needs from internal/githubapp.Client: manifest code exchange, installation lookup and token minting, repo/branch listing, repo webhook registration, and posting a preview deploy's own PR comment/commit status (preview_environments_github.go). *githubapp.Client satisfies this structurally; tests substitute a hand-written fake (github_app_test.go), the same "narrow, consumer-defined interface" shape every other external-system boundary in this package uses (Builder, DockerPinger, BackupRunner).
type GitHubAppSecrets ¶
type GitHubAppSecrets interface {
SetValue(ctx context.Context, serviceName, envKey, plaintext string) error
Resolve(ctx context.Context, serviceName, envKey string) (string, error)
DeleteAll(ctx context.Context, serviceName string) error
}
GitHubAppSecrets is the surface the GitHub App handlers need from internal/secrets.Manager: both SetValue (storing client_secret/ webhook_secret/private_key right after a successful code exchange) and Resolve (decrypting the private key back out, in memory only, immediately before signing a JWT). A different shape from BackupSecretsSetter (set-only) and internal/backup.SecretsResolver (resolve-only): this is the one credential-bearing feature in this codebase that both writes and reads back through internal/secrets from inside internal/api itself, because minting a fresh installation token on every repo/branch-listing call (see github_app_repos.go) needs the private key synchronously in the same request, not on a separate worker path the way internal/backup.Runner's own Resolve calls are. *secrets.Manager satisfies this structurally.
type GitHubAppStore ¶
type GitHubAppStore interface {
GetGitHubAppConnection(ctx context.Context) (store.GitHubAppConnection, error)
SaveGitHubAppConnection(ctx context.Context, c store.GitHubAppConnection) error
UpdateGitHubAppInstallation(ctx context.Context, installationID int64, accountLogin string) error
DeleteGitHubAppConnection(ctx context.Context) error
UpsertGitHubAppInstallation(ctx context.Context, installationID int64, accountLogin, accountType string) error
ListGitHubAppInstallations(ctx context.Context) ([]store.GitHubAppInstallation, error)
DeleteGitHubAppInstallation(ctx context.Context, id int64) error
}
GitHubAppStore is the store surface the GitHub App connection handlers need. *store.DB satisfies this structurally, part of the core Store interface (github_app_connections always exists as a table even when empty, the same "core store, not an optional plug-in" shape ingressSettings/domains already establish).
type GitLabAppClient ¶
type GitLabAppClient interface {
ExchangeCode(ctx context.Context, instanceURL, clientID, clientSecret, redirectURI, code string) (gitlabapp.Tokens, error)
RefreshToken(ctx context.Context, instanceURL, clientID, clientSecret, refreshToken string) (gitlabapp.Tokens, error)
ListProjects(ctx context.Context, instanceURL, accessToken string) ([]gitlabapp.Project, error)
GetProject(ctx context.Context, instanceURL, accessToken string, projectID int64) (gitlabapp.Project, error)
ListBranches(ctx context.Context, instanceURL, accessToken string, projectID int64) ([]gitlabapp.Branch, error)
CreateProjectWebhook(ctx context.Context, instanceURL, accessToken string, projectID int64, hookURL, secretToken string) error
CreateMergeRequestNote(ctx context.Context, instanceURL, accessToken, projectPath string, mrIID int, body string) (int64, error)
ListMergeRequestNotes(ctx context.Context, instanceURL, accessToken, projectPath string, mrIID int) ([]gitprovider.Comment, error)
UpdateMergeRequestNote(ctx context.Context, instanceURL, accessToken, projectPath string, mrIID int, noteID int64, body string) error
CreateCommitStatus(ctx context.Context, instanceURL, accessToken, projectPath, sha string, state gitlabapp.CommitState, targetURL, description, name string) error
}
GitLabAppClient is the surface internal/api needs from internal/gitlabapp.Client: OAuth code exchange/refresh, and project listing/lookup/webhook registration once connected. *gitlabapp.Client satisfies this structurally; tests substitute a hand-written fake.
type GitLabAppSecrets ¶
type GitLabAppSecrets interface {
SetValue(ctx context.Context, serviceName, envKey, plaintext string) error
Resolve(ctx context.Context, serviceName, envKey string) (string, error)
Exists(ctx context.Context, serviceName, envKey string) (bool, error)
DeleteAll(ctx context.Context, serviceName string) error
}
GitLabAppSecrets is the surface the GitLab App handlers need from internal/secrets.Manager: client_secret is set once at connect time and resolved back out on every OAuth token exchange/refresh and project API call; access_token/refresh_token/token_expires_at are written and re-read on the same schedule by gitlabAccessToken. The same "this feature both writes and reads back through internal/secrets" shape GitHubAppSecrets's own doc comment describes.
type GitLabAppStore ¶
type GitLabAppStore interface {
GetGitLabAppConnection(ctx context.Context) (store.GitLabAppConnection, error)
SaveGitLabAppConnection(ctx context.Context, c store.GitLabAppConnection) error
DeleteGitLabAppConnection(ctx context.Context) error
}
GitLabAppStore is the store surface the GitLab App connection handlers need. *store.DB satisfies this structurally, the same "core store" shape GitHubAppStore's own doc comment establishes.
type GitSourceSecrets ¶
type GitSourceSecrets interface {
SetValue(ctx context.Context, serviceName, envKey, plaintext string) error
Resolve(ctx context.Context, serviceName, envKey string) (string, error)
Exists(ctx context.Context, serviceName, envKey string) (bool, error)
}
GitSourceSecrets is the surface a git source's connect flow and the git-push webhook route (git_webhook.go) both need from internal/secrets.Manager: unlike SecretSetter and BackupSecretsSetter (write-only, a secret's value never resolved back through internal/api at all), this package genuinely does call Resolve, but only for its own server-side use, HMAC-verifying an incoming webhook and authenticating a git clone, never to populate an HTTP response body. See handleSetGitSource's and handleGitPushWebhook's own doc comments for that boundary; *secrets.Manager satisfies this structurally.
type GitSourceStore ¶
type GitSourceStore interface {
SaveGitSource(ctx context.Context, g store.GitSource) error
GetGitSource(ctx context.Context, serviceName string) (*store.GitSource, error)
DeleteGitSource(ctx context.Context, serviceName string) error
// ListGitSources backs GET /api/v1/apps/git-sources: every connected
// source's service name, repo URL and branch, filtered to the
// caller's visible apps by handleListGitSources itself (callerAppVisibility),
// the same shape handleListApps already uses for its own bulk list.
ListGitSources(ctx context.Context) ([]store.GitSourceSummary, error)
// SetGitSourcePreviewEnabled backs PUT
// /api/v1/apps/{name}/preview-settings (preview_environments_handlers.go):
// the opt-in toggle for preview environments per pull request.
SetGitSourcePreviewEnabled(ctx context.Context, serviceName string, enabled bool) error
// SetGitSourcePostPRComments backs the same PUT
// /api/v1/apps/{name}/preview-settings route: the opt-in toggle for
// posting a GitHub PR comment/commit status about a preview deploy.
SetGitSourcePostPRComments(ctx context.Context, serviceName string, enabled bool) error
// SetGitSourceDeploySettings backs PUT
// /api/v1/apps/{name}/git-source/deploy-settings: push path filters
// and forge status reporting.
SetGitSourceDeploySettings(ctx context.Context, serviceName string, paths, pathsIgnore []string, reportStatus bool) error
// SetGitSourceBuild backs PUT /api/v1/apps/{name}/git-source/build.
SetGitSourceBuild(ctx context.Context, serviceName, buildType, buildPath, baseDirectory string) error
}
GitSourceStore is the store surface the git source handlers need. *store.DB satisfies this structurally.
type GiteaAppClient ¶ added in v0.2.0
type GiteaAppClient interface {
ExchangeCode(ctx context.Context, instanceURL, clientID, clientSecret, redirectURI, code string) (giteaapp.Tokens, error)
RefreshToken(ctx context.Context, instanceURL, clientID, clientSecret, refreshToken string) (giteaapp.Tokens, error)
ListRepos(ctx context.Context, instanceURL, accessToken string) ([]giteaapp.Repo, error)
GetRepo(ctx context.Context, instanceURL, accessToken, fullName string) (giteaapp.Repo, error)
ListBranches(ctx context.Context, instanceURL, accessToken, fullName string) ([]giteaapp.Branch, error)
CreateRepoWebhook(ctx context.Context, instanceURL, accessToken, fullName, hookURL, secret string) error
CreateIssueComment(ctx context.Context, instanceURL, accessToken, fullName string, number int, body string) (int64, error)
ListIssueComments(ctx context.Context, instanceURL, accessToken, fullName string, number int) ([]gitprovider.Comment, error)
UpdateIssueComment(ctx context.Context, instanceURL, accessToken, fullName string, commentID int64, body string) error
CreateCommitStatus(ctx context.Context, instanceURL, accessToken, fullName, sha string, state giteaapp.CommitStatusState, targetURL, description, statusContext string) error
}
GiteaAppClient is the surface internal/api needs from internal/giteaapp.Client: OAuth code exchange/refresh, and repo listing/lookup/webhook registration once connected. *giteaapp.Client satisfies this structurally; tests substitute a hand-written fake.
type GiteaAppSecrets ¶ added in v0.2.0
type GiteaAppSecrets interface {
SetValue(ctx context.Context, serviceName, envKey, plaintext string) error
Resolve(ctx context.Context, serviceName, envKey string) (string, error)
Exists(ctx context.Context, serviceName, envKey string) (bool, error)
DeleteAll(ctx context.Context, serviceName string) error
}
GiteaAppSecrets is the surface the Gitea App handlers need from internal/secrets.Manager: client_secret is set once at connect time and resolved back out on every OAuth token exchange/refresh and repo/branch API call; access_token/refresh_token/token_expires_at are written and re-read on the same schedule by giteaAccessToken. The same "this feature both writes and reads back through internal/secrets" shape GitLabAppSecrets's own doc comment describes.
type GiteaAppStore ¶ added in v0.2.0
type GiteaAppStore interface {
GetGiteaAppConnection(ctx context.Context) (store.GiteaAppConnection, error)
SaveGiteaAppConnection(ctx context.Context, c store.GiteaAppConnection) error
DeleteGiteaAppConnection(ctx context.Context) error
}
GiteaAppStore is the store surface the Gitea App connection handlers need. *store.DB satisfies this structurally, the same "core store" shape GitLabAppStore's own doc comment establishes.
type HookRunStore ¶
type HookRunStore interface {
GetHookRuns(ctx context.Context, serviceName string) ([]store.HookRun, error)
}
HookRunStore is the store surface GET /api/v1/apps/{name}/hook-runs (apps_hooks.go) needs: the most recent outcome of each of a service's pre/post-deploy hooks (internal/reconcile/application's own HookRunRecorder, migrations/0083_service_hook_runs.sql). Always set, the same "core Store interface, not an optional plug-in" shape domainMaintenance above establishes.
type HumanVerifier ¶
HumanVerifier is the pluggable human check in front of the passwordless demo session. Verify returns nil when the visitor passed.
type ImageAutoUpdateStore ¶ added in v0.2.0
type ImageAutoUpdateStore interface {
SetImageAutoUpdate(ctx context.Context, serviceName string, enabled bool) error
GetImageAutoUpdate(ctx context.Context, serviceName string) (store.ImageAutoUpdate, error)
RecordImageAutoUpdateCheck(ctx context.Context, serviceName, result string, at time.Time) error
SetImageAutoUpdateWebhookHash(ctx context.Context, serviceName, hash string) error
}
ImageAutoUpdateStore is the store surface for per-app image auto-update.
type ImageLister ¶
type ImageLister interface {
ListImages(ctx context.Context, repo string) ([]docker.ImageInfo, error)
}
ImageLister is the surface GET /api/v1/apps/{name}/images needs: discover previously-built tags under a repo, so the deploy trigger form (web/src/components/DeployTriggerForm.tsx) can offer a dropdown instead of forcing an operator to hand-type a full image reference every time. Unlike DockerPinger above, this mirrors an existing docker.Runtime method (internal/docker/runtime.go) exactly rather than inventing a narrower one: ListImages is already the consumer-defined boundary every reconciler controller depends on for rollback candidate discovery, so redeclaring it here (structurally satisfied by *docker.Client, same as Runtime) avoids a second, divergent surface for the same one capability. *docker.Client satisfies this structurally.
type IngressPortOwner ¶ added in v0.2.0
IngressPortOwner reports whether this control plane's own embedded ingress (internal/ingress.Driver) currently has a listener bound to port. *ingress.Driver satisfies this.
type IngressSettingsStore ¶
type IngressSettingsStore interface {
GetIngressSettings(ctx context.Context) (store.IngressSettings, error)
UpdateIngressSettings(ctx context.Context, s store.IngressSettings) error
GetDashboardURL(ctx context.Context) (string, error)
SetDashboardURL(ctx context.Context, u string) error
}
IngressSettingsStore is the store surface the ingress settings handlers need. *store.DB satisfies this structurally, the same consumer-defined interface convention every other Store sub-interface in this package follows (see CertStore, StaticSiteStore).
type InviteStore ¶
type InviteStore interface {
SaveInvite(ctx context.Context, inv store.Invite) error
GetInviteByHash(ctx context.Context, hash string) (*store.Invite, error)
GetInviteByID(ctx context.Context, id string) (*store.Invite, error)
ListPendingInvites(ctx context.Context) ([]store.Invite, error)
RevokeInvite(ctx context.Context, id string) error
ClaimInvite(ctx context.Context, id string) error
}
InviteStore is the store surface the team-invite flow needs: always set, part of the core Store interface, same shape as PasswordResetTokenStore above.
type LBAdminStateStore ¶ added in v0.2.0
type LBAdminStateStore interface {
SetLBUpstreamAdminState(ctx context.Context, service string, replica int, state string) error
ListLBUpstreamAdminStates(ctx context.Context) (map[string]map[int]string, error)
}
LBAdminStateStore persists per-upstream admin state. *store.DB satisfies this; a LoadBalancerStore that does not implement it serves no admin state.
type LoadBalancerStore ¶ added in v0.2.0
type LoadBalancerStore interface {
GetServiceLoadBalancer(ctx context.Context, service string) (string, bool, error)
SetServiceLoadBalancer(ctx context.Context, service, configJSON string) error
DeleteServiceLoadBalancer(ctx context.Context, service string) error
ListLoadBalancerRows(ctx context.Context) ([]store.LoadBalancerRow, error)
}
LoadBalancerStore is the persistence surface for per-app load balancer config. *store.DB satisfies this.
type LocalContainerLister ¶ added in v0.2.0
type LocalContainerLister interface {
ListLocalContainers(ctx context.Context) ([]docker.LocalContainer, error)
}
LocalContainerLister is implemented by the real Docker client. A runtime that is not one cannot discover local source containers.
type LogArchiveStore ¶ added in v0.2.0
type LogArchiveStore interface {
UpsertLogArchivePolicy(ctx context.Context, p store.LogArchivePolicy) error
GetLogArchivePolicy(ctx context.Context, appName string) (store.LogArchivePolicy, error)
ListLogArchivePolicies(ctx context.Context) ([]store.LogArchivePolicy, error)
DeleteLogArchivePolicy(ctx context.Context, appName string) error
CountLogArchivePoliciesForTarget(ctx context.Context, targetID string) (int, error)
ListLogArchiveRuns(ctx context.Context, appName string, all bool, limit int) ([]store.LogArchiveRun, error)
}
LogArchiveStore persists log archive policies and run history.
type LogArchiver ¶ added in v0.2.0
type LogArchiver interface {
StartDump(ctx context.Context, req objectstore.DumpRequest) (store.LogArchiveRun, error)
}
LogArchiver starts manual log dumps.
type LogBudgetResource ¶
type LogBudgetResource struct {
MaxMB int64 `json:"max_mb"`
DefaultMB int64 `json:"default_mb"`
EffectiveMaxByte int64 `json:"effective_max_bytes"`
}
LogBudgetResource is the per-app budget; MaxMB 0 means no override.
type LogBudgetStore ¶
type LogBudgetStore interface {
GetLogBudget(ctx context.Context, resourceID string) (int64, error)
SetLogBudget(ctx context.Context, resourceID string, maxBytes int64) error
DeleteLogBudget(ctx context.Context, resourceID string) error
LogUsageAll(ctx context.Context, now time.Time, defaultMax int64) ([]telemetry.LogUsage, error)
}
LogBudgetStore is the per-app log budget and usage storage the routes need.
type LogPipelineStore ¶
type LogPipelineStore interface {
GetLogPipeline(ctx context.Context, resourceID string) ([]telemetry.PipelineRule, error)
SetLogPipeline(ctx context.Context, resourceID string, rules []telemetry.PipelineRule) error
DeleteLogPipeline(ctx context.Context, resourceID string) error
}
LogPipelineStore is the per-app log pipeline storage the routes need.
type LogUsageApp ¶
type LogUsageApp struct {
App string `json:"app"`
Bytes int64 `json:"bytes"`
Lines int64 `json:"lines"`
RateBytesMin float64 `json:"rate_bytes_per_min"`
BudgetBytes int64 `json:"budget_bytes"`
BudgetCustom bool `json:"budget_custom"`
Percent *float64 `json:"percent"`
ForecastDays *float64 `json:"forecast_days"`
TrimmedLines int64 `json:"trimmed_lines"`
TrimmedBytes int64 `json:"trimmed_bytes"`
}
LogUsageApp is one app's stored log volume against its budget.
type LogUsageResponse ¶
type LogUsageResponse struct {
DefaultBudgetBytes int64 `json:"default_budget_bytes"`
Apps []LogUsageApp `json:"apps"`
}
LogUsageResponse is GET /api/v1/logs/usage.
type LoginCodeStore ¶ added in v0.2.0
type LoginCodeStore interface {
CreateLoginCodeChallenge(ctx context.Context, c store.LoginCodeChallenge) error
GetLiveLoginCodeByBrowser(ctx context.Context, browserHash string, now time.Time) (store.LoginCodeChallenge, error)
ReserveLoginCodeAttempt(ctx context.Context, id string, maxAttempts int) (int, bool, error)
LockLoginCode(ctx context.Context, id string, now time.Time) (bool, error)
RedeemLoginCode(ctx context.Context, id string, now time.Time) (bool, error)
ListLiveLoginCodesForUser(ctx context.Context, userID string, now time.Time) ([]store.LoginCodeChallenge, error)
ClaimLapsedLoginCodes(ctx context.Context, now time.Time, limit int) ([]store.LoginCodeChallenge, error)
PruneLoginCodes(ctx context.Context, cutoff time.Time) error
CreateLoginApproval(ctx context.Context, a store.LoginApproval) error
GetLoginApproval(ctx context.Context, id string) (store.LoginApproval, error)
GetLoginApprovalByBrowser(ctx context.Context, browserHash string) (store.LoginApproval, error)
DecideLoginApproval(ctx context.Context, id, userID string, approve bool, decidedBy string, now time.Time) (bool, error)
ConsumeLoginApproval(ctx context.Context, id string, now time.Time) (bool, error)
ListPendingLoginApprovalsForUser(ctx context.Context, userID string, now time.Time) ([]store.LoginApproval, error)
ClaimLapsedLoginApprovals(ctx context.Context, now time.Time, limit int) ([]store.LoginApproval, error)
CreateTrustedDevice(ctx context.Context, d store.TrustedDevice) error
GetTrustedDeviceByHash(ctx context.Context, tokenHash string, now time.Time) (store.TrustedDevice, error)
TouchTrustedDevice(ctx context.Context, id string, now time.Time) error
ListTrustedDevices(ctx context.Context, userID string, now time.Time) ([]store.TrustedDevice, error)
RevokeTrustedDevice(ctx context.Context, userID, id string, now time.Time) (bool, error)
RevokeAllTrustedDevices(ctx context.Context, userID string, now time.Time) (int, error)
ExtendTrustedDevice(ctx context.Context, id string, expiresAt, now time.Time) error
PruneTrustedDevices(ctx context.Context, cutoff time.Time) error
SupersedeLoginApprovals(ctx context.Context, userID string, now time.Time) ([]store.LoginApproval, error)
ReplaceLoginApproval(ctx context.Context, a store.LoginApproval) ([]store.LoginApproval, error)
ExpireLoginCode(ctx context.Context, id string, now time.Time) (bool, error)
LockLoginCodesForUser(ctx context.Context, userID string, now time.Time) ([]string, error)
GetCodeLoginSettings(ctx context.Context) (store.CodeLoginSettings, bool, error)
SaveCodeLoginSettings(ctx context.Context, s store.CodeLoginSettings) error
}
LoginCodeStore is the store surface sign in with a code, new-device approval and trusted devices need.
type MajorUpgradeStore ¶ added in v0.2.0
type MajorUpgradeStore interface {
ListMajorUpgrades(ctx context.Context, databaseName string) ([]store.MajorUpgrade, error)
GetMajorUpgrade(ctx context.Context, id string) (store.MajorUpgrade, error)
ListMajorUpgradeSnapshots(ctx context.Context) ([]store.MajorUpgrade, error)
}
MajorUpgradeStore is the store surface the major upgrade routes read.
type MajorUpgrader ¶ added in v0.2.0
type MajorUpgrader interface {
RunMajorUpgrade(ctx context.Context, historyID, databaseName, toVersion string) error
Rollback(ctx context.Context, upgradeID string) error
DiscardSnapshot(ctx context.Context, upgradeID string) error
}
MajorUpgrader runs guarded major version upgrades (internal/backup's MajorUpgradeRunner).
type MasterKeyRotator ¶
type MasterKeyRotator interface {
RotateMasterKey(ctx context.Context, newMasterKey string) (rotatedAt time.Time, err error)
GetMasterKeyRotatedAt(ctx context.Context) (rotatedAt time.Time, ok bool, err error)
}
MasterKeyRotator is the surface POST /api/v1/system/master-key/rotate and the doctor's rotation-age check need from internal/secrets.Manager: rotate every stored DEK to a new master key (given as its serialized string, so this interface never imports internal/secrets' own MasterKey type), and report when that last succeeded. A distinct interface from SecretSetter above since a token scoped to AbilityWrite (SecretSetter's own gate) has no business rotating the one key every other secret in this control plane depends on; this is gated at AbilityRoot instead (see routes.go).
type MeshKeyRotator ¶ added in v0.2.0
type MeshKeyRotator interface {
RotateKey(ctx context.Context, nodeID string) (network.RotationResult, error)
RotationStatusFor(nodeID string) (network.RotationStatus, bool)
}
MeshKeyRotator is the narrow surface this package needs from *network.Coordinator for rotation: rotate one node's key, and read back what Coordinator itself knows about in-flight rotations. *network.Coordinator satisfies this structurally.
type MeshSettingsStore ¶ added in v0.2.0
type MeshSettingsStore interface {
GetMeshSetting(ctx context.Context) (store.MeshSetting, error)
SetMeshSetting(ctx context.Context, enabled bool, actor string, now time.Time) error
}
MeshSettingsStore persists the operator's mesh on/off choice; *store.DB satisfies it.
type MeshStatusProvider ¶ added in v0.2.0
MeshStatusProvider is the narrow surface this package needs from this node's live network.Mesh: exactly Status, never Apply or Close, since this package only ever reads the mesh, never drives it (the reconcile loop owns that). *network.Device, *network.Disabled, and any test fake implementing Status alone all satisfy this.
type MigrationHubStore ¶ added in v0.2.0
type MigrationHubStore interface {
CreateMigrationSession(ctx context.Context, s store.MigrationSession, items []store.MigrationItem) error
GetMigrationSession(ctx context.Context, id string) (store.MigrationSession, error)
ListMigrationSessions(ctx context.Context) ([]store.MigrationSession, error)
SetMigrationStep(ctx context.Context, id, step string, now time.Time) error
DeleteMigrationSession(ctx context.Context, id string) error
ListMigrationItems(ctx context.Context, sessionID string) ([]store.MigrationItem, error)
SetMigrationItemPlan(ctx context.Context, sessionID, sourceDB, targetName, targetVersion string, selected bool) error
MarkMigrationItemTargetCreated(ctx context.Context, sessionID, sourceDB, version string) error
SetMigrationItemStatus(ctx context.Context, sessionID, sourceDB, status, reason string, checked, mismatched int, detail string, now time.Time) error
}
MigrationHubStore is the store surface the migration hub routes need.
type ModelPreflightService ¶ added in v0.2.0
type ModelPreflightService interface {
PreflightEnabled() bool
Preflight(ctx context.Context, in models.PreflightInput) (models.PreflightResult, error)
CacheEnabled() bool
CacheList(ctx context.Context) (models.CacheReport, error)
CachePrune(ctx context.Context, volumes []string, dryRun bool) (models.CachePruneResult, error)
}
ModelPreflightService is the optional surface behind the Hugging Face preflight and model cache routes. The models service implements it.
type ModelService ¶ added in v0.2.0
type ModelService interface {
Create(ctx context.Context, in models.CreateInput) (models.Created, error)
List(ctx context.Context) ([]models.View, error)
Get(ctx context.Context, name string) (models.View, error)
Delete(ctx context.Context, name string) error
Restart(ctx context.Context, name string) error
RotateKey(ctx context.Context, name string) (string, error)
ListKeys(ctx context.Context, model string) ([]models.KeyView, error)
CreateKey(ctx context.Context, model string, in models.CreateKeyInput) (models.CreatedKey, error)
RevokeKey(ctx context.Context, model, id string) error
RotateKeyByID(ctx context.Context, model, id, actor string, grace *time.Duration) (models.CreatedKey, error)
Usage(ctx context.Context, model string, window time.Duration) (models.UsageReport, error)
EngineMetrics(ctx context.Context, name string, window time.Duration) (models.EngineMetricsReport, error)
FitCheck(ctx context.Context, req models.FitRequest) (models.FitReport, error)
SetResidency(ctx context.Context, name, residency string, idleTTL time.Duration) error
SetSwapGroup(ctx context.Context, name, group string) error
Wake(ctx context.Context, name string) error
Sleep(ctx context.Context, name string) error
ModelFit(ctx context.Context, name string) (models.FitReport, error)
SetHFToken(ctx context.Context, name, token string) error
GPUNodes(ctx context.Context) ([]models.GPUNode, error)
NodeGPU(ctx context.Context, nodeID string) (gpu.Info, bool, error)
UnplacedWorkloads(ctx context.Context) ([]models.Unplaced, error)
SetLocalNodeID(id string)
}
ModelService is the surface the /api/v1/models handlers need from internal/models.
type NetworkShareSecretsSetter ¶ added in v0.2.0
type NetworkShareSecretsSetter interface {
}
NetworkShareSecretsSetter is the surface network share create/update needs from internal/secrets.Manager, the same two-method shape RegistryCredentialSecretsSetter establishes: SetValue writes a CIFS share's password, never read back by any handler in this file.
type NetworkShareStore ¶ added in v0.2.0
type NetworkShareStore interface {
}
NetworkShareStore is the store surface the network share handlers need.
type NodeHostReports ¶ added in v0.2.2
type NodeHostReports interface {
Get(nodeID string) (agent.HostReport, bool)
}
NodeHostReports is the control plane's latest per-node agent host report.
type NodeMeshStatusSource ¶ added in v0.2.0
type NodeMeshStatusSource interface {
MeshStatus(ctx context.Context, nodeID string) (network.Status, error)
}
NodeMeshStatusSource reads a remote node's own WireGuard view over its agent session.
type NodeProviderConnectionStore ¶
type NodeProviderConnectionStore interface {
SaveNodeProviderConnection(ctx context.Context, c store.NodeProviderConnection) error
RecordNodeProviderTest(ctx context.Context, provider string, ok bool, detail string, at time.Time) error
DeleteNodeProviderConnection(ctx context.Context, provider string) error
ListNodeProviderConnections(ctx context.Context) ([]store.NodeProviderConnection, error)
}
NodeProviderConnectionStore is the store surface for connection metadata.
type NodeProviderSecrets ¶ added in v0.2.0
type NodeProviderSecrets interface {
SetValue(ctx context.Context, serviceName, envKey, plaintext string) error
Exists(ctx context.Context, serviceName, envKey string) (bool, error)
Resolve(ctx context.Context, serviceName, envKey string) (string, error)
}
NodeProviderSecrets is the surface the node provider credential handlers need from internal/secrets.Manager: unlike CloudflareDNSSecrets (write-only from this package's own perspective), this package does call Resolve, to authenticate the live provider API calls handleCreateNodeProvision and the catalog handlers below make. *secrets.Manager satisfies this structurally.
type NodeProvisionStore ¶ added in v0.2.0
type NodeProvisionStore interface {
SaveNodeProvision(ctx context.Context, p store.NodeProvision) error
GetNodeProvision(ctx context.Context, id string) (store.NodeProvision, error)
ListNodeProvisions(ctx context.Context) ([]store.NodeProvision, error)
UpdateNodeProvisionStatus(ctx context.Context, id, status, providerServerID, ipAddress, nodeID, failureReason string, updatedAt time.Time) error
}
NodeProvisionStore is the store surface the node provisioning handlers need.
type NodeProvisioner ¶ added in v0.2.0
type NodeProvisioner interface {
ListRegions(ctx context.Context) ([]provision.Region, error)
ListSizes(ctx context.Context, region string) ([]provision.Size, error)
CreateServer(ctx context.Context, opts provision.CreateOpts) (serverID, ipAddr string, err error)
GetServer(ctx context.Context, id string) (status provision.ServerStatus, ipAddr string, err error)
DeleteServer(ctx context.Context, id string) error
}
NodeProvisioner is the surface internal/provision.Provisioner implementations satisfy: a narrow, consumer-defined interface so this package's own tests inject a fake instead of hitting a real cloud API.
type NodeProvisionerFactory ¶ added in v0.2.0
type NodeProvisionerFactory func(provider, token string) (NodeProvisioner, error)
NodeProvisionerFactory builds a NodeProvisioner for a known provider name given its resolved API token. Overridable in this package's own tests via WithNodeProvisionerFactory, the same "seam, not an interface" shape gitSourceFetch/fetch already use elsewhere in this package.
type NodeRuntimeResolver ¶
NodeRuntimeResolver picks the docker.Runtime that owns a given nodeID: the control plane's own local Docker daemon for "" (the store's established "empty NodeID means this control plane's own local node" convention, store.DesiredService.NodeID's own doc comment), or a connected remote agent's Transport for anything else. This is a func type, not an interface, the same pattern fetchFunc (builds.go) already establishes for a single-method seam: the real implementation is cmd/levelrail/main.go's own resolveNodeTransport (used identically by every reconciler controller to pick which node's Runtime it drives), passed in as a closure over that function's own registry rather than this package importing internal/agent.Registry directly.
handleExecApp (exec.go) is the first internal/api handler that needs live, per-request node routing: DockerPinger/ImageLister/ DockerDiskUsager/DockerPruner above are all fixed to this control plane's own local daemon, a deliberate choice their own doc comments explain (adding a method to docker.Runtime itself would ripple into every one of Runtime's 6+ fake implementations across internal/reconcile and internal/agent's test files, for the sake of one read-only or narrowly-scoped signal). Exec has the opposite requirement: it must reach whichever node the target app's container is actually running on, so it needs the resolver, not a fixed Runtime.
type NodeSessionCloser ¶ added in v0.2.0
type NodeSessionCloser interface {
Disconnect(nodeID string)
}
NodeSessionCloser ends a node's live agent session. *agent.Server satisfies it; nil means a revoked node is only refused at its next connection.
type NodeStore ¶
type NodeStore interface {
ListNodes(ctx context.Context) ([]store.Node, error)
GetNode(ctx context.Context, id string) (*store.Node, error)
DeleteNode(ctx context.Context, id string) error
SaveNodeJoinToken(ctx context.Context, t store.NodeJoinToken) error
UpdateNodeWorkloads(ctx context.Context, id string, acceptsApp, acceptsBuild bool) error
// UpdateNodeRegion sets a node's optional location label, backing
// PUT /api/v1/nodes/{id}/region.
UpdateNodeRegion(ctx context.Context, id, region string) error
// SetNodeSchedulable is the cordon/uncordon mutation.
SetNodeSchedulable(ctx context.Context, id string, schedulable bool) error
RevokeNodeCert(ctx context.Context, id string, now time.Time) error
}
NodeStore is the store surface the node-management handlers need. *store.DB satisfies this structurally, the same narrow consumer-defined interface convention every other Store sub-interface in this package already follows.
type NotificationChannelTester ¶
type NotificationChannelTester interface {
SendTest(ctx context.Context, kind alerting.NotifyKind, notifyURL string) error
SendChannelTest(ctx context.Context, c alerting.NotificationChannel) error
}
NotificationChannelTester is the surface the test-send routes need: a real send through kind/notifyURL, not just a format check. *alerting.DeployDispatcher satisfies this structurally.
type NotificationChannels ¶
type NotificationChannels interface {
SaveNotificationChannel(ctx context.Context, c alerting.NotificationChannel) error
GetNotificationChannel(ctx context.Context, id string) (*alerting.NotificationChannel, error)
ListNotificationChannels(ctx context.Context) ([]alerting.NotificationChannel, error)
DeleteNotificationChannel(ctx context.Context, id string) error
RevealNotificationChannel(ctx context.Context, c alerting.NotificationChannel) (alerting.NotificationChannel, error)
}
NotificationChannels is the store surface the channel handlers need. *alerting.DB satisfies this structurally.
type NotificationDeliveryStore ¶
type NotificationDeliveryStore interface {
RecordNotificationDelivery(ctx context.Context, d alerting.NotificationDelivery) error
ListNotificationDeliveries(ctx context.Context, channelID string, limit int, before *time.Time) ([]alerting.NotificationDelivery, error)
}
NotificationDeliveryStore is the surface the delivery-history route and test-send recording need. *alerting.DB satisfies this structurally.
type OAuthIdentityStore ¶
type OAuthIdentityStore interface {
GetOAuthIdentity(ctx context.Context, provider, providerUserID string) (*store.OAuthIdentity, error)
SaveOAuthIdentity(ctx context.Context, i store.OAuthIdentity) error
ListOAuthIdentitiesForUser(ctx context.Context, userID string) ([]store.OAuthIdentity, error)
}
OAuthIdentityStore is the store surface the sign-in and account- linking handlers need. *store.DB satisfies this structurally.
type OAuthSecrets ¶
type OAuthSecrets interface {
SetValue(ctx context.Context, serviceName, envKey, plaintext string) error
Resolve(ctx context.Context, serviceName, envKey string) (string, error)
}
OAuthSecrets is the surface the OAuth flow needs from internal/secrets.Manager: unlike SecretSetter (write-only), a provider's client secret must be resolved on every sign-in attempt.
type OAuthSettingsStore ¶
type OAuthSettingsStore interface {
GetOAuthProviderSettings(ctx context.Context, provider string) (store.OAuthProviderSettings, error)
ListOAuthProviderSettings(ctx context.Context) ([]store.OAuthProviderSettings, error)
UpdateOAuthProviderSettings(ctx context.Context, s store.OAuthProviderSettings) error
}
OAuthSettingsStore is the store surface the OAuth settings and sign-in handlers need for provider configuration (oauth_settings.go, this file). *store.DB satisfies this structurally.
type OIDCJWKSProvider ¶ added in v0.2.0
OIDCJWKSProvider serves the public half of the signing key pipeline jobs' OIDC tokens are signed with. *oidc.Manager satisfies it.
type OIDCKeyRotator ¶ added in v0.2.0
type OIDCKeyRotator interface {
RotateKey(ctx context.Context, retireAfter time.Duration) (oidc.RotationResult, error)
}
OIDCKeyRotator rotates the pipeline OIDC signing key. *oidc.Manager satisfies it. A separate interface from OIDCJWKSProvider, not a wider one: a fake in a JWKS-only test has no reason to implement rotation too.
type ObjectClientResolver ¶ added in v0.2.0
type ObjectClientResolver interface {
Client(ctx context.Context, targetID string) (*objectstore.Client, store.BackupTarget, error)
}
ObjectClientResolver builds a bucket client for a stored destination.
type ObservabilityStore ¶ added in v0.2.0
type ObservabilityStore interface {
GetObservabilitySettings(ctx context.Context) (store.ObservabilitySettings, error)
UpdateObservabilitySettings(ctx context.Context, s store.ObservabilitySettings) error
}
ObservabilityStore is the store surface GET/PUT /api/v1/settings/observability need: the single platform-wide row, always present, the same shape EmailSettingsStore has for its own row.
type OnboardingStore ¶
type OnboardingStore interface {
GetOnboardingState(ctx context.Context) (store.OnboardingState, error)
MarkOnboardingCompleted(ctx context.Context) error
SetOnboardingProgress(ctx context.Context, currentStep string, steps map[string]string) error
}
OnboardingStore is the store surface the /api/v1/onboarding routes need.
type Option ¶
type Option func(*Router)
Option configures optional Router behavior.
func WithACMEDefaultDirectory ¶ added in v0.2.0
WithACMEDefaultDirectory sets the CA directory enable-https uses when the caller does not ask for staging. Empty means Let's Encrypt production.
func WithAIAssistantSecrets ¶ added in v0.2.0
func WithAIAssistantSecrets(s AIAssistantSecrets) Option
WithAIAssistantSecrets enables PUT/DELETE /api/v1/settings/ai-assistant. Without one configured (the default), both return 501; GET works regardless, the same shape WithEmailSecrets establishes.
func WithAIEngine ¶ added in v0.2.0
WithAIEngine enables every /api/v1/ai/... chat session route. Without one configured (the default), they all return 501, the same "not configured" shape WithBuilder's absence produces for the build trigger route.
func WithAPIRateLimit ¶
WithAPIRateLimit enables a general per-actor rate limit across every requireAbility-gated route (api_rate_limit.go): read-tier (AbilityRead) requests get readPerMinute budget, everything else (write, write:sensitive, deploy, root) gets the stricter writePerMinute budget, keyed per bearer token, per session user, or per client IP for an unauthenticated caller. Either argument <= 0 disables that tier. Without this option (the default), the whole check is skipped: existing tests and any embedder that never opts in see unthrottled behavior, the same "nil is valid" shape WithSecretSetter's own absence already establishes. This package never reads the environment directly: cmd/levelrail/main.go reads APP_API_RATE_LIMIT_READ_RPM / APP_API_RATE_LIMIT_WRITE_RPM and calls this unconditionally with their resolved (env-or-default) values, so the real control plane is always protected even when an operator never sets either env var.
func WithAccessSource ¶
func WithAccessSource(s AccessSource) Option
WithAccessSource turns on GET /api/v1/apps/{name}/access.
func WithAgentCAFingerprint ¶ added in v0.2.0
WithAgentCAFingerprint sets the agent CA fingerprint returned with each new node join token, so the enrollment command can pin it.
func WithAlertNoise ¶ added in v0.2.0
func WithAlertNoise(a AlertNoise) Option
WithAlertNoise enables the silence, maintenance window and alert history routes.
func WithAlertRules ¶
func WithAlertRules(a AlertRules) Option
WithAlertRules enables POST/GET /api/v1/apps/{name}/alerts and DELETE /api/v1/apps/{name}/alerts/{id}. Without one configured (the default), all three routes return 501, the same "not configured" shape WithSecretSetter and WithTelemetryQuerier's absence already produce: this control plane still starts and serves everything else without an alerting.DB wired in.
func WithAllowInsecureLogin ¶ added in v0.2.0
WithAllowInsecureLogin permits plain-HTTP sign-in even when an https dashboard URL is configured.
func WithAppTeardownOptions ¶ added in v0.2.0
func WithAppTeardownOptions(opts ...application.Option) Option
WithAppTeardownOptions sets the application options (instance ID, network prefix) used to match containers when an app is deleted, so delete never touches containers another control plane created on a shared daemon.
func WithApprovalChatNotifier ¶ added in v0.2.0
func WithApprovalChatNotifier(n ApprovalChatNotifier) Option
WithApprovalChatNotifier enables posting an interactive Approve/Deny message (deploy_approval_chat_notify.go) when a deploy approval is requested, to every notification channel that opted into InteractiveApprovals. Without one, requestDeployApproval simply doesn't post anything, the same "optional signal" shape as WithDeployNotifier.
func WithAuditLogRetention ¶
WithAuditLogRetention overrides how long an audit_log row survives before PurgeOldAuditEntries removes it. Without one configured (or passed as 0), defaultAuditLogRetention (90 days) applies. Same "no hardcoded thresholds, use env vars" shape as WithPreviewTTL: this package never reads the environment directly, cmd/levelrail/main.go reads APP_AUDIT_LOG_RETENTION_DAYS and passes the parsed duration here.
func WithAuthEngine ¶ added in v0.2.0
func WithAuthEngine(e *authengine.Engine) Option
WithAuthEngine supplies the library auth engine. NewRouter builds a default one over the store database when none is given.
func WithAuthEngineMFA ¶ added in v0.2.0
func WithAuthEngineMFA(m *authengine.MFA) Option
WithAuthEngineMFA serves TOTP and passkeys through the library on the existing routes. A nil service is a no-op, which keeps the built-in handlers.
func WithAutoPlacement ¶ added in v0.2.0
WithAutoPlacement overrides whether handleCreateApp/handleCreateDatabase auto-place a create request that omits node_id onto the least-loaded registered node (scheduling.go's autoPlaceNode), instead of leaving it on this control plane's own local node. Defaults to true (NewRouter's own struct literal); cmd/levelrail/main.go reads APP_AUTO_PLACEMENT and calls this with false to disable it, the same "this package never reads the environment directly" convention WithSessionTTL's own doc comment establishes. An explicit node_id in a create request always overrides this regardless of its value, on or off.
func WithBackupDeleter ¶ added in v0.2.0
func WithBackupDeleter(d BackupDeleter) Option
WithBackupDeleter enables DELETE /api/v1/databases/{name}/backups/{historyId} and its app volume counterpart. Without one configured (the default), both routes return 501, the same "not configured" shape WithBackupDownloader's absence produces: deleting the stored object behind a backup needs the same live secretsManager to resolve a target's credentials that downloading or uploading one does.
func WithBackupDownloader ¶
func WithBackupDownloader(d BackupDownloader) Option
WithBackupDownloader enables GET /api/v1/databases/{name}/backups/{historyId}/download. Without one configured (the default), that route returns 501, the same "not configured" shape WithBackupRunner's absence produces: both need a live secretsManager to resolve a target's credentials, WithBackupRunner to upload with them, this to download with them.
func WithBackupProtection ¶ added in v0.2.0
func WithBackupProtection(p BackupProtection, st BackupProtectionStore) Option
WithBackupProtection enables the backup health, restore drill, volume backup policy and restore-to routes. Without it they return 501.
func WithBackupRunner ¶
func WithBackupRunner(r BackupRunner) Option
WithBackupRunner enables POST /api/v1/databases/{name}/backups. Without one configured (the default), that route returns 501, the same "not configured" shape WithBackupSecrets' absence produces; listing backup history (GET .../backups) works regardless, since it only reads store.BackupHistory rows a runner already wrote in the past, nothing about it needs a live runner today.
func WithBackupSecrets ¶
func WithBackupSecrets(s BackupSecretsSetter) Option
WithBackupSecrets enables POST /api/v1/backup-targets. Without one configured (the default), that route returns 501, the same "not configured" shape WithSecretSetter's absence produces; listing, getting, and deleting an already-connected backup target work regardless, since none of those need to write a credential.
func WithBackupTargetTester ¶
func WithBackupTargetTester(t BackupTargetTester) Option
WithBackupTargetTester enables POST /api/v1/backup-targets/{id}/test. Without one configured (the default), that route returns 501, the same "not configured" shape WithRegistryAuthTester's absence produces for registry credentials: both need a live secretsManager to resolve a stored credential before using it.
func WithBackupVerifier ¶
func WithBackupVerifier(v BackupVerifier) Option
WithBackupVerifier enables POST /api/v1/databases/{name}/backups/{historyId}/verify. Without one configured (the default), that route returns 501, the same "not configured" shape WithBackupRunner's absence produces: verifying needs the identical live secretsManager WithBackupRunner and WithBackupDownloader already depend on, to resolve a target's credentials and re-download the object. Listing past verification attempts (GET .../verifications) works regardless, the same "listing needs no live runner" reasoning WithBackupRunner's own doc comment gives for backup history.
func WithBaseBackupRunner ¶ added in v0.2.0
func WithBaseBackupRunner(r BaseBackupRunner) Option
WithBaseBackupRunner enables POST /api/v1/databases/{name}/base-backups. Without one configured (the default), that route returns 501, the same "not configured" shape WithBackupRunner's absence produces; listing base backup history (GET .../base-backups) works regardless, the same "listing needs no live runner" reasoning WithBackupRunner's own doc comment gives.
func WithBitbucketAppSecrets ¶
func WithBitbucketAppSecrets(s BitbucketAppSecrets) Option
WithBitbucketAppSecrets enables the Bitbucket App routes that read or write a credential (connect, connect-start, callback, repo/branch listing, use-as-source). Without one configured, those return 501; GET/DELETE /api/v1/bitbucket-app work regardless.
func WithBuilder ¶
WithBuilder enables POST /api/v1/apps/{name}/builds: a manual build trigger for an operator with no working git webhook configured (see internal/webhook.Config's own doc comment on why that path is deliberately static, single-app configuration). Without one configured (the default), that route returns 501, the same "not configured" shape WithSecretSetter/WithTelemetryQuerier/WithAlertRules absence already share. cmd/levelrail/main.go passes the same *deploy.Pipeline the git webhook receiver uses, when a BuildKit connection was successfully established at startup.
func WithCapacityForecastLookback ¶ added in v0.2.0
WithCapacityForecastLookback overrides how far back GET /api/v1/nodes/{id}/capacity-forecast looks for disk/memory history (handleNodeCapacityForecast). Without one configured (or passed as 0), defaultCapacityForecastLookback (14 days) applies. Same "no hardcoded thresholds, use env vars" shape as WithResourceRecommendationLookback: this package never reads the environment directly, cmd/levelrail/main.go reads APP_CAPACITY_FORECAST_LOOKBACK and passes the parsed duration here.
func WithCertExpiryWarningWindow ¶
WithCertExpiryWarningWindow overrides how far ahead of a certificate's expiry GET /api/v1/certificates starts reporting "expiring_soon" instead of "healthy" (see alerting.CertExpiryStatus). Without one configured (or passed as 0), alerting.DefaultCertExpiryWarningWindow (14 days) applies. Same "no hardcoded thresholds, use env vars" shape as WithSessionTTL: this package never reads the environment directly, cmd/levelrail/main.go reads APP_CERT_EXPIRY_WARNING_WINDOW and passes the parsed duration here, and to alerting.NewEngine for a kind=cert_expiry rule's own evaluation.
func WithCertRenewalTracking ¶ added in v0.2.0
func WithCertRenewalTracking(src CertObservationSource, stalledThreshold time.Duration) Option
WithCertRenewalTracking lets GET /api/v1/certificates report a stalled renewal from the observations kind=cert_expiry rules record. A zero threshold falls back to alerting.DefaultCertRenewalStalledThreshold.
func WithChangelog ¶ added in v0.2.0
WithChangelog supplies the entries GET /api/v1/changelog serves, parsed once at startup from the repo's own CHANGELOG.md (see cmd/levelrail's loadChangelog). Without one configured (the default, nil), that route answers an empty entries list rather than failing: a bare, non-Docker install that hasn't shipped CHANGELOG.md next to the binary yet just sees an empty "what's new" panel, not a broken one.
func WithCloneRestoreRunner ¶
func WithCloneRestoreRunner(r CloneRestoreRunner) Option
WithCloneRestoreRunner enables POST /api/v1/databases/{name}/restore-as-new. Without one configured (the default), that route returns 501, the same "not configured" shape WithRestoreRunner's absence produces; listing clone-restore history (GET .../clone-restores) works regardless, the same "listing needs no live runner" reasoning WithRestoreRunner's own doc comment gives.
func WithCloudflareDNSSecrets ¶
func WithCloudflareDNSSecrets(s CloudflareDNSSecrets) Option
WithCloudflareDNSSecrets enables PUT/DELETE /api/v1/settings/cloudflare-dns. Without one configured (the default), both return 501; GET works regardless, the same shape WithCloudflareTunnelSecrets establishes.
func WithCloudflareDNSTokenResolver ¶ added in v0.2.0
func WithCloudflareDNSTokenResolver(r CloudflareDNSTokenResolver) Option
WithCloudflareDNSTokenResolver enables GET/POST/PUT/DELETE .../dns-records whenever Cloudflare DNS is the configured provider: without one set (the default), those routes return 501 unless Route53 DNS is configured instead. Distinct from WithCloudflareDNSSecrets, which can only check whether a token is stored, not read it back.
func WithCloudflareTunnelSecrets ¶
func WithCloudflareTunnelSecrets(s CloudflareTunnelSecrets) Option
WithCloudflareTunnelSecrets enables PUT/DELETE /api/v1/settings/cloudflare-tunnel. Without one configured (the default), both return 501; GET works regardless, the same shape WithEmailSecrets establishes.
func WithComposeSecrets ¶
func WithComposeSecrets(s ComposeSecretStore) Option
WithComposeSecrets enables POST /api/v1/apps/{name}/compose to resolve a compose file's generatable SERVICE_ magic vars. Without one configured (the default), that endpoint still works for compose files with no such vars, and fails with a clear error for ones that need one.
func WithContainerLister ¶
func WithContainerLister(l ContainerLister) Option
WithContainerLister enables GET /api/v1/system/containers. Without one configured (the default), that route returns 501, the same "not configured" shape WithExecRuntime's own absence already has.
func WithControlPlaneBackupScheduleDisabled ¶ added in v0.2.0
WithControlPlaneBackupScheduleDisabled tells the doctor check that scheduled snapshots are switched off, so it reports unknown, not a warning.
func WithControlPlaneBackups ¶ added in v0.2.0
func WithControlPlaneBackups(m ControlPlaneBackupManager) Option
WithControlPlaneBackups enables the /api/v1/system/backups routes. Without one, they return 501.
func WithControlPlaneDR ¶ added in v0.2.0
func WithControlPlaneDR(dr ControlPlaneDR, material EscrowMaterialReader) Option
WithControlPlaneDR enables the /api/v1/system/control-plane-dr routes and the doctor's disaster recovery check. Without it the routes return 501.
func WithDBPinger ¶
WithDBPinger enables the database check on GET /api/v1/system/doctor. Without one configured (the default), that check reports unknown, the same "optional signal, absence is not an error" shape WithDockerPinger's own absence already has.
func WithDashboardCache ¶ added in v0.2.0
WithDashboardCache enables the short TTL cache behind the dashboard's aggregate endpoints and the docker disk usage warm-up. ttl <= 0 keeps every request live; the binary resolves APP_DASHBOARD_CACHE_TTL and _STALE.
func WithDashboardListenAddr ¶ added in v0.2.0
WithDashboardListenAddr tells the reverse proxy guide where the dashboard listens.
func WithDashboardURL ¶ added in v0.2.0
WithDashboardURL sets the base URL used for links in outbound notices.
func WithDataDir ¶
WithDataDir enables disk-usage reporting on GET /api/v1/system/status. path should be the same APP_DATA_DIR the control plane itself was started with. Without one configured (the default), the status response simply omits the two data-dir byte fields, the same "optional signal, absence is not an error" shape WithSecretSetter's own absence already has for secret-setting.
func WithDatabaseAccess ¶ added in v0.2.0
func WithDatabaseAccess(s DatabaseAccessStore, ttl dbaccess.TTLLimits) Option
WithDatabaseAccess enables database users, temporary credentials and the network controls. ttl bounds temporary credential lifetimes.
func WithDatabaseUpgrader ¶ added in v0.2.0
func WithDatabaseUpgrader(u DatabaseUpgrader) Option
WithDatabaseUpgrader enables the database upgrade routes; without it they return 501.
func WithDeleteTeardownTimeout ¶ added in v0.2.0
WithDeleteTeardownTimeout bounds how long DELETE /apps/{name} waits for containers to stop.
func WithDemoMode ¶
func WithDemoMode(cfg DemoConfig) Option
WithDemoMode puts the Router in read-only demo mode: default-deny write gate, read elevation for the visitor account, noindex headers and the demo routes.
func WithDeployApprovalTTL ¶ added in v0.2.0
WithDeployApprovalTTL overrides how long a pending deploy approval (deploy_approvals.go) stays decidable before it's treated as expired. Without one configured (or passed as 0), defaultDeployApprovalTTL (24 hours) applies. Same "no hardcoded thresholds, use env vars" shape as WithAuditLogRetention: this package never reads the environment directly, cmd/levelrail/main.go reads APP_DEPLOY_APPROVAL_TTL and passes the parsed duration here.
func WithDeployGate ¶ added in v0.2.0
func WithDeployGate(s DeployGateStore, defaults deploysafety.Effective) Option
WithDeployGate enables the gate timeline, deploy safety settings and rollback target endpoints, resolving settings over defaults.
func WithDeployLogQuerier ¶
func WithDeployLogQuerier(s DeployLogQuerier) Option
WithDeployLogQuerier enables a finished deploy attempt's full log replay on GET /api/v1/apps/{name}/deploys/{deployId}/logs. Without one configured (the default), that route returns 501 for an attempt that has already finished; an in-progress attempt's live tail is unaffected (see WithDeployRecorder). cmd/levelrail/main.go passes the same *telemetry.DB internal/deploylog.Recorder writes to.
func WithDeployMaxConcurrent ¶ added in v0.2.0
WithDeployMaxConcurrent caps how many deploys run at once across all apps; deploys over the cap wait as queued. Zero or less means unlimited.
func WithDeployNotifier ¶
func WithDeployNotifier(n DeployNotifier) Option
WithDeployNotifier enables the actual send: without one configured (the default), a deploy attempt still finishes and is still recorded exactly as it is today, it just never dispatches a notification, even if WithDeployNotifyTargets has targets configured. Kept as a separate option from WithDeployNotifyTargets on purpose, the same "listing doesn't need a live runner" split WithBackupRunner/WithRestoreRunner already establish: a control plane can serve deploy-notify-target CRUD without necessarily having a dispatcher wired (e.g. in a test), and vice versa cmd/levelrail/main.go always wires both together from the same *alerting.DeployDispatcher, which itself embeds the *alerting.DB that WithDeployNotifyTargets is given.
func WithDeployNotifyTargets ¶
func WithDeployNotifyTargets(t DeployNotifyTargets) Option
WithDeployNotifyTargets enables POST/GET /api/v1/apps/{name}/deploy-notify-targets and DELETE .../deploy-notify-targets/{id}: CRUD for deploy-outcome notification destinations, the sibling surface to WithAlertRules for wave-2 deploy-outcome notifications. Without one configured (the default), all three routes return 501, the same "not configured" shape WithAlertRules' own absence produces.
func WithDeployRecorder ¶
WithDeployRecorder enables live build-log fan-out for the manual build trigger (handleTriggerBuild) and the in-progress side of GET /api/v1/apps/{name}/deploys/{deployId}/logs. Without one configured (the default), handleTriggerBuild falls back to build.SlogProgress (no persisted log, matching this package's pre-existing behavior) and the SSE log route returns 501 for any attempt still in progress. r must be the exact same *deploylog.Recorder instance passed to internal/webhook.New when a webhook handler is also wired: see that package's own doc comment for why a shared instance, not two independent ones, is required for a webhook-triggered attempt's live log to be visible through this router's SSE route.
func WithDeploySafety ¶ added in v0.2.0
func WithDeploySafety(s DeploySafetyStore, resolver docker.ImageResolver) Option
WithDeploySafety enables freeze windows, the stale-deploy guard and digest resolution for image deploys. resolver may be nil.
func WithDeviceLoginNotifier ¶ added in v0.2.0
func WithDeviceLoginNotifier(n DeviceLoginNotifier) Option
WithDeviceLoginNotifier enables the opt-in notice sent through channels with NotifyDeviceLogin when a CLI device login is waiting.
func WithDockerDiskUsager ¶
func WithDockerDiskUsager(u DockerDiskUsager) Option
WithDockerDiskUsager enables the docker_disk_usage field on GET /api/v1/system/status. Without one configured (the default), that field is simply omitted, the same "optional signal, absence is not an error" shape WithDockerPinger's own absence already has.
func WithDockerGuard ¶ added in v0.2.0
func WithDockerGuard(c DockerGuardController) Option
WithDockerGuard enables GET/PUT /api/v1/system/docker-guard, its doctor check and its attention item. Without it those report the guard as unknown.
func WithDockerPinger ¶
func WithDockerPinger(p DockerPinger) Option
WithDockerPinger enables Docker daemon connectivity reporting on GET /api/v1/system/status. Without one configured (the default), the response's DockerConnected field simply stays false, the same "optional signal, absence is not an error" shape WithDataDir and WithSecretSetter's own absence already have.
func WithDockerPruner ¶
func WithDockerPruner(p DockerPruner) Option
WithDockerPruner enables POST /api/v1/system/prune. Without one configured (the default), that route returns 501, the same "not configured" shape WithBuilder's own absence produces.
func WithDoctorAgentAdvertise ¶ added in v0.2.0
WithDoctorAgentAdvertise tells the agent_advertise_reachability check which address a real agent would dial: APP_AGENT_ADVERTISE_HOST and the port cmd/levelrail/main.go's own agentAddr() binds the agent gRPC service on. Empty host or zero port makes that check report unknown.
func WithDoctorClockSkewWarnAge ¶ added in v0.2.0
WithDoctorClockSkewWarnAge overrides how far this host's clock may drift from the remote HTTP Date header the clock_skew check compares against before it warns. Zero keeps defaultDoctorClockSkewWarnAge.
func WithDoctorDiskIOWarnLatency ¶ added in v0.2.0
WithDoctorDiskIOWarnLatency overrides the write+fsync latency the disk_io_latency check warns above, in place of defaultDoctorDiskIOWarnLatency. Zero keeps that default.
func WithDoctorDiskWarningBytes ¶
WithDoctorDiskWarningBytes overrides the free-space floor GET /api/v1/system/doctor's disk_space check warns below. Without one configured (or passed as 0), defaultDoctorDiskWarningBytes (1GiB) applies. Same "no hardcoded thresholds, use env vars" shape as WithCertExpiryWarningWindow: this package never reads the environment directly, cmd/levelrail/main.go reads APP_DOCTOR_DISK_WARNING_BYTES and passes the parsed value here.
func WithDoctorIngressPorts ¶ added in v0.2.0
WithDoctorIngressPorts overrides the two ports GET /api/v1/system/ doctor's port_<n> checks probe, in place of the literal 80/443 defaultDoctorHTTPPort/defaultDoctorHTTPSPort ports. cmd/levelrail/ main.go passes the same APP_INGRESS_HTTP_ADDR/APP_INGRESS_HTTPS_ADDR- derived ports already threaded to ingressreconcile.WithHTTPListenAddr/ WithListenAddr, so doctor stays accurate for an instance running its ingress on non-default ports. Either argument being 0 keeps that port's own default.
func WithDoctorMasterKeyRotationWarnAge ¶
WithDoctorMasterKeyRotationWarnAge overrides the age GET /api/v1/system/doctor's master_key_rotation check warns beyond, the same env-var-overridable-threshold shape WithDoctorDiskWarningBytes already establishes for disk_space.
func WithDoctorMinCPUCount ¶ added in v0.2.0
WithDoctorMinCPUCount overrides the recommended-minimum CPU core count the cpu check warns below. Zero keeps defaultDoctorMinCPUCount.
func WithDoctorMinRAMBytes ¶ added in v0.2.0
WithDoctorMinRAMBytes overrides the recommended-minimum total memory the ram check warns below. Zero keeps defaultDoctorMinRAMBytes.
func WithDoctorNetworkTimeout ¶ added in v0.2.0
WithDoctorNetworkTimeout overrides the bounded overall timeout GET /api/v1/system/doctor's network checks (public_ip, external_reachability_*, acme_reachability, clock_skew) share, the same "no hardcoded thresholds" shape as WithDoctorDiskWarningBytes. Zero keeps defaultDoctorNetworkTimeout.
func WithDoctorPublicIPEndpoint ¶ added in v0.2.0
WithDoctorPublicIPEndpoint overrides the plain-text-IP endpoint the public_ip check queries, in place of defaultDoctorPublicIPEndpoint. Lets an operator behind an egress proxy, or one who simply distrusts a third-party default, point this at their own endpoint.
func WithDomainBasicAuthSecrets ¶
func WithDomainBasicAuthSecrets(s DomainBasicAuthSecrets) Option
WithDomainBasicAuthSecrets enables PUT/DELETE /api/v1/apps/{name}/domains/{domain}/auth. Without one configured (the default), both return 501; GET works regardless, the same shape WithCloudflareTunnelSecrets establishes.
func WithDomainTLSCertSecrets ¶
func WithDomainTLSCertSecrets(s DomainTLSCertSecrets) Option
WithDomainTLSCertSecrets enables PUT/DELETE /api/v1/apps/{name}/domains/{domain}/tls-cert. Without one configured (the default), both return 501; GET works regardless, the same shape WithDomainBasicAuthSecrets establishes.
func WithEmailSecrets ¶
func WithEmailSecrets(s EmailSecretsStore) Option
WithEmailSecrets enables PUT /api/v1/settings/email. Without one configured (the default), that route returns 501; GET works regardless.
func WithEmailSender ¶
WithEmailSender enables the actual send behind POST /api/v1/auth/forgot-password. Without one, that route still returns its generic success response, it just never sends anything.
func WithErrorStore ¶
func WithErrorStore(s ErrorStore) Option
WithErrorStore turns on the Sentry-compatible receiver and the error routes.
func WithExecRuntime ¶
func WithExecRuntime(r NodeRuntimeResolver) Option
WithExecRuntime enables POST /apps/{name}/exec (exec.go's handleExecApp). Without one configured (the default), that route returns 501, the same "not configured" shape WithDockerPruner's absence produces: a control plane can run every other route with no resolver wired in, exec is the one action that needs live node routing (NodeRuntimeResolver's own doc comment).
func WithExposure ¶ added in v0.2.0
func WithExposure(m *exposure.Manager, s ExposureStore) Option
WithExposure enables the exposure audit and its guided restrictions. Without it, the exposure routes return 501 and the doctor group is absent.
func WithFirewallRequiredPorts ¶ added in v0.2.0
WithFirewallRequiredPorts overrides the ports POST /api/v1/firewall-rules refuses to deny or CIDR-restrict, defaulting to firewall.DefaultRequiredPorts. Pass this instance's actually configured management API, agent gRPC, and ingress ports whenever any of them were moved off their default address: a lockout check against the wrong port number is no check at all.
func WithFixit ¶
func WithFixit(s FixitStore) Option
WithFixit enables the fix-it engine routes and the DB-backed advertise host.
func WithGPUHostDiagnoser ¶ added in v0.2.0
func WithGPUHostDiagnoser(d GPUHostDiagnoser) Option
WithGPUHostDiagnoser adds the detailed host GPU checks to the doctor report. Without it the doctor shows only what nodes report.
func WithGitHubAppManifestConfig ¶
func WithGitHubAppManifestConfig(cfg githubapp.ManifestConfig) Option
WithGitHubAppManifestConfig overrides the permissions/events a fresh App registration requests (githubapp.BuildManifest's own doc comment). Without one configured, NewRouter defaults to githubapp.DefaultManifestConfig(), the same request this codebase has always sent.
func WithGitHubAppSecrets ¶
func WithGitHubAppSecrets(s GitHubAppSecrets) Option
WithGitHubAppSecrets enables the GitHub App routes that read or write a credential (manifest callback, installation callback, repo/branch listing). Without one configured, those return 501; GET/DELETE /api/v1/github-app work regardless.
func WithGitLabAppSecrets ¶
func WithGitLabAppSecrets(s GitLabAppSecrets) Option
WithGitLabAppSecrets enables the GitLab App routes that read or write a credential (connect, connect-start, callback, project listing, use-as-source). Without one configured, those return 501; GET/DELETE /api/v1/gitlab-app work regardless.
func WithGitSourceSecrets ¶
func WithGitSourceSecrets(s GitSourceSecrets) Option
WithGitSourceSecrets enables PUT /api/v1/apps/{name}/git-source and the git-push webhook route. Without one configured (the default), both return 501; listing/getting/deleting a git source works regardless, since neither needs to resolve a credential.
func WithGiteaAppSecrets ¶ added in v0.2.0
func WithGiteaAppSecrets(s GiteaAppSecrets) Option
WithGiteaAppSecrets enables the Gitea App routes that read or write a credential (connect, connect-start, callback, repo/branch listing, use-as-source). Without one configured, those return 501; GET/DELETE /api/v1/gitea-app work regardless.
func WithHSTS ¶ added in v0.2.0
WithHSTS enables the Strict-Transport-Security response header. Without it (the default), Strict-Transport-Security is never sent, see Router.hstsEnabled's own doc comment for why that's the safe default.
func WithHTTPSEnableLimits ¶ added in v0.2.0
WithHTTPSEnableLimits sets how many production enable attempts are allowed per hour (a guard against burning Let's Encrypt's failed-validation limit) and how long a certificate may stay pending before it is reported failed. Zero values keep the defaults.
func WithHostFirewallRunner ¶ added in v0.2.0
func WithHostFirewallRunner(run func(ctx context.Context, name string, args ...string) ([]byte, error), lookPath func(string) (string, error)) Option
WithHostFirewallRunner replaces how the host firewall endpoints run and find ufw, so tests never touch the real firewall.
func WithImageLister ¶
func WithImageLister(l ImageLister) Option
WithImageLister enables GET /api/v1/apps/{name}/images. Without one configured (the default), that route returns an empty list rather than 501 or 404: the deploy trigger form's manual text input always works regardless, so a missing image lister is "no suggestions available" (an empty array), not a request error, the same "optional signal, absence is not an error" shape WithDockerPinger's own absence already has.
func WithIngressPortOwner ¶ added in v0.2.0
func WithIngressPortOwner(o IngressPortOwner) Option
WithIngressPortOwner lets GET /api/v1/system/doctor's port_<n> checks recognize a bind failure caused by this control plane's own embedded ingress (internal/ingress.Driver) as expected rather than a real problem. Without one configured (the default), a bound port always reports fail, the same behavior this check had before ingress ownership was distinguishable.
func WithInviteTTL ¶
WithInviteTTL overrides how long a team invite stays acceptable before GetInviteByHash's expiry check rejects it. Without one configured (or passed as 0), defaultInviteTTL (7 days) applies. Same "no hardcoded thresholds, use env vars" shape as WithPreviewTTL: this package never reads the environment directly, cmd/levelrail/main.go reads APP_INVITE_TTL and passes the parsed duration here.
func WithJobLimits ¶ added in v0.2.0
WithJobLimits sets the per-app job count cap (APP_JOBS_MAX_PER_APP).
func WithLoadBalancers ¶ added in v0.2.0
func WithLoadBalancers(s LoadBalancerStore, registry *loadbalancer.Registry, stats loadbalancer.StatsSource) Option
WithLoadBalancers enables the /api/v1/apps/{name}/loadbalancer routes. registry and stats feed the live status route and may be nil.
func WithLogBroadcaster ¶
func WithLogBroadcaster(b *telemetry.LogBroadcaster) Option
WithLogBroadcaster enables GET /api/v1/apps/{name}/logs/stream, the live-tailing counterpart to WithTelemetryQuerier's historical GET .../logs. Without one configured (the default), that route returns 501, the same "not configured" shape WithDeployRecorder's absence produces for the in-progress side of a deploy attempt's log. Deliberately a separate option from WithTelemetryQuerier even though both are telemetry-flavored and cmd/levelrail/main.go always configures them together in practice: a control plane could in principle want historical log search without live tailing (or the reverse), and keeping them as two options leaves that possible instead of one silently implying the other. b must be the exact same *telemetry.LogBroadcaster instance passed to telemetry.NewLogCollector: see that constructor's own doc comment for why a shared instance, not two independent ones, is required for a line StreamOne receives from Docker to ever reach a viewer connected through this router's SSE route.
func WithLogBudgetStore ¶
func WithLogBudgetStore(s LogBudgetStore) Option
WithLogBudgetStore turns on the log budget and usage routes.
func WithLogPipelineStore ¶
func WithLogPipelineStore(s LogPipelineStore) Option
WithLogPipelineStore turns on the app log pipeline routes.
func WithLoginCodeKey ¶ added in v0.2.0
WithLoginCodeKey peppers stored sign-in code hashes with a key derived from the control plane's own secret, so a database copy alone cannot brute-force a live code.
func WithMajorUpgrader ¶ added in v0.2.0
func WithMajorUpgrader(u MajorUpgrader) Option
WithMajorUpgrader enables the major upgrade routes; without it they return 501.
func WithMasterKeyRotation ¶
func WithMasterKeyRotation(r MasterKeyRotator, masterKeyFilePath string) Option
WithMasterKeyRotation enables POST /api/v1/system/master-key/rotate and the doctor's rotation-age check. masterKeyFilePath should be the on-disk path the running control plane loaded its master key from, or "" if it came from APP_MASTER_KEY instead: see MasterKeyRotator's own doc comment for what that distinction changes about a rotation's response. Without this option configured (the default), the route returns 501, the same shape WithSecretSetter's own absence produces.
func WithMasterKeyWrapper ¶
func WithMasterKeyWrapper(w secrets.KeyWrapper) Option
WithMasterKeyWrapper makes rotation persist the new key wrapped by the external key service.
func WithMeshSettings ¶ added in v0.2.0
func WithMeshSettings(s MeshSettingsStore) Option
WithMeshSettings enables GET/PUT /api/v1/mesh/settings.
func WithMinAgentVersion ¶ added in v0.2.0
WithMinAgentVersion flags nodes whose agent reports an older version. Empty disables the check.
func WithModels ¶ added in v0.2.0
func WithModels(s ModelService) Option
WithModels enables the /api/v1/models routes. Without it they return 501.
func WithMultiNode ¶ added in v0.2.0
func WithMultiNode(s PlacementStore, cfg nodemove.Config, meshPortMin, meshPortMax int) Option
WithMultiNode enables persisted node moves, drains, labels and selectors. Without it those routes return 501 and drain keeps no history.
func WithNetworkShareSecrets ¶ added in v0.2.0
func WithNetworkShareSecrets(s NetworkShareSecretsSetter) Option
WithNetworkShareSecrets enables POST/PUT /api/v1/network-shares for a cifs share. Without one configured (the default), those return 501; GET, DELETE, and an nfs share's create/update work regardless, the same shape WithRegistryCredentialSecrets establishes.
func WithNewDeviceApproval ¶ added in v0.2.0
WithNewDeviceApproval pauses a password login from an untrusted browser until another live session of the account approves it.
func WithNodeAlertThresholds ¶
WithNodeAlertThresholds sets the thresholds GET /api/v1/nodes/{id} uses for its live alert_status section, the same values cmd/levelrail/main.go already resolves (from APP_ALERT_PATCH_STATUS_THRESHOLD, APP_ALERT_NODE_DISK_SPACE_THRESHOLD_PERCENT, APP_ALERT_NODE_CPU_THRESHOLD_PERCENT, APP_ALERT_NODE_MEMORY_THRESHOLD_BYTES) and passes to alerting.NewEngine, so a rule's scheduled evaluation and a node's on-demand check never disagree.
func WithNodeCertThresholds ¶ added in v0.2.0
WithNodeCertThresholds sets when a node's agent certificate is reported as expiring (warning) and critical. Zero keeps the alerting defaults.
func WithNodeJoinTokenTTL ¶ added in v0.2.0
WithNodeJoinTokenTTL sets how long a dashboard or CLI join token stays redeemable, clamped to [1m, 24h]. Zero keeps the 15 minute default.
func WithNodeProviderSecrets ¶ added in v0.2.0
func WithNodeProviderSecrets(s NodeProviderSecrets) Option
WithNodeProviderSecrets enables POST /api/v1/node-providers and every node-providers/{provider}/... route. Without it (the default), those routes return 501, the same shape WithCloudflareDNSSecrets establishes for its own credential.
func WithNodeProvisionerFactory ¶ added in v0.2.0
func WithNodeProvisionerFactory(f NodeProvisionerFactory) Option
WithNodeProvisionerFactory overrides how a NodeProvisioner is built from a provider name and resolved token, for this package's own tests. Production callers leave this unset; NewRouter's default, defaultNodeProvisionerFactory, builds real internal/provision clients.
func WithNodeProvisions ¶ added in v0.2.0
func WithNodeProvisions(s NodeProvisionStore) Option
WithNodeProvisions overrides the node provision store NewRouter otherwise wires to s (the *store.DB passed to NewRouter, which satisfies NodeProvisionStore structurally). This package's own tests use it to inject a store that fails a specific call, for the half-succeeded-write path handleCreateNodeProvision must handle.
func WithNodeSessionCloser ¶ added in v0.2.0
func WithNodeSessionCloser(c NodeSessionCloser) Option
WithNodeSessionCloser lets certificate revocation close the node's live session immediately.
func WithNotificationChannelTester ¶
func WithNotificationChannelTester(t NotificationChannelTester) Option
WithNotificationChannelTester enables the test-send routes: a real send, not just a format check. Without one, they return 501.
func WithNotificationChannels ¶
func WithNotificationChannels(c NotificationChannels) Option
WithNotificationChannels enables the notification-channel CRUD routes. Without one configured (the default), they return 501.
func WithNotificationDeliveries ¶
func WithNotificationDeliveries(d NotificationDeliveryStore) Option
WithNotificationDeliveries enables the delivery-history route and records a delivery row for every existing-channel test-send. Without one, the deliveries route returns 501 and test-send simply skips recording.
func WithOAuthSecrets ¶
func WithOAuthSecrets(s OAuthSecrets) Option
WithOAuthSecrets enables OAuth sign-in end to end. Without one configured (the default), those routes return 501, the same "not configured" shape WithSecretSetter's absence produces.
func WithOrphanedContainerManager ¶ added in v0.2.0
func WithOrphanedContainerManager(m OrphanedContainerManager) Option
WithOrphanedContainerManager enables POST /api/v1/system/containers/{name}/stop and .../remove. Without one configured (the default), both routes return 501, the same "not configured" shape WithOrphanedVolumeManager's absence produces.
func WithOrphanedVolumeManager ¶ added in v0.2.0
func WithOrphanedVolumeManager(m OrphanedVolumeManager) Option
WithOrphanedVolumeManager enables GET /api/v1/system/volumes/orphaned and POST /api/v1/system/volumes/orphaned/cleanup. Without one configured (the default), both routes return 501, the same "not configured" shape WithDockerPruner's absence produces.
func WithPITRRestoreRunner ¶ added in v0.2.0
func WithPITRRestoreRunner(r PITRRestoreRunner) Option
WithPITRRestoreRunner enables POST /api/v1/databases/{name}/pitr-restore and GET /api/v1/databases/{name}/pitr's own live window computation. Without one configured (the default), the restore route returns 501 and the status route reports enabled/enabled_at only, no window: the same "not configured" shape WithRestoreRunner's absence produces.
func WithPipelines ¶ added in v0.2.0
func WithPipelines(st PipelineStore, runner PipelineRunner) Option
WithPipelines enables the pipeline endpoints. runner may be nil, in which case definitions can be edited but starting, cancelling, and re-running return 501.
func WithPreviewLimits ¶ added in v0.2.0
func WithPreviewLimits(l PreviewLimits) Option
WithPreviewLimits sets the per-app and global preview caps (cmd/levelrail reads APP_PREVIEW_ENV_MAX_PER_APP and APP_PREVIEW_ENV_MAX_TOTAL).
func WithPreviewStuckAfter ¶ added in v0.2.0
WithPreviewStuckAfter sets how long a preview may stay in deploying before the startup sweep marks it failed. Zero keeps the default.
func WithPreviewTTL ¶
WithPreviewTTL overrides how long a preview environment can go without a webhook update before SweepStalePreviewEnvironments tears it down. Without one configured (or passed as 0), defaultPreviewTTL (7 days) applies. Same "no hardcoded thresholds, use env vars" shape as WithCertExpiryWarningWindow: this package never reads the environment directly, cmd/levelrail/main.go reads APP_PREVIEW_TTL and passes the parsed duration here.
func WithPublicHost ¶
WithPublicHost sets the IP or hostname GET /api/v1/apps/{name}/domains/{domain}/check tells an operator to point their DNS record at (domain_check.go's advertisedHost). Without one configured (the default), that handler falls back to a best-effort guess from the request's own Host header instead of failing: this package never reads the environment directly, cmd/levelrail/main.go reads APP_PUBLIC_HOST and passes it here, the same shape WithCertExpiryWarningWindow already follows for its own env var.
func WithPublicHostSource ¶ added in v0.2.0
WithPublicHostSource records how the public host was found ("env", "detected", "disabled" or "none"), shown on the ingress settings page.
func WithPushVAPIDPublicKey ¶ added in v0.2.0
WithPushVAPIDPublicKey enables browser push notifications: GET .../push-subscriptions/vapid-public-key returns publicKey, and POST .../push-subscriptions accepts new registrations. Without one configured (the default, no master key set), both return 501: the VAPID private key half can only ever be stored through secretsManager.
func WithReadinessProbes ¶ added in v0.2.0
func WithReadinessProbes(p ReadinessProbes) Option
WithReadinessProbes enables the database, migration and engine checks on GET /readyz.
func WithReconcileNudger ¶ added in v0.2.0
func WithReconcileNudger(n ReconcileNudger) Option
WithReconcileNudger lets desired-state-changing handlers (app/database create, stop, start, restart, delete) request an immediate reconcile pass right after they save, instead of every such action waiting up to a full resyncInterval to visibly take effect. Without one configured (the default), those handlers still work exactly as before: the resync ticker and Docker's own event stream are what converge desired and observed state regardless.
func WithRegistryAuthTester ¶
func WithRegistryAuthTester(t RegistryAuthTester) Option
WithRegistryAuthTester enables POST /api/v1/registry-credentials/{id}/test. Without one configured (the default), that route returns 501, the same shape WithDockerPinger's own absence produces for GET /api/v1/system/status.
func WithRegistryCatalogSecrets ¶ added in v0.2.0
func WithRegistryCatalogSecrets(s RegistryCatalogSecrets) Option
WithRegistryCatalogSecrets enables GET /api/v1/registry/repositories and GET /api/v1/registry/tags. Without one configured (the default), both return 501, the same shape WithRegistrySecrets establishes.
func WithRegistryCredentialSecrets ¶
func WithRegistryCredentialSecrets(s RegistryCredentialSecretsSetter) Option
WithRegistryCredentialSecrets enables POST /api/v1/registry-credentials. Without one configured (the default), that route returns 501; GET and DELETE work regardless, the same shape WithBackupSecrets establishes.
func WithRegistrySecrets ¶
func WithRegistrySecrets(s RegistrySecrets) Option
WithRegistrySecrets enables PUT/DELETE /api/v1/settings/registry. Without one configured (the default), both return 501; GET works regardless, the same shape WithCloudflareTunnelSecrets establishes.
func WithRequestLogThresholds ¶ added in v0.2.0
WithRequestLogThresholds sets requestLoggingMiddleware's Warn/Error duration bands. Either argument <= 0 keeps that band's own default. cmd/levelrail/main.go resolves APP_SLOW_REQUEST_THRESHOLD/ APP_CRITICAL_REQUEST_THRESHOLD and calls this unconditionally, the same "no hardcoded thresholds" convention WithSessionTTL's own doc comment establishes.
func WithRequestSummaryWindow ¶ added in v0.2.0
WithRequestSummaryWindow sets the lookback of the request summary attached to GET /api/v1/apps/{name}; non-positive keeps the 5 minute default.
func WithResourceRecommendationLookback ¶
WithResourceRecommendationLookback overrides how far back GET /api/v1/apps/{name}/resource-recommendation looks for usage history (handleAppResourceRecommendation). Without one configured (or passed as 0), defaultResourceRecommendationLookback (7 days) applies. Same "no hardcoded thresholds, use env vars" shape as WithSessionTTL/ WithCertExpiryWarningWindow: this package never reads the environment directly, cmd/levelrail/main.go reads APP_RESOURCE_RECOMMENDATION_LOOKBACK and passes the parsed duration here.
func WithRestoreRunner ¶
func WithRestoreRunner(r RestoreRunner) Option
WithRestoreRunner enables POST /api/v1/databases/{name}/restore. Without one configured (the default), that route returns 501, the same "not configured" shape WithBackupRunner's absence produces; listing restore history (GET .../restores) works regardless, the same "listing needs no live runner" reasoning WithBackupRunner's own doc comment gives for backup history.
func WithRoute53DNSCredentialResolver ¶ added in v0.2.0
func WithRoute53DNSCredentialResolver(r Route53DNSCredentialResolver) Option
WithRoute53DNSCredentialResolver is the same shape as WithCloudflareDNSTokenResolver for the Route53 access key pair.
func WithRoute53DNSSecrets ¶ added in v0.2.0
func WithRoute53DNSSecrets(s Route53DNSSecrets) Option
WithRoute53DNSSecrets enables PUT/DELETE /api/v1/settings/route53-dns. Without one configured (the default), both return 501; GET works regardless, the same shape WithCloudflareDNSSecrets establishes for its own, independent ACME DNS-01 provider.
func WithSSHNodeProvisions ¶ added in v0.2.0
func WithSSHNodeProvisions(s SSHNodeProvisionStore) Option
WithSSHNodeProvisions overrides the SSH node provision store NewRouter otherwise wires to s (the *store.DB passed to NewRouter, which satisfies SSHNodeProvisionStore structurally), the same "seam for a failing fake" shape WithNodeProvisions establishes for the cloud path.
func WithSSHProvisioner ¶ added in v0.2.0
func WithSSHProvisioner(p SSHProvisioner) Option
WithSSHProvisioner overrides the SSH provisioner NewRouter otherwise defaults to (sshprovision.New()), for this package's own tests: a fake that never dials a real network.
func WithScheduledTaskRunner ¶
func WithScheduledTaskRunner(r ScheduledTaskRunner) Option
WithScheduledTaskRunner enables POST /api/v1/apps/{name}/scheduled-tasks/{id}/run. Without one configured (the default), that route returns 501: scheduled task CRUD still works either way (rt.scheduledTasks is always set), only actually running one on demand needs this. r should be the exact same *scheduledtask.Runner instance cmd/levelrail/main.go wires into scheduledtask.NewScheduler, the same "construct once, share by reference" reasoning WithBackupRunner's own doc comment gives for backupRunner.
func WithSecretBinding ¶ added in v0.2.0
func WithSecretBinding(b SecretBinder) Option
WithSecretBinding enables GET /api/v1/system/secrets/binding, POST /api/v1/system/secrets/rebind, the doctor's secret_binding check, and the automatic rebind after a master key rotation.
func WithSecretRotationWarnAge ¶ added in v0.2.0
WithSecretRotationWarnAge overrides how old a secret's last-set value can get before it is flagged as due for rotation (GET /apps/{name}/secrets, GET .../env/all, and the doctor's stale_secrets check). Without one configured (or passed as 0), defaultSecretRotationWarnAge (90 days) applies. Same "no hardcoded thresholds, use env vars" shape as WithAuditLogRetention: this package never reads the environment directly, cmd/levelrail/main.go reads APP_SECRET_ROTATION_WARN_DAYS and passes the parsed duration here.
func WithSecretSetter ¶
func WithSecretSetter(s SecretSetter) Option
WithSecretSetter enables PUT /api/v1/apps/{name}/secrets/{key}. Without one configured (the default), that route returns 501: an operator running Levelrail without APP_MASTER_KEY set gets a clear "not configured" response instead of the route not existing at all or silently discarding the value.
func WithSelfUpgrade ¶ added in v0.2.0
func WithSelfUpgrade(s SelfUpgradeStore, launch SelfUpgradeLauncher) Option
WithSelfUpgrade enables the self-upgrade plan, start and attempts routes. launch may be nil to use systemd-run on a root host.
func WithServiceVolumeBackupRunner ¶
func WithServiceVolumeBackupRunner(r ServiceVolumeBackupRunner) Option
WithServiceVolumeBackupRunner enables POST /api/v1/apps/{name}/volumes/{volume}/backups. Without one configured (the default), that route returns 501, the same "not configured" shape WithBackupRunner's absence produces; listing history and reading the schedule work regardless, the same "no live runner needed" reasoning WithBackupRunner's own doc comment gives.
func WithServiceVolumeRestoreRunner ¶
func WithServiceVolumeRestoreRunner(r ServiceVolumeRestoreRunner) Option
WithServiceVolumeRestoreRunner enables POST /api/v1/apps/{name}/volumes/{volume}/restore. Without one configured (the default), that route returns 501, the same "not configured" shape WithRestoreRunner's absence produces.
func WithSessionTTL ¶
WithSessionTTL overrides how long a session cookie stays valid. Without one configured, defaultSessionTTL (24h) applies. The project's "no hardcoded thresholds, use env vars" rule is honored one layer up, at cmd/levelrail/main.go, which reads APP_SESSION_TTL and passes the parsed duration here; this package itself never reads the environment directly (NewRouter takes everything as constructor args, matching every other option here).
func WithStaleSecretCounter ¶ added in v0.2.0
func WithStaleSecretCounter(c StaleSecretCounter) Option
WithStaleSecretCounter enables the stale_secrets check on GET /api/v1/system/doctor. Without one configured (the default), that check reports unknown, the same "optional signal, absence is not an error" shape WithDBPinger's own absence already has.
func WithStandaloneSafety ¶ added in v0.2.0
func WithStandaloneSafety(s StandaloneSafety) Option
WithStandaloneSafety sets the control and ingress ports standalone domain targets are checked against.
func WithStaticOrphanGrace ¶
WithStaticOrphanGrace sets how old an orphaned static site must be before the sweep removes it. Zero keeps the default.
func WithStaticRootDir ¶
WithStaticRootDir sets the directory static deploys publish under, so a rollback can find a past deploy's tree again.
func WithStatusPage ¶ added in v0.2.0
func WithStatusPage(db StatusPageDB, cfg statuspage.Config, perMinute int) Option
WithStatusPage enables the status page management routes, the public page and the health sampler (see RunStatusPageSampler). perMinute is the per-client-IP budget on public reads.
func WithStatusPageViewer ¶ added in v0.2.0
func WithStatusPageViewer(st StatusPageStore, v StatusPageViewer, perMinute int) Option
WithStatusPageViewer wires a custom view builder, for tests.
func WithStorage ¶ added in v0.2.0
func WithStorage(d StorageDeps) Option
WithStorage enables the /api/v1/storage and /api/v1/log-archive routes. Without it they return 501.
func WithTelemetryQuerier ¶
func WithTelemetryQuerier(q TelemetryQuerier) Option
WithTelemetryQuerier enables GET /api/v1/apps/{name}/metrics and GET /api/v1/apps/{name}/logs. Without one configured, both routes return 501, the same "not configured" shape WithSecretSetter's absence produces, rather than the routes not existing at all or panicking on a nil dereference.
func WithTokenRedeemRateLimit ¶ added in v0.2.0
WithTokenRedeemRateLimit enables a per-client-IP budget on the unauthenticated POST /api/v1/auth/reset-password and POST /api/v1/invites/accept routes. perMinute <= 0 disables it.
func WithTraceStore ¶
func WithTraceStore(s TraceStore) Option
WithTraceStore turns on the OTLP receiver and the trace routes.
func WithUpgradeHistory ¶ added in v0.2.0
func WithUpgradeHistory(s UpgradeHistoryStore) Option
WithUpgradeHistory enables GET /api/v1/updates/history and the ack route. Without one the history is empty and acknowledging answers 501.
func WithUpgradeScheduling ¶ added in v0.2.0
func WithUpgradeScheduling(s UpgradeScheduleStore, sender dbupgrade.NoticeSender, cfg upgradesched.Config) Option
WithUpgradeScheduling enables scheduled and automatic upgrades. sender delivers the alerts (the deploy dispatcher), nil keeps them in the log.
func WithVaultSecrets ¶ added in v0.2.0
func WithVaultSecrets(s VaultSecrets) Option
WithVaultSecrets enables PUT/DELETE /api/v1/settings/vault. Without one configured (the default), both return 501; GET works regardless, the same shape WithCloudflareTunnelSecrets establishes.
func WithVolumeCloneRestoreRunner ¶
func WithVolumeCloneRestoreRunner(r VolumeCloneRestoreRunner) Option
WithVolumeCloneRestoreRunner enables POST /api/v1/apps/{name}/volumes/{volume}/restore-as-new. Without one configured (the default), that route returns 501, the same "not configured" shape WithServiceVolumeRestoreRunner's absence produces; listing clone-restore history (GET .../clone-restores) works regardless, the same "listing needs no live runner" reasoning WithCloneRestoreRunner's own doc comment gives.
func WithWakeToken ¶ added in v0.2.0
WithWakeToken sets the secret the ingress wake route presents to the control plane. Without one, the wake hook answers 404 for everyone.
func WithWebhookDeliveryRetention ¶ added in v0.2.0
WithWebhookDeliveryRetention overrides how long a webhook_deliveries row survives before PurgeOldWebhookDeliveries removes it. Without one configured (or passed as 0), defaultWebhookDeliveryRetention (30 days) applies. Same "no hardcoded thresholds, use env vars" shape as WithAuditLogRetention: this package never reads the environment directly, cmd/levelrail/main.go reads APP_WEBHOOK_DELIVERY_RETENTION_DAYS and passes the parsed duration here.
func WithWebhookFailedDeliveryLimits ¶ added in v0.3.0
WithWebhookFailedDeliveryLimits sets how many unsigned webhook deliveries are kept per app and how many body bytes each retains. A zero value keeps the default (20 rows, 2048 bytes). cmd/levelrail/main.go reads APP_WEBHOOK_FAILED_DELIVERY_KEEP and APP_WEBHOOK_FAILED_BODY_BYTES.
func WithWebhookRateLimit ¶ added in v0.2.0
WithWebhookRateLimit enables a per-(client IP, app name) budget on POST /api/v1/webhooks/github/{name} (git_webhook.go), checked before that route's DB lookup, secret resolution, and delivery-history write: a request rejected here never reaches any of that work. perMinute <= 0 disables it, the same "nil is valid" shape WithAPIRateLimit's own absence establishes; without this option (the default), the route is unthrottled. cmd/levelrail/main.go reads APP_WEBHOOK_RATE_LIMIT_RPM and calls this unconditionally with its resolved (env-or-default) value, so the real control plane is always protected even when an operator never sets the env var.
type OrganizationStore ¶
type OrganizationStore interface {
SaveOrganization(ctx context.Context, o store.Organization) error
GetOrganization(ctx context.Context, id string) (store.Organization, error)
ListOrganizations(ctx context.Context) ([]store.Organization, error)
DeleteOrganization(ctx context.Context, id string) error
SetProjectOrganization(ctx context.Context, projectID, orgID string) error
// SetOrganizationEnvVars/ListOrganizationEnvVars back GET/PUT
// /api/v1/organizations/{id}/env (organization_env.go): shared env
// vars every project filed under this organization inherits as the
// base layer beneath its own project_env_vars tier
// (internal/reconcile/application's resolveEnv), full-replace on
// write, mirroring ProjectStore's SetProjectEnvVars/ListProjectEnvVars
// one level up.
SetOrganizationEnvVars(ctx context.Context, orgID string, vars map[string]string) error
ListOrganizationEnvVars(ctx context.Context, orgID string) (map[string]string, error)
// ListOrganizationEnvVarsDetailed/SetOrganizationSecretEnvVar/
// DeleteOrganizationSecretEnvVar/ListOrganizationSecretEnvKeys back
// GET /api/v1/organizations/{id}/env/all and the secret-var
// sub-resource routes (organization_env.go), mirroring ProjectStore's
// own secret-capable extension one tier down.
ListOrganizationEnvVarsDetailed(ctx context.Context, orgID string) ([]store.SharedEnvVar, error)
SetOrganizationSecretEnvVar(ctx context.Context, orgID, key string) error
DeleteOrganizationSecretEnvVar(ctx context.Context, orgID, key string) error
ListOrganizationSecretEnvKeys(ctx context.Context, orgID string) ([]string, error)
}
OrganizationStore is the store surface the organizations handlers need.
type OrphanSweepResult ¶ added in v0.2.0
OrphanSweepResult counts what SweepOrphanPreviews repaired.
type OrphanedContainerManager ¶ added in v0.2.0
type OrphanedContainerManager interface {
Stop(ctx context.Context, id string, timeout time.Duration) error
Remove(ctx context.Context, id string, force bool) error
}
OrphanedContainerManager is the surface POST /api/v1/system/containers/{name}/stop and .../remove need: stop or remove one container by ID. Unlike ContainerLister, which only reads, this is the mutating half, the same read/destructive-action split DockerDiskUsager/DockerPruner and OrphanedVolumeManager's own list/remove pair already establish. Deliberately narrower than docker.Runtime (just the two methods these routes call), the same "consumer-defined boundary, no second divergent surface" reasoning DockerPinger/ImageLister give; *docker.Client satisfies this structurally via Stop and Remove (internal/docker/client.go).
isManagedContainer (containers_orphaned.go), not this package's callers of this interface, decides which containers these methods may ever be invoked against: every route calling it re-confirms a container is genuinely orphaned before calling Stop/Remove, never trusting a client-supplied flag.
type OrphanedVolumeManager ¶ added in v0.2.0
type OrphanedVolumeManager interface {
ListNamedVolumes(ctx context.Context) ([]docker.NamedVolume, error)
RemoveVolume(ctx context.Context, name string) error
}
OrphanedVolumeManager is the surface GET /api/v1/system/volumes/orphaned and POST /api/v1/system/volumes/orphaned/cleanup need: list this instance's own named (non-anonymous) Docker volumes, and remove one by exact name. Unlike DockerPruner, this package (not internal/docker) decides which of ListNamedVolumes' results are actually orphaned, by cross- referencing against current desired state (computeOrphanedVolumes in volumes_orphaned.go): internal/docker stays store-agnostic, the same split PruneContainers' own keep-list parameter already establishes. *docker.Client satisfies this structurally via ListNamedVolumes and RemoveVolume (internal/docker/volumes_orphaned.go).
type PITRRestoreHistoryStore ¶ added in v0.2.0
type PITRRestoreHistoryStore interface {
ListPITRRestoreHistory(ctx context.Context, databaseName string) ([]store.PITRRestoreHistory, error)
}
PITRRestoreHistoryStore is the store surface the PITR restore history handler needs.
type PITRRestoreRunner ¶ added in v0.2.0
type PITRRestoreRunner interface {
// WindowBounds returns the same information *backup.PITRRunner.Window
// does, destructured into plain values instead of that method's own
// PITRWindow struct: an interface method's return type must be
// identical across a package boundary, and internal/api never
// imports internal/backup's types directly (databaseContainerName's
// own doc comment describes this boundary), so a struct return here
// would need its own separately-declared, ever-so-slightly duplicate
// type for no real benefit over returning the three values plain.
WindowBounds(ctx context.Context, databaseName, containerName string) (hasBaseBackup bool, start, end time.Time, err error)
ValidateTarget(ctx context.Context, databaseName, containerName string, target time.Time) error
RunPITRRestore(ctx context.Context, historyID, databaseName, containerName, dataVolumeName, baseBackupHistoryID string, targetTime time.Time) error
}
PITRRestoreRunner is the surface the PITR restore endpoints need from internal/backup.PITRRunner: compute the currently recoverable window, validate a target timestamp against it, and run one restore attempt end to end. *backup.PITRRunner satisfies this structurally, the same boundary BaseBackupRunner above describes.
type PackageRegistryStore ¶
type PackageRegistryStore interface {
SavePackageRegistry(ctx context.Context, p store.PackageRegistry) error
GetPackageRegistry(ctx context.Context, id string) (store.PackageRegistry, error)
ListPackageRegistries(ctx context.Context) ([]store.PackageRegistry, error)
DeletePackageRegistry(ctx context.Context, id string) error
ListServicesUsingRegistryCredential(ctx context.Context, credentialID string) ([]string, error)
}
PackageRegistryStore is the store surface the package registry and registry credential usage handlers need.
type PipelineEvents ¶ added in v0.2.0
type PipelineEvents interface {
TriggerEvent(ctx context.Context, app string, ev pipeline.Event, ref, sha, actor string) []store.PipelineRun
}
PipelineEvents starts runs of every matching pipeline for a git event. *pipeline.Engine satisfies it.
type PipelineOverviewStore ¶ added in v0.2.0
type PipelineOverviewStore interface {
ListPipelineRunRows(ctx context.Context, f store.PipelineRunFilter) ([]store.PipelineRunRow, error)
PipelineAppCounts(ctx context.Context, since time.Time) ([]store.PipelineAppCounts, error)
}
PipelineOverviewStore is the cross-app read surface behind the Pipelines overview. *store.DB satisfies it.
type PipelineRunner ¶ added in v0.2.0
type PipelineRunner interface {
Start(ctx context.Context, p store.Pipeline, opt pipeline.StartOptions) (store.PipelineRun, error)
Cancel(ctx context.Context, runID string) error
Rerun(ctx context.Context, runID, actor string) (store.PipelineRun, error)
// DecideHold releases or rejects a run held for approval.
DecideHold(ctx context.Context, runID string, approved bool, by string) (bool, error)
Nudge()
}
PipelineRunner starts, cancels, and re-runs pipeline runs. *pipeline.Engine satisfies it.
type PipelineStore ¶ added in v0.2.0
type PipelineStore interface {
SavePipeline(ctx context.Context, p store.Pipeline) (store.Pipeline, error)
GetPipelineByName(ctx context.Context, app, name string) (store.Pipeline, error)
ListPipelines(ctx context.Context, app string) ([]store.Pipeline, error)
DeletePipeline(ctx context.Context, id string) error
ListPipelineRuns(ctx context.Context, app, pipelineID string, limit int) ([]store.PipelineRun, error)
GetPipelineRun(ctx context.Context, id string) (store.PipelineRun, error)
ListPipelineJobs(ctx context.Context, runID string) ([]store.PipelineJob, error)
ListPipelineLogs(ctx context.Context, runID, jobKey string, afterID int64, limit int) ([]store.PipelineLogLine, error)
ListPipelineStepLogs(ctx context.Context, runID, jobKey string, step *int, afterID int64, limit int) ([]store.PipelineLogLine, error)
ListPipelineApprovals(ctx context.Context, runID string) ([]store.PipelineApproval, error)
DecidePipelineApproval(ctx context.Context, id int64, decision, by, comment string, now time.Time) (bool, error)
ListPipelineTriggerLog(ctx context.Context, app string, limit int) ([]store.PipelineTriggerLog, error)
}
PipelineStore is the store surface the pipeline handlers need.
type PipelineSyncStore ¶ added in v0.2.0
type PipelineSyncStore interface {
GetPipelineSync(ctx context.Context, app string) (store.PipelineSync, error)
SavePipelineSync(ctx context.Context, s store.PipelineSync) error
}
PipelineSyncStore holds the per-app sync settings. *store.DB satisfies it.
type PipelineSyncer ¶ added in v0.2.0
type PipelineSyncer interface {
Sync(ctx context.Context, app string) (pipeline.SyncResult, error)
SyncOnPush(ctx context.Context, app, ref, sha string) (pipeline.SyncResult, bool, error)
}
PipelineSyncer copies an app's repository pipeline files into its saved definitions. *pipeline.Syncer satisfies it.
type PlacementStore ¶ added in v0.2.0
type PlacementStore interface {
nodemove.Store
ListNodeLabels(ctx context.Context) (map[string]map[string]string, error)
GetNodeLabels(ctx context.Context, nodeID string) (map[string]string, error)
SetNodeLabels(ctx context.Context, nodeID string, labels map[string]string) error
GetPlacementSelector(ctx context.Context, kind, resource string) (map[string]string, error)
SetPlacementSelector(ctx context.Context, kind, resource string, selector map[string]string) error
EnsureDatabaseMeshPort(ctx context.Context, name string, minPort, maxPort int) (int, error)
}
PlacementStore is the persistence multi-node placement needs; *store.DB satisfies it.
type PolicyStore ¶
type PolicyStore interface {
SavePolicy(ctx context.Context, p store.Policy) error
UpdatePolicy(ctx context.Context, id, name, description, document string) error
GetPolicy(ctx context.Context, id string) (*store.Policy, error)
ListPolicies(ctx context.Context) ([]store.Policy, error)
DeletePolicy(ctx context.Context, id string) error
AttachPolicy(ctx context.Context, id, policyID, principalType, principalID string) error
DetachPolicy(ctx context.Context, policyID, principalType, principalID string) error
ListPoliciesForPrincipal(ctx context.Context, principalType, principalID string) ([]store.Policy, error)
ListAttachmentsForPolicy(ctx context.Context, policyID string) ([]store.PolicyAttachment, error)
}
PolicyStore is the store surface the IAM policy handlers need, defined here next to the handlers that use it, the same "single-file feature" shape OnboardingStore/AuditStore already use rather than every store interface living in store_interfaces.go.
type PreviewEnvironmentStore ¶
type PreviewEnvironmentStore interface {
SavePreviewEnvironment(ctx context.Context, p store.PreviewEnvironment) error
UpdatePreviewEnvironment(ctx context.Context, p store.PreviewEnvironment) error
GetPreviewEnvironmentByAppAndPR(ctx context.Context, appName string, prNumber int) (*store.PreviewEnvironment, error)
ListPreviewEnvironmentsByApp(ctx context.Context, appName string) ([]store.PreviewEnvironment, error)
DeletePreviewEnvironment(ctx context.Context, id string) error
ListStalePreviewEnvironments(ctx context.Context, cutoff time.Time) ([]store.PreviewEnvironment, error)
ListPreviewEnvironments(ctx context.Context) ([]store.PreviewEnvironment, error)
SetPreviewEnvironmentCommentID(ctx context.Context, id string, commentID int64) error
SetPreviewEnvironmentExtendedUntil(ctx context.Context, id, until string) error
GetPreviewAppSettings(ctx context.Context, appName string) (store.PreviewAppSettings, error)
ListPreviewAppSettings(ctx context.Context) (map[string]store.PreviewAppSettings, error)
SavePreviewAppSettings(ctx context.Context, s store.PreviewAppSettings) error
// SavePreviewEphemeralDatabase through DeletePreviewEphemeralDatabase
// back the ephemeralInPreviews lifecycle
// (preview_environments_databases.go): provisioning a preview-scoped
// database instance, listing them for the API's own status surface,
// and tearing them down alongside the preview that owns them.
SavePreviewEphemeralDatabase(ctx context.Context, p store.PreviewEphemeralDatabase) error
GetPreviewEphemeralDatabaseByPreviewAndKey(ctx context.Context, previewEnvironmentID, sourceKey string) (*store.PreviewEphemeralDatabase, error)
ListPreviewEphemeralDatabasesByPreview(ctx context.Context, previewEnvironmentID string) ([]store.PreviewEphemeralDatabase, error)
UpdatePreviewEphemeralDatabaseStatus(ctx context.Context, id, status, statusReason, updatedAt string) error
DeletePreviewEphemeralDatabase(ctx context.Context, id string) error
// SavePreviewDatabaseIsolation through DeletePreviewDatabaseIsolation
// back the isolatedInPreviews lifecycle
// (preview_environments_database_isolation.go): an isolated Postgres
// role on an existing database, one per (preview, sourceKey).
SavePreviewDatabaseIsolation(ctx context.Context, p store.PreviewDatabaseIsolation) error
GetPreviewDatabaseIsolationByPreviewAndKey(ctx context.Context, previewEnvironmentID, sourceKey string) (*store.PreviewDatabaseIsolation, error)
ListPreviewDatabaseIsolationsByPreview(ctx context.Context, previewEnvironmentID string) ([]store.PreviewDatabaseIsolation, error)
UpdatePreviewDatabaseIsolationStatus(ctx context.Context, id, status, statusReason, updatedAt string) error
DeletePreviewDatabaseIsolation(ctx context.Context, id string) error
}
PreviewEnvironmentStore is the store surface preview environment webhook handling and its HTTP routes (preview_environments_handlers.go) need. *store.DB satisfies this structurally.
type PreviewLimits ¶ added in v0.2.0
PreviewLimits caps simultaneous live preview environments. Zero means unlimited for that scope.
type PreviewService ¶ added in v0.2.0
type PreviewService interface {
Config() preview.Config
Settings(ctx context.Context, app string) (preview.AppSettings, error)
SaveSettings(ctx context.Context, app string, patch preview.SettingsPatch) (preview.AppSettings, error)
List(ctx context.Context, app string) ([]preview.Record, error)
OpenImage(ctx context.Context, app, deploymentID string) (string, preview.Record, error)
Capture(ctx context.Context, app string) error
Prune(ctx context.Context, app string, all bool) (preview.PruneResult, error)
Status(ctx context.Context, app string) (preview.Summary, error)
DeleteApp(ctx context.Context, app string) error
}
PreviewService is the deploy preview surface; *preview.Manager satisfies it.
type ProbeAttemptStore ¶ added in v0.2.0
type ProbeAttemptStore interface {
ListProbeAttempts(ctx context.Context, deployID string) ([]store.ProbeAttempt, error)
}
ProbeAttemptStore is the store surface GET /api/v1/apps/{name}/deploys/{deployId}/probes needs: the individual readiness-probe attempts (migrations/0284_probe_attempts.sql, internal/probe.WithOnAttempt) one deploy attempt's cutover made. *store.DB satisfies this structurally.
type ProjectStore ¶
type ProjectStore interface {
SaveProject(ctx context.Context, p store.Project) error
GetProject(ctx context.Context, id string) (store.Project, error)
ListProjects(ctx context.Context) ([]store.Project, error)
DeleteProject(ctx context.Context, id string) error
// SetProjectEnvVars/ListProjectEnvVars back GET/PUT
// /api/v1/projects/{id}/env (project_env.go): shared env vars every
// app filed under this project inherits as its resolveEnv base
// layer (internal/reconcile/application), full-replace on write, the
// same shape PUT /api/v1/apps/{name}'s own env field already has.
SetProjectEnvVars(ctx context.Context, projectID string, vars map[string]string) error
ListProjectEnvVars(ctx context.Context, projectID string) (map[string]string, error)
// ListProjectEnvVarsDetailed/SetProjectSecretEnvVar/
// DeleteProjectSecretEnvVar/ListProjectSecretEnvKeys back GET
// /api/v1/projects/{id}/env/all and the secret-var sub-resource
// routes (project_env.go): the secret-capable extension of the
// plain-only pair above, reusing internal/secrets.Manager (via
// Router.secrets) for the actual encryption rather than a second
// path.
ListProjectEnvVarsDetailed(ctx context.Context, projectID string) ([]store.SharedEnvVar, error)
SetProjectSecretEnvVar(ctx context.Context, projectID, key string) error
DeleteProjectSecretEnvVar(ctx context.Context, projectID, key string) error
ListProjectSecretEnvKeys(ctx context.Context, projectID string) ([]string, error)
}
ProjectStore is the store surface the projects handlers need (projects.go). See that file's own package doc comment for why a project is deliberately not the start of the deferred Phase 4 teams/ RBAC work (repo-plan section 6's own scope note): no owner, no member list, no per-project ability, just create/list/get/delete.
type ProxyIntegrationStore ¶ added in v0.2.0
type ProxyIntegrationStore interface {
GetProxyIntegrationSettings(ctx context.Context) (store.ProxyIntegrationSettings, error)
UpdateProxyIntegrationSettings(ctx context.Context, s store.ProxyIntegrationSettings) error
ListProxyRouteStatus(ctx context.Context) ([]store.ProxyRouteStatus, error)
SaveProxyRouteVerification(ctx context.Context, s store.ProxyRouteStatus) error
}
ProxyIntegrationStore is the persistence the proxy integration routes need beyond what the syncer reads.
type PushSubscriptions ¶ added in v0.2.0
type PushSubscriptions interface {
SavePushSubscription(ctx context.Context, s store.PushSubscription) error
ListPushSubscriptionsForUser(ctx context.Context, userID string) ([]store.PushSubscription, error)
DeletePushSubscription(ctx context.Context, id, userID string) error
}
PushSubscriptions is the store surface the handlers below need. *store.DB satisfies this structurally.
type ReadinessProbes ¶ added in v0.2.0
type ReadinessProbes struct {
Database func(ctx context.Context) error
Migrations func(ctx context.Context) error
EngineStarted func() bool
}
ReadinessProbes are the cheap checks GET /readyz runs. A nil probe is skipped.
type ReconcileNudger ¶ added in v0.2.0
type ReconcileNudger interface {
Nudge()
}
ReconcileNudger is *reconcile.Engine's own Nudge method, narrowed the same consumer-defined way DockerPinger is above: a handler that just changed desired state calls it to request an immediate reconcile pass instead of leaving an operator watching a create/stop/start/restart take up to a full resyncInterval (default 30s) to visibly do anything. Reconcile's own idempotent, level-triggered contract is what makes an extra, unscheduled pass always safe.
type RegistryAuthTester ¶
type RegistryAuthTester interface {
TestRegistryAuth(ctx context.Context, host, username, password string) error
}
RegistryAuthTester is the surface POST /api/v1/registry-credentials/{id}/test needs: ask the control plane's own local Docker daemon to authenticate against a registry host with a username/password pair, without pulling anything. Fixed to this control plane's own local daemon, the same DockerPinger/ImageLister/ DockerDiskUsager/DockerPruner reasoning above applies: adding this to docker.Runtime would ripple into 6+ fakes for one narrowly-scoped signal. *docker.Client satisfies this structurally via TestRegistryAuth (internal/docker/client.go).
type RegistryCatalogClient ¶ added in v0.2.0
type RegistryCatalogClient interface {
ListRepositories(ctx context.Context, baseURL, username, password string) ([]string, error)
ListTags(ctx context.Context, baseURL, username, password, repository string) ([]string, error)
}
RegistryCatalogClient is the surface GET /api/v1/registry/repositories, GET /api/v1/registry/tags, and the registry-credential browse routes below need: query a Docker Registry HTTP API v2 server's catalog (_catalog, <name>/tags/list) over Basic Auth. The same client serves both Levelrail's own built-in registry (baseURL fixed to its loopback address) and an operator's stored external credential (baseURL taken from that credential's RegistryHost), since the protocol is identical either way. *registrycatalog.Client satisfies this structurally.
type RegistryCatalogSecrets ¶ added in v0.2.0
type RegistryCatalogSecrets interface {
Resolve(ctx context.Context, serviceName, envKey string) (string, error)
}
RegistryCatalogSecrets is the surface the catalog handlers need from internal/secrets.Manager: resolve the built-in registry's generated password to authenticate the catalog query server-side. Never echoed back to the caller, the same boundary RegistryCredentialSecretsSetter.Resolve already draws for handleTestRegistryCredential.
type RegistryCredentialSecretsSetter ¶
type RegistryCredentialSecretsSetter interface {
SetValue(ctx context.Context, serviceName, envKey, plaintext string) error
Resolve(ctx context.Context, serviceName, envKey string) (string, error)
}
RegistryCredentialSecretsSetter is the surface registry credential create/update/test/browse needs from internal/secrets.Manager. Resolve is used by handleTestRegistryCredential and the two credential browse handlers in registry_catalog.go, to authenticate against the real registry on the operator's behalf; it is never used to echo a password back in an HTTP response, the same boundary GitSourceSecrets already draws for its own Resolve use.
type RegistryCredentialStore ¶
type RegistryCredentialStore interface {
SaveRegistryCredential(ctx context.Context, c store.RegistryCredential) error
GetRegistryCredential(ctx context.Context, id string) (store.RegistryCredential, error)
GetRegistryCredentialByName(ctx context.Context, name string) (store.RegistryCredential, error)
ListRegistryCredentials(ctx context.Context) ([]store.RegistryCredential, error)
UpdateRegistryCredential(ctx context.Context, id, name, registryHost, username string, expiresAt *time.Time) error
DeleteRegistryCredential(ctx context.Context, id string) error
}
RegistryCredentialStore is the store surface the registry credential handlers need.
type RegistrySecrets ¶
type RegistrySecrets interface {
SetValue(ctx context.Context, serviceName, envKey, plaintext string) error
Exists(ctx context.Context, serviceName, envKey string) (bool, error)
DeleteAll(ctx context.Context, serviceName string) error
}
RegistrySecrets is the surface the built-in registry settings handlers need from internal/secrets.Manager: set the generated password (first enable), check whether one exists, and clear it (disable). *secrets.Manager satisfies this structurally, the same "narrow, consumer-defined interface" shape CloudflareTunnelSecrets already establishes.
type RegistryStore ¶
type RegistryStore interface {
GetRegistrySettings(ctx context.Context) (store.RegistrySettings, error)
UpdateRegistrySettings(ctx context.Context, s store.RegistrySettings) error
}
RegistryStore is the store surface GET/PUT/DELETE /api/v1/settings/registry need: the single platform-wide row, always present, the same shape CloudflareTunnelStore has for its own row.
type Restarter ¶ added in v0.2.0
type Restarter struct {
Supervised bool
Trigger func()
}
Restarter lets the HTTP layer ask the process to exit so its supervisor relaunches it. Supervised is false when nothing would bring it back.
type RestoreHistoryStore ¶
type RestoreHistoryStore interface {
ListRestoreHistory(ctx context.Context, databaseName string) ([]store.RestoreHistory, error)
}
RestoreHistoryStore is the store surface the restore history handler needs.
type RestoreRunner ¶
type RestoreRunner interface {
RunRestore(ctx context.Context, historyID, databaseName, backupHistoryID, engine, containerName string) error
}
RestoreRunner is the surface the restore trigger handler needs from internal/backup.RestoreRunner: run one restore attempt end to end, from an already-minted history ID through to a finished store.RestoreHistory row. *backup.RestoreRunner satisfies this structurally; internal/api never imports internal/backup directly, the same boundary BackupRunner's own doc comment describes.
type Role ¶
type Role struct {
Name string `json:"name"`
Description string `json:"description"`
Abilities []string `json:"abilities"`
ID string `json:"id,omitempty"`
Visibility string `json:"visibility,omitempty"`
Builtin bool `json:"builtin"`
UserCount int `json:"user_count"`
}
Role is a curated, named preset over the raw ability list (abilities.go): picking one sets a user's Abilities to exactly this set in one action, instead of hand-picking abilities individually. It is a convenience layer, not a second permission model: every existing ability check still only ever sees the resolved Abilities.
type RoleStore ¶ added in v0.2.0
type RoleStore interface {
ListRoles(ctx context.Context) ([]store.Role, error)
GetRole(ctx context.Context, id string) (store.Role, error)
CreateRole(ctx context.Context, r store.Role) error
UpdateRole(ctx context.Context, r store.Role) error
DeleteRole(ctx context.Context, id string) error
RoleUserCounts(ctx context.Context) (map[string]int, error)
UserRoleID(ctx context.Context, userID string) (string, error)
SetUserRole(ctx context.Context, userID, roleID string) error
ListUserEnvironmentGrants(ctx context.Context, userID string) ([]string, error)
SetUserEnvironmentGrants(ctx context.Context, userID string, environmentIDs []string) error
CountRootUsersExcept(ctx context.Context, userID string) (int, error)
CountRootUsersOutsideRole(ctx context.Context, roleID string) (int, error)
SyncRoleAbilities(ctx context.Context, roleID string) error
UpdateRoleAndSync(ctx context.Context, r store.Role) error
}
RoleStore is the store surface the stored-role, role-assignment and environment-grant routes need.
type Route53DNSCredentialResolver ¶ added in v0.2.0
type Route53DNSCredentialResolver interface {
Resolve(ctx context.Context, serviceName, envKey string) (string, error)
}
Route53DNSCredentialResolver is the same shape as CloudflareDNSTokenResolver for the Route53 access key pair.
type Route53DNSSecrets ¶ added in v0.2.0
type Route53DNSSecrets interface {
SetValue(ctx context.Context, serviceName, envKey, plaintext string) error
Exists(ctx context.Context, serviceName, envKey string) (bool, error)
DeleteAll(ctx context.Context, serviceName string) error
}
Route53DNSSecrets is the surface the Route53 DNS-01 settings handlers need from internal/secrets.Manager, the same shape CloudflareDNSSecrets already establishes for a distinct credential shape: an AWS IAM access key pair instead of a single API token.
type Route53DNSStore ¶ added in v0.2.0
type Route53DNSStore interface {
GetRoute53DNSSettings(ctx context.Context) (store.Route53DNSSettings, error)
UpdateRoute53DNSSettings(ctx context.Context, s store.Route53DNSSettings) error
}
Route53DNSStore is the store surface GET/PUT /api/v1/settings/route53-dns need, the same "single platform-wide row" shape CloudflareDNSStore already establishes for a distinct ACME DNS-01 provider.
type Router ¶
type Router struct {
// contains filtered or unexported fields
}
Router wires every internal/api handler onto one http.Handler.
func (*Router) BudgetStatuses ¶ added in v0.2.0
BudgetStatuses returns every budget's month to date position, for the budget_threshold alert rule.
func (*Router) CheckDomainStatus ¶
CheckDomainStatus exposes runDomainCheck to internal/alerting's kind=domain_health evaluator (see alerting.DomainCheckSource), the same DNS check handleCheckDomain itself runs. Uses rt.publicHost only: unlike an HTTP handler, an engine tick has no request Host header to fall back on for advertisedHost's own best-effort guess, so a domain_health rule needs APP_PUBLIC_HOST configured to evaluate meaningfully; without it every domain simply reports domainCheckStatusUnconfigured, which EvaluateDomainHealth treats as inconclusive, not unhealthy.
func (*Router) CheckImageUpdate ¶ added in v0.2.0
CheckImageUpdate compares serviceName's tag against its registry and redeploys when the digest moved. Skips (with a reason, not an error) apps built from source, stopped, frozen, or in a protected environment: an unattended pull must never bypass the gates a manual deploy goes through.
func (*Router) ComplianceSecuritySnapshot ¶
ComplianceSecuritySnapshot is the evidence pack's settings source: the stored policy, the live posture checks and the effective retention.
func (*Router) ComplianceUserRemover ¶
func (rt *Router) ComplianceUserRemover() compliance.UserRemover
ComplianceUserRemover removes an account with the same guards as the users API: never yourself, never the last user, never the last root.
func (*Router) DemoStats ¶
DemoStats returns a copy of the demo counters, or the zero value outside demo mode.
func (*Router) DrainDeployQueue ¶ added in v0.2.0
DrainDeployQueue starts every queued deploy that is no longer blocked. It runs after each deploy finishes and on a timer, so a queue survives restarts.
func (*Router) GitSourceCloneToken ¶ added in v0.2.0
GitSourceCloneToken resolves the clone credential for a git source's own repository for in-process callers outside this package (the pipeline engine's repo reads and builds): name's stored deploy token, else the connected GitHub App's installation token. repoURL must be the stored git source URL, never a request-supplied value, since this mints a live installation token. Empty when neither exists.
func (*Router) Handler ¶
Handler builds the *http.ServeMux with every route registered. Called once at startup; the returned handler is what gets wrapped in an *http.Server. Route registration is split across this file (core: brand, auth, users, oauth, tokens, apps, databases) and routes_platform.go (nodes, certs, ingress, email, domains, backups, restore, storage, integrations, audit) purely to keep each function under a readable size; there is no other meaning to the split.
func (*Router) NudgeReconciler ¶
func (rt *Router) NudgeReconciler()
NudgeReconciler asks for a prompt reconcile pass, for background jobs that change routing state outside a request.
func (*Router) PipelineRunEnv ¶ added in v0.2.0
PipelineRunEnv gives a pull request pipeline run the PREVIEW_PR_NUMBER, PREVIEW_BRANCH and PREVIEW_URL of the live preview built from its branch. Other runs, and runs with no live preview, get nothing.
func (*Router) PipelineStatusReporter ¶ added in v0.2.0
func (rt *Router) PipelineStatusReporter() pipeline.StatusReporter
PipelineStatusReporter returns the reporter that posts pipeline run state to the git forge hosting an app's repository.
func (*Router) PurgeOldAuditEntries ¶
PurgeOldAuditEntries deletes every audit_log row older than effectiveAuditLogRetention, returning how many rows were removed.
func (*Router) PurgeOldWebhookDeliveries ¶ added in v0.2.0
PurgeOldWebhookDeliveries deletes every webhook_deliveries row older than effectiveWebhookDeliveryRetention, returning how many rows were removed.
func (*Router) RecordRevoked ¶ added in v0.2.0
func (rt *Router) RecordRevoked(ctx context.Context, c dbaccess.TempCredential)
RecordRevoked implements dbaccess.SweepAuditor: the sweeper's own audit row.
func (*Router) ReleaseHandlers ¶ added in v0.2.0
func (rt *Router) ReleaseHandlers() map[string]deploy.ReleaseHandler
ReleaseHandlers replays held deploys; cmd/levelrail wires them into a deploy.Releaser.
func (*Router) ResumeCutoverRuns ¶ added in v0.2.0
ResumeCutoverRuns continues or rolls back cutover runs a restart interrupted. Call it once after the router is built.
func (*Router) RevokeTemp ¶ added in v0.2.0
RevokeTemp implements dbaccess.Revoker for the expiry sweeper. A database that no longer exists has nothing left to revoke.
func (*Router) RunAuditLogSweeper ¶
RunAuditLogSweeper calls PurgeOldAuditEntries on interval until ctx is done, the same ticker shape RunPreviewSweeper already establishes.
func (*Router) RunDeployApprovalExpirySweep ¶ added in v0.2.0
RunDeployApprovalExpirySweep calls expireIfStale-style cleanup across every pending approval on interval until ctx is done, the same ticker shape RunAuditLogSweeper (audit_retention.go) already establishes. The lazy per-request expiry in expireIfStale already guarantees a stale request never proceeds; this sweep only matters for a pending row no one ever looks at again, so its own status reflects reality in the UI without waiting for a read that may never come.
func (*Router) RunDeviceLoginExpirySweeper ¶ added in v0.2.0
RunDeviceLoginExpirySweeper sweeps once at start, so expiries that passed while the server was down are audited, then on every interval tick.
func (*Router) RunGateSweeper ¶ added in v0.2.0
RunGateSweeper prunes old gate events and expired tokens and sessions on interval until ctx is done.
func (*Router) RunNodeMoves ¶ added in v0.2.0
RunNodeMoves advances node moves and drains until ctx is done, resuming any left running by a previous process.
func (*Router) RunPreviewSweeper ¶
RunPreviewSweeper calls SweepStalePreviewEnvironments on interval until ctx is done, matching the shape of every other periodic loop in this codebase (backup.Scheduler.Run, scheduledtask.Scheduler.Run, alerting.Engine.Run).
func (*Router) RunStatusPageSampler ¶ added in v0.2.0
RunStatusPageSampler probes status page components until ctx ends. It returns nil at once when the status page is not configured.
func (*Router) RunWebhookDeliverySweeper ¶ added in v0.2.0
RunWebhookDeliverySweeper calls PurgeOldWebhookDeliveries on interval until ctx is done, the same ticker shape RunAuditLogSweeper already establishes: without it, webhook_deliveries would be the one inbound- request history table in this codebase that only ever grows.
func (*Router) SetAppTeardownOptions ¶ added in v0.2.0
func (rt *Router) SetAppTeardownOptions(opts ...application.Option)
SetAppTeardownOptions is WithAppTeardownOptions for callers that learn the instance ID only after the router is built.
func (*Router) SetCompliance ¶
func (rt *Router) SetCompliance(s *compliance.Service)
SetCompliance enables the access review and evidence pack routes.
func (*Router) SetControlPlaneDR ¶ added in v0.2.0
func (rt *Router) SetControlPlaneDR(dr ControlPlaneDR, material EscrowMaterialReader)
SetControlPlaneDR enables the disaster recovery routes after the router is built, for wiring that needs the router's own dependencies first.
func (*Router) SetDataExport ¶ added in v0.2.0
func (rt *Router) SetDataExport(s DataExportService)
SetDataExport enables the data export routes and the /metrics scrape endpoint after the router is built.
func (*Router) SetDatabaseUpgrader ¶ added in v0.2.0
func (rt *Router) SetDatabaseUpgrader(u DatabaseUpgrader)
SetDatabaseUpgrader is WithDatabaseUpgrader for wiring after NewRouter.
func (*Router) SetDatabaseVersionCatalog ¶
func (rt *Router) SetDatabaseVersionCatalog(c DatabaseVersionCatalog)
SetDatabaseVersionCatalog enables the database version catalog routes.
func (*Router) SetDockerGuard ¶ added in v0.2.0
func (rt *Router) SetDockerGuard(c DockerGuardController)
SetDockerGuard is WithDockerGuard for a guard booted before the router.
func (*Router) SetDoctorIngressEdge ¶ added in v0.2.0
func (rt *Router) SetDoctorIngressEdge(edge DoctorIngressEdge)
SetDoctorIngressEdge makes doctor report the ingress edge policy. Call it before the router serves requests.
func (*Router) SetEventWebhooks ¶
func (rt *Router) SetEventWebhooks(s EventWebhookService)
SetEventWebhooks enables the event webhook routes and starts feeding audited mutations to subscribers.
func (*Router) SetForgeDeployments ¶ added in v0.2.0
func (rt *Router) SetForgeDeployments(s ForgeDeploymentStore)
SetForgeDeployments wires the store that tracks forge deployments. Unset, deployments are not reported.
func (*Router) SetGate ¶ added in v0.2.0
func (rt *Router) SetGate(secret string, settings GateSettings)
SetGate enables the built-in auth gate provider. An empty secret leaves the check endpoint refusing every request.
func (*Router) SetLoadBalancers ¶ added in v0.2.0
func (rt *Router) SetLoadBalancers(s LoadBalancerStore, registry *loadbalancer.Registry, stats loadbalancer.StatsSource)
SetLoadBalancers enables the load balancer routes after construction, for wiring that needs the router before the reconciler exists.
func (*Router) SetLocalNodeID ¶ added in v0.2.0
SetLocalNodeID marks which node's row in GET /api/v1/nodes is the one HostDiskCollector/HostMemoryCollector's readings are real for: the node running the control plane process itself. A late setter, not a construction Option, because cmd/levelrail's mesh setup (the only source of this ID) runs after NewRouter is called; safe to call any time before the HTTP server starts accepting requests.
func (*Router) SetMesh ¶ added in v0.2.0
func (rt *Router) SetMesh(mesh MeshStatusProvider, rotator MeshKeyRotator)
SetMesh wires GET /api/v1/mesh and POST /api/v1/nodes/{id}/mesh/rotate-key to this node's live mesh device and coordinator. A late setter for the same reason SetLocalNodeID is: cmd/levelrail's mesh setup runs after NewRouter is called. Either argument may be nil independently (a test or an embedder that wants status but not rotation, or vice versa); both routes check their own dependency and return 501 rather than assuming the other was set too.
func (*Router) SetMeshPaths ¶ added in v0.2.0
SetMeshPaths sets the resolver the doctor and app status use to tell whether a remote node's app can be routed over the WireGuard mesh.
func (*Router) SetMeshPeerStatus ¶ added in v0.2.0
func (rt *Router) SetMeshPeerStatus(src NodeMeshStatusSource)
SetMeshPeerStatus wires node-pair diagnostics to remote agents' mesh views.
func (*Router) SetMeshStartError ¶ added in v0.2.0
SetMeshStartError records why the mesh failed to start, so the settings card can show it instead of a bare "restart required".
func (*Router) SetMeshZone ¶ added in v0.2.0
SetMeshZone mirrors SetLocalNodeID's own late-setter shape, for the identical reason: cmd/levelrail's mesh setup (the only source of this value, application.WithMeshZone's own call site) runs after NewRouter is called. Empty means mesh DNS resolution is off, the same "not configured, not broken" default application.Controller itself uses.
func (*Router) SetNodeHostReports ¶ added in v0.2.2
func (rt *Router) SetNodeHostReports(src NodeHostReports)
SetNodeHostReports wires remote nodes' agent-reported host memory split into GET /api/v1/nodes/resource-usage.
func (*Router) SetOIDCManager ¶ added in v0.2.0
func (rt *Router) SetOIDCManager(m OIDCJWKSProvider, issuerURL string, ratePerMinute int)
SetOIDCManager wires the OIDC signing key manager: it serves the public GET /.well-known/jwks.json document and the authenticated summary GET /api/v1/pipelines/oidc reads for the dashboard. Minting the tokens themselves is wired separately, into internal/pipeline.Config.OIDCIssuer, since that lives on the pipeline engine, not this router.
func (*Router) SetOIDCRotator ¶ added in v0.2.0
func (rt *Router) SetOIDCRotator(r OIDCKeyRotator)
SetOIDCRotator wires POST /api/v1/pipelines/oidc/rotate-key. Optional: nil (the default) means the endpoint returns 501, the same not-configured shape SetOIDCManager's own JWKS route uses.
func (*Router) SetOrphanReaper ¶ added in v0.2.0
SetOrphanReaper enables GET /api/v1/system/orphans and POST /api/v1/system/orphans/reap, backed by the same reaper the reconcile loop runs.
func (*Router) SetPipelineEvents ¶ added in v0.2.0
func (rt *Router) SetPipelineEvents(e PipelineEvents)
SetPipelineEvents wires git webhook deliveries to pipeline triggers.
func (*Router) SetPipelineSync ¶ added in v0.2.0
func (rt *Router) SetPipelineSync(syncer PipelineSyncer, st PipelineSyncStore)
SetPipelineSync enables repository sync of pipeline files: on a push to the tracked branch, and on demand through /pipeline-sync.
func (*Router) SetPipelines ¶ added in v0.2.0
func (rt *Router) SetPipelines(st PipelineStore, runner PipelineRunner)
SetPipelines wires the pipeline endpoints after construction, for wiring code that builds the engine after the router.
func (*Router) SetPreview ¶ added in v0.2.0
func (rt *Router) SetPreview(p PreviewService)
SetPreview enables the deploy preview routes.
func (*Router) SetProxyIntegration ¶ added in v0.2.0
func (rt *Router) SetProxyIntegration(syncer *proxyroutes.Syncer, st ProxyIntegrationStore, verifyTimeout time.Duration)
SetProxyIntegration enables the managed proxy routes API. syncer must be the same instance the reconciler uses.
func (*Router) SetProxyRouteCheck ¶
func (rt *Router) SetProxyRouteCheck(rc ingress.RouteCheck)
SetProxyRouteCheck lets verification prove that a proxy route reaches the built-in ingress. Call after SetProxyIntegration.
func (*Router) SetRestarter ¶ added in v0.2.0
SetRestarter enables POST /api/v1/system/restart.
func (*Router) SetScheduledMaintenance ¶
func (rt *Router) SetScheduledMaintenance(s ScheduledMaintenanceStore)
SetScheduledMaintenance enables the /api/v1/scheduled-maintenance routes.
func (*Router) SetSecretRotation ¶
func (rt *Router) SetSecretRotation(st SecretRotationStore, maxPerPass int, dueSoon time.Duration) *secretrotation.Engine
SetSecretRotation enables the rotation policy API and returns the engine the caller runs on a timer.
func (*Router) SetSecretScan ¶
func (rt *Router) SetSecretScan(s SecretScanService)
SetSecretScan enables the secret scanning routes.
func (*Router) SetStorage ¶ added in v0.2.0
func (rt *Router) SetStorage(d StorageDeps)
SetStorage enables the storage routes after construction, for wiring that needs the built Router first. Call it before the server starts serving.
func (*Router) SetSupplyChain ¶ added in v0.2.0
func (rt *Router) SetSupplyChain(s SupplyChainService)
SetSupplyChain enables the SBOM and scan routes.
func (*Router) SetWALShipStatus ¶ added in v0.2.0
func (rt *Router) SetWALShipStatus(src WALShipStatusSource)
SetWALShipStatus attaches the source "pitr status" reads shipping state from.
func (*Router) StaticOrphanGrace ¶
StaticOrphanGrace is the grace period the sweep uses.
func (*Router) StatusHostHandler ¶ added in v0.2.0
StatusHostHandler serves only the public status page when a request's Host matches the configured custom domain, and 404s everything else on that host so the dashboard and API are never reachable through it. Requests for any other host pass through to next untouched.
func (*Router) StatusPageAppStatus ¶ added in v0.2.0
StatusPageAppStatus reports an app's status for the status page sampler.
func (*Router) SweepDeviceLoginExpiry ¶ added in v0.2.0
SweepDeviceLoginExpiry marks every pending request past its TTL as expired and audits each exactly once, returning how many it claimed.
func (*Router) SweepOrphanPreviews ¶ added in v0.2.0
func (rt *Router) SweepOrphanPreviews(ctx context.Context) (OrphanSweepResult, error)
SweepOrphanPreviews repairs state a crash can leave behind: previews stuck in deploying (the control plane died mid-build) are marked failed, and services tagged as preview workloads that no preview row owns are removed with their containers. Owned resources are never touched.
func (*Router) SweepOrphanStaticSites ¶
SweepOrphanStaticSites removes static sites with no desired service and no queued or running deploy, once older than the grace period, so a site whose app is still being created is never removed. It returns the removed names.
func (*Router) SweepSignInExpiry ¶ added in v0.2.0
SweepSignInExpiry expires lapsed codes and approvals, auditing each once.
func (*Router) SweepStalePreviewEnvironments ¶
SweepStalePreviewEnvironments tears down every preview environment last updated before now minus effectivePreviewTTL, reusing teardownPreviewRecord, the exact same deletion path the pull-request- closed webhook and the manual teardown route already use. One preview's teardown failure never blocks the rest, the same "one broken resource must not block others" principle every other periodic loop in this codebase follows (alerting.Engine.Tick, backup.Scheduler.Tick, scheduledtask.Scheduler.Tick).
A partial teardown (http.StatusMultiStatus) counts as handled, not an error: teardownPreviewRecord already marks the row Failed with a reason and bumps its UpdatedAt, so the next sweep won't immediately retry the same broken preview every tick.
func (*Router) SweepTokenHygiene ¶ added in v0.2.0
SweepTokenHygiene runs the unused-token policy and prunes expired sign-in alert links and long-unseen browsers. System tokens (no owner) are never touched: the platform itself may depend on them.
func (*Router) TriggerScheduledDeploy ¶ added in v0.2.0
func (rt *Router) TriggerScheduledDeploy(ctx context.Context, serviceName, branch string) (string, error)
TriggerScheduledDeploy resolves serviceName's git source's latest commit on branch (no clone, resolveBranchSHA) and deploys it through the same path a webhook-triggered push uses (deployFromGitSourceAs), tagged store.DeployAttemptSourceSchedule so it shows up under ListDeployments' "schedule" trigger filter. The one difference from a real push: branch may not be gs.Branch, a scheduled redeploy can target any branch, gs is only consulted for repo_url/build config.
Satisfies internal/scheduledeploy.Trigger; called only from that package's Scheduler, never directly from an HTTP handler, so it returns a plain error rather than an (int, string) status pair.
func (*Router) UpgradeScheduler ¶ added in v0.2.0
func (rt *Router) UpgradeScheduler() *upgradesched.Scheduler
UpgradeScheduler returns the scheduler to run, or nil when scheduling is not configured. It is built once and shared with the HTTP handlers so a cancel and a fire serialise on the same lock.
func (*Router) UsageRollupTick ¶ added in v0.2.0
UsageRollupTick is the scheduler entry point: it snapshots missing days and evaluates nothing else, so a failure only delays history.
type SSHNodeProvisionStore ¶ added in v0.2.0
type SSHNodeProvisionStore interface {
SaveSSHNodeProvision(ctx context.Context, p store.SSHNodeProvision) error
GetSSHNodeProvision(ctx context.Context, id string) (store.SSHNodeProvision, error)
ListSSHNodeProvisions(ctx context.Context) ([]store.SSHNodeProvision, error)
UpdateSSHNodeProvisionProgress(ctx context.Context, id, status, detectedOS, detectedArch, log, nodeID, failureReason string, updatedAt time.Time) error
}
SSHNodeProvisionStore is the store surface the SSH node provisioning handlers need.
type SSHProvisioner ¶ added in v0.2.0
type SSHProvisioner interface {
Provision(ctx context.Context, creds sshprovision.Credentials, params sshprovision.InstallParams, onEvent func(sshprovision.Event)) (sshprovision.DetectedHost, error)
ScanHostKeys(ctx context.Context, host string, port int) ([]sshprovision.HostKey, error)
}
SSHProvisioner is the surface *sshprovision.Provisioner satisfies, narrowed to what this package calls: a seam for this package's own tests to inject a fake that never dials a real network, the same "consumer-defined interface" shape NodeProvisioner already establishes for the cloud path.
type SSOStore ¶
type SSOStore interface {
ListSSOConnections(ctx context.Context) ([]store.SSOConnection, error)
GetSSOConnection(ctx context.Context, id string) (store.SSOConnection, error)
SaveSSOConnection(ctx context.Context, c store.SSOConnection, create bool, now time.Time) error
DeleteSSOConnection(ctx context.Context, id string) error
ListSSOGroupMappings(ctx context.Context) ([]store.SSOGroupMapping, error)
ReplaceSSOGroupMappings(ctx context.Context, mappings []store.SSOGroupMapping, now time.Time) error
GetSSOSettings(ctx context.Context) (store.SSOSettings, error)
SetSSOEnforce(ctx context.Context, on bool, now time.Time) error
SetSCIMDefaultRole(ctx context.Context, roleID string, now time.Time) error
SaveSCIMTokenMeta(ctx context.Context, tokenID string, m store.SCIMTokenMeta) error
SCIMTokenMetas(ctx context.Context) (map[string]store.SCIMTokenMeta, error)
CreateProvisionedUser(ctx context.Context, u store.User, roleID string) error
}
SSOStore is the platform-side SSO state: connection policy, group to role mappings, enforcement and SCIM token labels. The IdP bindings, identities, directory and token hashes live in the auth library. *store.DB satisfies it.
type ScheduledMaintenanceStore ¶
type ScheduledMaintenanceStore interface {
InsertMaintenanceWindow(ctx context.Context, w store.MaintenanceWindow) (store.MaintenanceWindow, error)
ListMaintenanceWindows(ctx context.Context, since time.Time) ([]store.MaintenanceWindow, error)
DeleteMaintenanceWindow(ctx context.Context, id string) error
}
ScheduledMaintenanceStore is the store surface for scheduled maintenance windows. *store.DB satisfies it.
type ScheduledTaskRunner ¶
type ScheduledTaskRunner interface {
Run(ctx context.Context, task store.ScheduledTask) error
}
ScheduledTaskRunner runs a job on demand. *scheduledtask.Runner satisfies it structurally, and cmd/levelrail/main.go wires that same instance into the scheduler, so a scheduled tick and "run now" share one execution path.
type ScheduledTaskStarter ¶ added in v0.2.0
type ScheduledTaskStarter interface {
Start(ctx context.Context, task store.ScheduledTask, trigger string) (runID string, err error)
}
ScheduledTaskStarter is the richer on-demand surface: it records the run's history row synchronously and returns its ID while the run itself proceeds in the background. Preferred over ScheduledTaskRunner when the wired runner provides it.
type ScheduledTaskStore ¶
type ScheduledTaskStore interface {
SaveScheduledTask(ctx context.Context, t store.ScheduledTask) error
GetScheduledTask(ctx context.Context, id string) (store.ScheduledTask, error)
ListScheduledTasksForService(ctx context.Context, serviceName string) ([]store.ScheduledTask, error)
UpdateScheduledTask(ctx context.Context, id string, command []string, schedule string, enabled bool, concurrencyPolicy string, updatedAt time.Time) error
UpdateScheduledTaskConfig(ctx context.Context, t store.ScheduledTask, now time.Time) error
CountScheduledTasksForService(ctx context.Context, serviceName string) (int, error)
DeleteScheduledTask(ctx context.Context, id string) error
ListScheduledTaskRuns(ctx context.Context, f store.ScheduledTaskRunFilter) ([]store.ScheduledTaskRun, error)
GetScheduledTaskRun(ctx context.Context, id string) (store.ScheduledTaskRun, error)
}
ScheduledTaskStore is the store surface the scheduled job handlers need.
type SecretBinder ¶ added in v0.2.0
type SecretBinder interface {
BindingStatus(ctx context.Context) (secrets.BindingStatus, error)
Rebind(ctx context.Context) (secrets.RebindResult, error)
}
SecretBinder is the surface the secrets binding routes need from internal/secrets.Manager: count legacy unbound values and rebind them.
type SecretRotationStore ¶
type SecretRotationStore interface {
secretrotation.Store
UpsertSecretRotationPolicy(ctx context.Context, p store.SecretRotationPolicy, now time.Time) error
}
SecretRotationStore is the policy persistence the rotation API needs. *store.DB satisfies it.
type SecretScanService ¶
type SecretScanService interface {
Limits() secretscan.Limits
Policy(ctx context.Context, app string) (secretscan.Policy, error)
SetPolicy(ctx context.Context, app, policy string) (secretscan.Policy, error)
AllowList(ctx context.Context, app string) ([]secretscan.AllowEntry, error)
Allow(ctx context.Context, app, fingerprint, reason, actor string) (secretscan.AllowEntry, error)
Unallow(ctx context.Context, app, fingerprint string) (bool, error)
Run(ctx context.Context, attemptID string) (secretscan.Run, error)
ScanEnvNow(ctx context.Context, app string, env map[string]string) (secretscan.Result, error)
DeleteApp(ctx context.Context, app string) error
}
SecretScanService is the deploy-time secret scanning surface; *secretscan.Service satisfies it.
type SecretSetter ¶
type SecretSetter interface {
SetValueGuarded(ctx context.Context, serviceName, envKey, plaintext string, overwriteLocked bool) error
ListKeys(ctx context.Context, serviceName string) ([]store.SecretKeyInfo, error)
SetLocked(ctx context.Context, serviceName, envKey string, locked bool) error
Exists(ctx context.Context, serviceName, envKey string) (bool, error)
// ExistsForServices is Exists batched over many service names in one
// call, used by databases.go's handleListDatabases to show every
// row's TLS status without an Exists call per database.
ExistsForServices(ctx context.Context, serviceNames []string, envKey string) (map[string]bool, error)
// Resolve decrypts and returns one secret's plaintext value, the same
// read internal/reconcile/application already does immediately before
// container creation. environment_clone.go's own explicit,
// opt-in-only CopySecretValues path is the one HTTP-reachable caller
// that ever moves a decrypted value between two secret namespaces
// (source app/environment -> cloned app/environment) rather than
// only ever writing a caller-supplied plaintext the way
// SetValueGuarded's other callers do.
Resolve(ctx context.Context, serviceName, envKey string) (string, error)
// DeleteAll permanently removes every value stored under a
// namespace, used by handleDetachAppIntegration to clear one
// attached integration's field values in the same request that
// removes its app_integrations row.
DeleteAll(ctx context.Context, serviceName string) error
}
SecretSetter is the surface the secrets handlers need from internal/secrets.Manager: set a value (with a reversible per-key lock guard), list which keys exist, toggle a key's lock, and check whether one exists without decrypting it (Exists, used by databases.go's databaseTLSEnabled to show a database's TLS status, never to read the certificate back). Every other secret-backed feature in this file keeps using Manager's plain SetValue/Resolve directly, unaffected by this narrower interface.
type SecurityStore ¶ added in v0.2.0
type SecurityStore interface {
GetSecurityPolicy(ctx context.Context) (store.SecurityPolicy, bool, error)
SaveSecurityPolicy(ctx context.Context, p store.SecurityPolicy) error
GetUserSecuritySettings(ctx context.Context, userID string) (store.UserSecuritySettings, error)
ListUserSecuritySettings(ctx context.Context) ([]store.UserSecuritySettings, error)
SetRequireNewDeviceApproval(ctx context.Context, userID string, on bool, now time.Time) error
FlagUserForReset(ctx context.Context, userID, reason string, now time.Time) error
ClearUserResetFlag(ctx context.Context, userID string, now time.Time) error
CreateSignInAlertToken(ctx context.Context, t store.SignInAlertToken) error
ConsumeSignInAlertToken(ctx context.Context, id string, now time.Time) (store.SignInAlertToken, error)
PruneSignInAlertTokens(ctx context.Context, cutoff time.Time) error
ListTokenHygieneNotices(ctx context.Context) ([]store.TokenHygieneNotice, error)
SaveTokenHygieneNotice(ctx context.Context, n store.TokenHygieneNotice) error
MarkTokenHygieneDisabled(ctx context.Context, tokenID string, now time.Time) error
DeleteTokenHygieneNotice(ctx context.Context, tokenID string) error
RememberBrowser(ctx context.Context, userID, fingerprint string, now time.Time) (bool, bool, error)
ForgetBrowser(ctx context.Context, userID, fingerprint string) error
PruneKnownBrowsers(ctx context.Context, cutoff time.Time) error
}
SecurityStore is the store surface the security center needs.
type SelfUpgradeLauncher ¶ added in v0.2.0
SelfUpgradeLauncher starts the host command. Tests replace it.
type SelfUpgradeStore ¶ added in v0.2.0
type SelfUpgradeStore interface {
UpsertSelfUpgradeAttempt(ctx context.Context, a store.SelfUpgradeAttempt) error
ListSelfUpgradeAttempts(ctx context.Context, limit int) ([]store.SelfUpgradeAttempt, error)
}
SelfUpgradeStore is what the self-upgrade routes persist and read.
type ServiceVolumeBackupHistoryStore ¶
type ServiceVolumeBackupHistoryStore interface {
ListServiceVolumeBackupHistory(ctx context.Context, serviceName, volumeName string, limit int, before *time.Time) ([]store.BackupHistory, error)
}
ServiceVolumeBackupHistoryStore is the store surface the volume backup history handler needs, the volume counterpart of BackupHistoryStore (backups.go): GetBackupHistory is already generic by ID (shared with the database path via rt.backupHistory), so only the listing method needs its own volume-scoped query.
type ServiceVolumeBackupRunner ¶
type ServiceVolumeBackupRunner interface {
RunVolumeBackup(ctx context.Context, historyID, serviceName, volumeName, dockerVolumeName, targetID, sqlitePath string) error
}
ServiceVolumeBackupRunner is the surface the volume backup trigger handler needs from internal/backup.Runner: the volume counterpart of BackupRunner (backups.go). *backup.Runner satisfies this structurally, the same boundary BackupRunner's own doc comment describes.
type ServiceVolumeBackupScheduleStore ¶
type ServiceVolumeBackupScheduleStore interface {
SetServiceVolumeBackupSchedule(ctx context.Context, serviceName, volumeName, targetID, schedule string, retain, retainDays int, sqlitePath string) error
GetServiceVolumeBackupSchedule(ctx context.Context, serviceName, volumeName string) (store.ServiceVolumeBackupConfig, error)
}
ServiceVolumeBackupScheduleStore is the store surface the volume backup schedule handlers need: the volume counterpart of SetDatabaseBackupSchedule/GetDatabaseBackupSchedule-shaped access, kept as its own table (service_volume_backups) rather than columns on desired_services, see migrations/0075's own doc comment.
type ServiceVolumeRestoreHistoryStore ¶
type ServiceVolumeRestoreHistoryStore interface {
ListServiceVolumeRestoreHistory(ctx context.Context, serviceName, volumeName string) ([]store.RestoreHistory, error)
}
ServiceVolumeRestoreHistoryStore is the store surface the volume restore history handler needs, the volume counterpart of RestoreHistoryStore (restore.go).
type ServiceVolumeRestoreRunner ¶
type ServiceVolumeRestoreRunner interface {
RunVolumeRestore(ctx context.Context, historyID, serviceName, volumeName, dockerVolumeName, backupHistoryID string) error
}
ServiceVolumeRestoreRunner is the surface the volume restore trigger handler needs from internal/backup.RestoreRunner: the volume counterpart of RestoreRunner (restore.go). *backup.RestoreRunner satisfies this structurally, the same boundary RestoreRunner's own doc comment describes.
type SessionLinkTokenStore ¶ added in v0.2.0
type SessionLinkTokenStore interface {
SaveSessionLinkToken(ctx context.Context, t store.SessionLinkToken) error
GetSessionLinkTokenByHash(ctx context.Context, hash string) (*store.SessionLinkToken, error)
ClaimSessionLinkToken(ctx context.Context, id string) error
}
SessionLinkTokenStore is the store surface the session-link flow needs: always set, part of the core Store interface, same shape as PasswordResetTokenStore above.
type SetupGuideStore ¶ added in v0.2.0
type SetupGuideStore interface {
GetSetupGuideState(ctx context.Context) (store.SetupGuideState, error)
SetSetupGuideHidden(ctx context.Context, hidden bool, by string) error
SetSetupGuideOverride(ctx context.Context, stepID, state, by string) error
ResetSetupGuide(ctx context.Context) error
}
SetupGuideStore persists the Get started hub's dismissal and step overrides.
type StaleSecretCounter ¶ added in v0.2.0
type StaleSecretCounter interface {
CountStaleSecrets(ctx context.Context, cutoff time.Time) (int, error)
}
StaleSecretCounter is the surface GET /api/v1/system/doctor's stale_secrets check needs: count every secret-backed value (per-app and every secret-marked shared-env row alike) last set or rotated before cutoff. *store.DB satisfies this via CountStaleSecrets (internal/store/secret_rotation.go).
type StandaloneSafety ¶ added in v0.2.0
type StandaloneSafety struct {
// ControlPorts are this platform's own listeners on this server.
ControlPorts []standalone.ControlPort
// IngressPorts are the ports the embedded ingress listens on.
IngressPorts []int
}
StandaloneSafety is what the API needs to refuse dangerous standalone targets.
type Statement ¶
type Statement struct {
Effect Effect `json:"Effect"`
Action []string `json:"Action"`
Resource []string `json:"Resource"`
}
Statement is one Allow/Deny rule inside a Document: Action holds ability strings (abilities.go's AbilityRead etc.) or "*", Resource holds resource identifiers ("app:myapp", "database:main") or "*". Both are lists so one statement can cover several actions or resources at once, matching how a real IAM statement reads.
type StaticSiteStore ¶
type StaticSiteStore interface {
ListStaticSites(ctx context.Context) ([]store.StaticSite, error)
}
StaticSiteStore is the store surface handleListStaticSites needs. *store.DB satisfies this structurally, the same consumer-defined interface convention every other Store sub-interface in this package follows (see CertStore, DatabaseStore).
type StatusPageDB ¶ added in v0.2.0
type StatusPageDB interface {
StatusPageStore
statuspage.Store
}
StatusPageDB is everything the status page needs from the database.
type StatusPageStore ¶ added in v0.2.0
type StatusPageStore interface {
GetStatusPageSettings(ctx context.Context) (store.StatusPageSettings, error)
SaveStatusPageSettings(ctx context.Context, s store.StatusPageSettings) error
ListStatusComponents(ctx context.Context) ([]store.StatusComponent, error)
GetStatusComponent(ctx context.Context, id string) (store.StatusComponent, error)
SaveStatusComponent(ctx context.Context, c store.StatusComponent) error
DeleteStatusComponent(ctx context.Context, id string) error
SaveStatusIncident(ctx context.Context, i store.StatusIncident) error
GetStatusIncident(ctx context.Context, id string) (store.StatusIncident, error)
ListStatusIncidents(ctx context.Context, limit int) ([]store.StatusIncident, error)
DeleteStatusIncident(ctx context.Context, id string) error
AddStatusIncidentUpdate(ctx context.Context, u store.StatusIncidentUpdate) error
ListStatusIncidentUpdates(ctx context.Context) ([]store.StatusIncidentUpdate, error)
}
StatusPageStore is the persistence surface of the status page handlers. *store.DB satisfies it.
type StatusPageViewer ¶ added in v0.2.0
type StatusPageViewer interface {
View(ctx context.Context) (statuspage.View, error)
PreviewView(ctx context.Context) (statuspage.View, error)
Enabled(ctx context.Context) (bool, error)
Invalidate()
}
StatusPageViewer builds the public view. *statuspage.Service satisfies it.
type StorageDeps ¶ added in v0.2.0
type StorageDeps struct {
Options StorageOptionsStore
Archive LogArchiveStore
Clients ObjectClientResolver
Archiver LogArchiver
ArchiveRoot string
// BuildCache and BuildCacheSettings enable /api/v1/build-cache; nil answers 501.
BuildCache BuildCacheService
BuildCacheSettings BuildCacheSettingsStore
}
StorageDeps groups what the storage destination and log archive routes need.
type StorageOptionsStore ¶ added in v0.2.0
type StorageOptionsStore interface {
SaveStorageOptions(ctx context.Context, o store.StorageOptions) error
GetStorageOptions(ctx context.Context, targetID string) (store.StorageOptions, bool, error)
ListStorageOptions(ctx context.Context) (map[string]store.StorageOptions, error)
}
StorageOptionsStore persists per-destination options.
type Store ¶
type Store interface {
AppStore
AppGroupLister
AppComposeStore
CustomTemplateStore
DeployStore
DeployAttemptStore
ProbeAttemptStore
DatabaseStore
AuthStore
TokenStore
NodeStore
CertStore
StaticSiteStore
BackupTargetStore
RegistryCredentialStore
NetworkShareStore
FirewallRuleStore
AppStreamStore
BackupHistoryStore
BackupVerificationStore
RestoreHistoryStore
BaseBackupHistoryStore
PITRRestoreHistoryStore
MajorUpgradeStore
ServiceVolumeBackupHistoryStore
ServiceVolumeBackupScheduleStore
ServiceVolumeRestoreHistoryStore
CloneRestoreHistoryStore
VolumeCloneRestoreHistoryStore
AppVolumeMoveStore
ProjectStore
OrganizationStore
EnvironmentStore
IngressSettingsStore
UpdateSettingsStore
DomainStore
DomainBasicAuthStore
DomainMaintenanceStore
DomainTLSCertStore
DomainWAFStore
DomainAuthGateStore
DomainRedirectStore
DomainErrorPagesStore
DomainSearchVisibilityStore
DomainTrafficPolicyStore
GitSourceStore
AppScheduleStore
ImageAutoUpdateStore
AppSleepStore
DataImportStore
MigrationHubStore
AppImportStore
LoginCodeStore
SecurityStore
ExternalDatabaseStore
CanaryStore
DatabaseQueryStore
PreviewEnvironmentStore
GitHubAppStore
GitLabAppStore
BitbucketAppStore
GiteaAppStore
OAuthSettingsStore
OAuthIdentityStore
EmailSettingsStore
ObservabilityStore
CloudflareTunnelStore
RegistryStore
CloudflareDNSStore
Route53DNSStore
NodeProvisionStore
NodeProviderConnectionStore
PackageRegistryStore
SSHNodeProvisionStore
VaultSettingsStore
SessionLinkTokenStore
InviteStore
PushSubscriptions
AuditStore
ScheduledTaskStore
FeatureFlagStore
TagStore
AppIntegrationStore
OnboardingStore
WebhookDeliveryStore
PolicyStore
HookRunStore
DeployApprovalStore
AIAssistantSettingsStore
AIChatStore
RoleStore
AIControlStore
}
Store is the full surface NewRouter needs. *store.DB satisfies it structurally, same pattern internal/reconcile/application.ServiceStore already established for this codebase.
type SupplyChainService ¶ added in v0.2.0
type SupplyChainService interface {
Config() supplychain.Config
Settings(ctx context.Context, app string) (supplychain.Settings, error)
SaveSettings(ctx context.Context, app string, patch supplychain.SettingsPatch) (supplychain.Settings, error)
ArmOverride(ctx context.Context, app, reason string) (supplychain.Settings, error)
Get(ctx context.Context, app, attemptID string) (supplychain.Record, error)
OpenSBOM(ctx context.Context, app, attemptID string) ([]byte, supplychain.Record, error)
ScanNow(ctx context.Context, app, attemptID string) (supplychain.Record, error)
Lookup(ctx context.Context, ids []string) (map[string]supplychain.Record, error)
DeleteApp(ctx context.Context, app string) error
}
SupplyChainService is the SBOM and scan surface; *supplychain.Service satisfies it.
type TagStore ¶ added in v0.2.0
type TagStore interface {
SaveTag(ctx context.Context, t store.Tag) error
GetTag(ctx context.Context, id string) (store.Tag, error)
GetTagByName(ctx context.Context, name string) (store.Tag, error)
ListTags(ctx context.Context) ([]store.Tag, error)
DeleteTag(ctx context.Context, id string) error
AttachAppTag(ctx context.Context, tagID, appName string) error
DetachAppTag(ctx context.Context, tagID, appName string) error
ListTagsForApp(ctx context.Context, appName string) ([]store.Tag, error)
ListTagsForApps(ctx context.Context, appNames []string) (map[string][]store.Tag, error)
ListAppNamesByTag(ctx context.Context, tagID string) ([]string, error)
}
TagStore is the store surface the tag handlers need, mirroring FeatureFlagStore's own shape for a different child resource.
type TelemetryQuerier ¶
type TelemetryQuerier interface {
QueryMetrics(ctx context.Context, resourceID, metric string, from, to time.Time) ([]telemetry.Sample, error)
QueryLogs(ctx context.Context, resourceID string, from, to time.Time, query string) ([]telemetry.LogEntry, error)
// LatestByMetric backs handleAppResourceUsage
// (app_resource_usage.go): the dashboard-wide "what is every app
// doing right now" ranking, one query per metric rather than one
// query per app.
LatestByMetric(ctx context.Context, metric string) ([]telemetry.Sample, error)
}
TelemetryQuerier is the surface the metrics and logs query handlers need. *telemetry.Federator satisfies this structurally: today it fans out to exactly one source (this node's own local store), the same single-node-now shape already established for the reconcile agent transport, so Phase 3's real multi-node federation slots in here without this package changing.
type TokenStore ¶
type TokenStore interface {
SaveAPIToken(ctx context.Context, t store.APIToken) error
GetAPITokenByHash(ctx context.Context, hash string) (*store.APIToken, error)
GetAPITokenByID(ctx context.Context, id string) (*store.APIToken, error)
ListAPITokens(ctx context.Context) ([]store.APIToken, error)
RevokeAPIToken(ctx context.Context, id string) error
TouchAPITokenLastUsed(ctx context.Context, id string) error
}
TokenStore is the store surface the API-token handlers and the ability-aware auth middleware need.
type TraceStore ¶
type TraceStore interface {
WriteSpans(ctx context.Context, spans []telemetry.Span) error
ListTraces(ctx context.Context, f telemetry.TraceFilter) ([]telemetry.TraceSummary, error)
GetTrace(ctx context.Context, resourceID, traceID string) ([]telemetry.Span, error)
}
TraceStore is the span storage the trace routes need.
type TrialKeeper ¶
type TrialKeeper interface {
KeepTrialApp(ctx context.Context, name string) (store.TrialKeep, error)
}
TrialKeeper makes a trial deployment permanent. *store.DB satisfies it.
type UpdateSettingsStore ¶ added in v0.2.0
type UpdateSettingsStore interface {
GetUpdateSettings(ctx context.Context) (store.UpdateSettings, error)
UpdateUpdateSettings(ctx context.Context, s store.UpdateSettings) error
}
UpdateSettingsStore is the store surface the update settings handlers need. *store.DB satisfies this structurally, the same consumer-defined interface convention IngressSettingsStore already establishes.
type UpgradeHistoryStore ¶ added in v0.2.0
type UpgradeHistoryStore interface {
ListUpgradeHistory(ctx context.Context, limit int) ([]store.UpgradeHistoryEntry, error)
AcknowledgeUpgrade(ctx context.Context, id, byType, byID, byName string, now time.Time) (e store.UpgradeHistoryEntry, changed bool, err error)
ListNodeAgentVersionChanges(ctx context.Context, limit int) ([]store.NodeAgentVersionChange, error)
}
UpgradeHistoryStore is what the upgrade history routes need. ListUnacknowledgedUpgrades is the query the attention center consumes.
type UpgradeScheduleStore ¶ added in v0.2.0
type UpgradeScheduleStore interface {
upgradesched.Store
UpdateUpgradePolicy(ctx context.Context, p store.UpgradePolicy) error
}
UpgradeScheduleStore is the persistence behind scheduled and automatic upgrades. *store.DB satisfies it.
type UserCounter ¶ added in v0.2.0
UserCounter is the store surface EnsureSetupToken needs.
type VaultSecrets ¶ added in v0.2.0
type VaultSecrets interface {
SetValue(ctx context.Context, serviceName, envKey, plaintext string) error
Exists(ctx context.Context, serviceName, envKey string) (bool, error)
DeleteAll(ctx context.Context, serviceName string) error
}
VaultSecrets is the surface the Vault settings handlers need from internal/secrets.Manager: set the credential (PUT), check whether one exists (GET's has_credential, and PUT's "was a credential already set" check for the omitted-credential case), and clear it (DELETE). *secrets.Manager satisfies this structurally, the same "narrow, consumer-defined interface" shape CloudflareTunnelSecrets already establishes.
type VaultSettingsStore ¶ added in v0.2.0
type VaultSettingsStore interface {
GetVaultSettings(ctx context.Context) (store.VaultSettings, error)
UpdateVaultSettings(ctx context.Context, s store.VaultSettings) error
}
VaultSettingsStore is the store surface GET/PUT/DELETE /api/v1/settings/vault need: the single platform-wide row, always present, the same shape CloudflareTunnelStore has for its own row.
type VolumeCloneRestoreHistoryStore ¶
type VolumeCloneRestoreHistoryStore interface {
ListVolumeCloneRestores(ctx context.Context, serviceName, volumeName string) ([]store.VolumeCloneRestore, error)
}
VolumeCloneRestoreHistoryStore is the store surface the volume clone-restore history handler needs, the app service volume counterpart of CloneRestoreHistoryStore (database_clone_restore.go).
type VolumeCloneRestoreRunner ¶
type VolumeCloneRestoreRunner interface {
RunVolumeCloneRestore(ctx context.Context, historyID, sourceServiceName, sourceVolumeName, newVolumeName, backupHistoryID string) error
}
VolumeCloneRestoreRunner is the surface the volume clone-restore trigger handler needs from internal/backup.VolumeCloneRestoreRunner, the app service volume counterpart of CloneRestoreRunner. *backup. VolumeCloneRestoreRunner satisfies this structurally, the same boundary CloneRestoreRunner's own doc comment describes.
type WALShipStatusSource ¶ added in v0.2.0
type WALShipStatusSource interface {
WALShipStatus(databaseName string) (backup.WALShipStatus, bool)
}
WALShipStatusSource reports the last WAL shipping outcome per database.
type WebhookDeliveryStore ¶
type WebhookDeliveryStore interface {
SaveWebhookDelivery(ctx context.Context, d store.WebhookDelivery) error
GetWebhookDelivery(ctx context.Context, id string) (*store.WebhookDelivery, error)
ListWebhookDeliveries(ctx context.Context, serviceName string, limit int, before *time.Time) ([]store.WebhookDelivery, error)
// DeleteWebhookDeliveriesOlderThan backs the retention sweep
// (webhook_delivery_retention.go), the same age-based deletion
// AuditStore.DeleteAuditEntriesOlderThan already provides for audit_log.
DeleteWebhookDeliveriesOlderThan(ctx context.Context, cutoff time.Time) (int64, error)
// PruneFailedWebhookDeliveries caps unsigned deliveries per app so
// junk requests cannot grow the table between retention sweeps.
PruneFailedWebhookDeliveries(ctx context.Context, serviceName string, keep int) (int64, error)
}
WebhookDeliveryStore is the store surface real inbound webhook delivery history needs: row-per-delivery CRUD backing GET /api/v1/apps/{name}/webhook-deliveries and its replay endpoint. *store.DB satisfies this structurally.
Source Files
¶
- abilities.go
- access_log.go
- access_policy.go
- access_policy_handlers.go
- account.go
- account_access.go
- agent_identity.go
- ai_chat.go
- ai_control.go
- ai_control_gate.go
- ai_settings.go
- ai_turn.go
- alert_noise.go
- alerts.go
- api_rate_limit.go
- app_badge.go
- app_changes.go
- app_domains.go
- app_environment_domains.go
- app_events.go
- app_exposure.go
- app_exposure_check.go
- app_exposure_ports.go
- app_health_score.go
- app_import.go
- app_import_cutover.go
- app_import_cutover_backend.go
- app_import_cutover_run.go
- app_import_images.go
- app_import_images_state.go
- app_import_run.go
- app_import_session.go
- app_import_stage.go
- app_integrations.go
- app_listening_ports.go
- app_pending_image.go
- app_resource_usage.go
- app_run_state.go
- app_schedule.go
- app_schedule_trigger.go
- app_sleep.go
- app_sleep_fleet.go
- app_sleep_history.go
- app_status.go
- app_streams.go
- app_timeline.go
- app_urls.go
- app_volume_backup_download.go
- app_volume_backup_verify.go
- app_volume_backups.go
- app_volume_clone_restore.go
- app_volume_restore.go
- app_volumes.go
- apps.go
- apps_base_domain.go
- apps_branch_env.go
- apps_bulk.go
- apps_clone.go
- apps_clone_options.go
- apps_compose.go
- apps_connections.go
- apps_database.go
- apps_egress.go
- apps_group.go
- apps_health.go
- apps_health_discover.go
- apps_hooks.go
- apps_keep.go
- apps_list.go
- apps_log_drain.go
- apps_metrics_batch.go
- apps_move_with_volumes.go
- apps_multi.go
- apps_preview_env.go
- apps_storage.go
- apps_update_preserve.go
- apps_validate_spec.go
- apps_vault_env.go
- apps_volumes_attach.go
- attention_backup_coverage.go
- attention_datacopy.go
- attention_feed.go
- attention_quota.go
- attention_secret_rotation.go
- attention_upgrade_schedule.go
- attention_upgrades.go
- audit.go
- audit_retention.go
- auth.go
- authlib_device.go
- authlib_mfa.go
- authlib_mfa_passkeys.go
- authlib_oauth.go
- authlib_sessions.go
- authlib_sessions_sync.go
- authlib_status.go
- authlib_tokens.go
- backup_delete.go
- backup_download.go
- backup_protection.go
- backup_targets.go
- backup_verify.go
- backups.go
- backups_coverage.go
- beta_features.go
- bitbucket_app.go
- bitbucket_app_oauth.go
- bitbucket_app_repos.go
- body_limit.go
- branch_env_resolve.go
- brand.go
- build_cache.go
- build_detect.go
- builds.go
- builds_manual.go
- canary.go
- cascade_delete.go
- certificates.go
- changelog.go
- chat_interactions.go
- cli_console.go
- cli_console_host.go
- cli_console_session.go
- client_kind.go
- cloudflare_dns.go
- cloudflare_tunnel.go
- code_login_settings.go
- compliance.go
- compose_preview.go
- compose_revisions.go
- compose_stack.go
- containers.go
- containers_orphaned.go
- control_plane_backups.go
- control_plane_base_url.go
- control_plane_dr.go
- cost_estimate.go
- csrf_origin.go
- dashboard_cache.go
- dashboard_url.go
- data_export.go
- data_export_streams.go
- database_access.go
- database_access_audit.go
- database_access_temp.go
- database_access_who.go
- database_clone_restore.go
- database_engine_stats.go
- database_engines.go
- database_leftover_volume.go
- database_logs.go
- database_major_upgrade.go
- database_metrics.go
- database_network.go
- database_network_rules.go
- database_network_scope.go
- database_public_access.go
- database_ref_authz.go
- database_resource_recommendation.go
- database_slow_queries.go
- database_stop_start.go
- database_upgrades.go
- database_version.go
- database_versions.go
- database_viewer.go
- database_viewer_query.go
- database_viewer_saved.go
- databases.go
- demo.go
- demo_gate.go
- demo_stubs.go
- deploy_approval_chat_notify.go
- deploy_approvals.go
- deploy_attempts.go
- deploy_cancel.go
- deploy_commit_meta.go
- deploy_compare.go
- deploy_failure.go
- deploy_gate.go
- deploy_log_download.go
- deploy_notify_targets.go
- deploy_outcome.go
- deploy_policy.go
- deploy_probes.go
- deploy_queue.go
- deploy_rollback_static.go
- deploy_rollback_to.go
- deploy_safety.go
- deploy_steps.go
- deploy_suggestions.go
- deployments.go
- deployments_query.go
- deployments_stream.go
- deployments_timeline.go
- deploys.go
- deploys_failed.go
- devfixtures.go
- device_activity.go
- device_auth.go
- device_notify.go
- device_pending_summary.go
- device_url.go
- devmode.go
- devmode_debug.go
- diagnose.go
- diagnose_causes.go
- diagnose_container_logs.go
- diagnose_facts.go
- disk_usage_cache.go
- dns_automation.go
- dns_records.go
- dns_zones.go
- dns_zones_records.go
- dns_zones_tools.go
- dns_zones_wildcard.go
- docker_guard.go
- docker_guard_doctor.go
- dockerhub_search.go
- doctor.go
- doctor_channel_secrets.go
- doctor_cross_node_ingress.go
- doctor_exposure.go
- doctor_firewall.go
- doctor_hardening.go
- doctor_ingress_edge.go
- doctor_legacy_tokens.go
- doctor_nas.go
- doctor_network.go
- doctor_registry.go
- doctor_release_signature.go
- doctor_resources.go
- doctor_runtime.go
- doctor_secret_reveal.go
- domain_activity.go
- domain_auth_gate.go
- domain_automation_policy.go
- domain_basic_auth.go
- domain_check.go
- domain_doctor.go
- domain_enforcement.go
- domain_error_pages.go
- domain_maintenance.go
- domain_policies.go
- domain_policies_ports.go
- domain_policies_redirects.go
- domain_policies_summary.go
- domain_reachability.go
- domain_redirect.go
- domain_search_visibility.go
- domain_tls_cert.go
- domain_waf.go
- domain_wizard.go
- drain_placer.go
- email_settings.go
- env_export.go
- env_protection.go
- env_reveal.go
- env_reveal_auth.go
- env_settings.go
- environment_clone.go
- environment_compare.go
- environment_env.go
- environment_move.go
- environments.go
- environments_global.go
- errors_ingest.go
- errors_issues.go
- event_webhooks.go
- exec.go
- experimental_gate.go
- exposure.go
- exposure_restrict.go
- external_databases.go
- external_databases_list.go
- external_databases_viewer.go
- failure_context.go
- feature_flags.go
- firewall_host.go
- firewall_rules.go
- fixit.go
- fixit_disk.go
- gate_admin.go
- gate_authz.go
- gate_check.go
- gate_request.go
- gate_settings.go
- git_branches.go
- git_build_settings.go
- git_deploy_settings.go
- git_deployments.go
- git_forge.go
- git_providers.go
- git_source_commits.go
- git_sources.go
- git_webhook.go
- git_webhook_guard.go
- gitea_app.go
- gitea_app_oauth.go
- gitea_app_repos.go
- github_app.go
- github_app_installations.go
- github_app_manual.go
- github_app_register.go
- github_app_repos.go
- github_app_use_as_source.go
- github_app_visibility.go
- gitlab_app.go
- gitlab_app_oauth.go
- gitlab_app_projects.go
- go_live.go
- go_live_handlers.go
- go_live_probes.go
- gpu_doctor.go
- gpu_placement.go
- iac.go
- iam.go
- iam_analyze.go
- iam_catalog.go
- iam_environment.go
- iam_explain.go
- iam_handlers.go
- iam_inventory.go
- iam_preview.go
- iam_templates.go
- iam_validate.go
- iam_versions.go
- image_auto_update.go
- images.go
- imports.go
- imports_analyze.go
- ingress_https.go
- ingress_settings.go
- investigate.go
- invites.go
- list_scope.go
- live_logs.go
- loadbalancer.go
- loadbalancer_history.go
- loadbalancer_list.go
- log_archive.go
- log_budget.go
- log_level.go
- log_live_container.go
- log_pipeline.go
- log_redact.go
- log_saved_queries.go
- log_signatures.go
- login_approval.go
- login_code.go
- login_code_audit.go
- login_code_config.go
- logs.go
- logs_download.go
- loki.go
- maintenance_api.go
- master_key_rotation.go
- mesh.go
- mesh_connectivity.go
- mesh_settings.go
- metrics.go
- middleware.go
- migration_cutover.go
- migration_data_copy.go
- migration_hub.go
- migration_hub_local.go
- migration_hub_receipt.go
- migration_hub_run.go
- migration_hub_state.go
- mobile.go
- mobile_devices.go
- mobile_overview.go
- models.go
- models_fit.go
- models_hf.go
- models_keys.go
- models_metrics.go
- models_residency.go
- multinode.go
- network.go
- network_proxy.go
- network_shares.go
- network_topology.go
- network_topology_groups.go
- node_capacity_forecast.go
- node_cert.go
- node_drains.go
- node_events.go
- node_join_command.go
- node_memory_attribution.go
- node_metrics.go
- node_move_exec.go
- node_moves.go
- node_patch_status.go
- node_provider_connect.go
- node_provision.go
- node_resource_usage.go
- node_ssh_provision.go
- nodes.go
- nodes_list.go
- notification_channels.go
- notify_redact.go
- oauth.go
- oauth_client.go
- oauth_settings.go
- oauth_state.go
- observability_settings.go
- onboarding.go
- openapi.go
- openapi_gen.go
- organization_env.go
- organizations.go
- orphans.go
- package_registries.go
- passkeys.go
- password_reset.go
- pending_changes.go
- pending_state.go
- pipelines.go
- pipelines_events.go
- pipelines_oidc.go
- pipelines_overview.go
- pipelines_report.go
- pipelines_sync.go
- pitr.go
- placement_names.go
- platform_import.go
- preflight.go
- preview.go
- preview_comment.go
- preview_comment_providers.go
- preview_environments.go
- preview_environments_bitbucket.go
- preview_environments_database_isolation.go
- preview_environments_databases.go
- preview_environments_gitea.go
- preview_environments_github.go
- preview_environments_gitlab.go
- preview_environments_handlers.go
- preview_environments_notify.go
- preview_environments_policy_handlers.go
- preview_environments_sweep.go
- preview_environments_teardown.go
- preview_lifecycle.go
- preview_lifecycle_deploy.go
- preview_lifecycle_policy.go
- preview_orphans.go
- preview_pipeline_env.go
- preview_policy.go
- project_env.go
- project_restart.go
- project_stop_start.go
- projects.go
- prometheus.go
- promote.go
- promote_diff.go
- promote_env_snapshot.go
- proxy_integration.go
- proxy_integration_actions.go
- proxy_integration_detect.go
- proxy_integration_setup.go
- push_subscriptions.go
- quota.go
- quota_changes.go
- ratelimit.go
- readyz.go
- registry_catalog.go
- registry_credential_probe.go
- registry_credentials.go
- registry_settings.go
- request_logging.go
- request_origin.go
- requests.go
- resource_advice_attention.go
- resource_advisor.go
- resource_advisor_apply.go
- resource_advisor_collect.go
- resource_recommendation.go
- resource_ref_authz.go
- resources_live_apply.go
- respond.go
- restore.go
- reverse_proxy_guide.go
- roles.go
- roles_handlers.go
- roles_store.go
- route53_dns.go
- router.go
- router_options.go
- routes.go
- routes_alert_noise.go
- routes_app_import.go
- routes_backup_coverage.go
- routes_compliance.go
- routes_compose.go
- routes_database_access.go
- routes_database_upgrades.go
- routes_deploy_gate.go
- routes_deploy_policy.go
- routes_dns_zones.go
- routes_docker_guard.go
- routes_domain_policies.go
- routes_env_protection.go
- routes_event_webhooks.go
- routes_export.go
- routes_fixit.go
- routes_iac.go
- routes_iam_builder.go
- routes_iam_templates.go
- routes_jobs.go
- routes_loadbalancer.go
- routes_log_explorer.go
- routes_maintenance.go
- routes_mobile.go
- routes_models.go
- routes_multinode.go
- routes_pipelines.go
- routes_pipelines_overview.go
- routes_platform.go
- routes_platform_import.go
- routes_preview.go
- routes_proxy_integration.go
- routes_resource_advisor.go
- routes_secretscan.go
- routes_security.go
- routes_setup_guide.go
- routes_sso.go
- routes_standalone_domains.go
- routes_status_page.go
- routes_storage.go
- routes_supplychain.go
- routes_teams.go
- routes_traffic.go
- routes_usage_cost.go
- scheduled_tasks.go
- scheduling.go
- scim_proxy.go
- scim_reconcile.go
- scim_tokens.go
- secret_binding.go
- secret_rotation.go
- secret_rotation_policies.go
- secrets.go
- secretscan.go
- secure_request.go
- security_anomaly.go
- security_policy.go
- security_posture.go
- security_posture_rules.go
- security_sessions.go
- security_signin_alert.go
- security_token_hygiene.go
- self_upgrade.go
- server_address.go
- server_readiness.go
- service_templates.go
- service_templates_custom.go
- service_templates_install.go
- session_links.go
- setup_guide.go
- setup_token.go
- shared_env_secrets.go
- sign_in_labels.go
- sign_in_requests.go
- slo.go
- sso_glue.go
- sso_saml_admin.go
- sso_saml_flow.go
- sso_saml_user.go
- sso_settings.go
- standalone_candidates.go
- standalone_domains.go
- standalone_domains_safety.go
- standalone_scope.go
- static_sites.go
- static_sites_delete.go
- status.go
- status_page.go
- status_page_public.go
- step_up.go
- step_up_handlers.go
- storage_destinations.go
- storage_env_keys.go
- storage_orphans.go
- store_interfaces.go
- stream_reauth.go
- supplychain.go
- system_networks.go
- system_prune.go
- system_restart.go
- tags.go
- team_access.go
- team_access_lists.go
- team_gate.go
- team_invites.go
- team_members.go
- team_scope.go
- team_tokens.go
- teams.go
- terminal.go
- tls_owner.go
- tokens.go
- topology.go
- topology_graph.go
- traces.go
- traffic_summary.go
- twofactor.go
- updates.go
- updates_edge.go
- updates_history.go
- updates_notes.go
- updates_preflight.go
- updates_releases.go
- updates_schedule.go
- updates_schedule_host.go
- updates_settings.go
- usage_cost.go
- usage_cost_service.go
- usage_cost_settings.go
- usage_summary.go
- users.go
- users_lifecycle.go
- vault_settings.go
- visibility.go
- volumes_orphaned.go
- webhook_deliveries.go
- webhook_delivery_retention.go
- whoami.go