Skip to main content

internal/api/manage.go

internal/api · 646 lines · 47 declarations · source

This file carries the package documentation, rendered on the package page.

Declarations

const ManagementPrefix

const ManagementPrefix = "/manage/" + Version

ManagementPrefix is where the management operations live: a prefix of their own, so a proxy or a network policy can expose the memory surface and not this one.

source

type ManagementStores

type ManagementStores struct {
Projects *pg.ProjectStore
Provision func(ctx context.Context, scope string) error
Observations *pg.ObservationStore
Audit *pg.AuditStore
Refusals *pg.RefusalStore
Eraser *pg.Eraser
// Health is the instance's operational snapshot: the formation backlog, whether a worker is
// answering, and how many connections the deployment holds against the server's ceiling. A
// function for the same reason Provision is — it reads catalogue views the operator connection
// can see and this surface holds no connection of that kind.
//
// Optional: a deployment wired without it loses the panel and keeps every other one, which is
// the right failure for a monitoring read.
Health func(ctx context.Context) (pg.OperationalHealth, error)
}

ManagementStores is what the management surface reads and writes. Provision creates a project's storage and needs the administrative connection; it is a function so the surface holds no connection of that kind itself.

source

type ManagementServer

type ManagementServer struct {
credentials *credential.Store
stores ManagementStores
schema pg.Schema
log *slog.Logger
admission *Admission
authAudits refusedAuthBudget
}

ManagementServer serves the operator surface.

source

func NewManagementServer

func NewManagementServer(credentials *credential.Store, stores ManagementStores, schema pg.Schema, log *slog.Logger) *ManagementServer

source

type managementRoute

type managementRoute struct {
Operation
handler func(*ManagementServer) grantedHandler
request any
response any
}

source

var managementOperations

var managementOperations = []managementRoute{
{Operation{domain.AuditProjectCreate, http.MethodPost, "/projects/create", http.StatusCreated}, func(m *ManagementServer) grantedHandler { return m.createProject }, projectRequest{}, projectResponse{}},
{Operation{domain.AuditProjectList, http.MethodPost, "/projects/list", http.StatusOK}, func(m *ManagementServer) grantedHandler { return m.listProjects }, nil, projectListResponse{}},
{Operation{domain.AuditProjectSuspend, http.MethodPost, "/projects/suspend", http.StatusOK}, func(m *ManagementServer) grantedHandler { return m.suspendProject }, projectRequest{}, projectResponse{}},
{Operation{domain.AuditProjectResume, http.MethodPost, "/projects/resume", http.StatusOK}, func(m *ManagementServer) grantedHandler { return m.resumeProject }, projectRequest{}, projectResponse{}},
{Operation{domain.AuditProjectRetention, http.MethodPost, "/projects/retention", http.StatusOK}, func(m *ManagementServer) grantedHandler { return m.setProjectRetention }, projectRetentionRequest{}, projectRetentionResponse{}},
{Operation{domain.AuditCredentialIssue, http.MethodPost, "/credentials/issue", http.StatusCreated}, func(m *ManagementServer) grantedHandler { return m.issueCredential }, credentialIssueRequest{}, credentialIssued{}},
{Operation{domain.AuditCredentialList, http.MethodPost, "/credentials/list", http.StatusOK}, func(m *ManagementServer) grantedHandler { return m.listCredentials }, credentialListRequest{}, credentialListResponse{}},
{Operation{domain.AuditCredentialRevoke, http.MethodPost, "/credentials/revoke", http.StatusOK}, func(m *ManagementServer) grantedHandler { return m.revokeCredential }, credentialRevokeRequest{}, credentialRevoked{}},
{Operation{domain.AuditRefusalSummary, http.MethodPost, "/refusals/summary", http.StatusOK}, func(m *ManagementServer) grantedHandler { return m.refusalSummary }, projectPageRequest{}, pg.RefusalSummary{}},
{Operation{domain.AuditErasureList, http.MethodPost, "/erasures/list", http.StatusOK}, func(m *ManagementServer) grantedHandler { return m.listErasures }, projectPageRequest{}, erasureListResponse{}},
{Operation{domain.AuditFormationStatus, http.MethodPost, "/formation/status", http.StatusOK}, func(m *ManagementServer) grantedHandler { return m.formationStatus }, nil, formationStatusResponse{}},
{Operation{domain.AuditFormationParked, http.MethodPost, "/formation/parked", http.StatusOK}, func(m *ManagementServer) grantedHandler { return m.listParked }, parkedRequest{}, pg.ParkedPage{}},
{Operation{domain.AuditFormationUnpark, http.MethodPost, "/formation/unpark", http.StatusOK}, func(m *ManagementServer) grantedHandler { return m.unpark }, unparkRequest{}, unparkResponse{}},
{Operation{domain.AuditAuditSeal, http.MethodPost, "/audit/seal", http.StatusOK}, func(m *ManagementServer) grantedHandler { return m.sealAudit }, nil, domain.AuditSeal{}},
{Operation{domain.AuditAuditVerify, http.MethodPost, "/audit/verify", http.StatusOK}, func(m *ManagementServer) grantedHandler { return m.verifyAudit }, nil, domain.AuditVerification{}},
}

