opentofu/terraform/node_resource_validate.go
Kristin Laemmert 7b510c4add
Mildwonkey/node resource validate (#26206)
* terraform: refactor signature of EvalContext.InitProvisioner

Nothing was using the returned provisioners.Interface, so I simplified
the signature.

* terraform: remove provisioner-related EvalTree()s

The various Evals in eval_provisioner were removed from all callers and
replaced with straight-through code.

`NodeValidatableResource.EvalTree()` to `Execute()` was more involved. I
chose to leave the `EvalValidateResource` and `EvalValidateProvisioner`
Eval functions mostly as-is, changing the main function to `.Validate` to
make it clear that these are no longer eval nodes. Eventually I expect
to rename the file (perhaps to just Validate).
2020-09-14 08:43:14 -04:00

98 lines
2.9 KiB
Go

package terraform
import (
"fmt"
"github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/configs"
"github.com/zclconf/go-cty/cty"
)
// NodeValidatableResource represents a resource that is used for validation
// only.
type NodeValidatableResource struct {
*NodeAbstractResource
}
var (
_ GraphNodeModuleInstance = (*NodeValidatableResource)(nil)
_ GraphNodeExecutable = (*NodeValidatableResource)(nil)
_ GraphNodeReferenceable = (*NodeValidatableResource)(nil)
_ GraphNodeReferencer = (*NodeValidatableResource)(nil)
_ GraphNodeConfigResource = (*NodeValidatableResource)(nil)
_ GraphNodeAttachResourceConfig = (*NodeValidatableResource)(nil)
_ GraphNodeAttachProviderMetaConfigs = (*NodeValidatableResource)(nil)
)
func (n *NodeValidatableResource) Path() addrs.ModuleInstance {
// There is no expansion during validation, so we evaluate everything as
// single module instances.
return n.Addr.Module.UnkeyedInstanceShim()
}
// GraphNodeEvalable
func (n *NodeValidatableResource) Execute(ctx EvalContext, op walkOperation) error {
addr := n.ResourceAddr()
config := n.Config
// Declare the variables will be used are used to pass values along
// the evaluation sequence below. These are written to via pointers
// passed to the EvalNodes.
var configVal cty.Value
provider, providerSchema, err := GetProvider(ctx, n.ResolvedProvider)
if err != nil {
return err
}
evalValidateResource := &EvalValidateResource{
Addr: addr.Resource,
Provider: &provider,
ProviderMetas: n.ProviderMetas,
ProviderSchema: &providerSchema,
Config: config,
ConfigVal: &configVal,
}
err = evalValidateResource.Validate(ctx)
if err != nil {
return err
}
if managed := n.Config.Managed; managed != nil {
hasCount := n.Config.Count != nil
hasForEach := n.Config.ForEach != nil
// Validate all the provisioners
for _, p := range managed.Provisioners {
if p.Connection == nil {
p.Connection = config.Managed.Connection
} else if config.Managed.Connection != nil {
p.Connection.Config = configs.MergeBodies(config.Managed.Connection.Config, p.Connection.Config)
}
provisioner := ctx.Provisioner(p.Type)
if provisioner == nil {
return fmt.Errorf("provisioner %s not initialized", p.Type)
}
provisionerSchema := ctx.ProvisionerSchema(p.Type)
if provisionerSchema == nil {
return fmt.Errorf("provisioner %s not initialized", p.Type)
}
// Validate Provisioner Config
validateProvisioner := &EvalValidateProvisioner{
ResourceAddr: addr.Resource,
Provisioner: &provisioner,
Schema: &provisionerSchema,
Config: p,
ResourceHasCount: hasCount,
ResourceHasForEach: hasForEach,
}
err := validateProvisioner.Validate(ctx)
if err != nil {
return err
}
}
}
return nil
}