From bdaf8290b458794b93cc9540de7231e655950f07 Mon Sep 17 00:00:00 2001 From: Kristin Laemmert Date: Wed, 8 Aug 2018 15:04:51 -0700 Subject: [PATCH] registry/client: added a specific error if the registry client does not support the requested service. --- plugin/discovery/get.go | 3 +++ registry/client.go | 10 +++++----- registry/client_test.go | 8 +++----- registry/errors.go | 17 +++++++++++++++++ tools/terraform-bundle/package.go | 6 ++++-- 5 files changed, 32 insertions(+), 12 deletions(-) diff --git a/plugin/discovery/get.go b/plugin/discovery/get.go index c07cc0736..3357e6bfc 100644 --- a/plugin/discovery/get.go +++ b/plugin/discovery/get.go @@ -121,6 +121,9 @@ func (i *ProviderInstaller) Get(provider string, req Constraints) (PluginMeta, e // TODO: return multiple errors if err != nil { + if registry.IsServiceNotProvided(err) { + return PluginMeta{}, err + } return PluginMeta{}, ErrorNoSuchProvider } if len(allVersions.Versions) == 0 { diff --git a/registry/client.go b/registry/client.go index 5cd86cbd9..cdd33dc9e 100644 --- a/registry/client.go +++ b/registry/client.go @@ -58,7 +58,7 @@ func NewClient(services *disco.Disco, client *http.Client) *Client { } } -// Discover qeuries the host, and returns the url for the registry. +// Discover queries the host, and returns the url for the registry. func (c *Client) Discover(host svchost.Hostname, serviceID string) *url.URL { service := c.services.DiscoverServiceURL(host, serviceID) if service == nil { @@ -79,7 +79,7 @@ func (c *Client) ModuleVersions(module *regsrc.Module) (*response.ModuleVersions service := c.Discover(host, modulesServiceID) if service == nil { - return nil, fmt.Errorf("host %s does not provide Terraform modules", host) + return nil, &errServiceNotProvided{host: host.ForDisplay(), service: "modules"} } p, err := url.Parse(path.Join(module.Module(), "versions")) @@ -152,7 +152,7 @@ func (c *Client) ModuleLocation(module *regsrc.Module, version string) (string, service := c.Discover(host, modulesServiceID) if service == nil { - return "", fmt.Errorf("host %s does not provide Terraform modules", host.ForDisplay()) + return "", &errServiceNotProvided{host: host.ForDisplay(), service: "modules"} } var p *url.URL @@ -236,7 +236,7 @@ func (c *Client) TerraformProviderVersions(provider *regsrc.TerraformProvider) ( service := c.Discover(host, providersServiceID) if service == nil { - return nil, fmt.Errorf("host %s does not provide Terraform providers", host) + return nil, &errServiceNotProvided{host: host.ForDisplay(), service: "providers"} } p, err := url.Parse(path.Join(provider.TerraformProvider(), "versions")) @@ -290,7 +290,7 @@ func (c *Client) TerraformProviderLocation(provider *regsrc.TerraformProvider, v service := c.Discover(host, providersServiceID) if service == nil { - return nil, fmt.Errorf("host %s does not provide Terraform providers", host) + return nil, &errServiceNotProvided{host: host.ForDisplay(), service: "providers"} } p, err := url.Parse(path.Join( diff --git a/registry/client_test.go b/registry/client_test.go index ca857d3dc..ea5d1e5ef 100644 --- a/registry/client_test.go +++ b/registry/client_test.go @@ -214,7 +214,7 @@ func TestLookupProviderVersions(t *testing.T) { {"bar"}, } for _, tt := range tests { - provider, err := regsrc.NewTerraformProvider(tt.name, "", "") + provider := regsrc.NewTerraformProvider(tt.name, "", "") resp, err := client.TerraformProviderVersions(provider) if err != nil { t.Fatal(err) @@ -267,10 +267,8 @@ func TestLookupProviderLocation(t *testing.T) { } for _, tt := range tests { // FIXME: the tests are set up to succeed - os/arch is not being validated at this time - p, err := regsrc.NewTerraformProvider(tt.Name, "linux", "amd64") - if err != nil { - t.Fatal(err) - } + p := regsrc.NewTerraformProvider(tt.Name, "linux", "amd64") + locationMetadata, err := client.TerraformProviderLocation(p, tt.Version) if tt.Err { if err == nil { diff --git a/registry/errors.go b/registry/errors.go index 32c1792e7..6d6dc95d4 100644 --- a/registry/errors.go +++ b/registry/errors.go @@ -37,3 +37,20 @@ func IsProviderNotFound(err error) bool { _, ok := err.(*errProviderNotFound) return ok } + +// IsServiceNotProvided returns true only if the given error is a "service not provided" +// error. This allows callers to recognize this particular error condition +// as distinct from operational errors such as poor network connectivity. +func IsServiceNotProvided(err error) bool { + _, ok := err.(*errServiceNotProvided) + return ok +} + +type errServiceNotProvided struct { + host string + service string +} + +func (e *errServiceNotProvided) Error() string { + return fmt.Sprintf("host %s does not provide %s", e.host, e.service) +} diff --git a/tools/terraform-bundle/package.go b/tools/terraform-bundle/package.go index 82e43ee88..bd8823dbc 100644 --- a/tools/terraform-bundle/package.go +++ b/tools/terraform-bundle/package.go @@ -19,6 +19,8 @@ import ( "github.com/mitchellh/cli" ) +var releaseHost = "https://releases.hashicorp.com" + type PackageCommand struct { ui cli.Ui } @@ -177,7 +179,7 @@ func (c *PackageCommand) Run(args []string) int { CopyFile(plugin.Path, workDir+"/terraform-provider-"+plugin.Name+"_v"+plugin.Version.MustParse().String()) //put into temp dir } else { //attempt to get from the public registry if not found locally c.ui.Output(fmt.Sprintf("- Checking for provider plugin on %s...", - discovery.GetReleaseHost())) + releaseHost)) _, err := installer.Get(name, constraint) if err != nil { c.ui.Error(fmt.Sprintf("- Failed to resolve %s provider %s: %s", name, constraint, err)) @@ -265,7 +267,7 @@ func (c *PackageCommand) bundleFilename(version discovery.VersionStr, time time. func (c *PackageCommand) coreURL(version discovery.VersionStr, osName, archName string) string { return fmt.Sprintf( "%s/terraform/%s/terraform_%s_%s_%s.zip", - discovery.GetReleaseHost(), version, version, osName, archName, + releaseHost, version, version, osName, archName, ) }