github.com/vmware/govmomi@v0.51.0/cli/esx/guest_info.go (about)

     1  // © Broadcom. All Rights Reserved.
     2  // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
     3  // SPDX-License-Identifier: Apache-2.0
     4  
     5  package esx
     6  
     7  import (
     8  	"context"
     9  	"strings"
    10  
    11  	"github.com/vmware/govmomi/property"
    12  	"github.com/vmware/govmomi/vim25"
    13  	"github.com/vmware/govmomi/vim25/mo"
    14  	"github.com/vmware/govmomi/vim25/types"
    15  )
    16  
    17  type hostInfo struct {
    18  	*Executor
    19  	wids map[string]string
    20  }
    21  
    22  type GuestInfo struct {
    23  	c     *vim25.Client
    24  	hosts map[string]*hostInfo
    25  }
    26  
    27  func NewGuestInfo(c *vim25.Client) *GuestInfo {
    28  	return &GuestInfo{
    29  		c:     c,
    30  		hosts: make(map[string]*hostInfo),
    31  	}
    32  }
    33  
    34  func (g *GuestInfo) hostInfo(ctx context.Context, ref *types.ManagedObjectReference) (*hostInfo, error) {
    35  	// cache exectuor and uuid -> worldid map
    36  	if h, ok := g.hosts[ref.Value]; ok {
    37  		return h, nil
    38  	}
    39  
    40  	e, err := NewExecutor(ctx, g.c, ref)
    41  	if err != nil {
    42  		return nil, err
    43  	}
    44  
    45  	res, err := e.Run(ctx, []string{"vm", "process", "list"})
    46  	if err != nil {
    47  		return nil, err
    48  	}
    49  
    50  	ids := make(map[string]string, len(res.Values))
    51  
    52  	for _, process := range res.Values {
    53  		// Normalize uuid, esxcli and mo.VirtualMachine have different formats
    54  		uuid := strings.Replace(process["UUID"][0], " ", "", -1)
    55  		uuid = strings.Replace(uuid, "-", "", -1)
    56  
    57  		ids[uuid] = process["WorldID"][0]
    58  	}
    59  
    60  	h := &hostInfo{e, ids}
    61  	g.hosts[ref.Value] = h
    62  
    63  	return h, nil
    64  }
    65  
    66  // IpAddress attempts to find the guest IP address using esxcli.
    67  // ESX hosts must be configured with the /Net/GuestIPHack enabled.
    68  // For example:
    69  // $ govc host.esxcli -- system settings advanced set -o /Net/GuestIPHack -i 1
    70  func (g *GuestInfo) IpAddress(ctx context.Context, vm mo.Reference) (string, error) {
    71  	const any = "0.0.0.0"
    72  	var mvm mo.VirtualMachine
    73  
    74  	pc := property.DefaultCollector(g.c)
    75  	err := pc.RetrieveOne(ctx, vm.Reference(), []string{"runtime.host", "config.uuid"}, &mvm)
    76  	if err != nil {
    77  		return "", err
    78  	}
    79  
    80  	h, err := g.hostInfo(ctx, mvm.Runtime.Host)
    81  	if err != nil {
    82  		return "", err
    83  	}
    84  
    85  	// Normalize uuid, esxcli and mo.VirtualMachine have different formats
    86  	uuid := strings.Replace(mvm.Config.Uuid, "-", "", -1)
    87  
    88  	if wid, ok := h.wids[uuid]; ok {
    89  		res, err := h.Run(ctx, []string{"network", "vm", "port", "list", "--world-id", wid})
    90  		if err != nil {
    91  			return "", err
    92  		}
    93  
    94  		for _, val := range res.Values {
    95  			if ip, ok := val["IPAddress"]; ok {
    96  				if ip[0] != any {
    97  					return ip[0], nil
    98  				}
    99  			}
   100  		}
   101  	}
   102  
   103  	return any, nil
   104  }