X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=vendor%2Fgithub.com%2Fhashicorp%2Fterraform%2Fterraform%2Feval_provider.go;h=7df6584a1e56aac4a23f66672cb2d47ed0c49b62;hb=HEAD;hp=092fd18d838579a97ce377a40a0d7d8c8826feba;hpb=cec3de8a3bcaffd21dedd1bf42da4b490cae7e16;p=github%2Ffretlink%2Fterraform-provider-statuscake.git diff --git a/vendor/github.com/hashicorp/terraform/terraform/eval_provider.go b/vendor/github.com/hashicorp/terraform/terraform/eval_provider.go index 092fd18..7df6584 100644 --- a/vendor/github.com/hashicorp/terraform/terraform/eval_provider.go +++ b/vendor/github.com/hashicorp/terraform/terraform/eval_provider.go @@ -2,162 +2,145 @@ package terraform import ( "fmt" + "log" - "github.com/hashicorp/terraform/config" -) - -// EvalSetProviderConfig sets the parent configuration for a provider -// without configuring that provider, validating it, etc. -type EvalSetProviderConfig struct { - Provider string - Config **ResourceConfig -} - -func (n *EvalSetProviderConfig) Eval(ctx EvalContext) (interface{}, error) { - return nil, ctx.SetProviderConfig(n.Provider, *n.Config) -} + "github.com/hashicorp/hcl2/hcl" -// EvalBuildProviderConfig outputs a *ResourceConfig that is properly -// merged with parents and inputs on top of what is configured in the file. -type EvalBuildProviderConfig struct { - Provider string - Config **ResourceConfig - Output **ResourceConfig -} + "github.com/hashicorp/terraform/addrs" + "github.com/hashicorp/terraform/configs" + "github.com/hashicorp/terraform/providers" + "github.com/hashicorp/terraform/tfdiags" +) -func (n *EvalBuildProviderConfig) Eval(ctx EvalContext) (interface{}, error) { - cfg := *n.Config - - // If we have a configuration set, then merge that in - if input := ctx.ProviderInput(n.Provider); input != nil { - // "input" is a map of the subset of config values that were known - // during the input walk, set by EvalInputProvider. Note that - // in particular it does *not* include attributes that had - // computed values at input time; those appear *only* in - // "cfg" here. - rc, err := config.NewRawConfig(input) - if err != nil { - return nil, err - } - - merged := cfg.raw.Merge(rc) - cfg = NewResourceConfig(merged) +func buildProviderConfig(ctx EvalContext, addr addrs.ProviderConfig, config *configs.Provider) hcl.Body { + var configBody hcl.Body + if config != nil { + configBody = config.Config } - // Get the parent configuration if there is one - if parent := ctx.ParentProviderConfig(n.Provider); parent != nil { - merged := cfg.raw.Merge(parent.raw) - cfg = NewResourceConfig(merged) + var inputBody hcl.Body + inputConfig := ctx.ProviderInput(addr) + if len(inputConfig) > 0 { + inputBody = configs.SynthBody("", inputConfig) } - *n.Output = cfg - return nil, nil + switch { + case configBody != nil && inputBody != nil: + log.Printf("[TRACE] buildProviderConfig for %s: merging explicit config and input", addr) + // Note that the inputBody is the _base_ here, because configs.MergeBodies + // expects the base have all of the required fields, while these are + // forced to be optional for the override. The input process should + // guarantee that we have a value for each of the required arguments and + // that in practice the sets of attributes in each body will be + // disjoint. + return configs.MergeBodies(inputBody, configBody) + case configBody != nil: + log.Printf("[TRACE] buildProviderConfig for %s: using explicit config only", addr) + return configBody + case inputBody != nil: + log.Printf("[TRACE] buildProviderConfig for %s: using input only", addr) + return inputBody + default: + log.Printf("[TRACE] buildProviderConfig for %s: no configuration at all", addr) + return hcl.EmptyBody() + } } // EvalConfigProvider is an EvalNode implementation that configures // a provider that is already initialized and retrieved. type EvalConfigProvider struct { - Provider string - Config **ResourceConfig + Addr addrs.ProviderConfig + Provider *providers.Interface + Config *configs.Provider } func (n *EvalConfigProvider) Eval(ctx EvalContext) (interface{}, error) { - return nil, ctx.ConfigureProvider(n.Provider, *n.Config) + if n.Provider == nil { + return nil, fmt.Errorf("EvalConfigProvider Provider is nil") + } + + var diags tfdiags.Diagnostics + provider := *n.Provider + config := n.Config + + configBody := buildProviderConfig(ctx, n.Addr, config) + + resp := provider.GetSchema() + diags = diags.Append(resp.Diagnostics) + if diags.HasErrors() { + return nil, diags.NonFatalErr() + } + + configSchema := resp.Provider.Block + configVal, configBody, evalDiags := ctx.EvaluateBlock(configBody, configSchema, nil, EvalDataForNoInstanceKey) + diags = diags.Append(evalDiags) + if evalDiags.HasErrors() { + return nil, diags.NonFatalErr() + } + + configDiags := ctx.ConfigureProvider(n.Addr, configVal) + configDiags = configDiags.InConfigBody(configBody) + + return nil, configDiags.ErrWithWarnings() } // EvalInitProvider is an EvalNode implementation that initializes a provider // and returns nothing. The provider can be retrieved again with the // EvalGetProvider node. type EvalInitProvider struct { - Name string + TypeName string + Addr addrs.ProviderConfig } func (n *EvalInitProvider) Eval(ctx EvalContext) (interface{}, error) { - return ctx.InitProvider(n.Name) + return ctx.InitProvider(n.TypeName, n.Addr) } // EvalCloseProvider is an EvalNode implementation that closes provider // connections that aren't needed anymore. type EvalCloseProvider struct { - Name string + Addr addrs.ProviderConfig } func (n *EvalCloseProvider) Eval(ctx EvalContext) (interface{}, error) { - ctx.CloseProvider(n.Name) + ctx.CloseProvider(n.Addr) return nil, nil } // EvalGetProvider is an EvalNode implementation that retrieves an already // initialized provider instance for the given name. +// +// Unlike most eval nodes, this takes an _absolute_ provider configuration, +// because providers can be passed into and inherited between modules. +// Resource nodes must therefore know the absolute path of the provider they +// will use, which is usually accomplished by implementing +// interface GraphNodeProviderConsumer. type EvalGetProvider struct { - Name string - Output *ResourceProvider + Addr addrs.AbsProviderConfig + Output *providers.Interface + + // If non-nil, Schema will be updated after eval to refer to the + // schema of the provider. + Schema **ProviderSchema } func (n *EvalGetProvider) Eval(ctx EvalContext) (interface{}, error) { - result := ctx.Provider(n.Name) + if n.Addr.ProviderConfig.Type == "" { + // Should never happen + panic("EvalGetProvider used with uninitialized provider configuration address") + } + + result := ctx.Provider(n.Addr) if result == nil { - return nil, fmt.Errorf("provider %s not initialized", n.Name) + return nil, fmt.Errorf("provider %s not initialized", n.Addr) } if n.Output != nil { *n.Output = result } - return nil, nil -} - -// EvalInputProvider is an EvalNode implementation that asks for input -// for the given provider configurations. -type EvalInputProvider struct { - Name string - Provider *ResourceProvider - Config **ResourceConfig -} - -func (n *EvalInputProvider) Eval(ctx EvalContext) (interface{}, error) { - // If we already configured this provider, then don't do this again - if v := ctx.ProviderInput(n.Name); v != nil { - return nil, nil - } - - rc := *n.Config - - // Wrap the input into a namespace - input := &PrefixUIInput{ - IdPrefix: fmt.Sprintf("provider.%s", n.Name), - QueryPrefix: fmt.Sprintf("provider.%s.", n.Name), - UIInput: ctx.Input(), - } - - // Go through each provider and capture the input necessary - // to satisfy it. - config, err := (*n.Provider).Input(input, rc) - if err != nil { - return nil, fmt.Errorf( - "Error configuring %s: %s", n.Name, err) - } - - // Set the input that we received so that child modules don't attempt - // to ask for input again. - if config != nil && len(config.Config) > 0 { - // This repository of provider input results on the context doesn't - // retain config.ComputedKeys, so we need to filter those out here - // in order that later users of this data won't try to use the unknown - // value placeholder as if it were a literal value. This map is just - // of known values we've been able to complete so far; dynamic stuff - // will be merged in by EvalBuildProviderConfig on subsequent - // (post-input) walks. - confMap := config.Config - if config.ComputedKeys != nil { - for _, key := range config.ComputedKeys { - delete(confMap, key) - } - } - - ctx.SetProviderInput(n.Name, confMap) - } else { - ctx.SetProviderInput(n.Name, map[string]interface{}{}) + if n.Schema != nil { + *n.Schema = ctx.ProviderSchema(n.Addr) } return nil, nil