Documentation
¶
Index ¶
- Constants
- Variables
- func SourceProtoToString(s pbflagsv1.OverrideSource) string
- type AdminService
- func (a *AdminService) AcquireSyncLock(ctx context.Context, req *connect.Request[pbflagsv1.AcquireSyncLockRequest]) (*connect.Response[pbflagsv1.AcquireSyncLockResponse], error)
- func (a *AdminService) ClearAllConditionOverrides(ctx context.Context, ...) (*connect.Response[pbflagsv1.ClearAllConditionOverridesResponse], error)
- func (a *AdminService) ClearConditionOverride(ctx context.Context, ...) (*connect.Response[pbflagsv1.ClearConditionOverrideResponse], error)
- func (a *AdminService) GetAuditLog(ctx context.Context, req *connect.Request[pbflagsv1.GetAuditLogRequest]) (*connect.Response[pbflagsv1.GetAuditLogResponse], error)
- func (a *AdminService) GetFlag(ctx context.Context, req *connect.Request[pbflagsv1.GetFlagRequest]) (*connect.Response[pbflagsv1.GetFlagResponse], error)
- func (a *AdminService) GetLaunch(ctx context.Context, req *connect.Request[pbflagsv1.GetLaunchRequest]) (*connect.Response[pbflagsv1.GetLaunchResponse], error)
- func (a *AdminService) GetSyncLock(ctx context.Context, _ *connect.Request[pbflagsv1.GetSyncLockRequest]) (*connect.Response[pbflagsv1.GetSyncLockResponse], error)
- func (a *AdminService) KillLaunch(ctx context.Context, req *connect.Request[pbflagsv1.KillLaunchRequest]) (*connect.Response[pbflagsv1.KillLaunchResponse], error)
- func (a *AdminService) ListConditionOverrides(ctx context.Context, ...) (*connect.Response[pbflagsv1.ListConditionOverridesResponse], error)
- func (a *AdminService) ListFeatures(ctx context.Context, _ *connect.Request[pbflagsv1.ListFeaturesRequest]) (*connect.Response[pbflagsv1.ListFeaturesResponse], error)
- func (a *AdminService) ListLaunches(ctx context.Context, req *connect.Request[pbflagsv1.ListLaunchesRequest]) (*connect.Response[pbflagsv1.ListLaunchesResponse], error)
- func (a *AdminService) ReleaseSyncLock(ctx context.Context, req *connect.Request[pbflagsv1.ReleaseSyncLockRequest]) (*connect.Response[pbflagsv1.ReleaseSyncLockResponse], error)
- func (a *AdminService) RemoveFlagOverride(_ context.Context, _ *connect.Request[pbflagsv1.RemoveFlagOverrideRequest]) (*connect.Response[pbflagsv1.RemoveFlagOverrideResponse], error)
- func (a *AdminService) SetConditionOverride(ctx context.Context, ...) (*connect.Response[pbflagsv1.SetConditionOverrideResponse], error)
- func (a *AdminService) SetFlagOverride(_ context.Context, _ *connect.Request[pbflagsv1.SetFlagOverrideRequest]) (*connect.Response[pbflagsv1.SetFlagOverrideResponse], error)
- func (a *AdminService) UnkillLaunch(ctx context.Context, req *connect.Request[pbflagsv1.UnkillLaunchRequest]) (*connect.Response[pbflagsv1.UnkillLaunchResponse], error)
- func (a *AdminService) UpdateFlagState(ctx context.Context, req *connect.Request[pbflagsv1.UpdateFlagStateRequest]) (*connect.Response[pbflagsv1.UpdateFlagStateResponse], error)
- func (a *AdminService) UpdateLaunchRamp(ctx context.Context, req *connect.Request[pbflagsv1.UpdateLaunchRampRequest]) (*connect.Response[pbflagsv1.UpdateLaunchRampResponse], error)
- func (a *AdminService) UpdateLaunchStatus(ctx context.Context, req *connect.Request[pbflagsv1.UpdateLaunchStatusRequest]) (*connect.Response[pbflagsv1.UpdateLaunchStatusResponse], error)
- type AdminServiceOption
- type AuditLogFilter
- type ConditionOverride
- type FlagCondition
- type FlagExtra
- type Launch
- type OverrideListFilter
- type Store
- func (s *Store) AcquireSyncLock(ctx context.Context, actor, reason string) (*SyncLockInfo, error)
- func (s *Store) ClearAllConditionOverrides(ctx context.Context, flagID, actor, reason string) (int, error)
- func (s *Store) ClearConditionOverride(ctx context.Context, flagID string, conditionIndex *int32, ...) error
- func (s *Store) ClearOverridesForFlagsTx(ctx context.Context, tx pgx.Tx, flagIDs []string, actor string) (int, error)
- func (s *Store) ConfigManagedFeatures(ctx context.Context) (map[string]bool, error)
- func (s *Store) FlagsByLaunch(ctx context.Context, launches []Launch) (map[string][]string, error)
- func (s *Store) GetAuditLog(ctx context.Context, filter AuditLogFilter) ([]*pbflagsv1.AuditLogEntry, error)
- func (s *Store) GetFlag(ctx context.Context, flagID string) (*pbflagsv1.FlagDetail, *FlagExtra, error)
- func (s *Store) GetFlagState(ctx context.Context, flagID string) (*pbflagsv1.GetFlagStateResponse, error)
- func (s *Store) GetKilledFlags(ctx context.Context) (*pbflagsv1.GetKilledFlagsResponse, error)
- func (s *Store) GetLaunch(ctx context.Context, launchID string) (*Launch, error)
- func (s *Store) GetSyncLock(ctx context.Context) (*SyncLockInfo, error)
- func (s *Store) IsConfigManaged(ctx context.Context, flagID string) (bool, error)
- func (s *Store) KillLaunch(ctx context.Context, launchID string, actor string) error
- func (s *Store) ListAllLaunches(ctx context.Context) ([]Launch, error)
- func (s *Store) ListAllOverrides(ctx context.Context, f OverrideListFilter) ([]ConditionOverride, error)
- func (s *Store) ListFeatures(ctx context.Context) ([]*pbflagsv1.FeatureDetail, map[string]int, error)
- func (s *Store) ListLaunches(ctx context.Context, featureID string) ([]Launch, error)
- func (s *Store) ListLaunchesAffecting(ctx context.Context, featureID string) ([]Launch, error)
- func (s *Store) ListOverridesForFlag(ctx context.Context, flagID string) ([]ConditionOverride, error)
- func (s *Store) ReleaseSyncLock(ctx context.Context, actor, unlockReason string) error
- func (s *Store) SetConditionOverride(ctx context.Context, flagID string, conditionIndex *int32, ...) (*pbflagsv1.FlagValue, error)
- func (s *Store) UnkillLaunch(ctx context.Context, launchID string, actor string) error
- func (s *Store) UpdateFlagState(ctx context.Context, flagID string, state pbflagsv1.State, actor string) error
- func (s *Store) UpdateLaunchRamp(ctx context.Context, launchID string, pct int, source, actor string) (prevSource string, err error)
- func (s *Store) UpdateLaunchStatus(ctx context.Context, launchID string, status string, actor string) error
- type SyncLockHeldError
- type SyncLockInfo
Constants ¶
const ( ActionAcquireSyncLock = "ACQUIRE_SYNC_LOCK" ActionReleaseSyncLock = "RELEASE_SYNC_LOCK" ActionSetConditionOverride = "SET_CONDITION_OVERRIDE" ActionClearConditionOverride = "CLEAR_CONDITION_OVERRIDE" ActionClearAllConditionOverrides = "CLEAR_ALL_CONDITION_OVERRIDES" ActionConditionOverrideAutoClear = "CONDITION_OVERRIDE_AUTO_CLEARED" )
Audit-log action constants for the lock + condition-override epic. Defined here (rather than as bare strings) so they're greppable and callers can't typo them.
Variables ¶
var ( ErrFlagNotFound = errors.New("flag not found") ErrOverrideNotFound = errors.New("override not found") ErrInvalidArgument = errors.New("invalid argument") )
Sentinel errors used by the override / sync-lock store layer. mapStoreErr in service.go uses errors.Is to translate these into the right Connect codes — replacing the prior brittle substring matcher.
var ErrSyncNotLocked = errors.New("sync is not locked")
ErrSyncNotLocked is returned when ReleaseSyncLock is called while the lock is not held.
Functions ¶
func SourceProtoToString ¶ added in v0.20.0
func SourceProtoToString(s pbflagsv1.OverrideSource) string
SourceProtoToString is the inverse: proto enum → DB column value. Unspecified defaults to "cli" (the most common entry point).
Types ¶
type AdminService ¶
type AdminService struct {
// contains filtered or unexported fields
}
AdminService implements the FlagAdminService Connect handler.
func NewAdminService ¶
func NewAdminService(store *Store, logger *slog.Logger, opts ...AdminServiceOption) *AdminService
NewAdminService creates a FlagAdminService handler.
func (*AdminService) AcquireSyncLock ¶ added in v0.20.0
func (a *AdminService) AcquireSyncLock(ctx context.Context, req *connect.Request[pbflagsv1.AcquireSyncLockRequest]) (*connect.Response[pbflagsv1.AcquireSyncLockResponse], error)
func (*AdminService) ClearAllConditionOverrides ¶ added in v0.20.0
func (a *AdminService) ClearAllConditionOverrides(ctx context.Context, req *connect.Request[pbflagsv1.ClearAllConditionOverridesRequest]) (*connect.Response[pbflagsv1.ClearAllConditionOverridesResponse], error)
func (*AdminService) ClearConditionOverride ¶ added in v0.20.0
func (a *AdminService) ClearConditionOverride(ctx context.Context, req *connect.Request[pbflagsv1.ClearConditionOverrideRequest]) (*connect.Response[pbflagsv1.ClearConditionOverrideResponse], error)
func (*AdminService) GetAuditLog ¶
func (a *AdminService) GetAuditLog(ctx context.Context, req *connect.Request[pbflagsv1.GetAuditLogRequest]) (*connect.Response[pbflagsv1.GetAuditLogResponse], error)
func (*AdminService) GetFlag ¶
func (a *AdminService) GetFlag(ctx context.Context, req *connect.Request[pbflagsv1.GetFlagRequest]) (*connect.Response[pbflagsv1.GetFlagResponse], error)
func (*AdminService) GetLaunch ¶ added in v0.18.0
func (a *AdminService) GetLaunch(ctx context.Context, req *connect.Request[pbflagsv1.GetLaunchRequest]) (*connect.Response[pbflagsv1.GetLaunchResponse], error)
func (*AdminService) GetSyncLock ¶ added in v0.20.0
func (a *AdminService) GetSyncLock(ctx context.Context, _ *connect.Request[pbflagsv1.GetSyncLockRequest]) (*connect.Response[pbflagsv1.GetSyncLockResponse], error)
GetSyncLock is gated by --allow-runtime-overrides for symmetry with Acquire/Release: if the feature isn't on, no part of the lock surface is addressable.
func (*AdminService) KillLaunch ¶ added in v0.18.0
func (a *AdminService) KillLaunch(ctx context.Context, req *connect.Request[pbflagsv1.KillLaunchRequest]) (*connect.Response[pbflagsv1.KillLaunchResponse], error)
func (*AdminService) ListConditionOverrides ¶ added in v0.20.0
func (a *AdminService) ListConditionOverrides(ctx context.Context, req *connect.Request[pbflagsv1.ListConditionOverridesRequest]) (*connect.Response[pbflagsv1.ListConditionOverridesResponse], error)
func (*AdminService) ListFeatures ¶
func (a *AdminService) ListFeatures(ctx context.Context, _ *connect.Request[pbflagsv1.ListFeaturesRequest]) (*connect.Response[pbflagsv1.ListFeaturesResponse], error)
func (*AdminService) ListLaunches ¶ added in v0.18.0
func (a *AdminService) ListLaunches(ctx context.Context, req *connect.Request[pbflagsv1.ListLaunchesRequest]) (*connect.Response[pbflagsv1.ListLaunchesResponse], error)
func (*AdminService) ReleaseSyncLock ¶ added in v0.20.0
func (a *AdminService) ReleaseSyncLock(ctx context.Context, req *connect.Request[pbflagsv1.ReleaseSyncLockRequest]) (*connect.Response[pbflagsv1.ReleaseSyncLockResponse], error)
func (*AdminService) RemoveFlagOverride ¶
func (a *AdminService) RemoveFlagOverride(_ context.Context, _ *connect.Request[pbflagsv1.RemoveFlagOverrideRequest]) (*connect.Response[pbflagsv1.RemoveFlagOverrideResponse], error)
func (*AdminService) SetConditionOverride ¶ added in v0.20.0
func (a *AdminService) SetConditionOverride(ctx context.Context, req *connect.Request[pbflagsv1.SetConditionOverrideRequest]) (*connect.Response[pbflagsv1.SetConditionOverrideResponse], error)
func (*AdminService) SetFlagOverride ¶
func (a *AdminService) SetFlagOverride(_ context.Context, _ *connect.Request[pbflagsv1.SetFlagOverrideRequest]) (*connect.Response[pbflagsv1.SetFlagOverrideResponse], error)
func (*AdminService) UnkillLaunch ¶ added in v0.18.0
func (a *AdminService) UnkillLaunch(ctx context.Context, req *connect.Request[pbflagsv1.UnkillLaunchRequest]) (*connect.Response[pbflagsv1.UnkillLaunchResponse], error)
func (*AdminService) UpdateFlagState ¶
func (a *AdminService) UpdateFlagState(ctx context.Context, req *connect.Request[pbflagsv1.UpdateFlagStateRequest]) (*connect.Response[pbflagsv1.UpdateFlagStateResponse], error)
func (*AdminService) UpdateLaunchRamp ¶ added in v0.18.0
func (a *AdminService) UpdateLaunchRamp(ctx context.Context, req *connect.Request[pbflagsv1.UpdateLaunchRampRequest]) (*connect.Response[pbflagsv1.UpdateLaunchRampResponse], error)
func (*AdminService) UpdateLaunchStatus ¶ added in v0.18.0
func (a *AdminService) UpdateLaunchStatus(ctx context.Context, req *connect.Request[pbflagsv1.UpdateLaunchStatusRequest]) (*connect.Response[pbflagsv1.UpdateLaunchStatusResponse], error)
type AdminServiceOption ¶ added in v0.20.0
type AdminServiceOption func(*AdminService)
AdminServiceOption configures optional AdminService behavior.
func WithAllowRuntimeOverrides ¶ added in v0.20.0
func WithAllowRuntimeOverrides() AdminServiceOption
WithAllowRuntimeOverrides enables every state-changing RPC: condition overrides, sync lock acquire/release, flag state updates (kill/unkill), and launch ramp/status/kill/unkill. Default is disabled — operators opt in via the --allow-runtime-overrides server flag (default true at the binary level; off only on locked-down read-only deployments).
type AuditLogFilter ¶ added in v0.4.1
AuditLogFilter specifies optional filters for audit log queries.
type ConditionOverride ¶ added in v0.20.0
type ConditionOverride struct {
FlagID string
ConditionIndex *int32 // nil = static/compiled-default override
Value *pbflagsv1.FlagValue
Source string // "cli" or "ui"
Actor string
Reason string
CreatedAt time.Time
}
ConditionOverride is one row from feature_flags.condition_overrides.
type FlagCondition ¶ added in v0.16.0
type FlagCondition struct {
CEL string // CEL expression; empty string means "otherwise" (default fallback)
Value string // formatted display value
Comment string // annotation from YAML comment
LaunchID string // launch override ID (empty if none)
LaunchValue string // formatted launch override value
}
FlagCondition represents a single condition in a flag's condition chain.
type FlagExtra ¶ added in v0.16.0
type FlagExtra struct {
Conditions []FlagCondition
ConditionsError string
SyncSHA string
}
FlagExtra holds non-proto data loaded alongside a FlagDetail.
type Launch ¶ added in v0.17.0
type Launch struct {
LaunchID string
ScopeFeatureID *string // nil for cross-feature launches
Dimension string
RampPct int
RampSource string // "unspecified", "config", "cli", "ui"
Status string
KilledAt *time.Time
AffectedFeatures []string
Description *string
CreatedAt time.Time
UpdatedAt time.Time
RampSteps []int32
}
Launch represents a launch (gradual rollout) in the new schema.
type OverrideListFilter ¶ added in v0.20.0
type OverrideListFilter struct {
FlagID string
MinAge time.Duration
Actor string
// Limit caps the result count. Zero / negative defaults to
// defaultOverrideListLimit. Values above maxOverrideListLimit are
// clamped to that ceiling.
Limit int32
}
OverrideListFilter narrows the global override listing.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store provides PostgreSQL persistence for flag state.
func (*Store) AcquireSyncLock ¶ added in v0.20.0
AcquireSyncLock takes the global sync lock. If the lock is already held, returns *SyncLockHeldError carrying the current holder's metadata.
Race safety: uses INSERT ... ON CONFLICT DO NOTHING so concurrent acquires both attempt the insert; only one succeeds, the other re-reads the holder and returns SyncLockHeldError.
func (*Store) ClearAllConditionOverrides ¶ added in v0.20.0
func (s *Store) ClearAllConditionOverrides(ctx context.Context, flagID, actor, reason string) (int, error)
ClearAllConditionOverrides deletes every override on a flag, returning the number cleared. Reason is captured in the audit row.
func (*Store) ClearConditionOverride ¶ added in v0.20.0
func (s *Store) ClearConditionOverride( ctx context.Context, flagID string, conditionIndex *int32, actor, reason string, ) error
ClearConditionOverride deletes a single override row. Returns ErrOverrideNotFound when no row exists at this position.
func (*Store) ClearOverridesForFlagsTx ¶ added in v0.20.0
func (s *Store) ClearOverridesForFlagsTx(ctx context.Context, tx pgx.Tx, flagIDs []string, actor string) (int, error)
ClearOverridesForFlagsTx is invoked by sync inside its own transaction to auto-clear overrides for synced flags after a successful condition write. Each cleared override is audit-logged as CONDITION_OVERRIDE_AUTO_CLEARED.
Caller passes the tx so the override clear commits atomically with the new conditions, eliminating the race where new conditions are visible but old overrides still match.
func (*Store) ConfigManagedFeatures ¶ added in v0.20.0
ConfigManagedFeatures returns a set of feature IDs that are currently config-as-code managed (sync_sha is set). Used by the dashboard to surface a per-feature badge without an N+1 lookup.
func (*Store) FlagsByLaunch ¶ added in v0.20.0
FlagsByLaunch returns a map from launch_id to the sorted list of flag_ids whose condition chain references that launch (pb-6fi). The scan is restricted to the union of features the supplied launches affect — typically a small set — to keep the cost bounded for the admin UI's per-launch "impacted flags" panel. Conditions live in a proto-encoded BYTEA column, so we decode in Go rather than push the filter into SQL.
Returns an empty map (never nil) when launches is empty so callers can index without nil-checks. Failures to decode an individual flag's chain are logged and skipped — one bad row shouldn't blank out the whole UI panel.
func (*Store) GetAuditLog ¶
func (s *Store) GetAuditLog(ctx context.Context, filter AuditLogFilter) ([]*pbflagsv1.AuditLogEntry, error)
GetAuditLog returns audit log entries, optionally filtered by flag ID, action, and actor.
func (*Store) GetFlag ¶
func (s *Store) GetFlag(ctx context.Context, flagID string) (*pbflagsv1.FlagDetail, *FlagExtra, error)
GetFlag returns details for a single flag.
func (*Store) GetFlagState ¶
func (s *Store) GetFlagState(ctx context.Context, flagID string) (*pbflagsv1.GetFlagStateResponse, error)
GetFlagState returns the state and value for a single flag.
func (*Store) GetKilledFlags ¶
GetKilledFlags returns globally killed flag IDs.
func (*Store) GetSyncLock ¶ added in v0.20.0
func (s *Store) GetSyncLock(ctx context.Context) (*SyncLockInfo, error)
GetSyncLock returns the current lock state, or (nil, nil) if unlocked.
func (*Store) IsConfigManaged ¶ added in v0.20.0
IsConfigManaged returns true when the owning feature has a non-empty sync_sha (i.e., config-as-code is currently the source of truth for this flag's conditions). Callers use this to surface a warning when overriding.
func (*Store) KillLaunch ¶ added in v0.17.0
KillLaunch sets killed_at on a launch (reversible emergency disable).
func (*Store) ListAllLaunches ¶ added in v0.17.0
ListAllLaunches returns all launches.
func (*Store) ListAllOverrides ¶ added in v0.20.0
func (s *Store) ListAllOverrides(ctx context.Context, f OverrideListFilter) ([]ConditionOverride, error)
ListAllOverrides returns active condition overrides across all flags, newest first. Backs both the `pb overrides` CLI and the dashboard listing. The result is bounded — see OverrideListFilter.Limit.
func (*Store) ListFeatures ¶
func (s *Store) ListFeatures(ctx context.Context) ([]*pbflagsv1.FeatureDetail, map[string]int, error)
ListFeatures returns all features with their non-archived flags. The second return value maps flag_id → condition count (0 = static/default).
func (*Store) ListLaunches ¶ added in v0.17.0
ListLaunches returns launches scoped to a feature (defined in the feature config).
func (*Store) ListLaunchesAffecting ¶ added in v0.17.0
ListLaunchesAffecting returns all launches that affect a feature (including cross-feature).
func (*Store) ListOverridesForFlag ¶ added in v0.20.0
func (s *Store) ListOverridesForFlag(ctx context.Context, flagID string) ([]ConditionOverride, error)
ListOverridesForFlag returns all overrides on a single flag, ordered with the static-default (NULL) row first, then by condition_index ascending.
func (*Store) ReleaseSyncLock ¶ added in v0.20.0
ReleaseSyncLock releases the global sync lock. Returns ErrSyncNotLocked if no lock is currently held. unlockReason is captured in the audit row so retros can see why the lock was released.
func (*Store) SetConditionOverride ¶ added in v0.20.0
func (s *Store) SetConditionOverride( ctx context.Context, flagID string, conditionIndex *int32, value *pbflagsv1.FlagValue, source, actor, reason string, ) (*pbflagsv1.FlagValue, error)
SetConditionOverride upserts an override row for (flagID, conditionIndex). Returns the previous override value at this position, if any (for confirmation UX). conditionIndex == nil means override the static/compiled default. source must be "cli", "ui", or "automation".
Race safety: uses INSERT ... ON CONFLICT DO UPDATE keyed off the partial unique indexes, so concurrent set calls on the same (flag, index) can't both INSERT and trip the unique constraint.
func (*Store) UnkillLaunch ¶ added in v0.17.0
UnkillLaunch clears killed_at on a launch (resume where it left off).
func (*Store) UpdateFlagState ¶
func (s *Store) UpdateFlagState(ctx context.Context, flagID string, state pbflagsv1.State, actor string) error
UpdateFlagState sets the killed state for a flag (kill or unkill).
func (*Store) UpdateLaunchRamp ¶ added in v0.17.0
func (s *Store) UpdateLaunchRamp(ctx context.Context, launchID string, pct int, source, actor string) (prevSource string, err error)
UpdateLaunchRamp changes the ramp percentage for a launch and records an audit log entry. Returns the previous ramp_source so callers can warn when overriding config-managed ramp.
type SyncLockHeldError ¶ added in v0.20.0
type SyncLockHeldError struct {
Info SyncLockInfo
}
SyncLockHeldError is returned when AcquireSyncLock is called while the lock is already held by someone else. It carries the current holder so the caller can include it in user-facing error messages.
func (*SyncLockHeldError) Error ¶ added in v0.20.0
func (e *SyncLockHeldError) Error() string