Merge pull request #1104 from hashicorp/f-nil-resource-data
helper/schema: allow pointer values to ResourceData.Set
This commit is contained in:
commit
1e82ccf814
|
@ -137,6 +137,25 @@ func (d *ResourceData) Partial(on bool) {
|
||||||
// will be returned.
|
// will be returned.
|
||||||
func (d *ResourceData) Set(key string, value interface{}) error {
|
func (d *ResourceData) Set(key string, value interface{}) error {
|
||||||
d.once.Do(d.init)
|
d.once.Do(d.init)
|
||||||
|
|
||||||
|
// If the value is a pointer to a non-struct, get its value and
|
||||||
|
// use that. This allows Set to take a pointer to primitives to
|
||||||
|
// simplify the interface.
|
||||||
|
reflectVal := reflect.ValueOf(value)
|
||||||
|
if reflectVal.Kind() == reflect.Ptr {
|
||||||
|
if reflectVal.IsNil() {
|
||||||
|
// If the pointer is nil, then the value is just nil
|
||||||
|
value = nil
|
||||||
|
} else {
|
||||||
|
// Otherwise, we dereference the pointer as long as its not
|
||||||
|
// a pointer to a struct, since struct pointers are allowed.
|
||||||
|
reflectVal = reflect.Indirect(reflectVal)
|
||||||
|
if reflectVal.Kind() != reflect.Struct {
|
||||||
|
value = reflectVal.Interface()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return d.setWriter.WriteField(strings.Split(key, "."), value)
|
return d.setWriter.WriteField(strings.Split(key, "."), value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1178,6 +1178,8 @@ func TestResourceDataHasChange(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestResourceDataSet(t *testing.T) {
|
func TestResourceDataSet(t *testing.T) {
|
||||||
|
var testNilPtr *string
|
||||||
|
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
Schema map[string]*Schema
|
Schema map[string]*Schema
|
||||||
State *terraform.InstanceState
|
State *terraform.InstanceState
|
||||||
|
@ -1588,6 +1590,72 @@ func TestResourceDataSet(t *testing.T) {
|
||||||
GetKey: "ratios",
|
GetKey: "ratios",
|
||||||
GetValue: []interface{}{1.0, 2.2, 5.5},
|
GetValue: []interface{}{1.0, 2.2, 5.5},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// #13: Basic pointer
|
||||||
|
{
|
||||||
|
Schema: map[string]*Schema{
|
||||||
|
"availability_zone": &Schema{
|
||||||
|
Type: TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
State: nil,
|
||||||
|
|
||||||
|
Diff: nil,
|
||||||
|
|
||||||
|
Key: "availability_zone",
|
||||||
|
Value: testPtrTo("foo"),
|
||||||
|
|
||||||
|
GetKey: "availability_zone",
|
||||||
|
GetValue: "foo",
|
||||||
|
},
|
||||||
|
|
||||||
|
// #14: Basic nil value
|
||||||
|
{
|
||||||
|
Schema: map[string]*Schema{
|
||||||
|
"availability_zone": &Schema{
|
||||||
|
Type: TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
State: nil,
|
||||||
|
|
||||||
|
Diff: nil,
|
||||||
|
|
||||||
|
Key: "availability_zone",
|
||||||
|
Value: testPtrTo(nil),
|
||||||
|
|
||||||
|
GetKey: "availability_zone",
|
||||||
|
GetValue: "",
|
||||||
|
},
|
||||||
|
|
||||||
|
// #15: Basic nil pointer
|
||||||
|
{
|
||||||
|
Schema: map[string]*Schema{
|
||||||
|
"availability_zone": &Schema{
|
||||||
|
Type: TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
State: nil,
|
||||||
|
|
||||||
|
Diff: nil,
|
||||||
|
|
||||||
|
Key: "availability_zone",
|
||||||
|
Value: testNilPtr,
|
||||||
|
|
||||||
|
GetKey: "availability_zone",
|
||||||
|
GetValue: "",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, tc := range cases {
|
for i, tc := range cases {
|
||||||
|
@ -2788,3 +2856,7 @@ func TestResourceDataSetId_override(t *testing.T) {
|
||||||
t.Fatalf("bad: %#v", actual)
|
t.Fatalf("bad: %#v", actual)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testPtrTo(raw interface{}) interface{} {
|
||||||
|
return &raw
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue