apiclient

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Sep 9, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package apiclient is the one HTTP client implementation for the control plane's versioned API (internal/api, mounted at /api/v1). cmd/levelrail-cli and cmd/levelrail-mcp both import this package rather than each rolling their own: they are exactly the external callers the documented wire contract in internal/api exists for (see internal/store/tokens.go's own doc comment on APIToken), so neither gets special internal access, only this same bearer-token HTTP client. Wire-shape request/response types live in types.go; this file is the Client type itself and its methods.

Index

Constants

View Source
const (
	EnvAPIToken = "APP_API_TOKEN" //nolint:gosec // this is the name of an env var, not a credential value
	EnvAPIURL   = "APP_API_URL"
	EnvProfile  = "APP_PROFILE"
)

EnvAPIToken, EnvAPIURL, and EnvProfile are this project's established APP_*-env-var-prefix convention (see internal/brand's own envPrefix, and cmd/levelrail/main.go's APP_DATA_DIR/APP_HTTP_ADDR/etc.), not a product-name-specific prefix: renaming the product later must not require renaming these. Every caller of this package (the CLI, the MCP server) uses these same names, so a token or URL set for one is already set for the other.

View Source
const CredentialsFileName = "credentials"

CredentialsFileName is the file ReadCredentialsFile reads, inside a directory named after the caller's own binary (ConfigDir below), not a hardcoded product name.

View Source
const DefaultAPIURL = "http://localhost:8080"

DefaultAPIURL is a zero-config local default, so a caller with no flag, env var, or credentials file still reaches a locally running control plane out of the box: its own defaultHTTPAddr (cmd/levelrail/main.go) is ":8080", so this is that same port on loopback.

View Source
const DefaultProfile = "default"

DefaultProfile is the section ResolveProfile falls back to when neither a --profile flag nor APP_PROFILE is set, and the section an old, pre-profile flat credentials file (no "[section]" headers at all) is read as, for backward compatibility with every credentials file written before profile support existed.

Variables

This section is empty.

Functions

func ConfigDir

func ConfigDir(prog string) (string, error)

ConfigDir is "~/.config/<prog>", prog being the caller's own binary basename (filepath.Base(os.Args[0])), never a hardcoded product name: this makes the credentials file location follow the binary automatically if it's ever renamed, the same rebrandability property required everywhere else in this codebase.

func ExtractErrorMessage

func ExtractErrorMessage(data []byte) string

ExtractErrorMessage parses the control plane's {"error": "..."} body shape (internal/api/respond.go). A body that doesn't match that shape (a proxy's HTML error page, an empty body) falls back to the raw text so the caller still sees something, not a blank message. Exported so callers with their own hand-rolled request (outside this Client, e.g. the CLI's session-cookie authSessionClient) can reuse the same parsing rather than duplicating it.

func PathEscape

func PathEscape(s string) string

PathEscape guards against a name containing characters that would otherwise change the request's URL shape (a "/" turning one path segment into two, for instance). Server-side validation is the real authority on what a valid app name is; this only protects request construction from building a request to the wrong path. Exported for the same reuse reason as ExtractErrorMessage.

func ResolveAPIURL

func ResolveAPIURL(flagURL string, lookupEnv func(string) (string, bool), prog, profile string) string

ResolveAPIURL picks the base API URL by precedence: flagURL, then EnvAPIURL, then profile's section of the credentials file, then DefaultAPIURL.

func ResolveProfile

func ResolveProfile(flagProfile string, lookupEnv func(string) (string, bool)) string

ResolveProfile picks the active profile name by precedence: flagProfile, then EnvProfile, then DefaultProfile. It never returns an empty string.

func ResolveToken

func ResolveToken(flagToken string, lookupEnv func(string) (string, bool), prog, profile string) string

ResolveToken picks an API token by precedence: flagToken, then EnvAPIToken, then profile's section of the local credentials file. Returns "" (not an error) if none is set: an empty token is a valid, if unlikely to succeed, thing to send, and letting the server's own 401 be what reports "not authenticated" keeps this function from duplicating that judgment.

func WriteCredentialsFile

func WriteCredentialsFile(prog, profile string, creds Credentials) error

WriteCredentialsFile writes creds under profile's section in prog's credentials file, creating ConfigDir(prog) if it doesn't exist yet, and leaving every other profile section already in the file untouched. "auth login" is this function's only caller today: it is the one command that produces a credential rather than just consuming one. 0o600 on both the directory and the file, tighter than ReadCredentialsFile's own comment on the file needing to stay hand-editable: a freshly minted API token is a live credential, not a value that should ever be group- or world-readable by default.

Types

type APIError

type APIError struct {
	StatusCode int
	Message    string
	// RetryAfter is parsed from the response's Retry-After header
	// (seconds form only, the only form this control plane ever sends),
	// 0 when absent. Currently only the general per-actor rate limiter
	// (429 Too Many Requests, internal/api/api_rate_limit.go) sets it,
	// but any future response carrying the header gets the same
	// treatment for free.
	RetryAfter time.Duration
}

APIError is returned by Client methods for a non-2xx HTTP response: a real reply from the server, as opposed to a network-level failure (connection refused, DNS, timeout), which Client methods return as a plain wrapped error instead. Callers distinguish the two with errors.As, which is what picks the CLI's exit code and lets the MCP server surface a specific tool error (e.g. a 403's "token lacks the required ability" message) rather than a generic failure.

func (*APIError) Error

func (e *APIError) Error() string

type AlertRuleResource

type AlertRuleResource struct {
	ID         string `json:"id,omitempty"`
	Name       string `json:"name"`
	Kind       string `json:"kind"`
	ResourceID string `json:"resource_id,omitempty"`
	ChannelID  string `json:"channel_id,omitempty"`

	Metric      string  `json:"metric,omitempty"`
	Comparator  string  `json:"comparator,omitempty"`
	Threshold   float64 `json:"threshold"`
	ForDuration string  `json:"for_duration,omitempty"`

	RestartCountThreshold int    `json:"restart_count_threshold"`
	RestartWindow         string `json:"restart_window,omitempty"`

	ScheduledTaskID string `json:"scheduled_task_id,omitempty"`

	NotifyURL  string `json:"notify_url,omitempty"`
	NotifyKind string `json:"notify_kind,omitempty"`
	Enabled    bool   `json:"enabled"`

	Firing          bool       `json:"firing,omitempty"`
	PendingSince    *time.Time `json:"pending_since,omitempty"`
	FiringSince     *time.Time `json:"firing_since,omitempty"`
	LastEvaluatedAt *time.Time `json:"last_evaluated_at,omitempty"`
	LastValue       *float64   `json:"last_value,omitempty"`
}

AlertRuleResource mirrors internal/api's ruleResource (internal/api/alerts.go). Threshold-kind fields (Metric, Comparator, Threshold, ForDuration) and crashloop-kind fields (RestartCountThreshold, RestartWindow) are both present on the wire; only the ones matching Kind are meaningful, mirroring alerting.Rule's own shape. A kind=cert_expiry rule uses neither group: it watches every stored certificate platform-wide, not this rule's own resource_id.

type AppDatabaseResource

type AppDatabaseResource struct {
	AppName      string `json:"app_name,omitempty"`
	DatabaseName string `json:"database_name"`
	EnvVar       string `json:"env_var"`
	Field        string `json:"field"`
}

AppDatabaseResource mirrors internal/api's appDatabaseResource: PUT /api/v1/apps/{name}/database's response body.

type AppGroupResource

type AppGroupResource struct {
	AppID    string           `json:"app_id,omitempty"`
	Services []AppResource    `json:"services"`
	Status   AppStatusSummary `json:"status"`
}

AppGroupResource mirrors internal/api's appGroupResource (internal/api/apps_group.go): GET /api/v1/apps/{name}/group's response, name's sibling services under the same store.App plus one rollup status across all of them.

type AppHookRunsResource

type AppHookRunsResource struct {
	PreDeploy  *HookRunResource `json:"pre_deploy,omitempty"`
	PostDeploy *HookRunResource `json:"post_deploy,omitempty"`
}

AppHookRunsResource mirrors internal/api's appHookRunsResource: nil fields mean that hook has never run, not an empty HookRunResource.

type AppMetricsResource

type AppMetricsResource struct {
	Metric string                `json:"metric"`
	Points []MetricPointResource `json:"points"`
}

AppMetricsResource mirrors internal/api's metricsResponse (internal/api/metrics.go).

type AppResource

type AppResource struct {
	Name  string `json:"name"`
	Image string `json:"image"`
	Port  int    `json:"port"`
	// HostPort mirrors internal/api's appResource.HostPort: nil means
	// "let Docker assign one", a value pins the host-side port. Settable
	// on create and update, like Port.
	HostPort  *int              `json:"host_port,omitempty"`
	Domains   []string          `json:"domains,omitempty"`
	Env       map[string]string `json:"env,omitempty"`
	Resources *ServiceResources `json:"resources,omitempty"`
	Health    *ServiceHealth    `json:"health,omitempty"`
	// Hooks mirrors internal/api's appResource.Hooks: settable on create
	// and update, like Resources/Health above.
	Hooks  *ServiceHooks `json:"hooks,omitempty"`
	NodeID string        `json:"node_id,omitempty"`
	// ProjectID mirrors internal/api's appResource.ProjectID:
	// response-only, set via PUT /api/v1/apps/{name}/project.
	ProjectID string `json:"project_id,omitempty"`
	// EnvironmentID mirrors internal/api's appResource.EnvironmentID:
	// response-only, set via PUT /api/v1/apps/{name}/environment.
	EnvironmentID string `json:"environment_id,omitempty"`
	// EnvDirty mirrors internal/api's appResource.EnvDirty: true means
	// Env was saved since the running container was last recreated, so
	// the change is not live yet. Clears on restart or redeploy.
	EnvDirty bool `json:"env_dirty"`
	// Volumes mirrors internal/api's appResource.Volumes: this app's
	// declared named Docker volumes, response-only (declared through
	// app.yaml, not settable here).
	Volumes []AppVolumeResource `json:"volumes,omitempty"`
}

AppResource mirrors internal/api's appResource (apps.go). Field order and JSON tags match exactly, so a response decodes cleanly and a request encodes into exactly what the server expects.

type AppStatusSummary

type AppStatusSummary struct {
	Label   string `json:"label"`
	Variant string `json:"variant"`
}

AppStatusSummary mirrors internal/api's appStatusSummary (internal/api/app_status.go): a compact category rollup, not the raw conditions list ConditionResource carries.

type AppVolumeResource

type AppVolumeResource struct {
	Name          string `json:"name"`
	ContainerPath string `json:"container_path"`
}

AppVolumeResource mirrors internal/api's appVolumeResource (app_volumes.go): one of an app's named Docker volumes, identified by its logical name (what an operator wrote in app.yaml), not the resolved, platform-prefixed Docker volume name.

type AttachPolicyRequest

type AttachPolicyRequest struct {
	PrincipalType string `json:"principal_type"`
	PrincipalID   string `json:"principal_id"`
}

AttachPolicyRequest mirrors internal/api's attachPolicyRequest.

type AuditLogEntryResource

type AuditLogEntryResource struct {
	ID         string `json:"id"`
	ActorType  string `json:"actor_type"`
	ActorID    string `json:"actor_id"`
	ActorName  string `json:"actor_name"`
	Ability    string `json:"ability"`
	Method     string `json:"method"`
	Path       string `json:"path"`
	StatusCode int    `json:"status_code"`
	RemoteAddr string `json:"remote_addr"`
	CreatedAt  string `json:"created_at"`
	ClientKind string `json:"client_kind"`
}

AuditLogEntryResource mirrors internal/api's auditLogEntryResource (internal/api/audit.go).

type BackupHistoryResource

type BackupHistoryResource struct {
	ID             string `json:"id"`
	DatabaseName   string `json:"database_name,omitempty"`
	ServiceName    string `json:"service_name,omitempty"`
	VolumeName     string `json:"volume_name,omitempty"`
	TargetID       string `json:"target_id"`
	ObjectKey      string `json:"object_key"`
	SizeBytes      int64  `json:"size_bytes"`
	Status         string `json:"status"`
	Error          string `json:"error,omitempty"`
	StartedAt      string `json:"started_at"`
	FinishedAt     string `json:"finished_at,omitempty"`
	ChecksumSHA256 string `json:"checksum_sha256,omitempty"`
}

BackupHistoryResource mirrors internal/api's backupHistoryResource (internal/api/backups.go). ServiceName/VolumeName are set instead of DatabaseName for an app service volume backup, never alongside it.

type BackupScheduleResource

type BackupScheduleResource struct {
	DatabaseName string `json:"database_name"`
	TargetID     string `json:"target_id,omitempty"`
	Schedule     string `json:"schedule,omitempty"`
	Retain       int    `json:"retain,omitempty"`
	RetainDays   int    `json:"retain_days,omitempty"`
}

BackupScheduleResource mirrors internal/api's backupScheduleResource (internal/api/backups.go): PUT/DELETE .../backup-schedule only ever touch these three fields, never the full database resource.

type BackupTargetResource

type BackupTargetResource struct {
	ID        string `json:"id"`
	Name      string `json:"name"`
	Provider  string `json:"provider"`
	Endpoint  string `json:"endpoint,omitempty"`
	Region    string `json:"region,omitempty"`
	Bucket    string `json:"bucket"`
	CreatedAt string `json:"created_at"`
}

BackupTargetResource mirrors internal/api's backupTargetResource (internal/api/backup_targets.go). No credential fields: access_key_id and secret_access_key are write-only, accepted through CreateBackupTargetRequest/UpdateBackupTargetRequest and never echoed back in any response.

type BackupVerificationResource

type BackupVerificationResource struct {
	ID              string `json:"id"`
	BackupHistoryID string `json:"backup_history_id"`
	Status          string `json:"status"`
	ChecksumMatch   bool   `json:"checksum_match"`
	SizeMatch       bool   `json:"size_match"`
	FormatValid     bool   `json:"format_valid"`
	DownloadedBytes int64  `json:"downloaded_bytes"`
	Error           string `json:"error,omitempty"`
	CheckedBy       string `json:"checked_by,omitempty"`
	StartedAt       string `json:"started_at"`
	FinishedAt      string `json:"finished_at,omitempty"`
}

BackupVerificationResource mirrors internal/api's backupVerificationResource (internal/api/backup_verify.go).

type BuildTriggerRequest

type BuildTriggerRequest struct {
	RepoURL   string                   `json:"repo_url"`
	Ref       string                   `json:"ref"`
	ImageRepo string                   `json:"image_repo,omitempty"`
	Build     BuildTriggerRequestBuild `json:"build,omitempty"`
}

BuildTriggerRequest mirrors internal/api's triggerBuildRequest (internal/api/builds.go). Ref is required server-side (handleTriggerBuild rejects an empty one with 400), so every caller of TriggerBuild must resolve a real ref before sending this, never leave it blank.

type BuildTriggerRequestBuild

type BuildTriggerRequestBuild struct {
	Type string `json:"type,omitempty"`
	Path string `json:"path,omitempty"`
	// BaseDirectory scopes the build context to a subdirectory of the
	// repo, for a monorepo. Not meaningful for Type == "image".
	BaseDirectory string `json:"base_directory,omitempty"`
	Image         string `json:"image,omitempty"`
	// Args are Dockerfile build-time ARG values. Only meaningful for
	// Type == "dockerfile".
	Args map[string]string `json:"args,omitempty"`
}

BuildTriggerRequestBuild is BuildTriggerRequest's nested build.* input (internal/api/builds.go's triggerBuildBuildInput), matching the same fields app.yaml's own build: block has. Type left empty defaults server-side to a Dockerfile build. Image is only meaningful for Type == "image": a prebuilt registry reference deployed as-is, no repo/ref/build needed.

type BuildTriggerResponse

type BuildTriggerResponse struct {
	Image string      `json:"image"`
	App   AppResource `json:"app"`
}

BuildTriggerResponse mirrors internal/api's triggerBuildResponse: the real built image tag plus the app's full, now-updated resource.

type Client

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

Client is a minimal HTTP client for the control plane's versioned API (internal/api, mounted at /api/v1). It carries no session/cookie state: every request is a single bearer-token call, matching how this project's own token scheme (internal/api/abilities.go) is meant to be used by a non-interactive caller.

