github.com/nathanielks/terraform@v0.6.1-0.20170509030759-13e1a62319dc/terraform/transform_attach_config_provider.go (about)

     1  package terraform
     2  
     3  import (
     4  	"log"
     5  
     6  	"github.com/hashicorp/terraform/config"
     7  	"github.com/hashicorp/terraform/config/module"
     8  )
     9  
    10  // GraphNodeAttachProvider is an interface that must be implemented by nodes
    11  // that want provider configurations attached.
    12  type GraphNodeAttachProvider interface {
    13  	// Must be implemented to determine the path for the configuration
    14  	GraphNodeSubPath
    15  
    16  	// ProviderName with no module prefix. Example: "aws".
    17  	ProviderName() string
    18  
    19  	// Sets the configuration
    20  	AttachProvider(*config.ProviderConfig)
    21  }
    22  
    23  // AttachProviderConfigTransformer goes through the graph and attaches
    24  // provider configuration structures to nodes that implement the interfaces
    25  // above.
    26  //
    27  // The attached configuration structures are directly from the configuration.
    28  // If they're going to be modified, a copy should be made.
    29  type AttachProviderConfigTransformer struct {
    30  	Module *module.Tree // Module is the root module for the config
    31  }
    32  
    33  func (t *AttachProviderConfigTransformer) Transform(g *Graph) error {
    34  	if err := t.attachProviders(g); err != nil {
    35  		return err
    36  	}
    37  
    38  	return nil
    39  }
    40  
    41  func (t *AttachProviderConfigTransformer) attachProviders(g *Graph) error {
    42  	// Go through and find GraphNodeAttachProvider
    43  	for _, v := range g.Vertices() {
    44  		// Only care about GraphNodeAttachProvider implementations
    45  		apn, ok := v.(GraphNodeAttachProvider)
    46  		if !ok {
    47  			continue
    48  		}
    49  
    50  		// Determine what we're looking for
    51  		path := normalizeModulePath(apn.Path())
    52  		path = path[1:]
    53  		name := apn.ProviderName()
    54  		log.Printf("[TRACE] Attach provider request: %#v %s", path, name)
    55  
    56  		// Get the configuration.
    57  		tree := t.Module.Child(path)
    58  		if tree == nil {
    59  			continue
    60  		}
    61  
    62  		// Go through the provider configs to find the matching config
    63  		for _, p := range tree.Config().ProviderConfigs {
    64  			// Build the name, which is "name.alias" if an alias exists
    65  			current := p.Name
    66  			if p.Alias != "" {
    67  				current += "." + p.Alias
    68  			}
    69  
    70  			// If the configs match then attach!
    71  			if current == name {
    72  				log.Printf("[TRACE] Attaching provider config: %#v", p)
    73  				apn.AttachProvider(p)
    74  				break
    75  			}
    76  		}
    77  	}
    78  
    79  	return nil
    80  }