diff --git a/command/cliconfig/provider_installation.go b/command/cliconfig/provider_installation.go index 10e8f4fc1..d5e57ac05 100644 --- a/command/cliconfig/provider_installation.go +++ b/command/cliconfig/provider_installation.go @@ -138,7 +138,7 @@ func decodeProviderInstallationFromConfig(hclFile *hclast.File) ([]*ProviderInst exclude = bodyContent.Exclude case "network_mirror": type BodyContent struct { - Host string `hcl:"host"` + URL string `hcl:"url"` Include []string `hcl:"include"` Exclude []string `hcl:"exclude"` } @@ -152,15 +152,15 @@ func decodeProviderInstallationFromConfig(hclFile *hclast.File) ([]*ProviderInst )) continue } - if bodyContent.Host == "" { + if bodyContent.URL == "" { diags = diags.Append(tfdiags.Sourceless( tfdiags.Error, "Invalid provider_installation source block", - fmt.Sprintf("Invalid %s block at %s: \"host\" argument is required.", sourceTypeStr, block.Pos()), + fmt.Sprintf("Invalid %s block at %s: \"url\" argument is required.", sourceTypeStr, block.Pos()), )) continue } - location = ProviderInstallationNetworkMirror(bodyContent.Host) + location = ProviderInstallationNetworkMirror(bodyContent.URL) include = bodyContent.Include exclude = bodyContent.Exclude default: @@ -229,8 +229,8 @@ func (i ProviderInstallationFilesystemMirror) providerInstallationLocation() {} // ProviderInstallationNetworkMirror is a ProviderInstallationSourceLocation // representing installation from a particular local network mirror. The -// string value is the hostname exactly as written in the configuration, without -// any normalization. +// string value is the HTTP base URL exactly as written in the configuration, +// without any normalization. type ProviderInstallationNetworkMirror string func (i ProviderInstallationNetworkMirror) providerInstallationLocation() {} diff --git a/command/cliconfig/provider_installation_test.go b/command/cliconfig/provider_installation_test.go index a9cb7e00c..553d0bc75 100644 --- a/command/cliconfig/provider_installation_test.go +++ b/command/cliconfig/provider_installation_test.go @@ -22,7 +22,7 @@ func TestLoadConfig_providerInstallation(t *testing.T) { Include: []string{"example.com/*/*"}, }, { - Location: ProviderInstallationNetworkMirror("tf-Mirror.example.com"), + Location: ProviderInstallationNetworkMirror("https://tf-Mirror.example.com/"), Include: []string{"registry.terraform.io/*/*"}, Exclude: []string{"registry.Terraform.io/foobar/*"}, }, @@ -49,7 +49,7 @@ func TestLoadConfig_providerInstallationErrors(t *testing.T) { - Invalid provider_installation source block: Unknown provider installation source type "not_a_thing" at 2:3. - Invalid provider_installation source block: Invalid filesystem_mirror block at 1:1: "path" argument is required. -- Invalid provider_installation source block: Invalid network_mirror block at 1:1: "host" argument is required. +- Invalid provider_installation source block: Invalid network_mirror block at 1:1: "url" argument is required. - Invalid provider_installation source block: The items inside the provider_installation block at 1:1 must all be blocks. - Invalid provider_installation source block: The blocks inside the provider_installation block at 1:1 may not have any labels. - Invalid provider_installation block: The provider_installation block at 9:1 must not have any labels. diff --git a/command/cliconfig/testdata/provider-installation b/command/cliconfig/testdata/provider-installation index ff2d5fbec..91dc82eab 100644 --- a/command/cliconfig/testdata/provider-installation +++ b/command/cliconfig/testdata/provider-installation @@ -4,7 +4,7 @@ provider_installation { include = ["example.com/*/*"] } network_mirror { - host = "tf-Mirror.example.com" + url = "https://tf-Mirror.example.com/" include = ["registry.terraform.io/*/*"] exclude = ["registry.Terraform.io/foobar/*"] } diff --git a/internal/getproviders/http_mirror_source.go b/internal/getproviders/http_mirror_source.go index 5b5bb80f1..c2dedf9db 100644 --- a/internal/getproviders/http_mirror_source.go +++ b/internal/getproviders/http_mirror_source.go @@ -1,6 +1,7 @@ package getproviders import ( + "fmt" "net/url" "github.com/hashicorp/terraform/addrs" @@ -26,13 +27,11 @@ func NewHTTPMirrorSource(baseURL *url.URL) *HTTPMirrorSource { // AvailableVersions retrieves the available versions for the given provider // from the object's underlying HTTP mirror service. func (s *HTTPMirrorSource) AvailableVersions(provider addrs.Provider) (VersionList, error) { - // TODO: Implement - panic("HTTPMirrorSource.AvailableVersions not yet implemented") + return nil, fmt.Errorf("Network-based provider mirrors are not supported in this version of Terraform") } // PackageMeta retrieves metadata for the requested provider package // from the object's underlying HTTP mirror service. func (s *HTTPMirrorSource) PackageMeta(provider addrs.Provider, version Version, target Platform) (PackageMeta, error) { - // TODO: Implement - panic("HTTPMirrorSource.PackageMeta not yet implemented") + return PackageMeta{}, fmt.Errorf("Network-based provider mirrors are not supported in this version of Terraform") } diff --git a/internal/getproviders/network_mirror_source.go b/internal/getproviders/network_mirror_source.go deleted file mode 100644 index 26b8ba0f8..000000000 --- a/internal/getproviders/network_mirror_source.go +++ /dev/null @@ -1,39 +0,0 @@ -package getproviders - -import ( - "fmt" - - svchost "github.com/hashicorp/terraform-svchost" - - "github.com/hashicorp/terraform/addrs" -) - -// NetworkMirrorSource is a source that reads providers and their metadata -// from an HTTP server implementing the Terraform network mirror protocol. -type NetworkMirrorSource struct { - host svchost.Hostname -} - -var _ Source = (*NetworkMirrorSource)(nil) - -// NewNetworkMirrorSource constructs and returns a new network-based -// mirror source that will expect to find a mirror service on the given -// host. -func NewNetworkMirrorSource(host svchost.Hostname) *NetworkMirrorSource { - return &NetworkMirrorSource{ - host: host, - } -} - -// AvailableVersions retrieves the available versions for the given provider -// from the network mirror. -func (s *NetworkMirrorSource) AvailableVersions(provider addrs.Provider) (VersionList, error) { - return nil, fmt.Errorf("Network provider mirror is not supported in this version of Terraform") -} - -// PackageMeta checks to see if the network mirror contains a copy of the -// distribution package for the given provider version on the given target, -// and returns the metadata about it if so. -func (s *NetworkMirrorSource) PackageMeta(provider addrs.Provider, version Version, target Platform) (PackageMeta, error) { - return PackageMeta{}, fmt.Errorf("Network provider mirror is not supported in this version of Terraform") -} diff --git a/provider_source.go b/provider_source.go index bfbdf0f3f..1d804342e 100644 --- a/provider_source.go +++ b/provider_source.go @@ -3,11 +3,11 @@ package main import ( "fmt" "log" + "net/url" "os" "path/filepath" "github.com/apparentlymart/go-userdirs/userdirs" - svchost "github.com/hashicorp/terraform-svchost" "github.com/hashicorp/terraform-svchost/disco" "github.com/hashicorp/terraform/addrs" @@ -192,17 +192,26 @@ func providerSourceForCLIConfigLocation(loc cliconfig.ProviderInstallationSource return getproviders.NewFilesystemMirrorSource(string(loc)), nil case cliconfig.ProviderInstallationNetworkMirror: - host, err := svchost.ForComparison(string(loc)) + url, err := url.Parse(string(loc)) if err != nil { var diags tfdiags.Diagnostics diags = diags.Append(tfdiags.Sourceless( tfdiags.Error, - "Invalid hostname for provider installation source", - fmt.Sprintf("Cannot parse %q as a hostname for a network provider mirror: %s.", string(loc), err), + "Invalid URL for provider installation source", + fmt.Sprintf("Cannot parse %q as a URL for a network provider mirror: %s.", string(loc), err), )) return nil, diags } - return getproviders.NewNetworkMirrorSource(host), nil + if url.Scheme != "https" || url.Host == "" { + var diags tfdiags.Diagnostics + diags = diags.Append(tfdiags.Sourceless( + tfdiags.Error, + "Invalid URL for provider installation source", + fmt.Sprintf("Cannot use %q as a URL for a network provider mirror: the mirror must be at an https: URL.", string(loc)), + )) + return nil, diags + } + return getproviders.NewHTTPMirrorSource(url), nil default: // We should not get here because the set of cases above should