router

package
v0.3.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 31, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

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

View Source
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:"
)
View Source
const ProviderUnknown = "unknown"

ProviderUnknown is the sentinel value for resources with indeterminate providers.

View Source
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

func ExtractProviderFromType(resourceType string) string

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

func IsGlobalProvider(provider string) bool

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

func IsInternalPulumiType(resourceType string) bool

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

func IsPulumiComponentResource(resourceType string) bool

IsPulumiComponentResource reports whether resourceType is a Pulumi component resource (e.g., "pulumi:pulumi:Stack").

func IsPulumiProviderResource added in v0.3.0

func IsPulumiProviderResource(resourceType string) bool

IsPulumiProviderResource reports whether resourceType is a Pulumi provider resource (e.g., "pulumi:providers:aws").

func IsValidFeature

func IsValidFeature(name string) bool

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

func NewEngineAdapter(r Router) engine.Router

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

func NormalizeProvider(provider string) string

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

func ProviderMatches(resourceProvider, supportedProvider string) bool

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

func RegionMatches(pluginRegion, resourceRegion string) bool

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.

func (*CompiledPattern) Match

func (p *CompiledPattern) Match(resourceType string) (bool, error)

Match checks if the pattern matches the given resource type.

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

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

func FeatureFromMethod(method string) (Feature, bool)

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

func ParseFeature(s string) (Feature, bool)

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) Clear

func (c *PatternCache) Clear()

Clear clears the pattern cache.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL