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 }