configmgr

package
v1.8.2 Latest Latest
Warning

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

Go to latest
Published: Nov 11, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package configmgr is the write service for runtime config entries and their per-tenant overrides.

It lives apart from package config because package override imports config: a manager that touches both stores cannot sit in either. configmgr imports both and neither imports it.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CreateInput

type CreateInput struct {
	Key         string
	ValueType   string
	Description string
	Value       any
}

CreateInput is everything a new entry carries. Value must be valid for ValueType, which is required.

type Manager

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

Manager is the config write service. Every backend's SetConfig is an upsert that never checks anything and versions on every call, and no backend deletes a key's overrides with the key, so the store on its own will overwrite an existing entry, store "abc" as an int, erase a description on update, and bring a deleted key's overrides back to life when the key is recreated. Manager is the one path that refuses those writes, keeps every field a request did not name, drops the resolver cache and runs the watchers after each change, and reports it to an audit hook.

It is safe for concurrent use as far as its stores are. Update and Rollback are read-modify-write of one row with no version check, so two concurrent writers to the same key can lose one write. A SetOverride that races a Delete of its key can leave an orphan override behind until the key is recreated, when Create clears it.

func NewManager

func NewManager(store config.Store, overrides override.Store, resolver *override.Resolver, svc *config.Service, opts ...ManagerOption) *Manager

NewManager builds a config write service. resolver may be nil, in which case no resolver cache is invalidated; svc may be nil, in which case no watchers run.

func (*Manager) Create

func (m *Manager) Create(ctx context.Context, in CreateInput) (*config.Entry, error)

Create defines a new entry. It refuses an invalid key, type or value, and returns core.ErrConfigExists (vault.ErrConfigExists) when the key is taken, rather than overwriting the entry the way the store's upsert would.

func (*Manager) Delete

func (m *Manager) Delete(ctx context.Context, key string) error

Delete removes an entry together with its versions and every override for the key. Overrides go first and the entry last: a failure part way leaves the entry, so a retry finds it and finishes the job.

func (*Manager) DeleteOverride

func (m *Manager) DeleteOverride(ctx context.Context, key, tenantID string) error

DeleteOverride removes a tenant's override. It does not read the entry: an override whose entry is gone still resolves for its tenant (the resolver answers from the override before it reads the entry), so it has to be removable. A tenant with no override returns core.ErrOverrideNotFound from the store, whether or not the key exists.

func (*Manager) Rollback

func (m *Manager) Rollback(ctx context.Context, key string, version int64) (*config.Entry, error)

Rollback restores the value an entry held at version. The entry keeps its current type, description and metadata, because a version row keeps only the value. A version whose value does not fit the current type is refused, and rolling back to the value the entry already holds writes nothing. The result is a new version, not a rewrite of history.

func (*Manager) SetOverride

func (m *Manager) SetOverride(ctx context.Context, key, tenantID string, value any) (*override.Override, error)

SetOverride pins an entry's value for one tenant. The entry must exist and the value must be valid for its type: a mistyped override makes that tenant silently read the caller's fallback instead of the app value. An existing override for the tenant keeps its id, creation time and metadata.

func (*Manager) SetOverrideWithEntry

func (m *Manager) SetOverrideWithEntry(ctx context.Context, key, tenantID string, value any) (*override.Override, *config.Entry, error)

SetOverrideWithEntry is SetOverride that also returns the entry the value was judged against, so a caller that projects the override next to its entry need not read the entry again and risk a concurrent delete turning a stored override into an error.

func (*Manager) Update

func (m *Manager) Update(ctx context.Context, key string, in UpdateInput) (*config.Entry, error)

Update changes the value, type or description of an existing entry. Only non-nil fields change; the rest of the row (id, metadata, creation time) is carried over. A new value is validated against the entry's type, or against the new type when the type changes, which needs a value, and every tenant override must be a valid value of the new type too, or the change is refused naming the first tenant (in tenant order) whose is not. An entry whose stored type is not one the manager supports is read-only for its value. Asking for what the entry already holds writes, audits and notifies nothing.

type ManagerOption

type ManagerOption func(*Manager)

ManagerOption configures a Manager.

func WithManagerAppID

func WithManagerAppID(appID string) ManagerOption

WithManagerAppID sets the app every entry and override the manager touches belongs to.

func WithOnConfigMutate

func WithOnConfigMutate(fn func(ctx context.Context, action, resource, key, appID, tenantID string)) ManagerOption

WithOnConfigMutate registers a callback invoked after each successful write, with the context the write ran under, one of the config.* or override.* audit actions, the resource it concerns (config or override), the config key, the app, and the tenant an override write targets (empty for a write to the entry itself).

type UpdateInput

type UpdateInput struct {
	Value       *any
	ValueType   *string
	Description *string
}

UpdateInput changes only the fields that are non-nil. Value is a pointer to an any so that a json entry can be set to null: a nil Value pointer means "leave the value", a pointer to nil means null.

Jump to

Keyboard shortcuts

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