func NewClient

func NewClient(baseURL, token string, opts ...Option) *Client

NewClient builds a Client. baseURL should not have a trailing slash (trimmed defensively if it does). The timeout is long, not the usual few seconds a typical REST call would use: POST .../builds is synchronous and blocking (internal/api/builds.go's own doc comment), and a real Dockerfile build can legitimately take minutes.

func (*Client) AttachPolicy

func (c *Client) AttachPolicy(ctx context.Context, id string, req AttachPolicyRequest) error

AttachPolicy calls POST /api/v1/iam/policies/{id}/attachments.

func (*Client) ClearAppDatabaseAttachment

func (c *Client) ClearAppDatabaseAttachment(ctx context.Context, name string) error

ClearAppDatabaseAttachment calls DELETE /api/v1/apps/{name}/database.

func (*Client) ClearBackupSchedule

func (c *Client) ClearBackupSchedule(ctx context.Context, name string) error

ClearBackupSchedule calls DELETE /api/v1/databases/{name}/backup-schedule: returns name to its default "no scheduled backup configured" state. Past backup_history rows are untouched, only the going-forward configuration.

func (*Client) ClearDomainBasicAuth

func (c *Client) ClearDomainBasicAuth(ctx context.Context, name, domain string) (DomainBasicAuthResource, error)

ClearDomainBasicAuth calls DELETE /api/v1/apps/{name}/domains/{domain}/auth: removes basic auth protection from domain.

func (*Client) ClearDomainMaintenance

func (c *Client) ClearDomainMaintenance(ctx context.Context, name, domain string) (DomainMaintenanceResource, error)

ClearDomainMaintenance calls DELETE /api/v1/apps/{name}/domains/{domain}/maintenance: disables maintenance mode on domain.

func (*Client) ClearDomainTLSCert

func (c *Client) ClearDomainTLSCert(ctx context.Context, name, domain string) (DomainTLSCertResource, error)

ClearDomainTLSCert calls DELETE /api/v1/apps/{name}/domains/{domain}/tls-cert: removes domain's BYO certificate, reverting it to automatic ACME/internal issuance.

func (*Client) ClearLogDrain

func (c *Client) ClearLogDrain(ctx context.Context, name string) error

ClearLogDrain calls DELETE /api/v1/apps/{name}/log-drain. No response body (204 on success), matching SetSecret's own "no body beyond the status" shape above.

func (*Client) ClearVolumeBackupSchedule

func (c *Client) ClearVolumeBackupSchedule(ctx context.Context, name, volume string) error

ClearVolumeBackupSchedule calls DELETE /api/v1/apps/{name}/volumes/{volume}/backup-schedule: the app service volume counterpart of ClearBackupSchedule.

func (*Client) CompareDeploys

func (c *Client) CompareDeploys(ctx context.Context, name, from, to string) (DeployCompareResource, error)

CompareDeploys calls GET /api/v1/apps/{name}/deploys/compare: a before/after diff of deploy attempt from against to, or against the app's current live state when to is empty.

func (*Client) CordonNode

func (c *Client) CordonNode(ctx context.Context, id string) (NodeResource, error)

CordonNode calls POST /api/v1/nodes/{id}/cordon: marks id unschedulable for new placements without evacuating anything already running there.

func (*Client) CreateAlertRule

func (c *Client) CreateAlertRule(ctx context.Context, name string, req CreateAlertRuleRequest) (AlertRuleResource, error)

CreateAlertRule calls POST /api/v1/apps/{name}/alerts.

func (*Client) CreateApp

func (c *Client) CreateApp(ctx context.Context, req AppResource) (AppResource, error)

CreateApp calls POST /api/v1/apps.

func (*Client) CreateBackupTarget

func (c *Client) CreateBackupTarget(ctx context.Context, req CreateBackupTargetRequest) (BackupTargetResource, error)

CreateBackupTarget calls POST /api/v1/backup-targets.

func (*Client) CreateDatabase

func (c *Client) CreateDatabase(ctx context.Context, req DatabaseResource) (DatabaseResource, error)

CreateDatabase calls POST /api/v1/databases.

func (*Client) CreateEnvironment

func (c *Client) CreateEnvironment(ctx context.Context, projectID string, req CreateEnvironmentRequest) (EnvironmentResource, error)

CreateEnvironment calls POST /api/v1/projects/{id}/environments.

func (*Client) CreateFeatureFlag

func (c *Client) CreateFeatureFlag(ctx context.Context, name string, req FeatureFlagRequest) (FeatureFlagResource, error)

CreateFeatureFlag calls POST /api/v1/apps/{name}/flags.

func (*Client) CreateInvite

func (c *Client) CreateInvite(ctx context.Context, req CreateInviteRequest) (CreateInviteResponse, error)

CreateInvite calls POST /api/v1/invites.

func (*Client) CreateNodeJoinToken

func (c *Client) CreateNodeJoinToken(ctx context.Context) (CreateNodeJoinTokenResponse, error)

CreateNodeJoinToken calls POST /api/v1/nodes/join-tokens: mints a one-time enrollment token, returned in plaintext exactly once.

func (*Client) CreateNotificationChannel

func (c *Client) CreateNotificationChannel(ctx context.Context, req CreateNotificationChannelRequest) (NotificationChannelResource, error)

CreateNotificationChannel calls POST /api/v1/notification-channels.

func (*Client) CreateOrganization

func (c *Client) CreateOrganization(ctx context.Context, req CreateOrganizationRequest) (OrganizationResource, error)

CreateOrganization calls POST /api/v1/organizations.

func (*Client) CreatePolicy

func (c *Client) CreatePolicy(ctx context.Context, req PolicyRequest) (PolicyResource, error)

CreatePolicy calls POST /api/v1/iam/policies.

func (*Client) CreateProject

func (c *Client) CreateProject(ctx context.Context, req CreateProjectRequest) (ProjectResource, error)

CreateProject calls POST /api/v1/projects.

func (*Client) CreateRegistryCredential

func (c *Client) CreateRegistryCredential(ctx context.Context, req CreateRegistryCredentialRequest) (RegistryCredentialResource, error)

CreateRegistryCredential calls POST /api/v1/registry-credentials.

func (*Client) CreateScheduledTask

func (c *Client) CreateScheduledTask(ctx context.Context, name string, req ScheduledTaskRequest) (ScheduledTaskResource, error)

CreateScheduledTask calls POST /api/v1/apps/{name}/scheduled-tasks.

func (*Client) CreateUser

func (c *Client) CreateUser(ctx context.Context, req CreateUserRequest) (UserResource, error)

CreateUser calls POST /api/v1/auth/users.

func (*Client) DeleteAlertRule

func (c *Client) DeleteAlertRule(ctx context.Context, name, id string) error

DeleteAlertRule calls DELETE /api/v1/apps/{name}/alerts/{id}.

func (*Client) DeleteApp

func (c *Client) DeleteApp(ctx context.Context, name string) error

DeleteApp calls DELETE /api/v1/apps/{name}: removes the app's desired state (internal/api/apps.go's own handleDeleteApp doc comment covers the known gap that this does not itself stop the running container).

func (*Client) DeleteBackupTarget

func (c *Client) DeleteBackupTarget(ctx context.Context, id string) error

DeleteBackupTarget calls DELETE /api/v1/backup-targets/{id}.

func (*Client) DeleteDatabase

func (c *Client) DeleteDatabase(ctx context.Context, name string) error

DeleteDatabase calls DELETE /api/v1/databases/{name}.

func (*Client) DeleteEnvironment

func (c *Client) DeleteEnvironment(ctx context.Context, id string) error

DeleteEnvironment calls DELETE /api/v1/environments/{id}.

func (*Client) DeleteFeatureFlag

func (c *Client) DeleteFeatureFlag(ctx context.Context, name, id string) error

DeleteFeatureFlag calls DELETE /api/v1/apps/{name}/flags/{id}.

func (*Client) DeleteGitSource

func (c *Client) DeleteGitSource(ctx context.Context, name string) error

DeleteGitSource calls DELETE /api/v1/apps/{name}/git-source.

func (*Client) DeleteNode

func (c *Client) DeleteNode(ctx context.Context, id string) error

DeleteNode calls DELETE /api/v1/nodes/{id}. Refused with a 409 (*APIError) while any service or database is still placed on id, telling the caller to drain first (handleDeleteNode's own doc comment).

func (*Client) DeleteNotificationChannel

func (c *Client) DeleteNotificationChannel(ctx context.Context, id string) error

DeleteNotificationChannel calls DELETE /api/v1/notification-channels/{id}.

func (*Client) DeleteOrganization

func (c *Client) DeleteOrganization(ctx context.Context, id string) error

DeleteOrganization calls DELETE /api/v1/organizations/{id}.

func (*Client) DeletePolicy

func (c *Client) DeletePolicy(ctx context.Context, id string) error

DeletePolicy calls DELETE /api/v1/iam/policies/{id}.

func (*Client) DeleteProject

func (c *Client) DeleteProject(ctx context.Context, id string) error

DeleteProject calls DELETE /api/v1/projects/{id}.

func (*Client) DeleteRegistryCredential

func (c *Client) DeleteRegistryCredential(ctx context.Context, id string) error

DeleteRegistryCredential calls DELETE /api/v1/registry-credentials/{id}.

func (*Client) DeleteScheduledTask

func (c *Client) DeleteScheduledTask(ctx context.Context, name, id string) error

DeleteScheduledTask calls DELETE /api/v1/apps/{name}/scheduled-tasks/{id}.

func (*Client) DeleteUser

func (c *Client) DeleteUser(ctx context.Context, id string) error

DeleteUser calls DELETE /api/v1/users/{id}.

func (*Client) DeployApp

func (c *Client) DeployApp(ctx context.Context, name, image string, confirm bool) (AppResource, error)

DeployApp calls POST /api/v1/apps/{name}/deploys: points the app's desired image at image. Asynchronous: this returns as soon as the desired state is saved, not once a container is actually running it. Also how a rollback is done: deploying an older, already-known tag with this same method. confirm must be true to deploy into an app tagged with a protected environment (internal/api/environments.go's environmentNeedsConfirmation); otherwise the call fails with a 409, ignored when the app has no protected environment.

func (*Client) DeployCompose

func (c *Client) DeployCompose(ctx context.Context, name string, composeYAML []byte) (ComposeDeployResult, error)

DeployCompose calls POST /api/v1/apps/{name}/compose with composeYAML as the raw request body. Unlike every other Client method, this doesn't go through do(): handleDeployCompose (internal/api/apps_compose.go) reads the body directly via io.ReadAll and parses it as a compose.yaml document, so the body must be sent as-is, not JSON-marshaled, with Content-Type: text/yaml instead of do()'s hardcoded application/json.

func (*Client) DeploySpec

func (c *Client) DeploySpec(ctx context.Context, name string, req DeploySpecRequest) (DeploySpecResult, error)

DeploySpec calls POST /api/v1/apps/{name}/deploy-spec (internal/api/apps_multi.go's handleDeploySpec): fans req.Services out into N independent builds+deploys under one store.App named name. Synchronous and blocking, same as TriggerBuild, for the identical reason (internal/api/apps_multi.go's own doc comment).

func (*Client) DetachPolicy

func (c *Client) DetachPolicy(ctx context.Context, id, principalType, principalID string) error

DetachPolicy calls DELETE /api/v1/iam/policies/{id}/attachments/{principalType}/{principalID}.

func (*Client) DiagnoseApp

func (c *Client) DiagnoseApp(ctx context.Context, name, deployID string) (DiagnosisResource, error)

