github.com/vmware/govmomi@v0.51.0/cli/host/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 host
     6  
     7  import (
     8  	"context"
     9  	"flag"
    10  	"fmt"
    11  	"io"
    12  	"text/tabwriter"
    13  
    14  	"github.com/vmware/govmomi/cli"
    15  	"github.com/vmware/govmomi/cli/flags"
    16  	"github.com/vmware/govmomi/object"
    17  	"github.com/vmware/govmomi/property"
    18  	"github.com/vmware/govmomi/vim25/mo"
    19  	"github.com/vmware/govmomi/vim25/types"
    20  )
    21  
    22  type info struct {
    23  	*flags.ClientFlag
    24  	*flags.OutputFlag
    25  	*flags.HostSystemFlag
    26  }
    27  
    28  func init() {
    29  	cli.Register("host.info", &info{})
    30  }
    31  
    32  func (cmd *info) Register(ctx context.Context, f *flag.FlagSet) {
    33  	cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
    34  	cmd.ClientFlag.Register(ctx, f)
    35  
    36  	cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
    37  	cmd.OutputFlag.Register(ctx, f)
    38  
    39  	cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
    40  	cmd.HostSystemFlag.Register(ctx, f)
    41  }
    42  
    43  func (cmd *info) Process(ctx context.Context) error {
    44  	if err := cmd.ClientFlag.Process(ctx); err != nil {
    45  		return err
    46  	}
    47  	if err := cmd.OutputFlag.Process(ctx); err != nil {
    48  		return err
    49  	}
    50  	if err := cmd.HostSystemFlag.Process(ctx); err != nil {
    51  		return err
    52  	}
    53  	return nil
    54  }
    55  
    56  func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error {
    57  	c, err := cmd.Client()
    58  	if err != nil {
    59  		return err
    60  	}
    61  
    62  	var res infoResult
    63  	var props []string
    64  
    65  	if cmd.OutputFlag.All() {
    66  		props = nil // Load everything
    67  	} else {
    68  		props = []string{"summary"} // Load summary
    69  	}
    70  
    71  	// We could do without the -host flag, leaving it for compat
    72  	host, err := cmd.HostSystemIfSpecified()
    73  	if err != nil {
    74  		return err
    75  	}
    76  
    77  	// Default only if there is a single host
    78  	if host == nil && f.NArg() == 0 {
    79  		host, err = cmd.HostSystem()
    80  		if err != nil {
    81  			return err
    82  		}
    83  	}
    84  
    85  	if host != nil {
    86  		res.objects = append(res.objects, host)
    87  	} else {
    88  		res.objects, err = cmd.HostSystems(f.Args())
    89  		if err != nil {
    90  			return err
    91  		}
    92  	}
    93  
    94  	if len(res.objects) != 0 {
    95  		refs := make([]types.ManagedObjectReference, 0, len(res.objects))
    96  		for _, o := range res.objects {
    97  			refs = append(refs, o.Reference())
    98  		}
    99  
   100  		pc := property.DefaultCollector(c)
   101  		err = pc.Retrieve(ctx, refs, props, &res.HostSystems)
   102  		if err != nil {
   103  			return err
   104  		}
   105  	}
   106  
   107  	return cmd.WriteResult(&res)
   108  }
   109  
   110  type infoResult struct {
   111  	HostSystems []mo.HostSystem `json:"hostSystems"`
   112  	objects     []*object.HostSystem
   113  }
   114  
   115  func (r *infoResult) Write(w io.Writer) error {
   116  	// Maintain order via r.objects as Property collector does not always return results in order.
   117  	objects := make(map[types.ManagedObjectReference]mo.HostSystem, len(r.HostSystems))
   118  	for _, o := range r.HostSystems {
   119  		objects[o.Reference()] = o
   120  	}
   121  
   122  	tw := tabwriter.NewWriter(w, 2, 0, 2, ' ', 0)
   123  
   124  	for _, o := range r.objects {
   125  		host := objects[o.Reference()]
   126  		s := host.Summary
   127  		h := s.Hardware
   128  		z := s.QuickStats
   129  		ncpu := int32(h.NumCpuCores)
   130  		cpuUsage := 100 * float64(z.OverallCpuUsage) / float64(ncpu*h.CpuMhz)
   131  		memUsage := 100 * float64(z.OverallMemoryUsage) / float64(h.MemorySize>>20)
   132  
   133  		fmt.Fprintf(tw, "Name:\t%s\n", s.Config.Name)
   134  		fmt.Fprintf(tw, "  Path:\t%s\n", o.InventoryPath)
   135  		fmt.Fprintf(tw, "  Manufacturer:\t%s\n", h.Vendor)
   136  		fmt.Fprintf(tw, "  Logical CPUs:\t%d CPUs @ %dMHz\n", ncpu, h.CpuMhz)
   137  		fmt.Fprintf(tw, "  Processor type:\t%s\n", h.CpuModel)
   138  		fmt.Fprintf(tw, "  CPU usage:\t%d MHz (%.1f%%)\n", z.OverallCpuUsage, cpuUsage)
   139  		fmt.Fprintf(tw, "  Memory:\t%dMB\n", h.MemorySize/(1024*1024))
   140  		fmt.Fprintf(tw, "  Memory usage:\t%d MB (%.1f%%)\n", z.OverallMemoryUsage, memUsage)
   141  		fmt.Fprintf(tw, "  Boot time:\t%s\n", s.Runtime.BootTime)
   142  		if s.Runtime.InMaintenanceMode {
   143  			fmt.Fprint(tw, "  State:\tMaintenance Mode\n")
   144  		} else {
   145  			fmt.Fprintf(tw, "  State:\t%s\n", s.Runtime.ConnectionState)
   146  		}
   147  	}
   148  
   149  	return tw.Flush()
   150  }