vsphere/internal/helper/virtualmachine/virtual_machine_helper.go
func WaitForGuestIP(client *govmomi.Client, vm *object.VirtualMachine, timeout int, ignoredGuestIPs []interface{}) error {
	if timeout < 1 {
		log.Printf("[DEBUG] Skipping IP waiter for VM %q", vm.InventoryPath)
		return nil
	}
	log.Printf(
		"[DEBUG] Waiting for an available IP address on VM %q (timeout = %dm)",
		vm.InventoryPath,
		timeout,
	)

	p := client.PropertyCollector()
	ctx, cancel := context.WithTimeout(context.Background(), time.Minute*time.Duration(timeout))
	defer cancel()

	err := property.Wait(ctx, p, vm.Reference(), []string{"guest.ipAddress"}, func(pc []types.PropertyChange) bool {
		for _, c := range pc {
			if c.Op != types.PropertyChangeOpAssign {
				continue
			}

			if c.Val == nil {
				continue
			}

			ip := net.ParseIP(c.Val.(string))
			if skipIPAddrForWaiter(ip, ignoredGuestIPs) {
				continue
			}

			return true
		}

		return false
	})

	if err != nil {
		// Provide a friendly error message if we timed out waiting for a routable IP.
		if ctx.Err() == context.DeadlineExceeded {
			return errors.New("timeout waiting for an available IP address")
		}
		return err
	}

	log.Printf("[DEBUG] IP address is now available for VM %q", vm.InventoryPath)
	return nil
}
func WaitForGuestIP(client *govmomi.Client, vm *object.VirtualMachine, timeout int, ignoredGuestIPs []interface{}) error {
	if timeout < 1 {
		log.Printf("[DEBUG] Skipping IP waiter for VM %q", vm.InventoryPath)
		return nil
	}
	log.Printf(
		"[DEBUG] Waiting for an available IP address on VM %q (timeout = %dm)",
		vm.InventoryPath,
		timeout,
	)

	p := client.PropertyCollector()
	ctx, cancel := context.WithTimeout(context.Background(), time.Minute*time.Duration(timeout))
	defer cancel()

	err := property.Wait(ctx, p, vm.Reference(), []string{"guest.ipAddress"}, func(pc []types.PropertyChange) bool {
		for _, c := range pc {
			if c.Op != types.PropertyChangeOpAssign {
				continue
			}

			if c.Val == nil {
				continue
			}

			ip := net.ParseIP(c.Val.(string))
			if skipIPAddrForWaiter(ip, ignoredGuestIPs) {
				continue
			}

			return true
		}

		return false
	})

	if err != nil {
		// Provide a friendly error message if we timed out waiting for a routable IP.
		if ctx.Err() == context.DeadlineExceeded {
			return errors.New("timeout waiting for an available IP address")
		}
		return err
	}

	log.Printf("[DEBUG] IP address is now available for VM %q", vm.InventoryPath)
	return nil
}
// WaitForGuestIP waits for a virtual machine to have an IP address.
//
// The timeout is specified in minutes. If zero or a negative value is passed,
// the waiter returns without error immediately.