DiagnoseApp calls GET /api/v1/apps/{name}/diagnose (internal/api/diagnose.go's handleDiagnoseApp): a read-only, deterministic explanation of the app's newest deploy failure or crashloop state. deployID pins the diagnosis to one past attempt (?deploy_id=); empty means "the app's newest attempt."

func (*Client) DisableRegistry

func (c *Client) DisableRegistry(ctx context.Context) (RegistrySettingsResource, error)

DisableRegistry calls DELETE /api/v1/settings/registry: disables the registry and clears its generated credentials in one step.

func (*Client) DisconnectCloudflareDNS

func (c *Client) DisconnectCloudflareDNS(ctx context.Context) (CloudflareDNSResource, error)

DisconnectCloudflareDNS calls DELETE /api/v1/settings/cloudflare-dns.

func (*Client) DisconnectCloudflareTunnel

func (c *Client) DisconnectCloudflareTunnel(ctx context.Context) (CloudflareTunnelResource, error)

DisconnectCloudflareTunnel calls DELETE /api/v1/settings/cloudflare-tunnel: disables the tunnel and clears the stored token in one step.

func (*Client) DownloadAuditLogCSV

func (c *Client) DownloadAuditLogCSV(ctx context.Context, opts ListAuditLogOptions) ([]byte, error)

DownloadAuditLogCSV calls GET /api/v1/audit-log?format=csv: the same rows ListAuditLog returns, as a raw CSV file rather than JSON. Built as its own request rather than through do(), since the response body is a CSV file to pass through unmodified, not a JSON value to decode.

func (*Client) DrainNode

func (c *Client) DrainNode(ctx context.Context, id, targetNodeID string) (DrainNodeResponse, error)

DrainNode calls POST /api/v1/nodes/{id}/drain?target_node_id=: moves every service and database placed on id to targetNodeID (empty: the local-node sentinel, the server's own default).

func (*Client) EvaluateFeatureFlag

func (c *Client) EvaluateFeatureFlag(ctx context.Context, key, identifier string) (EvaluateFlagResource, error)

EvaluateFeatureFlag calls GET /api/v1/flags/evaluate/{key}, optionally with an identifier query param for consistent percentage-rollout bucketing. Flat, not nested under an app: see internal/api/feature_flags.go's own handleEvaluateFeatureFlag doc comment for why.

func (*Client) ExecApp

func (c *Client) ExecApp(ctx context.Context, name string, req ExecRequest) (ExecResponse, error)

ExecApp calls POST /api/v1/apps/{name}/exec: runs command (plus args) inside the app's currently running container and returns its stdout/stderr/exit code once it finishes. AbilityRoot-gated server-side (internal/api/exec.go's own doc comment: secrets are injected as plaintext env vars, so exec can read them anyway, and must sit behind the tier that boundary implies).

func (*Client) GetApp

func (c *Client) GetApp(ctx context.Context, name string) (AppResource, error)

GetApp calls GET /api/v1/apps/{name}.

func (*Client) GetAppGroup

func (c *Client) GetAppGroup(ctx context.Context, name string) (AppGroupResource, error)

GetAppGroup calls GET /api/v1/apps/{name}/group (internal/api/apps_group.go's handleGetAppGroup): name's sibling services under the same store.App, one call whether name already has siblings or is its own one-service group.

func (*Client) GetAppHookRuns

func (c *Client) GetAppHookRuns(ctx context.Context, name string) (AppHookRunsResource, error)

GetAppHookRuns calls GET /api/v1/apps/{name}/hook-runs (internal/api/apps_hooks.go's handleGetAppHookRuns): the most recent outcome of each of name's pre/post-deploy hooks.

func (*Client) GetAppNetwork

func (c *Client) GetAppNetwork(ctx context.Context, name string) (NetworkResource, error)

GetAppNetwork calls GET /api/v1/apps/{name}/network (internal/api/network.go's handleGetAppNetwork).

func (*Client) GetAppResourceRecommendation

func (c *Client) GetAppResourceRecommendation(ctx context.Context, name string) (ResourceRecommendationResource, error)

GetAppResourceRecommendation calls GET /api/v1/apps/{name}/resource-recommendation (internal/api/resource_recommendation.go's handleAppResourceRecommendation): a read-only, deterministic memory/CPU right-sizing suggestion derived from the app's own historical usage.

func (*Client) GetBackupTarget

func (c *Client) GetBackupTarget(ctx context.Context, id string) (BackupTargetResource, error)

GetBackupTarget calls GET /api/v1/backup-targets/{id}.

func (*Client) GetCloudflareDNS

func (c *Client) GetCloudflareDNS(ctx context.Context) (CloudflareDNSResource, error)

GetCloudflareDNS calls GET /api/v1/settings/cloudflare-dns: the Cloudflare DNS-01 credential's enabled/has_token state, needed for ACME to issue real wildcard certificates (HTTP-01 cannot).

func (*Client) GetCloudflareTunnel

func (c *Client) GetCloudflareTunnel(ctx context.Context) (CloudflareTunnelResource, error)

GetCloudflareTunnel calls GET /api/v1/settings/cloudflare-tunnel: the cloudflared container's configured/observed state, exposing the control plane through a Cloudflare Tunnel instead of an inbound port.

func (*Client) GetDatabase

func (c *Client) GetDatabase(ctx context.Context, name string) (DatabaseResource, error)

GetDatabase calls GET /api/v1/databases/{name}.

func (*Client) GetDatabaseResourceRecommendation

func (c *Client) GetDatabaseResourceRecommendation(ctx context.Context, name string) (ResourceRecommendationResource, error)

GetDatabaseResourceRecommendation calls GET /api/v1/databases/{name}/resource-recommendation (internal/api/database_resource_recommendation.go's handleDatabaseResourceRecommendation): the database-kind counterpart to GetAppResourceRecommendation, same wire shape.

func (*Client) GetDeployStatus

func (c *Client) GetDeployStatus(ctx context.Context, name string) ([]ConditionResource, error)

GetDeployStatus calls GET /api/v1/apps/{name}/deploys: the application controller's current stored reconcile conditions, not a deploy history log (internal/api/deploys.go's own handleDeployHistory doc comment).

func (*Client) GetDomainBasicAuth

func (c *Client) GetDomainBasicAuth(ctx context.Context, name, domain string) (DomainBasicAuthResource, error)

GetDomainBasicAuth calls GET /api/v1/apps/{name}/domains/{domain}/auth: domain's current HTTP Basic Auth state.

func (*Client) GetDomainMaintenance

func (c *Client) GetDomainMaintenance(ctx context.Context, name, domain string) (DomainMaintenanceResource, error)

GetDomainMaintenance calls GET /api/v1/apps/{name}/domains/{domain}/maintenance: domain's current maintenance-mode state.

func (*Client) GetDomainTLSCert

func (c *Client) GetDomainTLSCert(ctx context.Context, name, domain string) (DomainTLSCertResource, error)

GetDomainTLSCert calls GET /api/v1/apps/{name}/domains/{domain}/tls-cert: domain's current BYO certificate state.

func (*Client) GetEnvironmentEnv

func (c *Client) GetEnvironmentEnv(ctx context.Context, id string) (map[string]string, error)

GetEnvironmentEnv calls GET /api/v1/environments/{id}/env.

func (*Client) GetFeatureFlag

func (c *Client) GetFeatureFlag(ctx context.Context, name, id string) (FeatureFlagResource, error)

GetFeatureFlag calls GET /api/v1/apps/{name}/flags/{id}.

func (*Client) GetGitSource

func (c *Client) GetGitSource(ctx context.Context, name string) (GitSourceResource, error)

GetGitSource calls GET /api/v1/apps/{name}/git-source.

func (*Client) GetLogDrain

func (c *Client) GetLogDrain(ctx context.Context, name string) (LogDrainResource, error)

GetLogDrain calls GET /api/v1/apps/{name}/log-drain: the app's currently configured external log-forwarding sink. Returns *APIError with StatusCode 404 (via errors.As) if the app doesn't exist or has no drain configured, the same two-404-cases-in-one shape that route's own doc comment describes.

func (*Client) GetNode

func (c *Client) GetNode(ctx context.Context, id string) (NodeResource, error)

GetNode calls GET /api/v1/nodes/{id}.

func (*Client) GetNodeHealth

func (c *Client) GetNodeHealth(ctx context.Context, id string) ([]ConditionResource, error)

GetNodeHealth calls GET /api/v1/nodes/{id}/health: the node health controller's stored reconcile conditions, the same ConditionResource shape GetDeployStatus returns for an app.

func (*Client) GetNodePatchStatus

func (c *Client) GetNodePatchStatus(ctx context.Context, id string) (NodePatchStatusResource, error)

GetNodePatchStatus calls GET /api/v1/nodes/{id}/patch-status: the latest OS-patch reading HostPatchCollector wrote for id, or Checked == false if it has never checked (unsupported package manager, or the collector hasn't run yet).

func (*Client) GetOnboardingState

func (c *Client) GetOnboardingState(ctx context.Context) (OnboardingStateResource, error)

GetOnboardingState calls GET /api/v1/onboarding: whether the first-run onboarding flow has been completed.

func (*Client) GetOrganization

func (c *Client) GetOrganization(ctx context.Context, id string) (OrganizationResource, error)

GetOrganization calls GET /api/v1/organizations/{id}.

func (*Client) GetOrganizationEnv

func (c *Client) GetOrganizationEnv(ctx context.Context, id string) (map[string]string, error)

GetOrganizationEnv calls GET /api/v1/organizations/{id}/env.

func (*Client) GetPolicy

func (c *Client) GetPolicy(ctx context.Context, id string) (PolicyResource, error)

GetPolicy calls GET /api/v1/iam/policies/{id}.

func (*Client) GetProject

func (c *Client) GetProject(ctx context.Context, id string) (ProjectResource, error)

GetProject calls GET /api/v1/projects/{id}.

func (*Client) GetProjectEnv

func (c *Client) GetProjectEnv(ctx context.Context, id string) (map[string]string, error)

GetProjectEnv calls GET /api/v1/projects/{id}/env.

func (*Client) GetRegistryCredential

func (c *Client) GetRegistryCredential(ctx context.Context, id string) (RegistryCredentialResource, error)

GetRegistryCredential calls GET /api/v1/registry-credentials/{id}.

func (*Client) GetRegistrySettings

func (c *Client) GetRegistrySettings(ctx context.Context) (RegistrySettingsResource, error)

GetRegistrySettings calls GET /api/v1/settings/registry: the built-in registry container's configured/observed state.

func (*Client) GetScheduledTask

func (c *Client) GetScheduledTask(ctx context.Context, name, id string) (ScheduledTaskResource, error)

GetScheduledTask calls GET /api/v1/apps/{name}/scheduled-tasks/{id}.

func (*Client) GetServiceTemplate

func (c *Client) GetServiceTemplate(ctx context.Context, id string) (ServiceTemplateDetail, error)

GetServiceTemplate calls GET /api/v1/service-templates/{id}: one catalog entry, including its full compose.yaml body.

func (*Client) GetSession

func (c *Client) GetSession(ctx context.Context) (SessionInfoResource, error)

GetSession calls GET /api/v1/auth/session using this Client's bearer token, exactly the same auth mechanism every other method on this type uses. The server gates this route with requireAuth, session-cookie-only, by explicit design (internal/api/account.go's handleGetSession doc comment), so a call made through this method always gets back a real, honest 401 "authentication required" for a bearer-token caller, not a client-side bug.

func (*Client) GetSystemDoctor

func (c *Client) GetSystemDoctor(ctx context.Context) (SystemDoctorResource, error)

GetSystemDoctor calls GET /api/v1/system/doctor: the "levelrail-cli doctor" preflight bundle, a superset of GetSystemStatus above.

func (*Client) GetSystemStatus

func (c *Client) GetSystemStatus(ctx context.Context) (SystemStatusResource, error)

GetSystemStatus calls GET /api/v1/system/status: this control plane's own configured/not-configured signals, including local Docker daemon reachability (DockerConnected/DockerError).

func (*Client) GetUpdates

func (c *Client) GetUpdates(ctx context.Context) (UpdatesResource, error)

GetUpdates calls GET /api/v1/updates: the running control plane version against GitHub's latest published release.

func (*Client) GetVolumeBackupSchedule

func (c *Client) GetVolumeBackupSchedule(ctx context.Context, name, volume string) (VolumeBackupScheduleResource, error)

GetVolumeBackupSchedule calls GET /api/v1/apps/{name}/volumes/{volume}/backup-schedule: the app service volume counterpart of the schedule fields riding along on GET .../databases/{name} for a database (a service can have many volumes, so there is no single app resource to embed this in, hence its own dedicated GET here).

func (*Client) ListAlertRules

func (c *Client) ListAlertRules(ctx context.Context, name string) ([]AlertRuleResource, error)

ListAlertRules calls GET /api/v1/apps/{name}/alerts: every alert rule scoped to name, including disabled ones.

func (*Client) ListApps

func (c *Client) ListApps(ctx context.Context) ([]AppResource, error)

ListApps calls GET /api/v1/apps.

func (*Client) ListAuditLog

func (c *Client) ListAuditLog(ctx context.Context, opts ListAuditLogOptions) ([]AuditLogEntryResource, error)

ListAuditLog calls GET /api/v1/audit-log: every recorded write/ deploy/root-tier request, newest first, cursor-paginated by opts.Before.

func (*Client) ListBackupTargets

func (c *Client) ListBackupTargets(ctx context.Context) ([]BackupTargetResource, error)

ListBackupTargets calls GET /api/v1/backup-targets.

func (*Client) ListBackupVerifications

func (c *Client) ListBackupVerifications(ctx context.Context, name, historyID string) ([]BackupVerificationResource, error)

ListBackupVerifications calls GET /api/v1/databases/{name}/backups/{historyId}/verifications: every verification attempt made against one backup, newest first.

func (*Client) ListBackups

func (c *Client) ListBackups(ctx context.Context, name string, opts ListBackupsOptions) ([]BackupHistoryResource, error)

ListBackups calls GET /api/v1/databases/{name}/backups: the full backup attempt history for one database.

func (*Client) ListContainers

func (c *Client) ListContainers(ctx context.Context) ([]ContainerResource, error)

ListContainers calls GET /api/v1/system/containers: every container on this node, whether or not Levelrail manages it.

func (*Client) ListDatabaseEngines

func (c *Client) ListDatabaseEngines(ctx context.Context) ([]DatabaseEngineResource, error)

ListDatabaseEngines calls GET /api/v1/database-engines: every engine this control plane can actually create, backing the creation wizard's engine picker instead of a hardcoded list.

func (*Client) ListDatabases

func (c *Client) ListDatabases(ctx context.Context) ([]DatabaseResource, error)

ListDatabases calls GET /api/v1/databases.

func (*Client) ListDomains

func (c *Client) ListDomains(ctx context.Context) ([]DomainResource, error)

ListDomains calls GET /api/v1/domains: every service_domains row across every app, aggregated in one call.

func (*Client) ListEnvironments

func (c *Client) ListEnvironments(ctx context.Context, projectID string) ([]EnvironmentResource, error)

ListEnvironments calls GET /api/v1/projects/{id}/environments.

func (*Client) ListFeatureFlags

func (c *Client) ListFeatureFlags(ctx context.Context, name string) ([]FeatureFlagResource, error)

ListFeatureFlags calls GET /api/v1/apps/{name}/flags.

func (*Client) ListInvites

func (c *Client) ListInvites(ctx context.Context) ([]InviteResource, error)

ListInvites calls GET /api/v1/invites.

func (*Client) ListNodes

func (c *Client) ListNodes(ctx context.Context) ([]NodeResource, error)

ListNodes calls GET /api/v1/nodes.

func (*Client) ListNotificationChannels

func (c *Client) ListNotificationChannels(ctx context.Context) ([]NotificationChannelResource, error)

ListNotificationChannels calls GET /api/v1/notification-channels.

func (*Client) ListNotificationDeliveries

func (c *Client) ListNotificationDeliveries(ctx context.Context, id string, limit int) ([]NotificationDeliveryResource, error)

ListNotificationDeliveries calls GET /api/v1/notification-channels/{id}/deliveries: this channel's send history, newest first, up to limit rows (0 leaves the server's own default in place).

func (*Client) ListOrganizations

func (c *Client) ListOrganizations(ctx context.Context) ([]OrganizationResource, error)

ListOrganizations calls GET /api/v1/organizations.

func (*Client) ListPolicies

func (c *Client) ListPolicies(ctx context.Context) ([]PolicyResource, error)

ListPolicies calls GET /api/v1/iam/policies.

func (*Client) ListPolicyAttachments

func (c *Client) ListPolicyAttachments(ctx context.Context, id string) ([]PolicyAttachmentResource, error)

ListPolicyAttachments calls GET /api/v1/iam/policies/{id}/attachments.

func (*Client) ListPreviewEnvironments

func (c *Client) ListPreviewEnvironments(ctx context.Context, appName string) ([]PreviewEnvironmentResource, error)

ListPreviewEnvironments calls GET /api/v1/apps/{name}/previews: every active pull-request preview for an app.

func (*Client) ListProjects

func (c *Client) ListProjects(ctx context.Context) ([]ProjectResource, error)

ListProjects calls GET /api/v1/projects.

func (*Client) ListRegistryCredentials

func (c *Client) ListRegistryCredentials(ctx context.Context) ([]RegistryCredentialResource, error)

ListRegistryCredentials calls GET /api/v1/registry-credentials.

func (*Client) ListRoles

func (c *Client) ListRoles(ctx context.Context) ([]RoleResource, error)

ListRoles calls GET /api/v1/roles.

func (*Client) ListScheduledTasks

func (c *Client) ListScheduledTasks(ctx context.Context, name string) ([]ScheduledTaskResource, error)

ListScheduledTasks calls GET /api/v1/apps/{name}/scheduled-tasks.

func (*Client) ListSecrets

func (c *Client) ListSecrets(ctx context.Context, name string) ([]SecretKeyResource, error)

ListSecrets calls GET /api/v1/apps/{name}/secrets: every known secret key for the app with its locked state, never a value.

func (*Client) ListServiceTemplates

func (c *Client) ListServiceTemplates(ctx context.Context) ([]ServiceTemplateListItem, error)

ListServiceTemplates calls GET /api/v1/service-templates: the full catalog, without each entry's Compose body (see ServiceTemplateListItem).

func (*Client) ListUsers

func (c *Client) ListUsers(ctx context.Context) ([]UserResource, error)

ListUsers calls GET /api/v1/users.

func (*Client) ListVolumeBackupVerifications

func (c *Client) ListVolumeBackupVerifications(ctx context.Context, name, volume, historyID string) ([]BackupVerificationResource, error)

ListVolumeBackupVerifications calls GET /api/v1/apps/{name}/volumes/{volume}/backups/{historyId}/verifications: the app service volume counterpart of ListBackupVerifications.

func (*Client) ListVolumeBackups

func (c *Client) ListVolumeBackups(ctx context.Context, name, volume string, opts ListBackupsOptions) ([]BackupHistoryResource, error)

ListVolumeBackups calls GET /api/v1/apps/{name}/volumes/{volume}/backups: the app service volume counterpart of ListBackups.

func (*Client) ListWebhookDeliveries

func (c *Client) ListWebhookDeliveries(ctx context.Context, name string, opts ListWebhookDeliveriesOptions) ([]WebhookDeliveryResource, error)

ListWebhookDeliveries calls GET /api/v1/apps/{name}/webhook-deliveries: recent inbound git-provider webhook requests for name, newest first.

func (*Client) PollDeviceAuthToken

func (c *Client) PollDeviceAuthToken(ctx context.Context, deviceCode string) (DeviceTokenResponse, error)

PollDeviceAuthToken calls POST /api/v1/auth/device/token once. Unauthenticated, same as StartDeviceAuth. Returns *APIError with Message one of "authorization_pending"/"access_denied"/ "expired_token" until the request has been approved; the caller is expected to poll this on an interval (DeviceStartResponse.Interval) until it either returns a token or a terminal error.

func (*Client) PreviewPromotion

func (c *Client) PreviewPromotion(ctx context.Context, name, environmentID, target string) (PromotePreviewResource, error)

PreviewPromotion calls GET /api/v1/apps/{name}/promote/preview: what promoting name's current image into environmentID would change, without applying it. target disambiguates when more than one app in environmentID belongs to the same project; leave it empty to let the server auto-discover the sole candidate.

func (*Client) PromoteApp

func (c *Client) PromoteApp(ctx context.Context, name string, req PromoteAppRequest) (AppResource, error)

PromoteApp calls POST /api/v1/apps/{name}/promote: points the resolved target app's image at name's current image and redeploys it.

func (*Client) PurgeAuditLog

func (c *Client) PurgeAuditLog(ctx context.Context) (PurgeAuditLogResult, error)

PurgeAuditLog calls POST /api/v1/audit-log/purge: deletes every audit_log row older than the control plane's own configured retention window right now, instead of waiting for its next periodic sweep.

func (*Client) QueryAppMetrics

func (c *Client) QueryAppMetrics(ctx context.Context, name, metric string, from, to time.Time, step time.Duration) (AppMetricsResource, error)

QueryAppMetrics calls GET /api/v1/apps/{name}/metrics?metric=&from=&to=&step= (internal/api/metrics.go's handleQueryMetrics). from/to are sent as RFC3339; step of zero omits the query param, matching the server's own "step<=0 means raw unaggregated samples" contract (telemetry.Aggregate).

func (*Client) QueryLogs

func (c *Client) QueryLogs(ctx context.Context, name string, from, to time.Time, q string) ([]LogEntryResource, error)

QueryLogs calls GET /api/v1/apps/{name}/logs?from=&to=&q= (internal/api/logs.go's handleQueryLogs): a real, historical full-text search over already-stored log entries. from/to are sent as RFC3339, the same format the server requires (internal/api's parseTimeRange); q empty means every entry in the window, matching the server's own "empty query" contract.

func (*Client) ReplayWebhookDelivery

func (c *Client) ReplayWebhookDelivery(ctx context.Context, name, id string) (ReplayWebhookDeliveryResult, error)

ReplayWebhookDelivery calls POST /api/v1/apps/{name}/webhook-deliveries/{id}/replay: re-runs a stored delivery's exact payload through the same processing a live webhook takes, which can trigger a real build and deploy.

func (*Client) RestartApp

func (c *Client) RestartApp(ctx context.Context, name string) (AppResource, error)

RestartApp calls POST /api/v1/apps/{name}/restart: force a running container to be recreated with no image change (internal/api/apps.go's own handleRestartApp). No request body; the response is the app's current desired state, unchanged.

func (*Client) RevokeInvite

func (c *Client) RevokeInvite(ctx context.Context, id string) error

RevokeInvite calls DELETE /api/v1/invites/{id}.

func (*Client) RotateMasterKey

func (c *Client) RotateMasterKey(ctx context.Context, newMasterKey string) (RotateMasterKeyResult, error)

RotateMasterKey calls POST /api/v1/system/master-key/rotate: re-wraps every stored DEK from the control plane's currently active master key to newMasterKey, live, in one atomic step.

func (*Client) RunScheduledTask

func (c *Client) RunScheduledTask(ctx context.Context, name, id string) (ScheduledTaskResource, error)

RunScheduledTask calls POST /api/v1/apps/{name}/scheduled-tasks/{id}/run: triggers an immediate run and returns as soon as it starts, not once the command finishes.

func (*Client) SetAppDatabaseAttachment

func (c *Client) SetAppDatabaseAttachment(ctx context.Context, name string, req SetAppDatabaseRequest) (AppDatabaseResource, error)

SetAppDatabaseAttachment calls PUT /api/v1/apps/{name}/database: attaches an existing managed database to name as a real, persisted connection env var source.

func (*Client) SetAppEnvironment

func (c *Client) SetAppEnvironment(ctx context.Context, name, environmentID string) (AppResource, error)

SetAppEnvironment calls PUT /api/v1/apps/{name}/environment. An empty environmentID clears the assignment. Returns the updated app.

func (*Client) SetAppProject

func (c *Client) SetAppProject(ctx context.Context, name, projectID string) (AppResource, error)

SetAppProject calls PUT /api/v1/apps/{name}/project. An empty projectID clears the assignment. Returns the updated app.

func (*Client) SetBackupSchedule

func (c *Client) SetBackupSchedule(ctx context.Context, name string, req SetBackupScheduleRequest) (BackupScheduleResource, error)

SetBackupSchedule calls PUT /api/v1/databases/{name}/backup-schedule: configures a recurring backup, replacing any previously configured schedule for name.

func (*Client) SetCloudflareDNS

SetCloudflareDNS calls PUT /api/v1/settings/cloudflare-dns.

func (*Client) SetCloudflareTunnel

SetCloudflareTunnel calls PUT /api/v1/settings/cloudflare-tunnel.

func (*Client) SetDatabaseProject

func (c *Client) SetDatabaseProject(ctx context.Context, name, projectID string) (DatabaseResource, error)

SetDatabaseProject calls PUT /api/v1/databases/{name}/project. An empty projectID clears the assignment. Returns the updated database.

func (*Client) SetDatabasePublicAccess

func (c *Client) SetDatabasePublicAccess(ctx context.Context, name string, port int) (DatabasePublicAccessResource, error)

SetDatabasePublicAccess calls PUT /api/v1/databases/{name}/public-access: exposes name on the host at port (0 requests auto-assignment).

func (*Client) SetDatabaseResources

func (c *Client) SetDatabaseResources(ctx context.Context, name string, resources *ServiceResources) (DatabaseResource, error)

SetDatabaseResources calls PUT /api/v1/databases/{name}/resources: applies memory/CPU limits to name, replacing whatever was set before.

func (*Client) SetDomainBasicAuth

func (c *Client) SetDomainBasicAuth(ctx context.Context, name, domain string, req SetDomainBasicAuthRequest) (DomainBasicAuthResource, error)

SetDomainBasicAuth calls PUT /api/v1/apps/{name}/domains/{domain}/auth: enables HTTP Basic Auth on domain, enforced by Caddy on the next ingress reconcile pass.

func (*Client) SetDomainMaintenance

func (c *Client) SetDomainMaintenance(ctx context.Context, name, domain string) (DomainMaintenanceResource, error)

SetDomainMaintenance calls PUT /api/v1/apps/{name}/domains/{domain}/maintenance: enables maintenance mode on domain, enforced by Caddy on the next ingress reconcile pass.

func (*Client) SetDomainTLSCert

func (c *Client) SetDomainTLSCert(ctx context.Context, name, domain string, req SetDomainTLSCertRequest) (DomainTLSCertResource, error)

SetDomainTLSCert calls PUT /api/v1/apps/{name}/domains/{domain}/tls-cert: uploads a BYO certificate for domain, used by Caddy in place of automatic ACME/ internal issuance on the next ingress reconcile pass.

func (*Client) SetEnvironmentEnv

func (c *Client) SetEnvironmentEnv(ctx context.Context, id string, vars map[string]string) (map[string]string, error)

SetEnvironmentEnv calls PUT /api/v1/environments/{id}/env: a full replace, mirroring PUT /apps/{name}'s own env field semantics.

func (*Client) SetGitSource

func (c *Client) SetGitSource(ctx context.Context, name string, req SetGitSourceRequest) (GitSourceResource, error)

SetGitSource calls PUT /api/v1/apps/{name}/git-source: connects a repo (creating a new webhook secret) the first time it's called for an app, or edits the connection on every call after.

func (*Client) SetLogDrain

func (c *Client) SetLogDrain(ctx context.Context, name string, req SetLogDrainRequest) (LogDrainResource, error)

SetLogDrain calls PUT /api/v1/apps/{name}/log-drain.

func (*Client) SetNodeWorkloads

func (c *Client) SetNodeWorkloads(ctx context.Context, id string, req SetNodeWorkloadsRequest) (NodeResource, error)

SetNodeWorkloads calls PUT /api/v1/nodes/{id}/workloads: a full replace of both workload flags, not a partial patch, matching handleSetNodeWorkloads' own contract.

func (*Client) SetOrganizationEnv

func (c *Client) SetOrganizationEnv(ctx context.Context, id string, vars map[string]string) (map[string]string, error)

SetOrganizationEnv calls PUT /api/v1/organizations/{id}/env: a full replace, mirroring PUT /apps/{name}'s own env field semantics.

func (*Client) SetPreviewEnabled

func (c *Client) SetPreviewEnabled(ctx context.Context, appName string, enabled bool) (PreviewSettingsResource, error)

SetPreviewEnabled calls PUT /api/v1/apps/{name}/preview-settings, touching only the enabled toggle: post_pr_comments, if previously set, is left unchanged (SetPreviewSettingsRequest's own doc comment).

func (*Client) SetPreviewPostPRComments

func (c *Client) SetPreviewPostPRComments(ctx context.Context, appName string, enabled bool) (PreviewSettingsResource, error)

SetPreviewPostPRComments calls PUT /api/v1/apps/{name}/preview-settings, touching only the post_pr_comments toggle: enabled, if previously set, is left unchanged.

func (*Client) SetProjectEnv

func (c *Client) SetProjectEnv(ctx context.Context, id string, vars map[string]string) (map[string]string, error)

SetProjectEnv calls PUT /api/v1/projects/{id}/env: a full replace, mirroring PUT /apps/{name}'s own env field semantics.

func (*Client) SetProjectOrganization

func (c *Client) SetProjectOrganization(ctx context.Context, projectID, orgID string) (ProjectResource, error)

SetProjectOrganization calls PUT /api/v1/projects/{id}/organization. An empty orgID clears the assignment. Returns the updated project.

func (*Client) SetSecret

func (c *Client) SetSecret(ctx context.Context, name, key, value string, overwriteLocked bool) error

SetSecret calls PUT /api/v1/apps/{name}/secrets/{key}. No response body beyond the status (internal/api/secrets.go's handleSetSecret returns 204 on success), matching that handler's own doc comment on why a secret's value is never echoed back. overwriteLocked bypasses the server's 409-if-locked guard, the same escape hatch the dashboard's SecretsEditor exposes.

func (*Client) SetSecretLock

func (c *Client) SetSecretLock(ctx context.Context, name, key string, locked bool) error

SetSecretLock calls POST /api/v1/apps/{name}/secrets/{key}/lock: toggles the accidental-overwrite guard SetSecret's overwriteLocked bypasses. Reversible either direction, not a permanent write-once marker.

func (*Client) SetVolumeBackupSchedule

func (c *Client) SetVolumeBackupSchedule(ctx context.Context, name, volume string, req SetVolumeBackupScheduleRequest) (VolumeBackupScheduleResource, error)

SetVolumeBackupSchedule calls PUT /api/v1/apps/{name}/volumes/{volume}/backup-schedule: the app service volume counterpart of SetBackupSchedule.

func (*Client) StartApp

func (c *Client) StartApp(ctx context.Context, name string) (AppResource, error)

StartApp calls POST /api/v1/apps/{name}/start: clears the suspended flag StopApp set, letting the reconciler bring the container back.

func (*Client) StartDeviceAuth

func (c *Client) StartDeviceAuth(ctx context.Context, req DeviceStartRequest) (DeviceStartResponse, error)

StartDeviceAuth calls POST /api/v1/auth/device/start. Unauthenticated by design: call it on a Client built with an empty token (NewClient(baseURL, "")).

func (*Client) StopApp

func (c *Client) StopApp(ctx context.Context, name string) (AppResource, error)

StopApp calls POST /api/v1/apps/{name}/stop: marks the service suspended, so the reconciler stops (and leaves stopped) its container on the next pass, without touching desired state otherwise.

func (*Client) SweepPreviewEnvironments

func (c *Client) SweepPreviewEnvironments(ctx context.Context) (SweepPreviewEnvironmentsResult, error)

SweepPreviewEnvironments calls POST /api/v1/previews/sweep: the manual trigger for the TTL fallback that tears down any preview environment whose pull-request-closed webhook never arrived, cross-app.

func (*Client) TeardownPreviewEnvironment

func (c *Client) TeardownPreviewEnvironment(ctx context.Context, appName string, prNumber int) error

TeardownPreviewEnvironment calls POST /api/v1/apps/{name}/previews/{number}/teardown: the manual safety net alongside a pull request's own automatic close-triggered teardown.

func (*Client) TestBackupTarget

func (c *Client) TestBackupTarget(ctx context.Context, id string) error

TestBackupTarget calls POST /api/v1/backup-targets/{id}/test: probes the target's stored credentials against its configured bucket, without uploading or deleting anything.

func (*Client) TestExistingNotificationChannel

func (c *Client) TestExistingNotificationChannel(ctx context.Context, id string) error

TestExistingNotificationChannel calls POST /api/v1/notification-channels/{id}/test: the same real send, against an already-saved channel's own kind/notify_url.

func (*Client) TestNotificationChannel

func (c *Client) TestNotificationChannel(ctx context.Context, kind, notifyURL string) error

TestNotificationChannel calls POST /api/v1/notification-channels/test: fires a real test message via kind/notifyURL without requiring the channel to exist yet.

func (*Client) TestRegistryCredential

func (c *Client) TestRegistryCredential(ctx context.Context, id string) error

TestRegistryCredential calls POST /api/v1/registry-credentials/{id}/test: authenticates the credential's stored username/password against its registry host, without pulling anything.

func (*Client) TriggerBackup

func (c *Client) TriggerBackup(ctx context.Context, name, targetID string) (BackupHistoryResource, error)

TriggerBackup calls POST /api/v1/databases/{name}/backups: starts a real backup of name to targetID and returns as soon as the attempt is recorded and under way, not once the dump and upload actually finish. ListBackups is how a caller finds out whether it did.

func (*Client) TriggerBuild

func (c *Client) TriggerBuild(ctx context.Context, name string, req BuildTriggerRequest) (BuildTriggerResponse, error)

TriggerBuild calls POST /api/v1/apps/{name}/builds.

func (*Client) TriggerCloneRestore

func (c *Client) TriggerCloneRestore(ctx context.Context, name string, req TriggerCloneRestoreRequest) (CloneRestoreResource, error)

TriggerCloneRestore calls POST /api/v1/databases/{name}/restore-as-new: the non-destructive counterpart to TriggerRestore above. Creates a brand-new database and restores a previously succeeded backup of name into it, never touching name's own live data.

func (*Client) TriggerRestore

func (c *Client) TriggerRestore(ctx context.Context, name, backupID string) (RestoreHistoryResource, error)

TriggerRestore calls POST /api/v1/databases/{name}/restore: overwrites name's live data in place from a previously succeeded backup attempt. The single most destructive call this Client makes; callers must gate this behind their own explicit confirmation before ever reaching it.

func (*Client) TriggerVolumeBackup

func (c *Client) TriggerVolumeBackup(ctx context.Context, name, volume, targetID string) (BackupHistoryResource, error)

TriggerVolumeBackup calls POST /api/v1/apps/{name}/volumes/{volume}/backups: the app service volume counterpart of TriggerBackup.

func (*Client) TriggerVolumeCloneRestore

func (c *Client) TriggerVolumeCloneRestore(ctx context.Context, name, volume string, req TriggerVolumeCloneRestoreRequest) (VolumeCloneRestoreResource, error)

TriggerVolumeCloneRestore calls POST /api/v1/apps/{name}/volumes/{volume}/restore-as-new: the app service volume counterpart of TriggerCloneRestore. Creates a brand-new, standalone Docker volume and restores a previously succeeded backup of name/volume into it, never touching that volume's own live contents.

func (*Client) TriggerVolumeRestore

func (c *Client) TriggerVolumeRestore(ctx context.Context, name, volume, backupID string) (RestoreHistoryResource, error)

TriggerVolumeRestore calls POST /api/v1/apps/{name}/volumes/{volume}/restore: overwrites the named app service volume's live contents in place from a previously succeeded backup attempt, the app service volume counterpart of TriggerRestore. The same "single most destructive call" warning TriggerRestore's own doc comment gives applies identically here.

func (*Client) UncordonNode

func (c *Client) UncordonNode(ctx context.Context, id string) (NodeResource, error)

UncordonNode calls POST /api/v1/nodes/{id}/uncordon: the inverse of CordonNode.

func (*Client) UpdateBackupTarget

func (c *Client) UpdateBackupTarget(ctx context.Context, id string, req UpdateBackupTargetRequest) (BackupTargetResource, error)

UpdateBackupTarget calls PUT /api/v1/backup-targets/{id}: a full replace of name/provider/endpoint/region/bucket, matching handleUpdateBackupTarget's own contract. Credentials rotate only when req carries both AccessKeyID and SecretAccessKey.

func (*Client) UpdateEnvironment

func (c *Client) UpdateEnvironment(ctx context.Context, id string, req UpdateEnvironmentRequest) (EnvironmentResource, error)

UpdateEnvironment calls PATCH /api/v1/environments/{id}.

func (*Client) UpdateFeatureFlag

func (c *Client) UpdateFeatureFlag(ctx context.Context, name, id string, req FeatureFlagRequest) (FeatureFlagResource, error)

UpdateFeatureFlag calls PUT /api/v1/apps/{name}/flags/{id}: a full replace of Name/Description/Enabled/RolloutPercentage, not a partial patch, matching handleUpdateFeatureFlag's own contract. Key is never updated once created.

func (*Client) UpdatePolicy

func (c *Client) UpdatePolicy(ctx context.Context, id string, req PolicyRequest) (PolicyResource, error)

UpdatePolicy calls PUT /api/v1/iam/policies/{id}.

func (*Client) UpdateRegistryCredential

func (c *Client) UpdateRegistryCredential(ctx context.Context, id string, req UpdateRegistryCredentialRequest) (RegistryCredentialResource, error)

UpdateRegistryCredential calls PUT /api/v1/registry-credentials/{id}: a full replace of name/registry_host/username, matching handleUpdateRegistryCredential's own contract. The password rotates only when req carries one.

func (*Client) UpdateRegistrySettings

func (c *Client) UpdateRegistrySettings(ctx context.Context, req UpdateRegistrySettingsRequest) (RegistrySettingsResource, error)

UpdateRegistrySettings calls PUT /api/v1/settings/registry.

func (*Client) UpdateScheduledTask

func (c *Client) UpdateScheduledTask(ctx context.Context, name, id string, req ScheduledTaskRequest) (ScheduledTaskResource, error)

UpdateScheduledTask calls PUT /api/v1/apps/{name}/scheduled-tasks/{id}: a full replace of Command/Schedule/Enabled, not a partial patch, matching handleUpdateScheduledTask's own contract.

func (*Client) UpdateUserAbilities

func (c *Client) UpdateUserAbilities(ctx context.Context, id string, req UpdateUserAbilitiesRequest) (UserResource, error)

UpdateUserAbilities calls PUT /api/v1/users/{id}/abilities.

func (*Client) VerifyBackup

func (c *Client) VerifyBackup(ctx context.Context, name, historyID string) (BackupVerificationResource, error)

VerifyBackup calls POST /api/v1/databases/{name}/backups/{historyId}/verify: re-downloads a previously succeeded backup and checks it for corruption, returning as soon as the attempt is recorded and under way, not once the download and checks actually finish. ListBackupVerifications is how a caller finds out whether it passed.

func (*Client) VerifyVolumeBackup

func (c *Client) VerifyVolumeBackup(ctx context.Context, name, volume, historyID string) (BackupVerificationResource, error)

VerifyVolumeBackup calls POST /api/v1/apps/{name}/volumes/{volume}/backups/{historyId}/verify: the app service volume counterpart of VerifyBackup.

type CloneRestoreResource

type CloneRestoreResource struct {
	ID                 string `json:"id"`
	SourceDatabaseName string `json:"source_database_name"`
	NewDatabaseName    string `json:"new_database_name"`
	BackupHistoryID    string `json:"backup_history_id"`
	Status             string `json:"status"`
	Error              string `json:"error,omitempty"`
	StartedAt          string `json:"started_at"`
	FinishedAt         string `json:"finished_at,omitempty"`
}

CloneRestoreResource mirrors internal/api's cloneRestoreResource (internal/api/database_clone_restore.go): one "restore as new database" attempt.

type CloudflareDNSResource

type CloudflareDNSResource struct {
	Enabled  bool `json:"enabled"`
	HasToken bool `json:"has_token"`
}

CloudflareDNSResource mirrors internal/api's cloudflareDNSResource (internal/api/cloudflare_dns.go): GET/PUT/DELETE /api/v1/settings/cloudflare-dns's wire shape. The token itself never appears here in either direction.

type CloudflareTunnelResource

type CloudflareTunnelResource struct {
	Enabled  bool   `json:"enabled"`
	HasToken bool   `json:"has_token"`
	Status   string `json:"status"`
	Message  string `json:"message,omitempty"`
}

CloudflareTunnelResource mirrors internal/api's cloudflareTunnelResource (internal/api/cloudflare_tunnel.go): GET/PUT/DELETE /api/v1/settings/cloudflare-tunnel's wire shape. The token itself never appears here in either direction. A distinct credential and endpoint from CloudflareDNSResource: this one runs the cloudflared container, that one configures ACME's DNS-01 challenge.

type ComposeDeployResult

type ComposeDeployResult struct {
	AppID    string        `json:"app_id"`
	Services []AppResource `json:"services"`
}

ComposeDeployResult mirrors internal/api's composeDeployResponse (internal/api/apps_compose.go).

type ConditionResource

type ConditionResource struct {
	Type               string    `json:"Type"`
	Status             string    `json:"Status"`
	Reason             string    `json:"Reason"`
	Message            string    `json:"Message"`
	LastTransitionTime time.Time `json:"LastTransitionTime"`
}

ConditionResource mirrors internal/reconcile.Condition, the wire shape both GET /api/v1/apps/{name}/deploys (internal/api/deploys.go's handleDeployHistory) and GET /api/v1/databases/{name}/status (internal/api/databases.go's handleDatabaseStatus) return. The source type carries no json struct tags, so its field names are the wire field names verbatim; the tags here just make that explicit rather than relying on encoding/json's case-insensitive match.

type ContainerPortResource

type ContainerPortResource struct {
	ContainerPort int    `json:"container_port"`
	HostPort      int    `json:"host_port"`
	Protocol      string `json:"protocol"`
}

ContainerPortResource mirrors internal/api's containerPortResource.

type ContainerResource

type ContainerResource struct {
	Name    string                  `json:"name"`
	Image   string                  `json:"image"`
	Running bool                    `json:"running"`
	Ports   []ContainerPortResource `json:"ports"`
}

ContainerResource mirrors internal/api's containerResource (internal/api/containers.go): every container on this node, Levelrail-managed or not. Read-only, no id: see that file's own doc comment on why a stop/restart action doesn't belong on this endpoint.

type CreateAlertRuleRequest

type CreateAlertRuleRequest struct {
	Name                  string  `json:"name"`
	Kind                  string  `json:"kind"`
	Metric                string  `json:"metric,omitempty"`
	Comparator            string  `json:"comparator,omitempty"`
	Threshold             float64 `json:"threshold,omitempty"`
	ForDuration           string  `json:"for_duration,omitempty"`
	RestartCountThreshold int     `json:"restart_count_threshold,omitempty"`
	RestartWindow         string  `json:"restart_window,omitempty"`
	// ScheduledTaskID is kind=scheduled_task_failure-only: which of this
	// app's scheduled tasks the rule watches. RestartCountThreshold above
	// doubles as its consecutive-failure threshold.
	ScheduledTaskID string `json:"scheduled_task_id,omitempty"`
	ChannelID       string `json:"channel_id,omitempty"`
	NotifyURL       string `json:"notify_url,omitempty"`
	NotifyKind      string `json:"notify_kind,omitempty"`
	Enabled         bool   `json:"enabled"`
}

CreateAlertRuleRequest mirrors the fields internal/api's ruleResource actually reads from a create request body; id and resource_id always come from the server (alerting.NewRuleID, the app name in the URL), never the body, so this type has no fields for either. A kind=cert_expiry rule needs none of the threshold or crashloop fields below: it watches every stored certificate platform-wide, not this rule's own resource_id.

type CreateBackupTargetRequest

type CreateBackupTargetRequest struct {
	Name            string `json:"name"`
	Provider        string `json:"provider"`
	Endpoint        string `json:"endpoint,omitempty"`
	Region          string `json:"region,omitempty"`
	Bucket          string `json:"bucket"`
	AccessKeyID     string `json:"access_key_id"`
	SecretAccessKey string `json:"secret_access_key"`
}

CreateBackupTargetRequest mirrors internal/api's createBackupTargetRequest: AccessKeyID/SecretAccessKey are required here, unlike UpdateBackupTargetRequest where they're optional.

type CreateEnvironmentRequest

type CreateEnvironmentRequest struct {
	Name      string `json:"name"`
	Protected bool   `json:"protected,omitempty"`
}

CreateEnvironmentRequest mirrors internal/api's createEnvironmentRequest.

type CreateInviteRequest

type CreateInviteRequest struct {
	Email     string   `json:"email"`
	Role      string   `json:"role,omitempty"`
	Abilities []string `json:"abilities,omitempty"`
}

CreateInviteRequest mirrors internal/api's createInviteRequest. Role, when set, takes precedence server-side over Abilities, same precedence CreateUserRequest documents.

type CreateInviteResponse

type CreateInviteResponse struct {
	InviteResource
	Link string `json:"link"`
}

CreateInviteResponse mirrors internal/api's createInviteResponse: the invite plus Link, the accept URL to hand or send to the invited person.

type CreateNodeJoinTokenResponse

type CreateNodeJoinTokenResponse struct {
	Token     string    `json:"token"`
	ExpiresAt time.Time `json:"expires_at"`
}

CreateNodeJoinTokenResponse mirrors internal/api's createNodeJoinTokenResponse: a join token's one and only plaintext appearance, the same "shown once, never recoverable again" shape a created API token uses.

type CreateNotificationChannelRequest

type CreateNotificationChannelRequest struct {
	Name      string `json:"name"`
	Kind      string `json:"kind"`
	NotifyURL string `json:"notify_url"`
	Enabled   *bool  `json:"enabled,omitempty"`
}

CreateNotificationChannelRequest mirrors internal/api's createNotificationChannelRequest.

type CreateOrganizationRequest

type CreateOrganizationRequest struct {
	Name string `json:"name"`
}

CreateOrganizationRequest mirrors internal/api's createOrganizationRequest.

type CreateProjectRequest

type CreateProjectRequest struct {
	Name string `json:"name"`
}

CreateProjectRequest mirrors internal/api's createProjectRequest.

type CreateRegistryCredentialRequest

type CreateRegistryCredentialRequest struct {
	Name         string     `json:"name"`
	RegistryHost string     `json:"registry_host"`
	Username     string     `json:"username"`
	Password     string     `json:"password"`
	ExpiresAt    *time.Time `json:"expires_at,omitempty"`
}

CreateRegistryCredentialRequest mirrors internal/api's createRegistryCredentialRequest: Password is required here, unlike UpdateRegistryCredentialRequest where it's optional.

type CreateUserRequest

type CreateUserRequest struct {
	Email       string   `json:"email"`
	DisplayName string   `json:"display_name,omitempty"`
	Password    string   `json:"password"`
	Abilities   []string `json:"abilities,omitempty"`
	Role        string   `json:"role,omitempty"`
}

CreateUserRequest mirrors internal/api's createUserRequest. Role, when set, takes precedence server-side over Abilities (roles.go's resolveAbilities): set one or the other, not both.

type Credentials

type Credentials struct {
	APIURL string
	Token  string
}

Credentials is ReadCredentialsFile/WriteCredentialsFile's in-memory shape: the same two values as EnvAPIURL/EnvAPIToken.

func ReadCredentialsFile

func ReadCredentialsFile(prog, profile string) (Credentials, error)

ReadCredentialsFile reads profile's section from prog's credentials file. A missing file is a plain error the caller treats as "no credentials file," not logged or reported: this is the lowest-priority source in ResolveToken/ResolveAPIURL's precedence chain, its absence is the common case, not a problem. A file that exists but has no section named profile returns a zero Credentials and no error, the same "nothing configured here" shape, since asking for an unconfigured profile is not itself a failure to read the file.

type DatabaseEngineResource

type DatabaseEngineResource struct {
	ID             string `json:"id"`
	Label          string `json:"label"`
	DefaultVersion string `json:"default_version"`
}

DatabaseEngineResource mirrors internal/api's databaseEngineResource (internal/api/database_engines.go): one entry from GET /api/v1/database-engines, the dynamic registry backing the creation wizard's engine picker.

type DatabasePublicAccessResource

type DatabasePublicAccessResource struct {
	DatabaseName       string `json:"database_name"`
	PubliclyAccessible bool   `json:"publicly_accessible"`
	PublicPort         int    `json:"public_port,omitempty"`
}

DatabasePublicAccessResource mirrors internal/api's databasePublicAccessResource (internal/api/database_public_access.go): PUT/DELETE .../public-access only ever touch these three fields.

type DatabaseResource

type DatabaseResource struct {
	Name    string `json:"name"`
	Engine  string `json:"engine"`
	Version string `json:"version"`
	NodeID  string `json:"node_id,omitempty"`
	// ProjectID mirrors internal/api's databaseResource.ProjectID:
	// response-only, set via PUT /api/v1/databases/{name}/project.
	ProjectID string `json:"project_id,omitempty"`
	// Resources, PubliclyAccessible, PublicPort, and the Backup* fields
	// are set through their own dedicated routes (SetDatabaseResources,
	// SetDatabasePublicAccess, SetBackupSchedule), never through this
	// resource's own create/update body; see internal/api's
	// databaseResource for the identical boundary server-side.
	Resources          *ServiceResources `json:"resources,omitempty"`
	PubliclyAccessible bool              `json:"publicly_accessible,omitempty"`
	PublicPort         int               `json:"public_port,omitempty"`
	BackupTargetID     string            `json:"backup_target_id,omitempty"`
	BackupSchedule     string            `json:"backup_schedule,omitempty"`
	BackupRetain       int               `json:"backup_retain,omitempty"`
	BackupRetainDays   int               `json:"backup_retain_days,omitempty"`
}

DatabaseResource mirrors internal/api's databaseResource (internal/api/databases.go). NodeID is response-only, the same "shown but not settable through this endpoint" boundary AppResource's own NodeID field already documents.

type DeployCompareField

type DeployCompareField struct {
	Field string `json:"field"`
	From  string `json:"from"`
	To    string `json:"to"`
}

DeployCompareField mirrors internal/api's deployCompareField: one field that differs between From and To.

type DeployCompareResource

type DeployCompareResource struct {
	ServiceName         string               `json:"service_name"`
	From                DeployCompareSide    `json:"from"`
	To                  DeployCompareSide    `json:"to"`
	Changes             []DeployCompareField `json:"changes"`
	UnsnapshottedFields []string             `json:"unsnapshotted_fields"`
	Note                string               `json:"note"`
}

DeployCompareResource mirrors internal/api's deployCompareResource, GET /api/v1/apps/{name}/deploys/compare's response. UnsnapshottedFields and Note are the honest limitation this task's own design note requires: deploy_attempts never snapshotted env/resources/ domains/etc per attempt, so those cannot be diffed across past deploys, only reported as not tracked.

type DeployCompareSide

type DeployCompareSide struct {
	DeployID   string     `json:"deploy_id,omitempty"`
	IsCurrent  bool       `json:"is_current"`
	Image      string     `json:"image"`
	CommitSHA  string     `json:"commit_sha,omitempty"`
	Source     string     `json:"source,omitempty"`
	Status     string     `json:"status,omitempty"`
	StartedAt  *time.Time `json:"started_at,omitempty"`
	FinishedAt *time.Time `json:"finished_at,omitempty"`
}

DeployCompareSide mirrors internal/api's deployCompareSide (internal/api/deploy_compare.go): one side of a deploy comparison. IsCurrent true and DeployID empty means this side is the app's current live desired state, not a stored attempt.

type DeploySpecRequest

type DeploySpecRequest struct {
	RepoURL       string                       `json:"repo_url"`
	Ref           string                       `json:"ref"`
	ImageRepoBase string                       `json:"image_repo_base,omitempty"`
	Services      map[string]DeploySpecService `json:"services"`
}

DeploySpecRequest mirrors internal/api's deploySpecRequest (internal/api/apps_multi.go): POST /api/v1/apps/{name}/deploy-spec's body, one app.yaml services: map fanned out under app name.

type DeploySpecResult

type DeploySpecResult struct {
	AppID        string                    `json:"app_id"`
	Services     []DeploySpecServiceResult `json:"services"`
	AllSucceeded bool                      `json:"all_succeeded"`
}

DeploySpecResult mirrors internal/api's deploySpecResponse. AllSucceeded false means at least one ServiceKey's own Error is set; the request as a whole still succeeded at fanning out.

type DeploySpecService

type DeploySpecService struct {
	Build     DeploySpecServiceBuild          `json:"build"`
	Domains   []string                        `json:"domains,omitempty"`
	Port      int                             `json:"port,omitempty"`
	Health    *DeploySpecServiceHealth        `json:"health,omitempty"`
	Resources *DeploySpecServiceResources     `json:"resources,omitempty"`
	Env       map[string]DeploySpecServiceEnv `json:"env,omitempty"`
	Replicas  int                             `json:"replicas,omitempty"`
	Strategy  string                          `json:"strategy,omitempty"`
	Hooks     *DeploySpecServiceHooks         `json:"hooks,omitempty"`
}

DeploySpecService mirrors one entry in app.yaml's services: map (internal/spec.Service) as POST /api/v1/apps/{name}/deploy-spec expects to receive it directly, field for field.

type DeploySpecServiceBuild

type DeploySpecServiceBuild struct {
	Type               string `json:"type"`
	Path               string `json:"path,omitempty"`
	BaseDirectory      string `json:"baseDirectory,omitempty"`
	Image              string `json:"image,omitempty"`
	RegistryCredential string `json:"registryCredential,omitempty"`
}

DeploySpecServiceBuild mirrors internal/spec.Build's JSON wire shape: human-written field names, not AppResource's bytes/nanoCPUs encoding.

type DeploySpecServiceEnv

type DeploySpecServiceEnv struct {
	Value    string `json:"value,omitempty"`
	From     string `json:"from,omitempty"`
	Secret   bool   `json:"secret,omitempty"`
	Required bool   `json:"required,omitempty"`
}

DeploySpecServiceEnv mirrors internal/spec.EnvVar's JSON shape. Unlike app.yaml's YAML parsing, no plain-string shorthand: use Value for a literal.

type DeploySpecServiceHealth

type DeploySpecServiceHealth struct {
	Readiness *DeploySpecServiceProbe `json:"readiness,omitempty"`
	Liveness  *DeploySpecServiceProbe `json:"liveness,omitempty"`
}

DeploySpecServiceHealth mirrors internal/spec.Health.

type DeploySpecServiceHooks

type DeploySpecServiceHooks struct {
	PreDeploy  string `json:"preDeploy,omitempty"`
	PostDeploy string `json:"postDeploy,omitempty"`
}

DeploySpecServiceHooks mirrors internal/spec.Hooks.

type DeploySpecServiceProbe

type DeploySpecServiceProbe struct {
	Path     string `json:"path"`
	Interval string `json:"interval,omitempty"`
	Timeout  string `json:"timeout,omitempty"`
	Failures int    `json:"failures,omitempty"`
}

DeploySpecServiceProbe mirrors internal/spec.Probe: human-readable duration strings ("5s"), not ServiceProbe's nanosecond encoding.

type DeploySpecServiceResources

type DeploySpecServiceResources struct {
	Memory string  `json:"memory,omitempty"`
	CPU    float64 `json:"cpu,omitempty"`
}

DeploySpecServiceResources mirrors internal/spec.Resources: human-readable "512Mi"/0.5 values, not ServiceResources' bytes/ nanoCPUs encoding.

type DeploySpecServiceResult

type DeploySpecServiceResult struct {
	ServiceKey  string `json:"service_key"`
	ServiceName string `json:"service_name"`
	Image       string `json:"image,omitempty"`
	Error       string `json:"error,omitempty"`
}

DeploySpecServiceResult mirrors internal/api's deploySpecServiceResult: one service key's own build+deploy outcome. Error is set on failure, Image on success, matching deploy.ServiceOutcome's own "never both" contract.

type DeployTriggerRequest

type DeployTriggerRequest struct {
	Image   string `json:"image"`
	Confirm bool   `json:"confirm,omitempty"`
}

DeployTriggerRequest mirrors internal/api's deployTriggerRequest (internal/api/deploys.go). Response is a plain AppResource (the app's now-updated desired state), the same shape CreateApp/GetApp already use, so no separate response type is needed here.

type DeviceStartRequest

type DeviceStartRequest struct {
	ClientName string `json:"client_name,omitempty"`
}

DeviceStartRequest mirrors internal/api's deviceStartRequest.

type DeviceStartResponse

type DeviceStartResponse struct {
	DeviceCode              string `json:"device_code"`
	UserCode                string `json:"user_code"`
	VerificationURI         string `json:"verification_uri"`
	VerificationURIComplete string `json:"verification_uri_complete"`
	ExpiresIn               int    `json:"expires_in"`
	Interval                int    `json:"interval"`
}

DeviceStartResponse mirrors internal/api's deviceStartResponse.

type DeviceTokenRequest

type DeviceTokenRequest struct {
	DeviceCode string `json:"device_code"`
}

DeviceTokenRequest mirrors internal/api's deviceTokenRequest.

type DeviceTokenResponse

type DeviceTokenResponse struct {
	ID         string     `json:"id"`
	Name       string     `json:"name"`
	Abilities  []string   `json:"abilities"`
	CreatedAt  time.Time  `json:"created_at"`
	LastUsedAt *time.Time `json:"last_used_at,omitempty"`
	ExpiresAt  *time.Time `json:"expires_at,omitempty"`
	RevokedAt  *time.Time `json:"revoked_at,omitempty"`
	Token      string     `json:"token"`
}

DeviceTokenResponse mirrors internal/api's createTokenResponse, the shape POST /api/v1/auth/device/token returns once a request is approved.

type DiagnosisResource

type DiagnosisResource struct {
	Explanation     string            `json:"explanation"`
	Suggestion      string            `json:"suggestion"`
	Confidence      string            `json:"confidence"`
	MatchedSignals  []DiagnosisSignal `json:"matched_signals"`
	DeployAttemptID string            `json:"deploy_attempt_id,omitempty"`
}

DiagnosisResource mirrors internal/api's diagnosisResource (internal/api/diagnose.go): GET /api/v1/apps/{name}/diagnose's response, a deterministic explanation of a deploy failure or crashloop synthesized from internal/diagnose, never from an external model.

type DiagnosisSignal

type DiagnosisSignal struct {
	Source  string `json:"source"`
	Excerpt string `json:"excerpt"`
}

DiagnosisSignal mirrors internal/api's diagnosisSignalResource: one piece of evidence a diagnosis signature matched against.

type DimensionRecommendationResource

type DimensionRecommendationResource struct {
	Dimension      string  `json:"dimension"`
	SampleCount    int     `json:"sample_count"`
	DataSufficient bool    `json:"data_sufficient"`
	Confidence     string  `json:"confidence"`
	CurrentLimit   int64   `json:"current_limit"`
	P95Usage       float64 `json:"p95_usage"`
	P99Usage       float64 `json:"p99_usage"`
	SuggestedLimit int64   `json:"suggested_limit"`
	Action         string  `json:"action,omitempty"`
	Reason         string  `json:"reason"`
}

DimensionRecommendationResource mirrors internal/api's dimensionRecommendationResource (internal/api/resource_recommendation.go): one resource dimension's (memory or cpu) right-sizing suggestion. CurrentLimit/SuggestedLimit are bytes for memory, nano-CPUs for cpu, the same raw-unit convention AppResource.Resources already uses. Action is "" when there isn't enough data, or no limit is currently set, to responsibly suggest a change.

type DoctorCheckResource

type DoctorCheckResource struct {
	Code    string `json:"code"`
	Name    string `json:"name"`
	Status  string `json:"status"`
	Message string `json:"message"`
}

DoctorCheckResource mirrors internal/api's doctorCheckResource: one preflight check's result (Status is "ok", "warn", "fail", or "unknown").

type DomainBasicAuthResource

type DomainBasicAuthResource struct {
	Domain      string `json:"domain"`
	Enabled     bool   `json:"enabled"`
	Username    string `json:"username,omitempty"`
	HasPassword bool   `json:"has_password"`
}

DomainBasicAuthResource mirrors internal/api's domainBasicAuthResource (internal/api/domain_basic_auth.go): GET/PUT/DELETE /api/v1/apps/{name}/domains/{domain}/auth's wire shape. The password itself never appears here in either direction.

type DomainMaintenanceResource

type DomainMaintenanceResource struct {
	Domain  string `json:"domain"`
	Enabled bool   `json:"enabled"`
}

DomainMaintenanceResource mirrors internal/api's domainMaintenanceResource: GET/PUT/DELETE /api/v1/apps/{name}/domains/{domain}/maintenance's wire shape.

type DomainResource

type DomainResource struct {
	Domain      string `json:"domain"`
	ServiceName string `json:"service_name"`
}

DomainResource mirrors internal/api's domainResource (internal/api/ingress_settings.go).

type DomainTLSCertResource

type DomainTLSCertResource struct {
	Domain     string `json:"domain"`
	Enabled    bool   `json:"enabled"`
	UploadedAt string `json:"uploaded_at,omitempty"`
	ExpiresAt  string `json:"expires_at,omitempty"`
}

DomainTLSCertResource mirrors internal/api's domainTLSCertResource (internal/api/domain_tls_cert.go): GET/PUT/DELETE /api/v1/apps/{name}/domains/{domain}/tls-cert's wire shape. Neither the certificate nor the private key ever appears here.

type DrainNodeResponse

type DrainNodeResponse struct {
	TargetNodeID   string   `json:"target_node_id"`
	MovedServices  []string `json:"moved_services"`
	MovedDatabases []string `json:"moved_databases"`
	Errors         []string `json:"errors,omitempty"`
}

DrainNodeResponse mirrors internal/api's drainNodeResponse. A partial failure is not itself a Go error from DrainNode: it comes back as a successful response with Errors populated, naming exactly which resource didn't move so the caller can retry just that one.

type EnvironmentResource

type EnvironmentResource struct {
	ID        string `json:"id"`
	ProjectID string `json:"project_id"`
	Name      string `json:"name"`
	Protected bool   `json:"protected"`
	CreatedAt string `json:"created_at"`
}

EnvironmentResource mirrors internal/api's environmentResource (internal/api/environments.go).

type EvaluateFlagResource

type EvaluateFlagResource struct {
	Key     string `json:"key"`
	Enabled bool   `json:"enabled"`
}

EvaluateFlagResource mirrors internal/api's evaluateFlagResource: the tiny shape GET /api/v1/flags/evaluate/{key} returns.

type ExecRequest

type ExecRequest struct {
	Command        string   `json:"command"`
	Args           []string `json:"args,omitempty"`
	TimeoutSeconds int      `json:"timeout_seconds,omitempty"`
}

ExecRequest mirrors internal/api's execRequest (internal/api/exec.go). Command is required server-side and is never shell-interpreted: a caller who wants shell features (pipes, redirection, env expansion) passes Command: "sh", Args: []string{"-c", "..."} explicitly, the same contract the server documents.

type ExecResponse

type ExecResponse struct {
	Stdout    string `json:"stdout"`
	Stderr    string `json:"stderr,omitempty"`
	ExitCode  int    `json:"exit_code"`
	Truncated bool   `json:"truncated,omitempty"`
}

ExecResponse mirrors internal/api's execResponse. ExitCode is always the remote command's real exit code, never a client-level sentinel.

type FeatureFlagRequest

type FeatureFlagRequest struct {
	Key               string `json:"key,omitempty"`
	Name              string `json:"name"`
	Description       string `json:"description,omitempty"`
	Enabled           bool   `json:"enabled"`
	RolloutPercentage int    `json:"rollout_percentage"`
}

FeatureFlagRequest mirrors the fields internal/api's featureFlagResource actually reads from a create/update request body. Key is only read on create; an update ignores it (ID and ServiceName always come from the URL, same as ScheduledTaskRequest above).

type FeatureFlagResource

type FeatureFlagResource struct {
	ID                string    `json:"id,omitempty"`
	Key               string    `json:"key"`
	Name              string    `json:"name"`
	Description       string    `json:"description,omitempty"`
	ServiceName       string    `json:"service_name,omitempty"`
	Enabled           bool      `json:"enabled"`
	RolloutPercentage int       `json:"rollout_percentage"`
	CreatedAt         time.Time `json:"created_at,omitempty"`
	UpdatedAt         time.Time `json:"updated_at,omitempty"`
}

FeatureFlagResource mirrors internal/api's featureFlagResource (internal/api/feature_flags.go). Key is globally unique across the whole platform, not just within ServiceName: see that file's own migration comment for why.

type GitSourceResource

type GitSourceResource struct {
	ServiceName    string `json:"service_name"`
	RepoURL        string `json:"repo_url"`
	Branch         string `json:"branch"`
	BuildType      string `json:"build_type"`
	BuildPath      string `json:"build_path,omitempty"`
	HasToken       bool   `json:"has_token"`
	WebhookURL     string `json:"webhook_url"`
	WebhookSecret  string `json:"webhook_secret,omitempty"`
	PreviewEnabled bool   `json:"preview_enabled"`
	// PostPRComments mirrors store.GitSource.PostPRComments: the opt-in
	// toggle for a preview deploy's GitHub PR comment/commit status, set
	// via SetPreviewPostPRComments (preview-settings, same route as
	// PreviewEnabled).
	PostPRComments bool   `json:"post_pr_comments"`
	CreatedAt      string `json:"created_at"`
	UpdatedAt      string `json:"updated_at"`
}

GitSourceResource mirrors internal/api's gitSourceResource (internal/api/git_sources.go). AdditionalServices/Services (the multi-service fan-out fields) are deliberately not carried here: this client's SetGitSourceRequest only covers the single-service connect flow "apps deploy-spec" already handles for the multi-service case.

type HookRunResource

type HookRunResource struct {
	HookType string    `json:"hook_type"`
	Command  string    `json:"command"`
	ExitCode int       `json:"exit_code"`
	Success  bool      `json:"success"`
	Output   string    `json:"output"`
	RanAt    time.Time `json:"ran_at"`
}

HookRunResource mirrors internal/api's hookRunResource (apps_hooks.go): one pre/post-deploy hook's most recent outcome.

type InviteResource

type InviteResource struct {
	ID        string    `json:"id"`
	Email     string    `json:"email"`
	Role      string    `json:"role,omitempty"`
	Abilities []string  `json:"abilities"`
	CreatedBy string    `json:"created_by,omitempty"`
	CreatedAt time.Time `json:"created_at"`
	ExpiresAt time.Time `json:"expires_at"`
	Expired   bool      `json:"expired"`
}

InviteResource mirrors internal/api's inviteResource (internal/api/invites.go).

type ListAuditLogOptions

type ListAuditLogOptions struct {
	Limit      int
	Before     string
	Path       string
	Method     string
	ClientKind string
}

ListAuditLogOptions is ListAuditLog's and DownloadAuditLogCSV's shared query input, mirroring GET /api/v1/audit-log's own ?limit/?before/ ?path/?method/?client_kind params (internal/api/audit.go). Zero values omit the param, the same convention ListBackupsOptions establishes.

type ListBackupsOptions

type ListBackupsOptions struct {
	Limit  int
	Before string
}

ListBackupsOptions is ListBackups' pagination input, mirroring the server's ?limit/?before query params. Zero values omit the param (Limit <= 0 uses the server default, Before == "" is the first page).

type ListWebhookDeliveriesOptions

type ListWebhookDeliveriesOptions struct {
	Limit  int
	Before string
}

ListWebhookDeliveriesOptions is ListWebhookDeliveries' pagination input, the same shape ListBackupsOptions establishes.

type LogDrainResource

type LogDrainResource struct {
	AppName string `json:"app_name"`
	Type    string `json:"type"`
	Target  string `json:"target"`
	Enabled bool   `json:"enabled"`
}

LogDrainResource mirrors internal/api's logDrainResource (apps_log_drain.go): GET/PUT /api/v1/apps/{name}/log-drain's wire shape. Type is "http" or "syslog", validated server-side.

type LogEntryResource

type LogEntryResource struct {
	Timestamp  time.Time       `json:"timestamp"`
	Stream     string          `json:"stream"`
	Message    string          `json:"message"`
	Structured bool            `json:"structured"`
	FieldsJSON json.RawMessage `json:"fields,omitempty"`
}

LogEntryResource mirrors internal/api's logEntryResource (internal/api/logs.go).

type MetricPointResource

type MetricPointResource struct {
	Timestamp time.Time `json:"timestamp"`
	Value     float64   `json:"value"`
	Count     int       `json:"count"`
}

MetricPointResource mirrors internal/api's metricPoint (internal/api/metrics.go): one aggregated bucket of a queried metric.

type NetworkResource

type NetworkResource struct {
	ContainerPort int  `json:"container_port"`
	HostPort      int  `json:"host_port,omitempty"`
	Running       bool `json:"running"`
}

NetworkResource mirrors internal/api's networkResource (internal/api/network.go): the live traffic path, container's declared port plus whatever host port Docker currently has bound.

type NodeAlertStatusResource

type NodeAlertStatusResource struct {
	PatchStatus       string `json:"patch_status"`
	NodeDiskSpace     string `json:"node_disk_space"`
	NodeResourceUsage string `json:"node_resource_usage"`
}

NodeAlertStatusResource mirrors internal/api's nodeAlertStatusResource (internal/api/nodes.go): each field is "ok", "firing", or "unknown", a live re-evaluation of this one node's own standing for that node-scoped, platform-wide alert kind, not a rule's stored aggregate value.

type NodePatchStatusResource

type NodePatchStatusResource struct {
	Checked   bool       `json:"checked"`
	Total     int        `json:"total"`
	Security  int        `json:"security"`
	CheckedAt *time.Time `json:"checked_at,omitempty"`
}

NodePatchStatusResource mirrors internal/api's nodePatchStatusResponse (internal/api/node_patch_status.go). Checked distinguishes "never checked" (Total/Security both zero-valued and meaningless) from checked-and-genuinely-up-to-date (Checked true, Total 0): callers must branch on Checked first.

type NodeResource

type NodeResource struct {
	ID              string     `json:"id"`
	Name            string     `json:"name"`
	Address         string     `json:"address,omitempty"`
	Status          string     `json:"status"`
	CertFingerprint string     `json:"cert_fingerprint,omitempty"`
	JoinedAt        *time.Time `json:"joined_at,omitempty"`
	LastSeenAt      *time.Time `json:"last_seen_at,omitempty"`
	// Schedulable is the cordon state: false means the node refuses new
	// placements while whatever's already running there keeps running.
	Schedulable           bool      `json:"schedulable"`
	AcceptsAppWorkloads   bool      `json:"accepts_app_workloads"`
	AcceptsBuildWorkloads bool      `json:"accepts_build_workloads"`
	CreatedAt             time.Time `json:"created_at"`
	// AlertStatus is only set by GET /api/v1/nodes/{id} (a single-node
	// fetch), never the list endpoint; nil when telemetry isn't
	// configured on the control plane.
	AlertStatus *NodeAlertStatusResource `json:"alert_status,omitempty"`
}

NodeResource mirrors internal/api's nodeResource (internal/api/nodes.go).

type NotificationChannelResource

type NotificationChannelResource struct {
	ID        string `json:"id"`
	Name      string `json:"name"`
	Kind      string `json:"kind"`
	NotifyURL string `json:"notify_url"`
	Enabled   bool   `json:"enabled"`
	CreatedAt string `json:"created_at"`
	UpdatedAt string `json:"updated_at"`
}

NotificationChannelResource mirrors internal/api's notificationChannelResource (internal/api/notification_channels.go).

type NotificationDeliveryResource

type NotificationDeliveryResource struct {
	ID        string `json:"id"`
	ChannelID string `json:"channel_id"`
	Trigger   string `json:"trigger"`
	Success   bool   `json:"success"`
	Error     string `json:"error,omitempty"`
	CreatedAt string `json:"created_at"`
}

NotificationDeliveryResource mirrors internal/api's notificationDeliveryResource (internal/api/notification_channels.go).

type OnboardingStateResource

type OnboardingStateResource struct {
	Completed bool `json:"completed"`
}

OnboardingStateResource mirrors internal/api's onboardingStateResource (internal/api/onboarding.go).

type Option

type Option func(*Client)

Option configures a Client at construction time. See WithUserAgent.

func WithUserAgent

func WithUserAgent(userAgent string) Option

WithUserAgent sets the User-Agent header on every request this Client sends, so the control plane's audit log (internal/api's clientKindFromUserAgent) can tell which real client made a call rather than lumping every bearer-token caller into one bucket. Each of this project's own callers passes its own value: cmd/levelrail-cli sets "levelrail-cli/<version>", cmd/levelrail-mcp sets "levelrail-mcp/<version>".

type OrganizationResource

type OrganizationResource struct {
	ID        string `json:"id"`
	Name      string `json:"name"`
	CreatedAt string `json:"created_at"`
}

OrganizationResource mirrors internal/api's organizationResource (internal/api/organizations.go).

type PolicyAttachmentResource

type PolicyAttachmentResource struct {
	ID            string    `json:"id"`
	PolicyID      string    `json:"policy_id"`
	PrincipalType string    `json:"principal_type"`
	PrincipalID   string    `json:"principal_id"`
	CreatedAt     time.Time `json:"created_at"`
}

PolicyAttachmentResource mirrors internal/api's policyAttachmentResource.

type PolicyRequest

type PolicyRequest struct {
	Name        string          `json:"name"`
	Description string          `json:"description,omitempty"`
	Document    json.RawMessage `json:"document"`
}

PolicyRequest mirrors internal/api's policyRequest, the body for both CreatePolicy and UpdatePolicy.

type PolicyResource

type PolicyResource struct {
	ID          string          `json:"id"`
	Name        string          `json:"name"`
	Description string          `json:"description"`
	Document    json.RawMessage `json:"document"`
	CreatedAt   time.Time       `json:"created_at"`
	UpdatedAt   time.Time       `json:"updated_at"`
}

PolicyResource mirrors internal/api's policyResource (internal/api/iam_handlers.go).

type PreviewEnvironmentResource

type PreviewEnvironmentResource struct {
	PRNumber     int    `json:"pr_number"`
	PreviewAppID string `json:"preview_app_id"`
	Branch       string `json:"branch"`
	HeadSHA      string `json:"head_sha"`
	Domain       string `json:"domain,omitempty"`
	Status       string `json:"status"`
	StatusReason string `json:"status_reason,omitempty"`
	CreatedAt    string `json:"created_at"`
	UpdatedAt    string `json:"updated_at"`
	Stale        bool   `json:"stale"`
}

PreviewEnvironmentResource mirrors internal/api's previewEnvironmentResource (internal/api/preview_environments_handlers.go).

type PreviewSettingsResource

type PreviewSettingsResource struct {
	Enabled        bool `json:"enabled"`
	PostPRComments bool `json:"post_pr_comments"`
}

PreviewSettingsResource mirrors internal/api's previewSettingsResource: the resulting state of both preview-settings toggles after a SetPreviewSettingsRequest is applied.

type ProfileSummary

type ProfileSummary struct {
	Name   string
	APIURL string
}

ProfileSummary is ListProfiles' element type: a profile's name and API URL, deliberately never its token. See ListProfiles.

func ListProfiles

func ListProfiles(prog string) ([]ProfileSummary, error)

ListProfiles returns every profile section configured in prog's credentials file, in the order they first appear, each with its API URL but never its token: see ProfileSummary. Returns a nil slice, no error, for a missing file, the same "nothing configured" shape ReadCredentialsFile's own doc comment describes.

type ProjectResource

type ProjectResource struct {
	ID        string `json:"id"`
	Name      string `json:"name"`
	CreatedAt string `json:"created_at"`
	OrgID     string `json:"org_id,omitempty"`
}

ProjectResource mirrors internal/api's projectResource (internal/api/projects.go). OrgID is empty when the project isn't filed under any organization.

type PromoteAppRequest

type PromoteAppRequest struct {
	To      string `json:"to"`
	Target  string `json:"target,omitempty"`
	Confirm bool   `json:"confirm,omitempty"`
}

PromoteAppRequest mirrors internal/api's promoteTriggerRequest: POST /api/v1/apps/{name}/promote's body. Target is optional, the same "auto-discover the sole candidate, or disambiguate" contract PromotePreview's own Target query param has.

type PromotePreviewResource

type PromotePreviewResource struct {
	SourceApp           string               `json:"source_app"`
	TargetApp           string               `json:"target_app"`
	Environment         EnvironmentResource  `json:"environment"`
	From                PromotePreviewSide   `json:"from"`
	To                  PromotePreviewSide   `json:"to"`
	Changes             []DeployCompareField `json:"changes"`
	UnsnapshottedFields []string             `json:"unsnapshotted_fields"`
	Note                string               `json:"note"`
}

PromotePreviewResource mirrors internal/api's promotePreviewResource, GET /api/v1/apps/{name}/promote/preview's response.

type PromotePreviewSide

type PromotePreviewSide struct {
	AppName string `json:"app_name"`
	Image   string `json:"image"`
}

PromotePreviewSide mirrors internal/api's promotePreviewSide (internal/api/promote.go): one side of a promotion preview, always live desired state (there is no DeployID/CommitSHA/Status to show).

type PurgeAuditLogResult

type PurgeAuditLogResult struct {
	Deleted int64 `json:"deleted"`
}

PurgeAuditLogResult is POST /api/v1/audit-log/purge's response shape (internal/api/audit_retention.go's purgeAuditLogResponse).

type RegistryCredentialResource

type RegistryCredentialResource struct {
	ID           string     `json:"id"`
	Name         string     `json:"name"`
	RegistryHost string     `json:"registry_host"`
	Username     string     `json:"username"`
	CreatedAt    string     `json:"created_at"`
	ExpiresAt    *time.Time `json:"expires_at,omitempty"`
	ExpiryStatus string     `json:"expiry_status,omitempty"`
}

RegistryCredentialResource mirrors internal/api's registryCredentialResource (internal/api/registry_credentials.go). No password field, the same write-only convention BackupTargetResource uses for its own credentials. ExpiresAt/ExpiryStatus are operator-set metadata, not something the platform infers from the credential itself; ExpiryStatus is "healthy"/"expiring_soon"/"expired", empty when no expiry was set.

type RegistrySettingsResource

type RegistrySettingsResource struct {
	Enabled        bool   `json:"enabled"`
	Host           string `json:"host,omitempty"`
	Username       string `json:"username,omitempty"`
	HasCredentials bool   `json:"has_credentials"`
	Status         string `json:"status"`
	Message        string `json:"message,omitempty"`
	Password       string `json:"password,omitempty"`
}

RegistrySettingsResource mirrors internal/api's registrySettingsResource (internal/api/registry_settings.go): GET/PUT/DELETE /api/v1/settings/registry's wire shape. Password is write-once: it is only ever populated in the response to a PUT call that generates a fresh credential (the registry's first enable), empty every other time.

type ReplayWebhookDeliveryResult

type ReplayWebhookDeliveryResult struct {
	Status  int    `json:"status"`
	Message string `json:"message"`
}

ReplayWebhookDeliveryResult mirrors internal/api's replayWebhookDeliveryResult: the status/message a replayed delivery's re-run processing produced.

type ResourceRecommendationResource

type ResourceRecommendationResource struct {
	ServiceName    string                          `json:"service_name"`
	LookbackWindow string                          `json:"lookback_window"`
	Memory         DimensionRecommendationResource `json:"memory"`
	CPU            DimensionRecommendationResource `json:"cpu"`
	OOMDetectedAt  string                          `json:"oom_detected_at,omitempty"`
	OOMExcerpt     string                          `json:"oom_excerpt,omitempty"`
}

ResourceRecommendationResource mirrors internal/api's resourceRecommendationResource: the shared response shape for both GET /api/v1/apps/{name}/resource-recommendation (internal/api/resource_recommendation.go) and GET /api/v1/databases/{name}/resource-recommendation (internal/api/database_resource_recommendation.go), a deterministic memory/CPU right-sizing suggestion synthesized from internal/rightsizing over the resource's own historical usage samples, never from an external model, and never applied automatically. ServiceName holds the app or database name either way.

type RestoreHistoryResource

type RestoreHistoryResource struct {
	ID              string `json:"id"`
	DatabaseName    string `json:"database_name,omitempty"`
	ServiceName     string `json:"service_name,omitempty"`
	VolumeName      string `json:"volume_name,omitempty"`
	BackupHistoryID string `json:"backup_history_id"`
	Status          string `json:"status"`
	Error           string `json:"error,omitempty"`
	StartedAt       string `json:"started_at"`
	FinishedAt      string `json:"finished_at,omitempty"`
}

RestoreHistoryResource mirrors internal/api's restoreHistoryResource (internal/api/restore.go). ServiceName/VolumeName mirror BackupHistoryResource's own identical fields above.

type RoleResource

type RoleResource struct {
	Name        string   `json:"name"`
	Description string   `json:"description"`
	Abilities   []string `json:"abilities"`
}

RoleResource mirrors internal/api's Role (internal/api/roles.go).

type RotateMasterKeyRequest

type RotateMasterKeyRequest struct {
	NewMasterKey string `json:"newMasterKey"`
}

RotateMasterKeyRequest mirrors internal/api's rotateMasterKeyRequest: the new master key, read from a file or stdin by the CLI so it never appears as a bare command-line argument.

type RotateMasterKeyResult

type RotateMasterKeyResult struct {
	RotatedAt       time.Time `json:"rotatedAt"`
	PersistedToFile bool      `json:"persistedToFile"`
	Warning         string    `json:"warning,omitempty"`
}

RotateMasterKeyResult mirrors internal/api's rotateMasterKeyResponse. Warning is non-empty exactly when the operator has a required follow-up before the control plane's next restart: either the master key is env-sourced (update APP_MASTER_KEY out of band) or the file write itself failed (update the key file by hand).

type ScheduledTaskRequest

type ScheduledTaskRequest struct {
	Command  []string `json:"command"`
	Schedule string   `json:"schedule"`
	Enabled  bool     `json:"enabled"`
}

ScheduledTaskRequest mirrors the fields internal/api's scheduledTaskResource actually reads from a create/update request body (Command, Schedule, Enabled); ID and ServiceName always come from the URL, never the body.

type ScheduledTaskResource

type ScheduledTaskResource struct {
	ID          string   `json:"id,omitempty"`
	ServiceName string   `json:"service_name,omitempty"`
	Command     []string `json:"command"`
	Schedule    string   `json:"schedule"`
	Enabled     bool     `json:"enabled"`

	LastRunAt     *time.Time `json:"last_run_at,omitempty"`
	LastRunStatus string     `json:"last_run_status,omitempty"`
	LastRunOutput string     `json:"last_run_output,omitempty"`
	// ConsecutiveFailures mirrors internal/api's own field: what a
	// kind=scheduled_task_failure alert rule watches.
	ConsecutiveFailures int `json:"consecutive_failures"`

	CreatedAt time.Time `json:"created_at,omitempty"`
	UpdatedAt time.Time `json:"updated_at,omitempty"`
}

ScheduledTaskResource mirrors internal/api's scheduledTaskResource (internal/api/scheduled_tasks.go). Command is a real argv (no shell), and LastRun* describe only the single most recent run in place: there is no separate run-history endpoint.

type SecretKeyResource

type SecretKeyResource struct {
	Key    string `json:"key"`
	Locked bool   `json:"locked"`
}

SecretKeyResource mirrors internal/api's secretKeyResource (internal/api/secrets.go): a secret's key and locked state, never its value.

type ServiceHealth

type ServiceHealth struct {
	Readiness *ServiceProbe `json:"readiness,omitempty"`
	Liveness  *ServiceProbe `json:"liveness,omitempty"`
}

ServiceHealth mirrors internal/api's appResource.Health field.

type ServiceHooks

type ServiceHooks struct {
	PreDeploy  string `json:"pre_deploy,omitempty"`
	PostDeploy string `json:"post_deploy,omitempty"`
}

ServiceHooks mirrors internal/api's appResource.Hooks field (store.ServiceHooks' JSON encoding).

type ServiceProbe

type ServiceProbe struct {
	Path     string `json:"path"`
	Interval int64  `json:"interval,omitempty"`
	Timeout  int64  `json:"timeout,omitempty"`
	Failures int    `json:"failures,omitempty"`
}

ServiceProbe mirrors one of AppResource.Health's two probes (readiness or liveness).

type ServiceResources

type ServiceResources struct {
	MemoryBytes     int64  `json:"memory_bytes,omitempty"`
	NanoCPUs        int64  `json:"nano_cpus,omitempty"`
	SwapMemoryBytes int64  `json:"swap_memory_bytes,omitempty"`
	CPUSetCPUs      string `json:"cpuset_cpus,omitempty"`
}

ServiceResources mirrors internal/api's appResource.Resources field (internal/api/apps.go), which is itself store.DesiredService's own JSON encoding: bytes and nanoseconds, not app.yaml's human-friendly "512Mi"/"5s" strings. Redeclared here, not imported from internal/store or internal/api, so this package depends only on the documented wire contract, never on the control plane's internal Go types. ServiceProbe and ServiceHealth below share that same reasoning.

type ServiceTemplateDetail

type ServiceTemplateDetail struct {
	ID               string `json:"id"`
	Name             string `json:"name"`
	Slogan           string `json:"slogan"`
	Category         string `json:"category"`
	DocumentationURL string `json:"documentation_url"`
	Compose          string `json:"compose"`
}

ServiceTemplateDetail mirrors internal/api's serviceTemplateDetail: GET /api/v1/service-templates/{id}'s response, including the full compose.yaml body.

type ServiceTemplateListItem

type ServiceTemplateListItem struct {
	ID               string `json:"id"`
	Name             string `json:"name"`
	Slogan           string `json:"slogan"`
	Category         string `json:"category"`
	DocumentationURL string `json:"documentation_url"`
}

ServiceTemplateListItem mirrors internal/api's serviceTemplateListItem (internal/api/service_templates.go): one catalog entry from GET /api/v1/service-templates, without the full Compose body.

type SessionInfoResource

type SessionInfoResource struct {
	Username  string `json:"username"`
	ExpiresAt string `json:"expires_at"`
}

SessionInfoResource mirrors internal/api's sessionInfoResponse (internal/api/account.go)'s wire shape. GetSession below sends this over a plain bearer-token request, which handleGetSession's own doc comment says it will never honor ("deliberately not requireAbility: a bearer token has no session of its own to report on").

type SetAppDatabaseRequest

type SetAppDatabaseRequest struct {
	DatabaseName string `json:"database_name"`
	EnvVar       string `json:"env_var,omitempty"`
	Field        string `json:"field,omitempty"`
}

SetAppDatabaseRequest mirrors internal/api's setAppDatabaseRequest (apps_database.go). EnvVar and Field are both optional: the server defaults them ("DATABASE_URL"/"url") when left blank.

type SetAppEnvironmentRequest

type SetAppEnvironmentRequest struct {
	EnvironmentID string `json:"environment_id"`
}

SetAppEnvironmentRequest mirrors internal/api's setAppEnvironmentRequest. An empty EnvironmentID clears the assignment.

type SetAppProjectRequest

type SetAppProjectRequest struct {
	ProjectID string `json:"project_id"`
}

SetAppProjectRequest mirrors internal/api's setAppProjectRequest. An empty ProjectID clears the assignment.

type SetBackupScheduleRequest

type SetBackupScheduleRequest struct {
	TargetID   string `json:"target_id"`
	Schedule   string `json:"schedule"`
	Retain     int    `json:"retain,omitempty"`
	RetainDays int    `json:"retain_days,omitempty"`
}

SetBackupScheduleRequest mirrors internal/api's setBackupScheduleRequest.

type SetDatabaseProjectRequest

type SetDatabaseProjectRequest struct {
	ProjectID string `json:"project_id"`
}

SetDatabaseProjectRequest mirrors internal/api's setDatabaseProjectRequest. An empty ProjectID clears the assignment.

type SetDatabasePublicAccessRequest

type SetDatabasePublicAccessRequest struct {
	Port int `json:"port,omitempty"`
}

SetDatabasePublicAccessRequest mirrors internal/api's setDatabasePublicAccessRequest. Port 0 means auto-assign the next free port.

type SetDatabaseResourcesRequest

type SetDatabaseResourcesRequest struct {
	Resources *ServiceResources `json:"resources"`
}

SetDatabaseResourcesRequest mirrors internal/api's setDatabaseResourcesRequest.

type SetDomainBasicAuthRequest

type SetDomainBasicAuthRequest struct {
	Username string `json:"username"`
	Password string `json:"password,omitempty"`
}

SetDomainBasicAuthRequest mirrors internal/api's setDomainBasicAuthRequest. Password empty on an update means "leave the currently stored password unchanged".

type SetDomainTLSCertRequest

type SetDomainTLSCertRequest struct {
	Cert string `json:"cert"`
	Key  string `json:"key"`
}

SetDomainTLSCertRequest mirrors internal/api's setDomainTLSCertRequest: both fields are required every call, there is no "leave the current certificate unchanged" partial-update case.

type SetGitSourceRequest

type SetGitSourceRequest struct {
	RepoURL   string `json:"repo_url"`
	Branch    string `json:"branch,omitempty"`
	BuildType string `json:"build_type,omitempty"`
	BuildPath string `json:"build_path,omitempty"`
	Token     string `json:"token,omitempty"`
}

SetGitSourceRequest mirrors internal/api's setGitSourceRequest (internal/api/git_sources.go), minus the multi-service Services/ AdditionalServices fields (see GitSourceResource's own doc comment).

type SetLogDrainRequest

type SetLogDrainRequest struct {
	Type    string `json:"type"`
	Target  string `json:"target"`
	Enabled bool   `json:"enabled"`
}

SetLogDrainRequest mirrors internal/api's setLogDrainRequest.

type SetNodeWorkloadsRequest

type SetNodeWorkloadsRequest struct {
	AcceptsAppWorkloads   bool `json:"accepts_app_workloads"`
	AcceptsBuildWorkloads bool `json:"accepts_build_workloads"`
}

SetNodeWorkloadsRequest mirrors internal/api's setNodeWorkloadsRequest: a full replace of both fields, not a partial patch.

type SetPreviewSettingsRequest

type SetPreviewSettingsRequest struct {
	Enabled        *bool `json:"enabled,omitempty"`
	PostPRComments *bool `json:"post_pr_comments,omitempty"`
}

SetPreviewSettingsRequest mirrors internal/api's setPreviewSettingsRequest (preview_environments_handlers.go). Both fields are optional pointers: nil means "leave the currently stored value unchanged," so SetPreviewEnabled and SetPreviewPostPRComments (client.go) can each touch just their own toggle without resetting the other back to false.

type SetProjectOrganizationRequest

type SetProjectOrganizationRequest struct {
	OrgID string `json:"org_id"`
}

SetProjectOrganizationRequest mirrors internal/api's setProjectOrganizationRequest. An empty OrgID clears the assignment.

type SetSecretLockRequest

type SetSecretLockRequest struct {
	Locked bool `json:"locked"`
}

SetSecretLockRequest mirrors internal/api's setSecretLockRequest (internal/api/secrets.go).

type SetSecretRequest

type SetSecretRequest struct {
	Value           string `json:"value"`
	OverwriteLocked bool   `json:"overwrite_locked"`
}

SetSecretRequest mirrors internal/api's setSecretRequest (internal/api/secrets.go).

type SetVolumeBackupScheduleRequest

type SetVolumeBackupScheduleRequest struct {
	TargetID   string `json:"target_id"`
	Schedule   string `json:"schedule"`
	Retain     int    `json:"retain,omitempty"`
	RetainDays int    `json:"retain_days,omitempty"`
}

SetVolumeBackupScheduleRequest mirrors internal/api's setVolumeBackupScheduleRequest.

type SweepPreviewEnvironmentsResult

type SweepPreviewEnvironmentsResult struct {
	Swept int `json:"swept"`
}

SweepPreviewEnvironmentsResult mirrors internal/api's sweepPreviewEnvironmentsResponse (preview_environments_sweep.go).

type SystemDoctorResource

type SystemDoctorResource struct {
	OK     bool                  `json:"ok"`
	Checks []DoctorCheckResource `json:"checks"`
}

SystemDoctorResource mirrors internal/api's systemDoctorResponse (internal/api/doctor.go): the "levelrail-cli doctor" preflight bundle, a superset of SystemStatusResource above. OK is false only when at least one check's Status is "fail"; "warn" doesn't affect it.

type SystemStatusResource

type SystemStatusResource struct {
	SecretsConfigured   bool   `json:"secrets_configured"`
	TelemetryConfigured bool   `json:"telemetry_configured"`
	AlertsConfigured    bool   `json:"alerts_configured"`
	DataDirTotalBytes   int64  `json:"data_dir_total_bytes,omitempty"`
	DataDirFreeBytes    int64  `json:"data_dir_free_bytes,omitempty"`
	DockerConnected     bool   `json:"docker_connected"`
	DockerError         string `json:"docker_error,omitempty"`
}

SystemStatusResource mirrors internal/api's systemStatusResponse (internal/api/status.go): DockerConnected/DockerError are this control plane's own local Docker daemon reachability, not a per-node signal (see docker_connected's own doc comment on internal/api/status.go for why: multi-node Docker reachability forwarding isn't wired yet).

type TestNotificationChannelRequest

type TestNotificationChannelRequest struct {
	Kind      string `json:"kind"`
	NotifyURL string `json:"notify_url"`
}

TestNotificationChannelRequest mirrors internal/api's testNotificationChannelRequest.

type TriggerBackupRequest

type TriggerBackupRequest struct {
	TargetID string `json:"target_id"`
}

TriggerBackupRequest mirrors internal/api's triggerBackupRequest.

type TriggerCloneRestoreRequest

type TriggerCloneRestoreRequest struct {
	BackupID  string            `json:"backup_id"`
	NewName   string            `json:"new_name"`
	Version   string            `json:"version,omitempty"`
	ProjectID string            `json:"project_id,omitempty"`
	Resources *ServiceResources `json:"resources,omitempty"`
}

TriggerCloneRestoreRequest mirrors internal/api's cloneRestoreRequest.

type TriggerRestoreRequest

type TriggerRestoreRequest struct {
	BackupID string `json:"backup_id"`
}

TriggerRestoreRequest mirrors internal/api's triggerRestoreRequest.

type TriggerVolumeCloneRestoreRequest

type TriggerVolumeCloneRestoreRequest struct {
	BackupID      string `json:"backup_id"`
	NewVolumeName string `json:"new_volume_name,omitempty"`
}

TriggerVolumeCloneRestoreRequest mirrors internal/api's volumeCloneRestoreRequest.

type UpdateBackupTargetRequest

type UpdateBackupTargetRequest struct {
	Name            string `json:"name"`
	Provider        string `json:"provider"`
	Endpoint        string `json:"endpoint,omitempty"`
	Region          string `json:"region,omitempty"`
	Bucket          string `json:"bucket"`
	AccessKeyID     string `json:"access_key_id,omitempty"`
	SecretAccessKey string `json:"secret_access_key,omitempty"`
}

UpdateBackupTargetRequest mirrors internal/api's updateBackupTargetRequest. Blank AccessKeyID/SecretAccessKey keep the target's existing stored credentials; set together, they rotate them.

type UpdateCloudflareDNSRequest

type UpdateCloudflareDNSRequest struct {
	Enabled bool   `json:"enabled"`
	Token   string `json:"token,omitempty"`
}

UpdateCloudflareDNSRequest mirrors internal/api's updateCloudflareDNSRequest. Token empty on an update means "leave the currently stored token unchanged".

type UpdateCloudflareTunnelRequest

type UpdateCloudflareTunnelRequest struct {
	Enabled bool   `json:"enabled"`
	Token   string `json:"token,omitempty"`
}

UpdateCloudflareTunnelRequest mirrors internal/api's updateCloudflareTunnelRequest. Token empty on an update means "leave the currently stored token unchanged".

type UpdateEnvironmentRequest

type UpdateEnvironmentRequest struct {
	Protected bool `json:"protected"`
}

UpdateEnvironmentRequest mirrors internal/api's updateEnvironmentRequest (PATCH /api/v1/environments/{id}).

type UpdateRegistryCredentialRequest

type UpdateRegistryCredentialRequest struct {
	Name         string     `json:"name"`
	RegistryHost string     `json:"registry_host"`
	Username     string     `json:"username"`
	Password     string     `json:"password,omitempty"`
	ExpiresAt    *time.Time `json:"expires_at,omitempty"`
}

UpdateRegistryCredentialRequest mirrors internal/api's updateRegistryCredentialRequest. A blank Password keeps the credential's existing stored password; a non-blank one rotates it.

type UpdateRegistrySettingsRequest

type UpdateRegistrySettingsRequest struct {
	Enabled bool   `json:"enabled"`
	Host    string `json:"host,omitempty"`
}

UpdateRegistrySettingsRequest mirrors internal/api's updateRegistrySettingsRequest.

type UpdateUserAbilitiesRequest

type UpdateUserAbilitiesRequest struct {
	Abilities []string `json:"abilities,omitempty"`
	Role      string   `json:"role,omitempty"`
}

UpdateUserAbilitiesRequest mirrors internal/api's updateUserAbilitiesRequest, same Role/Abilities precedence as CreateUserRequest.

type UpdatesResource

type UpdatesResource struct {
	CurrentVersion  string  `json:"current_version"`
	LatestVersion   *string `json:"latest_version"`
	UpdateAvailable bool    `json:"update_available"`
	ReleaseURL      *string `json:"release_url"`
	PublishedAt     *string `json:"published_at"`
}

UpdatesResource mirrors internal/api's updateStatusResource (internal/api/updates.go): the running version compared against GitHub's latest published release. LatestVersion/ReleaseURL/PublishedAt are all nil when no release has ever been published.

type UserResource

type UserResource struct {
	ID          string     `json:"id"`
	Email       string     `json:"email"`
	DisplayName string     `json:"display_name"`
	HasPassword bool       `json:"has_password"`
	Providers   []string   `json:"providers"`
	Abilities   []string   `json:"abilities"`
	Role        string     `json:"role,omitempty"`
	IsFirstUser bool       `json:"is_first_user"`
	CreatedAt   time.Time  `json:"created_at"`
	LastLoginAt *time.Time `json:"last_login_at,omitempty"`
}

UserResource mirrors internal/api's userResource (internal/api/users.go).

type VolumeBackupScheduleResource

type VolumeBackupScheduleResource struct {
	ServiceName string `json:"service_name"`
	VolumeName  string `json:"volume_name"`
	TargetID    string `json:"target_id,omitempty"`
	Schedule    string `json:"schedule,omitempty"`
	Retain      int    `json:"retain,omitempty"`
	RetainDays  int    `json:"retain_days,omitempty"`
}

VolumeBackupScheduleResource mirrors internal/api's volumeBackupScheduleResource (internal/api/app_volume_backups.go).

type VolumeCloneRestoreResource

type VolumeCloneRestoreResource struct {
	ID                string `json:"id"`
	SourceServiceName string `json:"source_service_name"`
	SourceVolumeName  string `json:"source_volume_name"`
	NewVolumeName     string `json:"new_volume_name"`
	BackupHistoryID   string `json:"backup_history_id"`
	Status            string `json:"status"`
	Error             string `json:"error,omitempty"`
	StartedAt         string `json:"started_at"`
	FinishedAt        string `json:"finished_at,omitempty"`
}

VolumeCloneRestoreResource mirrors internal/api's volumeCloneRestoreResource (internal/api/app_volume_clone_restore.go): one "restore as new volume" attempt.

type WebhookDeliveryResource

type WebhookDeliveryResource struct {
	ID               string    `json:"id"`
	ServiceName      string    `json:"service_name"`
	Provider         string    `json:"provider"`
	EventType        string    `json:"event_type"`
	SignatureValid   bool      `json:"signature_valid"`
	Matched          bool      `json:"matched"`
	StatusCode       int       `json:"status_code"`
	Payload          string    `json:"payload"`
	PayloadTruncated bool      `json:"payload_truncated"`
	Error            string    `json:"error,omitempty"`
	ReceivedAt       time.Time `json:"received_at"`
}

WebhookDeliveryResource mirrors internal/api's webhookDeliveryResource (internal/api/webhook_deliveries.go): one recorded inbound git-provider webhook request.

Jump to

Keyboard shortcuts

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