Generalize target addresses before expansion
Before expansion happens, we only have expansion resource nodes that know their ConfigResource address. In order to properly compare these to targets within a module instance, we need to generalize the target to also be a ConfigResource. We can also remove the IgnoreIndices field from the transformer, since we have addresses that are properly scoped and can compare them in the correct context.
This commit is contained in:
parent
cbbd487130
commit
0df5a7e6cf
|
@ -5948,6 +5948,61 @@ resource "aws_instance" "foo" {
|
|||
}
|
||||
}
|
||||
|
||||
func TestContext2Plan_targetResourceInModuleInstance(t *testing.T) {
|
||||
m := testModuleInline(t, map[string]string{
|
||||
"main.tf": `
|
||||
module "mod" {
|
||||
count = 3
|
||||
source = "./mod"
|
||||
}
|
||||
`,
|
||||
"mod/main.tf": `
|
||||
resource "aws_instance" "foo" {
|
||||
}
|
||||
`,
|
||||
})
|
||||
|
||||
p := testProvider("aws")
|
||||
p.DiffFn = testDiffFn
|
||||
|
||||
target, diags := addrs.ParseTargetStr("module.mod[1].aws_instance.foo")
|
||||
if diags.HasErrors() {
|
||||
t.Fatal(diags.ErrWithWarnings())
|
||||
}
|
||||
|
||||
targets := []addrs.Targetable{target.Subject}
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Config: m,
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
Targets: targets,
|
||||
})
|
||||
|
||||
plan, diags := ctx.Plan()
|
||||
if diags.HasErrors() {
|
||||
t.Fatal(diags.ErrWithWarnings())
|
||||
}
|
||||
|
||||
expected := map[string]plans.Action{
|
||||
// the single targeted mod[1] instance
|
||||
`module.mod[1].aws_instance.foo`: plans.Create,
|
||||
}
|
||||
|
||||
for _, res := range plan.Changes.Resources {
|
||||
want := expected[res.Addr.String()]
|
||||
if res.Action != want {
|
||||
t.Fatalf("expected %s action, got: %q %s", want, res.Addr, res.Action)
|
||||
}
|
||||
delete(expected, res.Addr.String())
|
||||
}
|
||||
|
||||
for res, action := range expected {
|
||||
t.Errorf("missing %s change for %s", action, res)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContext2Plan_moduleRefIndex(t *testing.T) {
|
||||
m := testModuleInline(t, map[string]string{
|
||||
"main.tf": `
|
||||
|
|
|
@ -157,12 +157,6 @@ func (b *PlanGraphBuilder) Steps() []GraphTransformer {
|
|||
// Target
|
||||
&TargetsTransformer{
|
||||
Targets: b.Targets,
|
||||
|
||||
// Resource nodes from config have not yet been expanded for
|
||||
// "count", so we must apply targeting without indices. Exact
|
||||
// targeting will be dealt with later when these resources
|
||||
// DynamicExpand.
|
||||
IgnoreIndices: true,
|
||||
},
|
||||
|
||||
// Detect when create_before_destroy must be forced on for a particular
|
||||
|
|
|
@ -176,12 +176,6 @@ func (b *RefreshGraphBuilder) Steps() []GraphTransformer {
|
|||
// Target
|
||||
&TargetsTransformer{
|
||||
Targets: b.Targets,
|
||||
|
||||
// Resource nodes from config have not yet been expanded for
|
||||
// "count", so we must apply targeting without indices. Exact
|
||||
// targeting will be dealt with later when these resources
|
||||
// DynamicExpand.
|
||||
IgnoreIndices: true,
|
||||
},
|
||||
|
||||
// Close opened plugin connections
|
||||
|
|
|
@ -22,12 +22,6 @@ type GraphNodeTargetable interface {
|
|||
type TargetsTransformer struct {
|
||||
// List of targeted resource names specified by the user
|
||||
Targets []addrs.Targetable
|
||||
|
||||
// If set, the index portions of resource addresses will be ignored
|
||||
// for comparison. This is used when transforming a graph where
|
||||
// counted resources have not yet been expanded, since otherwise
|
||||
// the unexpanded nodes (which never have indices) would not match.
|
||||
IgnoreIndices bool
|
||||
}
|
||||
|
||||
func (t *TargetsTransformer) Transform(g *Graph) error {
|
||||
|
@ -133,25 +127,27 @@ func (t *TargetsTransformer) nodeIsTarget(v dag.Vertex, targets []addrs.Targetab
|
|||
vertexAddr = r.ResourceInstanceAddr()
|
||||
case GraphNodeConfigResource:
|
||||
vertexAddr = r.ResourceAddr()
|
||||
|
||||
default:
|
||||
// Only resource and resource instance nodes can be targeted.
|
||||
return false
|
||||
}
|
||||
|
||||
for _, targetAddr := range targets {
|
||||
if t.IgnoreIndices {
|
||||
// If we're ignoring indices then we'll convert any resource instance
|
||||
// addresses into resource addresses. We don't need to convert
|
||||
// vertexAddr because instance addresses are contained within
|
||||
// their associated resources, and so .TargetContains will take
|
||||
// care of this for us.
|
||||
switch instance := targetAddr.(type) {
|
||||
switch vertexAddr.(type) {
|
||||
case addrs.ConfigResource:
|
||||
// Before expansion happens, we only have nodes that know their
|
||||
// ConfigResource address. We need to take the more specific
|
||||
// target addresses and generalize them in order to compare with a
|
||||
// ConfigResource.
|
||||
switch target := targetAddr.(type) {
|
||||
case addrs.AbsResourceInstance:
|
||||
targetAddr = instance.ContainingResource().Config()
|
||||
case addrs.ModuleInstance:
|
||||
targetAddr = instance.Module()
|
||||
targetAddr = target.ContainingResource().Config()
|
||||
case addrs.AbsResource:
|
||||
targetAddr = target.Config()
|
||||
}
|
||||
}
|
||||
|
||||
if targetAddr.TargetContains(vertexAddr) {
|
||||
return true
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue