command/cliconfig: Installation methods, not installation sources

Unfortunately in the user model the noun "source" is already used for the
argument in the required_providers block to specify which provider to use,
so it's confusing to use the same noun to also refer to the method used to
obtain that provider.

In the hope of mitigating that confusion, here we use the noun "method",
as in "installation method", to talk about the decision between getting
a provider directly from its origin registry or getting it from some
mirror. This is distinct from the provider's "source", which is the
location where a provider _originates_ (prior to mirroring).

This noun is also not super awesome, but better than overloading an
existing term in the same feature.
This commit is contained in:
Martin Atkins 2020-04-22 16:28:06 -07:00
parent e872ec4461
commit f5012c12da
4 changed files with 50 additions and 50 deletions

View File

@ -235,13 +235,13 @@ func TestConfig_Merge(t *testing.T) {
}, },
ProviderInstallation: []*ProviderInstallation{ ProviderInstallation: []*ProviderInstallation{
{ {
Sources: []*ProviderInstallationSource{ Methods: []*ProviderInstallationMethod{
{Location: ProviderInstallationFilesystemMirror("a")}, {Location: ProviderInstallationFilesystemMirror("a")},
{Location: ProviderInstallationFilesystemMirror("b")}, {Location: ProviderInstallationFilesystemMirror("b")},
}, },
}, },
{ {
Sources: []*ProviderInstallationSource{ Methods: []*ProviderInstallationMethod{
{Location: ProviderInstallationFilesystemMirror("c")}, {Location: ProviderInstallationFilesystemMirror("c")},
}, },
}, },
@ -273,7 +273,7 @@ func TestConfig_Merge(t *testing.T) {
}, },
ProviderInstallation: []*ProviderInstallation{ ProviderInstallation: []*ProviderInstallation{
{ {
Sources: []*ProviderInstallationSource{ Methods: []*ProviderInstallationMethod{
{Location: ProviderInstallationFilesystemMirror("d")}, {Location: ProviderInstallationFilesystemMirror("d")},
}, },
}, },
@ -316,18 +316,18 @@ func TestConfig_Merge(t *testing.T) {
}, },
ProviderInstallation: []*ProviderInstallation{ ProviderInstallation: []*ProviderInstallation{
{ {
Sources: []*ProviderInstallationSource{ Methods: []*ProviderInstallationMethod{
{Location: ProviderInstallationFilesystemMirror("a")}, {Location: ProviderInstallationFilesystemMirror("a")},
{Location: ProviderInstallationFilesystemMirror("b")}, {Location: ProviderInstallationFilesystemMirror("b")},
}, },
}, },
{ {
Sources: []*ProviderInstallationSource{ Methods: []*ProviderInstallationMethod{
{Location: ProviderInstallationFilesystemMirror("c")}, {Location: ProviderInstallationFilesystemMirror("c")},
}, },
}, },
{ {
Sources: []*ProviderInstallationSource{ Methods: []*ProviderInstallationMethod{
{Location: ProviderInstallationFilesystemMirror("d")}, {Location: ProviderInstallationFilesystemMirror("d")},
}, },
}, },

View File

@ -11,7 +11,7 @@ import (
// ProviderInstallation is the structure of the "provider_installation" // ProviderInstallation is the structure of the "provider_installation"
// nested block within the CLI configuration. // nested block within the CLI configuration.
type ProviderInstallation struct { type ProviderInstallation struct {
Sources []*ProviderInstallationSource Methods []*ProviderInstallationMethod
} }
// decodeProviderInstallationFromConfig uses the HCL AST API directly to // decodeProviderInstallationFromConfig uses the HCL AST API directly to
@ -66,42 +66,42 @@ func decodeProviderInstallationFromConfig(hclFile *hclast.File) ([]*ProviderInst
// it will always be an hclast.ObjectType. // it will always be an hclast.ObjectType.
body := block.Val.(*hclast.ObjectType) body := block.Val.(*hclast.ObjectType)
for _, sourceBlock := range body.List.Items { for _, methodBlock := range body.List.Items {
if sourceBlock.Assign.Line != 0 { if methodBlock.Assign.Line != 0 {
// Seems to be an attribute rather than a block // Seems to be an attribute rather than a block
diags = diags.Append(tfdiags.Sourceless( diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error, tfdiags.Error,
"Invalid provider_installation source block", "Invalid provider_installation method block",
fmt.Sprintf("The items inside the provider_installation block at %s must all be blocks.", block.Pos()), fmt.Sprintf("The items inside the provider_installation block at %s must all be blocks.", block.Pos()),
)) ))
continue continue
} }
if len(sourceBlock.Keys) > 1 { if len(methodBlock.Keys) > 1 {
diags = diags.Append(tfdiags.Sourceless( diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error, tfdiags.Error,
"Invalid provider_installation source block", "Invalid provider_installation method block",
fmt.Sprintf("The blocks inside the provider_installation block at %s may not have any labels.", block.Pos()), fmt.Sprintf("The blocks inside the provider_installation block at %s may not have any labels.", block.Pos()),
)) ))
} }
sourceBody := sourceBlock.Val.(*hclast.ObjectType) methodBody := methodBlock.Val.(*hclast.ObjectType)
sourceTypeStr := sourceBlock.Keys[0].Token.Value().(string) methodTypeStr := methodBlock.Keys[0].Token.Value().(string)
var location ProviderInstallationSourceLocation var location ProviderInstallationLocation
var include, exclude []string var include, exclude []string
switch sourceTypeStr { switch methodTypeStr {
case "direct": case "direct":
type BodyContent struct { type BodyContent struct {
Include []string `hcl:"include"` Include []string `hcl:"include"`
Exclude []string `hcl:"exclude"` Exclude []string `hcl:"exclude"`
} }
var bodyContent BodyContent var bodyContent BodyContent
err := hcl.DecodeObject(&bodyContent, sourceBody) err := hcl.DecodeObject(&bodyContent, methodBody)
if err != nil { if err != nil {
diags = diags.Append(tfdiags.Sourceless( diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error, tfdiags.Error,
"Invalid provider_installation source block", "Invalid provider_installation method block",
fmt.Sprintf("Invalid %s block at %s: %s.", sourceTypeStr, block.Pos(), err), fmt.Sprintf("Invalid %s block at %s: %s.", methodTypeStr, block.Pos(), err),
)) ))
continue continue
} }
@ -115,20 +115,20 @@ func decodeProviderInstallationFromConfig(hclFile *hclast.File) ([]*ProviderInst
Exclude []string `hcl:"exclude"` Exclude []string `hcl:"exclude"`
} }
var bodyContent BodyContent var bodyContent BodyContent
err := hcl.DecodeObject(&bodyContent, sourceBody) err := hcl.DecodeObject(&bodyContent, methodBody)
if err != nil { if err != nil {
diags = diags.Append(tfdiags.Sourceless( diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error, tfdiags.Error,
"Invalid provider_installation source block", "Invalid provider_installation method block",
fmt.Sprintf("Invalid %s block at %s: %s.", sourceTypeStr, block.Pos(), err), fmt.Sprintf("Invalid %s block at %s: %s.", methodTypeStr, block.Pos(), err),
)) ))
continue continue
} }
if bodyContent.Path == "" { if bodyContent.Path == "" {
diags = diags.Append(tfdiags.Sourceless( diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error, tfdiags.Error,
"Invalid provider_installation source block", "Invalid provider_installation method block",
fmt.Sprintf("Invalid %s block at %s: \"path\" argument is required.", sourceTypeStr, block.Pos()), fmt.Sprintf("Invalid %s block at %s: \"path\" argument is required.", methodTypeStr, block.Pos()),
)) ))
continue continue
} }
@ -142,20 +142,20 @@ func decodeProviderInstallationFromConfig(hclFile *hclast.File) ([]*ProviderInst
Exclude []string `hcl:"exclude"` Exclude []string `hcl:"exclude"`
} }
var bodyContent BodyContent var bodyContent BodyContent
err := hcl.DecodeObject(&bodyContent, sourceBody) err := hcl.DecodeObject(&bodyContent, methodBody)
if err != nil { if err != nil {
diags = diags.Append(tfdiags.Sourceless( diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error, tfdiags.Error,
"Invalid provider_installation source block", "Invalid provider_installation method block",
fmt.Sprintf("Invalid %s block at %s: %s.", sourceTypeStr, block.Pos(), err), fmt.Sprintf("Invalid %s block at %s: %s.", methodTypeStr, block.Pos(), err),
)) ))
continue continue
} }
if bodyContent.URL == "" { if bodyContent.URL == "" {
diags = diags.Append(tfdiags.Sourceless( diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error, tfdiags.Error,
"Invalid provider_installation source block", "Invalid provider_installation method block",
fmt.Sprintf("Invalid %s block at %s: \"url\" argument is required.", sourceTypeStr, block.Pos()), fmt.Sprintf("Invalid %s block at %s: \"url\" argument is required.", methodTypeStr, block.Pos()),
)) ))
continue continue
} }
@ -165,13 +165,13 @@ func decodeProviderInstallationFromConfig(hclFile *hclast.File) ([]*ProviderInst
default: default:
diags = diags.Append(tfdiags.Sourceless( diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error, tfdiags.Error,
"Invalid provider_installation source block", "Invalid provider_installation method block",
fmt.Sprintf("Unknown provider installation source type %q at %s.", sourceTypeStr, sourceBlock.Pos()), fmt.Sprintf("Unknown provider installation method %q at %s.", methodTypeStr, methodBlock.Pos()),
)) ))
continue continue
} }
pi.Sources = append(pi.Sources, &ProviderInstallationSource{ pi.Methods = append(pi.Methods, &ProviderInstallationMethod{
Location: location, Location: location,
Include: include, Include: include,
Exclude: exclude, Exclude: exclude,
@ -184,22 +184,22 @@ func decodeProviderInstallationFromConfig(hclFile *hclast.File) ([]*ProviderInst
return ret, diags return ret, diags
} }
// ProviderInstallationSource represents an installation source block inside // ProviderInstallationMethod represents an installation method block inside
// a provider_installation block. // a provider_installation block.
type ProviderInstallationSource struct { type ProviderInstallationMethod struct {
Location ProviderInstallationSourceLocation Location ProviderInstallationLocation
Include []string `hcl:"include"` Include []string `hcl:"include"`
Exclude []string `hcl:"exclude"` Exclude []string `hcl:"exclude"`
} }
// ProviderInstallationSourceLocation is an interface type representing the // ProviderInstallationLocation is an interface type representing the
// different installation source types. The concrete implementations of // different installation location types. The concrete implementations of
// this interface are: // this interface are:
// //
// ProviderInstallationDirect: install from the provider's origin registry // ProviderInstallationDirect: install from the provider's origin registry
// ProviderInstallationFilesystemMirror(dir): install from a local filesystem mirror // ProviderInstallationFilesystemMirror(dir): install from a local filesystem mirror
// ProviderInstallationNetworkMirror(host): install from a network mirror // ProviderInstallationNetworkMirror(host): install from a network mirror
type ProviderInstallationSourceLocation interface { type ProviderInstallationLocation interface {
providerInstallationLocation() providerInstallationLocation()
} }
@ -209,7 +209,7 @@ func (i configProviderInstallationDirect) providerInstallationLocation() {}
// ProviderInstallationDirect is a ProviderInstallationSourceLocation // ProviderInstallationDirect is a ProviderInstallationSourceLocation
// representing installation from a provider's origin registry. // representing installation from a provider's origin registry.
var ProviderInstallationDirect ProviderInstallationSourceLocation = configProviderInstallationDirect{} var ProviderInstallationDirect ProviderInstallationLocation = configProviderInstallationDirect{}
// ProviderInstallationFilesystemMirror is a ProviderInstallationSourceLocation // ProviderInstallationFilesystemMirror is a ProviderInstallationSourceLocation
// representing installation from a particular local filesystem mirror. The // representing installation from a particular local filesystem mirror. The

View File

@ -16,7 +16,7 @@ func TestLoadConfig_providerInstallation(t *testing.T) {
want := &Config{ want := &Config{
ProviderInstallation: []*ProviderInstallation{ ProviderInstallation: []*ProviderInstallation{
{ {
Sources: []*ProviderInstallationSource{ Methods: []*ProviderInstallationMethod{
{ {
Location: ProviderInstallationFilesystemMirror("/tmp/example1"), Location: ProviderInstallationFilesystemMirror("/tmp/example1"),
Include: []string{"example.com/*/*"}, Include: []string{"example.com/*/*"},
@ -47,11 +47,11 @@ func TestLoadConfig_providerInstallationErrors(t *testing.T) {
_, diags := loadConfigFile(filepath.Join(fixtureDir, "provider-installation-errors")) _, diags := loadConfigFile(filepath.Join(fixtureDir, "provider-installation-errors"))
want := `7 problems: want := `7 problems:
- Invalid provider_installation source block: Unknown provider installation source type "not_a_thing" at 2:3. - Invalid provider_installation method block: Unknown provider installation method "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 method block: Invalid filesystem_mirror block at 1:1: "path" argument is required.
- Invalid provider_installation source block: Invalid network_mirror block at 1:1: "url" argument is required. - Invalid provider_installation method 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 method 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 method 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. - Invalid provider_installation block: The provider_installation block at 9:1 must not have any labels.
- Invalid provider_installation block: The provider_installation block at 11:1 must not be introduced with an equals sign.` - Invalid provider_installation block: The provider_installation block at 11:1 must not be introduced with an equals sign.`

View File

@ -39,14 +39,14 @@ func explicitProviderSource(config *cliconfig.ProviderInstallation, services *di
var diags tfdiags.Diagnostics var diags tfdiags.Diagnostics
var searchRules []getproviders.MultiSourceSelector var searchRules []getproviders.MultiSourceSelector
for _, sourceConfig := range config.Sources { for _, methodConfig := range config.Methods {
source, moreDiags := providerSourceForCLIConfigLocation(sourceConfig.Location, services) source, moreDiags := providerSourceForCLIConfigLocation(methodConfig.Location, services)
diags = diags.Append(moreDiags) diags = diags.Append(moreDiags)
if moreDiags.HasErrors() { if moreDiags.HasErrors() {
continue continue
} }
include, err := getproviders.ParseMultiSourceMatchingPatterns(sourceConfig.Include) include, err := getproviders.ParseMultiSourceMatchingPatterns(methodConfig.Include)
if err != nil { if err != nil {
diags = diags.Append(tfdiags.Sourceless( diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error, tfdiags.Error,
@ -54,7 +54,7 @@ func explicitProviderSource(config *cliconfig.ProviderInstallation, services *di
fmt.Sprintf("CLI config specifies invalid provider inclusion patterns: %s.", err), fmt.Sprintf("CLI config specifies invalid provider inclusion patterns: %s.", err),
)) ))
} }
exclude, err := getproviders.ParseMultiSourceMatchingPatterns(sourceConfig.Include) exclude, err := getproviders.ParseMultiSourceMatchingPatterns(methodConfig.Include)
if err != nil { if err != nil {
diags = diags.Append(tfdiags.Sourceless( diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error, tfdiags.Error,
@ -179,7 +179,7 @@ func implicitProviderSource(services *disco.Disco) getproviders.Source {
return getproviders.MultiSource(searchRules) return getproviders.MultiSource(searchRules)
} }
func providerSourceForCLIConfigLocation(loc cliconfig.ProviderInstallationSourceLocation, services *disco.Disco) (getproviders.Source, tfdiags.Diagnostics) { func providerSourceForCLIConfigLocation(loc cliconfig.ProviderInstallationLocation, services *disco.Disco) (getproviders.Source, tfdiags.Diagnostics) {
if loc == cliconfig.ProviderInstallationDirect { if loc == cliconfig.ProviderInstallationDirect {
return getproviders.NewMemoizeSource( return getproviders.NewMemoizeSource(
getproviders.NewRegistrySource(services), getproviders.NewRegistrySource(services),