github.com/adrian-bl/terraform@v0.7.0-rc2.0.20160705220747-de0a34fc3517/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  // EvalCloseProvider is an EvalNode implementation that closes provider
    75  // connections that aren't needed anymore.
    76  type EvalCloseProvider struct {
    77  	Name string
    78  }
    79  
    80  func (n *EvalCloseProvider) Eval(ctx EvalContext) (interface{}, error) {
    81  	ctx.CloseProvider(n.Name)
    82  	return nil, nil
    83  }
    84  
    85  // EvalGetProvider is an EvalNode implementation that retrieves an already
    86  // initialized provider instance for the given name.
    87  type EvalGetProvider struct {
    88  	Name   string
    89  	Output *ResourceProvider
    90  }
    91  
    92  func (n *EvalGetProvider) Eval(ctx EvalContext) (interface{}, error) {
    93  	result := ctx.Provider(n.Name)
    94  	if result == nil {
    95  		return nil, fmt.Errorf("provider %s not initialized", n.Name)
    96  	}
    97  
    98  	if n.Output != nil {
    99  		*n.Output = result
   100  	}
   101  
   102  	return nil, nil
   103  }
   104  
   105  // EvalInputProvider is an EvalNode implementation that asks for input
   106  // for the given provider configurations.
   107  type EvalInputProvider struct {
   108  	Name     string
   109  	Provider *ResourceProvider
   110  	Config   **ResourceConfig
   111  }
   112  
   113  func (n *EvalInputProvider) Eval(ctx EvalContext) (interface{}, error) {
   114  	// If we already configured this provider, then don't do this again
   115  	if v := ctx.ProviderInput(n.Name); v != nil {
   116  		return nil, nil
   117  	}
   118  
   119  	rc := *n.Config
   120  
   121  	// Wrap the input into a namespace
   122  	input := &PrefixUIInput{
   123  		IdPrefix:    fmt.Sprintf("provider.%s", n.Name),
   124  		QueryPrefix: fmt.Sprintf("provider.%s.", n.Name),
   125  		UIInput:     ctx.Input(),
   126  	}
   127  
   128  	// Go through each provider and capture the input necessary
   129  	// to satisfy it.
   130  	config, err := (*n.Provider).Input(input, rc)
   131  	if err != nil {
   132  		return nil, fmt.Errorf(
   133  			"Error configuring %s: %s", n.Name, err)
   134  	}
   135  
   136  	// Set the input that we received so that child modules don't attempt
   137  	// to ask for input again.
   138  	if config != nil && len(config.Config) > 0 {
   139  		ctx.SetProviderInput(n.Name, config.Config)
   140  	} else {
   141  		ctx.SetProviderInput(n.Name, map[string]interface{}{})
   142  	}
   143  
   144  	return nil, nil
   145  }