github.com/opentofu/opentofu@v1.7.1/internal/tofu/transform_attach_config_resource.go (about)

     1  // Copyright (c) The OpenTofu Authors
     2  // SPDX-License-Identifier: MPL-2.0
     3  // Copyright (c) 2023 HashiCorp, Inc.
     4  // SPDX-License-Identifier: MPL-2.0
     5  
     6  package tofu
     7  
     8  import (
     9  	"log"
    10  
    11  	"github.com/opentofu/opentofu/internal/configs"
    12  	"github.com/opentofu/opentofu/internal/dag"
    13  )
    14  
    15  // GraphNodeAttachResourceConfig is an interface that must be implemented by nodes
    16  // that want resource configurations attached.
    17  type GraphNodeAttachResourceConfig interface {
    18  	GraphNodeConfigResource
    19  
    20  	// Sets the configuration
    21  	AttachResourceConfig(*configs.Resource)
    22  }
    23  
    24  // AttachResourceConfigTransformer goes through the graph and attaches
    25  // resource configuration structures to nodes that implement
    26  // GraphNodeAttachManagedResourceConfig or GraphNodeAttachDataResourceConfig.
    27  //
    28  // The attached configuration structures are directly from the configuration.
    29  // If they're going to be modified, a copy should be made.
    30  type AttachResourceConfigTransformer struct {
    31  	Config *configs.Config // Config is the root node in the config tree
    32  }
    33  
    34  func (t *AttachResourceConfigTransformer) Transform(g *Graph) error {
    35  
    36  	// Go through and find GraphNodeAttachResource
    37  	for _, v := range g.Vertices() {
    38  		// Only care about GraphNodeAttachResource implementations
    39  		arn, ok := v.(GraphNodeAttachResourceConfig)
    40  		if !ok {
    41  			continue
    42  		}
    43  
    44  		// Determine what we're looking for
    45  		addr := arn.ResourceAddr()
    46  
    47  		// Get the configuration.
    48  		config := t.Config.Descendent(addr.Module)
    49  		if config == nil {
    50  			log.Printf("[TRACE] AttachResourceConfigTransformer: %q (%T) has no configuration available", dag.VertexName(v), v)
    51  			continue
    52  		}
    53  
    54  		for _, r := range config.Module.ManagedResources {
    55  			rAddr := r.Addr()
    56  
    57  			if rAddr != addr.Resource {
    58  				// Not the same resource
    59  				continue
    60  			}
    61  
    62  			log.Printf("[TRACE] AttachResourceConfigTransformer: attaching to %q (%T) config from %s", dag.VertexName(v), v, r.DeclRange)
    63  			arn.AttachResourceConfig(r)
    64  
    65  			// attach the provider_meta info
    66  			if gnapmc, ok := v.(GraphNodeAttachProviderMetaConfigs); ok {
    67  				log.Printf("[TRACE] AttachResourceConfigTransformer: attaching provider meta configs to %s", dag.VertexName(v))
    68  				if config == nil {
    69  					log.Printf("[TRACE] AttachResourceConfigTransformer: no config set on the transformer for %s", dag.VertexName(v))
    70  					continue
    71  				}
    72  				if config.Module == nil {
    73  					log.Printf("[TRACE] AttachResourceConfigTransformer: no module in config for %s", dag.VertexName(v))
    74  					continue
    75  				}
    76  				if config.Module.ProviderMetas == nil {
    77  					log.Printf("[TRACE] AttachResourceConfigTransformer: no provider metas defined for %s", dag.VertexName(v))
    78  					continue
    79  				}
    80  				gnapmc.AttachProviderMetaConfigs(config.Module.ProviderMetas)
    81  			}
    82  		}
    83  		for _, r := range config.Module.DataResources {
    84  			rAddr := r.Addr()
    85  
    86  			if rAddr != addr.Resource {
    87  				// Not the same resource
    88  				continue
    89  			}
    90  
    91  			log.Printf("[TRACE] AttachResourceConfigTransformer: attaching to %q (%T) config from %#v", dag.VertexName(v), v, r.DeclRange)
    92  			arn.AttachResourceConfig(r)
    93  
    94  			// attach the provider_meta info
    95  			if gnapmc, ok := v.(GraphNodeAttachProviderMetaConfigs); ok {
    96  				log.Printf("[TRACE] AttachResourceConfigTransformer: attaching provider meta configs to %s", dag.VertexName(v))
    97  				if config == nil {
    98  					log.Printf("[TRACE] AttachResourceConfigTransformer: no config set on the transformer for %s", dag.VertexName(v))
    99  					continue
   100  				}
   101  				if config.Module == nil {
   102  					log.Printf("[TRACE] AttachResourceConfigTransformer: no module in config for %s", dag.VertexName(v))
   103  					continue
   104  				}
   105  				if config.Module.ProviderMetas == nil {
   106  					log.Printf("[TRACE] AttachResourceConfigTransformer: no provider metas defined for %s", dag.VertexName(v))
   107  					continue
   108  				}
   109  				gnapmc.AttachProviderMetaConfigs(config.Module.ProviderMetas)
   110  			}
   111  		}
   112  	}
   113  
   114  	return nil
   115  }