diff --git a/plugin/discovery/get.go b/plugin/discovery/get.go index 2f6ac1a91..751844e17 100644 --- a/plugin/discovery/get.go +++ b/plugin/discovery/get.go @@ -134,6 +134,7 @@ func (i *ProviderInstaller) Get(provider string, req Constraints) (PluginMeta, e if len(allVersions.Versions) == 0 { return PluginMeta{}, ErrorNoSuitableVersion } + providerSource := allVersions.ID // Filter the list of plugin versions to those which meet the version constraints versions := allowedVersions(allVersions, req) @@ -175,7 +176,7 @@ func (i *ProviderInstaller) Get(provider string, req Constraints) (PluginMeta, e return PluginMeta{}, ErrorNoVersionCompatibleWithPlatform } - downloadURLs, err := i.listProviderDownloadURLs(provider, versionMeta.Version) + downloadURLs, err := i.listProviderDownloadURLs(providerSource, versionMeta.Version) providerURL := downloadURLs.DownloadURL i.Ui.Info(fmt.Sprintf("- Downloading plugin for provider %q (%s)...", provider, versionMeta.Version)) @@ -193,6 +194,9 @@ func (i *ProviderInstaller) Get(provider string, req Constraints) (PluginMeta, e } } + printedProviderName := fmt.Sprintf("%s (%s)", provider, providerSource) + i.Ui.Info(fmt.Sprintf("- Downloading plugin for provider %q (%s)...", printedProviderName, versionMeta.Version)) + log.Printf("[DEBUG] getting provider %q version %q", printedProviderName, versionMeta.Version) err = i.install(provider, v, providerURL) if err != nil { return PluginMeta{}, err diff --git a/plugin/discovery/get_test.go b/plugin/discovery/get_test.go index 534a01fa5..73e8bdd18 100644 --- a/plugin/discovery/get_test.go +++ b/plugin/discovery/get_test.go @@ -130,6 +130,7 @@ func testHandler(w http.ResponseWriter, r *http.Request) { func testReleaseServer() *httptest.Server { handler := http.NewServeMux() + handler.HandleFunc("/v1/providers/-/", testHandler) handler.HandleFunc("/v1/providers/terraform-providers/", testHandler) handler.HandleFunc("/terraform-provider-template/", testChecksumHandler) handler.HandleFunc("/terraform-provider-badsig/", testChecksumHandler) @@ -479,7 +480,7 @@ func Disco(s *httptest.Server) *disco.Disco { } var versionList = response.TerraformProvider{ - ID: "test", + ID: "terraform-providers/test", Versions: []*response.TerraformProviderVersion{ {Version: "1.2.1"}, {Version: "1.2.3"}, diff --git a/registry/regsrc/terraform_provider.go b/registry/regsrc/terraform_provider.go index 88acddfa2..58dedee5e 100644 --- a/registry/regsrc/terraform_provider.go +++ b/registry/regsrc/terraform_provider.go @@ -3,6 +3,7 @@ package regsrc import ( "fmt" "runtime" + "strings" "github.com/hashicorp/terraform/svchost" ) @@ -10,7 +11,7 @@ import ( var ( // DefaultProviderNamespace represents the namespace for canonical // HashiCorp-controlled providers. - DefaultProviderNamespace = "terraform-providers" + DefaultProviderNamespace = "-" ) // TerraformProvider describes a Terraform Registry Provider source. @@ -31,9 +32,14 @@ func NewTerraformProvider(name, os, arch string) *TerraformProvider { arch = runtime.GOARCH } + // separate namespace if included + namespace := DefaultProviderNamespace + if names := strings.SplitN(name, "/", 2); len(names) == 2 { + namespace, name = names[0], names[1] + } p := &TerraformProvider{ RawHost: PublicRegistryHost, - RawNamespace: DefaultProviderNamespace, + RawNamespace: namespace, RawName: name, OS: os, Arch: arch, diff --git a/registry/regsrc/terraform_provider_test.go b/registry/regsrc/terraform_provider_test.go new file mode 100644 index 000000000..50ffab073 --- /dev/null +++ b/registry/regsrc/terraform_provider_test.go @@ -0,0 +1,48 @@ +package regsrc + +import ( + "testing" +) + +func TestNewTerraformProviderNamespace(t *testing.T) { + tests := []struct { + name string + provider string + expectedNamespace string + expectedName string + }{ + { + name: "default", + provider: "null", + expectedNamespace: "-", + expectedName: "null", + }, { + name: "explicit", + provider: "terraform-providers/null", + expectedNamespace: "terraform-providers", + expectedName: "null", + }, { + name: "community", + provider: "community-providers/null", + expectedNamespace: "community-providers", + expectedName: "null", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + actual := NewTerraformProvider(tt.provider, "", "") + + if actual == nil { + t.Fatal("NewTerraformProvider() unexpectedly returned nil provider") + } + + if v := actual.RawNamespace; v != tt.expectedNamespace { + t.Fatalf("RawNamespace = %v, wanted %v", v, tt.expectedNamespace) + } + if v := actual.RawName; v != tt.expectedName { + t.Fatalf("RawName = %v, wanted %v", v, tt.expectedName) + } + }) + } +} diff --git a/registry/test/mock_registry.go b/registry/test/mock_registry.go index e94e6c173..9688fbeb5 100644 --- a/registry/test/mock_registry.go +++ b/registry/test/mock_registry.go @@ -100,14 +100,14 @@ var testMods = map[string][]testMod{ } var testProviders = map[string][]testProvider{ - "terraform-providers/foo": { + "-/foo": { { version: "0.2.3", url: "https://releases.hashicorp.com/terraform-provider-foo/0.2.3/terraform-provider-foo.zip", }, {version: "0.3.0"}, }, - "terraform-providers/bar": { + "-/bar": { { version: "0.1.1", url: "https://releases.hashicorp.com/terraform-provider-bar/0.1.1/terraform-provider-bar.zip", @@ -116,6 +116,22 @@ var testProviders = map[string][]testProvider{ }, } +func providerAlias(provider string) string { + re := regexp.MustCompile("^-/") + if re.MatchString(provider) { + return re.ReplaceAllString(provider, "terraform-providers/") + } + return provider +} + +func init() { + // Add provider aliases + for provider, info := range testProviders { + alias := providerAlias(provider) + testProviders[alias] = info + } +} + func latestVersion(versions []string) string { var col version.Collection for _, v := range versions { @@ -287,7 +303,7 @@ func mockRegHandler() http.Handler { } } - name := fmt.Sprintf("%s", matches[1]) + name := providerAlias(fmt.Sprintf("%s", matches[1])) versions, ok := testProviders[name] if !ok { http.NotFound(w, r) @@ -295,7 +311,7 @@ func mockRegHandler() http.Handler { } // only adding the single requested provider for now - // this is the minimal that any regisry is epected to support + // this is the minimal that any registry is expected to support pvs := &response.TerraformProviderVersions{ ID: name, }