mirror of
https://github.com/opentofu/opentofu.git
synced 2025-01-15 11:13:09 -06:00
sdk: use core schema for json state upgrade
When handling the json state in UpgradeResourceState, the schema must be what core uses, because that is the schema used for encoding/decoding the json state. When converting from flatmap to json state, the legacy schema will be used to decode the flatmap to a cty value, but the resulting json will be encoded using the CoreConfigSchema to match what core expects.
This commit is contained in:
parent
bcf2aa06dd
commit
ec65fb960d
@ -261,30 +261,31 @@ func (s *GRPCProviderServer) UpgradeResourceState(_ context.Context, req *proto.
|
|||||||
|
|
||||||
res := s.provider.ResourcesMap[req.TypeName]
|
res := s.provider.ResourcesMap[req.TypeName]
|
||||||
blockForCore := s.getResourceSchemaBlockForCore(req.TypeName)
|
blockForCore := s.getResourceSchemaBlockForCore(req.TypeName)
|
||||||
blockForShimming := s.getResourceSchemaBlockForShimming(req.TypeName)
|
|
||||||
|
|
||||||
version := int(req.Version)
|
version := int(req.Version)
|
||||||
|
|
||||||
var jsonMap map[string]interface{}
|
jsonMap := map[string]interface{}{}
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
// if there's a JSON state, we need to decode it.
|
switch {
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We first need to upgrade a flatmap state if it exists.
|
// We first need to upgrade a flatmap state if it exists.
|
||||||
// There should never be both a JSON and Flatmap state in the request.
|
// 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)
|
jsonMap, version, err = s.upgradeFlatmapState(version, req.RawState.Flatmap, res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
||||||
return resp, nil
|
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
|
// 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
|
// 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
|
// now we need to turn the state into the default json representation, so
|
||||||
// that it can be re-decoded using the actual schema.
|
// 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 {
|
if err != nil {
|
||||||
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
||||||
return resp, nil
|
return resp, nil
|
||||||
@ -433,6 +434,11 @@ func (s *GRPCProviderServer) removeAttributes(v interface{}, ty cty.Type) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ty == cty.DynamicPseudoType {
|
||||||
|
log.Printf("[DEBUG] ignoring dynamic block: %#v\n", v)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if !ty.IsObjectType() {
|
if !ty.IsObjectType() {
|
||||||
// This shouldn't happen, and will fail to decode further on, so
|
// This shouldn't happen, and will fail to decode further on, so
|
||||||
// there's no need to handle it here.
|
// there's no need to handle it here.
|
||||||
|
@ -154,10 +154,9 @@ func TestUpgradeState_removedAttr(t *testing.T) {
|
|||||||
r3 := &schema.Resource{
|
r3 := &schema.Resource{
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
"config_mode_attr": {
|
"config_mode_attr": {
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
ConfigMode: schema.SchemaConfigModeAttr,
|
ConfigMode: schema.SchemaConfigModeAttr,
|
||||||
SkipCoreTypeCheck: true,
|
Optional: true,
|
||||||
Optional: true,
|
|
||||||
Elem: &schema.Resource{
|
Elem: &schema.Resource{
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
"foo": {
|
"foo": {
|
||||||
|
Loading…
Reference in New Issue
Block a user