Documentation
¶
Overview ¶
Package router provides intelligent plugin routing for FinFocus cost calculations. It implements automatic provider-based routing and declarative pattern-based routing, enabling multi-cloud cost analysis with configurable plugin selection.
Index ¶
- Constants
- func AllEqualPriority(matches []PluginMatch) bool
- func ExtractProviderFromType(resourceType string) string
- func ExtractResourceRegion(resource engine.ResourceDescriptor) string
- func IsGlobalProvider(provider string) bool
- func IsInternalPulumiType(resourceType string) bool
- func IsPulumiComponentResource(resourceType string) bool
- func IsPulumiProviderResource(resourceType string) bool
- func IsValidFeature(name string) bool
- func NewEngineAdapter(r Router) engine.Router
- func NormalizeProvider(provider string) string
- func PluginRegion(client *pluginhost.Client) string
- func ProviderMatches(resourceProvider, supportedProvider string) bool
- func RegionMatches(pluginRegion, resourceRegion string) bool
- func ValidFeatureNames() []string
- type CompiledPattern
- type DefaultRouter
- type EngineAdapter
- type Feature
- type MatchReason
- type Option
- type PatternCache
- func (c *PatternCache) Clear()
- func (c *PatternCache) Match(pattern config.ResourcePattern, resourceType string) (bool, error)
- func (c *PatternCache) MatchGlob(pattern, resourceType string) (bool, error)
- func (c *PatternCache) MatchRegex(pattern, resourceType string) (bool, error)
- func (c *PatternCache) Size() int
- type PluginMatch
- type Router
- type ValidationError
- type ValidationResult
- type ValidationWarning
Constants ¶
const ( // PulumiInternalPrefix identifies all internal Pulumi resource types. // Resources with this prefix represent Pulumi framework constructs // rather than cloud infrastructure and have no associated cloud cost. PulumiInternalPrefix = "pulumi:" // PulumiProviderPrefix identifies Pulumi provider resources // (e.g., "pulumi:providers:aws", "pulumi:providers:gcp"). PulumiProviderPrefix = "pulumi:providers:" // PulumiComponentPrefix identifies Pulumi component resources // (e.g., "pulumi:pulumi:Stack"). PulumiComponentPrefix = "pulumi:pulumi:" )
const ProviderUnknown = "unknown"
ProviderUnknown is the sentinel value for resources with indeterminate providers.
const ProviderWildcard = "*"
ProviderWildcard represents a plugin that handles all providers.
Variables ¶
This section is empty.
Functions ¶
func AllEqualPriority ¶
func AllEqualPriority(matches []PluginMatch) bool
AllEqualPriority returns true if all matches have the same priority. AllEqualPriority reports whether all PluginMatch entries in the slice have the same Priority. It returns true for slices with zero or one element, or when every element's Priority equals the first element's Priority; otherwise it returns false.
func ExtractProviderFromType ¶
ExtractProviderFromType extracts the provider name from a Pulumi resource type string.
Resource types follow the format "provider:service/module:Type" where:
- provider: Cloud provider identifier (aws, gcp, azure, kubernetes)
- service/module: Service or module within the provider
- Type: The specific resource type
Examples:
- "aws:ec2/instance:Instance" → "aws"
- "gcp:compute:Instance" → "gcp"
- "azure:compute/vm:VM" → "azure"
- "kubernetes:core/v1:Pod" → "kubernetes"
- "aws-native:ec2:Instance" → "aws-native"
- "pulumi:providers:aws" → "pulumi"
- "" → "unknown"
The function extracts the first colon-separated segment as the provider. ExtractProviderFromType returns the provider name from a Pulumi resource type string. It extracts the first colon-separated segment of resourceType (the provider prefix). If resourceType is empty or does not contain a non-empty first segment, it returns ProviderUnknown.
resourceType is the Pulumi resource type string (e.g. "aws:s3/bucket:Bucket"). The returned string is the provider name (e.g. "aws") or the ProviderUnknown sentinel when indeterminate.
func ExtractResourceRegion ¶ added in v0.3.0
func ExtractResourceRegion(resource engine.ResourceDescriptor) string
ExtractResourceRegion extracts the region associated with the given resource descriptor. It checks common properties (region, availabilityZone, availability_zone, location) and normalizes availability zones to their region form; if none are present it attempts to parse a region from the resource's ARN or id. The returned string is the region (for example "us-west-2"), or an empty string if no region can be determined.
func IsGlobalProvider ¶
IsGlobalProvider checks if the provider value indicates a global plugin. IsGlobalProvider reports whether the provider string denotes a global plugin. It returns true when the provider is empty or equals ProviderWildcard ("*").
func IsInternalPulumiType ¶ added in v0.3.0
IsInternalPulumiType reports whether resourceType is an internal Pulumi resource type (prefixed with "pulumi:") that should not be routed to cost plugins by default.
Internal types include provider resources (pulumi:providers:*) and component resources (pulumi:pulumi:*). These represent Pulumi framework constructs with no associated cloud cost.
A future "pulumi cost plugin" can still opt-in to handle these types via declarative routing patterns.
func IsPulumiComponentResource ¶ added in v0.3.0
IsPulumiComponentResource reports whether resourceType is a Pulumi component resource (e.g., "pulumi:pulumi:Stack").
func IsPulumiProviderResource ¶ added in v0.3.0
IsPulumiProviderResource reports whether resourceType is a Pulumi provider resource (e.g., "pulumi:providers:aws").
func IsValidFeature ¶
IsValidFeature checks if a feature name is valid. IsValidFeature reports whether name exactly matches one of the valid Feature values. Comparison is case-sensitive; it returns true if a match is found and false otherwise.
func NewEngineAdapter ¶ added in v0.3.0
NewEngineAdapter returns an engine.Router that delegates routing decisions to the provided Router, converting router-specific plugin match results into engine.PluginMatch values.
func NormalizeProvider ¶
NormalizeProvider normalizes a provider string for comparison. NormalizeProvider returns the provider string with surrounding whitespace removed and all characters lowercased. Use the result for case-insensitive comparisons of provider identifiers.
func PluginRegion ¶ added in v0.3.0
func PluginRegion(client *pluginhost.Client) string
PluginRegion returns the region configured for the given plugin client. If the client or its metadata is nil, or no region is set, it returns an empty string to indicate a universal (all-region) plugin.
func ProviderMatches ¶
ProviderMatches checks if a resource's provider matches a plugin's supported provider. Returns true if:
- The supported provider is global (empty or "*")
ProviderMatches reports whether a resource provider matches a supported provider. It returns true if the supportedProvider denotes a global provider (empty or "*") or if the resourceProvider and supportedProvider are equal after normalization. resourceProvider is the provider identifier from a resource type. supportedProvider is the provider identifier declared by a plugin.
func RegionMatches ¶ added in v0.3.0
RegionMatches reports whether the plugin region matches the resource region. If either region is empty it is treated as a wildcard and the function returns true. Otherwise the comparison is performed case-insensitively; the function returns true if the regions match, false otherwise.
func ValidFeatureNames ¶
func ValidFeatureNames() []string
ValidFeatureNames returns the string names of all supported Feature values in the same order as ValidFeatures.
Types ¶
type CompiledPattern ¶
type CompiledPattern struct {
// Original is the original pattern configuration.
Original config.ResourcePattern
// Regex is the compiled regex (nil for glob patterns).
Regex *regexp.Regexp
}
CompiledPattern is a pre-compiled pattern for efficient matching.
func CompilePattern ¶
func CompilePattern(pattern config.ResourcePattern) (*CompiledPattern, error)
CompilePattern compiles a ResourcePattern for efficient matching. It returns a *CompiledPattern containing the original pattern and, if the pattern is a regex, the compiled *regexp.Regexp stored in the CompiledPattern.Regex field. If the pattern is marked as a regex but fails to compile, it returns an error that includes the original pattern and the underlying compilation error.
type DefaultRouter ¶
type DefaultRouter struct {
// contains filtered or unexported fields
}
DefaultRouter implements Router with automatic + declarative routing.
func NewRouter ¶
func NewRouter(opts ...Option) (*DefaultRouter, error)
NewRouter creates a new Router with the given options.
Example:
router, err := NewRouter(
WithClients(clients),
WithConfig(config.Routing),
NewRouter creates a DefaultRouter configured by the provided options.
The router is initialized with internal caches, builds a per-plugin routing lookup from any supplied routing config, and pre-compiles all declarative patterns found in that config for fast matching at runtime.
opts are functional options (e.g., WithConfig, WithClients) used to provide the routing configuration and available plugin clients.
NewRouter creates a DefaultRouter configured by the provided options. It initializes internal caches for compiled patterns and per-plugin routing configuration, applies each Option to the router, and pre-compiles all declarative patterns found in the routing configuration. The returned error is non-nil if any configured pattern fails to compile.
func (*DefaultRouter) SelectPlugins ¶
func (r *DefaultRouter) SelectPlugins( ctx context.Context, resource engine.ResourceDescriptor, feature string, ) []PluginMatch
SelectPlugins returns plugins that match a resource for a given feature.
func (*DefaultRouter) ShouldFallback ¶
func (r *DefaultRouter) ShouldFallback(pluginName string) bool
ShouldFallback returns true if fallback is enabled for a plugin.
func (*DefaultRouter) Validate ¶
func (r *DefaultRouter) Validate(_ context.Context) ValidationResult
Validate performs eager validation of the routing configuration.
type EngineAdapter ¶ added in v0.3.0
type EngineAdapter struct {
// contains filtered or unexported fields
}
EngineAdapter bridges the router package's Router interface to the engine package's Router interface. The only difference between the two PluginMatch types is MatchReason: router uses an int enum, engine uses a string.
func (*EngineAdapter) SelectPlugins ¶ added in v0.3.0
func (a *EngineAdapter) SelectPlugins( ctx context.Context, resource engine.ResourceDescriptor, feature string, ) []engine.PluginMatch
SelectPlugins delegates to the underlying router and converts the result slice from router.PluginMatch to engine.PluginMatch.
func (*EngineAdapter) ShouldFallback ¶ added in v0.3.0
func (a *EngineAdapter) ShouldFallback(pluginName string) bool
ShouldFallback delegates directly to the underlying router.
type Feature ¶
type Feature string
Feature represents a plugin capability type. Features determine which operations a plugin can handle (e.g., ProjectedCosts, Recommendations).
const ( // FeatureProjectedCosts enables projected cost estimation from infrastructure specs. FeatureProjectedCosts Feature = "ProjectedCosts" // FeatureActualCosts enables historical cost retrieval from cloud provider APIs. FeatureActualCosts Feature = "ActualCosts" // FeatureRecommendations enables cost optimization recommendations. FeatureRecommendations Feature = "Recommendations" // FeatureCarbon enables carbon footprint estimation for resources. FeatureCarbon Feature = "Carbon" // FeatureDryRun enables dry run simulation of cost changes. FeatureDryRun Feature = "DryRun" // FeatureBudgets enables budget tracking and alerts. FeatureBudgets Feature = "Budgets" // FeatureBatchCost enables batch cost queries across multiple resources. FeatureBatchCost Feature = "BatchCost" )
Feature constants define all supported plugin capabilities. These map to gRPC methods in the CostSource service.
func DefaultFeatures ¶
func DefaultFeatures() []Feature
DefaultFeatures returns the features assumed for plugins that don't report capabilities. DefaultFeatures returns the default feature set assumed for plugins that do not report capabilities. The default set includes FeatureProjectedCosts and FeatureActualCosts.
func FeatureFromMethod ¶
FeatureFromMethod returns the Feature corresponding to a gRPC method name. FeatureFromMethod looks up the Feature associated with a gRPC method name. It returns the Feature and true if a mapping exists; otherwise the zero Feature and false.
func ParseFeature ¶
ParseFeature parses a string into a Feature. ParseFeature parses s into a Feature if it matches a known feature name. It returns the parsed Feature and true when s exactly matches a valid feature name (case-sensitive), or the empty Feature and false otherwise.
func ValidFeatures ¶
func ValidFeatures() []Feature
ValidFeatures returns all supported Feature values (ProjectedCosts, ActualCosts, Recommendations, Carbon, DryRun, Budgets, BatchCost).
type MatchReason ¶
type MatchReason int
MatchReason describes how a plugin was matched to a resource.
const ( // MatchReasonNoMatch indicates the plugin did not match the resource. MatchReasonNoMatch MatchReason = iota - 1 // MatchReasonAutomatic means matched via SupportedProviders metadata. // The resource's provider (extracted from type) matched the plugin's // declared SupportedProviders list. MatchReasonAutomatic // MatchReasonPattern means matched via configured pattern. // A declarative glob or regex pattern matched the resource type. MatchReasonPattern // MatchReasonGlobal means plugin is global. // The plugin has empty SupportedProviders or ["*"]. MatchReasonGlobal )
func (MatchReason) String ¶
func (r MatchReason) String() string
String returns the string representation of a MatchReason.
type Option ¶
type Option func(*DefaultRouter)
Option configures a Router.
func WithClients ¶
func WithClients(clients []*pluginhost.Client) Option
WithClients sets the available plugin clients. WithClients returns an Option that injects the list of available plugin clients into a DefaultRouter. The provided clients slice is required for the router to function and replaces the router's current client list.
func WithConfig ¶
func WithConfig(cfg *config.RoutingConfig) Option
WithConfig sets the routing configuration. WithConfig returns an Option that sets the router's routing configuration. If cfg is nil, the router will operate in automatic provider-based routing only.
type PatternCache ¶
type PatternCache struct {
// contains filtered or unexported fields
}
PatternCache provides thread-safe caching for compiled regex patterns.
func NewPatternCache ¶
func NewPatternCache() *PatternCache
NewPatternCache returns a new PatternCache with an initialized, empty regex map and a zero-valued mutex ready for concurrent use.
func (*PatternCache) Match ¶
func (c *PatternCache) Match(pattern config.ResourcePattern, resourceType string) (bool, error)
Match matches a pattern against a resource type based on the pattern type.
func (*PatternCache) MatchGlob ¶
func (c *PatternCache) MatchGlob(pattern, resourceType string) (bool, error)
MatchGlob matches a glob pattern against a resource type.
func (*PatternCache) MatchRegex ¶
func (c *PatternCache) MatchRegex(pattern, resourceType string) (bool, error)
MatchRegex matches a regex pattern against a resource type. Compiled regexes are cached for performance.
func (*PatternCache) Size ¶
func (c *PatternCache) Size() int
Size returns the number of cached regex patterns.
type PluginMatch ¶
type PluginMatch struct {
// Client is the matched plugin client.
// Never nil.
Client *pluginhost.Client
// Priority is the configured priority (0 if not configured).
// Higher values = higher priority.
Priority int
// Fallback indicates if fallback is enabled for this plugin.
// Default is true.
Fallback bool
// MatchReason describes why this plugin matched.
MatchReason MatchReason
// Source describes where the routing decision came from.
// "automatic" for provider-based, "config" for declarative.
Source string
}
PluginMatch represents a plugin that matches a resource.
type Router ¶
type Router interface {
// SelectPlugins returns plugins that match a resource for a given feature.
//
// Matching Logic (in order of precedence):
// 1. Declarative patterns (if configured) - regex/glob matching
// 2. Automatic provider matching - SupportedProviders metadata
// 3. Global plugins - empty SupportedProviders or ["*"]
//
// Ordering:
// - Results are ordered by priority (highest first)
// - If all plugins have equal priority (0), all are returned for parallel query
//
// Parameters:
// - ctx: Context for cancellation and tracing
// - resource: The resource to find plugins for
// - feature: The feature being requested (e.g., "ProjectedCosts")
//
// Returns:
// - []PluginMatch: Matching plugins with metadata, never nil (may be empty)
SelectPlugins(ctx context.Context, resource engine.ResourceDescriptor, feature string) []PluginMatch
// ShouldFallback returns true if fallback is enabled for a plugin.
//
// Parameters:
// - pluginName: Name of the plugin to check
//
// Returns:
// - bool: True if fallback is enabled (default: true)
ShouldFallback(pluginName string) bool
// Validate performs eager validation of the routing configuration.
//
// Validation includes:
// - Plugin existence check (requires registry access)
// - Pattern syntax validation (regex compilation)
// - Feature name validation
// - Duplicate pattern detection
//
// Parameters:
// - ctx: Context for cancellation
//
// Returns:
// - ValidationResult: Contains errors (blocking) and warnings (non-blocking)
Validate(ctx context.Context) ValidationResult
}
Router selects appropriate plugins for resources based on provider matching, declarative patterns, and priority rules.
Thread Safety: All methods are safe for concurrent use.
Performance: SelectPlugins completes in <10ms per resource (SC-002).
type ValidationError ¶
type ValidationError struct {
// Plugin is the plugin name (empty for global errors).
Plugin string `json:"plugin"`
// Field is the configuration field with the error.
// Examples: "name", "patterns[0].pattern", "features"
Field string `json:"field"`
// Message describes the error.
Message string `json:"message"`
}
ValidationError represents a blocking validation error.
func (ValidationError) Error ¶
func (e ValidationError) Error() string
Error implements the error interface.
type ValidationResult ¶
type ValidationResult struct {
// Valid is true if no errors were found.
// Warnings do not affect validity.
Valid bool `json:"valid"`
// Errors are blocking issues that prevent routing.
// If len(Errors) > 0, Valid must be false.
Errors []ValidationError `json:"errors"`
// Warnings are non-blocking issues that should be reviewed.
// Routing will still work, but behavior may be unexpected.
Warnings []ValidationWarning `json:"warnings"`
}
ValidationResult contains the results of configuration validation.
func ValidateRoutingConfig ¶
func ValidateRoutingConfig(cfg *config.RoutingConfig, clients []*pluginhost.Client) ValidationResult
ValidateRoutingConfig validates the routing configuration against available plugins.
ValidateRoutingConfig validates routing configuration against the provided plugin clients. It verifies plugin presence, detects duplicate plugin entries, ensures priorities are >= 0, warns about unknown features, and validates pattern definitions (type must be "glob" or "regex", pattern must be non-empty, and regex patterns must compile). cfg is the routing configuration to validate; if nil, validation passes (automatic routing only). clients is the list of available plugin clients used to confirm plugin existence. It returns a ValidationResult whose Valid field is true when no blocking errors were found, Errors contains blocking validation issues, and Warnings contains non-blocking advisories.
func (ValidationResult) ErrorMessages ¶
func (r ValidationResult) ErrorMessages() []string
ErrorMessages returns all error messages as a slice of strings.
func (ValidationResult) HasErrors ¶
func (r ValidationResult) HasErrors() bool
HasErrors returns true if the validation result contains any errors.
func (ValidationResult) HasWarnings ¶
func (r ValidationResult) HasWarnings() bool
HasWarnings returns true if the validation result contains any warnings.
func (ValidationResult) WarningMessages ¶
func (r ValidationResult) WarningMessages() []string
WarningMessages returns all warning messages as a slice of strings.
type ValidationWarning ¶
type ValidationWarning struct {
// Plugin is the plugin name (empty for global warnings).
Plugin string `json:"plugin"`
// Field is the configuration field with the warning.
Field string `json:"field"`
// Message describes the warning.
Message string `json:"message"`
}
ValidationWarning represents a non-blocking warning.