The management surface, declared once, for the same reasons the memory surface is: it has to be enumerable for the contract, for the ledger and for the test that refuses every route to the wrong credential.

source

func ManagementOperations

func ManagementOperations() []Operation

ManagementOperations is the surface by operation, for the contract and the tests that walk it.

source

method ManagementServer.Handler

func (m *ManagementServer) Handler(readiness ...http.Handler) http.Handler

Handler mounts every management operation under the prefix, each behind the operator door, and the health endpoints, which say nothing; readiness, when given, is the database answering.

source

method ManagementServer.operated

func (m *ManagementServer) operated(next grantedHandler) http.Handler

operated is the operator door: an operator credential and nothing else, then the work slot.

source

method ManagementServer.recordRefusedAuth

func (m *ManagementServer) recordRefusedAuth(r *http.Request)

recordRefusedAuth is the memory door's rule applied here: the presented token never reaches the ledger, and the sampling budget bounds what an anonymous caller can make the instance write.

source

method ManagementServer.record

func (m *ManagementServer) record(r *http.Request, operation string, grant credential.Grant, project, outcome string, magnitude int)

record puts an operator's operation on the ledger, against the project the request named.

source

type projectRequest

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

source

type projectResponse

type projectResponse struct {
Project string `json:"project"`
Suspended bool `json:"suspended"`
}

source

type projectRetentionRequest

type projectRetentionRequest struct {
Name string `json:"name"`
RetentionDays *int `json:"retention_days"`
}

RetentionDays is how long new turns are kept. Null is indefinite, which is also how a project starts. Days rather than an interval: an interval accepted as text puts a parser between an operator and a deletion schedule.

source

type projectRetentionResponse

type projectRetentionResponse struct {
Project string `json:"project"`
Retention string `json:"retention"`
}

source

type projectListResponse

type projectListResponse struct {
Projects []pg.Listed `json:"projects"`
}

source

method ManagementServer.createProject

func (m *ManagementServer) createProject(w http.ResponseWriter, r *http.Request, grant credential.Grant)

source

method ManagementServer.listProjects

func (m *ManagementServer) listProjects(w http.ResponseWriter, r *http.Request, grant credential.Grant)

source

method ManagementServer.suspendProject

func (m *ManagementServer) suspendProject(w http.ResponseWriter, r *http.Request, grant credential.Grant)

source

method ManagementServer.resumeProject

func (m *ManagementServer) resumeProject(w http.ResponseWriter, r *http.Request, grant credential.Grant)

source

method ManagementServer.setProjectRetention

func (m *ManagementServer) setProjectRetention(w http.ResponseWriter, r *http.Request, grant credential.Grant)

setProjectRetention says how long a project keeps what it is told from now on.

A governance decision, so it is on the ledger beside suspension, and it changes nothing already stored: a deadline is stamped on a turn when it arrives, and the policy in force then governs it.

source

