globalref

package
v1.4.0 Latest Latest
Warning

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

Go to latest
Published: Mar 10, 2023 License: MPL-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package globalref is home to some analysis algorithms that aim to answer questions about references between objects and object attributes across an entire configuration.

This is a different problem than references within a single module, which we handle using some relatively simpler functions in the "lang" package in the parent directory. The globalref algorithms are often implemented in terms of those module-local reference-checking functions.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Analyzer

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

Analyzer is the main component of this package, serving as a container for various state that the analysis algorithms depend on either for their core functionality or for producing results more quickly.

Global reference analysis is currently intended only for "best effort" use-cases related to giving hints to the user or tailoring UI output. Avoid using it for anything that would cause changes to the analyzer being considered a breaking change under the v1 compatibility promises, because we expect to continue to refine and evolve these rules over time in ways that may cause us to detect either more or fewer references than today. Typically we will conservatively return more references than would be necessary dynamically, but that isn't guaranteed for all situations.

In particular, we currently typically don't distinguish between multiple instances of the same module, and so we overgeneralize references from one instance of a module as references from the same location in all instances of that module. We may make this more precise in future, which would then remove various detected references from the analysis results.

Each Analyzer works with a particular configs.Config object which it assumes represents the root module of a configuration. Config objects are typically immutable by convention anyway, but it's particularly important not to modify a configuration while it's attached to a live Analyzer, because the Analyzer contains caches derived from data in the configuration tree.

func NewAnalyzer

func NewAnalyzer(cfg *configs.Config, providerSchemas map[addrs.Provider]*providers.Schemas) *Analyzer

NewAnalyzer constructs a new analyzer bound to the given configuration and provider schemas.

The given object must represent a root module, or this function will panic.

The given provider schemas must cover at least all of the providers used in the given configuration. If not then analysis results will be silently incomplete for any decision that requires checking schema.

func (*Analyzer) ContributingResourceReferences

func (a *Analyzer) ContributingResourceReferences(refs ...Reference) []Reference

ContributingResourceReferences analyzes all of the given references and for each one tries to walk backwards through any named values to find all references to resource attributes that contributed either directly or indirectly to any of them.

This is a global operation that can be potentially quite expensive for complex configurations.

func (*Analyzer) ContributingResources

func (a *Analyzer) ContributingResources(refs ...Reference) []addrs.AbsResource

ContributingResources analyzes all of the given references and for each one tries to walk backwards through any named values to find all resources whose values contributed either directly or indirectly to any of them.

This is a wrapper around ContributingResourceReferences which simplifies the result to only include distinct resource addresses, not full references. If the configuration includes several different references to different parts of a resource, ContributingResources will not preserve that detail.

func (*Analyzer) MetaReferences

func (a *Analyzer) MetaReferences(ref Reference) []Reference

MetaReferences inspects the configuration to find the references contained within the most specific object that the given address refers to.

This finds only the direct references in that object, not any indirect references from those. This is a building block for some other Analyzer functions that can walk through multiple levels of reference.

If the given reference refers to something that doesn't exist in the configuration we're analyzing then MetaReferences will return no meta-references at all, which is indistinguishable from an existing object that doesn't refer to anything.

func (*Analyzer) ModuleConfig

func (a *Analyzer) ModuleConfig(addr addrs.ModuleInstance) *configs.Module

ModuleConfig retrieves a module configuration from the configuration the analyzer belongs to, or nil if there is no module with the given address.

func (*Analyzer) ReferencesFromOutputValue

func (a *Analyzer) ReferencesFromOutputValue(addr addrs.AbsOutputValue) []Reference

ReferencesFromOutputValue returns all of the direct references from the value expression of the given output value. It doesn't include any indirect references.

func (*Analyzer) ReferencesFromResourceInstance

func (a *Analyzer) ReferencesFromResourceInstance(addr addrs.AbsResourceInstance) []Reference

ReferencesFromResourceInstance returns all of the direct references from the definition of the resource instance at the given address. It doesn't include any indirect references.

The result doesn't directly include references from a "count" or "for_each" expression belonging to the associated resource, but it will include any references to count.index, each.key, or each.value that appear in the expressions which you can then, if you wish, resolve indirectly using Analyzer.MetaReferences. Alternatively, you can use Analyzer.ReferencesFromResourceRepetition to get that same result directly.

func (*Analyzer) ReferencesFromResourceRepetition

func (a *Analyzer) ReferencesFromResourceRepetition(addr addrs.AbsResource) []Reference

ReferencesFromResourceRepetition returns the references from the given resource's for_each or count expression, or an empty set if the resource doesn't use repetition.

This is a special-case sort of helper for use in situations where an expression might refer to count.index, each.key, or each.value, and thus we say that it depends indirectly on the repetition expression.

type Reference

type Reference struct {
	// ContainerAddr is always either addrs.ModuleInstance or
	// addrs.AbsResourceInstance. The latter is required if LocalRef's
	// subject is either an addrs.CountAddr or addrs.ForEachAddr, so
	// we can know which resource's repetition expression it's
	// referring to.
	ContainerAddr addrs.Targetable

	// LocalRef is a reference that would be resolved in the context
	// of the module instance or resource instance given in ContainerAddr.
	LocalRef *addrs.Reference
}

Reference combines an addrs.Reference with the address of the module instance or resource instance where it was found.

Because of the design of the Terraform language, our main model of references only captures the module-local part of the reference and assumes that it's always clear from context which module a reference belongs to. That's not true for globalref because our whole purpose is to work across module boundaries, and so this package in particular has its own representation of references.

func (Reference) DebugString

func (r Reference) DebugString() string

DebugString returns an internal (but still somewhat Terraform-language-like) compact string representation of the reciever, which isn't an address that any of our usual address parsers could accept but still captures the essence of what the reference represents.

The DebugString result is not suitable for end-user-oriented messages.

DebugString is also not suitable for use as a unique key for a reference, because it's ambiguous (between a no-key resource instance and a resource) and because it discards the source location information in the LocalRef.

func (Reference) ModuleAddr

func (r Reference) ModuleAddr() addrs.ModuleInstance

ModuleAddr returns the address of the module where the reference would be resolved.

This is either ContainerAddr directly if it's already just a module instance, or the module instance part of it if it's a resource instance.

func (Reference) ResourceAttr

func (r Reference) ResourceAttr() (ResourceAttr, bool)

ResourceAttr converts the Reference value to a more specific ResourceAttr value.

Because not all references belong to resources, the extra boolean return value indicates whether the returned address is valid.

func (Reference) ResourceInstance

func (r Reference) ResourceInstance() (addrs.AbsResourceInstance, bool)

ResourceInstance returns the address of the resource where the reference would be resolved, if there is one.

Because not all references belong to resources, the extra boolean return value indicates whether the returned address is valid.

type ResourceAttr

type ResourceAttr struct {
	Resource addrs.AbsResourceInstance
	Attr     cty.Path
}

ResourceAttr represents a global resource and attribute reference. This is a more specific form of the Reference type since it can only refer to a specific AbsResource and one of its attributes.

func (ResourceAttr) DebugString

func (r ResourceAttr) DebugString() string

Jump to

Keyboard shortcuts

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