Nest incompatible provider protocol error to include dynamic custom msg

This commit is contained in:
findkim 2019-01-14 13:07:54 -06:00
parent e168d81894
commit 6e0de3e3f5
3 changed files with 62 additions and 23 deletions

View File

@ -11,6 +11,7 @@ import (
"github.com/posener/complete" "github.com/posener/complete"
"github.com/zclconf/go-cty/cty" "github.com/zclconf/go-cty/cty"
"github.com/hashicorp/errwrap"
"github.com/hashicorp/terraform/backend" "github.com/hashicorp/terraform/backend"
"github.com/hashicorp/terraform/config" "github.com/hashicorp/terraform/config"
"github.com/hashicorp/terraform/configs" "github.com/hashicorp/terraform/configs"
@ -449,10 +450,15 @@ func (c *InitCommand) getProviders(path string, state *states.State, upgrade boo
_, err := c.providerInstaller.Get(provider, reqd.Versions) _, err := c.providerInstaller.Get(provider, reqd.Versions)
if err != nil { if err != nil {
switch err { constraint := reqd.Versions.String()
case discovery.ErrorNoSuchProvider: if constraint == "" {
constraint = "(any version)"
}
switch {
case err == discovery.ErrorNoSuchProvider:
c.Ui.Error(fmt.Sprintf(errProviderNotFound, provider, DefaultPluginVendorDir)) c.Ui.Error(fmt.Sprintf(errProviderNotFound, provider, DefaultPluginVendorDir))
case discovery.ErrorNoSuitableVersion: case err == discovery.ErrorNoSuitableVersion:
if reqd.Versions.Unconstrained() { if reqd.Versions.Unconstrained() {
// This should never happen, but might crop up if we catch // This should never happen, but might crop up if we catch
// the releases server in a weird state where the provider's // the releases server in a weird state where the provider's
@ -462,14 +468,21 @@ func (c *InitCommand) getProviders(path string, state *states.State, upgrade boo
} else { } else {
c.Ui.Error(fmt.Sprintf(errProviderVersionsUnsuitable, provider, reqd.Versions)) c.Ui.Error(fmt.Sprintf(errProviderVersionsUnsuitable, provider, reqd.Versions))
} }
case discovery.ErrorNoVersionCompatible: case errwrap.Contains(err, discovery.ErrorVersionIncompatible.Error()):
// FIXME: This error message is sub-awesome because we don't // Attempt to fetch nested error to display to the user which versions
// have enough information here to tell the user which versions // we considered and which versions might be compatible. Otherwise,
// we considered and which versions might be compatible. // we'll just display a generic version incompatible msg
constraint := reqd.Versions.String() incompatErr := errwrap.GetType(err, fmt.Errorf(""))
if constraint == "" { if incompatErr != nil {
constraint = "(any version)" c.Ui.Error(incompatErr.Error())
} else {
// Generic version incompatible msg
c.Ui.Error(fmt.Sprintf(errProviderIncompatible, provider, constraint))
} }
// Reset nested errors
err = discovery.ErrorVersionIncompatible
case err == discovery.ErrorNoVersionCompatible:
// Generic version incompatible msg
c.Ui.Error(fmt.Sprintf(errProviderIncompatible, provider, constraint)) c.Ui.Error(fmt.Sprintf(errProviderIncompatible, provider, constraint))
default: default:
c.Ui.Error(fmt.Sprintf(errProviderInstallError, provider, err.Error(), DefaultPluginVendorDir)) c.Ui.Error(fmt.Sprintf(errProviderInstallError, provider, err.Error(), DefaultPluginVendorDir))

View File

@ -22,6 +22,11 @@ const ErrorNoSuitableVersion = Error("no suitable version is available")
// version of Terraform. // version of Terraform.
const ErrorNoVersionCompatible = Error("no available version is compatible with this version of Terraform") const ErrorNoVersionCompatible = Error("no available version is compatible with this version of Terraform")
// ErrorVersionIncompatible indicates that all of the versions within the
// constraints are not compatible with the current version of Terrafrom, though
// there does exist a version outside of the constaints that is compatible.
const ErrorVersionIncompatible = Error("incompatible provider version")
// ErrorNoSuchProvider indicates that no provider exists with a name given // ErrorNoSuchProvider indicates that no provider exists with a name given
const ErrorNoSuchProvider = Error("no provider exists with the given name") const ErrorNoSuchProvider = Error("no provider exists with the given name")

View File

@ -13,6 +13,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"github.com/hashicorp/errwrap"
getter "github.com/hashicorp/go-getter" getter "github.com/hashicorp/go-getter"
multierror "github.com/hashicorp/go-multierror" multierror "github.com/hashicorp/go-multierror"
"github.com/hashicorp/terraform/httpclient" "github.com/hashicorp/terraform/httpclient"
@ -168,16 +169,22 @@ func (i *ProviderInstaller) Get(provider string, req Constraints) (PluginMeta, e
} }
// Prompt version suggestion to UI based on closest protocol match // Prompt version suggestion to UI based on closest protocol match
closestVersion := VersionStr(closestMatch.Version).MustParse()
var errMsg string var errMsg string
closestVersion := VersionStr(closestMatch.Version).MustParse()
if v.NewerThan(closestVersion) { if v.NewerThan(closestVersion) {
errMsg = providerProtocolTooNew errMsg = providerProtocolTooNew
} else { } else {
errMsg = providerProtocolTooOld errMsg = providerProtocolTooOld
} }
i.Ui.Error(fmt.Sprintf(errMsg, provider, v.String(), tfversion.String(),
closestVersion.String(), closestVersion.MinorUpgradeConstraintStr())) constraintStr := req.String()
return PluginMeta{}, ErrorNoVersionCompatible if constraintStr == "" {
constraintStr = "(any version)"
}
return PluginMeta{}, errwrap.Wrap(ErrorVersionIncompatible, fmt.Errorf(fmt.Sprintf(
errMsg, provider, v.String(), tfversion.String(),
closestVersion.String(), closestVersion.MinorUpgradeConstraintStr(), constraintStr)))
} }
downloadURLs, err := i.listProviderDownloadURLs(providerSource, versionMeta.Version) downloadURLs, err := i.listProviderDownloadURLs(providerSource, versionMeta.Version)
@ -582,27 +589,41 @@ func getFile(url string) ([]byte, error) {
return data, nil return data, nil
} }
// ProviderProtocolTooOld is a message sent to the CLI UI if the provider's // providerProtocolTooOld is a message sent to the CLI UI if the provider's
// supported protocol versions are too old for the user's version of terraform, // supported protocol versions are too old for the user's version of terraform,
// but an older version of the provider is compatible. // but an older version of the provider is compatible.
const providerProtocolTooOld = `Provider %q v%s is not compatible with Terraform %s. const providerProtocolTooOld = `
[reset][bold][red]Provider %q v%s is not compatible with Terraform %s.[reset][red]
Provider version %s is the earliest compatible version. Provider version %s is the earliest compatible version. Select it with
Select it with the following version constraint: the following version constraint:
version = %q version = %q
Terraform checked all of the plugin versions matching the given constraint:
%s
Consult the documentation for this provider for more information on
compatibility between provider and Terraform versions.
` `
// ProviderProtocolTooNew is a message sent to the CLI UI if the provider's // providerProtocolTooNew is a message sent to the CLI UI if the provider's
// supported protocol versions are too new for the user's version of terraform, // supported protocol versions are too new for the user's version of terraform,
// and the user could either upgrade terraform or choose an older version of the // and the user could either upgrade terraform or choose an older version of the
// provider // provider
const providerProtocolTooNew = `Provider %q v%s is not compatible with Terraform %s. const providerProtocolTooNew = `
[reset][bold][red]Provider %q v%s is not compatible with Terraform %s.[reset][red]
Provider version v%s is the latest compatible version. Select Provider version %s is the latest compatible version. Select it with
it with the following constraint: the following constraint:
version = %q version = %q
Terraform checked all of the plugin versions matching the given constraint:
%s
Consult the documentation for this provider for more information on
compatibility between provider and Terraform versions.
Alternatively, upgrade to the latest version of Terraform for compatibility with newer provider releases. Alternatively, upgrade to the latest version of Terraform for compatibility with newer provider releases.
` `