func retentionText

func retentionText(days *int) string

retentionText says a policy the way an operator wrote it.

source

method ManagementServer.setSuspended

func (m *ManagementServer) setSuspended(w http.ResponseWriter, r *http.Request, grant credential.Grant, operation string, suspended bool)

source

type credentialIssueRequest

type credentialIssueRequest struct {
Name string `json:"name"`
Project string `json:"project"`
// Access is read_only or read_write; omitted means read_write.
Access string `json:"access"`
}

source

type credentialIssued

type credentialIssued struct {
ID string `json:"id"`
Name string `json:"name"`
Project string `json:"project"`
Access string `json:"access"`
Token string `json:"token"`
}

credentialIssued carries the token once. It is not recoverable afterwards, by anyone.

source

type credentialListRequest

type credentialListRequest struct {
// Project names whose credentials to list; empty lists the operator credentials.
Project string `json:"project"`
Limit int `json:"limit"`
}

source

type credentialListResponse

type credentialListResponse struct {
Credentials []credential.Listed `json:"credentials"`
}

source

type credentialRevokeRequest

type credentialRevokeRequest struct {
ID string `json:"id"`
}

source

type credentialRevoked

type credentialRevoked struct {
ID string `json:"id"`
Revoked bool `json:"revoked"`
}

source

method ManagementServer.issueCredential

func (m *ManagementServer) issueCredential(w http.ResponseWriter, r *http.Request, grant credential.Grant)

source

method ManagementServer.listCredentials

func (m *ManagementServer) listCredentials(w http.ResponseWriter, r *http.Request, grant credential.Grant)

source

method ManagementServer.revokeCredential

func (m *ManagementServer) revokeCredential(w http.ResponseWriter, r *http.Request, grant credential.Grant)

source

type projectPageRequest

type projectPageRequest struct {
Project string `json:"project"`
Limit int `json:"limit"`
}

source

type erasureListResponse

type erasureListResponse struct {
Erasures []pg.ErasureReceipt `json:"erasures"`
}

source

method ManagementServer.projectPage

func (m *ManagementServer) projectPage(w http.ResponseWriter, r *http.Request) (projectPageRequest, bool)

source

method ManagementServer.refusalSummary

func (m *ManagementServer) refusalSummary(w http.ResponseWriter, r *http.Request, grant credential.Grant)

source

method ManagementServer.listErasures

func (m *ManagementServer) listErasures(w http.ResponseWriter, r *http.Request, grant credential.Grant)

source

type formationScope

type formationScope struct {
Project string `json:"project"`
Suspended bool `json:"suspended"`
Stored *int64 `json:"stored"`
Formed *int64 `json:"formed"`
Parked int `json:"parked"`
}

source

type formationStatusResponse

type formationStatusResponse struct {
Scopes []formationScope `json:"scopes"`
}

source

method ManagementServer.formationStatus

func (m *ManagementServer) formationStatus(w http.ResponseWriter, r *http.Request, grant credential.Grant)

source

type parkedRequest

type parkedRequest struct {
Project string `json:"project"`
// After is an exclusive log offset; omitted starts from the beginning.
After *int64 `json:"after"`
Limit int `json:"limit"`
}

source

method ManagementServer.listParked

func (m *ManagementServer) listParked(w http.ResponseWriter, r *http.Request, grant credential.Grant)

source

type unparkRequest

type unparkRequest struct {
Project string `json:"project"`
ObservationID string `json:"observation_id"`
}

source

type unparkResponse

type unparkResponse struct {
ObservationID string `json:"observation_id"`
Unparked bool `json:"unparked"`
}

source

method ManagementServer.unpark

func (m *ManagementServer) unpark(w http.ResponseWriter, r *http.Request, grant credential.Grant)

source

method ManagementServer.sealAudit

func (m *ManagementServer) sealAudit(w http.ResponseWriter, r *http.Request, grant credential.Grant)

source

method ManagementServer.verifyAudit

func (m *ManagementServer) verifyAudit(w http.ResponseWriter, r *http.Request, grant credential.Grant)

source