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/zclconf/go-cty/cty"
"github.com/hashicorp/errwrap"
"github.com/hashicorp/terraform/backend"
"github.com/hashicorp/terraform/config"
"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)
if err != nil {
switch err {
case discovery.ErrorNoSuchProvider:
constraint := reqd.Versions.String()
if constraint == "" {
constraint = "(any version)"
}
switch {
case err == discovery.ErrorNoSuchProvider:
c.Ui.Error(fmt.Sprintf(errProviderNotFound, provider, DefaultPluginVendorDir))
case discovery.ErrorNoSuitableVersion:
case err == discovery.ErrorNoSuitableVersion:
if reqd.Versions.Unconstrained() {
// This should never happen, but might crop up if we catch
// 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 {
c.Ui.Error(fmt.Sprintf(errProviderVersionsUnsuitable, provider, reqd.Versions))
}
case discovery.ErrorNoVersionCompatible:
// FIXME: This error message is sub-awesome because we don't
// have enough information here to tell the user which versions
// we considered and which versions might be compatible.
constraint := reqd.Versions.String()
if constraint == "" {
constraint = "(any version)"
case errwrap.Contains(err, discovery.ErrorVersionIncompatible.Error()):
// Attempt to fetch nested error to display to the user which versions
// we considered and which versions might be compatible. Otherwise,
// we'll just display a generic version incompatible msg
incompatErr := errwrap.GetType(err, fmt.Errorf(""))
if incompatErr != nil {
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))
default:
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.
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
const ErrorNoSuchProvider = Error("no provider exists with the given name")

View File

@ -13,6 +13,7 @@ import (
"strconv"
"strings"
"github.com/hashicorp/errwrap"
getter "github.com/hashicorp/go-getter"
multierror "github.com/hashicorp/go-multierror"
"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
closestVersion := VersionStr(closestMatch.Version).MustParse()
var errMsg string
closestVersion := VersionStr(closestMatch.Version).MustParse()
if v.NewerThan(closestVersion) {
errMsg = providerProtocolTooNew
} else {
errMsg = providerProtocolTooOld
}
i.Ui.Error(fmt.Sprintf(errMsg, provider, v.String(), tfversion.String(),
closestVersion.String(), closestVersion.MinorUpgradeConstraintStr()))
return PluginMeta{}, ErrorNoVersionCompatible
constraintStr := req.String()
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)
@ -582,27 +589,41 @@ func getFile(url string) ([]byte, error) {
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,
// 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.
Select it with the following version constraint:
Provider version %s is the earliest compatible version. Select it with
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,
// and the user could either upgrade terraform or choose an older version of the
// 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
it with the following constraint:
Provider version %s is the latest compatible version. Select it with
the following constraint:
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.
`