github.com/rmenn/terraform@v0.3.8-0.20150225065417-fc84b3a78802/terraform/eval_provider.go (about)

     1  package terraform
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/hashicorp/terraform/config"
     7  )
     8  
     9  // EvalConfigProvider is an EvalNode implementation that configures
    10  // a provider that is already initialized and retrieved.
    11  type EvalConfigProvider struct {
    12  	Provider string
    13  	Config   **ResourceConfig
    14  }
    15  
    16  func (n *EvalConfigProvider) Eval(ctx EvalContext) (interface{}, error) {
    17  	cfg := *n.Config
    18  
    19  	// If we have a configuration set, then use that
    20  	if input := ctx.ProviderInput(n.Provider); input != nil {
    21  		rc, err := config.NewRawConfig(input)
    22  		if err != nil {
    23  			return nil, err
    24  		}
    25  
    26  		merged := cfg.raw.Merge(rc)
    27  		cfg = NewResourceConfig(merged)
    28  	}
    29  
    30  	// Get the parent configuration if there is one
    31  	if parent := ctx.ParentProviderConfig(n.Provider); parent != nil {
    32  		merged := cfg.raw.Merge(parent.raw)
    33  		cfg = NewResourceConfig(merged)
    34  	}
    35  
    36  	return nil, ctx.ConfigureProvider(n.Provider, cfg)
    37  }
    38  
    39  // EvalInitProvider is an EvalNode implementation that initializes a provider
    40  // and returns nothing. The provider can be retrieved again with the
    41  // EvalGetProvider node.
    42  type EvalInitProvider struct {
    43  	Name string
    44  }
    45  
    46  func (n *EvalInitProvider) Eval(ctx EvalContext) (interface{}, error) {
    47  	return ctx.InitProvider(n.Name)
    48  }
    49  
    50  // EvalGetProvider is an EvalNode implementation that retrieves an already
    51  // initialized provider instance for the given name.
    52  type EvalGetProvider struct {
    53  	Name   string
    54  	Output *ResourceProvider
    55  }
    56  
    57  func (n *EvalGetProvider) Eval(ctx EvalContext) (interface{}, error) {
    58  	result := ctx.Provider(n.Name)
    59  	if result == nil {
    60  		return nil, fmt.Errorf("provider %s not initialized", n.Name)
    61  	}
    62  
    63  	if n.Output != nil {
    64  		*n.Output = result
    65  	}
    66  
    67  	return nil, nil
    68  }
    69  
    70  // EvalInputProvider is an EvalNode implementation that asks for input
    71  // for the given provider configurations.
    72  type EvalInputProvider struct {
    73  	Name     string
    74  	Provider *ResourceProvider
    75  	Config   *config.RawConfig
    76  }
    77  
    78  func (n *EvalInputProvider) Eval(ctx EvalContext) (interface{}, error) {
    79  	// If we already configured this provider, then don't do this again
    80  	if v := ctx.ProviderInput(n.Name); v != nil {
    81  		return nil, nil
    82  	}
    83  
    84  	rc := NewResourceConfig(n.Config)
    85  	rc.Config = make(map[string]interface{})
    86  
    87  	// Wrap the input into a namespace
    88  	input := &PrefixUIInput{
    89  		IdPrefix:    fmt.Sprintf("provider.%s", n.Name),
    90  		QueryPrefix: fmt.Sprintf("provider.%s.", n.Name),
    91  		UIInput:     ctx.Input(),
    92  	}
    93  
    94  	// Go through each provider and capture the input necessary
    95  	// to satisfy it.
    96  	config, err := (*n.Provider).Input(input, rc)
    97  	if err != nil {
    98  		return nil, fmt.Errorf(
    99  			"Error configuring %s: %s", n.Name, err)
   100  	}
   101  
   102  	// Set the input that we received so that child modules don't attempt
   103  	// to ask for input again.
   104  	if config != nil && len(config.Config) > 0 {
   105  		ctx.SetProviderInput(n.Name, config.Config)
   106  	} else {
   107  		ctx.SetProviderInput(n.Name, map[string]interface{}{})
   108  	}
   109  
   110  	return nil, nil
   111  }