Merge pull request #20397 from hashicorp/jbardin/init-error

move provider init error to where it is generated
This commit is contained in:
James Bardin 2019-02-20 15:12:43 -05:00 committed by GitHub
commit 0d6230db12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 43 deletions

View File

@ -9,7 +9,6 @@ import (
"os"
"path/filepath"
"sort"
"strings"
"sync"
"github.com/hashicorp/terraform/backend"
@ -594,25 +593,3 @@ func (b *Local) stateWorkspaceDir() string {
return DefaultWorkspaceDir
}
func (b *Local) pluginInitRequired(providerErr *terraform.ResourceProviderError) {
b.CLI.Output(b.Colorize().Color(fmt.Sprintf(
strings.TrimSpace(errPluginInit)+"\n",
providerErr)))
}
// this relies on multierror to format the plugin errors below the copy
const errPluginInit = `
[reset][bold][yellow]Plugin reinitialization required. Please run "terraform init".[reset]
[yellow]Reason: Could not satisfy plugin requirements.
Plugins are external binaries that Terraform uses to access and manipulate
resources. The configuration provided requires plugins which can't be located,
don't satisfy the version constraints, or are otherwise incompatible.
[reset][red]%s
[reset][yellow]Terraform automatically discovers provider requirements from your
configuration, including providers used in child modules. To see the
requirements and constraints from each module, run "terraform providers".
`

View File

@ -172,16 +172,18 @@ func NewContext(opts *ContextOpts) (*Context, tfdiags.Diagnostics) {
// Bind available provider plugins to the constraints in config
var providerFactories map[string]providers.Factory
if opts.ProviderResolver != nil {
var err error
deps := ConfigTreeDependencies(opts.Config, state)
reqd := deps.AllPluginRequirements()
if opts.ProviderSHA256s != nil && !opts.SkipProviderVerify {
reqd.LockExecutables(opts.ProviderSHA256s)
}
log.Printf("[TRACE] terraform.NewContext: resolving provider version selections")
providerFactories, err = resourceProviderFactories(opts.ProviderResolver, reqd)
if err != nil {
diags = diags.Append(err)
var providerDiags tfdiags.Diagnostics
providerFactories, providerDiags = resourceProviderFactories(opts.ProviderResolver, reqd)
diags = diags.Append(providerDiags)
if diags.HasErrors() {
return nil, diags
}
} else {

View File

@ -3,7 +3,8 @@ package terraform
import (
"fmt"
multierror "github.com/hashicorp/go-multierror"
"github.com/hashicorp/terraform/tfdiags"
"github.com/hashicorp/terraform/plugin/discovery"
"github.com/hashicorp/terraform/providers"
)
@ -170,18 +171,6 @@ type ResourceProvider interface {
ReadDataApply(*InstanceInfo, *InstanceDiff) (*InstanceState, error)
}
// ResourceProviderError may be returned when creating a Context if the
// required providers cannot be satisfied. This error can then be used to
// format a more useful message for the user.
type ResourceProviderError struct {
Errors []error
}
func (e *ResourceProviderError) Error() string {
// use multierror to format the default output
return multierror.Append(nil, e.Errors...).Error()
}
// ResourceProviderCloser is an interface that providers that can close
// connections that aren't needed anymore must implement.
type ResourceProviderCloser interface {
@ -296,13 +285,35 @@ func ProviderHasDataSource(p ResourceProvider, n string) bool {
// This should be called only with configurations that have passed calls
// to config.Validate(), which ensures that all of the given version
// constraints are valid. It will panic if any invalid constraints are present.
func resourceProviderFactories(resolver providers.Resolver, reqd discovery.PluginRequirements) (map[string]providers.Factory, error) {
func resourceProviderFactories(resolver providers.Resolver, reqd discovery.PluginRequirements) (map[string]providers.Factory, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
ret, errs := resolver.ResolveProviders(reqd)
if errs != nil {
return nil, &ResourceProviderError{
Errors: errs,
diags = diags.Append(
tfdiags.Sourceless(tfdiags.Error,
"Could not satisfy plugin requirements",
errPluginInit,
),
)
for _, err := range errs {
diags = diags.Append(err)
}
return nil, diags
}
return ret, nil
}
const errPluginInit = `
Plugin reinitialization required. Please run "terraform init".
Plugins are external binaries that Terraform uses to access and manipulate
resources. The configuration provided requires plugins which can't be located,
don't satisfy the version constraints, or are otherwise incompatible.
Terraform automatically discovers provider requirements from your
configuration, including providers used in child modules. To see the
requirements and constraints from each module, run "terraform providers".
`