7 "github.com/hashicorp/terraform/configs/configschema"
8 "github.com/hashicorp/terraform/dag"
11 // GraphNodeAttachResourceSchema is an interface implemented by node types
12 // that need a resource schema attached.
13 type GraphNodeAttachResourceSchema interface {
15 GraphNodeProviderConsumer
17 AttachResourceSchema(schema *configschema.Block, version uint64)
20 // GraphNodeAttachProviderConfigSchema is an interface implemented by node types
21 // that need a provider configuration schema attached.
22 type GraphNodeAttachProviderConfigSchema interface {
25 AttachProviderConfigSchema(*configschema.Block)
28 // GraphNodeAttachProvisionerSchema is an interface implemented by node types
29 // that need one or more provisioner schemas attached.
30 type GraphNodeAttachProvisionerSchema interface {
31 ProvisionedBy() []string
33 // SetProvisionerSchema is called during transform for each provisioner
34 // type returned from ProvisionedBy, providing the configuration schema
35 // for each provisioner in turn. The implementer should save these for
36 // later use in evaluating provisioner configuration blocks.
37 AttachProvisionerSchema(name string, schema *configschema.Block)
40 // AttachSchemaTransformer finds nodes that implement
41 // GraphNodeAttachResourceSchema, GraphNodeAttachProviderConfigSchema, or
42 // GraphNodeAttachProvisionerSchema, looks up the needed schemas for each
43 // and then passes them to a method implemented by the node.
44 type AttachSchemaTransformer struct {
48 func (t *AttachSchemaTransformer) Transform(g *Graph) error {
50 // Should never happen with a reasonable caller, but we'll return a
51 // proper error here anyway so that we'll fail gracefully.
52 return fmt.Errorf("AttachSchemaTransformer used with nil Schemas")
55 for _, v := range g.Vertices() {
57 if tv, ok := v.(GraphNodeAttachResourceSchema); ok {
58 addr := tv.ResourceAddr()
59 mode := addr.Resource.Mode
60 typeName := addr.Resource.Type
61 providerAddr, _ := tv.ProvidedBy()
62 providerType := providerAddr.ProviderConfig.Type
64 schema, version := t.Schemas.ResourceTypeConfig(providerType, mode, typeName)
66 log.Printf("[ERROR] AttachSchemaTransformer: No resource schema available for %s", addr)
69 log.Printf("[TRACE] AttachSchemaTransformer: attaching resource schema to %s", dag.VertexName(v))
70 tv.AttachResourceSchema(schema, version)
73 if tv, ok := v.(GraphNodeAttachProviderConfigSchema); ok {
74 providerAddr := tv.ProviderAddr()
75 schema := t.Schemas.ProviderConfig(providerAddr.ProviderConfig.Type)
77 log.Printf("[ERROR] AttachSchemaTransformer: No provider config schema available for %s", providerAddr)
80 log.Printf("[TRACE] AttachSchemaTransformer: attaching provider config schema to %s", dag.VertexName(v))
81 tv.AttachProviderConfigSchema(schema)
84 if tv, ok := v.(GraphNodeAttachProvisionerSchema); ok {
85 names := tv.ProvisionedBy()
86 for _, name := range names {
87 schema := t.Schemas.ProvisionerConfig(name)
89 log.Printf("[ERROR] AttachSchemaTransformer: No schema available for provisioner %q on %q", name, dag.VertexName(v))
92 log.Printf("[TRACE] AttachSchemaTransformer: attaching provisioner %q config schema to %s", name, dag.VertexName(v))
93 tv.AttachProvisionerSchema(name, schema)