addrs: Disallow provider source addresses starting with terraform-
The main motivation here is to produce a helpful error if a user incorrectly uses the terraform-provider- prefix (which we see on provider VCS repositories and plugin executables) as part of the source address. However, this also more broadly blocks "terraform-" as a prefix in anticipation of whatever instinct causes the phenomenon where e.g. Python's PyPI has thousands of packages whose names start with "python-", even though everything on PyPI is for Python by definition. This is definitely not _necessary_, but it's better to be restrictive at first and weaken later as needed.
This commit is contained in:
parent
7909dd318d
commit
0a46ded3e7
|
@ -324,6 +324,51 @@ func ParseProviderSourceString(str string) (Provider, tfdiags.Diagnostics) {
|
||||||
return Provider{}, diags
|
return Provider{}, diags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Due to how plugin executables are named and provider git repositories
|
||||||
|
// are conventionally named, it's a reasonable and
|
||||||
|
// apparently-somewhat-common user error to incorrectly use the
|
||||||
|
// "terraform-provider-" prefix in a provider source address. There is
|
||||||
|
// no good reason for a provider to have the prefix "terraform-" anyway,
|
||||||
|
// so we've made that invalid from the start both so we can give feedback
|
||||||
|
// to provider developers about the terraform- prefix being redundant
|
||||||
|
// and give specialized feedback to folks who incorrectly use the full
|
||||||
|
// terraform-provider- prefix to help them self-correct.
|
||||||
|
const redundantPrefix = "terraform-"
|
||||||
|
const userErrorPrefix = "terraform-provider-"
|
||||||
|
if strings.HasPrefix(ret.Type, redundantPrefix) {
|
||||||
|
if strings.HasPrefix(ret.Type, userErrorPrefix) {
|
||||||
|
// Likely user error. We only return this specialized error if
|
||||||
|
// whatever is after the prefix would otherwise be a
|
||||||
|
// syntactically-valid provider type, so we don't end up advising
|
||||||
|
// the user to try something that would be invalid for another
|
||||||
|
// reason anyway.
|
||||||
|
// (This is mainly just for robustness, because the validation
|
||||||
|
// we already did above should've rejected most/all ways for
|
||||||
|
// the suggestedType to end up invalid here.)
|
||||||
|
suggestedType := ret.Type[len(userErrorPrefix):]
|
||||||
|
if _, err := ParseProviderPart(suggestedType); err == nil {
|
||||||
|
suggestedAddr := ret
|
||||||
|
suggestedAddr.Type = suggestedType
|
||||||
|
diags = diags.Append(tfdiags.Sourceless(
|
||||||
|
tfdiags.Error,
|
||||||
|
"Invalid provider type",
|
||||||
|
fmt.Sprintf("Provider source %q has a type with the prefix %q, which isn't valid. Although that prefix is often used in the names of version control repositories for Terraform providers, provider source strings should not include it.\n\nDid you mean %q?", ret.ForDisplay(), userErrorPrefix, suggestedAddr.ForDisplay()),
|
||||||
|
))
|
||||||
|
return Provider{}, diags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Otherwise, probably instead an incorrectly-named provider, perhaps
|
||||||
|
// arising from a similar instinct to what causes there to be
|
||||||
|
// thousands of Python packages on PyPI with "python-"-prefixed
|
||||||
|
// names.
|
||||||
|
diags = diags.Append(tfdiags.Sourceless(
|
||||||
|
tfdiags.Error,
|
||||||
|
"Invalid provider type",
|
||||||
|
fmt.Sprintf("Provider source %q has a type with the prefix %q, which isn't allowed because it would be redundant to name a Terraform provider with that prefix. If you are the author of this provider, rename it to not include the prefix.", ret, redundantPrefix),
|
||||||
|
))
|
||||||
|
return Provider{}, diags
|
||||||
|
}
|
||||||
|
|
||||||
return ret, diags
|
return ret, diags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -379,6 +379,20 @@ func TestParseProviderSourceStr(t *testing.T) {
|
||||||
Provider{},
|
Provider{},
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// We forbid the terraform- prefix both because it's redundant to
|
||||||
|
// include "terraform" in a Terraform provider name and because we use
|
||||||
|
// the longer prefix terraform-provider- to hint for users who might be
|
||||||
|
// accidentally using the git repository name or executable file name
|
||||||
|
// instead of the provider type.
|
||||||
|
"example.com/hashicorp/terraform-provider-bad": {
|
||||||
|
Provider{},
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
"example.com/hashicorp/terraform-bad": {
|
||||||
|
Provider{},
|
||||||
|
true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, test := range tests {
|
for name, test := range tests {
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
terraform {
|
||||||
|
required_providers {
|
||||||
|
usererror = { # ERROR: Invalid provider type
|
||||||
|
source = "foo/terraform-provider-foo"
|
||||||
|
}
|
||||||
|
badname = { # ERROR: Invalid provider type
|
||||||
|
source = "foo/terraform-foo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue