github.com/ggiamarchi/terraform@v0.3.7-0.20150607194748-ed2a66a46a71/terraform/eval_provider.go (about)

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