init
This commit is contained in:
+258
@@ -0,0 +1,258 @@
|
||||
package api
|
||||
|
||||
import "time"
|
||||
|
||||
// Deployment states, as they appear on the wire.
|
||||
const (
|
||||
StatePending = "pending"
|
||||
StateUploading = "uploading"
|
||||
StateReady = "ready"
|
||||
StateFailed = "failed"
|
||||
StateDeleting = "deleting"
|
||||
)
|
||||
|
||||
// Key scopes, as they appear on the wire.
|
||||
const (
|
||||
ScopeAdmin = "admin"
|
||||
ScopeProject = "project"
|
||||
)
|
||||
|
||||
// ---------------------------------------------------------------- projects
|
||||
|
||||
// Project is the server's view of a project.
|
||||
//
|
||||
// Every mutable setting also appears in ProjectPatch. Adding a field here that
|
||||
// cannot be changed afterwards is a deliberate choice, not an oversight: Name
|
||||
// is immutable because renaming would invalidate every deployed URL and every
|
||||
// webroot symlink pointing at it.
|
||||
type Project struct {
|
||||
Name string `json:"name"`
|
||||
DisplayName string `json:"display_name,omitempty"`
|
||||
IndexFile string `json:"index_file"`
|
||||
NotFoundFile string `json:"not_found_file,omitempty"`
|
||||
SPAFallback bool `json:"spa_fallback"`
|
||||
CacheControl string `json:"cache_control"`
|
||||
|
||||
RetentionCount int `json:"retention_count"`
|
||||
RetentionGrace int `json:"retention_grace_s"`
|
||||
MaxFiles int `json:"max_files"`
|
||||
MaxFileBytes int64 `json:"max_file_bytes"`
|
||||
MaxTotalBytes int64 `json:"max_total_bytes"`
|
||||
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// ActiveDeployment is nil when the project has never been deployed, which
|
||||
// is why it is a pointer rather than a zero-valued struct.
|
||||
ActiveDeployment *Deployment `json:"active_deployment,omitempty"`
|
||||
// URL is where the active deployment is served, when the server knows its
|
||||
// public base URL.
|
||||
URL string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
// CreateProjectRequest creates a project. Everything except Name is optional
|
||||
// and falls back to the server's defaults.
|
||||
type CreateProjectRequest struct {
|
||||
Name string `json:"name"`
|
||||
Patch *ProjectPatch `json:"config,omitempty"`
|
||||
}
|
||||
|
||||
// ProjectPatch is a partial update.
|
||||
//
|
||||
// Every field is a pointer so the server can tell "leave this alone" from "set
|
||||
// this to the zero value" — without that, PATCH could never clear a custom 404
|
||||
// document or turn the SPA fallback off.
|
||||
type ProjectPatch struct {
|
||||
DisplayName *string `json:"display_name,omitempty"`
|
||||
IndexFile *string `json:"index_file,omitempty"`
|
||||
NotFoundFile *string `json:"not_found_file,omitempty"`
|
||||
SPAFallback *bool `json:"spa_fallback,omitempty"`
|
||||
CacheControl *string `json:"cache_control,omitempty"`
|
||||
RetentionCount *int `json:"retention_count,omitempty"`
|
||||
RetentionGrace *int `json:"retention_grace_s,omitempty"`
|
||||
MaxFiles *int `json:"max_files,omitempty"`
|
||||
MaxFileBytes *int64 `json:"max_file_bytes,omitempty"`
|
||||
MaxTotalBytes *int64 `json:"max_total_bytes,omitempty"`
|
||||
}
|
||||
|
||||
// ProjectList is the paged response for GET /api/v1/projects.
|
||||
type ProjectList struct {
|
||||
Projects []Project `json:"projects"`
|
||||
NextCursor string `json:"next_cursor,omitempty"`
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------- keys
|
||||
|
||||
// Key describes an API key. It never carries the secret: the full token exists
|
||||
// on the wire exactly once, in CreateKeyResponse.
|
||||
type Key struct {
|
||||
ID string `json:"id"`
|
||||
Scope string `json:"scope"`
|
||||
Project string `json:"project,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
ExpiresAt *time.Time `json:"expires_at,omitempty"`
|
||||
LastUsed *time.Time `json:"last_used_at,omitempty"`
|
||||
RevokedAt *time.Time `json:"revoked_at,omitempty"`
|
||||
}
|
||||
|
||||
// Revoked reports whether the key has been revoked.
|
||||
func (k Key) Revoked() bool { return k.RevokedAt != nil }
|
||||
|
||||
// CreateKeyRequest mints a key. Project is set by the URL for the
|
||||
// project-scoped endpoint and must be empty otherwise.
|
||||
type CreateKeyRequest struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
// ExpiresAt is absolute, not a duration: the CLI parses "90d" locally so a
|
||||
// clock skew between client and server cannot silently shift expiry.
|
||||
ExpiresAt *time.Time `json:"expires_at,omitempty"`
|
||||
}
|
||||
|
||||
// CreateKeyResponse is the only place a full token ever appears.
|
||||
type CreateKeyResponse struct {
|
||||
Key Key `json:"key"`
|
||||
// Token is shown once and never retrievable again. Clients must not log it.
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
// KeyList is the response for the key listing endpoints.
|
||||
type KeyList struct {
|
||||
Keys []Key `json:"keys"`
|
||||
}
|
||||
|
||||
// WhoAmI describes the caller's own credential.
|
||||
type WhoAmI struct {
|
||||
KeyID string `json:"key_id"`
|
||||
Scope string `json:"scope"`
|
||||
Project string `json:"project,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
ExpiresAt *time.Time `json:"expires_at,omitempty"`
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------- deployments
|
||||
|
||||
// Deployment is the server's view of one upload.
|
||||
type Deployment struct {
|
||||
ID string `json:"id"`
|
||||
Project string `json:"project"`
|
||||
State string `json:"state"`
|
||||
Active bool `json:"active"`
|
||||
FileCount int `json:"file_count"`
|
||||
TotalBytes int64 `json:"total_bytes"`
|
||||
Meta map[string]string `json:"meta,omitempty"`
|
||||
Error string `json:"error,omitempty"`
|
||||
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
FinalizedAt *time.Time `json:"finalized_at,omitempty"`
|
||||
ActivatedAt *time.Time `json:"activated_at,omitempty"`
|
||||
|
||||
// URL is where this deployment is served, set on the response to an
|
||||
// activation when the server knows its public base URL. It is the project's
|
||||
// URL: only the active deployment has one, since there are no per-version
|
||||
// preview addresses.
|
||||
URL string `json:"url,omitempty"`
|
||||
|
||||
// Files is populated only by GET .../deployments/{id}?files=true.
|
||||
Files []FileEntry `json:"files,omitempty"`
|
||||
}
|
||||
|
||||
// FileEntry is one line of a manifest. Digest is lowercase hex; the server
|
||||
// stores the raw 32 bytes, and hex exists only at this boundary.
|
||||
type FileEntry struct {
|
||||
Path string `json:"path"`
|
||||
Digest string `json:"digest"`
|
||||
Size int64 `json:"size"`
|
||||
}
|
||||
|
||||
// CreateDeploymentRequest starts a deployment.
|
||||
type CreateDeploymentRequest struct {
|
||||
Meta map[string]string `json:"meta,omitempty"`
|
||||
}
|
||||
|
||||
// ManifestRequest declares the complete file list of a deployment.
|
||||
type ManifestRequest struct {
|
||||
Files []FileEntry `json:"files"`
|
||||
}
|
||||
|
||||
// ManifestResponse tells the client which blobs the server does not have yet.
|
||||
//
|
||||
// Missing is the number that makes content-addressed upload worth having, so
|
||||
// the CLI prints it: "142 files, 3.1 MiB; 11 new blobs, 402 KiB to upload".
|
||||
type ManifestResponse struct {
|
||||
Missing []string `json:"missing"`
|
||||
MissingBytes int64 `json:"missing_bytes"`
|
||||
Have int `json:"have"`
|
||||
FileCount int `json:"file_count"`
|
||||
TotalBytes int64 `json:"total_bytes"`
|
||||
}
|
||||
|
||||
// BlobResponse acknowledges an uploaded blob.
|
||||
type BlobResponse struct {
|
||||
Digest string `json:"digest"`
|
||||
Size int64 `json:"size"`
|
||||
}
|
||||
|
||||
// DeploymentList is the paged response for the deployment listing endpoint.
|
||||
type DeploymentList struct {
|
||||
Deployments []Deployment `json:"deployments"`
|
||||
NextCursor string `json:"next_cursor,omitempty"`
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------ system
|
||||
|
||||
// SystemInfo is the response for GET /api/v1/system/info.
|
||||
type SystemInfo struct {
|
||||
Version string `json:"version"`
|
||||
UptimeS int64 `json:"uptime_s"`
|
||||
Projects int64 `json:"projects"`
|
||||
Deployments int64 `json:"deployments"`
|
||||
Blobs int64 `json:"blobs"`
|
||||
CASBytes int64 `json:"cas_bytes"`
|
||||
LinkMode string `json:"link_mode"`
|
||||
SchemaVer int `json:"schema_version"`
|
||||
}
|
||||
|
||||
// GCRequest asks for a garbage collection pass.
|
||||
type GCRequest struct {
|
||||
DryRun bool `json:"dry_run,omitempty"`
|
||||
}
|
||||
|
||||
// GCStats reports what a collection pass did, or would have done.
|
||||
//
|
||||
// On a dry run the blob numbers count what is collectable right now, not what
|
||||
// deleting the listed deployments would additionally free: nothing was deleted,
|
||||
// so those blobs are still referenced. The figures are a floor.
|
||||
type GCStats struct {
|
||||
DryRun bool `json:"dry_run"`
|
||||
DeploymentsDeleted int `json:"deployments_deleted"`
|
||||
BlobsDeleted int `json:"blobs_deleted"`
|
||||
BytesFreed int64 `json:"bytes_freed"`
|
||||
}
|
||||
|
||||
// FsckRequest asks for a consistency check, optionally correcting what it
|
||||
// finds.
|
||||
type FsckRequest struct {
|
||||
Repair bool `json:"repair,omitempty"`
|
||||
}
|
||||
|
||||
// FsckReport is the result of a consistency check.
|
||||
type FsckReport struct {
|
||||
// Blobs is how many were examined, DriftCount how many disagreed with the
|
||||
// manifests that reference them. Drift lists the first hundred of them,
|
||||
// because the list is for a person to read.
|
||||
Blobs int64 `json:"blobs"`
|
||||
DriftCount int `json:"drift_count"`
|
||||
Drift []BlobDrift `json:"drift,omitempty"`
|
||||
Repaired int `json:"repaired"`
|
||||
}
|
||||
|
||||
// BlobDrift is one blob whose stored reference count is not the number of
|
||||
// manifest entries that name it.
|
||||
type BlobDrift struct {
|
||||
Digest string `json:"digest"`
|
||||
// Stored above Actual only wastes disk. Stored below Actual is the
|
||||
// dangerous direction: the collector may remove content a deployment still
|
||||
// needs.
|
||||
Stored int64 `json:"stored"`
|
||||
Actual int64 `json:"actual"`
|
||||
}
|
||||
Reference in New Issue
Block a user