mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
helper/schema: Fix setting a set in a list
The added test in this commit, without the fix, will make d.Set return the following error: `Invalid address to set: []string{"ports", "0", "set"}` This was due to the fact that setSet in feild_writer_map tried to convert a slice into a set by creating a temp set schema and calling writeField on that with the address(`[]string{"ports", "0", "set"}"` in this case). However the temp schema was only for the set and not the whole schema as seen in the address so, it should have been `[]string{"set"}"` so it would align with the schema. This commits adds another variable there(tempAddr) which will only contain the last entry of the address that would be the set key, which would match the created schema This commit potentially fixes the problem described in #16331
This commit is contained in:
parent
af9d046afb
commit
44a45b7332
@ -297,13 +297,14 @@ func (w *MapFieldWriter) setSet(
|
|||||||
// we get the proper order back based on the hash code.
|
// we get the proper order back based on the hash code.
|
||||||
if v := reflect.ValueOf(value); v.Kind() == reflect.Slice {
|
if v := reflect.ValueOf(value); v.Kind() == reflect.Slice {
|
||||||
// Build a temp *ResourceData to use for the conversion
|
// Build a temp *ResourceData to use for the conversion
|
||||||
|
tempAddr := addr[len(addr)-1:]
|
||||||
tempSchema := *schema
|
tempSchema := *schema
|
||||||
tempSchema.Type = TypeList
|
tempSchema.Type = TypeList
|
||||||
tempSchemaMap := map[string]*Schema{addr[0]: &tempSchema}
|
tempSchemaMap := map[string]*Schema{tempAddr[0]: &tempSchema}
|
||||||
tempW := &MapFieldWriter{Schema: tempSchemaMap}
|
tempW := &MapFieldWriter{Schema: tempSchemaMap}
|
||||||
|
|
||||||
// Set the entire list, this lets us get sane values out of it
|
// Set the entire list, this lets us get sane values out of it
|
||||||
if err := tempW.WriteField(addr, value); err != nil {
|
if err := tempW.WriteField(tempAddr, value); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,7 +320,7 @@ func (w *MapFieldWriter) setSet(
|
|||||||
}
|
}
|
||||||
for i := 0; i < v.Len(); i++ {
|
for i := 0; i < v.Len(); i++ {
|
||||||
is := strconv.FormatInt(int64(i), 10)
|
is := strconv.FormatInt(int64(i), 10)
|
||||||
result, err := tempR.ReadField(append(addrCopy, is))
|
result, err := tempR.ReadField(append(tempAddr, is))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -2059,6 +2059,69 @@ func TestResourceDataSet(t *testing.T) {
|
|||||||
GetKey: "availability_zone",
|
GetKey: "availability_zone",
|
||||||
GetValue: "",
|
GetValue: "",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// #16: Set in a list
|
||||||
|
{
|
||||||
|
Schema: map[string]*Schema{
|
||||||
|
"ports": &Schema{
|
||||||
|
Type: TypeList,
|
||||||
|
Elem: &Resource{
|
||||||
|
Schema: map[string]*Schema{
|
||||||
|
"set": &Schema{
|
||||||
|
Type: TypeSet,
|
||||||
|
Elem: &Schema{Type: TypeInt},
|
||||||
|
Set: func(a interface{}) int {
|
||||||
|
return a.(int)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
State: nil,
|
||||||
|
|
||||||
|
Key: "ports",
|
||||||
|
Value: []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"set": []interface{}{
|
||||||
|
1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
GetKey: "ports",
|
||||||
|
GetValue: []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"set": []interface{}{
|
||||||
|
1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
GetPreProcess: func(v interface{}) interface{} {
|
||||||
|
if v == nil {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
s, ok := v.([]interface{})
|
||||||
|
if !ok {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
for _, v := range s {
|
||||||
|
m, ok := v.(map[string]interface{})
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if m["set"] == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if s, ok := m["set"].(*Set); ok {
|
||||||
|
m["set"] = s.List()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return v
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
oldEnv := os.Getenv(PanicOnErr)
|
oldEnv := os.Getenv(PanicOnErr)
|
||||||
|
Loading…
Reference in New Issue
Block a user