Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 34 additions & 16 deletions linode/instanceconfig/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,33 @@ func createDevice(deviceMap map[string]any) linodego.InstanceConfigDevice {
return device
}

func expandDevicesBlock(devicesBlock any) *linodego.InstanceConfigDeviceMap {
func setDeviceMapField(target *linodego.InstanceConfigDeviceMap, deviceKey string, device linodego.InstanceConfigDevice) error {
if target == nil {
return nil
}

structVal := reflect.ValueOf(target).Elem()
lookupKey := strings.ToUpper(strings.TrimSpace(deviceKey))
field := structVal.FieldByName(lookupKey)

if !field.IsValid() {
return fmt.Errorf("unknown device %q (no matching field on InstanceConfigDeviceMap)", deviceKey)
}
if !field.CanSet() {
return fmt.Errorf("cannot set device %q (field exists but is unsettable)", deviceKey)
}

field.Set(reflect.ValueOf(&device))
return nil
}

func expandDevicesBlock(devicesBlock any) (*linodego.InstanceConfigDeviceMap, error) {
var result linodego.InstanceConfigDeviceMap

devices := devicesBlock.(*schema.Set).List()

if len(devices) <= 0 {
return nil
return nil, nil
}

seenDevices := make(map[string]bool)
Expand All @@ -118,26 +138,23 @@ func expandDevicesBlock(devicesBlock any) *linodego.InstanceConfigDeviceMap {
seenDevices[deviceName.(string)] = true
}

field := reflect.Indirect(
reflect.ValueOf(&result),
).FieldByName(
strings.ToUpper(deviceName.(string)),
)

field.Set(reflect.ValueOf(&linodeGoDevice))
err := setDeviceMapField(&result, deviceName.(string), linodeGoDevice)
if err != nil {
return nil, err
}
}
}

return &result
return &result, nil
}

func expandDevicesNamedBlock(devicesNamedBlock any) *linodego.InstanceConfigDeviceMap {
func expandDevicesNamedBlock(devicesNamedBlock any) (*linodego.InstanceConfigDeviceMap, error) {
var result linodego.InstanceConfigDeviceMap

deviceMapSlice := devicesNamedBlock.([]any)

if len(deviceMapSlice) < 1 {
return nil
return nil, nil
}

devices := deviceMapSlice[0].(map[string]any)
Expand All @@ -151,12 +168,13 @@ func expandDevicesNamedBlock(devicesNamedBlock any) *linodego.InstanceConfigDevi
currentDevice := currentDeviceSlice[0].(map[string]any)
linodeGoDevice := createDevice(currentDevice)

// Get the corresponding struct field and set it to the correct device
field := reflect.Indirect(reflect.ValueOf(&result)).FieldByName(strings.ToUpper(k))
field.Set(reflect.ValueOf(&linodeGoDevice))
err := setDeviceMapField(&result, k, linodeGoDevice)
if err != nil {
return nil, err
}
}

return &result
return &result, nil
}

func expandHelpers(helpersRaw any) *linodego.InstanceConfigHelpers {
Expand Down
10 changes: 8 additions & 2 deletions linode/instanceconfig/helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ func TestExpandDevicesNamedBlock(t *testing.T) {
},
}

result := expandDevicesNamedBlock(inputValue)
result, err := expandDevicesNamedBlock(inputValue)
if err != nil {
t.Fatalf("failed to expand devices named block: %s", err)
}

if result.SDA.DiskID != 12345 {
t.Fatal("disk id != 12345")
Expand All @@ -46,7 +49,10 @@ func TestExpandDevicesBlock(t *testing.T) {
return schema.HashString(i.(map[string]any)["device_name"])
}, inputValue)

result := expandDevicesBlock(setValue)
result, err := expandDevicesBlock(setValue)
if err != nil {
t.Fatalf("failed to expand devices block: %s", err)
}

if result.SDA.DiskID != 12345 {
t.Fatal("disk id != 12345")
Expand Down
21 changes: 17 additions & 4 deletions linode/instanceconfig/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,17 @@ func createResource(ctx context.Context, d *schema.ResourceData, meta any) diag.
}

var devices *linodego.InstanceConfigDeviceMap
var err error
if devicesBlock, ok := d.GetOk("device"); ok {
devices = expandDevicesBlock(devicesBlock)
devices, err = expandDevicesBlock(devicesBlock)
if err != nil {
return diag.Errorf("failed to expand devices block: %s", err)
}
} else if devicesBlock, ok := d.GetOk("devices"); ok {
devices = expandDevicesNamedBlock(devicesBlock)
devices, err = expandDevicesNamedBlock(devicesBlock)
if err != nil {
return diag.Errorf("failed to expand devices named block: %s", err)
}
}
if devices != nil {
createOpts.Devices = *devices
Expand Down Expand Up @@ -213,14 +220,20 @@ func updateResource(ctx context.Context, d *schema.ResourceData, meta any) diag.

if d.HasChange("device") {
if devices, ok := d.GetOk("device"); ok {
putRequest.Devices = expandDevicesBlock(devices)
putRequest.Devices, err = expandDevicesBlock(devices)
if err != nil {
return diag.Errorf("failed to expand devices block: %s", err)
}
}
shouldUpdate = true
}

if d.HasChange("devices") {
if devices, ok := d.GetOk("devices"); ok {
putRequest.Devices = expandDevicesNamedBlock(devices)
putRequest.Devices, err = expandDevicesNamedBlock(devices)
if err != nil {
return diag.Errorf("failed to expand devices named block: %s", err)
}
}
shouldUpdate = true
}
Expand Down