func DiskRefreshOperation(d *schema.ResourceData, c *govmomi.Client, l object.VirtualDeviceList) error {
	log.Printf("[DEBUG] DiskRefreshOperation: Beginning refresh")
	devices := SelectDisks(l, d.Get("scsi_controller_count").(int))
	log.Printf("[DEBUG] DiskRefreshOperation: Disk devices located: %s", DeviceListString(devices))
	curSet := d.Get(subresourceTypeDisk).([]interface{})
	log.Printf("[DEBUG] DiskRefreshOperation: Current resource set from state: %s", subresourceListString(curSet))
	var newSet []interface{}
	// First check for negative keys. These are freshly added devices that are
	// usually coming into read post-create.
	//
	// If we find what we are looking for, we remove the device from the working
	// set so that we don't try and process it in the next few passes.
	log.Printf("[DEBUG] DiskRefreshOperation: Looking for freshly-created or re-assigned resources to read in")
	for i, item := range curSet {
		m := item.(map[string]interface{})
		if m["key"].(int) < 1 {
			r := NewDiskSubresource(c, d, m, nil, i)
			if err := r.Read(l); err != nil {
				return fmt.Errorf("%s: %s", r.Addr(), err)
			}
			if r.Get("key").(int) < 1 {
				// This should not have happened - if it did, our device
				// creation/update logic failed somehow that we were not able to track.
				return fmt.Errorf("device %d with address %s still unaccounted for after update/read", r.Get("key").(int), r.Get("device_address").(string))
			}
			newSet = append(newSet, r.Data())
			for i := 0; i < len(devices); i++ {
				device := devices[i]
				if device.GetVirtualDevice().Key == int32(r.Get("key").(int)) {
					devices = append(devices[:i], devices[i+1:]...)
					i--
				}
			}
		}
	}
	log.Printf("[DEBUG] DiskRefreshOperation: Disk devices after created/re-assigned device search: %s", DeviceListString(devices))
	log.Printf("[DEBUG] DiskRefreshOperation: Resource set to write after created/re-assigned device search: %s", subresourceListString(newSet))

	// Go over the remaining devices, refresh via key, and then remove their
	// entries as well.
	log.Printf("[DEBUG] DiskRefreshOperation: Looking for devices known in state")
	for i := 0; i < len(devices); i++ {
		device := devices[i]
		for n, item := range curSet {
			m := item.(map[string]interface{})
			if m["key"].(int) < 1 {
				// Skip any of these keys as we won't be matching any of those anyway here
				continue
			}
			if !diskUUIDMatch(device, m["uuid"].(string)) {
				// Skip any device that doesn't match UUID
				continue
			}
			// We should have our device -> resource match, so read now.
			r := NewDiskSubresource(c, d, m, nil, n)
			if err := r.Read(l); err != nil {
				return fmt.Errorf("%s: %s", r.Addr(), err)
			}
			// Done reading, push this onto our new set and remove the device from
			// the list
			newSet = append(newSet, r.Data())
			devices = append(devices[:i], devices[i+1:]...)
			i--
		}
	}
	log.Printf("[DEBUG] DiskRefreshOperation: Resource set to write after known device search: %s", subresourceListString(newSet))
	log.Printf("[DEBUG] DiskRefreshOperation: Probable orphaned disk devices: %s", DeviceListString(devices))

	// Finally, any device that is still here is orphaned. They should be added
	// as new devices.
	log.Printf("[DEBUG] DiskRefreshOperation: Adding orphaned devices")
	for i, device := range devices {
		m := make(map[string]interface{})
		vd := device.GetVirtualDevice()
		ctlr := l.FindByKey(vd.ControllerKey)
		if ctlr == nil {
			return fmt.Errorf("could not find controller with key %d", vd.Key)
		}
		m["key"] = int(vd.Key)
		var err error
		m["device_address"], err = computeDevAddr(vd, ctlr.(types.BaseVirtualController))
		if err != nil {
			return fmt.Errorf("error computing device address: %s", err)
		}
		// We want to set keep_on_remove for these disks as well so that they are
		// not destroyed when we remove them in the next TF run.
		m["keep_on_remove"] = true
		r := NewDiskSubresource(c, d, m, nil, len(newSet))
		if err := r.Read(l); err != nil {
			return fmt.Errorf("%s: %s", r.Addr(), err)
		}
		// Add a generic label indicating that this disk is orphaned.
		r.Set("label", fmt.Sprintf("%s%d", diskOrphanedPrefix, i))
		newSet = append(newSet, r.Data())
	}

	log.Printf("[DEBUG] DiskRefreshOperation: Resource set to write after adding orphaned devices: %s", subresourceListString(newSet))
	// Sort the device list by unit number. This provides some semblance of order
	// in the state as devices are added and removed.
	sort.Sort(virtualDiskSubresourceSorter(newSet))
	log.Printf("[DEBUG] DiskRefreshOperation: Final (sorted) resource set to write: %s", subresourceListString(newSet))
	log.Printf("[DEBUG] DiskRefreshOperation: Refresh operation complete, sending new resource set")
	return d.Set(subresourceTypeDisk, newSet)
}
func DiskRefreshOperation(d *schema.ResourceData, c *govmomi.Client, l object.VirtualDeviceList) error {
	log.Printf("[DEBUG] DiskRefreshOperation: Beginning refresh")
	devices := SelectDisks(l, d.Get("scsi_controller_count").(int))
	log.Printf("[DEBUG] DiskRefreshOperation: Disk devices located: %s", DeviceListString(devices))
	curSet := d.Get(subresourceTypeDisk).([]interface{})
	log.Printf("[DEBUG] DiskRefreshOperation: Current resource set from state: %s", subresourceListString(curSet))
	var newSet []interface{}
	
	
	
	
	
	log.Printf("[DEBUG] DiskRefreshOperation: Looking for freshly-created or re-assigned resources to read in")
	for i, item := range curSet {
		m := item.(map[string]interface{})
		if m["key"].(int) < 1 {
			r := NewDiskSubresource(c, d, m, nil, i)
			if err := r.Read(l); err != nil {
				return fmt.Errorf("%s: %s", r.Addr(), err)
			}
			if r.Get("key").(int) < 1 {
				
				
				return fmt.Errorf("device %d with address %s still unaccounted for after update/read", r.Get("key").(int), r.Get("device_address").(string))
			}
			newSet = append(newSet, r.Data())
			for i := 0; i < len(devices); i++ {
				device := devices[i]
				if device.GetVirtualDevice().Key == int32(r.Get("key").(int)) {
					devices = append(devices[:i], devices[i+1:]...)
					i--
				}
			}
		}
	}
	log.Printf("[DEBUG] DiskRefreshOperation: Disk devices after created/re-assigned device search: %s", DeviceListString(devices))
	log.Printf("[DEBUG] DiskRefreshOperation: Resource set to write after created/re-assigned device search: %s", subresourceListString(newSet))

	
	
	log.Printf("[DEBUG] DiskRefreshOperation: Looking for devices known in state")
	for i := 0; i < len(devices); i++ {
		device := devices[i]
		for n, item := range curSet {
			m := item.(map[string]interface{})
			if m["key"].(int) < 1 {
				
				continue
			}
			if !diskUUIDMatch(device, m["uuid"].(string)) {
				
				continue
			}
			
			r := NewDiskSubresource(c, d, m, nil, n)
			if err := r.Read(l); err != nil {
				return fmt.Errorf("%s: %s", r.Addr(), err)
			}
			
			
			newSet = append(newSet, r.Data())
			devices = append(devices[:i], devices[i+1:]...)
			i--
		}
	}
	log.Printf("[DEBUG] DiskRefreshOperation: Resource set to write after known device search: %s", subresourceListString(newSet))
	log.Printf("[DEBUG] DiskRefreshOperation: Probable orphaned disk devices: %s", DeviceListString(devices))

	
	
	log.Printf("[DEBUG] DiskRefreshOperation: Adding orphaned devices")
	for i, device := range devices {
		m := make(map[string]interface{})
		vd := device.GetVirtualDevice()
		ctlr := l.FindByKey(vd.ControllerKey)
		if ctlr == nil {
			return fmt.Errorf("could not find controller with key %d", vd.Key)
		}
		m["key"] = int(vd.Key)
		var err error
		m["device_address"], err = computeDevAddr(vd, ctlr.(types.BaseVirtualController))
		if err != nil {
			return fmt.Errorf("error computing device address: %s", err)
		}
		
		
		m["keep_on_remove"] = true
		r := NewDiskSubresource(c, d, m, nil, len(newSet))
		if err := r.Read(l); err != nil {
			return fmt.Errorf("%s: %s", r.Addr(), err)
		}
		
		r.Set("label", fmt.Sprintf("%s%d", diskOrphanedPrefix, i))
		newSet = append(newSet, r.Data())
	}

	log.Printf("[DEBUG] DiskRefreshOperation: Resource set to write after adding orphaned devices: %s", subresourceListString(newSet))
	
	
	sort.Sort(virtualDiskSubresourceSorter(newSet))
	log.Printf("[DEBUG] DiskRefreshOperation: Final (sorted) resource set to write: %s", subresourceListString(newSet))
	log.Printf("[DEBUG] DiskRefreshOperation: Refresh operation complete, sending new resource set")
	return d.Set(subresourceTypeDisk, newSet)
}
func DiskRefreshOperation ( d * schema . ResourceData , c * govmomi . Client , l object . VirtualDeviceList ) error { log . Printf ( " " ) devices := SelectDisks ( l , d . Get ( " " ) . ( int ) ) log . Printf ( " " , DeviceListString ( devices ) ) curSet := d . Get ( subresourceTypeDisk ) . ( [ ] interface { } ) log . Printf ( " " , subresourceListString ( curSet ) ) var newSet [ ] interface { } // First check for negative keys. These are freshly added devices that are // usually coming into read post-create. // // If we find what we are looking for, we remove the device from the working // set so that we don't try and process it in the next few passes. log . Printf ( " " ) for i , item := range curSet { m := item . ( map [ string ] interface { } ) if m [ " " ] . ( int ) < 1 { r := NewDiskSubresource ( c , d , m , nil , i ) if err := r . Read ( l ) ; err != nil { return fmt . Errorf ( " " , r . Addr ( ) , err ) } if r . Get ( " " ) . ( int ) < 1 { // This should not have happened - if it did, our device // creation/update logic failed somehow that we were not able to track. return fmt . Errorf ( " " , r . Get ( " " ) . ( int ) , r . Get ( " " ) . ( string ) ) } newSet = append ( newSet , r . Data ( ) ) for i := 0 ; i < len ( devices ) ; i ++ { device := devices [ i ] if device . GetVirtualDevice ( ) . Key == int32 ( r . Get ( " " ) . ( int ) ) { devices = append ( devices [ : i ] , devices [ i + 1 : ] ... ) i -- } } } } log . Printf ( " " , DeviceListString ( devices ) ) log . Printf ( " " , subresourceListString ( newSet ) ) // Go over the remaining devices, refresh via key, and then remove their // entries as well. log . Printf ( " " ) for i := 0 ; i < len ( devices ) ; i ++ { device := devices [ i ] for n , item := range curSet { m := item . ( map [ string ] interface { } ) if m [ " " ] . ( int ) < 1 { // Skip any of these keys as we won't be matching any of those anyway here continue } if ! diskUUIDMatch ( device , m [ " " ] . ( string ) ) { // Skip any device that doesn't match UUID continue } // We should have our device -> resource match, so read now. r := NewDiskSubresource ( c , d , m , nil , n ) if err := r . Read ( l ) ; err != nil { return fmt . Errorf ( " " , r . Addr ( ) , err ) } // Done reading, push this onto our new set and remove the device from // the list newSet = append ( newSet , r . Data ( ) ) devices = append ( devices [ : i ] , devices [ i + 1 : ] ... ) i -- } } log . Printf ( " " , subresourceListString ( newSet ) ) log . Printf ( " " , DeviceListString ( devices ) ) // Finally, any device that is still here is orphaned. They should be added // as new devices. log . Printf ( " " ) for i , device := range devices { m := make ( map [ string ] interface { } ) vd := device . GetVirtualDevice ( ) ctlr := l . FindByKey ( vd . ControllerKey ) if ctlr == nil { return fmt . Errorf ( " " , vd . Key ) } m [ " " ] = int ( vd . Key ) var err error m [ " " ] , err = computeDevAddr ( vd , ctlr . ( types . BaseVirtualController ) ) if err != nil { return fmt . Errorf ( " " , err ) } // We want to set keep_on_remove for these disks as well so that they are // not destroyed when we remove them in the next TF run. m [ " " ] = true r := NewDiskSubresource ( c , d , m , nil , len ( newSet ) ) if err := r . Read ( l ) ; err != nil { return fmt . Errorf ( " " , r . Addr ( ) , err ) } // Add a generic label indicating that this disk is orphaned. r . Set ( " " , fmt . Sprintf ( " " , diskOrphanedPrefix , i ) ) newSet = append ( newSet , r . Data ( ) ) } log . Printf ( " " , subresourceListString ( newSet ) ) // Sort the device list by unit number. This provides some semblance of order // in the state as devices are added and removed. sort . Sort ( virtualDiskSubresourceSorter ( newSet ) ) log . Printf ( " " , subresourceListString ( newSet ) ) log . Printf ( " " ) return d . Set ( subresourceTypeDisk , newSet ) }
// DiskRefreshOperation processes a refresh operation for all of the disks in
// the resource.
//
// This functions similar to DiskApplyOperation, but nothing to change is
// returned, all necessary values are just set and committed to state.
DiskRefreshOperation processes a refresh operation for all of the disks in the resource . This functions similar to DiskApplyOperation but nothing to change is returned all necessary values are just set and committed to state .