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 }