github.com/vmware/govmomi@v0.43.0/govc/host/info.go (about)

     1  /*
     2  Copyright (c) 2014-2023 VMware, Inc. All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package host
    18  
    19  import (
    20  	"context"
    21  	"flag"
    22  	"fmt"
    23  	"io"
    24  	"text/tabwriter"
    25  
    26  	"github.com/vmware/govmomi/govc/cli"
    27  	"github.com/vmware/govmomi/govc/flags"
    28  	"github.com/vmware/govmomi/object"
    29  	"github.com/vmware/govmomi/property"
    30  	"github.com/vmware/govmomi/vim25/mo"
    31  	"github.com/vmware/govmomi/vim25/types"
    32  )
    33  
    34  type info struct {
    35  	*flags.ClientFlag
    36  	*flags.OutputFlag
    37  	*flags.HostSystemFlag
    38  }
    39  
    40  func init() {
    41  	cli.Register("host.info", &info{})
    42  }
    43  
    44  func (cmd *info) Register(ctx context.Context, f *flag.FlagSet) {
    45  	cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
    46  	cmd.ClientFlag.Register(ctx, f)
    47  
    48  	cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
    49  	cmd.OutputFlag.Register(ctx, f)
    50  
    51  	cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
    52  	cmd.HostSystemFlag.Register(ctx, f)
    53  }
    54  
    55  func (cmd *info) Process(ctx context.Context) error {
    56  	if err := cmd.ClientFlag.Process(ctx); err != nil {
    57  		return err
    58  	}
    59  	if err := cmd.OutputFlag.Process(ctx); err != nil {
    60  		return err
    61  	}
    62  	if err := cmd.HostSystemFlag.Process(ctx); err != nil {
    63  		return err
    64  	}
    65  	return nil
    66  }
    67  
    68  func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error {
    69  	c, err := cmd.Client()
    70  	if err != nil {
    71  		return err
    72  	}
    73  
    74  	var res infoResult
    75  	var props []string
    76  
    77  	if cmd.OutputFlag.All() {
    78  		props = nil // Load everything
    79  	} else {
    80  		props = []string{"summary"} // Load summary
    81  	}
    82  
    83  	// We could do without the -host flag, leaving it for compat
    84  	host, err := cmd.HostSystemIfSpecified()
    85  	if err != nil {
    86  		return err
    87  	}
    88  
    89  	// Default only if there is a single host
    90  	if host == nil && f.NArg() == 0 {
    91  		host, err = cmd.HostSystem()
    92  		if err != nil {
    93  			return err
    94  		}
    95  	}
    96  
    97  	if host != nil {
    98  		res.objects = append(res.objects, host)
    99  	} else {
   100  		res.objects, err = cmd.HostSystems(f.Args())
   101  		if err != nil {
   102  			return err
   103  		}
   104  	}
   105  
   106  	if len(res.objects) != 0 {
   107  		refs := make([]types.ManagedObjectReference, 0, len(res.objects))
   108  		for _, o := range res.objects {
   109  			refs = append(refs, o.Reference())
   110  		}
   111  
   112  		pc := property.DefaultCollector(c)
   113  		err = pc.Retrieve(ctx, refs, props, &res.HostSystems)
   114  		if err != nil {
   115  			return err
   116  		}
   117  	}
   118  
   119  	return cmd.WriteResult(&res)
   120  }
   121  
   122  type infoResult struct {
   123  	HostSystems []mo.HostSystem `json:"hostSystems"`
   124  	objects     []*object.HostSystem
   125  }
   126  
   127  func (r *infoResult) Write(w io.Writer) error {
   128  	// Maintain order via r.objects as Property collector does not always return results in order.
   129  	objects := make(map[types.ManagedObjectReference]mo.HostSystem, len(r.HostSystems))
   130  	for _, o := range r.HostSystems {
   131  		objects[o.Reference()] = o
   132  	}
   133  
   134  	tw := tabwriter.NewWriter(w, 2, 0, 2, ' ', 0)
   135  
   136  	for _, o := range r.objects {
   137  		host := objects[o.Reference()]
   138  		s := host.Summary
   139  		h := s.Hardware
   140  		z := s.QuickStats
   141  		ncpu := int32(h.NumCpuCores)
   142  		cpuUsage := 100 * float64(z.OverallCpuUsage) / float64(ncpu*h.CpuMhz)
   143  		memUsage := 100 * float64(z.OverallMemoryUsage) / float64(h.MemorySize>>20)
   144  
   145  		fmt.Fprintf(tw, "Name:\t%s\n", s.Config.Name)
   146  		fmt.Fprintf(tw, "  Path:\t%s\n", o.InventoryPath)
   147  		fmt.Fprintf(tw, "  Manufacturer:\t%s\n", h.Vendor)
   148  		fmt.Fprintf(tw, "  Logical CPUs:\t%d CPUs @ %dMHz\n", ncpu, h.CpuMhz)
   149  		fmt.Fprintf(tw, "  Processor type:\t%s\n", h.CpuModel)
   150  		fmt.Fprintf(tw, "  CPU usage:\t%d MHz (%.1f%%)\n", z.OverallCpuUsage, cpuUsage)
   151  		fmt.Fprintf(tw, "  Memory:\t%dMB\n", h.MemorySize/(1024*1024))
   152  		fmt.Fprintf(tw, "  Memory usage:\t%d MB (%.1f%%)\n", z.OverallMemoryUsage, memUsage)
   153  		fmt.Fprintf(tw, "  Boot time:\t%s\n", s.Runtime.BootTime)
   154  		if s.Runtime.InMaintenanceMode {
   155  			fmt.Fprint(tw, "  State:\tMaintenance Mode\n")
   156  		} else {
   157  			fmt.Fprintf(tw, "  State:\t%s\n", s.Runtime.ConnectionState)
   158  		}
   159  	}
   160  
   161  	return tw.Flush()
   162  }