vsphere/internal/virtualdevice/virtual_machine_device_subresource.go
func applyDeviceChange(l object.VirtualDeviceList, cs []types.BaseVirtualDeviceConfigSpec) object.VirtualDeviceList {
	log.Printf("[DEBUG] applyDeviceChange: Applying changes: %s", DeviceChangeString(cs))
	log.Printf("[DEBUG] applyDeviceChange: Device list before changes: %s", DeviceListString(l))
	for _, s := range cs {
		spec := s.GetVirtualDeviceConfigSpec()
		switch spec.Operation {
		case types.VirtualDeviceConfigSpecOperationAdd:
			l = append(l, spec.Device)
		case types.VirtualDeviceConfigSpecOperationEdit:
			// Edit operations may not be 100% necessary to apply. This is because
			// more often than not, the device will probably be edited in place off
			// of the original reference, meaning that the slice should actually
			// point to the updated item. However, the safer of the two options is to
			// assume that this may *not* be happening as we are not enforcing that
			// in implementation anywhere.
			for n, dev := range l {
				if dev.GetVirtualDevice().Key == spec.Device.GetVirtualDevice().Key {
					l[n] = spec.Device
				}
			}
		case types.VirtualDeviceConfigSpecOperationRemove:
			for i := 0; i < len(l); i++ {
				dev := l[i]
				if dev.GetVirtualDevice().Key == spec.Device.GetVirtualDevice().Key {
					l = append(l[:i], l[i+1:]...)
					i--
				}
			}
		default:
			panic("unknown op")
		}
	}
	log.Printf("[DEBUG] applyDeviceChange: Device list after changes: %s", DeviceListString(l))
	return l
}
func applyDeviceChange(l object.VirtualDeviceList, cs []types.BaseVirtualDeviceConfigSpec) object.VirtualDeviceList {
	log.Printf("[DEBUG] applyDeviceChange: Applying changes: %s", DeviceChangeString(cs))
	log.Printf("[DEBUG] applyDeviceChange: Device list before changes: %s", DeviceListString(l))
	for _, s := range cs {
		spec := s.GetVirtualDeviceConfigSpec()
		switch spec.Operation {
		case types.VirtualDeviceConfigSpecOperationAdd:
			l = append(l, spec.Device)
		case types.VirtualDeviceConfigSpecOperationEdit:
			// Edit operations may not be 100% necessary to apply. This is because
			// more often than not, the device will probably be edited in place off
			// of the original reference, meaning that the slice should actually
			// point to the updated item. However, the safer of the two options is to
			// assume that this may *not* be happening as we are not enforcing that
			// in implementation anywhere.
			for n, dev := range l {
				if dev.GetVirtualDevice().Key == spec.Device.GetVirtualDevice().Key {
					l[n] = spec.Device
				}
			}
		case types.VirtualDeviceConfigSpecOperationRemove:
			for i := 0; i < len(l); i++ {
				dev := l[i]
				if dev.GetVirtualDevice().Key == spec.Device.GetVirtualDevice().Key {
					l = append(l[:i], l[i+1:]...)
					i--
				}
			}
		default:
			panic("unknown op")
		}
	}
	log.Printf("[DEBUG] applyDeviceChange: Device list after changes: %s", DeviceListString(l))
	return l
}
// applyDeviceChange applies a pending types.BaseVirtualDeviceConfigSpec to a
// working set to either add, remove, or update devices so that the working
// VirtualDeviceList is as up to date as possible.