Documentation
¶
Overview ¶
Package staging provides provider-neutral staging of parameter and secret changes for every supported provider (AWS, Google Cloud, Azure).
Index ¶
- Variables
- func CheckEntryAndTagConflicts(ctx context.Context, resolve ApplyStrategyResolver, entries map[EntryKey]Entry, ...) (map[EntryKey]struct{}, error)
- type AWSParamStrategy
- func (s *AWSParamStrategy) Apply(ctx context.Context, name string, entry Entry) error
- func (s *AWSParamStrategy) ApplyTags(ctx context.Context, name string, tagEntry TagEntry) error
- func (s *AWSParamStrategy) FetchCurrent(ctx context.Context, name string) (*FetchResult, error)
- func (s *AWSParamStrategy) FetchCurrentTags(ctx context.Context, name string) (map[string]string, error)
- func (s *AWSParamStrategy) FetchCurrentValue(ctx context.Context, name string) (*EditFetchResult, error)
- func (s *AWSParamStrategy) FetchLastModified(ctx context.Context, name string) (time.Time, error)
- func (s *AWSParamStrategy) FetchVersion(ctx context.Context, input string) (value string, versionLabel string, err error)
- func (s *AWSParamStrategy) HasDeleteOptions() bool
- func (s *AWSParamStrategy) ItemName() string
- func (s *AWSParamStrategy) ParseName(input string) (string, error)
- func (s *AWSParamStrategy) ParseSpec(input string) (name string, hasVersion bool, err error)
- func (s *AWSParamStrategy) Service() Service
- func (s *AWSParamStrategy) ServiceName() string
- type AWSSecretStrategy
- func (s *AWSSecretStrategy) Apply(ctx context.Context, name string, entry Entry) error
- func (s *AWSSecretStrategy) ApplyTags(ctx context.Context, name string, tagEntry TagEntry) error
- func (s *AWSSecretStrategy) FetchCurrent(ctx context.Context, name string) (*FetchResult, error)
- func (s *AWSSecretStrategy) FetchCurrentTags(ctx context.Context, name string) (map[string]string, error)
- func (s *AWSSecretStrategy) FetchCurrentValue(ctx context.Context, name string) (*EditFetchResult, error)
- func (s *AWSSecretStrategy) FetchLastModified(ctx context.Context, name string) (time.Time, error)
- func (s *AWSSecretStrategy) FetchVersion(ctx context.Context, input string) (value string, versionLabel string, err error)
- func (s *AWSSecretStrategy) HasDeleteOptions() bool
- func (s *AWSSecretStrategy) ItemName() string
- func (s *AWSSecretStrategy) ParseName(input string) (string, error)
- func (s *AWSSecretStrategy) ParseSpec(input string) (name string, hasVersion bool, err error)
- func (s *AWSSecretStrategy) Service() Service
- func (s *AWSSecretStrategy) ServiceName() string
- type ApplyStrategy
- type ApplyStrategyResolver
- type AzureParamStrategy
- func (s *AzureParamStrategy) Apply(ctx context.Context, name string, entry Entry) error
- func (s *AzureParamStrategy) ApplyTags(ctx context.Context, name string, tagEntry TagEntry) error
- func (s *AzureParamStrategy) FetchCurrent(ctx context.Context, name string) (*FetchResult, error)
- func (s *AzureParamStrategy) FetchCurrentTags(ctx context.Context, name string) (map[string]string, error)
- func (s *AzureParamStrategy) FetchCurrentValue(ctx context.Context, name string) (*EditFetchResult, error)
- func (s *AzureParamStrategy) FetchLastModified(ctx context.Context, name string) (time.Time, error)
- func (s *AzureParamStrategy) FetchVersion(ctx context.Context, input string) (value string, versionLabel string, err error)
- func (s *AzureParamStrategy) HasDeleteOptions() bool
- func (s *AzureParamStrategy) ItemName() string
- func (s *AzureParamStrategy) ParseName(input string) (string, error)
- func (s *AzureParamStrategy) ParseSpec(input string) (name string, hasVersion bool, err error)
- func (s *AzureParamStrategy) Service() Service
- func (s *AzureParamStrategy) ServiceName() string
- type AzureSecretStrategy
- func (s *AzureSecretStrategy) Apply(ctx context.Context, name string, entry Entry) error
- func (s *AzureSecretStrategy) ApplyTags(ctx context.Context, name string, tagEntry TagEntry) error
- func (s *AzureSecretStrategy) FetchCurrent(ctx context.Context, name string) (*FetchResult, error)
- func (s *AzureSecretStrategy) FetchCurrentTags(ctx context.Context, name string) (map[string]string, error)
- func (s *AzureSecretStrategy) FetchCurrentValue(ctx context.Context, name string) (*EditFetchResult, error)
- func (s *AzureSecretStrategy) FetchLastModified(ctx context.Context, name string) (time.Time, error)
- func (s *AzureSecretStrategy) FetchVersion(ctx context.Context, input string) (value string, versionLabel string, err error)
- func (s *AzureSecretStrategy) HasDeleteOptions() bool
- func (s *AzureSecretStrategy) ItemName() string
- func (s *AzureSecretStrategy) ParseName(input string) (string, error)
- func (s *AzureSecretStrategy) ParseSpec(input string) (name string, hasVersion bool, err error)
- func (s *AzureSecretStrategy) Service() Service
- func (s *AzureSecretStrategy) ServiceName() string
- type DeleteOptions
- type DeleteStrategy
- type DiffStrategy
- type EditFetchResult
- type EditStrategy
- type Entry
- type EntryKey
- type EntryPrinter
- type FetchResult
- type FullStrategy
- type GoogleCloudSecretStrategy
- func (s *GoogleCloudSecretStrategy) Apply(ctx context.Context, name string, entry Entry) error
- func (s *GoogleCloudSecretStrategy) ApplyTags(ctx context.Context, name string, tagEntry TagEntry) error
- func (s *GoogleCloudSecretStrategy) FetchCurrent(ctx context.Context, name string) (*FetchResult, error)
- func (s *GoogleCloudSecretStrategy) FetchCurrentTags(ctx context.Context, name string) (map[string]string, error)
- func (s *GoogleCloudSecretStrategy) FetchCurrentValue(ctx context.Context, name string) (*EditFetchResult, error)
- func (s *GoogleCloudSecretStrategy) FetchLastModified(ctx context.Context, name string) (time.Time, error)
- func (s *GoogleCloudSecretStrategy) FetchVersion(ctx context.Context, input string) (value string, versionLabel string, err error)
- func (s *GoogleCloudSecretStrategy) HasDeleteOptions() bool
- func (s *GoogleCloudSecretStrategy) ItemName() string
- func (s *GoogleCloudSecretStrategy) ParseName(input string) (string, error)
- func (s *GoogleCloudSecretStrategy) ParseSpec(input string) (name string, hasVersion bool, err error)
- func (s *GoogleCloudSecretStrategy) Service() Service
- func (s *GoogleCloudSecretStrategy) ServiceName() string
- type Operation
- type Parser
- type ParserFactory
- type ResetStrategy
- type ResolvedScope
- type ResourceNotFoundError
- type ScopeResolver
- type Service
- type ServiceStrategy
- type State
- func (s *State) EntryCount() int
- func (s *State) ExtractService(service Service) *State
- func (s *State) IsEmpty() bool
- func (s *State) MarshalJSON() ([]byte, error)
- func (s *State) Merge(other *State)
- func (s *State) RemoveService(service Service)
- func (s *State) TagCount() int
- func (s *State) TotalCount() int
- func (s *State) UnmarshalJSON(data []byte) error
- type StrategyFactory
- type TagEntry
Constants ¶
This section is empty.
Variables ¶
var ( // ErrNotStaged is returned when a parameter/secret is not staged. ErrNotStaged = errors.New("not staged") // ErrStateVersionTooNew is returned by UnmarshalJSON when the on-disk staging // state was written by a newer suve than this build can read. The caller must // upgrade suve; the state is left untouched rather than rewritten as an older // version. ErrStateVersionTooNew = errors.New("staging state was written by a newer suve; upgrade suve") // ErrStateVersionTooOld is returned by UnmarshalJSON when the state was // written by an older suve whose on-disk layout this build does not migrate. // The state decodes as empty (its records are dropped), but the error makes // that drop explicit so an importer can report it instead of silently // importing nothing. The working store treats it as a benign reset. ErrStateVersionTooOld = errors.New("staging state was written by an older suve and cannot be read; its records were dropped") // ErrDuplicateRecord is returned by UnmarshalJSON when a payload carries two // records for the same (name, namespace). Silently keeping the last one would // hide the ambiguity, so the state is rejected instead. ErrDuplicateRecord = errors.New("duplicate staged record") )
var ErrServiceNotConfigured = errors.New("staging service not configured")
ErrServiceNotConfigured is returned by a ScopeResolver when the active scope does not name this service's backing resource (e.g. no Azure Key Vault while only App Configuration is configured). A single-service command treats it as a fatal usage error (with the resolver's descriptive message); a provider-wide command treats it as "skip this service" — an unconfigured service can hold no staged state, since staging is keyed by the resource name.
Functions ¶
func CheckEntryAndTagConflicts ¶ added in v1.8.1
func CheckEntryAndTagConflicts( ctx context.Context, resolve ApplyStrategyResolver, entries map[EntryKey]Entry, tags map[EntryKey]TagEntry, ) (map[EntryKey]struct{}, error)
CheckEntryAndTagConflicts checks staged value changes and staged tag changes for conflicts and returns the merged set of conflicting EntryKeys.
- Create: conflicts if the resource now exists (someone else created it).
- Update/Delete with BaseModifiedAt: conflicts if the remote was modified after the base time.
- Tag change with BaseModifiedAt: conflicts if the remote was modified after the tags were fetched. A tag change without a base time cannot be checked, and a remote that no longer exists is skipped (the tag apply fails on its own).
The check fails closed: when a probe fails for any reason other than ResourceNotFoundError (throttling, a network error, a read-denied policy), the key cannot be proven conflict-free, so a non-nil error naming every such key is returned and the caller must not apply. Many write paths do not re-read before writing (a Delete never does), so skipping the key would let the apply overwrite or delete a newer remote version unchecked.
Each key is probed through the strategy resolved for its own namespace, so two same-named entries in different App Configuration namespaces never collapse onto one namespace's remote state; namespace-agnostic providers resolve the single strategy under the empty namespace. Each remote's last-modified time is fetched at most once, even when a key carries both a value change and a tag change.
Types ¶
type AWSParamStrategy ¶ added in v1.8.2
type AWSParamStrategy struct {
// contains filtered or unexported fields
}
AWSParamStrategy implements ServiceStrategy for AWS Parameter Store over a provider.Store. Parameter Store specifics:
- Versions are integers, parsed with version.AWSParameterStore (#N, ~SHIFT).
- Values carry a type (String / SecureString / StringList); a SecureString is masked in diffs, and an edit keeps the existing type unless it staged one.
- There are no delete options.
The zero value (no store) is a parser-only strategy (ParseName/ParseSpec).
func NewAWSParamStrategy ¶ added in v1.8.2
func NewAWSParamStrategy(store provider.Store) *AWSParamStrategy
NewAWSParamStrategy creates a new AWS Parameter Store strategy over the given provider store. A nil store is allowed for parser-only use.
func (*AWSParamStrategy) ApplyTags ¶ added in v1.8.2
ApplyTags applies staged tag changes. Additions are applied before removals.
func (*AWSParamStrategy) FetchCurrent ¶ added in v1.8.2
func (s *AWSParamStrategy) FetchCurrent(ctx context.Context, name string) (*FetchResult, error)
FetchCurrent fetches the current value for diffing.
func (*AWSParamStrategy) FetchCurrentTags ¶ added in v1.8.2
func (s *AWSParamStrategy) FetchCurrentTags(ctx context.Context, name string) (map[string]string, error)
FetchCurrentTags fetches the current tags. A missing item or an item with no tags yields nil.
func (*AWSParamStrategy) FetchCurrentValue ¶ added in v1.8.2
func (s *AWSParamStrategy) FetchCurrentValue(ctx context.Context, name string) (*EditFetchResult, error)
FetchCurrentValue fetches the current value for editing. Returns *ResourceNotFoundError if the item doesn't exist.
func (*AWSParamStrategy) FetchLastModified ¶ added in v1.8.2
FetchLastModified returns the last modified time of the item. It returns a *ResourceNotFoundError when the item does not exist, so callers can tell "missing" apart from "exists but has no modification time" (the latter returns a zero time with a nil error).
func (*AWSParamStrategy) FetchVersion ¶ added in v1.8.2
func (s *AWSParamStrategy) FetchVersion(ctx context.Context, input string) (value string, versionLabel string, err error)
FetchVersion fetches the value for a specific version.
func (*AWSParamStrategy) HasDeleteOptions ¶ added in v1.8.2
func (s *AWSParamStrategy) HasDeleteOptions() bool
HasDeleteOptions reports whether the service has delete options.
func (*AWSParamStrategy) ItemName ¶ added in v1.8.2
func (s *AWSParamStrategy) ItemName() string
ItemName returns the item name for messages.
func (*AWSParamStrategy) ParseName ¶ added in v1.8.2
ParseName parses and validates a name for editing (no version specifier).
func (*AWSParamStrategy) ParseSpec ¶ added in v1.8.2
ParseSpec parses a version spec string for reset.
func (*AWSParamStrategy) Service ¶ added in v1.8.2
func (s *AWSParamStrategy) Service() Service
Service returns the service type.
func (*AWSParamStrategy) ServiceName ¶ added in v1.8.2
func (s *AWSParamStrategy) ServiceName() string
ServiceName returns the user-friendly service name.
type AWSSecretStrategy ¶ added in v1.8.2
type AWSSecretStrategy struct {
// contains filtered or unexported fields
}
AWSSecretStrategy implements ServiceStrategy for Secrets Manager over a provider.Store. Secrets Manager specifics:
- Versions are ids or staging labels, parsed with version.AWSSecretsManager (#ID, :LABEL, ~SHIFT); ids render truncated.
- Delete takes force / recovery-window options.
- A staged string edit refuses to overwrite a binary secret.
The zero value (no store) is a parser-only strategy (ParseName/ParseSpec).
func NewAWSSecretStrategy ¶ added in v1.8.2
func NewAWSSecretStrategy(store provider.Store) *AWSSecretStrategy
NewAWSSecretStrategy creates a new Secrets Manager strategy over the given provider store. A nil store is allowed for parser-only use.
func (*AWSSecretStrategy) ApplyTags ¶ added in v1.8.2
ApplyTags applies staged tag changes. Additions are applied before removals.
func (*AWSSecretStrategy) FetchCurrent ¶ added in v1.8.2
func (s *AWSSecretStrategy) FetchCurrent(ctx context.Context, name string) (*FetchResult, error)
FetchCurrent fetches the current value for diffing.
func (*AWSSecretStrategy) FetchCurrentTags ¶ added in v1.8.2
func (s *AWSSecretStrategy) FetchCurrentTags(ctx context.Context, name string) (map[string]string, error)
FetchCurrentTags fetches the current tags. A missing item or an item with no tags yields nil.
func (*AWSSecretStrategy) FetchCurrentValue ¶ added in v1.8.2
func (s *AWSSecretStrategy) FetchCurrentValue(ctx context.Context, name string) (*EditFetchResult, error)
FetchCurrentValue fetches the current value for editing. Returns *ResourceNotFoundError if the item doesn't exist.
func (*AWSSecretStrategy) FetchLastModified ¶ added in v1.8.2
FetchLastModified returns the last modified time of the item. It returns a *ResourceNotFoundError when the item does not exist, so callers can tell "missing" apart from "exists but has no modification time" (the latter returns a zero time with a nil error).
func (*AWSSecretStrategy) FetchVersion ¶ added in v1.8.2
func (s *AWSSecretStrategy) FetchVersion(ctx context.Context, input string) (value string, versionLabel string, err error)
FetchVersion fetches the value for a specific version.
func (*AWSSecretStrategy) HasDeleteOptions ¶ added in v1.8.2
func (s *AWSSecretStrategy) HasDeleteOptions() bool
HasDeleteOptions reports whether the service has delete options.
func (*AWSSecretStrategy) ItemName ¶ added in v1.8.2
func (s *AWSSecretStrategy) ItemName() string
ItemName returns the item name for messages.
func (*AWSSecretStrategy) ParseName ¶ added in v1.8.2
ParseName parses and validates a name for editing (no version specifier).
func (*AWSSecretStrategy) ParseSpec ¶ added in v1.8.2
ParseSpec parses a version spec string for reset.
func (*AWSSecretStrategy) Service ¶ added in v1.8.2
func (s *AWSSecretStrategy) Service() Service
Service returns the service type.
func (*AWSSecretStrategy) ServiceName ¶ added in v1.8.2
func (s *AWSSecretStrategy) ServiceName() string
ServiceName returns the user-friendly service name.
type ApplyStrategy ¶
type ApplyStrategy interface {
ServiceStrategy
// Apply applies a staged entry operation to the remote store.
// Handles OperationCreate, OperationUpdate, and OperationDelete based on entry.Operation.
Apply(ctx context.Context, name string, entry Entry) error
// ApplyTags applies staged tag changes to the remote store.
ApplyTags(ctx context.Context, name string, tagEntry TagEntry) error
// FetchLastModified returns the last modified time of the resource in the remote store.
// It returns a *ResourceNotFoundError when the resource does not exist, so
// callers can distinguish "missing" from "exists but has no modification
// time" (the latter returns a zero time with a nil error). Providers that
// disable conflict detection may always return a zero time with a nil error.
FetchLastModified(ctx context.Context, name string) (time.Time, error)
}
ApplyStrategy defines service-specific apply operations.
type ApplyStrategyResolver ¶ added in v1.7.0
type ApplyStrategyResolver func(namespace string) (ApplyStrategy, error)
ApplyStrategyResolver resolves the ApplyStrategy for a given namespace. It mirrors the per-namespace resolution the apply path uses so a namespaced provider (Azure App Configuration) probes each entry against the remote state of its OWN namespace rather than the default one.
type AzureParamStrategy ¶ added in v1.10.0
type AzureParamStrategy struct {
// contains filtered or unexported fields
}
AzureParamStrategy implements the staging strategies for Azure App Configuration. App Configuration is UNVERSIONED, so:
- There are no version specifiers: version.AzureAppConfiguration takes the whole argument as the key, since '#', ':' and '~' are legal key characters.
- Conflict detection is disabled (last-write-wins): FetchLastModified and the edit base time return zero, so apply never reports a modified-after conflict. Apply overwrites unconditionally. FetchLastModified still reports a missing setting as not found, for the delete existence check.
- Tag mutation is supported (azappconfig/v2 GET-merge-PUT + ETag): ApplyTags forwards TagEntry.Add/Remove to the store's Tag/Untag.
A nil store yields a parser-only strategy (ParseName/ParseSpec).
func NewAzureParamStrategy ¶ added in v1.10.0
func NewAzureParamStrategy(store provider.Store) *AzureParamStrategy
NewAzureParamStrategy creates an Azure App Configuration staging strategy over the given provider store. A nil store is allowed for parser-only use.
func (*AzureParamStrategy) Apply ¶ added in v1.10.0
Apply applies a staged operation to Azure App Configuration.
func (*AzureParamStrategy) ApplyTags ¶ added in v1.10.0
ApplyTags applies staged tag changes to App Configuration: TagEntry.Add via the store's Tag and TagEntry.Remove via Untag (each a GET-merge-PUT under the scope's namespace label). Additions are applied before removals.
func (*AzureParamStrategy) FetchCurrent ¶ added in v1.10.0
func (s *AzureParamStrategy) FetchCurrent(ctx context.Context, name string) (*FetchResult, error)
FetchCurrent fetches the current value from App Configuration for diffing. App Configuration is unversioned, so the identifier is empty.
func (*AzureParamStrategy) FetchCurrentTags ¶ added in v1.10.0
func (s *AzureParamStrategy) FetchCurrentTags(ctx context.Context, name string) (map[string]string, error)
FetchCurrentTags fetches the setting's current tags so stage diff can show the current value of a removed tag. A missing setting or a setting with no tags yields nil.
func (*AzureParamStrategy) FetchCurrentValue ¶ added in v1.10.0
func (s *AzureParamStrategy) FetchCurrentValue(ctx context.Context, name string) (*EditFetchResult, error)
FetchCurrentValue fetches the current value for editing. LastModified is left zero so the edit flow records no conflict base (last-write-wins).
func (*AzureParamStrategy) FetchLastModified ¶ added in v1.10.0
FetchLastModified reports whether the setting exists, but never a modification time: App Configuration staging uses last-write-wins, so an existing setting yields a zero time and no modified-after conflict is ever reported. A missing setting yields a *ResourceNotFoundError, so the delete use case refuses to stage a delete of a setting that does not exist (and a staged create is still checked against a setting created since).
func (*AzureParamStrategy) FetchVersion ¶ added in v1.10.0
func (s *AzureParamStrategy) FetchVersion(ctx context.Context, input string) (value string, versionLabel string, err error)
FetchVersion fetches the current value. App Configuration is unversioned and the entire argument is the key, so this only ever resolves the current value.
func (*AzureParamStrategy) HasDeleteOptions ¶ added in v1.10.0
func (s *AzureParamStrategy) HasDeleteOptions() bool
HasDeleteOptions returns false: App Configuration has no delete options.
func (*AzureParamStrategy) ItemName ¶ added in v1.10.0
func (s *AzureParamStrategy) ItemName() string
ItemName returns the item name for messages.
func (*AzureParamStrategy) ParseName ¶ added in v1.10.0
func (s *AzureParamStrategy) ParseName(input string) (string, error)
ParseName parses and validates a name. App Configuration is unversioned, so the entire argument is the key (':' / '#' / '~' are legal key characters).
func (*AzureParamStrategy) ParseSpec ¶ added in v1.10.0
func (s *AzureParamStrategy) ParseSpec(input string) (name string, hasVersion bool, err error)
ParseSpec parses a name for reset. App Configuration is unversioned, so a version is never present; the entire argument is the key.
func (*AzureParamStrategy) Service ¶ added in v1.10.0
func (s *AzureParamStrategy) Service() Service
Service returns the service type.
func (*AzureParamStrategy) ServiceName ¶ added in v1.10.0
func (s *AzureParamStrategy) ServiceName() string
ServiceName returns the user-friendly service name.
type AzureSecretStrategy ¶ added in v1.10.0
type AzureSecretStrategy struct {
// contains filtered or unexported fields
}
AzureSecretStrategy implements the staging strategies for Azure Key Vault secrets over a provider.Store. Key Vault specifics:
- Versions are opaque ids, parsed with version.AzureKeyVault (#ID, ~SHIFT); a staged "edit" applies as a new version via Put.
- There are no force / recovery-window delete options (delete is a soft delete), so HasDeleteOptions reports false.
- Tags are writable, so tag/untag staging is supported.
- Conflict detection uses the secret's last-modified timestamp, like AWS.
The zero value (no store) is a parser-only strategy (ParseName/ParseSpec).
func NewAzureSecretStrategy ¶ added in v1.10.0
func NewAzureSecretStrategy(store provider.Store) *AzureSecretStrategy
NewAzureSecretStrategy creates an Azure Key Vault staging strategy over the given provider store. A nil store is allowed for parser-only use.
func (*AzureSecretStrategy) ApplyTags ¶ added in v1.10.0
ApplyTags applies staged tag changes. Additions are applied before removals.
func (*AzureSecretStrategy) FetchCurrent ¶ added in v1.10.0
func (s *AzureSecretStrategy) FetchCurrent(ctx context.Context, name string) (*FetchResult, error)
FetchCurrent fetches the current value for diffing.
func (*AzureSecretStrategy) FetchCurrentTags ¶ added in v1.10.0
func (s *AzureSecretStrategy) FetchCurrentTags(ctx context.Context, name string) (map[string]string, error)
FetchCurrentTags fetches the current tags. A missing item or an item with no tags yields nil.
func (*AzureSecretStrategy) FetchCurrentValue ¶ added in v1.10.0
func (s *AzureSecretStrategy) FetchCurrentValue(ctx context.Context, name string) (*EditFetchResult, error)
FetchCurrentValue fetches the current value for editing. Returns *ResourceNotFoundError if the item doesn't exist.
func (*AzureSecretStrategy) FetchLastModified ¶ added in v1.10.0
func (s *AzureSecretStrategy) FetchLastModified(ctx context.Context, name string) (time.Time, error)
FetchLastModified returns the last modified time of the item. It returns a *ResourceNotFoundError when the item does not exist, so callers can tell "missing" apart from "exists but has no modification time" (the latter returns a zero time with a nil error).
func (*AzureSecretStrategy) FetchVersion ¶ added in v1.10.0
func (s *AzureSecretStrategy) FetchVersion(ctx context.Context, input string) (value string, versionLabel string, err error)
FetchVersion fetches the value for a specific version.
func (*AzureSecretStrategy) HasDeleteOptions ¶ added in v1.10.0
func (s *AzureSecretStrategy) HasDeleteOptions() bool
HasDeleteOptions reports whether the service has delete options.
func (*AzureSecretStrategy) ItemName ¶ added in v1.10.0
func (s *AzureSecretStrategy) ItemName() string
ItemName returns the item name for messages.
func (*AzureSecretStrategy) ParseName ¶ added in v1.10.0
ParseName parses and validates a name for editing (no version specifier).
func (*AzureSecretStrategy) ParseSpec ¶ added in v1.10.0
ParseSpec parses a version spec string for reset.
func (*AzureSecretStrategy) Service ¶ added in v1.10.0
func (s *AzureSecretStrategy) Service() Service
Service returns the service type.
func (*AzureSecretStrategy) ServiceName ¶ added in v1.10.0
func (s *AzureSecretStrategy) ServiceName() string
ServiceName returns the user-friendly service name.
type DeleteOptions ¶
type DeleteOptions struct {
// Force enables immediate permanent deletion without recovery window.
Force bool `json:"force,omitempty"`
// RecoveryWindow is the number of days before permanent deletion (7-30).
// Only used when Force is false. 0 means default (30 days).
//nolint:tagliatelle // JSON uses snake_case for consistency with file storage format
RecoveryWindow int `json:"recovery_window,omitempty"`
}
DeleteOptions holds options for Secrets Manager delete operations.
type DeleteStrategy ¶ added in v0.1.1
type DeleteStrategy interface {
ServiceStrategy
// FetchLastModified returns the last modified time of the resource in the remote store.
// Used for existence and conflict detection when applying delete operations.
// It returns a *ResourceNotFoundError when the resource does not exist, so
// callers can distinguish "missing" from "exists but has no modification
// time" (the latter returns a zero time with a nil error).
FetchLastModified(ctx context.Context, name string) (time.Time, error)
}
DeleteStrategy defines service-specific delete staging operations.
type DiffStrategy ¶
type DiffStrategy interface {
ServiceStrategy
// FetchCurrent fetches the current value from the remote store for diffing.
FetchCurrent(ctx context.Context, name string) (*FetchResult, error)
// FetchCurrentTags fetches the current tags from the remote store for showing in diff output.
// Returns nil map if the resource doesn't exist or has no tags.
FetchCurrentTags(ctx context.Context, name string) (map[string]string, error)
}
DiffStrategy defines service-specific diff/fetch operations.
type EditFetchResult ¶
type EditFetchResult struct {
// Value is the current remote value.
Value string
// LastModified is the last modification time of the resource.
// Used for conflict detection when applying staged changes.
LastModified time.Time
}
EditFetchResult holds the result of fetching a value for editing.
type EditStrategy ¶
type EditStrategy interface {
Parser
// FetchCurrentValue fetches the current value from the remote store for editing.
// Returns the value and last modified time for conflict detection.
FetchCurrentValue(ctx context.Context, name string) (*EditFetchResult, error)
}
EditStrategy defines service-specific edit operations.
type Entry ¶
type Entry struct {
Operation Operation `json:"operation"`
Value *string `json:"value,omitempty"` // nil for delete, pointer to distinguish from empty string
Description *string `json:"description,omitempty"`
// ValueType classifies the staged value in the provider-neutral domain model.
// It only matters on the AWS Parameter Store axis (String / SecureString /
// StringList); every other provider's staging path ignores it. An empty value
// means "unset": the apply path treats it as ValueTypePlaintext for create, and
// as "preserve the existing type" for update. Older on-disk entries written
// before this field existed decode as empty, preserving the prior plaintext
// behavior. Optional and additive so the working-store schema stays backward
// compatible (no version bump).
//nolint:tagliatelle // JSON uses snake_case for consistency with file storage format
ValueType domain.ValueType `json:"value_type,omitempty"`
//nolint:tagliatelle // JSON uses snake_case for consistency with file storage format
StagedAt time.Time `json:"staged_at"`
// BaseModifiedAt records the remote last-modified time when the value was fetched.
// Used for conflict detection: if the remote store was modified after this time, it's a conflict.
// Only set for update/delete operations (nil for create since there's no base).
//nolint:tagliatelle // JSON uses snake_case for consistency with file storage format
BaseModifiedAt *time.Time `json:"base_modified_at,omitempty"`
// DeleteOptions holds Secrets Manager-specific delete options.
// Only used when Operation is OperationDelete and service is Secrets Manager.
//nolint:tagliatelle // JSON uses snake_case for consistency with file storage format
DeleteOptions *DeleteOptions `json:"delete_options,omitempty"`
}
Entry represents a single staged entity change (create/update/delete). Tags are managed separately in TagEntry.
type EntryKey ¶ added in v1.5.2
EntryKey identifies a staged item — an entry or a tag change — by name and namespace. Namespace is the Azure App Configuration label axis; empty is the null/default namespace and the only value for every other provider. Carrying both in one value is what makes it impossible to address a staged item without its namespace: the store API and the in-memory state maps are keyed by EntryKey, so a namespaced App Configuration setting can never be silently resolved under the default namespace. The same name under two namespaces is two distinct items.
func SortedEntryKeys ¶ added in v1.5.2
SortedEntryKeys returns the keys of m sorted by (name, namespace) for deterministic iteration and output.
type EntryPrinter ¶
EntryPrinter prints staged entries to the given writer.
func (*EntryPrinter) PrintEntry ¶
func (p *EntryPrinter) PrintEntry(key EntryKey, entry Entry, verbose, showDeleteOptions bool)
PrintEntry prints a single staged entry identified by key. If verbose is true, shows detailed information including timestamp and value. If showDeleteOptions is true, shows delete options (Force/RecoveryWindow) for delete operations.
type FetchResult ¶
type FetchResult struct {
// Value is the current remote value.
Value string
// Identifier is a display string for the version (e.g., "#3" for AWS Parameter Store, "#abc123" for Secrets Manager).
Identifier string
// Secret reports whether the fetched value is secret material (a Secrets
// Manager/Key Vault/Secret Manager value, or a SecureString param), so a
// staged-diff consumer masks it. A SecureString param is a secret on the
// value-type axis even though it lives on the param service (#677).
Secret bool
}
FetchResult holds the result of fetching a value from the remote store.
type FullStrategy ¶
type FullStrategy interface {
ApplyStrategy
DiffStrategy
EditStrategy
ResetStrategy
}
FullStrategy combines all service-specific strategy interfaces. This enables unified stage commands that work with any provider service.
type GoogleCloudSecretStrategy ¶ added in v0.8.1
type GoogleCloudSecretStrategy struct {
// contains filtered or unexported fields
}
GoogleCloudSecretStrategy implements the staging strategies for Google Cloud Secret Manager over a provider.Store. Secret Manager specifics:
- Versions are immutable integers, parsed with version.GoogleCloudSecretManager (#N, ~SHIFT); a staged "edit" applies as a new version via Put.
- There are no delete options (no force / recovery window), so HasDeleteOptions reports false and Delete ignores staged DeleteOptions.
- There are no staging labels (:LABEL).
The zero value (no store) is a parser-only strategy (ParseName/ParseSpec).
func NewGoogleCloudSecretStrategy ¶ added in v0.8.1
func NewGoogleCloudSecretStrategy(store provider.Store) *GoogleCloudSecretStrategy
NewGoogleCloudSecretStrategy creates a Google Cloud Secret Manager staging strategy over the given provider store. A nil store is allowed for parser-only use.
func (*GoogleCloudSecretStrategy) ApplyTags ¶ added in v0.8.1
func (s *GoogleCloudSecretStrategy) ApplyTags(ctx context.Context, name string, tagEntry TagEntry) error
ApplyTags applies staged tag changes. Additions are applied before removals.
func (*GoogleCloudSecretStrategy) FetchCurrent ¶ added in v0.8.1
func (s *GoogleCloudSecretStrategy) FetchCurrent(ctx context.Context, name string) (*FetchResult, error)
FetchCurrent fetches the current value for diffing.
func (*GoogleCloudSecretStrategy) FetchCurrentTags ¶ added in v0.8.1
func (s *GoogleCloudSecretStrategy) FetchCurrentTags(ctx context.Context, name string) (map[string]string, error)
FetchCurrentTags fetches the current tags. A missing item or an item with no tags yields nil.
func (*GoogleCloudSecretStrategy) FetchCurrentValue ¶ added in v0.8.1
func (s *GoogleCloudSecretStrategy) FetchCurrentValue(ctx context.Context, name string) (*EditFetchResult, error)
FetchCurrentValue fetches the current value for editing. Returns *ResourceNotFoundError if the item doesn't exist.
func (*GoogleCloudSecretStrategy) FetchLastModified ¶ added in v0.8.1
func (s *GoogleCloudSecretStrategy) FetchLastModified(ctx context.Context, name string) (time.Time, error)
FetchLastModified returns the last modified time of the item. It returns a *ResourceNotFoundError when the item does not exist, so callers can tell "missing" apart from "exists but has no modification time" (the latter returns a zero time with a nil error).
func (*GoogleCloudSecretStrategy) FetchVersion ¶ added in v0.8.1
func (s *GoogleCloudSecretStrategy) FetchVersion(ctx context.Context, input string) (value string, versionLabel string, err error)
FetchVersion fetches the value for a specific version.
func (*GoogleCloudSecretStrategy) HasDeleteOptions ¶ added in v0.8.1
func (s *GoogleCloudSecretStrategy) HasDeleteOptions() bool
HasDeleteOptions reports whether the service has delete options.
func (*GoogleCloudSecretStrategy) ItemName ¶ added in v0.8.1
func (s *GoogleCloudSecretStrategy) ItemName() string
ItemName returns the item name for messages.
func (*GoogleCloudSecretStrategy) ParseName ¶ added in v0.8.1
ParseName parses and validates a name for editing (no version specifier).
func (*GoogleCloudSecretStrategy) ParseSpec ¶ added in v0.8.1
func (s *GoogleCloudSecretStrategy) ParseSpec(input string) (name string, hasVersion bool, err error)
ParseSpec parses a version spec string for reset.
func (*GoogleCloudSecretStrategy) Service ¶ added in v0.8.1
func (s *GoogleCloudSecretStrategy) Service() Service
Service returns the service type.
func (*GoogleCloudSecretStrategy) ServiceName ¶ added in v0.8.1
func (s *GoogleCloudSecretStrategy) ServiceName() string
ServiceName returns the user-friendly service name.
type Parser ¶
type Parser interface {
ServiceStrategy
// ParseName parses and validates a name, returning only the base name without version specifiers.
// Returns an error if version specifiers are present.
ParseName(input string) (string, error)
// ParseSpec parses a version spec string.
// Returns the base name and whether a version/shift was specified.
ParseSpec(input string) (name string, hasVersion bool, err error)
}
Parser provides name/spec parsing without provider access. Use this interface when only parsing is needed (e.g., status, add commands).
func AWSParamParserFactory ¶ added in v1.8.2
func AWSParamParserFactory() Parser
AWSParamParserFactory creates a Parser without provider access. Use this for operations that don't need AWS access (e.g., status, parsing).
func AWSSecretParserFactory ¶ added in v1.8.2
func AWSSecretParserFactory() Parser
AWSSecretParserFactory creates a Parser without provider access. Use this for operations that don't need AWS access (e.g., status, parsing).
func AzureParamParserFactory ¶ added in v1.10.0
func AzureParamParserFactory() Parser
AzureParamParserFactory yields a parser-only strategy.
func AzureSecretParserFactory ¶ added in v1.10.0
func AzureSecretParserFactory() Parser
AzureSecretParserFactory yields a parser-only strategy.
func GoogleCloudSecretParserFactory ¶ added in v0.8.1
func GoogleCloudSecretParserFactory() Parser
GoogleCloudSecretParserFactory creates a Parser without provider access, for operations that don't need Google Cloud access (e.g. status, parsing).
type ParserFactory ¶
type ParserFactory func() Parser
ParserFactory creates a Parser without a provider client.
type ResetStrategy ¶
type ResetStrategy interface {
Parser
// FetchVersion fetches the value for a specific version.
// Returns the value and a version label for display.
FetchVersion(ctx context.Context, input string) (value string, versionLabel string, err error)
// FetchCurrentValue fetches the current value from the remote store for auto-skip detection.
// Uses same signature as EditStrategy for implementation reuse.
FetchCurrentValue(ctx context.Context, name string) (*EditFetchResult, error)
}
ResetStrategy defines service-specific reset operations.
type ResolvedScope ¶ added in v0.8.1
type ResolvedScope struct {
// Scope keys the on-disk staging state (see provider.Scope.Key).
Scope provider.Scope
// Target describes where changes will be applied.
Target provider.Target
}
ResolvedScope is the outcome of resolving the active provider's staging scope: the provider.Scope used to key on-disk staging state, plus the Target shown in apply/import confirmation prompts (e.g. an AWS profile/account/region, or a Google Cloud project).
type ResourceNotFoundError ¶ added in v0.4.8
type ResourceNotFoundError struct {
Err error
}
ResourceNotFoundError indicates a resource was not found in the remote store.
func (*ResourceNotFoundError) Error ¶ added in v0.4.8
func (e *ResourceNotFoundError) Error() string
func (*ResourceNotFoundError) Unwrap ¶ added in v0.4.8
func (e *ResourceNotFoundError) Unwrap() error
type ScopeResolver ¶ added in v0.8.1
type ScopeResolver func(ctx context.Context) (ResolvedScope, error)
ScopeResolver resolves the active provider's staging scope. AWS resolves it from the STS caller identity; Google Cloud from the configured project. It may perform network calls (e.g. STS GetCallerIdentity), so it is only invoked by staging commands, never by read/write commands.
type Service ¶
type Service string
Service is the provider-neutral service axis a staged change belongs to.
func SupportedServices ¶ added in v0.8.0
SupportedServices returns the staging Services supported by the given scope, in the scope's stable kind order. This is the registry-driven iteration source that replaces hardcoded {ServiceParam, ServiceSecret} loops.
type ServiceStrategy ¶
type ServiceStrategy interface {
// Service returns the service type (ServiceParam or ServiceSecret).
Service() Service
// ServiceName returns the user-friendly service name (e.g., "Parameter Store", "Key Vault").
ServiceName() string
// ItemName returns the item name for messages (e.g., "parameter", "secret").
ItemName() string
// HasDeleteOptions returns true if delete options should be displayed.
HasDeleteOptions() bool
}
ServiceStrategy defines the common interface for service-specific operations. Every provider's staging strategy implements it, so the stage commands are written once for all services.
type State ¶
type State struct {
Version int
Entries map[Service]map[EntryKey]Entry
Tags map[Service]map[EntryKey]TagEntry
}
State represents the entire staging state (v3). Entries and Tags are keyed by EntryKey (name + namespace) and managed separately for cleaner separation of concerns. On disk each item is a structured record carrying its name and namespace explicitly; see MarshalJSON / UnmarshalJSON.
func NewEmptyState ¶ added in v0.7.0
func NewEmptyState() *State
NewEmptyState creates a new empty state with initialized maps.
func (*State) EntryCount ¶ added in v0.7.0
EntryCount returns the total number of entries in the state.
func (*State) ExtractService ¶ added in v0.7.0
ExtractService returns a new state containing only entries for the specified service. If service is empty, returns a clone of the entire state.
func (*State) MarshalJSON ¶ added in v1.5.2
MarshalJSON writes the state as structured (name, namespace) records, sorted for deterministic output.
func (*State) Merge ¶ added in v0.7.0
Merge merges another state into this state. The other state takes precedence for conflicting entries.
func (*State) RemoveService ¶ added in v0.7.0
RemoveService removes all entries for the specified service from this state. If service is empty, clears all entries.
func (*State) TagCount ¶ added in v0.7.0
TagCount returns the total number of tag entries in the state.
func (*State) TotalCount ¶ added in v0.7.0
TotalCount returns the total number of entries and tags in the state.
func (*State) UnmarshalJSON ¶ added in v1.5.2
UnmarshalJSON reads a v3 (structured-record) state. Pre-v3 layouts (NUL-composite string map keys) are intentionally NOT migrated: they are treated as empty (see stateVersion) so a format bump never crashes commands — stale local working state is dropped rather than converted.
type StrategyFactory ¶
type StrategyFactory func(ctx context.Context) (FullStrategy, error)
StrategyFactory creates a FullStrategy for a given context. Used to defer provider client initialization until command execution.
type TagEntry ¶ added in v0.3.0
type TagEntry struct {
Add map[string]string `json:"add,omitempty"` // Tags to add or update
Remove maputil.Set[string] `json:"remove,omitempty"` // Tag keys to remove
// StagedAt records when the tag change was staged.
//nolint:tagliatelle // JSON uses snake_case for consistency with file storage format
StagedAt time.Time `json:"staged_at"`
// BaseModifiedAt records the remote last-modified time when tags were fetched.
// Used for conflict detection.
//nolint:tagliatelle // JSON uses snake_case for consistency with file storage format
BaseModifiedAt *time.Time `json:"base_modified_at,omitempty"`
}
TagEntry represents staged tag changes for an entity. Managed separately from Entry for cleaner separation of concerns.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package binding is the single per-(provider, service kind) lookup that the CLI, GUI and TUI share.
|
Package binding is the single per-(provider, service kind) lookup that the CLI, GUI and TUI share. |
|
Package cli provides shared runners and command builders for stage commands.
|
Package cli provides shared runners and command builders for stage commands. |
|
Package store provides storage interfaces and implementations for staging.
|
Package store provides storage interfaces and implementations for staging. |
|
file
Package file provides file-based staging storage.
|
Package file provides file-based staging storage. |
|
file/internal/crypt
Package crypt provides encryption for staging files.
|
Package crypt provides encryption for staging files. |
|
file/internal/keyprovider
Package keyprovider resolves the AES-256 data key used to encrypt the working staging state files (param.json/secret.json).
|
Package keyprovider resolves the AES-256 data key used to encrypt the working staging state files (param.json/secret.json). |
|
testutil
Package testutil provides test utilities for staging package.
|
Package testutil provides test utilities for staging package. |
|
Package transition implements state machine logic for staging operations.
|
Package transition implements state machine logic for staging operations. |