addrs: detect builtin provider when parsing legacy provider string (#25154)

* addrs: detect builtin provider when parsing legacy provider string

The ParseLegacyAbsProviderConfig was not detecting builtin providers
("terraform"), which caused issues for all users with 0.12 state and
the "terraform_remote_state" data source. Since "terraform" is the only
built-in provider this adds a very simple check to the parser so it
properly returns the builtin FQN.

* add tests to the addrs package
This commit is contained in:
Kristin Laemmert 2020-06-08 08:27:36 -04:00 committed by GitHub
parent d741c3f917
commit 58bcc2e9bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 74 additions and 3 deletions

View File

@ -279,9 +279,14 @@ func ParseLegacyAbsProviderConfig(traversal hcl.Traversal) (AbsProviderConfig, t
return ret, diags
}
// We always assume legacy-style providers in legacy state
// We always assume legacy-style providers in legacy state ...
if tt, ok := remain[1].(hcl.TraverseAttr); ok {
ret.Provider = NewLegacyProvider(tt.Name)
// ... unless it's the builtin "terraform" provider, a special case.
if tt.Name == "terraform" {
ret.Provider = NewBuiltInProvider(tt.Name)
} else {
ret.Provider = NewLegacyProvider(tt.Name)
}
} else {
diags = diags.Append(&hcl.Diagnostic{
Severity: hcl.DiagError,

View File

@ -1,6 +1,7 @@
package addrs
import (
"reflect"
"testing"
"github.com/go-test/deep"
@ -241,3 +242,39 @@ func TestAbsProviderConfigLegacyString(t *testing.T) {
}
}
}
func TestParseLegacyAbsProviderConfigStr(t *testing.T) {
tests := []struct {
Config string
Want AbsProviderConfig
}{
{
`provider.foo`,
AbsProviderConfig{
Module: RootModule,
Provider: NewLegacyProvider("foo"),
},
},
{
`module.child_module.provider.foo`,
AbsProviderConfig{
Module: RootModule.Child("child_module"),
Provider: NewLegacyProvider("foo"),
},
},
{
`provider.terraform`,
AbsProviderConfig{
Module: RootModule,
Provider: NewBuiltInProvider("terraform"),
},
},
}
for _, test := range tests {
got, _ := ParseLegacyAbsProviderConfigStr(test.Config)
if !reflect.DeepEqual(got, test.Want) {
t.Errorf("wrong result. Got %s, want %s\n", got, test.Want)
}
}
}

View File

@ -10,6 +10,20 @@
}
},
"resources": [
{
"mode": "data",
"type": "terraform_remote_state",
"name": "random",
"provider": "provider.terraform",
"instances": [
{
"schema_version": 0,
"attributes_flat": {
"backend": "remote"
}
}
]
},
{
"mode": "managed",
"type": "null_resource",

View File

@ -10,6 +10,20 @@
}
},
"resources": [
{
"mode": "data",
"type": "terraform_remote_state",
"name": "random",
"provider": "provider[\"terraform.io/builtin/terraform\"]",
"instances": [
{
"schema_version": 0,
"attributes_flat": {
"backend": "remote"
}
}
]
},
{
"mode": "managed",
"type": "null_resource",

View File

@ -87,7 +87,8 @@ func prepareStateV4(sV4 *stateV4) (*File, tfdiags.Diagnostics) {
// If ParseAbsProviderConfigStr returns an error, the state may have
// been written before Provider FQNs were introduced and the
// AbsProviderConfig string format will need normalization. If so,
// we assume it is a default (hashicorp) provider.
// we treat it like a legacy provider (namespace "-") and let the
// provider installer handle detecting the FQN.
var legacyAddrDiags tfdiags.Diagnostics
providerAddr, legacyAddrDiags = addrs.ParseLegacyAbsProviderConfigStr(rsV4.ProviderConfig)
if legacyAddrDiags.HasErrors() {