plan

package
v1.5.0 Latest Latest
Warning

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

Go to latest
Published: Sep 21, 2025 License: MIT Imports: 18 Imported by: 0

Documentation

Index

Constants

View Source
const (

	// MaxPropertiesPerResource limits the number of properties extracted per resource to prevent runaway extraction
	MaxPropertiesPerResource = 100
	// MaxPropertyValueSize limits individual property values to 10KB
	MaxPropertyValueSize = 10240
	// MaxTotalPropertyMemory limits total memory usage for all properties to 10MB
	MaxTotalPropertyMemory = 10485760
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Analyzer

type Analyzer struct {
	// contains filtered or unexported fields
}

Analyzer processes Terraform plan data and generates summaries

func NewAnalyzer

func NewAnalyzer(plan *tfjson.Plan, cfg *config.Config) *Analyzer

NewAnalyzer creates a new plan analyzer

func (*Analyzer) AnalyzePropertyChanges added in v1.1.4

func (a *Analyzer) AnalyzePropertyChanges(change *tfjson.ResourceChange) PropertyChangeAnalysis

AnalyzePropertyChanges extracts property changes with performance safeguards using the new compareObjects method (exported for testing)

func (*Analyzer) AnalyzeResource added in v1.1.0

func (a *Analyzer) AnalyzeResource(change *tfjson.ResourceChange) (*ResourceAnalysis, error)

AnalyzeResource performs comprehensive analysis with performance limits

func (*Analyzer) GenerateSummary

func (a *Analyzer) GenerateSummary(planFile string) *PlanSummary

GenerateSummary creates a comprehensive summary of the plan

func (*Analyzer) GetChangesByResourceType

func (a *Analyzer) GetChangesByResourceType(changes []ResourceChange, resourceType string) []ResourceChange

GetChangesByResourceType returns changes filtered by Terraform resource type

func (*Analyzer) GetChangesByType

func (a *Analyzer) GetChangesByType(changes []ResourceChange, changeType ChangeType) []ResourceChange

GetChangesByType returns changes filtered by type

func (*Analyzer) GetDestructiveChangeCount

func (a *Analyzer) GetDestructiveChangeCount(changes []ResourceChange) int

GetDestructiveChangeCount returns the count of destructive changes

func (*Analyzer) GetDestructiveChanges

func (a *Analyzer) GetDestructiveChanges(changes []ResourceChange) []ResourceChange

GetDestructiveChanges returns only the changes that are considered destructive

func (*Analyzer) HasDestructiveChanges

func (a *Analyzer) HasDestructiveChanges(changes []ResourceChange) bool

HasDestructiveChanges returns true if there are any destructive changes

func (*Analyzer) IsSensitiveProperty

func (a *Analyzer) IsSensitiveProperty(resourceType string, propertyName string) bool

IsSensitiveProperty checks if a property is sensitive for a given resource type

func (*Analyzer) IsSensitiveResource

func (a *Analyzer) IsSensitiveResource(resourceType string) bool

IsSensitiveResource checks if a resource type is in the sensitive resources list

func (*Analyzer) ProcessOutputChanges added in v1.2.0

func (a *Analyzer) ProcessOutputChanges(plan *tfjson.Plan) ([]OutputChange, error)

ProcessOutputChanges processes all output changes in the plan (requirement 2.1)

type BackendInfo

type BackendInfo struct {
	Type     string         `json:"type"`     // e.g., "s3", "local", "remote"
	Location string         `json:"location"` // bucket name, file path, etc.
	Config   map[string]any `json:"config"`   // additional backend config
}

BackendInfo contains information about the Terraform backend

type ChangeStatistics

type ChangeStatistics struct {
	ToAdd        int `json:"to_add"`       // ADDED: Resources to be created (new resources)
	ToChange     int `json:"to_change"`    // MODIFIED: Resources to be updated (existing resources with changes)
	ToDestroy    int `json:"to_destroy"`   // REMOVED: Resources to be destroyed (deleted resources)
	Replacements int `json:"replacements"` // REPLACEMENTS: Resources to be replaced (definite replacements)
	HighRisk     int `json:"high_risk"`    // HIGH RISK: Sensitive resources with danger flag
	Unmodified   int `json:"unmodified"`   // UNMODIFIED: Resources with no changes (no-op)
	Total        int `json:"total"`        // TOTAL: Total number of resource changes across all categories
	// Output change statistics (excludes no-ops per requirement 4.5)
	OutputChanges int `json:"output_changes"` // OUTPUT CHANGES: Total number of output changes (excludes no-ops)
}

ChangeStatistics provides counts of different types of changes for the enhanced statistics summary table

type ChangeType

type ChangeType string

ChangeType represents the type of change being made to a resource

const (
	ChangeTypeCreate  ChangeType = "create"  // Resource is being created
	ChangeTypeUpdate  ChangeType = "update"  // Resource is being updated
	ChangeTypeDelete  ChangeType = "delete"  // Resource is being deleted
	ChangeTypeReplace ChangeType = "replace" // Resource is being replaced
	ChangeTypeNoOp    ChangeType = "no-op"   // No operation on resource
)

ChangeType constants represent different types of Terraform resource changes

func FromTerraformAction

func FromTerraformAction(actions tfjson.Actions) ChangeType

FromTerraformAction converts a Terraform action to our ChangeType

func (ChangeType) IsDestructive

func (ct ChangeType) IsDestructive() bool

IsDestructive returns true if the change type is considered destructive

type Formatter

type Formatter struct {
	// contains filtered or unexported fields
}

Formatter handles different output formats for plan summaries

func NewFormatter

func NewFormatter(cfg *config.Config) *Formatter

NewFormatter creates a new formatter instance

func (*Formatter) OutputSummary

func (f *Formatter) OutputSummary(summary *PlanSummary, outputConfig *config.OutputConfiguration, showDetails bool) error

OutputSummary outputs the plan summary using go-output v2 library

ARCHITECTURE: Simplified Plan Rendering This function implements the simplified rendering architecture that fixes the multi-table rendering bug by following the proven pattern from go-output v2's collapsible-tables example.

Key architectural decisions: 1. Unified Table Creation: Uses output.NewTableContent() exclusively for consistent table creation 2. Unified Document Building: Uses output.New().AddContent().AddContent().Build() pattern 3. Format Handling Delegation: All format-specific logic delegated to go-output library 4. Conservative Error Handling: Individual table failures logged but don't stop rendering

ENHANCEMENT: No-Op Filtering Integration (Task 4.3) This enhanced version applies no-op filtering based on f.config.Plan.ShowNoOps configuration and displays "No changes detected" message when no actual changes exist (Requirement 3.5)

The previous implementation incorrectly disabled tables due to a perceived "library bug" that didn't actually exist. This approach re-enables all tables while maintaining all existing functionality including collapsible content and provider grouping.

func (*Formatter) ValidateOutputFormat

func (f *Formatter) ValidateOutputFormat(outputFormat string) error

ValidateOutputFormat validates that the output format is supported

type GoldenFileHelper added in v1.3.0

type GoldenFileHelper struct {
	// contains filtered or unexported fields
}

GoldenFileHelper provides utilities for golden file testing

func NewGoldenFileHelper added in v1.3.0

func NewGoldenFileHelper(testdataDir string) *GoldenFileHelper

NewGoldenFileHelper creates a new golden file helper

func (*GoldenFileHelper) CompareOrUpdateGolden added in v1.3.0

func (g *GoldenFileHelper) CompareOrUpdateGolden(t *testing.T, testName string, got []byte)

CompareOrUpdateGolden compares output with golden file or updates it if -update-golden flag is set

func (*GoldenFileHelper) LoadGoldenFile added in v1.3.0

func (g *GoldenFileHelper) LoadGoldenFile(t *testing.T, testName string) []byte

LoadGoldenFile loads content from a golden file

func (*GoldenFileHelper) SaveGoldenFile added in v1.3.0

func (g *GoldenFileHelper) SaveGoldenFile(t *testing.T, testName string, content []byte)

SaveGoldenFile saves content to a golden file (useful for initial creation)

type OutputChange

type OutputChange struct {
	Name       string     `json:"name"`
	ChangeType ChangeType `json:"change_type"`
	Sensitive  bool       `json:"sensitive"`
	Before     any        `json:"before,omitempty"`
	After      any        `json:"after,omitempty"`
	// New fields for outputs support (requirement 2.3, 2.5, 2.6, 2.7)
	IsUnknown bool   `json:"is_unknown"` // Whether output value is unknown (requirement 2.3)
	Action    string `json:"action"`     // "Add", "Modify", "Remove" actions (requirements 2.5, 2.6, 2.7)
	Indicator string `json:"indicator"`  // "+", "~", "-" visual indicators (requirements 2.5, 2.6, 2.7)
	// Field for no-op filtering (Output Refinements feature)
	IsNoOp bool `json:"-"` // Internal: true if before equals after
}

OutputChange represents a change to a Terraform output

type Parser

type Parser struct {
	// contains filtered or unexported fields
}

Parser handles Terraform plan file parsing

func NewParser

func NewParser(planFile string) *Parser

NewParser creates a new plan parser instance

func (*Parser) LoadPlan

func (p *Parser) LoadPlan() (*tfjson.Plan, error)

LoadPlan loads and parses a Terraform plan file

func (*Parser) ValidateStructure

func (p *Parser) ValidateStructure(plan *tfjson.Plan) error

ValidateStructure validates that the plan has the expected structure

type PerformanceLimits added in v1.1.0

type PerformanceLimits struct {
	MaxPropertiesPerResource int   `json:"max_properties_per_resource"` // Default: 100
	MaxPropertySize          int   `json:"max_property_size"`           // Default: 1MB
	MaxTotalMemory           int64 `json:"max_total_memory"`            // Default: 100MB
	MaxDependencyDepth       int   `json:"max_dependency_depth"`        // Default: 10
	MaxResourcesPerGroup     int   `json:"max_resources_per_group"`     // Default: 1000
}

PerformanceLimits defines memory and processing limits for analysis

type PlanBuilder added in v1.3.0

type PlanBuilder struct {
	// contains filtered or unexported fields
}

PlanBuilder provides a functional builder pattern for creating test Terraform plans

func CreateEmptyPlan added in v1.3.0

func CreateEmptyPlan() *PlanBuilder

CreateEmptyPlan creates a plan with no changes

func CreateHighRiskPlan added in v1.3.0

func CreateHighRiskPlan() *PlanBuilder

CreateHighRiskPlan creates a plan with potentially dangerous changes

func CreateMultiProviderPlan added in v1.3.0

func CreateMultiProviderPlan(resourceCount int) *PlanBuilder

CreateMultiProviderPlan creates a plan with resources from multiple providers

func CreatePropertyBenchmarkPlan added in v1.3.0

func CreatePropertyBenchmarkPlan(propertyCount, propertySize int) *PlanBuilder

CreatePropertyBenchmarkPlan creates a plan optimized for property performance testing

func CreateSimplePlan added in v1.3.0

func CreateSimplePlan() *PlanBuilder

CreateSimplePlan creates a basic plan with a few resources

func NewPlanBuilder added in v1.3.0

func NewPlanBuilder() *PlanBuilder

NewPlanBuilder creates a new plan builder with sensible defaults

func (*PlanBuilder) AddMultiProviderResources added in v1.3.0

func (b *PlanBuilder) AddMultiProviderResources(count int) *PlanBuilder

AddMultiProviderResources adds resources from multiple providers for realistic testing

func (*PlanBuilder) AddOutput added in v1.3.0

func (b *PlanBuilder) AddOutput(name string, change OutputChange) *PlanBuilder

AddOutput adds an output change to the plan

func (*PlanBuilder) AddPropertyHeavyResource added in v1.3.0

func (b *PlanBuilder) AddPropertyHeavyResource(resourceType, name string, propertyCount, propertySize int) *PlanBuilder

AddPropertyHeavyResource adds a resource with many properties for performance testing

func (*PlanBuilder) AddResource added in v1.3.0

func (b *PlanBuilder) AddResource(resource tfjson.ResourceChange) *PlanBuilder

AddResource adds a resource change to the plan

func (*PlanBuilder) AddSimpleResource added in v1.3.0

func (b *PlanBuilder) AddSimpleResource(provider, resourceType, name, action string) *PlanBuilder

AddSimpleResource adds a simple resource change with basic configuration

func (*PlanBuilder) AddVariable added in v1.3.0

func (b *PlanBuilder) AddVariable(name string, value any) *PlanBuilder

AddVariable adds a variable to the plan

func (*PlanBuilder) Build added in v1.3.0

func (b *PlanBuilder) Build() *tfjson.Plan

Build creates the final terraform-json Plan

func (*PlanBuilder) BuildJSON added in v1.3.0

func (b *PlanBuilder) BuildJSON() ([]byte, error)

BuildJSON creates the plan and marshals it to JSON

func (*PlanBuilder) SaveToTempFile added in v1.3.0

func (b *PlanBuilder) SaveToTempFile(filename string) (string, error)

SaveToTempFile creates the plan and saves it to a temporary file (for benchmarks)

func (*PlanBuilder) SaveToTestdata added in v1.3.0

func (b *PlanBuilder) SaveToTestdata(filename string) (string, error)

SaveToTestdata creates the plan and saves it to the testdata directory

func (*PlanBuilder) WithFormatVersion added in v1.3.0

func (b *PlanBuilder) WithFormatVersion(version string) *PlanBuilder

WithFormatVersion sets the plan format version

func (*PlanBuilder) WithTerraformVersion added in v1.3.0

func (b *PlanBuilder) WithTerraformVersion(version string) *PlanBuilder

WithTerraformVersion sets the Terraform version

type PlanSummary

type PlanSummary struct {
	FormatVersion    string           `json:"format_version"`
	TerraformVersion string           `json:"terraform_version"`
	PlanFile         string           `json:"plan_file"`
	Workspace        string           `json:"workspace"`
	Backend          BackendInfo      `json:"backend"`
	CreatedAt        time.Time        `json:"created_at"`
	ResourceChanges  []ResourceChange `json:"resource_changes"`
	OutputChanges    []OutputChange   `json:"output_changes"`
	Statistics       ChangeStatistics `json:"statistics"`
}

PlanSummary contains the summarised information from a Terraform plan

type PropertyChange added in v1.1.0

type PropertyChange struct {
	Name                string   `json:"name"`                 // Property name only (no full resource path since we're already at resource level)
	Path                []string `json:"path"`                 // For nested properties
	Before              any      `json:"before"`               // Actual before value
	After               any      `json:"after"`                // Actual after value
	Sensitive           bool     `json:"sensitive"`            // From sensitive_values
	Size                int      `json:"size"`                 // Size in bytes for memory tracking
	Action              string   `json:"action"`               // "add", "remove", "update" actions
	TriggersReplacement bool     `json:"triggers_replacement"` // Whether this change causes resource replacement
	// New fields for unknown values (requirement 1.6)
	IsUnknown   bool   `json:"is_unknown"`   // Whether this property has unknown values
	UnknownType string `json:"unknown_type"` // "before", "after", "both" to track unknown states (requirement 1.7)
}

PropertyChange represents a single property that changed between before/after states

type PropertyChangeAnalysis added in v1.1.0

type PropertyChangeAnalysis struct {
	Changes   []PropertyChange `json:"changes"`
	Count     int              `json:"count"`
	TotalSize int              `json:"total_size_bytes"`
	Truncated bool             `json:"truncated"` // True if hit performance limits
}

PropertyChangeAnalysis focuses on detailed property change information

type ReplacementType

type ReplacementType string

ReplacementType represents whether a resource will be replaced

const (
	ReplacementNever  ReplacementType = "Never"  // Resource will not be replaced
	ReplacementAlways ReplacementType = "Always" // Resource will be replaced
)

ReplacementType constants represent different replacement scenarios for Terraform resources

type ResourceAnalysis added in v1.1.0

type ResourceAnalysis struct {
	PropertyChanges    PropertyChangeAnalysis `json:"property_changes"`
	ReplacementReasons []string               `json:"replacement_reasons"`
	RiskLevel          string                 `json:"risk_level"` // "low", "medium", "high", "critical"
}

ResourceAnalysis contains comprehensive analysis results for a single resource This is used for progressive disclosure with go-output v2 collapsible sections

type ResourceChange

type ResourceChange struct {
	Address          string          `json:"address"`
	Type             string          `json:"type"`
	Name             string          `json:"name"`
	ChangeType       ChangeType      `json:"change_type"`
	IsDestructive    bool            `json:"is_destructive"`
	ReplacementType  ReplacementType `json:"replacement_type"`
	PhysicalID       string          `json:"physical_id"`       // current physical resource ID
	PlannedID        string          `json:"planned_id"`        // planned physical resource ID
	ModulePath       string          `json:"module_path"`       // module hierarchy path
	ChangeAttributes []string        `json:"change_attributes"` // specific attributes changing
	Before           any             `json:"before,omitempty"`
	After            any             `json:"after,omitempty"`
	// New fields for danger highlights
	IsDangerous      bool     `json:"is_dangerous"`      // Whether this change is flagged as dangerous
	DangerReason     string   `json:"danger_reason"`     // Reason why this change is dangerous
	DangerProperties []string `json:"danger_properties"` // List of dangerous property changes
	// Enhanced summary visualization fields
	Provider         string                 `json:"provider,omitempty"`          // Provider name extracted from resource type (e.g., "aws", "azurerm")
	TopChanges       []string               `json:"top_changes,omitempty"`       // First 3 changed properties for updates (only shown if show_context=true)
	ReplacementHints []string               `json:"replacement_hints,omitempty"` // Human-readable replacement reasons (always shown)
	PropertyChanges  PropertyChangeAnalysis `json:"property_changes"`            // Detailed property change analysis
	// New fields for unknown values (requirement 1.2, 1.5)
	HasUnknownValues  bool     `json:"has_unknown_values"` // Whether resource contains unknown properties (requirement 1.2)
	UnknownProperties []string `json:"unknown_properties"` // List of unknown property paths (requirement 1.5)
	// Field for no-op filtering (Output Refinements feature)
	IsNoOp bool `json:"-"` // Internal: true for no-op resources
}

ResourceChange represents a change to a Terraform resource

Jump to

Keyboard shortcuts

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