Documentation
¶
Overview ¶
Package cli implements the Cobra-based command-line interface for FinFocus.
The CLI provides the primary user interface with subcommands for:
- cost projected: Calculate projected costs from Pulumi preview JSON
- cost actual: Fetch actual historical costs with time ranges
- plugin list: List installed plugins
- plugin validate: Validate plugin installations
Usage Patterns ¶
Commands use RunE for proper error handling and cmd.Printf() for output. Date inputs support multiple formats including "2006-01-02" and RFC3339.
Configuration ¶
CLI flags take precedence over environment variables and config file settings. Debug output can be enabled with --debug flag or FINFOCUS_LOG_LEVEL=debug.
Index ¶
- Constants
- Variables
- func ApplyFilters(ctx context.Context, resources []engine.ResourceDescriptor, filters []string) ([]engine.ResourceDescriptor, error)
- func DetectPluginMode(args []string, lookupEnv func(string) (string, bool)) bool
- func FormatStatus(status StepStatus, nonInteractive bool) string
- func HasStatusAnnotationsForTest(recs []TestableRecommendation) bool
- func InitCache(ctx context.Context, cmd *cobra.Command) cache.Cache
- func IsValidPluginName(name string) bool
- func NewAnalyzerCheckCmd() *cobra.Command
- func NewAnalyzerCmd() *cobra.Command
- func NewAnalyzerInstallCmd() *cobra.Command
- func NewAnalyzerServeCmd() *cobra.Command
- func NewAnalyzerUninstallCmd() *cobra.Command
- func NewConfigGetCmd() *cobra.Command
- func NewConfigInitCmd() *cobra.Command
- func NewConfigListCmd() *cobra.Command
- func NewConfigRoutesCmd() *cobra.Command
- func NewConfigRoutesListCmd() *cobra.Command
- func NewConfigRoutesTestCmd() *cobra.Command
- func NewConfigSetCmd() *cobra.Command
- func NewConfigValidateCmd() *cobra.Command
- func NewCostActualCmd() *cobra.Command
- func NewCostEstimateCmd() *cobra.Command
- func NewCostProjectedCmd() *cobra.Command
- func NewCostRecommendationsCmd() *cobra.Command
- func NewOverviewCmd() *cobra.Command
- func NewPluginCertifyCmd() *cobra.Command
- func NewPluginConformanceCmd() *cobra.Command
- func NewPluginInitCmd() *cobra.Command
- func NewPluginInspectCmd() *cobra.Command
- func NewPluginInstallCmd() *cobra.Command
- func NewPluginListCmd() *cobra.Command
- func NewPluginRemoveCmd() *cobra.Command
- func NewPluginUpdateCmd() *cobra.Command
- func NewPluginValidateCmd() *cobra.Command
- func NewRootCmd(ver string) *cobra.Command
- func NewRootCmdWithArgs(ver string, args []string, lookupEnv func(string) (string, bool)) *cobra.Command
- func NewSetupCmd() *cobra.Command
- func NewSetupCmdWithRunner(runner *SetupRunner) *cobra.Command
- func ParseBudgetFilters(ctx context.Context, filters []string) (*engine.BudgetFilterOptions, error)
- func ParseModifications(mods []string) (map[string]map[string]string, error)
- func ParsePropertyOverrides(props []string) (map[string]string, error)
- func ParseTime(str string) (time.Time, error)
- func ParseTimeRange(fromStr, toStr string) (time.Time, time.Time, error)
- func RenderActualCostOutput(ctx context.Context, cmd *cobra.Command, outputFormat string, ...) error
- func RenderBudgetStatus(w io.Writer, status *engine.BudgetStatus) error
- func RenderCostOutput(ctx context.Context, cmd *cobra.Command, outputFormat string, ...) error
- func RenderRecommendationsJSONForTest(w io.Writer, recs []TestableRecommendation) error
- func RenderRecommendationsNDJSONForTest(w io.Writer, recs []TestableRecommendation) error
- func RenderRecommendationsOutput(_ context.Context, cmd *cobra.Command, outputFormat string, ...) error
- func RenderRecommendationsSummaryForTest(w io.Writer, recs []TestableRecommendation)
- func RenderRecommendationsTableVerboseForTest(w io.Writer, recs []TestableRecommendation, verbose bool) error
- func RenderScopedBudgetStatus(w io.Writer, result *engine.ScopedBudgetResult, filter *BudgetScopeFilter) error
- func RunAnalyzerServe(cmd *cobra.Command) error
- func RunPluginInit(cmd *cobra.Command, opts *PluginInitOptions) error
- func ValidateBudgetFilter(filter string) error
- func ValidateDateRange(from, to time.Time) error
- func ValidateEstimateFlags(params *CostEstimateParams) error
- func ValidatePlugin(_ context.Context, plugin registry.PluginInfo) error
- func WithReleaseTagFetcher(fetcher func(context.Context) (string, error)) func(*FixtureResolver)
- type AnalyzerInstaller
- type AnalyzerInstallerFunc
- type BudgetExitError
- type BudgetRenderResult
- type BudgetScopeFilter
- type CostEstimateParams
- type CostFlags
- type FixtureResolver
- type FixtureSource
- type PluginInitOptions
- type PluginInstaller
- type PluginInstallerFunc
- type PluginJSONEntry
- type PromptResult
- type RecordedRequest
- type RecorderWorkflow
- func (w *RecorderWorkflow) CopyRecordedRequestsToTestdata(targetDir string) error
- func (w *RecorderWorkflow) PrepareOutputDirectory() error
- func (w *RecorderWorkflow) RunWithRecorder(ctx context.Context, planPath, statePath string, recordFixtures bool) error
- func (w *RecorderWorkflow) Session() *RecordingSession
- func (w *RecorderWorkflow) SetFixtureDirectory(path string)
- func (w *RecorderWorkflow) ValidateRecordings() error
- type RecordingSession
- type RouteMatchOutput
- type RouteRuleOutput
- type RoutesListOutput
- type RoutesTestOutput
- type SetupOptions
- type SetupResult
- type SetupRunner
- type StepResult
- type StepStatus
- type TestableRecommendation
- func ApplyActionTypeFilterForTest(recs []TestableRecommendation, filter string) ([]TestableRecommendation, error)
- func MergeDismissedRecommendationsForTest(recs []TestableRecommendation, storePath string) ([]TestableRecommendation, error)
- func SortRecommendationsBySavingsForTest(recs []TestableRecommendation) []TestableRecommendation
Constants ¶
const DirPermBase = 0o700
DirPermBase is the permission mode for the base and standard directories.
const DirPermPlugins = 0o750
DirPermPlugins is the permission mode for the plugins directory.
const MaxBudgetFilters = 100
MaxBudgetFilters is the maximum number of filter arguments allowed. This prevents potential DoS from excessive filter arguments.
const MaxBudgetTags = 50
MaxBudgetTags is the maximum number of tag filters allowed. This prevents memory exhaustion from unbounded tag map growth.
Variables ¶
var DefaultPlugins = []string{
"aws-public",
}
DefaultPlugins is the set of plugins installed by default during setup.
var ErrInvalidBudgetFilter = errors.New("invalid budget filter syntax")
ErrInvalidBudgetFilter is returned when a budget filter has invalid syntax.
var ErrPluginValidationFailed = errors.New("one or more plugins failed validation")
ErrPluginValidationFailed is returned when one or more plugins fail validation. This replaces os.Exit(1) to allow proper testing and error handling (SC-002 fix).
Functions ¶
func ApplyFilters ¶ added in v0.2.2
func ApplyFilters( ctx context.Context, resources []engine.ResourceDescriptor, filters []string, ) ([]engine.ResourceDescriptor, error)
ApplyFilters validates and applies a slice of filter strings to a resource set. It logs validation failures and filter application results for debugging.
The function performs two passes:
- Validation: All filters are validated upfront. If any filter is invalid, an error is returned immediately without applying any filters.
- Application: Valid filters are applied sequentially, reducing the resource set.
An empty filter slice returns the original resources unchanged. A warning is logged if the filtered result is empty.
Filter syntax follows engine.ValidateFilter rules: "key=value" format (e.g., "type=aws:ec2/instance", "tag:env=prod").
func DetectPluginMode ¶
DetectPluginMode determines if the application should run in Pulumi plugin mode. It checks the binary name and the FINFOCUS_PLUGIN_MODE environment variable. This is a pure function with no side effects and is safe to call multiple times.
args: usually os.Args (nil or empty is handled gracefully). lookupEnv: function to retrieve environment variables (e.g., os.LookupEnv).
If nil, environment variable detection is skipped.
func FormatStatus ¶ added in v0.3.0
func FormatStatus(status StepStatus, nonInteractive bool) string
FormatStatus returns a status marker appropriate for the output mode.
func HasStatusAnnotationsForTest ¶ added in v0.3.0
func HasStatusAnnotationsForTest(recs []TestableRecommendation) bool
HasStatusAnnotationsForTest is a test export for hasStatusAnnotations.
func InitCache ¶ added in v0.3.0
InitCache creates a cache.Cache instance based on configuration precedence: CLI flag (--cache-ttl) > env var (FINFOCUS_CACHE_TTL) > config file > default. Returns nil when caching is disabled (TTL<=0) or initialization fails. When --cache-ttl is explicitly set to 0, caching is disabled regardless of config/env.
func IsValidPluginName ¶
IsValidPluginName reports whether the provided name satisfies the plugin naming rules. The name must be between 2 and 50 characters, contain only lowercase letters (`a`–`z`), digits (`0`–`9`) or hyphens (`-`), and must not start or end with a hyphen. It returns true when all conditions are met, false otherwise.
func NewAnalyzerCheckCmd ¶ added in v0.3.2
NewAnalyzerCheckCmd creates the analyzer check command.
func NewAnalyzerCmd ¶
NewAnalyzerCmd creates the analyzer command group for Pulumi Analyzer plugin functionality.
The analyzer command provides subcommands for running FinFocus as a Pulumi Analyzer plugin. This enables zero-click cost estimation during `pulumi preview` operations.
func NewAnalyzerInstallCmd ¶ added in v0.3.0
NewAnalyzerInstallCmd creates the analyzer install command.
This command installs the finfocus binary as a Pulumi analyzer plugin by creating a symlink (Unix) or copy (Windows) in the Pulumi plugin directory.
func NewAnalyzerServeCmd ¶
NewAnalyzerServeCmd creates the analyzer serve command.
This command starts the gRPC server for the Pulumi Analyzer plugin. It binds to a random TCP port and prints ONLY the port number to stdout (this is the handshake protocol with Pulumi engine).
exclusively for the port handshake.
func NewAnalyzerUninstallCmd ¶ added in v0.3.0
NewAnalyzerUninstallCmd creates the analyzer uninstall command.
This command removes all installed analyzer-finfocus-v* directories from the Pulumi plugin directory.
func NewConfigGetCmd ¶
NewConfigGetCmd creates the config get command for retrieving configuration values.
func NewConfigInitCmd ¶
NewConfigInitCmd creates the config init command for initializing configuration. When run inside a Pulumi project (without --global), it creates a project-local .finfocus/ directory with config.yaml and .gitignore. Otherwise, it creates the global ~/.finfocus/config.yaml.
func NewConfigListCmd ¶
NewConfigListCmd creates the config list command for listing all configuration values.
func NewConfigRoutesCmd ¶ added in v0.3.3
NewConfigRoutesCmd returns a Cobra command that groups plugin routing subcommands. It has no RunE of its own — it delegates to the list and test subcommands.
func NewConfigRoutesListCmd ¶ added in v0.3.3
NewConfigRoutesListCmd returns a Cobra command that displays the effective routing configuration. It supports table (default) and JSON output formats via the --output flag.
func NewConfigRoutesTestCmd ¶ added in v0.3.3
NewConfigRoutesTestCmd returns a command that simulates plugin routing for a resource type.
func NewConfigSetCmd ¶
NewConfigSetCmd creates the config set command for setting configuration values.
func NewConfigValidateCmd ¶
NewConfigValidateCmd returns a Cobra command that validates the application's configuration. The command checks general configuration syntax and routing semantics, including plugin existence, pattern and feature validation, priority values, and duplicate plugin detection. The returned command accepts a --verbose / -v flag to emit detailed validation information.
func NewCostActualCmd ¶
NewCostActualCmd creates the "actual" subcommand for fetching actual historical costs.
The command retrieves historical costs from cloud provider billing APIs or estimates costs based on Pulumi preview JSON or Pulumi state timestamps. When neither --pulumi-json nor --pulumi-state is provided the current Pulumi project is auto-detected and `pulumi stack export` is used; in that mode the --from date is auto-detected from the earliest resource Created timestamp. Common flags registered include --pulumi-json, --pulumi-state, --from, --to, --adapter, --output, --group-by, --estimate-confidence, --fallback-estimate, --filter, and --jobs. Validation of flag combinations is performed by executeCostActual.
func NewCostEstimateCmd ¶ added in v0.3.0
NewCostEstimateCmd creates the "estimate" subcommand for what-if cost analysis.
The command supports two mutually exclusive modes:
1. Single-resource mode:
- --provider (required), --resource-type (required), --property (optional, repeatable)
- Estimates cost impact of property changes on a single resource
2. Plan-based mode:
- --pulumi-json (required), --modify (optional, repeatable)
- Estimates cost impact of modifications to resources in an existing Pulumi plan
Common flags:
- --output: Output format (table, json, ndjson)
- --interactive: Launch interactive TUI mode
- --region: Region for cost calculation
- --adapter: Use specific plugin adapter
Returns:
- *cobra.Command: The configured estimate subcommand
func NewCostProjectedCmd ¶
NewCostProjectedCmd returns a Cobra command configured to calculate projected costs from a Pulumi preview JSON and render the results in table, JSON, or NDJSON formats. The command accepts either an explicit Pulumi preview JSON file or will auto-detect and run a Pulumi preview in the current project when the --pulumi-json flag is omitted.
The command registers the following flags:
- --pulumi-json: optional path to a Pulumi preview JSON output (auto-detected if omitted).
- --spec-dir: directory containing pricing specification files.
- --adapter: restricts execution to a single adapter plugin.
- --output: output format ("table", "json", or "ndjson").
- --filter: repeatable resource filter expressions (e.g., "type=aws:ec2/instance").
- --utilization: utilization rate for sustainability calculations (0.0 to 1.0).
- --jobs, -j: number of parallel workers (0 = auto based on CPU count).
The returned command is ready to be added to the application's command tree.
func NewCostRecommendationsCmd ¶
NewCostRecommendationsCmd creates the "recommendations" subcommand that fetches cost optimization recommendations for resources described in a Pulumi preview JSON.
The command is configured with flags:
- --pulumi-json (required): path to Pulumi preview JSON output
- --adapter: restrict to a specific adapter plugin
- --output: output format (table, json, ndjson; defaults from configuration)
- --filter: filter expressions for recommendations (e.g., 'action=MIGRATE')
The returned *cobra.Command is ready to be added to the CLI command tree.
func NewOverviewCmd ¶ added in v0.3.0
NewOverviewCmd constructs the "overview" Cobra command that displays a unified stack cost dashboard combining Pulumi state and preview data with cost information, drift analysis, and recommendations. It supports auto-detection of the Pulumi project/stack or explicit --pulumi-state / --pulumi-json inputs, and is configured with flags for date range, adapter, output format, resource filtering, interactive/plain mode, pagination, confirmation behavior, and budget controls (exit-on-threshold, exit-code, budget-scope).
func NewPluginCertifyCmd ¶
NewPluginCertifyCmd creates the plugin certify command for running certification NewPluginCertifyCmd returns a Cobra command that runs the conformance suite against a plugin binary and generates a Markdown certification report. The command accepts a single plugin path argument and provides flags to control output and execution:
- --output, -o: path to write the certification report (default: stdout)
- --mode: communication mode, either "tcp" or "stdio" (default: "tcp")
- --timeout: global certification timeout as a duration string (default: "10m")
The command prints progress and a summary; it exits with a non-zero code when certification is not achieved.
func NewPluginConformanceCmd ¶
NewPluginConformanceCmd creates the plugin conformance command for running NewPluginConformanceCmd returns a Cobra command configured to run conformance tests against a plugin binary. The command verifies a plugin's protocol compliance and supports the following flags: --mode (tcp|stdio), --verbosity (quiet|normal|verbose|debug), --output (table|json|junit), --output-file, --timeout, --category (repeatable: protocol, error, performance, context), and --filter (regex for test names).
func NewPluginInitCmd ¶
NewPluginInitCmd builds the Cobra command that scaffolds a plugin project and writes NewPluginInitCmd creates and returns a Cobra command for initializing a plugin development project. The command exposes "init <plugin-name>" and scaffolds a new plugin project including module setup, manifest, boilerplate source, Makefile, README, and example tests. It registers flags for author, providers, output directory, force overwrite, and fixture recording options (`--record-fixtures`, `--fixture-version`, `--offline`, `--strict`) and marks the author and providers flags as required.
func NewPluginInspectCmd ¶
NewPluginInspectCmd creates the plugin inspect command.
func NewPluginInstallCmd ¶
NewPluginInstallCmd creates the install command for installing plugins from registry or URL.
--plugin-dir Custom plugin directory (default: ~/.finfocus/plugins) --clean Remove other versions after successful install --fallback-to-latest Automatically install latest stable version if requested version lacks assets
NewPluginInstallCmd creates the "install" CLI command that installs a plugin from either the registry or a direct URL.
The returned *cobra.Command parses a single plugin specifier argument and supports options to control installation behavior, including reinstallation, saving to config, cleanup of other versions, custom plugin directory, and controlling fallback behavior when platform-specific assets are missing. It also accepts repeatable metadata key=value pairs that are passed through to the installer.
Notable flags:
- --force, -f: reinstall even if the requested version already exists.
- --no-save: do not add the plugin to the user's config file.
- --clean: remove other installed versions after a successful install.
- --plugin-dir: specify a custom plugin installation directory.
- --fallback-to-latest: automatically attempt a compatible latest stable release if the requested version lacks assets.
- --no-fallback: disable fallback behavior entirely (mutually exclusive with --fallback-to-latest).
- --metadata: repeatable key=value pairs attached to the plugin install.
The command prints progress, shows a security warning for URL-based installs, and displays a concise install result. NewPluginInstallCmd creates the "install" subcommand for installing plugins from a registry or URL. The command accepts a single plugin specifier argument and configures flags for force reinstall, skipping save, cleaning other versions, custom plugin directory, fallback controls, and repeatable metadata key=value pairs. The command validates the specifier, displays security warnings when appropriate, parses metadata, constructs an installer, attempts installation (with fallback and cleanup behavior controlled by flags), and prints progress and results. It returns the configured *cobra.Command.
func NewPluginListCmd ¶
NewPluginListCmd creates a Cobra "list" command for displaying plugins. The command lists installed plugins by default and supports an `--verbose` flag for detailed output and an `--available` flag to list plugins from the registry. It returns the configured *cobra.Command.
func NewPluginRemoveCmd ¶
NewPluginRemoveCmd returns a Cobra command configured to remove an installed plugin. The command accepts a single plugin name argument and provides the flags `--keep-config` to retain the plugin entry in the configuration and `--plugin-dir` to specify a custom plugin directory. On execution it removes the plugin files and, unless `--keep-config` is set, removes the plugin entry from the configuration. The command's execution returns an error if removal fails.
func NewPluginUpdateCmd ¶
NewPluginUpdateCmd returns a Cobra command that updates an installed plugin to the latest or a specified version. The command requires a single positional argument (plugin name) and provides the following flags:
--dry-run Show what would be updated without making changes. --version Specific version to update to (default: latest). --plugin-dir Custom plugin directory.
NewPluginUpdateCmd returns a cobra command that updates an installed plugin to the latest version or to a specified version. The command accepts a single plugin name argument and supports the flags --dry-run (show changes without applying), --version (target version), and --plugin-dir (custom plugin directory). It prints progress messages and a summary of the result (including name, old/new versions, and path).
The command's execution returns an error if the underlying installer fails to perform the NewPluginUpdateCmd returns a *cobra.Command configured to update an installed plugin. The command expects a single positional argument (plugin name) and updates that plugin to the latest version or to a specific version supplied via the --version flag. It supports --dry-run to preview changes and --plugin-dir to override the plugin directory. The command prints progress and summary information and returns an error if the update operation fails.
func NewPluginValidateCmd ¶
NewPluginValidateCmd creates the plugin validate command for validating plugin installations.
func NewRootCmd ¶
NewRootCmd creates the root Cobra command for the finfocus CLI. It wires up logging, tracing, audit logging, and subcommands (cost, plugin, config, analyzer, overview, setup). The command dynamically adjusts its Use and Example strings based on whether it's running as a Pulumi tool plugin (detected via binary name or FINFOCUS_PLUGIN_MODE env var).
func NewRootCmdWithArgs ¶
func NewRootCmdWithArgs( ver string, args []string, lookupEnv func(string) (string, bool), ) *cobra.Command
NewRootCmdWithArgs creates the root command with explicit args and env lookup for testability. This allows tests to inject custom args and environment variables.
func NewSetupCmd ¶ added in v0.3.0
NewSetupCmd creates the top-level setup command that bootstraps the FinFocus environment.
func NewSetupCmdWithRunner ¶ added in v0.3.0
func NewSetupCmdWithRunner(runner *SetupRunner) *cobra.Command
NewSetupCmdWithRunner creates the setup command with the given runner for dependency injection.
func ParseBudgetFilters ¶ added in v0.3.0
ParseBudgetFilters parses a slice of filter strings into BudgetFilterOptions. Filter syntax:
- "provider=<name>": Filter by provider (e.g., "provider=kubecost")
- "tag:<key>=<value>": Filter by metadata tag (e.g., "tag:namespace=production")
Provider filters use OR logic (any provider matches). Tag filters use AND logic (all tags must match). Tag values support glob patterns (e.g., "tag:namespace=prod-*").
Returns an error if any filter has invalid syntax per ValidateBudgetFilter, or if input limits are exceeded (MaxBudgetFilters, MaxBudgetTags).
func ParseModifications ¶ added in v0.3.0
ParseModifications parses --modify resource:key=value flags into a map. Exported for testing.
Parameters:
- mods: Slice of strings in "resource:key=value" format
Returns:
- map[string]map[string]string: Map of resource name to property overrides
- error: If any modification has invalid format or exceeds limits
func ParsePropertyOverrides ¶ added in v0.3.0
ParsePropertyOverrides parses --property key=value flags into a map. Exported for testing.
Parameters:
- props: Slice of strings in "key=value" format
Returns:
- map[string]string: Parsed key-value pairs
- error: If any property has invalid format or exceeds limits
func ParseTime ¶
ParseTime parses str as a date in either "YYYY-MM-DD" or RFC3339 format. It validates that the parsed time is not in the future and is not more than maxPastYears years in the past.
func ParseTimeRange ¶
ParseTimeRange parses the provided from and to date strings into time values and validates that the range is chronological.
ParseTimeRange accepts two date strings, parses each into a time.Time, and ensures the 'to' time is after the 'from' time. It returns the parsed from and to times on success. If either date cannot be parsed or if the 'to' time is not after the 'from' time, an error is returned describing the failure. Additionally validates that the date range does not exceed maximum limits.
func RenderActualCostOutput ¶
func RenderActualCostOutput( ctx context.Context, cmd *cobra.Command, outputFormat string, resultWithErrors *engine.CostResultWithErrors, groupBy string, estimateConfidence bool, ) error
RenderActualCostOutput routes actual cost results to the appropriate rendering function. The context parameter enables trace ID propagation for contextual logging.
func RenderBudgetStatus ¶ added in v0.2.4
func RenderBudgetStatus(w io.Writer, status *engine.BudgetStatus) error
RenderBudgetStatus renders the budget status to the writer. It automatically detects if the output is a TTY and renders appropriately: - TTY: Styled output with colors and borders using Lip Gloss. RenderBudgetStatus renders the given budget status to w using a terminal-styled bordered box when w is a TTY or plain text suitable for non-interactive outputs otherwise.
w is the destination for the rendered output. status is the budget status to render; if status is nil, the function performs no output and returns nil.
The function returns any error produced by the chosen rendering implementation.
func RenderCostOutput ¶
func RenderCostOutput( ctx context.Context, cmd *cobra.Command, outputFormat string, resultWithErrors *engine.CostResultWithErrors, ) error
RenderCostOutput routes the cost results to the appropriate rendering function based on the detected output mode (Plain, Styled, or Interactive). The context parameter enables trace ID propagation for contextual logging.
func RenderRecommendationsJSONForTest ¶
func RenderRecommendationsJSONForTest(w io.Writer, recs []TestableRecommendation) error
RenderRecommendationsJSONForTest is a test export for renderRecommendationsJSON.
func RenderRecommendationsNDJSONForTest ¶
func RenderRecommendationsNDJSONForTest(w io.Writer, recs []TestableRecommendation) error
RenderRecommendationsNDJSONForTest is a test export for renderRecommendationsNDJSON.
func RenderRecommendationsOutput ¶
func RenderRecommendationsOutput( _ context.Context, cmd *cobra.Command, outputFormat string, result *engine.RecommendationsResult, verbose bool, paginationMeta *pagination.PaginationMeta, ) error
RenderRecommendationsOutput routes the recommendations results to the appropriate rendering function based on the output format and terminal mode. In interactive terminals, it launches the TUI; otherwise, it renders table output. Returns an error if result is nil.
func RenderRecommendationsSummaryForTest ¶
func RenderRecommendationsSummaryForTest(w io.Writer, recs []TestableRecommendation)
RenderRecommendationsSummaryForTest is a test export for renderRecommendationsSummary.
func RenderRecommendationsTableVerboseForTest ¶
func RenderRecommendationsTableVerboseForTest(w io.Writer, recs []TestableRecommendation, verbose bool) error
RenderRecommendationsTableVerboseForTest is a test export for renderRecommendationsTableWithVerbose.
func RenderScopedBudgetStatus ¶ added in v0.2.6
func RenderScopedBudgetStatus(w io.Writer, result *engine.ScopedBudgetResult, filter *BudgetScopeFilter) error
RenderScopedBudgetStatus renders the hierarchical scoped budget result to the writer. It automatically detects if the output is a TTY and renders appropriately.
func RunAnalyzerServe ¶
RunAnalyzerServe starts the Pulumi Analyzer gRPC server, writes the selected listening port to stdout for the Pulumi plugin handshake, and runs until the RunAnalyzerServe starts a Pulumi gRPC analyzer server, prints the assigned port number to stdout for the Pulumi plugin handshake, and blocks until shutdown.
The provided Cobra command's context is used for cancellation. The function installs signal handlers for SIGINT and SIGTERM and performs a graceful shutdown when a termination signal is received or when the command context is canceled. It also sets the analyzer mode environment variable to indicate analyzer-only operation and may load project-specific configuration and plugins as part of server setup.
Parameters:
- cmd: the Cobra command whose context controls lifecycle and cancellation.
Returns:
- an error if the server fails to bind to a TCP port, if the listener's address cannot be determined, or if the gRPC server fails while serving; returns nil on normal graceful shutdown.
func RunPluginInit ¶
func RunPluginInit(cmd *cobra.Command, opts *PluginInitOptions) error
RunPluginInit validates the provided PluginInitOptions, creates the target project directory (honoring the force flag), generates the boilerplate project files, and prints progress and next-step instructions to the command output. RunPluginInit initializes a new plugin project on disk and scaffolds all required files.
RunPluginInit validates the plugin name and provider list, creates the project directory, generates project files, and optionally runs a fixture recording workflow to populate testdata. It prints progress and next-step instructions to the provided Cobra command's output.
cmd is the Cobra command used for printing progress and for deriving context. opts provides initialization options such as Name, Author, Providers, OutputDir, Force, and flags controlling fixture recording.
It returns an error if validation fails (invalid name or no providers), if the project directory cannot be created, if file generation fails, or if the optional fixture recording workflow fails when the Strict option is set.
func ValidateBudgetFilter ¶ added in v0.3.0
ValidateBudgetFilter validates a single budget filter string. Valid formats:
- "provider=<value>": Provider filter (value required)
- "tag:<key>=<value>": Tag filter (key required, value can be empty, supports glob patterns)
Returns an error for invalid syntax:
- Missing "=" in tag filter
- Empty key after "tag:"
- Invalid glob pattern in tag value
- Unknown filter prefix
func ValidateDateRange ¶
ValidateDateRange validates that the date range is within acceptable limits. Returns an error if the range exceeds maxDateRangeDays (approximately 1 year).
func ValidateEstimateFlags ¶ added in v0.3.0
func ValidateEstimateFlags(params *CostEstimateParams) error
ValidateEstimateFlags validates that the estimate command flags are consistent. Exported for testing.
Rules:
- Single-resource mode requires both --provider and --resource-type
- Plan-based mode requires --pulumi-json
- --property is only valid in single-resource mode
- --modify is only valid in plan-based mode
- Modes are mutually exclusive
Returns an error describing the validation failure, or nil if valid.
func ValidatePlugin ¶
func ValidatePlugin(_ context.Context, plugin registry.PluginInfo) error
ValidatePlugin validates a plugin's binary and its optional manifest. It ensures the binary exists at plugin.Path, is not a directory, and has the executable bit set. If a manifest file named "plugin.manifest.json" exists in the same directory, it is loaded and its Name and Version fields are compared to plugin.Name and plugin.Version. The function returns nil when all checks pass; otherwise it returns an error describing the first failing check (missing binary, stat error, path is a directory, not executable, invalid manifest, or manifest name/version mismatch).
ctx is reserved for future use and is not inspected. plugin provides the plugin's Path, Name, and Version used for validation.
func WithReleaseTagFetcher ¶ added in v0.2.4
func WithReleaseTagFetcher( fetcher func(context.Context) (string, error), ) func(*FixtureResolver)
WithReleaseTagFetcher configures a custom release tag fetcher function.
Types ¶
type AnalyzerInstaller ¶ added in v0.3.0
type AnalyzerInstaller interface {
Install(ctx context.Context, opts analyzer.InstallOptions) (*analyzer.InstallResult, error)
}
AnalyzerInstaller is the interface for installing the Pulumi analyzer.
type AnalyzerInstallerFunc ¶ added in v0.3.0
type AnalyzerInstallerFunc func(ctx context.Context, opts analyzer.InstallOptions) (*analyzer.InstallResult, error)
AnalyzerInstallerFunc is a function adapter for AnalyzerInstaller.
func (AnalyzerInstallerFunc) Install ¶ added in v0.3.0
func (f AnalyzerInstallerFunc) Install( ctx context.Context, opts analyzer.InstallOptions, ) (*analyzer.InstallResult, error)
Install delegates to the underlying function.
type BudgetExitError ¶ added in v0.2.5
BudgetExitError is a sentinel error that carries an exit code for budget threshold violations. It is used to communicate the exit code from budget evaluation to the CLI layer.
func (*BudgetExitError) Error ¶ added in v0.2.5
func (e *BudgetExitError) Error() string
type BudgetRenderResult ¶ added in v0.2.6
type BudgetRenderResult struct {
// LegacyStatus is set when using legacy budget configuration.
LegacyStatus *engine.BudgetStatus
// ScopedResult is set when using scoped budget configuration.
ScopedResult *engine.ScopedBudgetResult
}
BudgetRenderResult holds the result of budget rendering for exit code evaluation. It can contain either a legacy BudgetStatus or a ScopedBudgetResult.
type BudgetScopeFilter ¶ added in v0.2.6
type BudgetScopeFilter struct {
// ShowGlobal displays the global budget section.
ShowGlobal bool
// ShowProvider displays the BY PROVIDER section.
ShowProvider bool
// ShowTag displays the BY TAG section.
ShowTag bool
// ShowType displays the BY TYPE section.
ShowType bool
// ProviderFilter limits provider display to specific providers.
ProviderFilter []string
// TagFilter limits tag display to specific tag selectors.
TagFilter []string
// TypeFilter limits type display to specific resource types.
TypeFilter []string
}
BudgetScopeFilter defines which budget scopes to render.
func NewBudgetScopeFilter ¶ added in v0.2.6
func NewBudgetScopeFilter(scopeFlag string) *BudgetScopeFilter
NewBudgetScopeFilter creates a filter from a --budget-scope flag value. Empty string means show all scopes. Otherwise, accepts comma-separated values: - "global" - show global budget only - "provider" - show BY PROVIDER section - "provider=aws" - show only AWS provider budget - "tag" - show BY TAG section - "tag=team:platform" - show only the specific tag budget - "type" - show BY TYPE section - "type=aws:ec2/instance" - show only the specific resource type budget.
type CostEstimateParams ¶ added in v0.3.0
type CostEstimateParams struct {
// Single-resource mode flags
Provider string
ResourceType string
Properties []string // key=value format
Region string
// Plan-based mode flags
PlanPath string
Modify []string // resource:key=value format
// Common flags
Interactive bool
Output string
Adapter string
}
CostEstimateParams holds the parameters for the estimate cost command execution. Exported for testing.
type CostFlags ¶ added in v0.2.5
type CostFlags struct {
ExitOnThreshold bool
ExitCode int
BudgetScope string // Filter which budget scopes to display (T025)
Stack string // Pulumi stack name for auto-detection
}
CostFlags holds the budget exit flags for the cost command group. These are persistent flags that apply to all cost subcommands.
type FixtureResolver ¶ added in v0.2.4
type FixtureResolver struct {
// contains filtered or unexported fields
}
func NewFixtureResolver ¶ added in v0.2.4
func NewFixtureResolver( logger zerolog.Logger, offline bool, version, localBase string, opts ...func(*FixtureResolver), ) *FixtureResolver
NewFixtureResolver creates a FixtureResolver configured to resolve fixtures.
logger is used for structured logging. offline toggles local-only resolution when true. version selects the fixture version to resolve (e.g., "latest", a tag, "main", or "local"). localBase sets the base filesystem path to search for local fixtures. opts are optional configuration functions that can customize the resolver behavior.
The returned FixtureResolver is ready to resolve and (when not offline) download fixture sources.
func (*FixtureResolver) DownloadFixture ¶ added in v0.2.4
func (r *FixtureResolver) DownloadFixture(ctx context.Context, source *FixtureSource) (string, error)
func (*FixtureResolver) ResolvePlanFixture ¶ added in v0.2.4
func (r *FixtureResolver) ResolvePlanFixture(ctx context.Context, provider string) (*FixtureSource, error)
func (*FixtureResolver) ResolveStateFixture ¶ added in v0.2.4
func (r *FixtureResolver) ResolveStateFixture(ctx context.Context) (*FixtureSource, error)
type FixtureSource ¶ added in v0.2.4
type PluginInitOptions ¶
type PluginInitOptions struct {
Name string
Author string
Providers []string
OutputDir string
Force bool
RecordFixtures bool
FixtureVersion string
Offline bool
Strict bool
}
PluginInitOptions contains configuration options for plugin initialization.
type PluginInstaller ¶ added in v0.3.0
type PluginInstaller interface {
Install(
ctx context.Context,
specifier string,
opts registry.InstallOptions,
progress func(string),
) (*registry.InstallResult, error)
}
PluginInstaller is the interface for installing plugins.
type PluginInstallerFunc ¶ added in v0.3.0
type PluginInstallerFunc func( ctx context.Context, specifier string, opts registry.InstallOptions, progress func(string), ) (*registry.InstallResult, error)
PluginInstallerFunc is a function adapter for PluginInstaller.
func (PluginInstallerFunc) Install ¶ added in v0.3.0
func (f PluginInstallerFunc) Install( ctx context.Context, specifier string, opts registry.InstallOptions, progress func(string), ) (*registry.InstallResult, error)
Install delegates to the underlying function.
type PluginJSONEntry ¶ added in v0.3.0
type PluginJSONEntry struct {
Name string `json:"name"`
Version string `json:"version"`
Path string `json:"path"`
SpecVersion string `json:"specVersion"`
RuntimeVersion string `json:"runtimeVersion"`
SupportedProviders []string `json:"supportedProviders"`
Capabilities []string `json:"capabilities"`
Notes string `json:"notes,omitempty"`
}
PluginJSONEntry is the JSON-serializable representation of a plugin for the --output json format. It matches the plugin-list-json contract schema.
type PromptResult ¶ added in v0.2.3
type PromptResult struct {
// Accepted is true if the user accepted the prompt (typed "y" or "Y")
Accepted bool
// TimedOut is true if the prompt timed out waiting for input (reserved for future use)
TimedOut bool
// Cancelled is true if the user explicitly cancelled (e.g., Ctrl+C)
Cancelled bool
}
PromptResult contains the result of a user prompt interaction.
func ConfirmFallback ¶ added in v0.2.3
func ConfirmFallback( writer io.Writer, reader io.Reader, pluginName string, requestedVersion string, fallbackVersion string, platform string, ) PromptResult
ConfirmFallback prompts the user to confirm fallback to an alternative version. It returns immediately with Accepted=false in non-interactive (non-TTY) environments.
Parameters:
- writer: where to write the prompt message (typically cmd.OutOrStdout())
- reader: where to read user input from (typically os.Stdin)
- pluginName: name of the plugin being installed
- requestedVersion: the version originally requested
- fallbackVersion: the version being offered as fallback
- platform: the platform string (e.g., "linux/amd64")
The prompt defaults to "No" (abort) when the user presses Enter without input. Valid inputs: "y", "Y", "yes", "Yes", "YES" for acceptance; anything else declines.
func ConfirmFallbackWithStdin ¶ added in v0.2.3
func ConfirmFallbackWithStdin( writer io.Writer, pluginName string, requestedVersion string, fallbackVersion string, platform string, ) PromptResult
ConfirmFallbackWithStdin is a convenience wrapper that uses os.Stdin as the reader.
type RecordedRequest ¶ added in v0.2.4
type RecorderWorkflow ¶ added in v0.2.4
type RecorderWorkflow struct {
// contains filtered or unexported fields
}
func NewRecorderWorkflow ¶ added in v0.2.4
func NewRecorderWorkflow(logger zerolog.Logger, outputDir string) *RecorderWorkflow
NewRecorderWorkflow creates a RecorderWorkflow configured with the provided logger and output directory. It initializes an internal RecordingSession with a generated session ID, the given output directory, the current start time, and a status of "initialized". logger is used for workflow logging. outputDir is the base directory where recorded request files and session data will be placed. It returns a pointer to the constructed RecorderWorkflow.
func (*RecorderWorkflow) CopyRecordedRequestsToTestdata ¶ added in v0.2.4
func (w *RecorderWorkflow) CopyRecordedRequestsToTestdata(targetDir string) error
func (*RecorderWorkflow) PrepareOutputDirectory ¶ added in v0.2.4
func (w *RecorderWorkflow) PrepareOutputDirectory() error
func (*RecorderWorkflow) RunWithRecorder ¶ added in v0.2.4
func (*RecorderWorkflow) Session ¶ added in v0.2.4
func (w *RecorderWorkflow) Session() *RecordingSession
func (*RecorderWorkflow) SetFixtureDirectory ¶ added in v0.2.4
func (w *RecorderWorkflow) SetFixtureDirectory(path string)
func (*RecorderWorkflow) ValidateRecordings ¶ added in v0.2.4
func (w *RecorderWorkflow) ValidateRecordings() error
type RecordingSession ¶ added in v0.2.4
type RecordingSession struct {
ID string `json:"id"`
OutputDir string `json:"output_dir"`
FixtureDir string `json:"fixture_dir"`
StartedAt time.Time `json:"started_at"`
CompletedAt time.Time `json:"completed_at"`
Status string `json:"status"`
Errors []string `json:"errors,omitempty"`
Recorded []RecordedRequest `json:"recorded,omitempty"`
}
type RouteMatchOutput ¶ added in v0.3.3
type RouteMatchOutput struct {
Rank int `json:"rank"`
Plugin string `json:"plugin"`
Priority int `json:"priority"`
MatchReason string `json:"match_reason"`
Source string `json:"source"`
Fallback bool `json:"fallback"`
}
RouteMatchOutput represents a single plugin match in the test output.
type RouteRuleOutput ¶ added in v0.3.3
type RouteRuleOutput struct {
Plugin string `json:"plugin"`
Priority int `json:"priority"`
Features []string `json:"features"`
Patterns []string `json:"patterns"`
Fallback bool `json:"fallback"`
}
RouteRuleOutput represents a single routing rule in the list output.
type RoutesListOutput ¶ added in v0.3.3
type RoutesListOutput struct {
Mode string `json:"mode"`
ConfigPath string `json:"config_path"`
Source string `json:"source"`
Rules []RouteRuleOutput `json:"rules"`
}
RoutesListOutput is the JSON output structure for the config routes list command.
type RoutesTestOutput ¶ added in v0.3.3
type RoutesTestOutput struct {
ResourceType string `json:"resource_type"`
Region string `json:"region,omitempty"`
Provider string `json:"provider"`
Mode string `json:"mode"`
Matches []RouteMatchOutput `json:"matches"`
Features map[string]string `json:"features"`
}
RoutesTestOutput is the JSON output structure for the config routes test command.
type SetupOptions ¶ added in v0.3.0
type SetupOptions struct {
SkipAnalyzer bool `json:"skipAnalyzer,omitempty" yaml:"skipAnalyzer,omitempty"`
SkipPlugins bool `json:"skipPlugins,omitempty" yaml:"skipPlugins,omitempty"`
NonInteractive bool `json:"nonInteractive,omitempty" yaml:"nonInteractive,omitempty"`
}
SetupOptions holds the configuration for the setup command, derived from CLI flags.
type SetupResult ¶ added in v0.3.0
type SetupResult struct {
Steps []StepResult `json:"steps,omitempty" yaml:"steps,omitempty"`
HasErrors bool `json:"hasErrors,omitempty" yaml:"hasErrors,omitempty"`
HasWarnings bool `json:"hasWarnings,omitempty" yaml:"hasWarnings,omitempty"`
}
SetupResult is the aggregate outcome of all setup steps.
type SetupRunner ¶ added in v0.3.0
type SetupRunner struct {
AnalyzerInstaller AnalyzerInstaller
PluginInstaller PluginInstaller
}
SetupRunner holds injectable dependencies for setup steps that require external services (analyzer installation, plugin installation).
func NewSetupRunner ¶ added in v0.3.0
func NewSetupRunner() *SetupRunner
NewSetupRunner returns a SetupRunner wired with production defaults.
func (*SetupRunner) StepInstallAnalyzer ¶ added in v0.3.0
func (r *SetupRunner) StepInstallAnalyzer(ctx context.Context) StepResult
StepInstallAnalyzer installs the Pulumi analyzer using the runner's AnalyzerInstaller.
func (*SetupRunner) StepInstallPlugins ¶ added in v0.3.0
func (r *SetupRunner) StepInstallPlugins(ctx context.Context, baseDir string) []StepResult
StepInstallPlugins installs the default plugin set. Returns one StepResult per plugin in the default set. baseDir is the resolved FinFocus home directory (e.g., ~/.finfocus).
type StepResult ¶ added in v0.3.0
type StepResult struct {
Name string `json:"name" yaml:"name"`
Status StepStatus `json:"status" yaml:"status"`
Message string `json:"message" yaml:"message"`
Critical bool `json:"critical,omitempty" yaml:"critical,omitempty"`
Err error `json:"-" yaml:"-"`
}
StepResult describes the outcome of executing a single setup step.
func StepCreateDirectories ¶ added in v0.3.0
func StepCreateDirectories(baseDir string) []StepResult
StepCreateDirectories creates the required FinFocus directories. Returns one StepResult per directory.
func StepDetectPulumi ¶ added in v0.3.0
func StepDetectPulumi(ctx context.Context) StepResult
StepDetectPulumi checks if the pulumi CLI is on PATH and reports its version.
func StepDisplayVersion ¶ added in v0.3.0
func StepDisplayVersion() StepResult
StepDisplayVersion prints the FinFocus version and Go runtime info.
func StepInitConfig ¶ added in v0.3.0
func StepInitConfig(baseDir string) StepResult
StepInitConfig initializes the default config file if one does not exist.
type StepStatus ¶ added in v0.3.0
type StepStatus int
StepStatus represents the outcome of a single setup step.
const ( // StepSuccess indicates the step completed successfully. StepSuccess StepStatus = iota // StepWarning indicates the step completed with a non-fatal issue. StepWarning // StepSkipped indicates the step was intentionally skipped via flag. StepSkipped // StepError indicates the step failed. StepError )
func (StepStatus) MarshalJSON ¶ added in v0.3.0
func (s StepStatus) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler to output StepStatus as a string.
func (StepStatus) String ¶ added in v0.3.0
func (s StepStatus) String() string
String returns the human-readable label for a StepStatus.
func (*StepStatus) UnmarshalJSON ¶ added in v0.3.0
func (s *StepStatus) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler to parse StepStatus from a string.
type TestableRecommendation ¶
type TestableRecommendation struct {
ResourceID string
Type string
Description string
EstimatedSavings float64
Currency string
Status string
}
TestableRecommendation is a test-friendly version of engine.Recommendation. It's used to avoid circular imports in tests.
func ApplyActionTypeFilterForTest ¶
func ApplyActionTypeFilterForTest( recs []TestableRecommendation, filter string, ) ([]TestableRecommendation, error)
ApplyActionTypeFilterForTest is a test export for applyActionTypeFilter.
func MergeDismissedRecommendationsForTest ¶ added in v0.3.0
func MergeDismissedRecommendationsForTest( recs []TestableRecommendation, storePath string, ) ([]TestableRecommendation, error)
MergeDismissedRecommendationsForTest is a test export for mergeDismissedRecommendations.
func SortRecommendationsBySavingsForTest ¶
func SortRecommendationsBySavingsForTest(recs []TestableRecommendation) []TestableRecommendation
SortRecommendationsBySavingsForTest is a test export for sortRecommendationsBySavings.
Source Files
¶
- analyzer.go
- analyzer_check.go
- analyzer_install.go
- analyzer_serve.go
- analyzer_uninstall.go
- common_execution.go
- config_get.go
- config_init.go
- config_list.go
- config_routes.go
- config_set.go
- config_validate.go
- constants.go
- cost_actual.go
- cost_budget.go
- cost_budget_render.go
- cost_estimate.go
- cost_projected.go
- cost_recommendations.go
- cost_recommendations_dismiss.go
- cost_recommendations_history.go
- cost_recommendations_testhelpers.go
- cost_recommendations_undismiss.go
- cost_tui.go
- doc.go
- filters.go
- logging_setup.go
- mode.go
- output_mode.go
- overview.go
- plugin_certify.go
- plugin_conformance.go
- plugin_init.go
- plugin_init_fixtures.go
- plugin_init_recording.go
- plugin_inspect.go
- plugin_install.go
- plugin_list.go
- plugin_remove.go
- plugin_update.go
- plugin_validate.go
- prompt.go
- root.go
- setup.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package pagination provides utilities for CLI pagination, sorting, and result formatting.
|
Package pagination provides utilities for CLI pagination, sorting, and result formatting. |