Skip to content

Commit

Permalink
Add support for partial addresses and targets that start with 'resour…
Browse files Browse the repository at this point in the history
…ce.' (#35333)

* Add support for partial addresses and targets that start with 'resource.'

* fix broken tests
  • Loading branch information
liamcervante committed Jun 14, 2024
1 parent 68ceed4 commit 55600d8
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 35 deletions.
71 changes: 36 additions & 35 deletions internal/addrs/move_endpoint_module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclsyntax"

"github.com/hashicorp/terraform/internal/tfdiags"
)

Expand Down Expand Up @@ -1118,7 +1119,7 @@ func TestMoveEndpointChainAndNested(t *testing.T) {
},

{
Endpoint: mustParseAbsResourceInstanceStr("module.foo[2].module.bar.resource.baz").ContainingResource(),
Endpoint: mustParseAbsResourceInstanceStr("module.foo[2].module.bar.resource_type.baz").ContainingResource(),
Other: AbsModuleCall{
Module: mustParseModuleInstanceStr("module.foo[2]"),
Call: ModuleCall{Name: "bar"},
Expand All @@ -1128,7 +1129,7 @@ func TestMoveEndpointChainAndNested(t *testing.T) {
},

{
Endpoint: mustParseAbsResourceInstanceStr("module.foo[2].module.bar[3].resource.baz[2]"),
Endpoint: mustParseAbsResourceInstanceStr("module.foo[2].module.bar[3].resource_type.baz[2]"),
Other: AbsModuleCall{
Module: mustParseModuleInstanceStr("module.foo[2]"),
Call: ModuleCall{Name: "bar"},
Expand All @@ -1155,14 +1156,14 @@ func TestMoveEndpointChainAndNested(t *testing.T) {
},

{
Endpoint: mustParseAbsResourceInstanceStr("module.foo[2].resource.baz").ContainingResource(),
Endpoint: mustParseAbsResourceInstanceStr("module.foo[2].resource_type.baz").ContainingResource(),
Other: mustParseModuleInstanceStr("module.foo[2]"),
CanChainFrom: false,
NestedWithin: true,
},

{
Endpoint: mustParseAbsResourceInstanceStr("module.foo[2].module.bar.resource.baz"),
Endpoint: mustParseAbsResourceInstanceStr("module.foo[2].module.bar.resource_type.baz"),
Other: mustParseModuleInstanceStr("module.foo[2]"),
CanChainFrom: false,
NestedWithin: true,
Expand All @@ -1173,28 +1174,28 @@ func TestMoveEndpointChainAndNested(t *testing.T) {
Module: mustParseModuleInstanceStr("module.foo[2]"),
Call: ModuleCall{Name: "bar"},
},
Other: mustParseAbsResourceInstanceStr("module.foo[2].resource.baz").ContainingResource(),
Other: mustParseAbsResourceInstanceStr("module.foo[2].resource_type.baz").ContainingResource(),
CanChainFrom: false,
NestedWithin: false,
},

{
Endpoint: mustParseModuleInstanceStr("module.foo[2]"),
Other: mustParseAbsResourceInstanceStr("module.foo[2].resource.baz").ContainingResource(),
Other: mustParseAbsResourceInstanceStr("module.foo[2].resource_type.baz").ContainingResource(),
CanChainFrom: false,
NestedWithin: false,
},

{
Endpoint: mustParseAbsResourceInstanceStr("module.foo[2].resource.baz").ContainingResource(),
Other: mustParseAbsResourceInstanceStr("module.foo[2].resource.baz").ContainingResource(),
Endpoint: mustParseAbsResourceInstanceStr("module.foo[2].resource_type.baz").ContainingResource(),
Other: mustParseAbsResourceInstanceStr("module.foo[2].resource_type.baz").ContainingResource(),
CanChainFrom: true,
NestedWithin: false,
},

{
Endpoint: mustParseAbsResourceInstanceStr("module.foo[2].resource.baz"),
Other: mustParseAbsResourceInstanceStr("module.foo[2].resource.baz[2]").ContainingResource(),
Endpoint: mustParseAbsResourceInstanceStr("module.foo[2].resource_type.baz"),
Other: mustParseAbsResourceInstanceStr("module.foo[2].resource_type.baz[2]").ContainingResource(),
CanChainFrom: false,
NestedWithin: true,
},
Expand All @@ -1204,53 +1205,53 @@ func TestMoveEndpointChainAndNested(t *testing.T) {
Module: mustParseModuleInstanceStr("module.foo[2]"),
Call: ModuleCall{Name: "bar"},
},
Other: mustParseAbsResourceInstanceStr("module.foo[2].resource.baz"),
Other: mustParseAbsResourceInstanceStr("module.foo[2].resource_type.baz"),
CanChainFrom: false,
},

{
Endpoint: mustParseModuleInstanceStr("module.foo[2]"),
Other: mustParseAbsResourceInstanceStr("module.foo[2].resource.baz"),
Other: mustParseAbsResourceInstanceStr("module.foo[2].resource_type.baz"),
CanChainFrom: false,
},
{
Endpoint: mustParseAbsResourceInstanceStr("module.foo[2].resource.baz").ContainingResource(),
Other: mustParseAbsResourceInstanceStr("module.foo[2].resource.baz"),
Endpoint: mustParseAbsResourceInstanceStr("module.foo[2].resource_type.baz").ContainingResource(),
Other: mustParseAbsResourceInstanceStr("module.foo[2].resource_type.baz"),
CanChainFrom: false,
},

{
Endpoint: mustParseAbsResourceInstanceStr("module.foo[2].resource.baz"),
Other: mustParseAbsResourceInstanceStr("module.foo[2].resource.baz"),
Endpoint: mustParseAbsResourceInstanceStr("module.foo[2].resource_type.baz"),
Other: mustParseAbsResourceInstanceStr("module.foo[2].resource_type.baz"),
CanChainFrom: true,
},

{
Endpoint: mustParseAbsResourceInstanceStr("resource.baz"),
Endpoint: mustParseAbsResourceInstanceStr("resource_type.baz"),
EndpointMod: Module{"foo"},
Other: mustParseAbsResourceInstanceStr("module.foo[2].resource.baz"),
Other: mustParseAbsResourceInstanceStr("module.foo[2].resource_type.baz"),
CanChainFrom: true,
},

{
Endpoint: mustParseAbsResourceInstanceStr("module.foo[2].resource.baz"),
Other: mustParseAbsResourceInstanceStr("resource.baz"),
Endpoint: mustParseAbsResourceInstanceStr("module.foo[2].resource_type.baz"),
Other: mustParseAbsResourceInstanceStr("resource_type.baz"),
OtherMod: Module{"foo"},
CanChainFrom: true,
},

{
Endpoint: mustParseAbsResourceInstanceStr("resource.baz"),
Endpoint: mustParseAbsResourceInstanceStr("resource_type.baz"),
EndpointMod: Module{"foo"},
Other: mustParseAbsResourceInstanceStr("resource.baz"),
Other: mustParseAbsResourceInstanceStr("resource_type.baz"),
OtherMod: Module{"foo"},
CanChainFrom: true,
},

{
Endpoint: mustParseAbsResourceInstanceStr("resource.baz").ContainingResource(),
Endpoint: mustParseAbsResourceInstanceStr("resource_type.baz").ContainingResource(),
EndpointMod: Module{"foo"},
Other: mustParseAbsResourceInstanceStr("module.foo[2].resource.baz").ContainingResource(),
Other: mustParseAbsResourceInstanceStr("module.foo[2].resource_type.baz").ContainingResource(),
CanChainFrom: true,
},

Expand All @@ -1275,29 +1276,29 @@ func TestMoveEndpointChainAndNested(t *testing.T) {
},

{
Endpoint: mustParseAbsResourceInstanceStr("resource.baz"),
Endpoint: mustParseAbsResourceInstanceStr("resource_type.baz"),
EndpointMod: Module{"foo"},
Other: mustParseAbsResourceInstanceStr("module.foo[2].resource.baz").ContainingResource(),
Other: mustParseAbsResourceInstanceStr("module.foo[2].resource_type.baz").ContainingResource(),
NestedWithin: true,
},

{
Endpoint: mustParseAbsResourceInstanceStr("module.foo[2].resource.baz"),
Other: mustParseAbsResourceInstanceStr("resource.baz").ContainingResource(),
Endpoint: mustParseAbsResourceInstanceStr("module.foo[2].resource_type.baz"),
Other: mustParseAbsResourceInstanceStr("resource_type.baz").ContainingResource(),
OtherMod: Module{"foo"},
NestedWithin: true,
},

{
Endpoint: mustParseAbsResourceInstanceStr("resource.baz"),
Endpoint: mustParseAbsResourceInstanceStr("resource_type.baz"),
EndpointMod: Module{"foo"},
Other: mustParseAbsResourceInstanceStr("resource.baz").ContainingResource(),
Other: mustParseAbsResourceInstanceStr("resource_type.baz").ContainingResource(),
OtherMod: Module{"foo"},
NestedWithin: true,
},

{
Endpoint: mustParseAbsResourceInstanceStr("ressurce.baz").ContainingResource(),
Endpoint: mustParseAbsResourceInstanceStr("resource_type.baz").ContainingResource(),
EndpointMod: Module{"foo"},
Other: mustParseModuleInstanceStr("module.foo[2]"),
NestedWithin: true,
Expand Down Expand Up @@ -1406,7 +1407,7 @@ func TestSelectsModule(t *testing.T) {
{
Endpoint: &MoveEndpointInModule{
module: mustParseModuleInstanceStr("module.foo").Module(),
relSubject: mustParseAbsResourceInstanceStr(`module.bar.resource.name["key"]`),
relSubject: mustParseAbsResourceInstanceStr(`module.bar.resource_type.name["key"]`),
},
Addr: mustParseModuleInstanceStr(`module.foo[1].module.bar`),
Selects: true,
Expand All @@ -1420,15 +1421,15 @@ func TestSelectsModule(t *testing.T) {
},
{
Endpoint: &MoveEndpointInModule{
relSubject: mustParseAbsResourceInstanceStr(`module.bar.module.baz["key"].resource.name`).ContainingResource(),
relSubject: mustParseAbsResourceInstanceStr(`module.bar.module.baz["key"].resource_type.name`).ContainingResource(),
},
Addr: mustParseModuleInstanceStr(`module.bar.module.baz["key"]`),
Selects: true,
},
{
Endpoint: &MoveEndpointInModule{
module: mustParseModuleInstanceStr("module.nope").Module(),
relSubject: mustParseAbsResourceInstanceStr(`module.bar.resource.name["key"]`),
relSubject: mustParseAbsResourceInstanceStr(`module.bar.resource_type.name["key"]`),
},
Addr: mustParseModuleInstanceStr(`module.foo[1].module.bar`),
Selects: false,
Expand All @@ -1442,7 +1443,7 @@ func TestSelectsModule(t *testing.T) {
},
{
Endpoint: &MoveEndpointInModule{
relSubject: mustParseAbsResourceInstanceStr(`module.nope.module.baz["key"].resource.name`).ContainingResource(),
relSubject: mustParseAbsResourceInstanceStr(`module.nope.module.baz["key"].resource_type.name`).ContainingResource(),
},
Addr: mustParseModuleInstanceStr(`module.bar.module.baz["key"]`),
Selects: false,
Expand Down
5 changes: 5 additions & 0 deletions internal/addrs/parse_target.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/hashicorp/hcl/v2/hclsyntax"

"github.com/hashicorp/hcl/v2"

"github.com/hashicorp/terraform/internal/tfdiags"
)

Expand Down Expand Up @@ -161,6 +162,10 @@ func parseResourceInstanceUnderModule(moduleAddr ModuleInstance, remain hcl.Trav
if remain.RootName() == "data" {
mode = DataResourceMode
remain = remain[1:]
} else if remain.RootName() == "resource" {
// Starting a resource address with "resource" is optional, so we'll
// just ignore it.
remain = remain[1:]
}

if len(remain) < 2 {
Expand Down
19 changes: 19 additions & 0 deletions internal/addrs/parse_target_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/go-test/deep"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclsyntax"

"github.com/hashicorp/terraform/internal/tfdiags"
)

Expand Down Expand Up @@ -86,6 +87,24 @@ func TestParseTarget(t *testing.T) {
},
``,
},
{
`resource.aws_instance.foo`,
&Target{
Subject: AbsResource{
Resource: Resource{
Mode: ManagedResourceMode,
Type: "aws_instance",
Name: "foo",
},
Module: RootModuleInstance,
},
SourceRange: tfdiags.SourceRange{
Start: tfdiags.SourcePos{Line: 1, Column: 1, Byte: 0},
End: tfdiags.SourcePos{Line: 1, Column: 26, Byte: 25},
},
},
``,
},
{
`aws_instance.foo[1]`,
&Target{
Expand Down
4 changes: 4 additions & 0 deletions internal/addrs/partial_expanded.go
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,10 @@ func ParsePartialExpandedResource(traversal hcl.Traversal) (PartialExpandedResou
if remain.RootName() == "data" {
mode = DataResourceMode
remain = remain[1:]
} else if remain.RootName() == "resource" {
// Starting a resource address with "resource" is optional, so we'll
// just ignore it if it's present.
remain = remain[1:]
}

if len(remain) < 2 {
Expand Down
11 changes: 11 additions & 0 deletions internal/addrs/partial_expanded_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,17 @@ func TestParsePartialExpandedResource(t *testing.T) {
},
remain: 1,
},
{
addr: "resource.resource_type.resource_name",
want: PartialExpandedResource{
resource: Resource{
Mode: ManagedResourceMode,
Type: "resource_type",
Name: "resource_name",
},
},
remain: 0,
},
}

for _, tc := range tcs {
Expand Down

0 comments on commit 55600d8

Please sign in to comment.