Documentation
¶
Overview ¶
Package configapp is the configuration service of the admin plane: the scanned catalog, schema scans and scan batches, plans and their previews, plan templates, pending work and administrators' MCP tokens. It checks who may do what (the signed-in principal on the context, with its permissions and datasources) and holds every business rule; the admin API (GraphQL) and the configuration MCP endpoint only adapt their requests and results.
Index ¶
- Constants
- Variables
- func DecodePlan(v any) (configplan.Plan, error)
- func LoadCatalog(ctx context.Context, in introspect.Introspector, schemas []string, ...) (introspect.Catalog, error)
- func NormalizeJSON(v any) any
- func ParseID(id string) (int64, error)
- type Against
- type AppliedPlan
- type ApplyRequest
- type Built
- type CatalogCounts
- type CatalogCoverage
- type CatalogFilter
- type CatalogLinks
- type CatalogPage
- type CatalogRow
- type CommitInput
- type Draft
- type EntityItem
- type EntityMCPItem
- type FieldItem
- type FieldReference
- type GrantItem
- type Imports
- type Introspection
- type McpToken
- type McpTokenInput
- type McpTokenSecret
- type PendingDraft
- type PendingPlan
- type PendingState
- type PendingStateInput
- type PendingTable
- type PendingWork
- type PlanChange
- type PlanException
- type PlanObjects
- type PlanReport
- type PlanStore
- type PlanTemplate
- type PlanTemplateInput
- type Preview
- type RelationshipItem
- type RoleItem
- type ScanBatch
- type ScanBatchInput
- type ScanBatchItem
- type ScanJob
- type Scans
- type SchemaInfo
- type SchemaList
- type ScopeCondition
- type ScopeStats
- type Sections
- type Service
- func (r *Service) ApplyPlan(ctx context.Context, in ApplyRequest) (*AppliedPlan, error)
- func (r *Service) BuildDraft(ctx context.Context, d Draft) (Built, error)
- func (r *Service) CancelScanBatch(ctx context.Context, id string) (*ScanBatch, error)
- func (r *Service) Catalog(ctx context.Context, f CatalogFilter, against Against, offset, limit int) (*CatalogPage, error)
- func (r *Service) CatalogLinks(ctx context.Context, ref string, against Against) (*CatalogLinks, error)
- func (r *Service) CatalogRefs(ctx context.Context, f CatalogFilter, against Against) ([]string, error)
- func (r *Service) CatalogTable(ctx context.Context, ref string, against Against) (*configplan.Candidate, error)
- func (r *Service) CheckpointWorkspace(ctx context.Context, comment *string) (revision.Revision, error)
- func (r *Service) CommitWorkspace(ctx context.Context, in CommitInput) (revision.Revision, error)
- func (r *Service) CreateMcpToken(ctx context.Context, in McpTokenInput) (*McpTokenSecret, error)
- func (r *Service) DeletePlanTemplate(ctx context.Context, name string) (bool, error)
- func (r *Service) Diff(ctx context.Context, from string, to Against) (string, error)
- func (r *Service) DiscardDraft(ctx context.Context, id string) (revision.Revision, error)
- func (r *Service) Drafts(ctx context.Context) ([]PendingDraft, error)
- func (r *Service) EditWorkspace(ctx context.Context, in WorkspaceEditInput) (*Workspace, error)
- func (r *Service) FieldReferences(ctx context.Context, entity string) ([]FieldReference, error)
- func (r *Service) McpTokens(ctx context.Context) ([]McpToken, error)
- func (r *Service) MergeDraft(ctx context.Context, id string) (*Workspace, error)
- func (r *Service) Ops() revisionops.Service
- func (r *Service) Pending(ctx context.Context, against Against) (*PendingWork, error)
- func (r *Service) PendingLog(ctx context.Context, key string) ([]PendingState, error)
- func (r *Service) PlanScope(ctx context.Context, scope configplan.Scope, against Against) (*ScopeStats, error)
- func (r *Service) PlanTemplateVersions(ctx context.Context, name string) ([]PlanTemplate, error)
- func (r *Service) PlanTemplates(ctx context.Context) ([]PlanTemplate, error)
- func (r *Service) PreviewInWorkspace(ctx context.Context, p configplan.Plan, review bool) (*Preview, error)
- func (r *Service) PreviewPlan(ctx context.Context, p configplan.Plan, against Against, review bool) (*Preview, error)
- func (r *Service) Previewed(ctx context.Context, planID string) (*Preview, error)
- func (r *Service) ResetWorkspace(ctx context.Context, to string) (*Workspace, error)
- func (r *Service) ResolveConflict(ctx context.Context, id string, theirs bool) (*Workspace, error)
- func (r *Service) RestartChanges(ctx context.Context, next *config.Config) ([]string, error)
- func (r *Service) RetryScanBatch(ctx context.Context, id string) (*ScanBatch, error)
- func (r *Service) Revision(ctx context.Context, id string) (revision.Revision, error)
- func (r *Service) Revisions(ctx context.Context, limit int) ([]revision.Revision, error)
- func (r *Service) RevokeMcpToken(ctx context.Context, id string) (bool, error)
- func (r *Service) SavePlanTemplate(ctx context.Context, in PlanTemplateInput) (*PlanTemplate, error)
- func (r *Service) ScanBatches(ctx context.Context, datasource string) ([]ScanBatch, error)
- func (r *Service) SchemaList(ctx context.Context, datasource string, refresh bool) (*SchemaList, error)
- func (r *Service) SchemaScan(ctx context.Context, id string, cancel bool) (*ScanJob, error)
- func (r *Service) SchemaTables(ctx context.Context, datasource string, schemas []string) (*Imports, error)
- func (r *Service) SelectConfig(ctx context.Context, against Against) (*config.Config, error)
- func (r *Service) SetPendingState(ctx context.Context, in PendingStateInput) (*PendingState, error)
- func (r *Service) Simulate(ctx context.Context, in SimulateRequest) (*Simulation, error)
- func (r *Service) StartScanBatch(ctx context.Context, in ScanBatchInput) (*ScanBatch, error)
- func (r *Service) StartSchemaScan(ctx context.Context, datasource string, schemas []string) (*ScanJob, error)
- func (r *Service) UpdateWorkspace(ctx context.Context, to string) (*Workspace, error)
- func (r *Service) Validate(ctx context.Context, against Against) (*Validation, error)
- func (r *Service) WatchScanBatches()
- func (r *Service) Workspace(ctx context.Context) (*Workspace, error)
- func (r *Service) WorkspaceLog(ctx context.Context, limit *int) ([]WorkspaceLogEntry, error)
- type SimulateRequest
- type Simulation
- type Simulator
- type TableLink
- type UnscannedSchemas
- type UserItem
- type Validation
- type Workspace
- type WorkspaceConflict
- type WorkspaceEditInput
- type WorkspaceItemInput
- type WorkspaceLogEntry
- type WorkspaceNote
- type WorkspaceRef
Constants ¶
const ( ItemEntity = "entity" ItemRole = "role" ItemUser = "user" ItemSettings = "settings" )
The kinds of workspace items, as the console names its changes.
const ( ScanStatePending = "PENDING" ScanStateRunning = "RUNNING" ScanStateDone = "DONE" ScanStateFailed = "FAILED" ScanStateCanceled = "CANCELED" )
The states of a scan job (GraphQL ScanState), as scanjobs names them.
const ( // No entity reads the table. TableStatusNew = "NEW" // An entity of the workspace reads it, not yet published. TableStatusWorkspace = "WORKSPACE" // A published entity reads it. TableStatusPublished = "PUBLISHED" )
How a scanned table stands to the configuration (GraphQL TableStatus).
const RequestScanTimeout = 30 * time.Second
RequestScanTimeout bounds the reads that answer within their request: tableComments and schemaList.
Variables ¶
var ErrPlanChanged = errors.New("the plan is not the one previewed, or its preview expired and what it evaluates " +
"to changed since (a publish, a workspace edit or a new scan): preview it again")
ErrPlanChanged: a plan is not the one its preview ID names, or changed while it was checked.
var ErrWorkspaceChanged = workspace.ErrChanged
ErrWorkspaceChanged: the workspace was written since it was read.
var ErrWorkspaceContent = errors.New("workspace items are not a configuration")
ErrWorkspaceContent is a workspace whose items do not read as configuration (an agent wrote a section of the wrong shape): what it would configure cannot be told, as a validation of it reports.
var Schema = mergeSchema(EntityItem{}, RoleItem{}, UserItem{})
Schema is how the configuration's values merge, read off the item types (see mergeSchema): fields and relationships keyed by name, grants by the entity they name; optional text, and switches off unless set, unset when empty or false (an empty token hash: no token).
Functions ¶
func DecodePlan ¶
func DecodePlan(v any) (configplan.Plan, error)
DecodePlan reads a plan from its JSON value.
func LoadCatalog ¶
func LoadCatalog( ctx context.Context, in introspect.Introspector, schemas []string, withDefault bool, ) (introspect.Catalog, error)
LoadCatalog loads a catalog that matches names the way the database compares them, as assembly does.
func NormalizeJSON ¶
NormalizeJSON turns json.Number values (GraphQL variables decode numbers so) into int64 or float64, so YAML encodes them as numbers, not strings.
Types ¶
type Against ¶
Against is the configuration a read is about: the caller's workspace (the published configuration until they write it), a revision, or, the zero Against, the published revision. The console reads its workspace; agents read the published configuration unless they plan (see PreviewInWorkspace).
type AppliedPlan ¶
type AppliedPlan struct {
Items []WorkspaceRef `json:"items"`
Comment string `json:"comment,omitempty"`
}
AppliedPlan is what applying a plan wrote.
type ApplyRequest ¶
type ApplyRequest struct {
Plan configplan.Plan
PlanID string
Review bool
// Confirmed are the IDs of the exceptions to confirm reported to the
// administrator: every one of them.
Confirmed []string
Comment string
// Agent names the agent (its token) applying the plan; empty: the
// administrator, in the console.
Agent string
}
ApplyRequest applies a plan to the caller's workspace.
type CatalogCounts ¶
type CatalogCoverage ¶
type CatalogCoverage struct {
Datasource string `json:"datasource"`
// Schemas scanned.
Scanned int `json:"scanned"`
// Schemas listed; null when never listed.
Listed *int `json:"listed,omitempty"`
// Listed schemas never scanned.
Unscanned []string `json:"unscanned"`
// When the oldest scanned schema was scanned; null when none.
OldestScan *time.Time `json:"oldestScan,omitempty"`
}
What has been scanned of a datasource.
type CatalogFilter ¶
type CatalogFilter struct {
// Datasources to search; empty: all.
Datasources []string `json:"datasources,omitempty"`
// Glob patterns (* and ?) on schema names.
Schemas []string `json:"schemas,omitempty"`
// Glob patterns on table names.
Tables []string `json:"tables,omitempty"`
// A part of the table name or its comment.
Search *string `json:"search,omitempty"`
Status []string `json:"status,omitempty"`
// Only configured tables whose columns and fields differ.
Drift *bool `json:"drift,omitempty"`
}
type CatalogLinks ¶
type CatalogPage ¶
type CatalogPage struct {
// Tables matching the filter.
Total int `json:"total"`
Tables []CatalogRow `json:"tables"`
// Tables by status, matching every condition but the status.
Counts *CatalogCounts `json:"counts"`
Coverage []CatalogCoverage `json:"coverage"`
}
type CatalogRow ¶
type CatalogRow struct {
// datasource.schema.table: the ID an entity named like the table would have.
Ref string `json:"ref"`
Datasource string `json:"datasource"`
Schema string `json:"schema"`
Table string `json:"table"`
Description string `json:"description"`
View bool `json:"view"`
Columns int `json:"columns"`
// Foreign keys of the table, and of other scanned tables referencing it.
ForeignKeys int `json:"foreignKeys"`
ReferencedBy int `json:"referencedBy"`
// Whether a key identifies a row.
HasKey bool `json:"hasKey"`
SideEffects bool `json:"sideEffects"`
Status string `json:"status"`
// The entity that reads the table.
Entity *string `json:"entity,omitempty"`
// Columns without a field, and fields without a column.
Added []string `json:"added"`
Missing []string `json:"missing"`
// When the table's schema was scanned.
ScannedAt *time.Time `json:"scannedAt,omitempty"`
}
type CommitInput ¶
type CommitInput struct {
Version int `json:"version"`
ExpectedPublished string `json:"expectedPublished"`
Comment *string `json:"comment,omitempty"`
RestartRequired *bool `json:"restartRequired,omitempty"`
}
CommitInput commits the workspace at the version reviewed.
type Draft ¶
type Draft struct {
Base string
Edit configedit.Edit
}
Draft is a configuration being edited: a base revision with sections replaced.
type EntityItem ¶
type EntityItem struct {
Name string `json:"name"`
Source *string `json:"source,omitempty"`
Datasource *string `json:"datasource,omitempty"`
Schema *string `json:"schema,omitempty"`
Kind *string `json:"kind,omitempty"`
Description *string `json:"description,omitempty"`
PrimaryKey []string `json:"primaryKey"`
UniqueKeys [][]string `json:"uniqueKeys"`
Fields []FieldItem `json:"fields" merge:"key=name"`
Relationships []RelationshipItem `json:"relationships" merge:"key=name"`
TenantPolicy any `json:"tenantPolicy,omitempty"`
LegacyAccess any `json:"legacyAccess,omitempty"`
Mcp *EntityMCPItem `json:"mcp,omitempty"`
Params []string `json:"params"`
Affects []string `json:"affects"`
AllowCascade *bool `json:"allowCascade,omitempty" merge:"unset"`
}
EntityItem is an entity. Lists are always written (empty when unset); legacyAccess holds the entity-level roles, fieldACL and rowPolicies.
func EntityItemOf ¶
func EntityItemOf(e config.EntityConfig) EntityItem
EntityItemOf is the item of an entity built in code (a candidate).
type EntityMCPItem ¶
type EntityMCPItem struct {
DmlTools *bool `json:"dmlTools,omitempty"`
CustomTool *bool `json:"customTool,omitempty" merge:"unset"`
TrustedProcedure *bool `json:"trustedProcedure,omitempty" merge:"unset"`
}
EntityMCPItem are an entity's MCP flags; an unset dmlTools defaults on.
type FieldItem ¶
type FieldItem struct {
Name string `json:"name"`
Alias *string `json:"alias,omitempty"`
Description *string `json:"description,omitempty"`
Mask *string `json:"mask,omitempty"`
Exclude *bool `json:"exclude,omitempty" merge:"unset"`
}
FieldItem is a field of an entity.
type FieldReference ¶
type FieldReference struct {
Field string `json:"field"`
Kind string `json:"kind"`
Name string `json:"name"`
Via *string `json:"via,omitempty"`
}
FieldReference is a place in the workspace naming a field of an entity: a role or user (Via fields: a grant lists it, which removing the field takes care of; rows: a grant filters by it, to fix first), or an entity's relationship, primaryKey, uniqueKey or tenantPolicy (Name its ID).
type GrantItem ¶
type GrantItem struct {
Entity string `json:"entity"`
Actions []string `json:"actions"`
FieldsRestricted *bool `json:"fieldsRestricted,omitempty"`
ReadFields []string `json:"readFields"`
WriteFields []string `json:"writeFields"`
Rows any `json:"rows,omitempty"`
}
GrantItem is a grant of a role or user; actions are upper case (READ). Without fieldsRestricted, read or write fields restrict the grant.
type Imports ¶
type Imports struct {
Datasource string
DefaultSchema string
// Source is the token of the database the tables were read from.
Source string
Tables []configplan.Candidate
}
Imports are the scanned tables of a datasource with the entity proposed for each.
type Introspection ¶
type Introspection func( ctx context.Context, datasource string, database config.DatabaseConfig, fn func(introspect.Introspector) error, ) error
Introspection runs fn with the introspector of datasource, reading the database that database (its configuration) names: what is read is what the caller took from its configuration, even before the runtime applies it.
type McpToken ¶
type McpToken struct {
ID string `json:"id"`
Name string `json:"name"`
CreatedAt time.Time `json:"createdAt"`
// null: never expires.
ExpiresAt *time.Time `json:"expiresAt,omitempty"`
LastUsedAt *time.Time `json:"lastUsedAt,omitempty"`
// The datasources it reaches; null: every one.
Datasources []string `json:"datasources,omitempty"`
// Refused: created read only, which is no longer offered; generate a new one.
Retired bool `json:"retired"`
}
type McpTokenInput ¶
type McpTokenInput struct {
// Names the client, unique among the administrator's tokens.
Name string `json:"name"`
// Days until it expires; null or 0 never.
ExpiresInDays *int `json:"expiresInDays,omitempty"`
// Limits it to these datasources; null: every one.
Datasources []string `json:"datasources,omitempty"`
}
type McpTokenSecret ¶
type PendingDraft ¶
PendingDraft is a draft with the revision it builds on: the first up its parents that is not a draft (0: none).
type PendingPlan ¶
type PendingPlan struct {
// Changes when the report does: a new situation opens again.
Key string `json:"key"`
Template *PlanTemplate `json:"template"`
Report *PlanReport `json:"report"`
State *PendingState `json:"state,omitempty"`
}
type PendingState ¶
type PendingState struct {
Key string `json:"key"`
// open, snoozed or ignored; a snooze that ended reads open.
Status string `json:"status"`
Owner *string `json:"owner,omitempty"`
Reason *string `json:"reason,omitempty"`
Until *time.Time `json:"until,omitempty"`
UpdatedBy string `json:"updatedBy"`
UpdatedAt time.Time `json:"updatedAt"`
}
type PendingStateInput ¶
type PendingStateInput struct {
// The item's key, as PendingWork gives it.
Key string `json:"key"`
// open, snoozed or ignored.
Status string `json:"status"`
Owner *string `json:"owner,omitempty"`
Reason *string `json:"reason,omitempty"`
// When a snoozed item opens again.
Until *time.Time `json:"until,omitempty"`
}
type PendingTable ¶
type PendingWork ¶
type PendingWork struct {
// Recurring templates whose plan would change the configuration or has rules it cannot apply.
Plans []PendingPlan `json:"plans"`
// Tables whose fields differ from their columns.
DriftTables []PendingTable `json:"driftTables"`
Drift int `json:"drift"`
NewTables int `json:"newTables"`
UnscannedSchemas int `json:"unscannedSchemas"`
// Datasources whose schemas were never listed: what they hold is unknown.
UnlistedDatasources []string `json:"unlistedDatasources"`
}
type PlanChange ¶
type PlanChange struct {
// import, createRole, grant, exclude, mask, syncAdd or syncRemove.
Kind string `json:"kind"`
Principal *string `json:"principal,omitempty"`
Actions []string `json:"actions"`
Mask *string `json:"mask,omitempty"`
// Fields a field change touches.
Fields int `json:"fields"`
Entities []string `json:"entities"`
}
type PlanException ¶
type PlanException struct {
// Identifies the exception within its plan: a draft is saved with each exception to confirm
// confirmed by its ID.
ID string `json:"id"`
// renamed, noKey, sideEffects, relationshipDropped, qualified, unknownUser,
// noFields, referenced, denied or review.
Kind string `json:"kind"`
// block (the proposal cannot be taken), confirm (taking it needs the
// exception acknowledged) or info.
Level string `json:"level"`
// Not only informative: level is block or confirm.
Warning bool `json:"warning"`
// The table, when excluding it is a way out.
Ref *string `json:"ref,omitempty"`
Entity *string `json:"entity,omitempty"`
Detail *string `json:"detail,omitempty"`
}
type PlanObjects ¶
type PlanReport ¶
type PlanReport struct {
Matched int `json:"matched"`
Excluded int `json:"excluded"`
Objects []PlanObjects `json:"objects"`
Changes []PlanChange `json:"changes"`
Exceptions []PlanException `json:"exceptions"`
Unscanned []UnscannedSchemas `json:"unscanned"`
// When the tables in scope were scanned, oldest and newest.
ScannedFrom *time.Time `json:"scannedFrom,omitempty"`
ScannedTo *time.Time `json:"scannedTo,omitempty"`
}
type PlanStore ¶
type PlanStore interface {
PlanTemplates(ctx context.Context) ([]configstore.PlanTemplate, error)
PlanTemplateVersions(ctx context.Context, name string) ([]configstore.PlanTemplate, error)
PutPlanTemplate(ctx context.Context, t configstore.PlanTemplate, expected int) (configstore.PlanTemplate, error)
DeletePlanTemplate(ctx context.Context, name string) error
AdminTokens(ctx context.Context, username string) ([]configstore.AdminToken, error)
AdminTokenByHash(ctx context.Context, hash string) (configstore.AdminToken, bool, error)
CreateAdminToken(ctx context.Context, t configstore.AdminToken) (configstore.AdminToken, error)
DeleteAdminToken(ctx context.Context, username, id string) error
TouchAdminToken(ctx context.Context, id string, at time.Time) error
PendingStates(ctx context.Context) ([]configstore.PendingState, error)
PendingLog(ctx context.Context, key string) ([]configstore.PendingState, error)
PutPendingState(ctx context.Context, p configstore.PendingState) (configstore.PendingState, error)
workspace.Store
}
PlanStore keeps plan templates, the administrators' tokens for the configuration MCP endpoint and the state of pending work, outside configuration revisions.
type PlanTemplate ¶
type PlanTemplate struct {
Name string `json:"name"`
Plan any `json:"plan"`
// Its new matches are pending after each scan.
Recurring bool `json:"recurring"`
// Bumped by every save.
Version int `json:"version"`
// Who saved this version.
Author string `json:"author"`
UpdatedAt time.Time `json:"updatedAt"`
}
type PlanTemplateInput ¶
type PlanTemplateInput struct {
// 1 to 64 characters.
Name string `json:"name"`
Plan any `json:"plan"`
// Report its new matches as pending.
Recurring bool `json:"recurring"`
// The version edited; null creates a template, failing when the name is
// taken. Another administrator's save meanwhile fails with CONFLICT.
ExpectedVersion *int `json:"expectedVersion,omitempty"`
}
type Preview ¶
type Preview struct {
// PlanID identifies the plan with what it was evaluated against.
PlanID string
Plan configplan.Plan
Review bool
Proposal configplan.Proposal
// Base is the configuration the plan applies to.
Base *config.Config
Report *PlanReport
Validation *Validation
// contains filtered or unexported fields
}
Preview is a plan evaluated against a configuration.
type RelationshipItem ¶
type RelationshipItem struct {
Name string `json:"name"`
Target string `json:"target"`
Cardinality string `json:"cardinality"`
JoinOn any `json:"joinOn"`
}
RelationshipItem is a relationship of an entity.
type RoleItem ¶
type RoleItem struct {
Name string `json:"name"`
Description *string `json:"description,omitempty"`
Grants []GrantItem `json:"grants" merge:"key=entity"`
}
RoleItem is a role.
type ScanBatch ¶
type ScanBatch struct {
ID string `json:"id"`
Datasource string `json:"datasource"`
// running, done or canceled.
State string `json:"state"`
Total int `json:"total"`
Done int `json:"done"`
Failed int `json:"failed"`
Canceled int `json:"canceled"`
// Schemas waiting or scanning.
Pending int `json:"pending"`
Items []ScanBatchItem `json:"items"`
StartedBy string `json:"startedBy"`
StartedAt time.Time `json:"startedAt"`
FinishedAt *time.Time `json:"finishedAt,omitempty"`
}
type ScanBatchInput ¶
type ScanBatchItem ¶
type Scans ¶
type Scans struct {
// contains filtered or unexported fields
}
Scans runs schema scans on a bounded pool of workers and keeps what each scan found, per schema, in a catalog store until the next scan of that schema: coming back to the console, restarting or reaching another replica does not scan again. Decoded schemas are cached per process and read again when the store holds a newer scan.
func NewScans ¶
NewScans returns scans that run on opts.Bus (see scanjobs.Options), keeping them in store (in memory when nil); Close stops them.
type SchemaInfo ¶
type SchemaList ¶
type SchemaList struct {
Datasource string `json:"datasource"`
// Every user schema; when the database cannot list them, one named "" for its
// default schema, which a scan without schemas reads.
Schemas []SchemaInfo `json:"schemas"`
// Where unqualified names resolve; null when unknown.
DefaultSchema *string `json:"defaultSchema,omitempty"`
ListedAt time.Time `json:"listedAt"`
// Identifies the database the datasource reads (its driver and read
// connection); results of another source are stale.
Source string `json:"source"`
}
type ScopeCondition ¶
type ScopeStats ¶
type ScopeStats struct {
Total int `json:"total"`
// The first matching tables.
Samples []CatalogRow `json:"samples"`
// Every condition of the scope with how many tables it selects alone.
Conditions []ScopeCondition `json:"conditions"`
}
type Sections ¶
type Sections struct {
Entities []EntityItem `json:"entities"`
Roles []RoleItem `json:"roles"`
Users []UserItem `json:"users"`
Settings map[string]any `json:"settings"`
}
Sections are a configuration as a workspace holds it, item by item: each entity, role and user, and the settings (every other top-level section). Their JSON is what the workspace stores and the console edits; the admin API's input types (EntityInput, RoleInput, UserInput) have the same shape. A nil list or settings is a section left out (an edit keeps the base's).
func SectionsOf ¶
SectionsOf are the sections of what a configuration says: an unset value is not in its item (lists are written empty).
func SectionsOfConfig ¶
SectionsOfConfig are the sections of a configuration built in code (a plan's outcome), as SectionsOf has them: a zero value is unset.
func SectionsOfPayload ¶
SectionsOfPayload are the sections of a stored payload.
func (Sections) Edit ¶
func (s Sections) Edit() (configedit.Edit, error)
Edit is s as an edit of a base configuration, saying what the items say: the sections s holds replace the base's, empty text and lists, and switches off unless set, are left unset (they mean the same), and a user's token is the one its item holds (none without a hash).
type Service ¶
type Service struct {
Store revision.Store
Introspect Introspection
// Scans runs schema scans in the background and keeps their results;
// nil refuses them.
Scans *Scans
// Plans keeps plan templates, MCP tokens and pending states; nil refuses
// them.
Plans PlanStore
// Capabilities reports the serving snapshot's capabilities; nil reports
// none.
Capabilities func() bootstrap.EntityCapabilities
// contains filtered or unexported fields
}
Service is the configuration service. It holds no per-request state.
func (*Service) ApplyPlan ¶
func (r *Service) ApplyPlan(ctx context.Context, in ApplyRequest) (*AppliedPlan, error)
ApplyPlan writes a previewed plan (see applicable) into the caller's workspace: the items it changes, as the console writes them, with a note of the agent (if one applies it) and its comment. The console's "add to the workspace" and an agent's plan_apply both come here. A plan that changes nothing, does not validate or has blocking exceptions fails.
func (*Service) BuildDraft ¶
BuildDraft applies d to its base revision through configedit, the same chain as `store import`: decode, defaults, validation, store secret rule and the deterministic encoding.
func (*Service) CancelScanBatch ¶
CancelScanBatch asks the owner of a batch to stop; this process stops at once a batch it runs.
func (*Service) Catalog ¶
func (r *Service) Catalog( ctx context.Context, f CatalogFilter, against Against, offset, limit int, ) (*CatalogPage, error)
Catalog pages through the scanned tables matching f, against the configuration against is.
func (*Service) CatalogLinks ¶
func (r *Service) CatalogLinks(ctx context.Context, ref string, against Against) (*CatalogLinks, error)
CatalogLinks lists the foreign keys of a table and those referencing it, among the scanned tables of its datasource, with the entities reading the other tables.
func (*Service) CatalogRefs ¶
func (r *Service) CatalogRefs(ctx context.Context, f CatalogFilter, against Against) ([]string, error)
CatalogRefs lists the refs of every table matching f.
func (*Service) CatalogTable ¶
func (r *Service) CatalogTable(ctx context.Context, ref string, against Against) (*configplan.Candidate, error)
CatalogTable is one scanned table in full, with the entity proposed for it; nil when no scanned table has the ref.
func (*Service) CheckpointWorkspace ¶
func (r *Service) CheckpointWorkspace(ctx context.Context, comment *string) (revision.Revision, error)
CheckpointWorkspace saves the caller's workspace as a draft to share.
func (*Service) CommitWorkspace ¶
CommitWorkspace publishes the caller's workspace at the version reviewed.
func (*Service) CreateMcpToken ¶
func (r *Service) CreateMcpToken(ctx context.Context, in McpTokenInput) (*McpTokenSecret, error)
CreateMcpToken creates a token of the caller for one client; the token is returned once.
func (*Service) DeletePlanTemplate ¶
DeletePlanTemplate deletes a template with its versions.
func (*Service) Diff ¶
Diff is the unified diff, secrets redacted, from a revision to the configuration to is.
func (*Service) DiscardDraft ¶
DiscardDraft discards a draft, saved by anyone, an agent included: it stays in the history and is never published.
func (*Service) Drafts ¶
func (r *Service) Drafts(ctx context.Context) ([]PendingDraft, error)
Drafts lists every draft, newest first, with what each builds on, worked out over the whole history.
func (*Service) EditWorkspace ¶
EditWorkspace writes items of the caller's workspace (see workspaceops.WriteItems: an item written meanwhile merges).
func (*Service) FieldReferences ¶
FieldReferences are the places the caller's workspace names the fields of the entity with ID entity, by field: roles and users first, a grant's row filter before its field lists.
func (*Service) MergeDraft ¶
MergeDraft takes draft id into the caller's workspace.
func (*Service) Ops ¶
func (r *Service) Ops() revisionops.Service
Ops returns the revision operations shared with the `store` CLI.
func (*Service) Pending ¶
Pending evaluates every recurring template, reporting each that would change the configuration or has rules it cannot apply, lists the tables whose fields differ, and counts the tables not imported and the schemas never scanned. A principal limited to some datasources sees what is about them only: their tables and the templates whose scope names only them.
func (*Service) PendingLog ¶
PendingLog lists what was set of a pending item, newest first.
func (*Service) PlanScope ¶
func (r *Service) PlanScope(ctx context.Context, scope configplan.Scope, against Against) (*ScopeStats, error)
PlanScope counts what a scope selects, and each of its conditions alone.
func (*Service) PlanTemplateVersions ¶
PlanTemplateVersions lists the versions of a template, newest first.
func (*Service) PlanTemplates ¶
func (r *Service) PlanTemplates(ctx context.Context) ([]PlanTemplate, error)
PlanTemplates lists the plan templates; a principal limited to some datasources sees those whose scope names only them.
func (*Service) PreviewInWorkspace ¶
func (r *Service) PreviewInWorkspace(ctx context.Context, p configplan.Plan, review bool) (*Preview, error)
PreviewInWorkspace previews a plan against the caller's workspace, as an agent working for them does.
func (*Service) PreviewPlan ¶
func (r *Service) PreviewPlan(ctx context.Context, p configplan.Plan, against Against, review bool) (*Preview, error)
PreviewPlan evaluates a plan against the configuration against is, as a review of a recurring template's proposal when review is set, and keeps the result for its maker.
func (*Service) ResetWorkspace ¶
ResetWorkspace makes the caller's workspace revision to as it is.
func (*Service) ResolveConflict ¶
ResolveConflict resolves a conflict of the caller's workspace.
func (*Service) RestartChanges ¶
RestartChanges compares a configuration with the published one.
func (*Service) RetryScanBatch ¶
RetryScanBatch scans again, as a new batch, what failed or was canceled in a batch.
func (*Service) RevokeMcpToken ¶
RevokeMcpToken revokes one of the caller's tokens.
func (*Service) SavePlanTemplate ¶
func (r *Service) SavePlanTemplate(ctx context.Context, in PlanTemplateInput) (*PlanTemplate, error)
SavePlanTemplate creates a template, or saves a new version of one while it is still at in.ExpectedVersion.
func (*Service) ScanBatches ¶
ScanBatches lists the recent batches of datasource, running ones first.
func (*Service) SchemaList ¶
func (r *Service) SchemaList(ctx context.Context, datasource string, refresh bool) (*SchemaList, error)
SchemaList lists the schemas of datasource with what was scanned of each; the list is read from the database once, and again on refresh.
func (*Service) SchemaScan ¶
SchemaScan reads a scan, or cancels it.
func (*Service) SchemaTables ¶
func (r *Service) SchemaTables(ctx context.Context, datasource string, schemas []string) (*Imports, error)
SchemaTables returns the tables of the kept ones of schemas (nil: all).
func (*Service) SelectConfig ¶
SelectConfig is the configuration against is.
func (*Service) SetPendingState ¶
func (r *Service) SetPendingState(ctx context.Context, in PendingStateInput) (*PendingState, error)
SetPendingState records who handles a pending item and how.
func (*Service) Simulate ¶
func (r *Service) Simulate(ctx context.Context, in SimulateRequest) (*Simulation, error)
Simulate evaluates one authorization offline.
func (*Service) StartScanBatch ¶
StartScanBatch scans schemas of a datasource on the server, a few at a time; the same request sent again (by its key) gets the batch it started.
func (*Service) StartSchemaScan ¶
func (r *Service) StartSchemaScan(ctx context.Context, datasource string, schemas []string) (*ScanJob, error)
StartSchemaScan queues a scan of schemas of datasource (none: every schema it lists, or its default one) and keeps what it finds.
func (*Service) UpdateWorkspace ¶
UpdateWorkspace moves the caller's workspace onto revision to.
func (*Service) Validate ¶
Validate builds a draft and reports whether it validates, what of it needs a restart and what the serving connections cannot do.
func (*Service) WatchScanBatches ¶
func (r *Service) WatchScanBatches()
WatchScanBatches takes over the scan batches of processes that stopped.
func (*Service) WorkspaceLog ¶
WorkspaceLog is the caller's workspace log, newest first.
type SimulateRequest ¶
type SimulateRequest struct {
// Against selects the configuration.
Against Against
// User is a configured user name, or role:<name>.
User, Entity, Action string
Fields []string
Subject map[string]any
}
SimulateRequest is one authorization to evaluate.
type Simulation ¶
type Simulation struct {
Allowed bool `json:"allowed"`
Reason string `json:"reason"`
Fields []string `json:"fields"`
// Effective row filter in rowPolicies JSON form; null means every row.
RowFilter any `json:"rowFilter,omitempty"`
Grants []string `json:"grants"`
// Set when no single grant covers the requested fields.
FieldScopes [][]string `json:"fieldScopes,omitempty"`
}
Simulation is one authorization evaluated offline.
type Simulator ¶
type Simulator struct {
// contains filtered or unexported fields
}
Simulator evaluates the authorizations of one user or role of a configuration, without touching any database.
func NewSimulator ¶
NewSimulator evaluates who, a configured user name or "role:<name>", in cfg; subject supplies attributes the user does not set.
type TableLink ¶
type TableLink struct {
// The other table.
Ref string `json:"ref"`
Name string `json:"name"`
// Columns of the referencing table, and the referenced ones.
Columns []string `json:"columns"`
RefColumns []string `json:"refColumns"`
// The entity reading the other table, if any.
Entity *string `json:"entity,omitempty"`
}
A foreign key between two scanned tables.
type UnscannedSchemas ¶
type UserItem ¶
type UserItem struct {
Name string `json:"name"`
Description *string `json:"description,omitempty"`
Roles []string `json:"roles"`
Grants []GrantItem `json:"grants" merge:"key=entity"`
Subject any `json:"subject,omitempty"`
Disabled *bool `json:"disabled,omitempty" merge:"unset"`
TokenHash *string `json:"tokenHash,omitempty"`
}
UserItem is a user, its token included: one without a token hash has none.
type Validation ¶
type Validation struct {
Ok bool `json:"ok"`
Error *string `json:"error,omitempty"`
ContentHash *string `json:"contentHash,omitempty"`
// Changes against the published revision that need a restart.
RestartRequired []string `json:"restartRequired"`
// Grants the routed datasource connections cannot run (they do not block publishing).
Warnings []string `json:"warnings"`
}
type Workspace ¶
type Workspace struct {
// The revision it builds on.
Base string `json:"base"`
Version int `json:"version"`
// The console's sections (entities, roles, users, settings).
Sections any `json:"sections"`
Conflicts []WorkspaceConflict `json:"conflicts"`
// Where changes came from: plans agents applied, drafts taken in.
Notes []WorkspaceNote `json:"notes"`
// Drafts taken in or saved from it (not to offer it for review), and the
// draft it holds as it is (saved from it, nothing changed since).
Taken []string `json:"taken"`
Checkpoint *string `json:"checkpoint,omitempty"`
UpdatedAt *time.Time `json:"updatedAt,omitempty"`
// The administrator, or agent:<token name>.
UpdatedBy string `json:"updatedBy"`
}
Workspace is an administrator's workspace as it stands: the one copy of their unpublished work, written by them (in any console) and their agents.
type WorkspaceConflict ¶
type WorkspaceConflict struct {
ID string `json:"id"`
Kind string `json:"kind"`
Key string `json:"key"`
// Where in the item, e.g. fields[email].mask; empty: the whole item.
Path string `json:"path"`
// The values (null when removed: MineGone, TheirsGone).
Mine any `json:"mine,omitempty"`
MineGone bool `json:"mineGone"`
Theirs any `json:"theirs,omitempty"`
TheirsGone bool `json:"theirsGone"`
// published (a newer revision), draft (one taken in) or workspace (a
// write made meanwhile, by another console or an agent).
Source string `json:"source"`
FromID *string `json:"fromId,omitempty"`
FromBy *string `json:"fromBy,omitempty"`
}
WorkspaceConflict is a value the workspace and another side changed differently; the workspace keeps its value until resolved.
type WorkspaceEditInput ¶
type WorkspaceEditInput struct {
Items []WorkspaceItemInput `json:"items"`
}
WorkspaceEditInput writes items of the workspace.
type WorkspaceItemInput ¶
type WorkspaceItemInput struct {
Kind string `json:"kind"`
Key string `json:"key"`
Value any `json:"value,omitempty"`
Previous any `json:"previous,omitempty"`
RenamedFrom *string `json:"renamedFrom,omitempty"`
}
WorkspaceItemInput writes one item: its value (null removes it) and the value its writer read (null: absent). An item written meanwhile merges. RenamedFrom is the key of the item of the same kind (an entity or a role) it was renamed or moved from, which it replaces; references follow it.
type WorkspaceLogEntry ¶
type WorkspaceLogEntry struct {
Version int `json:"version"`
At time.Time `json:"at"`
By string `json:"by"`
// edit, apply, update, reset, merge, resolve, checkpoint or commit.
Op string `json:"op"`
Items []WorkspaceRef `json:"items"`
Note *string `json:"note,omitempty"`
}
WorkspaceLogEntry is a write of a workspace.
type WorkspaceNote ¶
type WorkspaceNote struct {
// agent or draft.
Source string `json:"source"`
By string `json:"by"`
Text string `json:"text"`
}
WorkspaceNote says where changes came from.
type WorkspaceRef ¶
WorkspaceRef names an item: entity (by ID), role or user (by name), or settings.