mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-24 08:00:17 -06:00
Add a warning when multiple likely forks of a provider are detected (#1009)
Signed-off-by: Christian Mesh <christianmesh1@gmail.com>
This commit is contained in:
parent
99e51a166d
commit
78464f251a
@ -33,6 +33,7 @@ ENHANCEMENTS:
|
||||
* state: Provider addresses in the statefile referring to registry.terraform.io will be treated as referring to registry.opentofu.org unless the full provider address is specified in the config or `OPENTOFU_STATEFILE_PROVIDER_ADDRESS_TRANSLATION` is set to `0`. ([#773](https://github.com/opentofu/opentofu/pull/773))
|
||||
* The default provider namespace has been changed from "hasicorp" to "opentofu". This only impacts providers that do not explicitly have a namespace set, ex "aws" vs "hasicorp/aws". This change should be transparent and not require action to be taken by users.
|
||||
* init: Ensured that the `tofu init` command has consistent spelling of the word `initialization` in its output. ([#855](https://github.com/opentofu/opentofu/pull/855/files))
|
||||
* init: A warning is now emitted when two providers who share the same name are detected. This can help prevent misconfigurations when switching a project to use a fork of a provider. ([#1009](https://github.com/opentofu/opentofu/pull/1009))
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
|
@ -546,7 +546,13 @@ func (c *InitCommand) getProviders(ctx context.Context, config *configs.Config,
|
||||
reqs = reqs.Merge(stateReqs)
|
||||
}
|
||||
|
||||
potentialProviderConflicts := make(map[string][]string)
|
||||
|
||||
for providerAddr := range reqs {
|
||||
if providerAddr.Namespace == "hashicorp" || providerAddr.Namespace == "opentofu" {
|
||||
potentialProviderConflicts[providerAddr.Type] = append(potentialProviderConflicts[providerAddr.Type], providerAddr.ForDisplay())
|
||||
}
|
||||
|
||||
if providerAddr.IsLegacy() {
|
||||
diags = diags.Append(tfdiags.Sourceless(
|
||||
tfdiags.Error,
|
||||
@ -559,6 +565,20 @@ func (c *InitCommand) getProviders(ctx context.Context, config *configs.Config,
|
||||
}
|
||||
}
|
||||
|
||||
for name, addrs := range potentialProviderConflicts {
|
||||
if len(addrs) > 1 {
|
||||
diags = diags.Append(tfdiags.Sourceless(
|
||||
tfdiags.Warning,
|
||||
"Potential provider misconfiguration",
|
||||
fmt.Sprintf(
|
||||
"OpenTofu has detected multiple providers of type %s (%s) which may be a misconfiguration.\n\nIf this is intentional you can ignore this warning",
|
||||
name,
|
||||
strings.Join(addrs, ", "),
|
||||
),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
previousLocks, moreDiags := c.lockedDependencies()
|
||||
diags = diags.Append(moreDiags)
|
||||
|
||||
|
@ -1631,6 +1631,71 @@ func TestInit_getProviderDetectedLegacy(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestInit_getProviderDetectedDuplicate(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := t.TempDir()
|
||||
testCopyDir(t, testFixturePath("init-get-provider-detected-duplicate"), td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
// We need to construct a multisource with a mock source and a registry
|
||||
// source: the mock source will return ErrRegistryProviderNotKnown for an
|
||||
// unknown provider, and the registry source will allow us to look up the
|
||||
// appropriate namespace if possible.
|
||||
providerSource, psClose := newMockProviderSource(t, map[string][]string{
|
||||
"hashicorp/foo": {"1.2.3"},
|
||||
"opentofu/foo": {"1.2.3"},
|
||||
"hashicorp/bar": {"1.2.3"},
|
||||
})
|
||||
defer psClose()
|
||||
registrySource, rsClose := testRegistrySource(t)
|
||||
defer rsClose()
|
||||
multiSource := getproviders.MultiSource{
|
||||
{Source: providerSource},
|
||||
{Source: registrySource},
|
||||
}
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
view, _ := testView(t)
|
||||
m := Meta{
|
||||
Ui: ui,
|
||||
View: view,
|
||||
ProviderSource: multiSource,
|
||||
}
|
||||
|
||||
c := &InitCommand{
|
||||
Meta: m,
|
||||
}
|
||||
|
||||
args := []string{
|
||||
"-backend=false", // should be possible to install plugins without backend init
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("expected error, got output: \n%s\n%s", ui.OutputWriter.String(), ui.ErrorWriter.String())
|
||||
}
|
||||
|
||||
// error output is the main focus of this test
|
||||
errOutput := ui.ErrorWriter.String()
|
||||
errors := []string{
|
||||
"Warning: Potential provider misconfiguration",
|
||||
"OpenTofu has detected multiple providers of type foo",
|
||||
"If this is intentional you can ignore this warning",
|
||||
}
|
||||
unexpected := []string{
|
||||
"OpenTofu has detected multiple providers of type bar",
|
||||
}
|
||||
for _, want := range errors {
|
||||
if !strings.Contains(errOutput, want) {
|
||||
t.Fatalf("expected error %q: %s", want, errOutput)
|
||||
}
|
||||
}
|
||||
for _, unwanted := range unexpected {
|
||||
if strings.Contains(errOutput, unwanted) {
|
||||
t.Fatalf("unexpected error %q: %s", unwanted, errOutput)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestInit_providerSource(t *testing.T) {
|
||||
// Create a temporary working directory that is empty
|
||||
td := t.TempDir()
|
||||
|
10
internal/command/testdata/init-get-provider-detected-duplicate/child/main.tf
vendored
Normal file
10
internal/command/testdata/init-get-provider-detected-duplicate/child/main.tf
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
dupechild = {
|
||||
source = "hashicorp/bar"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This will try to install hashicorp/foo
|
||||
provider foo {}
|
15
internal/command/testdata/init-get-provider-detected-duplicate/main.tf
vendored
Normal file
15
internal/command/testdata/init-get-provider-detected-duplicate/main.tf
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
foo = {
|
||||
// This will conflict with the child modules hashicorp/foo
|
||||
source = "opentofu/foo"
|
||||
}
|
||||
dupe = {
|
||||
// This should not conflict with the child modules hashicorp/bar
|
||||
source = "bar"
|
||||
}
|
||||
}
|
||||
}
|
||||
module "some-baz-stuff" {
|
||||
source = "./child"
|
||||
}
|
Loading…
Reference in New Issue
Block a user