func CdromRefreshOperation(d *schema.ResourceData, c *govmomi.Client, l object.VirtualDeviceList) error {
	log.Printf("[DEBUG] CdromRefreshOperation: Beginning refresh")
	// While we are currently only restricting CD devices to one device, we have
	// to actually account for the fact that someone could add multiple CD drives
	// out of band. So this workflow is similar to the multi-device workflow that
	// exists for network devices.
	devices := l.Select(func(device types.BaseVirtualDevice) bool {
		if _, ok := device.(*types.VirtualCdrom); ok {
			return true
		}
		return false
	})
	log.Printf("[DEBUG] CdromRefreshOperation: CDROM devices located: %s", DeviceListString(devices))
	curSet := d.Get(subresourceTypeCdrom).([]interface{})
	log.Printf("[DEBUG] CdromRefreshOperation: 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] CdromRefreshOperation: Looking for freshly-created resources to read in")
	for n, item := range curSet {
		m := item.(map[string]interface{})
		if m["key"].(int) < 1 {
			r := NewCdromSubresource(c, d, m, nil, n)
			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] CdromRefreshOperation: CDROM devices after freshly-created device search: %s", DeviceListString(devices))
	log.Printf("[DEBUG] CdromRefreshOperation: Resource set to write after freshly-created device search: %s", subresourceListString(newSet))

	// Go over the remaining devices, refresh via key, and then remove their
	// entries as well.
	log.Printf("[DEBUG] CdromRefreshOperation: 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) < 0 {
				// Skip any of these keys as we won't be matching any of those anyway here
				continue
			}
			if device.GetVirtualDevice().Key != int32(m["key"].(int)) {
				// Skip any device that doesn't match key as well
				continue
			}
			// We should have our device -> resource match, so read now.
			r := NewCdromSubresource(c, d, m, nil, n)
			vApp, err := verifyVAppCdromIso(d, device.(*types.VirtualCdrom), l, c)
			if err != nil {
				return err
			}
			if vApp == true && r.Get("client_device") == true {
				log.Printf("[DEBUG] CdromRefreshOperation: %s: Skipping read since CDROM is in use for vApp ISO transport", r)
				// Set the CDROM properties to match a client device so there won't be a diff.
				r.Set("client_device", true)
				r.Set("datastore_id", "")
				r.Set("path", "")
			} else {
				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] CdromRefreshOperation: Resource set to write after known device search: %s", subresourceListString(newSet))
	log.Printf("[DEBUG] CdromRefreshOperation: Probable orphaned CDROM devices: %s", DeviceListString(devices))

	// Finally, any device that is still here is orphaned. They should be added
	// as new devices.
	for n, 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)
		}
		r := NewCdromSubresource(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())
	}

	log.Printf("[DEBUG] CdromRefreshOperation: Resource set to write after adding orphaned devices: %s", subresourceListString(newSet))
	log.Printf("[DEBUG] CdromRefreshOperation: Refresh operation complete, sending new resource set")
	return d.Set(subresourceTypeCdrom, newSet)
}
func CdromRefreshOperation(d *schema.ResourceData, c *govmomi.Client, l object.VirtualDeviceList) error {
	log.Printf("[DEBUG] CdromRefreshOperation: Beginning refresh")
	
	
	
	
	devices := l.Select(func(device types.BaseVirtualDevice) bool {
		if _, ok := device.(*types.VirtualCdrom); ok {
			return true
		}
		return false
	})
	log.Printf("[DEBUG] CdromRefreshOperation: CDROM devices located: %s", DeviceListString(devices))
	curSet := d.Get(subresourceTypeCdrom).([]interface{})
	log.Printf("[DEBUG] CdromRefreshOperation: Current resource set from state: %s", subresourceListString(curSet))
	var newSet []interface{}
	
	
	
	
	
	log.Printf("[DEBUG] CdromRefreshOperation: Looking for freshly-created resources to read in")
	for n, item := range curSet {
		m := item.(map[string]interface{})
		if m["key"].(int) < 1 {
			r := NewCdromSubresource(c, d, m, nil, n)
			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] CdromRefreshOperation: CDROM devices after freshly-created device search: %s", DeviceListString(devices))
	log.Printf("[DEBUG] CdromRefreshOperation: Resource set to write after freshly-created device search: %s", subresourceListString(newSet))

	
	
	log.Printf("[DEBUG] CdromRefreshOperation: 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) < 0 {
				
				continue
			}
			if device.GetVirtualDevice().Key != int32(m["key"].(int)) {
				
				continue
			}
			
			r := NewCdromSubresource(c, d, m, nil, n)
			vApp, err := verifyVAppCdromIso(d, device.(*types.VirtualCdrom), l, c)
			if err != nil {
				return err
			}
			if vApp == true && r.Get("client_device") == true {
				log.Printf("[DEBUG] CdromRefreshOperation: %s: Skipping read since CDROM is in use for vApp ISO transport", r)
				
				r.Set("client_device", true)
				r.Set("datastore_id", "")
				r.Set("path", "")
			} else {
				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] CdromRefreshOperation: Resource set to write after known device search: %s", subresourceListString(newSet))
	log.Printf("[DEBUG] CdromRefreshOperation: Probable orphaned CDROM devices: %s", DeviceListString(devices))

	
	
	for n, 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)
		}
		r := NewCdromSubresource(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())
	}

	log.Printf("[DEBUG] CdromRefreshOperation: Resource set to write after adding orphaned devices: %s", subresourceListString(newSet))
	log.Printf("[DEBUG] CdromRefreshOperation: Refresh operation complete, sending new resource set")
	return d.Set(subresourceTypeCdrom, newSet)
}
func CdromRefreshOperation ( d * schema . ResourceData , c * govmomi . Client , l object . VirtualDeviceList ) error { log . Printf ( " " ) // While we are currently only restricting CD devices to one device, we have // to actually account for the fact that someone could add multiple CD drives // out of band. So this workflow is similar to the multi-device workflow that // exists for network devices. devices := l . Select ( func ( device types . BaseVirtualDevice ) bool { if _ , ok := device . ( * types . VirtualCdrom ) ; ok { return true } return false } ) log . Printf ( " " , DeviceListString ( devices ) ) curSet := d . Get ( subresourceTypeCdrom ) . ( [ ] 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 n , item := range curSet { m := item . ( map [ string ] interface { } ) if m [ " " ] . ( int ) < 1 { r := NewCdromSubresource ( c , d , m , nil , n ) 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 ) < 0 { // Skip any of these keys as we won't be matching any of those anyway here continue } if device . GetVirtualDevice ( ) . Key != int32 ( m [ " " ] . ( int ) ) { // Skip any device that doesn't match key as well continue } // We should have our device -> resource match, so read now. r := NewCdromSubresource ( c , d , m , nil , n ) vApp , err := verifyVAppCdromIso ( d , device . ( * types . VirtualCdrom ) , l , c ) if err != nil { return err } if vApp == true && r . Get ( " " ) == true { log . Printf ( " " , r ) // Set the CDROM properties to match a client device so there won't be a diff. r . Set ( " " , true ) r . Set ( " " , " " ) r . Set ( " " , " " ) } else { 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. for n , 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 ) } r := NewCdromSubresource ( c , d , m , nil , n ) if err := r . Read ( l ) ; err != nil { return fmt . Errorf ( " " , r . Addr ( ) , err ) } newSet = append ( newSet , r . Data ( ) ) } log . Printf ( " " , subresourceListString ( newSet ) ) log . Printf ( " " ) return d . Set ( subresourceTypeCdrom , newSet ) }
// CdromRefreshOperation processes a refresh operation for all of the disks in
// the resource.
//
// This functions similar to CdromApplyOperation, but nothing to change is
// returned, all necessary values are just set and committed to state.
CdromRefreshOperation processes a refresh operation for all of the disks in the resource . This functions similar to CdromApplyOperation but nothing to change is returned all necessary values are just set and committed to state .