Merge pull request #21625 from hashicorp/f-allow-missing-MigrateState

helper/plugin: Allow missing MigrateState for provider flatmap state upgrades
This commit is contained in:
James Bardin 2019-06-10 17:35:53 -04:00 committed by GitHub
commit c502b4c144
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 88 additions and 5 deletions

View File

@ -2,7 +2,6 @@ package plugin
import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"log" "log"
"strconv" "strconv"
@ -316,11 +315,15 @@ func (s *GRPCProviderServer) upgradeFlatmapState(version int, m map[string]strin
requiresMigrate = version < res.StateUpgraders[0].Version requiresMigrate = version < res.StateUpgraders[0].Version
} }
if requiresMigrate { if requiresMigrate && res.MigrateState == nil {
if res.MigrateState == nil { // Providers were previously allowed to bump the version
return nil, 0, errors.New("cannot upgrade state, missing MigrateState function") // without declaring MigrateState.
// If there are further upgraders, then we've only updated that far.
if len(res.StateUpgraders) > 0 {
schemaType = res.StateUpgraders[0].Type
upgradedVersion = res.StateUpgraders[0].Version
} }
} else if requiresMigrate {
is := &terraform.InstanceState{ is := &terraform.InstanceState{
ID: m["id"], ID: m["id"],
Attributes: m, Attributes: m,

View File

@ -437,6 +437,86 @@ func TestUpgradeState_flatmapState(t *testing.T) {
} }
} }
func TestUpgradeState_flatmapStateMissingMigrateState(t *testing.T) {
r := &schema.Resource{
SchemaVersion: 1,
Schema: map[string]*schema.Schema{
"one": {
Type: schema.TypeInt,
Required: true,
},
},
}
server := &GRPCProviderServer{
provider: &schema.Provider{
ResourcesMap: map[string]*schema.Resource{
"test": r,
},
},
}
testReqs := []*proto.UpgradeResourceState_Request{
{
TypeName: "test",
Version: 0,
RawState: &proto.RawState{
Flatmap: map[string]string{
"id": "bar",
"one": "1",
},
},
},
{
TypeName: "test",
Version: 1,
RawState: &proto.RawState{
Flatmap: map[string]string{
"id": "bar",
"one": "1",
},
},
},
{
TypeName: "test",
Version: 1,
RawState: &proto.RawState{
Json: []byte(`{"id":"bar","one":1}`),
},
},
}
for i, req := range testReqs {
t.Run(fmt.Sprintf("%d-%d", i, req.Version), func(t *testing.T) {
resp, err := server.UpgradeResourceState(nil, req)
if err != nil {
t.Fatal(err)
}
if len(resp.Diagnostics) > 0 {
for _, d := range resp.Diagnostics {
t.Errorf("%#v", d)
}
t.Fatal("error")
}
val, err := msgpack.Unmarshal(resp.UpgradedState.Msgpack, r.CoreConfigSchema().ImpliedType())
if err != nil {
t.Fatal(err)
}
expected := cty.ObjectVal(map[string]cty.Value{
"id": cty.StringVal("bar"),
"one": cty.NumberIntVal(1),
})
if !cmp.Equal(expected, val, valueComparer, equateEmpty) {
t.Fatal(cmp.Diff(expected, val, valueComparer, equateEmpty))
}
})
}
}
func TestPlanResourceChange(t *testing.T) { func TestPlanResourceChange(t *testing.T) {
r := &schema.Resource{ r := &schema.Resource{
SchemaVersion: 4, SchemaVersion: 4,