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:
parent
e872ec4461
commit
f5012c12da
|
@ -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")},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.`
|
||||||
|
|
||||||
|
|
|
@ -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),
|
||||||
|
|
Loading…
Reference in New Issue