mirror of
https://github.com/hashicorp/terraform.git
synced 2026-03-21 18:10:30 -04:00
164 lines
5.4 KiB
Go
164 lines
5.4 KiB
Go
// Copyright IBM Corp. 2014, 2026
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package stackaddrs
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/hashicorp/hcl/v2"
|
|
"github.com/hashicorp/hcl/v2/hclsyntax"
|
|
|
|
"github.com/hashicorp/terraform/internal/addrs"
|
|
"github.com/hashicorp/terraform/internal/collections"
|
|
"github.com/hashicorp/terraform/internal/tfdiags"
|
|
)
|
|
|
|
// InConfigComponent represents addresses of objects that belong to the modules
|
|
// associated with a particular component.
|
|
//
|
|
// Although the type parameter is rather unconstrained, it doesn't make sense to
|
|
// use this for types other than those from package addrs that represent
|
|
// configuration constructs, like [addrs.ConfigResource], etc.
|
|
type InConfigComponent[T InComponentable] struct {
|
|
Component ConfigComponent
|
|
Item T
|
|
}
|
|
|
|
// ConfigResource represents a resource configuration from inside a
|
|
// particular component.
|
|
type ConfigResource = InConfigComponent[addrs.ConfigResource]
|
|
|
|
// ConfigModule represents a module from inside a particular component.
|
|
//
|
|
// Note that the string representation of the address of the root module of
|
|
// a component is identical to the string representation of the component
|
|
// address alone.
|
|
type ConfigModule = InConfigComponent[addrs.Module]
|
|
|
|
func (c InConfigComponent[T]) String() string {
|
|
itemStr := c.Item.String()
|
|
componentStr := c.Component.String()
|
|
if itemStr == "" {
|
|
return componentStr
|
|
}
|
|
return componentStr + "." + itemStr
|
|
}
|
|
|
|
// UniqueKey implements collections.UniqueKeyer.
|
|
func (c InConfigComponent[T]) UniqueKey() collections.UniqueKey[InConfigComponent[T]] {
|
|
return inConfigComponentKey[T]{
|
|
componentKey: c.Component.UniqueKey(),
|
|
itemKey: c.Item.UniqueKey(),
|
|
}
|
|
}
|
|
|
|
type inConfigComponentKey[T InComponentable] struct {
|
|
componentKey collections.UniqueKey[ConfigComponent]
|
|
itemKey addrs.UniqueKey
|
|
}
|
|
|
|
// IsUniqueKey implements collections.UniqueKey.
|
|
func (inConfigComponentKey[T]) IsUniqueKey(InConfigComponent[T]) {}
|
|
|
|
// InAbsComponentInstance represents addresses of objects that belong to the module
|
|
// instances associated with a particular component instance.
|
|
//
|
|
// Although the type parameter is rather unconstrained, it doesn't make sense to
|
|
// use this for types other than those from package addrs that represent
|
|
// objects that can belong to Terraform modules, like
|
|
// [addrs.AbsResourceInstance], etc.
|
|
type InAbsComponentInstance[T InComponentable] struct {
|
|
Component AbsComponentInstance
|
|
Item T
|
|
}
|
|
|
|
// AbsResource represents a not-yet-expanded resource from inside a particular
|
|
// component instance.
|
|
type AbsResource = InAbsComponentInstance[addrs.AbsResource]
|
|
|
|
var _ collections.UniqueKeyer[AbsResource] = AbsResource{}
|
|
|
|
// AbsResourceInstance represents an instance of a resource from inside a
|
|
// particular component instance.
|
|
type AbsResourceInstance = InAbsComponentInstance[addrs.AbsResourceInstance]
|
|
|
|
// AbsResourceInstanceObject represents an object associated with an instance
|
|
// of a resource from inside a particular component instance.
|
|
type AbsResourceInstanceObject = InAbsComponentInstance[addrs.AbsResourceInstanceObject]
|
|
|
|
// AbsActionInvocationInstance represents an instance of an action from inside a
|
|
// particular component instance.
|
|
type AbsActionInvocationInstance = InAbsComponentInstance[addrs.AbsActionInstance]
|
|
|
|
// AbsModuleInstance represents an instance of a module from inside a
|
|
// particular component instance.
|
|
//
|
|
// Note that the string representation of the address of the root module of
|
|
// a component instance is identical to the string representation of the
|
|
// component instance address alone.
|
|
type AbsModuleInstance = InAbsComponentInstance[addrs.ModuleInstance]
|
|
|
|
func (c InAbsComponentInstance[T]) String() string {
|
|
itemStr := c.Item.String()
|
|
componentStr := c.Component.String()
|
|
if itemStr == "" {
|
|
return componentStr
|
|
}
|
|
return componentStr + "." + itemStr
|
|
}
|
|
|
|
// UniqueKey implements collections.UniqueKeyer.
|
|
func (c InAbsComponentInstance[T]) UniqueKey() collections.UniqueKey[InAbsComponentInstance[T]] {
|
|
return inAbsComponentInstanceKey[T]{
|
|
componentKey: c.Component.UniqueKey(),
|
|
itemKey: c.Item.UniqueKey(),
|
|
}
|
|
}
|
|
|
|
type inAbsComponentInstanceKey[T InComponentable] struct {
|
|
componentKey collections.UniqueKey[AbsComponentInstance]
|
|
itemKey addrs.UniqueKey
|
|
}
|
|
|
|
// IsUniqueKey implements collections.UniqueKey.
|
|
func (inAbsComponentInstanceKey[T]) IsUniqueKey(InAbsComponentInstance[T]) {}
|
|
|
|
// InComponentable just embeds the interfaces that we require for the type
|
|
// parameters of both the [InConfigComponent] and [InAbsComponent] types.
|
|
type InComponentable interface {
|
|
addrs.UniqueKeyer
|
|
fmt.Stringer
|
|
}
|
|
|
|
func ParseAbsResourceInstanceObject(traversal hcl.Traversal) (AbsResourceInstanceObject, tfdiags.Diagnostics) {
|
|
stack, remain, diags := ParseAbsComponentInstanceOnly(traversal)
|
|
if diags.HasErrors() {
|
|
return AbsResourceInstanceObject{}, diags
|
|
}
|
|
|
|
resource, diags := addrs.ParseAbsResourceInstance(remain)
|
|
if diags.HasErrors() {
|
|
return AbsResourceInstanceObject{}, diags
|
|
}
|
|
|
|
return AbsResourceInstanceObject{
|
|
Component: stack,
|
|
Item: addrs.AbsResourceInstanceObject{
|
|
ResourceInstance: resource,
|
|
},
|
|
}, diags
|
|
}
|
|
|
|
func ParseAbsResourceInstanceObjectStr(s string) (AbsResourceInstanceObject, tfdiags.Diagnostics) {
|
|
var diags tfdiags.Diagnostics
|
|
traversal, hclDiags := hclsyntax.ParseTraversalAbs([]byte(s), "", hcl.InitialPos)
|
|
diags = diags.Append(hclDiags)
|
|
if diags.HasErrors() {
|
|
return AbsResourceInstanceObject{}, diags
|
|
}
|
|
|
|
ret, moreDiags := ParseAbsResourceInstanceObject(traversal)
|
|
diags = diags.Append(moreDiags)
|
|
return ret, diags
|
|
}
|