mirror of https://github.com/hashicorp/terraform
stacks: add the packages service to the rpc api (#34319)
* stacks: add the packages service to the rpc api * go generatepull/34331/head
parent
cbfbe51556
commit
e703eb7b17
@ -0,0 +1,75 @@
|
||||
package dynrpcserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
tf1 "github.com/hashicorp/terraform/internal/rpcapi/terraform1"
|
||||
)
|
||||
|
||||
type Packages struct {
|
||||
impl tf1.PackagesServer
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
var _ tf1.PackagesServer = (*Packages)(nil)
|
||||
|
||||
func NewPackagesStub() *Packages {
|
||||
return &Packages{}
|
||||
}
|
||||
|
||||
func (s *Packages) FetchModulePackage(a0 context.Context, a1 *tf1.FetchModulePackage_Request) (*tf1.FetchModulePackage_Response, error) {
|
||||
impl, err := s.realRPCServer()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return impl.FetchModulePackage(a0, a1)
|
||||
}
|
||||
|
||||
func (s *Packages) FetchProviderPackage(a0 context.Context, a1 *tf1.FetchProviderPackage_Request) (*tf1.FetchProviderPackage_Response, error) {
|
||||
impl, err := s.realRPCServer()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return impl.FetchProviderPackage(a0, a1)
|
||||
}
|
||||
|
||||
func (s *Packages) ModulePackageSourceAddr(a0 context.Context, a1 *tf1.ModulePackageSourceAddr_Request) (*tf1.ModulePackageSourceAddr_Response, error) {
|
||||
impl, err := s.realRPCServer()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return impl.ModulePackageSourceAddr(a0, a1)
|
||||
}
|
||||
|
||||
func (s *Packages) ModulePackageVersions(a0 context.Context, a1 *tf1.ModulePackageVersions_Request) (*tf1.ModulePackageVersions_Response, error) {
|
||||
impl, err := s.realRPCServer()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return impl.ModulePackageVersions(a0, a1)
|
||||
}
|
||||
|
||||
func (s *Packages) ProviderPackageVersions(a0 context.Context, a1 *tf1.ProviderPackageVersions_Request) (*tf1.ProviderPackageVersions_Response, error) {
|
||||
impl, err := s.realRPCServer()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return impl.ProviderPackageVersions(a0, a1)
|
||||
}
|
||||
|
||||
func (s *Packages) ActivateRPCServer(impl tf1.PackagesServer) {
|
||||
s.mu.Lock()
|
||||
s.impl = impl
|
||||
s.mu.Unlock()
|
||||
}
|
||||
|
||||
func (s *Packages) realRPCServer() (tf1.PackagesServer, error) {
|
||||
s.mu.RLock()
|
||||
impl := s.impl
|
||||
s.mu.RUnlock()
|
||||
if impl == nil {
|
||||
return nil, unavailableErr
|
||||
}
|
||||
return impl, nil
|
||||
}
|
||||
@ -0,0 +1,256 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package rpcapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/apparentlymart/go-versions/versions"
|
||||
"github.com/hashicorp/terraform-svchost/disco"
|
||||
|
||||
"github.com/hashicorp/terraform/internal/addrs"
|
||||
"github.com/hashicorp/terraform/internal/getmodules"
|
||||
"github.com/hashicorp/terraform/internal/getproviders"
|
||||
"github.com/hashicorp/terraform/internal/providercache"
|
||||
"github.com/hashicorp/terraform/internal/registry"
|
||||
"github.com/hashicorp/terraform/internal/registry/regsrc"
|
||||
"github.com/hashicorp/terraform/internal/rpcapi/terraform1"
|
||||
)
|
||||
|
||||
var _ terraform1.PackagesServer = (*packagesServer)(nil)
|
||||
|
||||
func newPackagesServer(services *disco.Disco) *packagesServer {
|
||||
return &packagesServer{
|
||||
services: services,
|
||||
|
||||
// This function lets us control the provider source during tests.
|
||||
providerSourceFn: func(services *disco.Disco) getproviders.Source {
|
||||
// TODO: Implement loading from alternate sources like network or filesystem
|
||||
// mirrors.
|
||||
return getproviders.NewRegistrySource(services)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type providerSourceFn func(services *disco.Disco) getproviders.Source
|
||||
|
||||
type packagesServer struct {
|
||||
terraform1.UnimplementedPackagesServer
|
||||
|
||||
services *disco.Disco
|
||||
providerSourceFn providerSourceFn
|
||||
}
|
||||
|
||||
func (p *packagesServer) ProviderPackageVersions(ctx context.Context, request *terraform1.ProviderPackageVersions_Request) (*terraform1.ProviderPackageVersions_Response, error) {
|
||||
response := new(terraform1.ProviderPackageVersions_Response)
|
||||
|
||||
source := p.providerSourceFn(p.services)
|
||||
provider, diags := addrs.ParseProviderSourceString(request.SourceAddr)
|
||||
response.Diagnostics = append(response.Diagnostics, diagnosticsToProto(diags)...)
|
||||
if diags.HasErrors() {
|
||||
return response, nil
|
||||
}
|
||||
|
||||
versions, warnings, err := source.AvailableVersions(ctx, provider)
|
||||
|
||||
displayWarnings := make([]string, len(warnings))
|
||||
for ix, warning := range warnings {
|
||||
displayWarnings[ix] = fmt.Sprintf("- %s", warning)
|
||||
}
|
||||
if len(displayWarnings) > 0 {
|
||||
response.Diagnostics = append(response.Diagnostics, &terraform1.Diagnostic{
|
||||
Severity: terraform1.Diagnostic_WARNING,
|
||||
Summary: "Additional provider information from registry",
|
||||
Detail: fmt.Sprintf("The remote registry returned warnings for %s:\n%s", provider.ForDisplay(), strings.Join(displayWarnings, "\n")),
|
||||
})
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
// TODO: Parse the different error types so we can provide specific
|
||||
// error diagnostics, see commands/init.go:621.
|
||||
response.Diagnostics = append(response.Diagnostics, &terraform1.Diagnostic{
|
||||
Severity: terraform1.Diagnostic_ERROR,
|
||||
Summary: "Failed to query available provider packages",
|
||||
Detail: fmt.Sprintf("Could not retrieve the list of available versions for provider %s: %s.", provider.ForDisplay(), err),
|
||||
})
|
||||
return response, nil
|
||||
}
|
||||
|
||||
for _, version := range versions {
|
||||
response.Versions = append(response.Versions, version.String())
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (p *packagesServer) FetchProviderPackage(ctx context.Context, request *terraform1.FetchProviderPackage_Request) (*terraform1.FetchProviderPackage_Response, error) {
|
||||
|
||||
response := new(terraform1.FetchProviderPackage_Response)
|
||||
|
||||
version, err := versions.ParseVersion(request.Version)
|
||||
if err != nil {
|
||||
response.Diagnostics = append(response.Diagnostics, &terraform1.Diagnostic{
|
||||
Severity: terraform1.Diagnostic_ERROR,
|
||||
Summary: "Invalid platform",
|
||||
Detail: fmt.Sprintf("The requested version %s is invalid: %s.", request.Version, err),
|
||||
})
|
||||
return response, nil
|
||||
}
|
||||
|
||||
source := p.providerSourceFn(p.services)
|
||||
provider, diags := addrs.ParseProviderSourceString(request.SourceAddr)
|
||||
response.Diagnostics = append(response.Diagnostics, diagnosticsToProto(diags)...)
|
||||
if diags.HasErrors() {
|
||||
return response, nil
|
||||
}
|
||||
|
||||
var allowedHashes []getproviders.Hash
|
||||
for _, hash := range request.Hashes {
|
||||
allowedHashes = append(allowedHashes, getproviders.Hash(hash))
|
||||
}
|
||||
|
||||
for _, requestPlatform := range request.Platforms {
|
||||
result := new(terraform1.FetchProviderPackage_PlatformResult)
|
||||
response.Results = append(response.Results, result)
|
||||
|
||||
platform, err := getproviders.ParsePlatform(requestPlatform)
|
||||
if err != nil {
|
||||
result.Diagnostics = append(result.Diagnostics, &terraform1.Diagnostic{
|
||||
Severity: terraform1.Diagnostic_ERROR,
|
||||
Summary: "Invalid platform",
|
||||
Detail: fmt.Sprintf("The requested platform %s is invalid: %s.", requestPlatform, err),
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
meta, err := source.PackageMeta(ctx, provider, version, platform)
|
||||
if err != nil {
|
||||
// TODO: Parse the different error types so we can provide specific
|
||||
// error diagnostics, see commands/init.go:731.
|
||||
result.Diagnostics = append(result.Diagnostics, &terraform1.Diagnostic{
|
||||
Severity: terraform1.Diagnostic_ERROR,
|
||||
Summary: "Failed to query provider package metadata",
|
||||
Detail: fmt.Sprintf("Could not retrieve package metadata for provider %s@%s for %s: %s.", provider.ForDisplay(), version.String(), platform.String(), err),
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
into := providercache.NewDirWithPlatform(request.CacheDir, platform)
|
||||
authResult, err := into.InstallPackage(ctx, meta, allowedHashes)
|
||||
if err != nil {
|
||||
// TODO: Parse the different error types so we can provide specific
|
||||
// error diagnostics, see commands/init.go:731.
|
||||
result.Diagnostics = append(result.Diagnostics, &terraform1.Diagnostic{
|
||||
Severity: terraform1.Diagnostic_ERROR,
|
||||
Summary: "Failed to download provider package",
|
||||
Detail: fmt.Sprintf("Could not download provider %s@%s for %s: %s.", provider.ForDisplay(), version.String(), platform.String(), err),
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
var hashes []string
|
||||
if authResult.SignedByAnyParty() {
|
||||
for _, hash := range meta.AcceptableHashes() {
|
||||
hashes = append(hashes, string(hash))
|
||||
}
|
||||
}
|
||||
|
||||
providerPackage := into.ProviderVersion(provider, version)
|
||||
hash, err := providerPackage.Hash()
|
||||
if err != nil {
|
||||
result.Diagnostics = append(result.Diagnostics, &terraform1.Diagnostic{
|
||||
Severity: terraform1.Diagnostic_ERROR,
|
||||
Summary: "Failed to hash provider package",
|
||||
Detail: fmt.Sprintf("Could not hash provider %s@%s for %s: %s.", provider.ForDisplay(), version.String(), platform.String(), err),
|
||||
})
|
||||
continue
|
||||
}
|
||||
hashes = append(hashes, string(hash))
|
||||
result.Provider = &terraform1.ProviderPackage{
|
||||
SourceAddr: request.SourceAddr,
|
||||
Version: request.Version,
|
||||
Hashes: hashes,
|
||||
}
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (p *packagesServer) ModulePackageVersions(ctx context.Context, request *terraform1.ModulePackageVersions_Request) (*terraform1.ModulePackageVersions_Response, error) {
|
||||
response := new(terraform1.ModulePackageVersions_Response)
|
||||
|
||||
module, err := regsrc.ParseModuleSource(request.SourceAddr)
|
||||
if err != nil {
|
||||
response.Diagnostics = append(response.Diagnostics, &terraform1.Diagnostic{
|
||||
Severity: terraform1.Diagnostic_ERROR,
|
||||
Summary: "Invalid module source",
|
||||
Detail: fmt.Sprintf("Module source %s is invalid: %s.", request.SourceAddr, err),
|
||||
})
|
||||
return response, nil
|
||||
}
|
||||
|
||||
client := registry.NewClient(p.services, nil)
|
||||
versions, err := client.ModuleVersions(ctx, module)
|
||||
if err != nil {
|
||||
response.Diagnostics = append(response.Diagnostics, &terraform1.Diagnostic{
|
||||
Severity: terraform1.Diagnostic_ERROR,
|
||||
Summary: "Failed to query available module packages",
|
||||
Detail: fmt.Sprintf("Could not retrieve the list of available modules for module %s: %s.", module.Display(), err),
|
||||
})
|
||||
return response, nil
|
||||
}
|
||||
|
||||
for _, module := range versions.Modules {
|
||||
for _, version := range module.Versions {
|
||||
response.Versions = append(response.Versions, version.Version)
|
||||
}
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (p *packagesServer) ModulePackageSourceAddr(ctx context.Context, request *terraform1.ModulePackageSourceAddr_Request) (*terraform1.ModulePackageSourceAddr_Response, error) {
|
||||
response := new(terraform1.ModulePackageSourceAddr_Response)
|
||||
|
||||
module, err := regsrc.ParseModuleSource(request.SourceAddr)
|
||||
if err != nil {
|
||||
response.Diagnostics = append(response.Diagnostics, &terraform1.Diagnostic{
|
||||
Severity: terraform1.Diagnostic_ERROR,
|
||||
Summary: "Invalid module source",
|
||||
Detail: fmt.Sprintf("Module source %s is invalid: %s.", request.SourceAddr, err),
|
||||
})
|
||||
return response, nil
|
||||
}
|
||||
|
||||
client := registry.NewClient(p.services, nil)
|
||||
location, err := client.ModuleLocation(ctx, module, request.Version)
|
||||
if err != nil {
|
||||
response.Diagnostics = append(response.Diagnostics, &terraform1.Diagnostic{
|
||||
Severity: terraform1.Diagnostic_ERROR,
|
||||
Summary: "Failed to query module package metadata",
|
||||
Detail: fmt.Sprintf("Could not retrieve package metadata for provider %s at %s: %s.", module.Display(), request.Version, err),
|
||||
})
|
||||
return response, nil
|
||||
}
|
||||
response.Url = location
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (p *packagesServer) FetchModulePackage(ctx context.Context, request *terraform1.FetchModulePackage_Request) (*terraform1.FetchModulePackage_Response, error) {
|
||||
response := new(terraform1.FetchModulePackage_Response)
|
||||
|
||||
fetcher := getmodules.NewPackageFetcher()
|
||||
if err := fetcher.FetchPackage(ctx, request.CacheDir, request.Url); err != nil {
|
||||
response.Diagnostics = append(response.Diagnostics, &terraform1.Diagnostic{
|
||||
Severity: terraform1.Diagnostic_ERROR,
|
||||
Summary: "Failed to download module package",
|
||||
Detail: fmt.Sprintf("Could not download provider from %s: %s.", request.Url, err),
|
||||
})
|
||||
return response, nil
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
@ -0,0 +1,307 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package rpcapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/apparentlymart/go-versions/versions"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/hashicorp/terraform-svchost/disco"
|
||||
|
||||
"github.com/hashicorp/terraform/internal/addrs"
|
||||
"github.com/hashicorp/terraform/internal/getproviders"
|
||||
"github.com/hashicorp/terraform/internal/rpcapi/terraform1"
|
||||
)
|
||||
|
||||
func TestPackagesServer_ProviderPackageVersions(t *testing.T) {
|
||||
|
||||
tcs := map[string]struct {
|
||||
source string
|
||||
expectedVersions []string
|
||||
expectedWarnings []string
|
||||
sourceFn providerSourceFn
|
||||
}{
|
||||
"single_version": {
|
||||
source: "hashicorp/foo",
|
||||
expectedVersions: []string{"0.1.0"},
|
||||
sourceFn: func(_ *disco.Disco) getproviders.Source {
|
||||
packages := []getproviders.PackageMeta{
|
||||
{
|
||||
Provider: addrs.MustParseProviderSourceString("hashicorp/foo"),
|
||||
Version: versions.MustParseVersion("0.1.0"),
|
||||
},
|
||||
}
|
||||
return getproviders.NewMockSource(packages, nil)
|
||||
},
|
||||
},
|
||||
"multiple_versions": {
|
||||
source: "hashicorp/foo",
|
||||
expectedVersions: []string{"0.1.0", "0.2.0"},
|
||||
sourceFn: func(_ *disco.Disco) getproviders.Source {
|
||||
packages := []getproviders.PackageMeta{
|
||||
{
|
||||
Provider: addrs.MustParseProviderSourceString("hashicorp/foo"),
|
||||
Version: versions.MustParseVersion("0.1.0"),
|
||||
},
|
||||
{
|
||||
Provider: addrs.MustParseProviderSourceString("hashicorp/foo"),
|
||||
Version: versions.MustParseVersion("0.2.0"),
|
||||
},
|
||||
}
|
||||
return getproviders.NewMockSource(packages, nil)
|
||||
},
|
||||
},
|
||||
"with_warnings": {
|
||||
source: "hashicorp/foo",
|
||||
expectedVersions: []string{"0.1.0"},
|
||||
expectedWarnings: []string{"- warning one", "- warning two"},
|
||||
sourceFn: func(_ *disco.Disco) getproviders.Source {
|
||||
packages := []getproviders.PackageMeta{
|
||||
{
|
||||
Provider: addrs.MustParseProviderSourceString("hashicorp/foo"),
|
||||
Version: versions.MustParseVersion("0.1.0"),
|
||||
},
|
||||
}
|
||||
warnings := map[addrs.Provider]getproviders.Warnings{
|
||||
addrs.MustParseProviderSourceString("hashicorp/foo"): {
|
||||
"warning one",
|
||||
"warning two",
|
||||
},
|
||||
}
|
||||
return getproviders.NewMockSource(packages, warnings)
|
||||
},
|
||||
},
|
||||
}
|
||||
for name, tc := range tcs {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
service := &packagesServer{
|
||||
providerSourceFn: tc.sourceFn,
|
||||
}
|
||||
|
||||
response, err := service.ProviderPackageVersions(context.Background(), &terraform1.ProviderPackageVersions_Request{
|
||||
SourceAddr: tc.source,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(tc.expectedWarnings) > 0 {
|
||||
for _, diag := range response.Diagnostics {
|
||||
if diag.Severity == terraform1.Diagnostic_WARNING && diag.Summary == "Additional provider information from registry" {
|
||||
expected := fmt.Sprintf("The remote registry returned warnings for %s:\n%s", tc.source, strings.Join(tc.expectedWarnings, "\n"))
|
||||
if diff := cmp.Diff(expected, diag.Detail); len(diff) > 0 {
|
||||
t.Errorf(diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We're expecting only one diagnostic with the warnings.
|
||||
if len(response.Diagnostics) > 1 {
|
||||
for _, diag := range response.Diagnostics {
|
||||
t.Errorf("unexpected diagnostics: %s", diag.Detail)
|
||||
}
|
||||
return
|
||||
}
|
||||
} else {
|
||||
// Otherwise we're expecting no diagnostics.
|
||||
if len(response.Diagnostics) > 0 {
|
||||
for _, diag := range response.Diagnostics {
|
||||
t.Errorf("unexpected diagnostics: %s", diag.Detail)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(tc.expectedVersions, response.Versions); len(diff) > 0 {
|
||||
t.Errorf(diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestPackagesServer_FetchProviderPackage(t *testing.T) {
|
||||
providerHashes := providerHashes(t)
|
||||
|
||||
tcs := map[string]struct {
|
||||
// source, version, platforms, and hashes are what we're going to pass
|
||||
// in as the request.
|
||||
source string
|
||||
version string
|
||||
platforms []string
|
||||
hashes []string
|
||||
|
||||
// platformLocations, and platformHashes are what we're going to use to
|
||||
// create our virtual provider metadata.
|
||||
platformLocations map[string]string
|
||||
platformHashes map[string][]string
|
||||
|
||||
// diagnostics are the expected diagnostics for each platform.
|
||||
diagnostics map[string][]string
|
||||
}{
|
||||
"single_version_and_platform": {
|
||||
source: "hashicorp/foo",
|
||||
version: "0.1.0",
|
||||
platforms: []string{"linux_amd64"},
|
||||
platformLocations: map[string]string{
|
||||
"linux_amd64": "terraform_provider_foo",
|
||||
},
|
||||
},
|
||||
"single_version_multiple_platforms": {
|
||||
source: "hashicorp/foo",
|
||||
version: "0.1.0",
|
||||
platforms: []string{"linux_amd64", "darwin_arm64"},
|
||||
platformLocations: map[string]string{
|
||||
"linux_amd64": "terraform_provider_foo",
|
||||
"darwin_arm64": "terraform_provider_bar",
|
||||
},
|
||||
},
|
||||
"single_version_and_platform_with_hashes": {
|
||||
source: "hashicorp/foo",
|
||||
version: "0.1.0",
|
||||
platforms: []string{"linux_amd64"},
|
||||
platformLocations: map[string]string{
|
||||
"linux_amd64": "terraform_provider_foo",
|
||||
},
|
||||
platformHashes: map[string][]string{
|
||||
"linux_amd64": {
|
||||
"h1:dJTExJ11p+lRE8FAm4HWzTw+uMEyfE6AXXxiOgl/nB0=",
|
||||
},
|
||||
},
|
||||
},
|
||||
"single_version_and_platform_with_hashes_clash": {
|
||||
source: "hashicorp/foo",
|
||||
version: "0.1.0",
|
||||
hashes: []string{"h1:Hod4iOH+qbXMtH4orEmCem6F3T+YRPhDSNlXmOIRNuY="},
|
||||
platforms: []string{"linux_amd64"},
|
||||
platformLocations: map[string]string{
|
||||
"linux_amd64": "terraform_provider_foo",
|
||||
},
|
||||
platformHashes: map[string][]string{
|
||||
"linux_amd64": {
|
||||
"h1:dJTExJ11p+lRE8FAm4HWzTw+uMEyfE6AXXxiOgl/nB0=",
|
||||
},
|
||||
},
|
||||
diagnostics: map[string][]string{
|
||||
"linux_amd64": {
|
||||
"the local package for registry.terraform.io/hashicorp/foo 0.1.0 doesn't match any of the checksums previously recorded in the dependency lock file",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for name, tc := range tcs {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
service := &packagesServer{
|
||||
providerSourceFn: func(_ *disco.Disco) getproviders.Source {
|
||||
var providers []getproviders.PackageMeta
|
||||
for _, p := range tc.platforms {
|
||||
platform := parsePlatform(t, p)
|
||||
|
||||
var authentication getproviders.PackageAuthentication
|
||||
if len(tc.platformHashes) > 0 {
|
||||
authentication = getproviders.NewPackageHashAuthentication(platform, func() []getproviders.Hash {
|
||||
var hashes []getproviders.Hash
|
||||
for _, hash := range tc.platformHashes[p] {
|
||||
hashes = append(hashes, getproviders.Hash(hash))
|
||||
}
|
||||
return hashes
|
||||
}())
|
||||
}
|
||||
|
||||
providers = append(providers, getproviders.PackageMeta{
|
||||
Provider: addrs.MustParseProviderSourceString(tc.source),
|
||||
Version: versions.MustParseVersion(tc.version),
|
||||
TargetPlatform: platform,
|
||||
Location: getproviders.PackageLocalDir(path.Join("testdata", "providers", tc.platformLocations[p])),
|
||||
Authentication: authentication,
|
||||
})
|
||||
}
|
||||
|
||||
return getproviders.NewMockSource(providers, nil)
|
||||
},
|
||||
}
|
||||
|
||||
cacheDir := t.TempDir()
|
||||
response, err := service.FetchProviderPackage(context.Background(), &terraform1.FetchProviderPackage_Request{
|
||||
CacheDir: cacheDir,
|
||||
SourceAddr: tc.source,
|
||||
Version: tc.version,
|
||||
Platforms: tc.platforms,
|
||||
Hashes: tc.hashes,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(response.Diagnostics) > 0 {
|
||||
for _, diag := range response.Diagnostics {
|
||||
t.Errorf("unexpected diagnostics: %s", diag.Detail)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if len(response.Results) != len(tc.platforms) {
|
||||
t.Fatalf("wrong number of results")
|
||||
}
|
||||
|
||||
for ix, platform := range tc.platforms {
|
||||
result := response.Results[ix]
|
||||
|
||||
if tc.diagnostics != nil && len(tc.diagnostics[platform]) > 0 {
|
||||
if len(result.Diagnostics) != len(tc.diagnostics[platform]) {
|
||||
t.Fatalf("expected %d diagnostics for %s but found %d", len(tc.diagnostics[platform]), platform, len(result.Diagnostics))
|
||||
}
|
||||
for ix, expected := range tc.diagnostics[platform] {
|
||||
if !strings.Contains(result.Diagnostics[ix].Detail, expected) {
|
||||
t.Errorf("expected: %s\nactual: %s", expected, result.Diagnostics[ix])
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
} else {
|
||||
if len(result.Diagnostics) > 0 {
|
||||
for _, diag := range result.Diagnostics {
|
||||
t.Errorf("unexpected diagnostics for %s: %s", platform, diag.Detail)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(providerHashes[tc.platformLocations[platform]], result.Provider.Hashes); len(diff) > 0 {
|
||||
t.Errorf(diff)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func providerHashes(t *testing.T) map[string][]string {
|
||||
var hashes map[string][]string
|
||||
|
||||
data, err := os.ReadFile("testdata/providers/hashes.json")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(data, &hashes); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
return hashes
|
||||
}
|
||||
|
||||
func parsePlatform(t *testing.T, raw string) getproviders.Platform {
|
||||
platform, err := getproviders.ParsePlatform(raw)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return platform
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,4 @@
|
||||
{
|
||||
"terraform_provider_foo": ["h1:dJTExJ11p+lRE8FAm4HWzTw+uMEyfE6AXXxiOgl/nB0="],
|
||||
"terraform_provider_bar": ["h1:Hod4iOH+qbXMtH4orEmCem6F3T+YRPhDSNlXmOIRNuY="]
|
||||
}
|
||||
@ -0,0 +1,2 @@
|
||||
This is not a real provider executable. It's just here to give the packages
|
||||
service something to install.
|
||||
@ -0,0 +1,2 @@
|
||||
This is not a real provider executable. It's just here to give the packages
|
||||
service something to install.
|
||||
Loading…
Reference in new issue