mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-30 10:47:14 -06:00
291110fe78
The new data source planning logic no longer needs a separate action, and the apply status can be determined from whether the After value is complete or not.
99 lines
2.9 KiB
Go
99 lines
2.9 KiB
Go
package terraform
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/hashicorp/terraform/plans"
|
|
"github.com/hashicorp/terraform/states"
|
|
"github.com/hashicorp/terraform/tfdiags"
|
|
)
|
|
|
|
// evalReadDataApply is an EvalNode implementation that deals with the main part
|
|
// of the data resource lifecycle: either actually reading from the data source
|
|
// or generating a plan to do so.
|
|
type evalReadDataApply struct {
|
|
evalReadData
|
|
}
|
|
|
|
func (n *evalReadDataApply) Eval(ctx EvalContext) (interface{}, error) {
|
|
absAddr := n.Addr.Absolute(ctx.Path())
|
|
|
|
var diags tfdiags.Diagnostics
|
|
|
|
var planned *plans.ResourceInstanceChange
|
|
if n.Planned != nil {
|
|
planned = *n.Planned
|
|
}
|
|
|
|
if n.ProviderSchema == nil || *n.ProviderSchema == nil {
|
|
return nil, fmt.Errorf("provider schema not available for %s", n.Addr)
|
|
}
|
|
|
|
if planned != nil && planned.Action != plans.Read {
|
|
// If any other action gets in here then that's always a bug; this
|
|
// EvalNode only deals with reading.
|
|
return nil, fmt.Errorf(
|
|
"invalid action %s for %s: only Read is supported (this is a bug in Terraform; please report it!)",
|
|
planned.Action, absAddr,
|
|
)
|
|
}
|
|
|
|
if err := ctx.Hook(func(h Hook) (HookAction, error) {
|
|
return h.PreApply(absAddr, states.CurrentGen, planned.Action, planned.Before, planned.After)
|
|
}); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// We have a change and it is complete, which means we read the data
|
|
// source during plan and only need to store it in state.
|
|
if planned.After.IsWhollyKnown() {
|
|
if err := ctx.Hook(func(h Hook) (HookAction, error) {
|
|
return h.PostApply(absAddr, states.CurrentGen, planned.After, nil)
|
|
}); err != nil {
|
|
diags = diags.Append(err)
|
|
}
|
|
|
|
*n.State = &states.ResourceInstanceObject{
|
|
Value: planned.After,
|
|
Status: states.ObjectReady,
|
|
}
|
|
return nil, diags.ErrWithWarnings()
|
|
}
|
|
|
|
config := *n.Config
|
|
providerSchema := *n.ProviderSchema
|
|
schema, _ := providerSchema.SchemaForResourceAddr(n.Addr.ContainingResource())
|
|
if schema == nil {
|
|
// Should be caught during validation, so we don't bother with a pretty error here
|
|
return nil, fmt.Errorf("provider %q does not support data source %q", n.ProviderAddr.Provider.String(), n.Addr.Resource.Type)
|
|
}
|
|
|
|
forEach, _ := evaluateForEachExpression(config.ForEach, ctx)
|
|
keyData := EvalDataForInstanceKey(n.Addr.Key, forEach)
|
|
|
|
configVal, _, configDiags := ctx.EvaluateBlock(config.Config, schema, nil, keyData)
|
|
diags = diags.Append(configDiags)
|
|
if configDiags.HasErrors() {
|
|
return nil, diags.ErrWithWarnings()
|
|
}
|
|
|
|
newVal, readDiags := n.readDataSource(ctx, configVal)
|
|
diags = diags.Append(readDiags)
|
|
if diags.HasErrors() {
|
|
return nil, diags.ErrWithWarnings()
|
|
}
|
|
|
|
*n.State = &states.ResourceInstanceObject{
|
|
Value: newVal,
|
|
Status: states.ObjectReady,
|
|
}
|
|
|
|
if err := ctx.Hook(func(h Hook) (HookAction, error) {
|
|
return h.PostApply(absAddr, states.CurrentGen, newVal, diags.Err())
|
|
}); err != nil {
|
|
diags = diags.Append(err)
|
|
}
|
|
|
|
return nil, diags.ErrWithWarnings()
|
|
}
|