Documentation
¶
Overview ¶
Package configplan turns a plan, a scope of scanned tables and rules to apply to them, into a proposal: the configuration changes and a report of what they cover, what changes, the exceptions to look at, and when the changes take effect. It is deterministic and reads no database: the console, saved templates and the configuration MCP endpoint all evaluate plans here, against the scanned catalog and a base configuration.
Index ¶
- Constants
- func ConfiguredTables(datasource string, cat introspect.Catalog, cfg *config.Config) map[string]config.EntityConfig
- func IdentityUniqueKeys(d entity.Entity) [][]string
- func Ref(datasource, schema, table string) string
- func TableKey(schema, table string) string
- func Unscanned(sources []Source, scope Scope) map[string][]string
- type Candidate
- type Change
- type Exception
- type FieldRule
- type GrantRule
- type Index
- type Input
- type Objects
- type Plan
- type Proposal
- type Report
- type Row
- type Scope
- type Source
- type Status
- type SyncRule
Constants ¶
const ( ChangeImport = "import" ChangeCreateRole = "createRole" ChangeGrant = "grant" ChangeExclude = "exclude" ChangeMask = "mask" ChangeSyncAdd = "syncAdd" ChangeSyncRemove = "syncRemove" )
Change kinds.
const ( // ExceptionRenamed: the entity name differs from the table, which another // entity of the schema uses. ExceptionRenamed = "renamed" // ExceptionNoKey: no key identifies a row; updates and deletes are not // granted. ExceptionNoKey = "noKey" // ExceptionSideEffects: triggers or rules may write other tables. ExceptionSideEffects = "sideEffects" // ExceptionRelationshipDropped: a foreign key references a table that has // no entity. ExceptionRelationshipDropped = "relationshipDropped" // ExceptionQualified: an existing reference would name several entities // once the plan adds its own; it is rewritten to the ID of the one it // named. ExceptionQualified = "qualified" // ExceptionUnknownUser: a grant names a user that does not exist. ExceptionUnknownUser = "unknownUser" // ExceptionNoFields: a grant's field patterns match no field. ExceptionNoFields = "noFields" // ExceptionReferenced: a field to remove is still referenced. ExceptionReferenced = "referenced" // ExceptionDenied: the connection lacks the privilege for an action. ExceptionDenied = "denied" // ExceptionReview: a new table enters an existing grant. ExceptionReview = "review" )
Exception kinds.
const ( // LevelBlock exceptions keep the proposal from being taken. No rule of // the engine raises one today; an outcome that does not validate blocks // the same way. LevelBlock = "block" // LevelConfirm exceptions change what is granted or fail to apply: taking // the proposal needs them acknowledged. LevelConfirm = "confirm" // LevelInfo exceptions only inform. LevelInfo = "info" )
Exception levels: what a reviewer has to do about an exception.
Variables ¶
This section is empty.
Functions ¶
func ConfiguredTables ¶
func ConfiguredTables(datasource string, cat introspect.Catalog, cfg *config.Config) map[string]config.EntityConfig
ConfiguredTables maps each catalog table (by TableKey) to the configured entity of datasource that reads it, resolved by the catalog like the runtime does.
func IdentityUniqueKeys ¶
IdentityUniqueKeys lists the unique keys of d that identify a row.
func Ref ¶
Ref names a table: datasource.schema.table, or datasource.table in a datasource without schemas, like an entity ID.
Types ¶
type Candidate ¶
type Candidate struct {
Table entity.Entity
// Configured is the entity of the configuration that reads the table.
Configured *config.EntityConfig
// Entity is an entity proposed for the table, named like the
// configured one if any.
Entity config.EntityConfig
// ID identifies the entity: the configured one's when configured.
ID string
}
Candidate is a scanned table with the entity that reads it, if any, and a zero-permission entity proposed for it.
func Candidates ¶
func Candidates( datasource string, cat introspect.Catalog, cfg *config.Config, names map[string]string, only map[string]bool, ) []Candidate
Candidates proposes an entity for the tables of cat (those of only, by TableKey, when only is not nil), sorted by schema and table: names follow the tables, numbered when another entity of the datasource and schema uses one; names (by TableKey) are preferred where given. Names are worked out over every table, so a candidate is named the same whichever are asked for. Foreign keys become relationships between candidates and to configured entities, in both directions.
type Change ¶
type Change struct {
Kind string
Principal string
Actions []string
Mask string
// Fields counts the fields a field change touches.
Fields int
Entities []string
}
Change summarizes one kind of change over the entities it applies to.
type Exception ¶
type Exception struct {
Kind string
// Level is block, confirm or info (see levelOf).
Level string
// Warning marks exceptions that are not only informative.
Warning bool
// Ref is the table, when excluding it is a way out.
Ref string
Entity string
// Detail names what the exception is about: a name, an action, a field.
Detail string
}
Exception is something a reviewer should look at.
type FieldRule ¶
type FieldRule struct {
// Columns are glob patterns on column names.
Columns []string `json:"columns"`
// Types are glob patterns on column types; empty: any type.
Types []string `json:"types,omitempty"`
Exclude bool `json:"exclude,omitempty"`
Mask string `json:"mask,omitempty"`
}
FieldRule hides or masks the fields of matching columns.
type GrantRule ¶
type GrantRule struct {
// Principal is role:<name> or user:<name>; a role is created if needed.
Principal string `json:"principal"`
Actions []string `json:"actions"`
// Fields are glob patterns of the fields granted; empty: every field.
Fields []string `json:"fields,omitempty"`
// Rows filters the rows granted, as in a grant.
Rows config.FilterConfig `json:"rows,omitempty"`
}
GrantRule grants actions to a role or a user.
type Index ¶
type Index struct {
// contains filtered or unexported fields
}
Index is every scanned table with where it stands, worked out once for a set of scans and a configuration: many scopes (catalog pages, counts of conditions, several administrators) filter it instead of each resolving the configured entities of every table again.
func (*Index) Match ¶
Match lists the positions of the rows in scope, in order: a few bytes a row, to keep for paging through them with At.
func (*Index) Referenced ¶
Referenced counts the foreign keys of scanned tables referencing a table.
type Input ¶
type Input struct {
// Base is the configuration the plan changes: the console's workspace,
// or the published configuration.
Base *config.Config
// Published tells published tables from those only in Base; nil: none.
Published *config.Config
Sources []Source
// Denied reports an entity action the serving connections cannot run,
// with why; nil reports none.
Denied func(entity, action string) (reason string, denied bool)
// Review reports every new table a grant covers, as a recurring
// template's proposal needs.
Review bool
}
Input is what a plan is evaluated against.
type Plan ¶
type Plan struct {
Scope Scope `json:"scope"`
// Import adds an entity for each table in scope no entity reads.
Import bool `json:"import,omitempty"`
// Grants grant actions on the entities of the tables in scope.
Grants []GrantRule `json:"grants,omitempty"`
// Fields hide or mask the fields of those entities by column.
Fields []FieldRule `json:"fields,omitempty"`
// Sync brings their fields in line with the scanned columns.
Sync *SyncRule `json:"sync,omitempty"`
// Exclude leaves tables out of the plan, by Ref.
Exclude []string `json:"exclude,omitempty"`
// Names names the entities imported for tables, by Ref.
Names map[string]string `json:"names,omitempty"`
}
Plan selects tables and says what to do with them. Its JSON form is what templates store and the MCP tools take.
type Proposal ¶
type Proposal struct {
// Config is Base with the changes applied.
Config *config.Config
// Entities are the entities added or changed, in configuration order.
Entities []config.EntityConfig
// Added are the IDs of the entities added.
Added []string
// Roles and Users are the principals added or changed.
Roles map[string]config.RoleDefinition
Users map[string]config.UserConfig
Report Report
}
Proposal is the outcome of a plan.
func Evaluate ¶
Evaluate applies p to in.Base. It does not validate the result: the caller runs it through the configuration chain.
func (Proposal) Edit ¶
func (p Proposal) Edit() configedit.Edit
Edit is the proposal as an edit of the configuration it was evaluated against: the sections it changes, whole, as what they say (config.SpecOf: a default is left unset, as before it applied).
type Report ¶
type Report struct {
// Matched counts the tables in scope; Excluded those left out of them.
Matched int
Excluded int
Objects []Objects
Changes []Change
// Exceptions need a look: they may be excluded or changed.
Exceptions []Exception
// Unscanned are the schemas in scope never scanned, by datasource.
Unscanned map[string][]string
// ScannedFrom and ScannedTo bound when the tables in scope were scanned;
// zero when unknown.
ScannedFrom, ScannedTo time.Time
}
Report is what a reviewer reads before taking a proposal.
type Row ¶
type Row struct {
Ref string
Datasource string
Table entity.Entity
Status Status
// Entity is the entity of the base configuration that reads the table.
Entity *config.EntityConfig
// Added are columns without a field, Missing fields without a column.
Added, Missing []string
// ScannedAt is when the table's schema was scanned; zero when unknown.
ScannedAt time.Time
}
Row is a scanned table with where it stands against the configuration.
type Scope ¶
type Scope struct {
// Datasources limits the scope to these datasources; empty: all.
Datasources []string `json:"datasources,omitempty"`
// Schemas are glob patterns (* and ?) on schema names; empty: all.
Schemas []string `json:"schemas,omitempty"`
// Tables are glob patterns on table names; empty: all.
Tables []string `json:"tables,omitempty"`
// Search matches a part of the table name or its comment.
Search string `json:"search,omitempty"`
// Status limits the scope to tables in these states; empty: all.
Status []Status `json:"status,omitempty"`
// Drift limits the scope to configured tables whose columns and fields
// differ.
Drift bool `json:"drift,omitempty"`
// Refs limits the scope to these tables.
Refs []string `json:"refs,omitempty"`
}
Scope selects scanned tables; every condition set must hold.
type Source ¶
type Source struct {
Datasource string
// Catalog holds every scanned schema of the datasource.
Catalog introspect.Catalog
// Listed are the schemas the datasource lists; nil when unknown.
Listed []string
// Scanned are the schemas scanned.
Scanned []string
// ScannedAt is when each scanned schema was scanned.
ScannedAt map[string]time.Time
}
Source is what was scanned of one datasource.