From 94ea534e4080f3f1bf337617473df3dc7b1357ba Mon Sep 17 00:00:00 2001 From: Nick Fagerlund Date: Tue, 27 Feb 2024 17:42:17 -0800 Subject: [PATCH] Refactor terraform.Hook to use a resource-identifying wrapper struct The terraform.Hook interface lets other areas of code perform streaming reactions to various events, generally in the service of some UI somewhere. Nearly all of the methods on this interface take an `addrs.AbsResourceInstance` as their first argument, to identify the resource that's being operated on. However, that addrs struct doesn't necessarily contain everything you might want in order to uniquely and usefully identify a resource. It has the module instance and resource instance addresses, but it lacks the provider source address, which can affect how the consuming UI should display the resource's events. (For example, Terraform Cloud wants reliable info about who maintains a given provider, what cloud provider it operates on, and where to find its documentation.) Instead of polluting `addrs.AbsResourceInstance` with extra information that isn't relevant to other call sites, let's change the first argument of each Hook method to be a wrapper struct defined in the package that owns the Hook interface, and add the provider address to that wrapper as a sibling of the resource address. This causes a big noisy commit today, but should streamline future updates to the UI-facing "identity" of a resource; existing callers can ignore any new fields they're uninterested in, or exploit new info as needed. Other than making new information available for future edits to Hook implementing types, this commit should have no effect on existing behavior. --- internal/command/views/hook_count.go | 14 ++-- internal/command/views/hook_count_test.go | 33 +++++--- internal/command/views/hook_json.go | 38 +++++----- internal/command/views/hook_json_test.go | 31 +++++--- internal/command/views/hook_ui.go | 48 ++++++------ internal/command/views/hook_ui_test.go | 33 +++++--- .../internal/stackeval/terraform_hook.go | 32 ++++---- .../internal/stackeval/terraform_hook_test.go | 27 ++++--- internal/terraform/context_apply.go | 8 +- internal/terraform/hook.go | 76 ++++++++++--------- internal/terraform/hook_mock.go | 70 ++++++++--------- internal/terraform/hook_stop.go | 34 ++++----- internal/terraform/hook_test.go | 68 ++++++++--------- .../node_resource_abstract_instance.go | 39 ++++++---- internal/terraform/node_resource_import.go | 8 +- .../terraform/node_resource_plan_instance.go | 8 +- internal/terraform/terraform_test.go | 4 +- 17 files changed, 320 insertions(+), 251 deletions(-) diff --git a/internal/command/views/hook_count.go b/internal/command/views/hook_count.go index dd9dd5408e..f4c4e2b7f8 100644 --- a/internal/command/views/hook_count.go +++ b/internal/command/views/hook_count.go @@ -45,7 +45,7 @@ func (h *countHook) Reset() { h.Imported = 0 } -func (h *countHook) PreApply(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (terraform.HookAction, error) { +func (h *countHook) PreApply(id terraform.HookResourceIdentity, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (terraform.HookAction, error) { h.Lock() defer h.Unlock() @@ -53,17 +53,17 @@ func (h *countHook) PreApply(addr addrs.AbsResourceInstance, dk addrs.DeposedKey h.pending = make(map[string]plans.Action) } - h.pending[addr.String()] = action + h.pending[id.Addr.String()] = action return terraform.HookActionContinue, nil } -func (h *countHook) PostApply(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, newState cty.Value, err error) (terraform.HookAction, error) { +func (h *countHook) PostApply(id terraform.HookResourceIdentity, dk addrs.DeposedKey, newState cty.Value, err error) (terraform.HookAction, error) { h.Lock() defer h.Unlock() if h.pending != nil { - pendingKey := addr.String() + pendingKey := id.Addr.String() if action, ok := h.pending[pendingKey]; ok { delete(h.pending, pendingKey) @@ -86,12 +86,12 @@ func (h *countHook) PostApply(addr addrs.AbsResourceInstance, dk addrs.DeposedKe return terraform.HookActionContinue, nil } -func (h *countHook) PostDiff(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (terraform.HookAction, error) { +func (h *countHook) PostDiff(id terraform.HookResourceIdentity, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (terraform.HookAction, error) { h.Lock() defer h.Unlock() // We don't count anything for data resources - if addr.Resource.Resource.Mode == addrs.DataResourceMode { + if id.Addr.Resource.Resource.Mode == addrs.DataResourceMode { return terraform.HookActionContinue, nil } @@ -109,7 +109,7 @@ func (h *countHook) PostDiff(addr addrs.AbsResourceInstance, dk addrs.DeposedKey return terraform.HookActionContinue, nil } -func (h *countHook) PostApplyImport(addr addrs.AbsResourceInstance, importing plans.ImportingSrc) (terraform.HookAction, error) { +func (h *countHook) PostApplyImport(id terraform.HookResourceIdentity, importing plans.ImportingSrc) (terraform.HookAction, error) { h.Lock() defer h.Unlock() diff --git a/internal/command/views/hook_count_test.go b/internal/command/views/hook_count_test.go index b3654b9fba..f8297d1ff7 100644 --- a/internal/command/views/hook_count_test.go +++ b/internal/command/views/hook_count_test.go @@ -17,6 +17,17 @@ import ( legacy "github.com/hashicorp/terraform/internal/legacy/terraform" ) +func testCountHookResourceID(addr addrs.AbsResourceInstance) terraform.HookResourceIdentity { + return terraform.HookResourceIdentity{ + Addr: addr, + ProviderAddr: addrs.Provider{ + Type: "test", + Namespace: "hashicorp", + Hostname: "example.com", + }, + } +} + func TestCountHook_impl(t *testing.T) { var _ terraform.Hook = new(countHook) } @@ -35,7 +46,7 @@ func TestCountHookPostDiff_DestroyDeposed(t *testing.T) { Name: k, }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance) - h.PostDiff(addr, states.DeposedKey("deadbeef"), plans.Delete, cty.DynamicVal, cty.DynamicVal) + h.PostDiff(testCountHookResourceID(addr), states.DeposedKey("deadbeef"), plans.Delete, cty.DynamicVal, cty.DynamicVal) } expected := new(countHook) @@ -66,7 +77,7 @@ func TestCountHookPostDiff_DestroyOnly(t *testing.T) { Name: k, }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance) - h.PostDiff(addr, addrs.NotDeposed, plans.Delete, cty.DynamicVal, cty.DynamicVal) + h.PostDiff(testCountHookResourceID(addr), addrs.NotDeposed, plans.Delete, cty.DynamicVal, cty.DynamicVal) } expected := new(countHook) @@ -108,7 +119,7 @@ func TestCountHookPostDiff_AddOnly(t *testing.T) { Name: k, }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance) - h.PostDiff(addr, addrs.NotDeposed, plans.Create, cty.DynamicVal, cty.DynamicVal) + h.PostDiff(testCountHookResourceID(addr), addrs.NotDeposed, plans.Create, cty.DynamicVal, cty.DynamicVal) } expected := new(countHook) @@ -153,7 +164,7 @@ func TestCountHookPostDiff_ChangeOnly(t *testing.T) { Name: k, }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance) - h.PostDiff(addr, addrs.NotDeposed, plans.Update, cty.DynamicVal, cty.DynamicVal) + h.PostDiff(testCountHookResourceID(addr), addrs.NotDeposed, plans.Update, cty.DynamicVal, cty.DynamicVal) } expected := new(countHook) @@ -184,7 +195,7 @@ func TestCountHookPostDiff_Mixed(t *testing.T) { Name: k, }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance) - h.PostDiff(addr, addrs.NotDeposed, a, cty.DynamicVal, cty.DynamicVal) + h.PostDiff(testCountHookResourceID(addr), addrs.NotDeposed, a, cty.DynamicVal, cty.DynamicVal) } expected := new(countHook) @@ -216,7 +227,7 @@ func TestCountHookPostDiff_NoChange(t *testing.T) { Name: k, }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance) - h.PostDiff(addr, addrs.NotDeposed, plans.NoOp, cty.DynamicVal, cty.DynamicVal) + h.PostDiff(testCountHookResourceID(addr), addrs.NotDeposed, plans.NoOp, cty.DynamicVal, cty.DynamicVal) } expected := new(countHook) @@ -248,7 +259,7 @@ func TestCountHookPostDiff_DataSource(t *testing.T) { Name: k, }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance) - h.PostDiff(addr, addrs.NotDeposed, a, cty.DynamicVal, cty.DynamicVal) + h.PostDiff(testCountHookResourceID(addr), addrs.NotDeposed, a, cty.DynamicVal, cty.DynamicVal) } expected := new(countHook) @@ -294,8 +305,8 @@ func TestCountHookApply_ChangeOnly(t *testing.T) { Name: k, }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance) - h.PreApply(addr, addrs.NotDeposed, plans.Update, cty.DynamicVal, cty.DynamicVal) - h.PostApply(addr, addrs.NotDeposed, cty.DynamicVal, nil) + h.PreApply(testCountHookResourceID(addr), addrs.NotDeposed, plans.Update, cty.DynamicVal, cty.DynamicVal) + h.PostApply(testCountHookResourceID(addr), addrs.NotDeposed, cty.DynamicVal, nil) } expected := &countHook{pending: make(map[string]plans.Action)} @@ -325,8 +336,8 @@ func TestCountHookApply_DestroyOnly(t *testing.T) { Name: k, }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance) - h.PreApply(addr, addrs.NotDeposed, plans.Delete, cty.DynamicVal, cty.DynamicVal) - h.PostApply(addr, addrs.NotDeposed, cty.DynamicVal, nil) + h.PreApply(testCountHookResourceID(addr), addrs.NotDeposed, plans.Delete, cty.DynamicVal, cty.DynamicVal) + h.PostApply(testCountHookResourceID(addr), addrs.NotDeposed, cty.DynamicVal, nil) } expected := &countHook{pending: make(map[string]plans.Action)} diff --git a/internal/command/views/hook_json.go b/internal/command/views/hook_json.go index f9076f61e5..0d2858faad 100644 --- a/internal/command/views/hook_json.go +++ b/internal/command/views/hook_json.go @@ -61,21 +61,21 @@ type applyProgress struct { heartbeatDone chan struct{} } -func (h *jsonHook) PreApply(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (terraform.HookAction, error) { +func (h *jsonHook) PreApply(id terraform.HookResourceIdentity, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (terraform.HookAction, error) { if action != plans.NoOp { idKey, idValue := format.ObjectValueIDOrName(priorState) - h.view.Hook(json.NewApplyStart(addr, action, idKey, idValue)) + h.view.Hook(json.NewApplyStart(id.Addr, action, idKey, idValue)) } progress := applyProgress{ - addr: addr, + addr: id.Addr, action: action, start: h.timeNow().Round(time.Second), done: make(chan struct{}), heartbeatDone: make(chan struct{}), } h.applyingLock.Lock() - h.applying[addr.String()] = progress + h.applying[id.Addr.String()] = progress h.applyingLock.Unlock() if action != plans.NoOp { @@ -98,8 +98,8 @@ func (h *jsonHook) applyingHeartbeat(progress applyProgress) { } } -func (h *jsonHook) PostApply(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, newState cty.Value, err error) (terraform.HookAction, error) { - key := addr.String() +func (h *jsonHook) PostApply(id terraform.HookResourceIdentity, dk addrs.DeposedKey, newState cty.Value, err error) (terraform.HookAction, error) { + key := id.Addr.String() h.applyingLock.Lock() progress := h.applying[key] if progress.done != nil { @@ -118,50 +118,50 @@ func (h *jsonHook) PostApply(addr addrs.AbsResourceInstance, dk addrs.DeposedKey // Errors are collected and displayed post-apply, so no need to // re-render them here. Instead just signal that this resource failed // to apply. - h.view.Hook(json.NewApplyErrored(addr, progress.action, elapsed)) + h.view.Hook(json.NewApplyErrored(id.Addr, progress.action, elapsed)) } else { idKey, idValue := format.ObjectValueID(newState) - h.view.Hook(json.NewApplyComplete(addr, progress.action, idKey, idValue, elapsed)) + h.view.Hook(json.NewApplyComplete(id.Addr, progress.action, idKey, idValue, elapsed)) } return terraform.HookActionContinue, nil } -func (h *jsonHook) PreProvisionInstanceStep(addr addrs.AbsResourceInstance, typeName string) (terraform.HookAction, error) { - h.view.Hook(json.NewProvisionStart(addr, typeName)) +func (h *jsonHook) PreProvisionInstanceStep(id terraform.HookResourceIdentity, typeName string) (terraform.HookAction, error) { + h.view.Hook(json.NewProvisionStart(id.Addr, typeName)) return terraform.HookActionContinue, nil } -func (h *jsonHook) PostProvisionInstanceStep(addr addrs.AbsResourceInstance, typeName string, err error) (terraform.HookAction, error) { +func (h *jsonHook) PostProvisionInstanceStep(id terraform.HookResourceIdentity, typeName string, err error) (terraform.HookAction, error) { if err != nil { // Errors are collected and displayed post-apply, so no need to // re-render them here. Instead just signal that this provisioner step // failed. - h.view.Hook(json.NewProvisionErrored(addr, typeName)) + h.view.Hook(json.NewProvisionErrored(id.Addr, typeName)) } else { - h.view.Hook(json.NewProvisionComplete(addr, typeName)) + h.view.Hook(json.NewProvisionComplete(id.Addr, typeName)) } return terraform.HookActionContinue, nil } -func (h *jsonHook) ProvisionOutput(addr addrs.AbsResourceInstance, typeName string, msg string) { +func (h *jsonHook) ProvisionOutput(id terraform.HookResourceIdentity, typeName string, msg string) { s := bufio.NewScanner(strings.NewReader(msg)) s.Split(scanLines) for s.Scan() { line := strings.TrimRightFunc(s.Text(), unicode.IsSpace) if line != "" { - h.view.Hook(json.NewProvisionProgress(addr, typeName, line)) + h.view.Hook(json.NewProvisionProgress(id.Addr, typeName, line)) } } } -func (h *jsonHook) PreRefresh(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, priorState cty.Value) (terraform.HookAction, error) { +func (h *jsonHook) PreRefresh(id terraform.HookResourceIdentity, dk addrs.DeposedKey, priorState cty.Value) (terraform.HookAction, error) { idKey, idValue := format.ObjectValueID(priorState) - h.view.Hook(json.NewRefreshStart(addr, idKey, idValue)) + h.view.Hook(json.NewRefreshStart(id.Addr, idKey, idValue)) return terraform.HookActionContinue, nil } -func (h *jsonHook) PostRefresh(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, priorState cty.Value, newState cty.Value) (terraform.HookAction, error) { +func (h *jsonHook) PostRefresh(id terraform.HookResourceIdentity, dk addrs.DeposedKey, priorState cty.Value, newState cty.Value) (terraform.HookAction, error) { idKey, idValue := format.ObjectValueID(newState) - h.view.Hook(json.NewRefreshComplete(addr, idKey, idValue)) + h.view.Hook(json.NewRefreshComplete(id.Addr, idKey, idValue)) return terraform.HookActionContinue, nil } diff --git a/internal/command/views/hook_json_test.go b/internal/command/views/hook_json_test.go index b0c3732e71..c8d98c0e90 100644 --- a/internal/command/views/hook_json_test.go +++ b/internal/command/views/hook_json_test.go @@ -16,6 +16,17 @@ import ( "github.com/zclconf/go-cty/cty" ) +func testJSONHookResourceID(addr addrs.AbsResourceInstance) terraform.HookResourceIdentity { + return terraform.HookResourceIdentity{ + Addr: addr, + ProviderAddr: addrs.Provider{ + Type: "test", + Namespace: "hashicorp", + Hostname: "example.com", + }, + } +} + // Test a sequence of hooks associated with creating a resource func TestJSONHook_create(t *testing.T) { streams, done := terminal.StreamsForTesting(t) @@ -48,15 +59,15 @@ func TestJSONHook_create(t *testing.T) { }), }) - action, err := hook.PreApply(addr, addrs.NotDeposed, plans.Create, priorState, plannedNewState) + action, err := hook.PreApply(testJSONHookResourceID(addr), addrs.NotDeposed, plans.Create, priorState, plannedNewState) testHookReturnValues(t, action, err) - action, err = hook.PreProvisionInstanceStep(addr, "local-exec") + action, err = hook.PreProvisionInstanceStep(testJSONHookResourceID(addr), "local-exec") testHookReturnValues(t, action, err) - hook.ProvisionOutput(addr, "local-exec", `Executing: ["/bin/sh" "-c" "touch /etc/motd"]`) + hook.ProvisionOutput(testJSONHookResourceID(addr), "local-exec", `Executing: ["/bin/sh" "-c" "touch /etc/motd"]`) - action, err = hook.PostProvisionInstanceStep(addr, "local-exec", nil) + action, err = hook.PostProvisionInstanceStep(testJSONHookResourceID(addr), "local-exec", nil) testHookReturnValues(t, action, err) // Travel 10s into the future, notify the progress goroutine, and sleep @@ -80,7 +91,7 @@ func TestJSONHook_create(t *testing.T) { now = now.Add(2 * time.Second) nowMu.Unlock() - action, err = hook.PostApply(addr, addrs.NotDeposed, plannedNewState, nil) + action, err = hook.PostApply(testJSONHookResourceID(addr), addrs.NotDeposed, plannedNewState, nil) testHookReturnValues(t, action, err) // Shut down the progress goroutine if still active @@ -203,15 +214,15 @@ func TestJSONHook_errors(t *testing.T) { }), }) - action, err := hook.PreApply(addr, addrs.NotDeposed, plans.Delete, priorState, plannedNewState) + action, err := hook.PreApply(testJSONHookResourceID(addr), addrs.NotDeposed, plans.Delete, priorState, plannedNewState) testHookReturnValues(t, action, err) provisionError := fmt.Errorf("provisioner didn't want to") - action, err = hook.PostProvisionInstanceStep(addr, "local-exec", provisionError) + action, err = hook.PostProvisionInstanceStep(testJSONHookResourceID(addr), "local-exec", provisionError) testHookReturnValues(t, action, err) applyError := fmt.Errorf("provider was sad") - action, err = hook.PostApply(addr, addrs.NotDeposed, plannedNewState, applyError) + action, err = hook.PostApply(testJSONHookResourceID(addr), addrs.NotDeposed, plannedNewState, applyError) testHookReturnValues(t, action, err) // Shut down the progress goroutine @@ -285,10 +296,10 @@ func TestJSONHook_refresh(t *testing.T) { }), }) - action, err := hook.PreRefresh(addr, addrs.NotDeposed, state) + action, err := hook.PreRefresh(testJSONHookResourceID(addr), addrs.NotDeposed, state) testHookReturnValues(t, action, err) - action, err = hook.PostRefresh(addr, addrs.NotDeposed, state, state) + action, err = hook.PostRefresh(testJSONHookResourceID(addr), addrs.NotDeposed, state, state) testHookReturnValues(t, action, err) wantResource := map[string]interface{}{ diff --git a/internal/command/views/hook_ui.go b/internal/command/views/hook_ui.go index e9771ad1c3..79638f0d83 100644 --- a/internal/command/views/hook_ui.go +++ b/internal/command/views/hook_ui.go @@ -70,8 +70,8 @@ const ( uiResourceNoOp ) -func (h *UiHook) PreApply(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (terraform.HookAction, error) { - dispAddr := addr.String() +func (h *UiHook) PreApply(id terraform.HookResourceIdentity, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (terraform.HookAction, error) { + dispAddr := id.Addr.String() if dk != addrs.NotDeposed { dispAddr = fmt.Sprintf("%s (deposed object %s)", dispAddr, dk) } @@ -120,7 +120,7 @@ func (h *UiHook) PreApply(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, a )) } - key := addr.String() + key := id.Addr.String() uiState := uiResourceState{ DispAddr: key, IDKey: idKey, @@ -183,16 +183,16 @@ func (h *UiHook) stillApplying(state uiResourceState) { } } -func (h *UiHook) PostApply(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, newState cty.Value, applyerr error) (terraform.HookAction, error) { - id := addr.String() +func (h *UiHook) PostApply(id terraform.HookResourceIdentity, dk addrs.DeposedKey, newState cty.Value, applyerr error) (terraform.HookAction, error) { + addr := id.Addr.String() h.resourcesLock.Lock() - state := h.resources[id] + state := h.resources[addr] if state.DoneCh != nil { close(state.DoneCh) } - delete(h.resources, id) + delete(h.resources, addr) h.resourcesLock.Unlock() var stateIdSuffix string @@ -222,7 +222,7 @@ func (h *UiHook) PostApply(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, return terraform.HookActionContinue, nil } - addrStr := addr.String() + addrStr := id.Addr.String() if dk != addrs.NotDeposed { addrStr = fmt.Sprintf("%s (deposed object %s)", addrStr, dk) } @@ -236,20 +236,20 @@ func (h *UiHook) PostApply(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, return terraform.HookActionContinue, nil } -func (h *UiHook) PreProvisionInstanceStep(addr addrs.AbsResourceInstance, typeName string) (terraform.HookAction, error) { +func (h *UiHook) PreProvisionInstanceStep(id terraform.HookResourceIdentity, typeName string) (terraform.HookAction, error) { h.println(fmt.Sprintf( h.view.colorize.Color("[reset][bold]%s: Provisioning with '%s'...[reset]"), - addr, typeName, + id.Addr, typeName, )) return terraform.HookActionContinue, nil } -func (h *UiHook) ProvisionOutput(addr addrs.AbsResourceInstance, typeName string, msg string) { +func (h *UiHook) ProvisionOutput(id terraform.HookResourceIdentity, typeName string, msg string) { var buf bytes.Buffer prefix := fmt.Sprintf( h.view.colorize.Color("[reset][bold]%s (%s):[reset] "), - addr, typeName, + id.Addr, typeName, ) s := bufio.NewScanner(strings.NewReader(msg)) s.Split(scanLines) @@ -263,13 +263,13 @@ func (h *UiHook) ProvisionOutput(addr addrs.AbsResourceInstance, typeName string h.println(strings.TrimSpace(buf.String())) } -func (h *UiHook) PreRefresh(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, priorState cty.Value) (terraform.HookAction, error) { +func (h *UiHook) PreRefresh(id terraform.HookResourceIdentity, dk addrs.DeposedKey, priorState cty.Value) (terraform.HookAction, error) { var stateIdSuffix string if k, v := format.ObjectValueID(priorState); k != "" && v != "" { stateIdSuffix = fmt.Sprintf(" [%s=%s]", k, v) } - addrStr := addr.String() + addrStr := id.Addr.String() if dk != addrs.NotDeposed { addrStr = fmt.Sprintf("%s (deposed object %s)", addrStr, dk) } @@ -280,18 +280,18 @@ func (h *UiHook) PreRefresh(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, return terraform.HookActionContinue, nil } -func (h *UiHook) PreImportState(addr addrs.AbsResourceInstance, importID string) (terraform.HookAction, error) { +func (h *UiHook) PreImportState(id terraform.HookResourceIdentity, importID string) (terraform.HookAction, error) { h.println(fmt.Sprintf( h.view.colorize.Color("[reset][bold]%s: Importing from ID %q..."), - addr, importID, + id.Addr, importID, )) return terraform.HookActionContinue, nil } -func (h *UiHook) PostImportState(addr addrs.AbsResourceInstance, imported []providers.ImportedResource) (terraform.HookAction, error) { +func (h *UiHook) PostImportState(id terraform.HookResourceIdentity, imported []providers.ImportedResource) (terraform.HookAction, error) { h.println(fmt.Sprintf( h.view.colorize.Color("[reset][bold][green]%s: Import prepared!"), - addr, + id.Addr, )) for _, s := range imported { h.println(fmt.Sprintf( @@ -303,28 +303,28 @@ func (h *UiHook) PostImportState(addr addrs.AbsResourceInstance, imported []prov return terraform.HookActionContinue, nil } -func (h *UiHook) PrePlanImport(addr addrs.AbsResourceInstance, importID string) (terraform.HookAction, error) { +func (h *UiHook) PrePlanImport(id terraform.HookResourceIdentity, importID string) (terraform.HookAction, error) { h.println(fmt.Sprintf( h.view.colorize.Color("[reset][bold]%s: Preparing import... [id=%s]"), - addr, importID, + id.Addr, importID, )) return terraform.HookActionContinue, nil } -func (h *UiHook) PreApplyImport(addr addrs.AbsResourceInstance, importing plans.ImportingSrc) (terraform.HookAction, error) { +func (h *UiHook) PreApplyImport(id terraform.HookResourceIdentity, importing plans.ImportingSrc) (terraform.HookAction, error) { h.println(fmt.Sprintf( h.view.colorize.Color("[reset][bold]%s: Importing... [id=%s]"), - addr, importing.ID, + id.Addr, importing.ID, )) return terraform.HookActionContinue, nil } -func (h *UiHook) PostApplyImport(addr addrs.AbsResourceInstance, importing plans.ImportingSrc) (terraform.HookAction, error) { +func (h *UiHook) PostApplyImport(id terraform.HookResourceIdentity, importing plans.ImportingSrc) (terraform.HookAction, error) { h.println(fmt.Sprintf( h.view.colorize.Color("[reset][bold]%s: Import complete [id=%s]"), - addr, importing.ID, + id.Addr, importing.ID, )) return terraform.HookActionContinue, nil diff --git a/internal/command/views/hook_ui_test.go b/internal/command/views/hook_ui_test.go index badfb501cd..8ae8ab6e06 100644 --- a/internal/command/views/hook_ui_test.go +++ b/internal/command/views/hook_ui_test.go @@ -22,6 +22,17 @@ import ( "github.com/hashicorp/terraform/internal/terraform" ) +func testUiHookResourceID(addr addrs.AbsResourceInstance) terraform.HookResourceIdentity { + return terraform.HookResourceIdentity{ + Addr: addr, + ProviderAddr: addrs.Provider{ + Type: "test", + Namespace: "hashicorp", + Hostname: "example.com", + }, + } +} + // Test the PreApply hook for creating a new resource func TestUiHookPreApply_create(t *testing.T) { streams, done := terminal.StreamsForTesting(t) @@ -51,7 +62,7 @@ func TestUiHookPreApply_create(t *testing.T) { }), }) - action, err := h.PreApply(addr, addrs.NotDeposed, plans.Create, priorState, plannedNewState) + action, err := h.PreApply(testUiHookResourceID(addr), addrs.NotDeposed, plans.Create, priorState, plannedNewState) if err != nil { t.Fatal(err) } @@ -109,7 +120,7 @@ func TestUiHookPreApply_periodicTimer(t *testing.T) { }), }) - action, err := h.PreApply(addr, addrs.NotDeposed, plans.Update, priorState, plannedNewState) + action, err := h.PreApply(testUiHookResourceID(addr), addrs.NotDeposed, plans.Update, priorState, plannedNewState) if err != nil { t.Fatal(err) } @@ -173,7 +184,7 @@ func TestUiHookPreApply_destroy(t *testing.T) { })) key := states.NewDeposedKey() - action, err := h.PreApply(addr, key, plans.Delete, priorState, plannedNewState) + action, err := h.PreApply(testUiHookResourceID(addr), key, plans.Delete, priorState, plannedNewState) if err != nil { t.Fatal(err) } @@ -224,7 +235,7 @@ func TestUiHookPostApply_colorInterpolation(t *testing.T) { "id": cty.StringVal("[blue]"), }) - action, err := h.PostApply(addr, addrs.NotDeposed, newState, nil) + action, err := h.PostApply(testUiHookResourceID(addr), addrs.NotDeposed, newState, nil) if err != nil { t.Fatal(err) } @@ -277,7 +288,7 @@ func TestUiHookPostApply_emptyState(t *testing.T) { "names": cty.List(cty.String), })) - action, err := h.PostApply(addr, addrs.NotDeposed, newState, nil) + action, err := h.PostApply(testUiHookResourceID(addr), addrs.NotDeposed, newState, nil) if err != nil { t.Fatal(err) } @@ -310,7 +321,7 @@ func TestPreProvisionInstanceStep(t *testing.T) { Name: "foo", }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance) - action, err := h.PreProvisionInstanceStep(addr, "local-exec") + action, err := h.PreProvisionInstanceStep(testUiHookResourceID(addr), "local-exec") if err != nil { t.Fatal(err) } @@ -397,7 +408,7 @@ test_instance.foo (winrm): bar view := NewView(streams) h := NewUiHook(view) - h.ProvisionOutput(addr, tc.provisioner, tc.input) + h.ProvisionOutput(testUiHookResourceID(addr), tc.provisioner, tc.input) result := done(t) if got := result.Stdout(); got != tc.wantOutput { @@ -425,7 +436,7 @@ func TestPreRefresh(t *testing.T) { "bar": cty.ListValEmpty(cty.String), }) - action, err := h.PreRefresh(addr, addrs.NotDeposed, priorState) + action, err := h.PreRefresh(testUiHookResourceID(addr), addrs.NotDeposed, priorState) if err != nil { t.Fatal(err) @@ -457,7 +468,7 @@ func TestPreRefresh_noID(t *testing.T) { "bar": cty.ListValEmpty(cty.String), }) - action, err := h.PreRefresh(addr, addrs.NotDeposed, priorState) + action, err := h.PreRefresh(testUiHookResourceID(addr), addrs.NotDeposed, priorState) if err != nil { t.Fatal(err) @@ -484,7 +495,7 @@ func TestPreImportState(t *testing.T) { Name: "foo", }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance) - action, err := h.PreImportState(addr, "test") + action, err := h.PreImportState(testUiHookResourceID(addr), "test") if err != nil { t.Fatal(err) @@ -532,7 +543,7 @@ func TestPostImportState(t *testing.T) { }, } - action, err := h.PostImportState(addr, imported) + action, err := h.PostImportState(testUiHookResourceID(addr), imported) if err != nil { t.Fatal(err) diff --git a/internal/stacks/stackruntime/internal/stackeval/terraform_hook.go b/internal/stacks/stackruntime/internal/stackeval/terraform_hook.go index 3b21a4c6d7..787d38fda7 100644 --- a/internal/stacks/stackruntime/internal/stackeval/terraform_hook.go +++ b/internal/stacks/stackruntime/internal/stackeval/terraform_hook.go @@ -56,26 +56,26 @@ func (h *componentInstanceTerraformHook) resourceInstanceObjectAddr(riAddr addrs } } -func (h *componentInstanceTerraformHook) PreDiff(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, priorState, proposedNewState cty.Value) (terraform.HookAction, error) { +func (h *componentInstanceTerraformHook) PreDiff(id terraform.HookResourceIdentity, dk addrs.DeposedKey, priorState, proposedNewState cty.Value) (terraform.HookAction, error) { hookMore(h.ctx, h.seq, h.hooks.ReportResourceInstanceStatus, &hooks.ResourceInstanceStatusHookData{ - Addr: h.resourceInstanceObjectAddr(addr, dk), + Addr: h.resourceInstanceObjectAddr(id.Addr, dk), Status: hooks.ResourceInstancePlanning, }) return terraform.HookActionContinue, nil } -func (h *componentInstanceTerraformHook) PostDiff(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (terraform.HookAction, error) { +func (h *componentInstanceTerraformHook) PostDiff(id terraform.HookResourceIdentity, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (terraform.HookAction, error) { hookMore(h.ctx, h.seq, h.hooks.ReportResourceInstanceStatus, &hooks.ResourceInstanceStatusHookData{ - Addr: h.resourceInstanceObjectAddr(addr, dk), + Addr: h.resourceInstanceObjectAddr(id.Addr, dk), Status: hooks.ResourceInstancePlanned, }) return terraform.HookActionContinue, nil } -func (h *componentInstanceTerraformHook) PreApply(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (terraform.HookAction, error) { +func (h *componentInstanceTerraformHook) PreApply(id terraform.HookResourceIdentity, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (terraform.HookAction, error) { if action != plans.NoOp { hookMore(h.ctx, h.seq, h.hooks.ReportResourceInstanceStatus, &hooks.ResourceInstanceStatusHookData{ - Addr: h.resourceInstanceObjectAddr(addr, dk), + Addr: h.resourceInstanceObjectAddr(id.Addr, dk), Status: hooks.ResourceInstanceApplying, }) } @@ -85,7 +85,7 @@ func (h *componentInstanceTerraformHook) PreApply(addr addrs.AbsResourceInstance h.resourceInstanceObjectApplyAction = addrs.MakeMap[addrs.AbsResourceInstanceObject, plans.Action]() } localObjAddr := addrs.AbsResourceInstanceObject{ - ResourceInstance: addr, + ResourceInstance: id.Addr, DeposedKey: dk, } @@ -106,9 +106,9 @@ func (h *componentInstanceTerraformHook) PreApply(addr addrs.AbsResourceInstance return terraform.HookActionContinue, nil } -func (h *componentInstanceTerraformHook) PostApply(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, newState cty.Value, err error) (terraform.HookAction, error) { - objAddr := h.resourceInstanceObjectAddr(addr, dk) - localObjAddr := addr.DeposedObject(dk) +func (h *componentInstanceTerraformHook) PostApply(id terraform.HookResourceIdentity, dk addrs.DeposedKey, newState cty.Value, err error) (terraform.HookAction, error) { + objAddr := h.resourceInstanceObjectAddr(id.Addr, dk) + localObjAddr := id.Addr.DeposedObject(dk) h.mu.Lock() action, ok := h.resourceInstanceObjectApplyAction.GetOk(localObjAddr) @@ -143,19 +143,19 @@ func (h *componentInstanceTerraformHook) PostApply(addr addrs.AbsResourceInstanc return terraform.HookActionContinue, nil } -func (h *componentInstanceTerraformHook) PreProvisionInstanceStep(addr addrs.AbsResourceInstance, typeName string) (terraform.HookAction, error) { +func (h *componentInstanceTerraformHook) PreProvisionInstanceStep(id terraform.HookResourceIdentity, typeName string) (terraform.HookAction, error) { // NOTE: We assume provisioner events are always about the "current" // object for the given resource instance, because the hook API does // not include a DeposedKey argument in this case. hookMore(h.ctx, h.seq, h.hooks.ReportResourceInstanceProvisionerStatus, &hooks.ResourceInstanceProvisionerHookData{ - Addr: h.resourceInstanceObjectAddr(addr, addrs.NotDeposed), + Addr: h.resourceInstanceObjectAddr(id.Addr, addrs.NotDeposed), Name: typeName, Status: hooks.ProvisionerProvisioning, }) return terraform.HookActionContinue, nil } -func (h *componentInstanceTerraformHook) ProvisionOutput(addr addrs.AbsResourceInstance, typeName string, msg string) { +func (h *componentInstanceTerraformHook) ProvisionOutput(id terraform.HookResourceIdentity, typeName string, msg string) { // TODO: determine whether we should continue line splitting as we do with jsonHook // NOTE: We assume provisioner events are always about the "current" @@ -163,14 +163,14 @@ func (h *componentInstanceTerraformHook) ProvisionOutput(addr addrs.AbsResourceI // not include a DeposedKey argument in this case. output := msg hookMore(h.ctx, h.seq, h.hooks.ReportResourceInstanceProvisionerStatus, &hooks.ResourceInstanceProvisionerHookData{ - Addr: h.resourceInstanceObjectAddr(addr, addrs.NotDeposed), + Addr: h.resourceInstanceObjectAddr(id.Addr, addrs.NotDeposed), Name: typeName, Status: hooks.ProvisionerProvisioning, Output: &output, }) } -func (h *componentInstanceTerraformHook) PostProvisionInstanceStep(addr addrs.AbsResourceInstance, typeName string, err error) (terraform.HookAction, error) { +func (h *componentInstanceTerraformHook) PostProvisionInstanceStep(id terraform.HookResourceIdentity, typeName string, err error) (terraform.HookAction, error) { // NOTE: We assume provisioner events are always about the "current" // object for the given resource instance, because the hook API does // not include a DeposedKey argument in this case. @@ -179,7 +179,7 @@ func (h *componentInstanceTerraformHook) PostProvisionInstanceStep(addr addrs.Ab status = hooks.ProvisionerErrored } hookMore(h.ctx, h.seq, h.hooks.ReportResourceInstanceProvisionerStatus, &hooks.ResourceInstanceProvisionerHookData{ - Addr: h.resourceInstanceObjectAddr(addr, addrs.NotDeposed), + Addr: h.resourceInstanceObjectAddr(id.Addr, addrs.NotDeposed), Name: typeName, Status: status, }) diff --git a/internal/stacks/stackruntime/internal/stackeval/terraform_hook_test.go b/internal/stacks/stackruntime/internal/stackeval/terraform_hook_test.go index 809908da75..03a87c6cec 100644 --- a/internal/stacks/stackruntime/internal/stackeval/terraform_hook_test.go +++ b/internal/stacks/stackruntime/internal/stackeval/terraform_hook_test.go @@ -56,6 +56,15 @@ func TestTerraformHook(t *testing.T) { Key: addrs.NoKey, }, } + providerAddr := addrs.Provider{ + Type: "foo", + Namespace: "hashicorp", + Hostname: "example.com", + } + resourceIdentity := terraform.HookResourceIdentity{ + Addr: resourceAddr, + ProviderAddr: providerAddr, + } stackAddr := stackaddrs.AbsResourceInstanceObject{ Component: componentAddr, Item: resourceAddr.CurrentObject(), @@ -63,7 +72,7 @@ func TestTerraformHook(t *testing.T) { t.Run("PreDiff", func(t *testing.T) { hook := makeHook() - action, err := hook.PreDiff(resourceAddr, addrs.NotDeposed, cty.NilVal, cty.NilVal) + action, err := hook.PreDiff(resourceIdentity, addrs.NotDeposed, cty.NilVal, cty.NilVal) if err != nil { t.Errorf("unexpected error: %s", err) } @@ -85,7 +94,7 @@ func TestTerraformHook(t *testing.T) { t.Run("PostDiff", func(t *testing.T) { hook := makeHook() - action, err := hook.PostDiff(resourceAddr, addrs.NotDeposed, plans.Create, cty.NilVal, cty.NilVal) + action, err := hook.PostDiff(resourceIdentity, addrs.NotDeposed, plans.Create, cty.NilVal, cty.NilVal) if err != nil { t.Errorf("unexpected error: %s", err) } @@ -107,7 +116,7 @@ func TestTerraformHook(t *testing.T) { t.Run("PreApply", func(t *testing.T) { hook := makeHook() - action, err := hook.PreApply(resourceAddr, addrs.NotDeposed, plans.Create, cty.NilVal, cty.NilVal) + action, err := hook.PreApply(resourceIdentity, addrs.NotDeposed, plans.Create, cty.NilVal, cty.NilVal) if err != nil { t.Errorf("unexpected error: %s", err) } @@ -130,7 +139,7 @@ func TestTerraformHook(t *testing.T) { t.Run("PostApply", func(t *testing.T) { hook := makeHook() // It is invalid to call PostApply without first calling PreApply - action, err := hook.PreApply(resourceAddr, addrs.NotDeposed, plans.Create, cty.NilVal, cty.NilVal) + action, err := hook.PreApply(resourceIdentity, addrs.NotDeposed, plans.Create, cty.NilVal, cty.NilVal) if err != nil { t.Errorf("unexpected error: %s", err) } @@ -138,7 +147,7 @@ func TestTerraformHook(t *testing.T) { t.Errorf("wrong action: %#v", action) } - action, err = hook.PostApply(resourceAddr, addrs.NotDeposed, cty.NilVal, nil) + action, err = hook.PostApply(resourceIdentity, addrs.NotDeposed, cty.NilVal, nil) if err != nil { t.Errorf("unexpected error: %s", err) } @@ -161,7 +170,7 @@ func TestTerraformHook(t *testing.T) { t.Run("PostApply errored", func(t *testing.T) { hook := makeHook() // It is invalid to call PostApply without first calling PreApply - action, err := hook.PreApply(resourceAddr, addrs.NotDeposed, plans.Create, cty.NilVal, cty.NilVal) + action, err := hook.PreApply(resourceIdentity, addrs.NotDeposed, plans.Create, cty.NilVal, cty.NilVal) if err != nil { t.Errorf("unexpected error: %s", err) } @@ -169,7 +178,7 @@ func TestTerraformHook(t *testing.T) { t.Errorf("wrong action: %#v", action) } - action, err = hook.PostApply(resourceAddr, addrs.NotDeposed, cty.NilVal, errors.New("splines unreticulatable")) + action, err = hook.PostApply(resourceIdentity, addrs.NotDeposed, cty.NilVal, errors.New("splines unreticulatable")) if err != nil { t.Errorf("unexpected error: %s", err) } @@ -235,12 +244,12 @@ func TestTerraformHook(t *testing.T) { hook := makeHook() for _, action := range tc.actions { - _, err := hook.PreApply(resourceAddr, addrs.NotDeposed, action, cty.NilVal, cty.NilVal) + _, err := hook.PreApply(resourceIdentity, addrs.NotDeposed, action, cty.NilVal, cty.NilVal) if err != nil { t.Fatalf("unexpected error in PreApply: %s", err) } - _, err = hook.PostApply(resourceAddr, addrs.NotDeposed, cty.NilVal, nil) + _, err = hook.PostApply(resourceIdentity, addrs.NotDeposed, cty.NilVal, nil) if err != nil { t.Fatalf("unexpected error in PostApply: %s", err) } diff --git a/internal/terraform/context_apply.go b/internal/terraform/context_apply.go index 10686b6f06..11d7ad892a 100644 --- a/internal/terraform/context_apply.go +++ b/internal/terraform/context_apply.go @@ -121,11 +121,15 @@ func (c *Context) ApplyAndEval(plan *plans.Plan, config *configs.Config, opts *A // Import is a no-op change during an apply (all the real action happens during the plan) but we'd // like to show some helpful output that mirrors the way we show other changes. if rc.Importing != nil { + hookResourceID := HookResourceIdentity{ + Addr: rc.Addr, + ProviderAddr: rc.ProviderAddr.Provider, + } for _, h := range c.hooks { // In future, we may need to call PostApplyImport separately elsewhere in the apply // operation. For now, though, we'll call Pre and Post hooks together. - h.PreApplyImport(rc.Addr, *rc.Importing) - h.PostApplyImport(rc.Addr, *rc.Importing) + h.PreApplyImport(hookResourceID, *rc.Importing) + h.PostApplyImport(hookResourceID, *rc.Importing) } } } diff --git a/internal/terraform/hook.go b/internal/terraform/hook.go index 49acfb1540..2e457f2814 100644 --- a/internal/terraform/hook.go +++ b/internal/terraform/hook.go @@ -25,6 +25,14 @@ const ( HookActionHalt ) +// HookResourceIdentity is passed to Hook interface methods to fully identify +// the resource instance being operated on. It currently includes the resource +// address and the provider address. +type HookResourceIdentity struct { + Addr addrs.AbsResourceInstance + ProviderAddr addrs.Provider +} + // Hook is the interface that must be implemented to hook into various // parts of Terraform, allowing you to inspect or change behavior at runtime. // @@ -36,14 +44,14 @@ type Hook interface { // PreApply and PostApply are called before and after an action for a // single instance is applied. The error argument in PostApply is the // error, if any, that was returned from the provider Apply call itself. - PreApply(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (HookAction, error) - PostApply(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, newState cty.Value, err error) (HookAction, error) + PreApply(id HookResourceIdentity, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (HookAction, error) + PostApply(id HookResourceIdentity, dk addrs.DeposedKey, newState cty.Value, err error) (HookAction, error) // PreDiff and PostDiff are called before and after a provider is given // the opportunity to customize the proposed new state to produce the // planned new state. - PreDiff(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, priorState, proposedNewState cty.Value) (HookAction, error) - PostDiff(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (HookAction, error) + PreDiff(id HookResourceIdentity, dk addrs.DeposedKey, priorState, proposedNewState cty.Value) (HookAction, error) + PostDiff(id HookResourceIdentity, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (HookAction, error) // The provisioning hooks signal both the overall start end end of // provisioning for a particular instance and of each of the individual @@ -63,32 +71,32 @@ type Hook interface { // This will be called multiple times as output comes in, with each call // representing one line of output. It cannot control whether the // provisioner continues running. - PreProvisionInstance(addr addrs.AbsResourceInstance, state cty.Value) (HookAction, error) - PostProvisionInstance(addr addrs.AbsResourceInstance, state cty.Value) (HookAction, error) - PreProvisionInstanceStep(addr addrs.AbsResourceInstance, typeName string) (HookAction, error) - PostProvisionInstanceStep(addr addrs.AbsResourceInstance, typeName string, err error) (HookAction, error) - ProvisionOutput(addr addrs.AbsResourceInstance, typeName string, line string) + PreProvisionInstance(id HookResourceIdentity, state cty.Value) (HookAction, error) + PostProvisionInstance(id HookResourceIdentity, state cty.Value) (HookAction, error) + PreProvisionInstanceStep(id HookResourceIdentity, typeName string) (HookAction, error) + PostProvisionInstanceStep(id HookResourceIdentity, typeName string, err error) (HookAction, error) + ProvisionOutput(id HookResourceIdentity, typeName string, line string) // PreRefresh and PostRefresh are called before and after a single // resource state is refreshed, respectively. - PreRefresh(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, priorState cty.Value) (HookAction, error) - PostRefresh(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, priorState cty.Value, newState cty.Value) (HookAction, error) + PreRefresh(id HookResourceIdentity, dk addrs.DeposedKey, priorState cty.Value) (HookAction, error) + PostRefresh(id HookResourceIdentity, dk addrs.DeposedKey, priorState cty.Value, newState cty.Value) (HookAction, error) // PreImportState and PostImportState are called before and after // (respectively) each state import operation for a given resource address when // using the legacy import command. - PreImportState(addr addrs.AbsResourceInstance, importID string) (HookAction, error) - PostImportState(addr addrs.AbsResourceInstance, imported []providers.ImportedResource) (HookAction, error) + PreImportState(id HookResourceIdentity, importID string) (HookAction, error) + PostImportState(id HookResourceIdentity, imported []providers.ImportedResource) (HookAction, error) // PrePlanImport and PostPlanImport are called during a plan before and after planning to import // a new resource using the configuration-driven import workflow. - PrePlanImport(addr addrs.AbsResourceInstance, importID string) (HookAction, error) - PostPlanImport(addr addrs.AbsResourceInstance, imported []providers.ImportedResource) (HookAction, error) + PrePlanImport(id HookResourceIdentity, importID string) (HookAction, error) + PostPlanImport(id HookResourceIdentity, imported []providers.ImportedResource) (HookAction, error) // PreApplyImport and PostApplyImport are called during an apply for each imported resource when // using the configuration-driven import workflow. - PreApplyImport(addr addrs.AbsResourceInstance, importing plans.ImportingSrc) (HookAction, error) - PostApplyImport(addr addrs.AbsResourceInstance, importing plans.ImportingSrc) (HookAction, error) + PreApplyImport(id HookResourceIdentity, importing plans.ImportingSrc) (HookAction, error) + PostApplyImport(id HookResourceIdentity, importing plans.ImportingSrc) (HookAction, error) // Stopping is called if an external signal requests that Terraform // gracefully abort an operation in progress. @@ -119,70 +127,70 @@ type NilHook struct{} var _ Hook = (*NilHook)(nil) -func (*NilHook) PreApply(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (HookAction, error) { +func (*NilHook) PreApply(id HookResourceIdentity, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (HookAction, error) { return HookActionContinue, nil } -func (*NilHook) PostApply(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, newState cty.Value, err error) (HookAction, error) { +func (*NilHook) PostApply(id HookResourceIdentity, dk addrs.DeposedKey, newState cty.Value, err error) (HookAction, error) { return HookActionContinue, nil } -func (*NilHook) PreDiff(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, priorState, proposedNewState cty.Value) (HookAction, error) { +func (*NilHook) PreDiff(id HookResourceIdentity, dk addrs.DeposedKey, priorState, proposedNewState cty.Value) (HookAction, error) { return HookActionContinue, nil } -func (*NilHook) PostDiff(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (HookAction, error) { +func (*NilHook) PostDiff(id HookResourceIdentity, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (HookAction, error) { return HookActionContinue, nil } -func (*NilHook) PreProvisionInstance(addr addrs.AbsResourceInstance, state cty.Value) (HookAction, error) { +func (*NilHook) PreProvisionInstance(id HookResourceIdentity, state cty.Value) (HookAction, error) { return HookActionContinue, nil } -func (*NilHook) PostProvisionInstance(addr addrs.AbsResourceInstance, state cty.Value) (HookAction, error) { +func (*NilHook) PostProvisionInstance(id HookResourceIdentity, state cty.Value) (HookAction, error) { return HookActionContinue, nil } -func (*NilHook) PreProvisionInstanceStep(addr addrs.AbsResourceInstance, typeName string) (HookAction, error) { +func (*NilHook) PreProvisionInstanceStep(id HookResourceIdentity, typeName string) (HookAction, error) { return HookActionContinue, nil } -func (*NilHook) PostProvisionInstanceStep(addr addrs.AbsResourceInstance, typeName string, err error) (HookAction, error) { +func (*NilHook) PostProvisionInstanceStep(id HookResourceIdentity, typeName string, err error) (HookAction, error) { return HookActionContinue, nil } -func (*NilHook) ProvisionOutput(addr addrs.AbsResourceInstance, typeName string, line string) { +func (*NilHook) ProvisionOutput(id HookResourceIdentity, typeName string, line string) { } -func (*NilHook) PreRefresh(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, priorState cty.Value) (HookAction, error) { +func (*NilHook) PreRefresh(id HookResourceIdentity, dk addrs.DeposedKey, priorState cty.Value) (HookAction, error) { return HookActionContinue, nil } -func (*NilHook) PostRefresh(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, priorState cty.Value, newState cty.Value) (HookAction, error) { +func (*NilHook) PostRefresh(id HookResourceIdentity, dk addrs.DeposedKey, priorState cty.Value, newState cty.Value) (HookAction, error) { return HookActionContinue, nil } -func (*NilHook) PreImportState(addr addrs.AbsResourceInstance, importID string) (HookAction, error) { +func (*NilHook) PreImportState(id HookResourceIdentity, importID string) (HookAction, error) { return HookActionContinue, nil } -func (*NilHook) PostImportState(addr addrs.AbsResourceInstance, imported []providers.ImportedResource) (HookAction, error) { +func (*NilHook) PostImportState(id HookResourceIdentity, imported []providers.ImportedResource) (HookAction, error) { return HookActionContinue, nil } -func (h *NilHook) PrePlanImport(addr addrs.AbsResourceInstance, importID string) (HookAction, error) { +func (h *NilHook) PrePlanImport(id HookResourceIdentity, importID string) (HookAction, error) { return HookActionContinue, nil } -func (h *NilHook) PostPlanImport(addr addrs.AbsResourceInstance, imported []providers.ImportedResource) (HookAction, error) { +func (h *NilHook) PostPlanImport(id HookResourceIdentity, imported []providers.ImportedResource) (HookAction, error) { return HookActionContinue, nil } -func (h *NilHook) PreApplyImport(addr addrs.AbsResourceInstance, importing plans.ImportingSrc) (HookAction, error) { +func (h *NilHook) PreApplyImport(id HookResourceIdentity, importing plans.ImportingSrc) (HookAction, error) { return HookActionContinue, nil } -func (h *NilHook) PostApplyImport(addr addrs.AbsResourceInstance, importing plans.ImportingSrc) (HookAction, error) { +func (h *NilHook) PostApplyImport(id HookResourceIdentity, importing plans.ImportingSrc) (HookAction, error) { return HookActionContinue, nil } diff --git a/internal/terraform/hook_mock.go b/internal/terraform/hook_mock.go index 1fa9155b07..518212c838 100644 --- a/internal/terraform/hook_mock.go +++ b/internal/terraform/hook_mock.go @@ -141,12 +141,12 @@ type MockHook struct { var _ Hook = (*MockHook)(nil) -func (h *MockHook) PreApply(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (HookAction, error) { +func (h *MockHook) PreApply(id HookResourceIdentity, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (HookAction, error) { h.Lock() defer h.Unlock() h.PreApplyCalled = true - h.PreApplyAddr = addr + h.PreApplyAddr = id.Addr h.PreApplyGen = dk h.PreApplyAction = action h.PreApplyPriorState = priorState @@ -154,41 +154,41 @@ func (h *MockHook) PreApply(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, return h.PreApplyReturn, h.PreApplyError } -func (h *MockHook) PostApply(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, newState cty.Value, err error) (HookAction, error) { +func (h *MockHook) PostApply(id HookResourceIdentity, dk addrs.DeposedKey, newState cty.Value, err error) (HookAction, error) { h.Lock() defer h.Unlock() h.PostApplyCalled = true - h.PostApplyAddr = addr + h.PostApplyAddr = id.Addr h.PostApplyGen = dk h.PostApplyNewState = newState h.PostApplyError = err if h.PostApplyFn != nil { - return h.PostApplyFn(addr, dk, newState, err) + return h.PostApplyFn(id.Addr, dk, newState, err) } return h.PostApplyReturn, h.PostApplyReturnError } -func (h *MockHook) PreDiff(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, priorState, proposedNewState cty.Value) (HookAction, error) { +func (h *MockHook) PreDiff(id HookResourceIdentity, dk addrs.DeposedKey, priorState, proposedNewState cty.Value) (HookAction, error) { h.Lock() defer h.Unlock() h.PreDiffCalled = true - h.PreDiffAddr = addr + h.PreDiffAddr = id.Addr h.PreDiffGen = dk h.PreDiffPriorState = priorState h.PreDiffProposedState = proposedNewState return h.PreDiffReturn, h.PreDiffError } -func (h *MockHook) PostDiff(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (HookAction, error) { +func (h *MockHook) PostDiff(id HookResourceIdentity, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (HookAction, error) { h.Lock() defer h.Unlock() h.PostDiffCalled = true - h.PostDiffAddr = addr + h.PostDiffAddr = id.Addr h.PostDiffGen = dk h.PostDiffAction = action h.PostDiffPriorState = priorState @@ -196,123 +196,123 @@ func (h *MockHook) PostDiff(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, return h.PostDiffReturn, h.PostDiffError } -func (h *MockHook) PreProvisionInstance(addr addrs.AbsResourceInstance, state cty.Value) (HookAction, error) { +func (h *MockHook) PreProvisionInstance(id HookResourceIdentity, state cty.Value) (HookAction, error) { h.Lock() defer h.Unlock() h.PreProvisionInstanceCalled = true - h.PreProvisionInstanceAddr = addr + h.PreProvisionInstanceAddr = id.Addr h.PreProvisionInstanceState = state return h.PreProvisionInstanceReturn, h.PreProvisionInstanceError } -func (h *MockHook) PostProvisionInstance(addr addrs.AbsResourceInstance, state cty.Value) (HookAction, error) { +func (h *MockHook) PostProvisionInstance(id HookResourceIdentity, state cty.Value) (HookAction, error) { h.Lock() defer h.Unlock() h.PostProvisionInstanceCalled = true - h.PostProvisionInstanceAddr = addr + h.PostProvisionInstanceAddr = id.Addr h.PostProvisionInstanceState = state return h.PostProvisionInstanceReturn, h.PostProvisionInstanceError } -func (h *MockHook) PreProvisionInstanceStep(addr addrs.AbsResourceInstance, typeName string) (HookAction, error) { +func (h *MockHook) PreProvisionInstanceStep(id HookResourceIdentity, typeName string) (HookAction, error) { h.Lock() defer h.Unlock() h.PreProvisionInstanceStepCalled = true - h.PreProvisionInstanceStepAddr = addr + h.PreProvisionInstanceStepAddr = id.Addr h.PreProvisionInstanceStepProvisionerType = typeName return h.PreProvisionInstanceStepReturn, h.PreProvisionInstanceStepError } -func (h *MockHook) PostProvisionInstanceStep(addr addrs.AbsResourceInstance, typeName string, err error) (HookAction, error) { +func (h *MockHook) PostProvisionInstanceStep(id HookResourceIdentity, typeName string, err error) (HookAction, error) { h.Lock() defer h.Unlock() h.PostProvisionInstanceStepCalled = true - h.PostProvisionInstanceStepAddr = addr + h.PostProvisionInstanceStepAddr = id.Addr h.PostProvisionInstanceStepProvisionerType = typeName h.PostProvisionInstanceStepErrorArg = err return h.PostProvisionInstanceStepReturn, h.PostProvisionInstanceStepError } -func (h *MockHook) ProvisionOutput(addr addrs.AbsResourceInstance, typeName string, line string) { +func (h *MockHook) ProvisionOutput(id HookResourceIdentity, typeName string, line string) { h.Lock() defer h.Unlock() h.ProvisionOutputCalled = true - h.ProvisionOutputAddr = addr + h.ProvisionOutputAddr = id.Addr h.ProvisionOutputProvisionerType = typeName h.ProvisionOutputMessage = line } -func (h *MockHook) PreRefresh(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, priorState cty.Value) (HookAction, error) { +func (h *MockHook) PreRefresh(id HookResourceIdentity, dk addrs.DeposedKey, priorState cty.Value) (HookAction, error) { h.Lock() defer h.Unlock() h.PreRefreshCalled = true - h.PreRefreshAddr = addr + h.PreRefreshAddr = id.Addr h.PreRefreshGen = dk h.PreRefreshPriorState = priorState return h.PreRefreshReturn, h.PreRefreshError } -func (h *MockHook) PostRefresh(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, priorState cty.Value, newState cty.Value) (HookAction, error) { +func (h *MockHook) PostRefresh(id HookResourceIdentity, dk addrs.DeposedKey, priorState cty.Value, newState cty.Value) (HookAction, error) { h.Lock() defer h.Unlock() h.PostRefreshCalled = true - h.PostRefreshAddr = addr + h.PostRefreshAddr = id.Addr h.PostRefreshPriorState = priorState h.PostRefreshNewState = newState return h.PostRefreshReturn, h.PostRefreshError } -func (h *MockHook) PreImportState(addr addrs.AbsResourceInstance, importID string) (HookAction, error) { +func (h *MockHook) PreImportState(id HookResourceIdentity, importID string) (HookAction, error) { h.Lock() defer h.Unlock() h.PreImportStateCalled = true - h.PreImportStateAddr = addr + h.PreImportStateAddr = id.Addr h.PreImportStateID = importID return h.PreImportStateReturn, h.PreImportStateError } -func (h *MockHook) PostImportState(addr addrs.AbsResourceInstance, imported []providers.ImportedResource) (HookAction, error) { +func (h *MockHook) PostImportState(id HookResourceIdentity, imported []providers.ImportedResource) (HookAction, error) { h.Lock() defer h.Unlock() h.PostImportStateCalled = true - h.PostImportStateAddr = addr + h.PostImportStateAddr = id.Addr h.PostImportStateNewStates = imported return h.PostImportStateReturn, h.PostImportStateError } -func (h *MockHook) PrePlanImport(addr addrs.AbsResourceInstance, importID string) (HookAction, error) { +func (h *MockHook) PrePlanImport(id HookResourceIdentity, importID string) (HookAction, error) { h.PrePlanImportCalled = true - h.PrePlanImportAddr = addr + h.PrePlanImportAddr = id.Addr return h.PrePlanImportReturn, h.PrePlanImportError } -func (h *MockHook) PostPlanImport(addr addrs.AbsResourceInstance, imported []providers.ImportedResource) (HookAction, error) { +func (h *MockHook) PostPlanImport(id HookResourceIdentity, imported []providers.ImportedResource) (HookAction, error) { h.PostPlanImportCalled = true - h.PostPlanImportAddr = addr + h.PostPlanImportAddr = id.Addr return h.PostPlanImportReturn, h.PostPlanImportError } -func (h *MockHook) PreApplyImport(addr addrs.AbsResourceInstance, importing plans.ImportingSrc) (HookAction, error) { +func (h *MockHook) PreApplyImport(id HookResourceIdentity, importing plans.ImportingSrc) (HookAction, error) { h.PreApplyImportCalled = true - h.PreApplyImportAddr = addr + h.PreApplyImportAddr = id.Addr return h.PreApplyImportReturn, h.PreApplyImportError } -func (h *MockHook) PostApplyImport(addr addrs.AbsResourceInstance, importing plans.ImportingSrc) (HookAction, error) { +func (h *MockHook) PostApplyImport(id HookResourceIdentity, importing plans.ImportingSrc) (HookAction, error) { h.Lock() defer h.Unlock() h.PostApplyImportCalled = true - h.PostApplyImportAddr = addr + h.PostApplyImportAddr = id.Addr return h.PostApplyImportReturn, h.PostApplyImportError } diff --git a/internal/terraform/hook_stop.go b/internal/terraform/hook_stop.go index df74629abd..f3e5129046 100644 --- a/internal/terraform/hook_stop.go +++ b/internal/terraform/hook_stop.go @@ -23,70 +23,70 @@ type stopHook struct { var _ Hook = (*stopHook)(nil) -func (h *stopHook) PreApply(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (HookAction, error) { +func (h *stopHook) PreApply(id HookResourceIdentity, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (HookAction, error) { return h.hook() } -func (h *stopHook) PostApply(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, newState cty.Value, err error) (HookAction, error) { +func (h *stopHook) PostApply(id HookResourceIdentity, dk addrs.DeposedKey, newState cty.Value, err error) (HookAction, error) { return h.hook() } -func (h *stopHook) PreDiff(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, priorState, proposedNewState cty.Value) (HookAction, error) { +func (h *stopHook) PreDiff(id HookResourceIdentity, dk addrs.DeposedKey, priorState, proposedNewState cty.Value) (HookAction, error) { return h.hook() } -func (h *stopHook) PostDiff(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (HookAction, error) { +func (h *stopHook) PostDiff(id HookResourceIdentity, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (HookAction, error) { return h.hook() } -func (h *stopHook) PreProvisionInstance(addr addrs.AbsResourceInstance, state cty.Value) (HookAction, error) { +func (h *stopHook) PreProvisionInstance(id HookResourceIdentity, state cty.Value) (HookAction, error) { return h.hook() } -func (h *stopHook) PostProvisionInstance(addr addrs.AbsResourceInstance, state cty.Value) (HookAction, error) { +func (h *stopHook) PostProvisionInstance(id HookResourceIdentity, state cty.Value) (HookAction, error) { return h.hook() } -func (h *stopHook) PreProvisionInstanceStep(addr addrs.AbsResourceInstance, typeName string) (HookAction, error) { +func (h *stopHook) PreProvisionInstanceStep(id HookResourceIdentity, typeName string) (HookAction, error) { return h.hook() } -func (h *stopHook) PostProvisionInstanceStep(addr addrs.AbsResourceInstance, typeName string, err error) (HookAction, error) { +func (h *stopHook) PostProvisionInstanceStep(id HookResourceIdentity, typeName string, err error) (HookAction, error) { return h.hook() } -func (h *stopHook) ProvisionOutput(addr addrs.AbsResourceInstance, typeName string, line string) { +func (h *stopHook) ProvisionOutput(id HookResourceIdentity, typeName string, line string) { } -func (h *stopHook) PreRefresh(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, priorState cty.Value) (HookAction, error) { +func (h *stopHook) PreRefresh(id HookResourceIdentity, dk addrs.DeposedKey, priorState cty.Value) (HookAction, error) { return h.hook() } -func (h *stopHook) PostRefresh(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, priorState cty.Value, newState cty.Value) (HookAction, error) { +func (h *stopHook) PostRefresh(id HookResourceIdentity, dk addrs.DeposedKey, priorState cty.Value, newState cty.Value) (HookAction, error) { return h.hook() } -func (h *stopHook) PreImportState(addr addrs.AbsResourceInstance, importID string) (HookAction, error) { +func (h *stopHook) PreImportState(id HookResourceIdentity, importID string) (HookAction, error) { return h.hook() } -func (h *stopHook) PostImportState(addr addrs.AbsResourceInstance, imported []providers.ImportedResource) (HookAction, error) { +func (h *stopHook) PostImportState(id HookResourceIdentity, imported []providers.ImportedResource) (HookAction, error) { return h.hook() } -func (h *stopHook) PrePlanImport(addr addrs.AbsResourceInstance, importID string) (HookAction, error) { +func (h *stopHook) PrePlanImport(id HookResourceIdentity, importID string) (HookAction, error) { return h.hook() } -func (h *stopHook) PostPlanImport(addr addrs.AbsResourceInstance, imported []providers.ImportedResource) (HookAction, error) { +func (h *stopHook) PostPlanImport(id HookResourceIdentity, imported []providers.ImportedResource) (HookAction, error) { return h.hook() } -func (h *stopHook) PreApplyImport(addr addrs.AbsResourceInstance, importing plans.ImportingSrc) (HookAction, error) { +func (h *stopHook) PreApplyImport(id HookResourceIdentity, importing plans.ImportingSrc) (HookAction, error) { return h.hook() } -func (h *stopHook) PostApplyImport(addr addrs.AbsResourceInstance, importing plans.ImportingSrc) (HookAction, error) { +func (h *stopHook) PostApplyImport(id HookResourceIdentity, importing plans.ImportingSrc) (HookAction, error) { return h.hook() } diff --git a/internal/terraform/hook_test.go b/internal/terraform/hook_test.go index c96c3d57ba..5727e7c746 100644 --- a/internal/terraform/hook_test.go +++ b/internal/terraform/hook_test.go @@ -37,121 +37,121 @@ type testHookCall struct { InstanceID string } -func (h *testHook) PreApply(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (HookAction, error) { +func (h *testHook) PreApply(id HookResourceIdentity, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (HookAction, error) { h.mu.Lock() defer h.mu.Unlock() - h.Calls = append(h.Calls, &testHookCall{"PreApply", addr.String()}) + h.Calls = append(h.Calls, &testHookCall{"PreApply", id.Addr.String()}) return HookActionContinue, nil } -func (h *testHook) PostApply(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, newState cty.Value, err error) (HookAction, error) { +func (h *testHook) PostApply(id HookResourceIdentity, dk addrs.DeposedKey, newState cty.Value, err error) (HookAction, error) { h.mu.Lock() defer h.mu.Unlock() - h.Calls = append(h.Calls, &testHookCall{"PostApply", addr.String()}) + h.Calls = append(h.Calls, &testHookCall{"PostApply", id.Addr.String()}) return HookActionContinue, nil } -func (h *testHook) PreDiff(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, priorState, proposedNewState cty.Value) (HookAction, error) { +func (h *testHook) PreDiff(id HookResourceIdentity, dk addrs.DeposedKey, priorState, proposedNewState cty.Value) (HookAction, error) { h.mu.Lock() defer h.mu.Unlock() - h.Calls = append(h.Calls, &testHookCall{"PreDiff", addr.String()}) + h.Calls = append(h.Calls, &testHookCall{"PreDiff", id.Addr.String()}) return HookActionContinue, nil } -func (h *testHook) PostDiff(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (HookAction, error) { +func (h *testHook) PostDiff(id HookResourceIdentity, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (HookAction, error) { h.mu.Lock() defer h.mu.Unlock() - h.Calls = append(h.Calls, &testHookCall{"PostDiff", addr.String()}) + h.Calls = append(h.Calls, &testHookCall{"PostDiff", id.Addr.String()}) return HookActionContinue, nil } -func (h *testHook) PreProvisionInstance(addr addrs.AbsResourceInstance, state cty.Value) (HookAction, error) { +func (h *testHook) PreProvisionInstance(id HookResourceIdentity, state cty.Value) (HookAction, error) { h.mu.Lock() defer h.mu.Unlock() - h.Calls = append(h.Calls, &testHookCall{"PreProvisionInstance", addr.String()}) + h.Calls = append(h.Calls, &testHookCall{"PreProvisionInstance", id.Addr.String()}) return HookActionContinue, nil } -func (h *testHook) PostProvisionInstance(addr addrs.AbsResourceInstance, state cty.Value) (HookAction, error) { +func (h *testHook) PostProvisionInstance(id HookResourceIdentity, state cty.Value) (HookAction, error) { h.mu.Lock() defer h.mu.Unlock() - h.Calls = append(h.Calls, &testHookCall{"PostProvisionInstance", addr.String()}) + h.Calls = append(h.Calls, &testHookCall{"PostProvisionInstance", id.Addr.String()}) return HookActionContinue, nil } -func (h *testHook) PreProvisionInstanceStep(addr addrs.AbsResourceInstance, typeName string) (HookAction, error) { +func (h *testHook) PreProvisionInstanceStep(id HookResourceIdentity, typeName string) (HookAction, error) { h.mu.Lock() defer h.mu.Unlock() - h.Calls = append(h.Calls, &testHookCall{"PreProvisionInstanceStep", addr.String()}) + h.Calls = append(h.Calls, &testHookCall{"PreProvisionInstanceStep", id.Addr.String()}) return HookActionContinue, nil } -func (h *testHook) PostProvisionInstanceStep(addr addrs.AbsResourceInstance, typeName string, err error) (HookAction, error) { +func (h *testHook) PostProvisionInstanceStep(id HookResourceIdentity, typeName string, err error) (HookAction, error) { h.mu.Lock() defer h.mu.Unlock() - h.Calls = append(h.Calls, &testHookCall{"PostProvisionInstanceStep", addr.String()}) + h.Calls = append(h.Calls, &testHookCall{"PostProvisionInstanceStep", id.Addr.String()}) return HookActionContinue, nil } -func (h *testHook) ProvisionOutput(addr addrs.AbsResourceInstance, typeName string, line string) { +func (h *testHook) ProvisionOutput(id HookResourceIdentity, typeName string, line string) { h.mu.Lock() defer h.mu.Unlock() - h.Calls = append(h.Calls, &testHookCall{"ProvisionOutput", addr.String()}) + h.Calls = append(h.Calls, &testHookCall{"ProvisionOutput", id.Addr.String()}) } -func (h *testHook) PreRefresh(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, priorState cty.Value) (HookAction, error) { +func (h *testHook) PreRefresh(id HookResourceIdentity, dk addrs.DeposedKey, priorState cty.Value) (HookAction, error) { h.mu.Lock() defer h.mu.Unlock() - h.Calls = append(h.Calls, &testHookCall{"PreRefresh", addr.String()}) + h.Calls = append(h.Calls, &testHookCall{"PreRefresh", id.Addr.String()}) return HookActionContinue, nil } -func (h *testHook) PostRefresh(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, priorState cty.Value, newState cty.Value) (HookAction, error) { +func (h *testHook) PostRefresh(id HookResourceIdentity, dk addrs.DeposedKey, priorState cty.Value, newState cty.Value) (HookAction, error) { h.mu.Lock() defer h.mu.Unlock() - h.Calls = append(h.Calls, &testHookCall{"PostRefresh", addr.String()}) + h.Calls = append(h.Calls, &testHookCall{"PostRefresh", id.Addr.String()}) return HookActionContinue, nil } -func (h *testHook) PreImportState(addr addrs.AbsResourceInstance, importID string) (HookAction, error) { +func (h *testHook) PreImportState(id HookResourceIdentity, importID string) (HookAction, error) { h.mu.Lock() defer h.mu.Unlock() - h.Calls = append(h.Calls, &testHookCall{"PreImportState", addr.String()}) + h.Calls = append(h.Calls, &testHookCall{"PreImportState", id.Addr.String()}) return HookActionContinue, nil } -func (h *testHook) PostImportState(addr addrs.AbsResourceInstance, imported []providers.ImportedResource) (HookAction, error) { +func (h *testHook) PostImportState(id HookResourceIdentity, imported []providers.ImportedResource) (HookAction, error) { h.mu.Lock() defer h.mu.Unlock() - h.Calls = append(h.Calls, &testHookCall{"PostImportState", addr.String()}) + h.Calls = append(h.Calls, &testHookCall{"PostImportState", id.Addr.String()}) return HookActionContinue, nil } -func (h *testHook) PrePlanImport(addr addrs.AbsResourceInstance, importID string) (HookAction, error) { +func (h *testHook) PrePlanImport(id HookResourceIdentity, importID string) (HookAction, error) { h.mu.Lock() defer h.mu.Unlock() - h.Calls = append(h.Calls, &testHookCall{"PrePlanImport", addr.String()}) + h.Calls = append(h.Calls, &testHookCall{"PrePlanImport", id.Addr.String()}) return HookActionContinue, nil } -func (h *testHook) PostPlanImport(addr addrs.AbsResourceInstance, imported []providers.ImportedResource) (HookAction, error) { +func (h *testHook) PostPlanImport(id HookResourceIdentity, imported []providers.ImportedResource) (HookAction, error) { h.mu.Lock() defer h.mu.Unlock() - h.Calls = append(h.Calls, &testHookCall{"PostPlanImport", addr.String()}) + h.Calls = append(h.Calls, &testHookCall{"PostPlanImport", id.Addr.String()}) return HookActionContinue, nil } -func (h *testHook) PreApplyImport(addr addrs.AbsResourceInstance, importing plans.ImportingSrc) (HookAction, error) { +func (h *testHook) PreApplyImport(id HookResourceIdentity, importing plans.ImportingSrc) (HookAction, error) { h.mu.Lock() defer h.mu.Unlock() - h.Calls = append(h.Calls, &testHookCall{"PreApplyImport", addr.String()}) + h.Calls = append(h.Calls, &testHookCall{"PreApplyImport", id.Addr.String()}) return HookActionContinue, nil } -func (h *testHook) PostApplyImport(addr addrs.AbsResourceInstance, importing plans.ImportingSrc) (HookAction, error) { +func (h *testHook) PostApplyImport(id HookResourceIdentity, importing plans.ImportingSrc) (HookAction, error) { h.mu.Lock() defer h.mu.Unlock() - h.Calls = append(h.Calls, &testHookCall{"PostApplyImport", addr.String()}) + h.Calls = append(h.Calls, &testHookCall{"PostApplyImport", id.Addr.String()}) return HookActionContinue, nil } diff --git a/internal/terraform/node_resource_abstract_instance.go b/internal/terraform/node_resource_abstract_instance.go index b7d44b2c29..6df94d2919 100644 --- a/internal/terraform/node_resource_abstract_instance.go +++ b/internal/terraform/node_resource_abstract_instance.go @@ -72,6 +72,13 @@ func (n *NodeAbstractResourceInstance) Path() addrs.ModuleInstance { return n.Addr.Module } +func (n *NodeAbstractResourceInstance) HookResourceIdentity() HookResourceIdentity { + return HookResourceIdentity{ + Addr: n.Addr, + ProviderAddr: n.ResolvedProvider.Provider, + } +} + // GraphNodeReferenceable func (n *NodeAbstractResourceInstance) ReferenceableAddrs() []addrs.Referenceable { addr := n.ResourceInstanceAddr() @@ -215,7 +222,7 @@ func (n *NodeAbstractResourceInstance) preApplyHook(ctx EvalContext, change *pla plannedNewState := change.After diags = diags.Append(ctx.Hook(func(h Hook) (HookAction, error) { - return h.PreApply(n.Addr, change.DeposedKey, change.Action, priorState, plannedNewState) + return h.PreApply(n.HookResourceIdentity(), change.DeposedKey, change.Action, priorState, plannedNewState) })) if diags.HasErrors() { return diags @@ -238,7 +245,7 @@ func (n *NodeAbstractResourceInstance) postApplyHook(ctx EvalContext, state *sta newState = cty.NullVal(cty.DynamicPseudoType) } diags = diags.Append(ctx.Hook(func(h Hook) (HookAction, error) { - return h.PostApply(n.Addr, addrs.NotDeposed, newState, err) + return h.PostApply(n.HookResourceIdentity(), addrs.NotDeposed, newState, err) })) } @@ -610,7 +617,7 @@ func (n *NodeAbstractResourceInstance) refresh(ctx EvalContext, deposedKey state // Call pre-refresh hook diags = diags.Append(ctx.Hook(func(h Hook) (HookAction, error) { - return h.PreRefresh(absAddr, deposedKey, state.Value) + return h.PreRefresh(n.HookResourceIdentity(), deposedKey, state.Value) })) if diags.HasErrors() { return state, diags @@ -708,7 +715,7 @@ func (n *NodeAbstractResourceInstance) refresh(ctx EvalContext, deposedKey state // Call post-refresh hook diags = diags.Append(ctx.Hook(func(h Hook) (HookAction, error) { - return h.PostRefresh(absAddr, deposedKey, priorVal, ret.Value) + return h.PostRefresh(n.HookResourceIdentity(), deposedKey, priorVal, ret.Value) })) if diags.HasErrors() { return ret, diags @@ -877,7 +884,7 @@ func (n *NodeAbstractResourceInstance) plan( // Call pre-diff hook diags = diags.Append(ctx.Hook(func(h Hook) (HookAction, error) { - return h.PreDiff(n.Addr, addrs.NotDeposed, priorVal, proposedNewVal) + return h.PreDiff(n.HookResourceIdentity(), addrs.NotDeposed, priorVal, proposedNewVal) })) if diags.HasErrors() { return nil, nil, keyData, diags @@ -1235,7 +1242,7 @@ func (n *NodeAbstractResourceInstance) plan( // Call post-refresh hook diags = diags.Append(ctx.Hook(func(h Hook) (HookAction, error) { - return h.PostDiff(n.Addr, addrs.NotDeposed, action, priorVal, plannedNewVal) + return h.PostDiff(n.HookResourceIdentity(), addrs.NotDeposed, action, priorVal, plannedNewVal) })) if diags.HasErrors() { return nil, nil, keyData, diags @@ -1562,7 +1569,7 @@ func (n *NodeAbstractResourceInstance) readDataSource(ctx EvalContext, configVal log.Printf("[TRACE] readDataSource: %s configuration is complete, so reading from provider", n.Addr) diags = diags.Append(ctx.Hook(func(h Hook) (HookAction, error) { - return h.PreApply(n.Addr, addrs.NotDeposed, plans.Read, cty.NullVal(configVal.Type()), configVal) + return h.PreApply(n.HookResourceIdentity(), addrs.NotDeposed, plans.Read, cty.NullVal(configVal.Type()), configVal) })) if diags.HasErrors() { return newVal, diags @@ -1645,7 +1652,7 @@ func (n *NodeAbstractResourceInstance) readDataSource(ctx EvalContext, configVal } diags = diags.Append(ctx.Hook(func(h Hook) (HookAction, error) { - return h.PostApply(n.Addr, addrs.NotDeposed, newVal, diags.Err()) + return h.PostApply(n.HookResourceIdentity(), addrs.NotDeposed, newVal, diags.Err()) })) return newVal, diags @@ -1811,7 +1818,7 @@ func (n *NodeAbstractResourceInstance) planDataSource(ctx EvalContext, checkRule } diags = diags.Append(ctx.Hook(func(h Hook) (HookAction, error) { - return h.PostDiff(n.Addr, addrs.NotDeposed, plans.Read, priorVal, proposedNewVal) + return h.PostDiff(n.HookResourceIdentity(), addrs.NotDeposed, plans.Read, priorVal, proposedNewVal) })) return plannedChange, plannedNewState, keyData, diags @@ -2001,7 +2008,7 @@ func (n *NodeAbstractResourceInstance) applyDataSource(ctx EvalContext, planned diags = diags.Append(checkDiags) if diags.HasErrors() { diags = diags.Append(ctx.Hook(func(h Hook) (HookAction, error) { - return h.PostApply(n.Addr, addrs.NotDeposed, planned.Before, diags.Err()) + return h.PostApply(n.HookResourceIdentity(), addrs.NotDeposed, planned.Before, diags.Err()) })) return nil, keyData, diags // failed preconditions prevent further evaluation } @@ -2091,7 +2098,7 @@ func (n *NodeAbstractResourceInstance) evalApplyProvisioners(ctx EvalContext, st // Call pre hook diags = diags.Append(ctx.Hook(func(h Hook) (HookAction, error) { - return h.PreProvisionInstance(n.Addr, state.Value) + return h.PreProvisionInstance(n.HookResourceIdentity(), state.Value) })) if diags.HasErrors() { return diags @@ -2107,7 +2114,7 @@ func (n *NodeAbstractResourceInstance) evalApplyProvisioners(ctx EvalContext, st // Call post hook return diags.Append(ctx.Hook(func(h Hook) (HookAction, error) { - return h.PostProvisionInstance(n.Addr, state.Value) + return h.PostProvisionInstance(n.HookResourceIdentity(), state.Value) })) } @@ -2217,7 +2224,7 @@ func (n *NodeAbstractResourceInstance) applyProvisioners(ctx EvalContext, state { // Call pre hook err := ctx.Hook(func(h Hook) (HookAction, error) { - return h.PreProvisionInstanceStep(n.Addr, prov.Type) + return h.PreProvisionInstanceStep(n.HookResourceIdentity(), prov.Type) }) if err != nil { return diags.Append(err) @@ -2227,7 +2234,7 @@ func (n *NodeAbstractResourceInstance) applyProvisioners(ctx EvalContext, state // The output function outputFn := func(msg string) { ctx.Hook(func(h Hook) (HookAction, error) { - h.ProvisionOutput(n.Addr, prov.Type, msg) + h.ProvisionOutput(n.HookResourceIdentity(), prov.Type, msg) return HookActionContinue, nil }) } @@ -2246,7 +2253,7 @@ func (n *NodeAbstractResourceInstance) applyProvisioners(ctx EvalContext, state if len(configMarks) > 0 { outputFn = func(msg string) { ctx.Hook(func(h Hook) (HookAction, error) { - h.ProvisionOutput(n.Addr, prov.Type, "(output suppressed due to sensitive value in config)") + h.ProvisionOutput(n.HookResourceIdentity(), prov.Type, "(output suppressed due to sensitive value in config)") return HookActionContinue, nil }) } @@ -2262,7 +2269,7 @@ func (n *NodeAbstractResourceInstance) applyProvisioners(ctx EvalContext, state // Call post hook hookErr := ctx.Hook(func(h Hook) (HookAction, error) { - return h.PostProvisionInstanceStep(n.Addr, prov.Type, applyDiags.Err()) + return h.PostProvisionInstanceStep(n.HookResourceIdentity(), prov.Type, applyDiags.Err()) }) switch prov.OnFailure { diff --git a/internal/terraform/node_resource_import.go b/internal/terraform/node_resource_import.go index 608cbabee2..90949cda16 100644 --- a/internal/terraform/node_resource_import.go +++ b/internal/terraform/node_resource_import.go @@ -81,10 +81,14 @@ func (n *graphNodeImportState) Execute(ctx EvalContext, op walkOperation) (diags // import state absAddr := n.Addr.Resource.Absolute(ctx.Path()) + hookResourceID := HookResourceIdentity{ + Addr: absAddr, + ProviderAddr: n.ResolvedProvider.Provider, + } // Call pre-import hook diags = diags.Append(ctx.Hook(func(h Hook) (HookAction, error) { - return h.PreImportState(absAddr, n.ID) + return h.PreImportState(hookResourceID, n.ID) })) if diags.HasErrors() { return diags @@ -107,7 +111,7 @@ func (n *graphNodeImportState) Execute(ctx EvalContext, op walkOperation) (diags // Call post-import hook diags = diags.Append(ctx.Hook(func(h Hook) (HookAction, error) { - return h.PostImportState(absAddr, imported) + return h.PostImportState(hookResourceID, imported) })) return diags } diff --git a/internal/terraform/node_resource_plan_instance.go b/internal/terraform/node_resource_plan_instance.go index 2419f25572..ff916267ee 100644 --- a/internal/terraform/node_resource_plan_instance.go +++ b/internal/terraform/node_resource_plan_instance.go @@ -443,9 +443,13 @@ func (n *NodePlannableResourceInstance) replaceTriggered(ctx EvalContext, repDat func (n *NodePlannableResourceInstance) importState(ctx EvalContext, addr addrs.AbsResourceInstance, importId string, provider providers.Interface, providerSchema providers.ProviderSchema) (*states.ResourceInstanceObject, tfdiags.Diagnostics) { var diags tfdiags.Diagnostics absAddr := addr.Resource.Absolute(ctx.Path()) + hookResourceID := HookResourceIdentity{ + Addr: absAddr, + ProviderAddr: n.ResolvedProvider.Provider, + } diags = diags.Append(ctx.Hook(func(h Hook) (HookAction, error) { - return h.PrePlanImport(absAddr, importId) + return h.PrePlanImport(hookResourceID, importId) })) if diags.HasErrors() { return nil, diags @@ -553,7 +557,7 @@ func (n *NodePlannableResourceInstance) importState(ctx EvalContext, addr addrs. // call post-import hook diags = diags.Append(ctx.Hook(func(h Hook) (HookAction, error) { - return h.PostPlanImport(absAddr, imported) + return h.PostPlanImport(hookResourceID, imported) })) if imported[0].TypeName == "" { diff --git a/internal/terraform/terraform_test.go b/internal/terraform/terraform_test.go index a1b2b46118..3a6d1efed4 100644 --- a/internal/terraform/terraform_test.go +++ b/internal/terraform/terraform_test.go @@ -264,7 +264,7 @@ type HookRecordApplyOrder struct { l sync.Mutex } -func (h *HookRecordApplyOrder) PreApply(addr addrs.AbsResourceInstance, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (HookAction, error) { +func (h *HookRecordApplyOrder) PreApply(id HookResourceIdentity, dk addrs.DeposedKey, action plans.Action, priorState, plannedNewState cty.Value) (HookAction, error) { if plannedNewState.RawEquals(priorState) { return HookActionContinue, nil } @@ -273,7 +273,7 @@ func (h *HookRecordApplyOrder) PreApply(addr addrs.AbsResourceInstance, dk addrs h.l.Lock() defer h.l.Unlock() - h.IDs = append(h.IDs, addr.String()) + h.IDs = append(h.IDs, id.Addr.String()) h.Diffs = append(h.Diffs, &plans.Change{ Action: action, Before: priorState,