diff --git a/helper/plugin/grpc_provider.go b/helper/plugin/grpc_provider.go index b9b420995..c907bcb72 100644 --- a/helper/plugin/grpc_provider.go +++ b/helper/plugin/grpc_provider.go @@ -261,30 +261,31 @@ func (s *GRPCProviderServer) UpgradeResourceState(_ context.Context, req *proto. res := s.provider.ResourcesMap[req.TypeName] blockForCore := s.getResourceSchemaBlockForCore(req.TypeName) - blockForShimming := s.getResourceSchemaBlockForShimming(req.TypeName) version := int(req.Version) - var jsonMap map[string]interface{} + jsonMap := map[string]interface{}{} var err error - // if there's a JSON state, we need to decode it. - if len(req.RawState.Json) > 0 { - err = json.Unmarshal(req.RawState.Json, &jsonMap) - if err != nil { - resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err) - return resp, nil - } - } - + switch { // We first need to upgrade a flatmap state if it exists. // There should never be both a JSON and Flatmap state in the request. - if req.RawState.Flatmap != nil { + case len(req.RawState.Flatmap) > 0: jsonMap, version, err = s.upgradeFlatmapState(version, req.RawState.Flatmap, res) if err != nil { resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err) return resp, nil } + // if there's a JSON state, we need to decode it. + case len(req.RawState.Json) > 0: + err = json.Unmarshal(req.RawState.Json, &jsonMap) + if err != nil { + resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err) + return resp, nil + } + default: + log.Println("[DEBUG] no state provided to upgrade") + return resp, nil } // complete the upgrade of the JSON states @@ -295,11 +296,11 @@ func (s *GRPCProviderServer) UpgradeResourceState(_ context.Context, req *proto. } // The provider isn't required to clean out removed fields - s.removeAttributes(jsonMap, blockForShimming.ImpliedType()) + s.removeAttributes(jsonMap, blockForCore.ImpliedType()) // now we need to turn the state into the default json representation, so // that it can be re-decoded using the actual schema. - val, err := schema.JSONMapToStateValue(jsonMap, blockForShimming) + val, err := schema.JSONMapToStateValue(jsonMap, blockForCore) if err != nil { resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err) return resp, nil @@ -433,6 +434,11 @@ func (s *GRPCProviderServer) removeAttributes(v interface{}, ty cty.Type) { return } + if ty == cty.DynamicPseudoType { + log.Printf("[DEBUG] ignoring dynamic block: %#v\n", v) + return + } + if !ty.IsObjectType() { // This shouldn't happen, and will fail to decode further on, so // there's no need to handle it here. diff --git a/helper/plugin/grpc_provider_test.go b/helper/plugin/grpc_provider_test.go index f58778c47..6186cd411 100644 --- a/helper/plugin/grpc_provider_test.go +++ b/helper/plugin/grpc_provider_test.go @@ -154,10 +154,9 @@ func TestUpgradeState_removedAttr(t *testing.T) { r3 := &schema.Resource{ Schema: map[string]*schema.Schema{ "config_mode_attr": { - Type: schema.TypeList, - ConfigMode: schema.SchemaConfigModeAttr, - SkipCoreTypeCheck: true, - Optional: true, + Type: schema.TypeList, + ConfigMode: schema.SchemaConfigModeAttr, + Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "foo": {