1package terraform
2
3import (
4	"github.com/hashicorp/terraform/configs"
5	"github.com/hashicorp/terraform/configs/configschema"
6	"github.com/hashicorp/terraform/providers"
7	"github.com/hashicorp/terraform/provisioners"
8	"github.com/zclconf/go-cty/cty"
9)
10
11// NodeValidatableResource represents a resource that is used for validation
12// only.
13type NodeValidatableResource struct {
14	*NodeAbstractResource
15}
16
17var (
18	_ GraphNodeSubPath              = (*NodeValidatableResource)(nil)
19	_ GraphNodeEvalable             = (*NodeValidatableResource)(nil)
20	_ GraphNodeReferenceable        = (*NodeValidatableResource)(nil)
21	_ GraphNodeReferencer           = (*NodeValidatableResource)(nil)
22	_ GraphNodeResource             = (*NodeValidatableResource)(nil)
23	_ GraphNodeAttachResourceConfig = (*NodeValidatableResource)(nil)
24)
25
26// GraphNodeEvalable
27func (n *NodeValidatableResource) EvalTree() EvalNode {
28	addr := n.ResourceAddr()
29	config := n.Config
30
31	// Declare the variables will be used are used to pass values along
32	// the evaluation sequence below. These are written to via pointers
33	// passed to the EvalNodes.
34	var provider providers.Interface
35	var providerSchema *ProviderSchema
36	var configVal cty.Value
37
38	seq := &EvalSequence{
39		Nodes: []EvalNode{
40			&EvalGetProvider{
41				Addr:   n.ResolvedProvider,
42				Output: &provider,
43				Schema: &providerSchema,
44			},
45			&EvalValidateResource{
46				Addr:           addr.Resource,
47				Provider:       &provider,
48				ProviderSchema: &providerSchema,
49				Config:         config,
50				ConfigVal:      &configVal,
51			},
52		},
53	}
54
55	if managed := n.Config.Managed; managed != nil {
56		hasCount := n.Config.Count != nil
57
58		// Validate all the provisioners
59		for _, p := range managed.Provisioners {
60			var provisioner provisioners.Interface
61			var provisionerSchema *configschema.Block
62
63			if p.Connection == nil {
64				p.Connection = config.Managed.Connection
65			} else if config.Managed.Connection != nil {
66				p.Connection.Config = configs.MergeBodies(config.Managed.Connection.Config, p.Connection.Config)
67			}
68
69			seq.Nodes = append(
70				seq.Nodes,
71				&EvalGetProvisioner{
72					Name:   p.Type,
73					Output: &provisioner,
74					Schema: &provisionerSchema,
75				},
76				&EvalValidateProvisioner{
77					ResourceAddr:     addr.Resource,
78					Provisioner:      &provisioner,
79					Schema:           &provisionerSchema,
80					Config:           p,
81					ResourceHasCount: hasCount,
82				},
83			)
84		}
85	}
86
87	return seq
88}
89