Documentation
¶
Overview ¶
Package util provides shared utilities for the CLI.
Shared command lifecycle ¶
WithClient(cmd, fn) wraps context creation, login, session-key persistence + logout, and SilenceUsage so command RunE functions don't repeat that plumbing. Read flags first (so flag errors still print usage), then run the API calls and rendering inside fn, which receives the context and a logged-in *api.Client.
Shared output helpers ¶
Entity commands render results as JSON or pterm tables. These helpers keep that output consistent and remove the per-entity duplication; the typed JSON output structs (one per entity) stay in their packages and are passed in generically:
- PrintJSON / FprintJSON marshal a value as indented JSON (single object or array), to stdout or an explicit io.Writer.
- PrintJSONColumnFiltered keeps only the requested keys when the user passed an explicit --column subset.
- PrintTable renders a pterm table from a column list and a per-cell value function; it is generic over the item type.
- PermissionsToJSONOutput / PrintPermissionTable render the permission output shared by the resource and folder commands.
Index ¶
- Variables
- func CELExpressionReferencesFields(celCmd string, fieldNames []string, options ...cel.EnvOption) (bool, error)
- func ExplainAPIError(op string, err error) error
- func FprintJSON(w io.Writer, v any) error
- func GetClient(ctx context.Context) (*api.Client, error)
- func GetClientCertificate() (tls.Certificate, error)
- func GetContext() (context.Context, context.CancelFunc)
- func GetHTTPClient() (*http.Client, error)
- func InitCELProgram(celCmd string, options ...cel.EnvOption) (*cel.Program, error)
- func NoColumnsError(valid []string) error
- func PrintJSON(v any) error
- func PrintJSONColumnFiltered[T any](items []T, columns []string) error
- func PrintPermissionTable(columns []string, permissions []api.Permission) error
- func PrintTable[T any](columns []string, items []T, ...) error
- func ReadPassword(prompt string) (string, error)
- func SaveSessionKeysAndLogout(ctx context.Context, client *api.Client)
- func WithClient(cmd *cobra.Command, fn func(ctx context.Context, client *api.Client) error) error
- type ColumnAlias
- type ColumnAliasResolver
- type ColumnRegistry
- func (r *ColumnRegistry[T]) CelEnvOptions() []cel.EnvOption
- func (r *ColumnRegistry[T]) DefaultTableColumns() []string
- func (r *ColumnRegistry[T]) Filter(ctx context.Context, items []T, celCmd string) ([]T, error)
- func (r *ColumnRegistry[T]) RequiresSecrets(columns []string) bool
- func (r *ColumnRegistry[T]) Resolver() *ColumnAliasResolver
- func (r *ColumnRegistry[T]) SecretCelNames() []string
- func (r *ColumnRegistry[T]) TableValue(item T, col string) (string, bool)
- type ColumnSpec
- type PermissionJSONOutput
Constants ¶
This section is empty.
Variables ¶
var ( // ErrNoID is returned by commands that require an --id flag when none is provided. ErrNoID = errors.New("no ID provided") // ErrNoColumns is returned by list/get commands when no output column is selected. ErrNoColumns = errors.New("no columns specified") )
Sentinel errors for recurring CLI input-validation failures. They are returned (optionally wrapped with extra context via fmt.Errorf and %w) so callers and tests can match them with errors.Is rather than comparing message strings.
var PermissionColumns = []string{
"ID", "Aco", "AcoForeignKey", "Aro", "AroForeignKey", "Type", "CreatedTimestamp", "ModifiedTimestamp",
}
PermissionColumns lists the column names accepted by the permission table commands (resource/folder permission). Used to build "valid columns" guidance.
Functions ¶
func CELExpressionReferencesFields ¶
func CELExpressionReferencesFields(celCmd string, fieldNames []string, options ...cel.EnvOption) (bool, error)
CELExpressionReferencesFields checks if a CEL expression references any of the given field names. Returns true if the expression references at least one of the specified fields.
func ExplainAPIError ¶
ExplainAPIError wraps err with operation-level context and, when err carries an *api.APIError, prepends a human-friendly explanation of the HTTP status code so users get actionable guidance instead of a bare status. The original error chain is preserved for errors.Is / errors.As.
func FprintJSON ¶
FprintJSON marshals v with two-space indent and writes it to w followed by a newline.
func GetClientCertificate ¶
func GetClientCertificate() (tls.Certificate, error)
func GetContext ¶
func GetContext() (context.Context, context.CancelFunc)
func GetHTTPClient ¶
func InitCELProgram ¶
InitCELProgram - Initialize a CEL program with given CEL command and a set of environments
func NoColumnsError ¶
NoColumnsError wraps ErrNoColumns with the set of valid column names so the user knows what to choose from. The result stays matchable with errors.Is(err, ErrNoColumns).
func PrintJSON ¶
PrintJSON marshals v with two-space indent and prints it to stdout followed by a newline. Use for single-entity get output and for full (unfiltered) list output.
func PrintJSONColumnFiltered ¶
PrintJSONColumnFiltered marshals each item, re-decodes it into a map, keeps only the requested column keys, and prints the indented array to stdout. Use when the caller requested an explicit subset of columns; otherwise use PrintJSON(items).
func PrintPermissionTable ¶
func PrintPermissionTable(columns []string, permissions []api.Permission) error
PrintPermissionTable renders the permission table using the legacy lowercased-column switch shared by the resource and folder permission commands. An unknown column yields an "unknown Column: %v" error (capitalized, preserving the historical message).
func PrintTable ¶
func PrintTable[T any](columns []string, items []T, valueFn func(item T, column string) (string, bool)) error
PrintTable renders a header row of column names followed by one row per item. valueFn returns the rendered cell string for (item, column) and reports whether the column is known; an unknown column yields an "unknown column: %q" error. It is generic over the item type so it serves both the api.* entity types and the resource package's decryptedResource.
func ReadPassword ¶
ReadPassword reads a Password interactively or via Pipe
func SaveSessionKeysAndLogout ¶
SaveSessionKeysAndLogout saves any pending session keys to the server and then logs out. This should be used instead of client.Logout() to ensure session keys are persisted.
func WithClient ¶
WithClient runs fn with a logged-in client, handling context, login, session-key persistence + logout, and SilenceUsage. SilenceUsage is set after login, so flag and login errors still print usage while runtime errors do not.
Types ¶
type ColumnAlias ¶
ColumnAlias declares a canonical column name together with the legacy input forms that should resolve to it. Used by list commands to accept snake_case (canonical), PascalCase, and lowercased-concat forms uniformly in --column and --filter flags.
type ColumnAliasResolver ¶
type ColumnAliasResolver struct {
// contains filtered or unexported fields
}
ColumnAliasResolver normalizes user-supplied column names to their canonical form via case-insensitive lookup against name+aliases.
func NewColumnAliasResolver ¶
func NewColumnAliasResolver(specs []ColumnAlias) *ColumnAliasResolver
func (*ColumnAliasResolver) Canonical ¶
func (r *ColumnAliasResolver) Canonical() []string
Canonical returns the canonical column names in declaration order. Useful for building --column flag help text and default value slices.
func (*ColumnAliasResolver) Normalize ¶
func (r *ColumnAliasResolver) Normalize(input string) (string, error)
Normalize maps an input column name to its canonical form. Returns an error listing the valid canonical names if the input matches nothing.
func (*ColumnAliasResolver) NormalizeAll ¶
func (r *ColumnAliasResolver) NormalizeAll(inputs []string) ([]string, error)
NormalizeAll normalizes a slice of input column names, returning the canonical-name slice or the first error encountered.
type ColumnRegistry ¶
type ColumnRegistry[T any] struct { // contains filtered or unexported fields }
ColumnRegistry holds the column specs for one entity type and precomputes the lookups and CEL options derived from them. It owns the shared CEL filter loop, so each entity package only declares its columns once.
func NewColumnRegistry ¶
func NewColumnRegistry[T any](noun string, columns []ColumnSpec[T]) *ColumnRegistry[T]
NewColumnRegistry builds a registry from the given column specs. noun is the plural entity word used in the "no such <noun> found with filter" error returned by Filter when nothing matches. Each canonical name and every alias is registered as a CEL variable so legacy and canonical filter expressions both compile.
func (*ColumnRegistry[T]) CelEnvOptions ¶
func (r *ColumnRegistry[T]) CelEnvOptions() []cel.EnvOption
CelEnvOptions returns the CEL environment options registering every canonical name and alias as a variable. Pass to util.CELExpressionReferencesFields.
func (*ColumnRegistry[T]) DefaultTableColumns ¶
func (r *ColumnRegistry[T]) DefaultTableColumns() []string
DefaultTableColumns returns the canonical names of columns shown in the default table output, in declaration order.
func (*ColumnRegistry[T]) Filter ¶
func (r *ColumnRegistry[T]) Filter(ctx context.Context, items []T, celCmd string) ([]T, error)
Filter evaluates celCmd against each item and returns the matching subset. An empty celCmd returns items unchanged; a valid expression matching nothing returns an error naming the entity.
func (*ColumnRegistry[T]) RequiresSecrets ¶
func (r *ColumnRegistry[T]) RequiresSecrets(columns []string) bool
RequiresSecrets reports whether any of the (already-normalized, canonical) columns demands secret decryption.
func (*ColumnRegistry[T]) Resolver ¶
func (r *ColumnRegistry[T]) Resolver() *ColumnAliasResolver
Resolver returns the alias resolver for normalizing --column / --filter input to canonical names and for building flag help text.
func (*ColumnRegistry[T]) SecretCelNames ¶
func (r *ColumnRegistry[T]) SecretCelNames() []string
SecretCelNames returns all CEL variable names (canonical and alias) whose value comes from secret decryption — used to detect whether a --filter expression forces secret fetching.
func (*ColumnRegistry[T]) TableValue ¶
func (r *ColumnRegistry[T]) TableValue(item T, col string) (string, bool)
TableValue resolves a canonical column name to the item's rendered table cell. Suitable as the valueFn for PrintTable; returns false for unknown columns.
type ColumnSpec ¶
type ColumnSpec[T any] struct { Name string Aliases []string DefaultTable bool RequiresSecrets bool // value depends on the expensive secret-decryption path CelType *cel.Type CelValue func(item T) any TableValue func(item T) string }
ColumnSpec describes one --column / --filter attribute on an entity of type T. The canonical Name is snake_case (matching JSON tags and Passbolt API conventions); Aliases keep legacy PascalCase and lowercased-concat forms working for backwards compatibility, both as CEL variables and as eval-map keys.
type PermissionJSONOutput ¶
type PermissionJSONOutput struct {
ID *string `json:"id,omitempty"`
Aco *string `json:"aco,omitempty"`
AcoForeignKey *string `json:"aco_foreign_key,omitempty"`
Aro *string `json:"aro,omitempty"`
AroForeignKey *string `json:"aro_foreign_key,omitempty"`
Type *int `json:"type,omitempty"`
CreatedTimestamp *time.Time `json:"created_timestamp,omitempty"`
ModifiedTimestamp *time.Time `json:"modified_timestamp,omitempty"`
}
func PermissionsToJSONOutput ¶
func PermissionsToJSONOutput(permissions []api.Permission) []PermissionJSONOutput
PermissionsToJSONOutput maps API permissions to the wire output struct shared by the resource and folder permission commands.