github.com/hashicorp/terraform-plugin-sdk@v1.17.2/terraform/transform_attach_schema.go (about)

     1  package terraform
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  
     7  	"github.com/hashicorp/terraform-plugin-sdk/internal/configs/configschema"
     8  	"github.com/hashicorp/terraform-plugin-sdk/internal/dag"
     9  )
    10  
    11  // GraphNodeAttachResourceSchema is an interface implemented by node types
    12  // that need a resource schema attached.
    13  type GraphNodeAttachResourceSchema interface {
    14  	GraphNodeResource
    15  	GraphNodeProviderConsumer
    16  
    17  	AttachResourceSchema(schema *configschema.Block, version uint64)
    18  }
    19  
    20  // GraphNodeAttachProviderConfigSchema is an interface implemented by node types
    21  // that need a provider configuration schema attached.
    22  type GraphNodeAttachProviderConfigSchema interface {
    23  	GraphNodeProvider
    24  
    25  	AttachProviderConfigSchema(*configschema.Block)
    26  }
    27  
    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
    32  
    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)
    38  }
    39  
    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 {
    45  	Schemas *Schemas
    46  }
    47  
    48  func (t *AttachSchemaTransformer) Transform(g *Graph) error {
    49  	if t.Schemas == nil {
    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")
    53  	}
    54  
    55  	for _, v := range g.Vertices() {
    56  
    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
    63  
    64  			schema, version := t.Schemas.ResourceTypeConfig(providerType, mode, typeName)
    65  			if schema == nil {
    66  				log.Printf("[ERROR] AttachSchemaTransformer: No resource schema available for %s", addr)
    67  				continue
    68  			}
    69  			log.Printf("[TRACE] AttachSchemaTransformer: attaching resource schema to %s", dag.VertexName(v))
    70  			tv.AttachResourceSchema(schema, version)
    71  		}
    72  
    73  		if tv, ok := v.(GraphNodeAttachProviderConfigSchema); ok {
    74  			providerAddr := tv.ProviderAddr()
    75  			schema := t.Schemas.ProviderConfig(providerAddr.ProviderConfig.Type)
    76  			if schema == nil {
    77  				log.Printf("[ERROR] AttachSchemaTransformer: No provider config schema available for %s", providerAddr)
    78  				continue
    79  			}
    80  			log.Printf("[TRACE] AttachSchemaTransformer: attaching provider config schema to %s", dag.VertexName(v))
    81  			tv.AttachProviderConfigSchema(schema)
    82  		}
    83  
    84  		if tv, ok := v.(GraphNodeAttachProvisionerSchema); ok {
    85  			names := tv.ProvisionedBy()
    86  			for _, name := range names {
    87  				schema := t.Schemas.ProvisionerConfig(name)
    88  				if schema == nil {
    89  					log.Printf("[ERROR] AttachSchemaTransformer: No schema available for provisioner %q on %q", name, dag.VertexName(v))
    90  					continue
    91  				}
    92  				log.Printf("[TRACE] AttachSchemaTransformer: attaching provisioner %q config schema to %s", name, dag.VertexName(v))
    93  				tv.AttachProvisionerSchema(name, schema)
    94  			}
    95  		}
    96  	}
    97  
    98  	return nil
    99  }