github.com/vmware/govmomi@v0.37.2/govc/datacenter/info.go (about)

     1  /*
     2  Copyright (c) 2016-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 datacenter
    18  
    19  import (
    20  	"context"
    21  	"flag"
    22  	"fmt"
    23  	"io"
    24  	"text/tabwriter"
    25  
    26  	"github.com/vmware/govmomi/find"
    27  	"github.com/vmware/govmomi/govc/cli"
    28  	"github.com/vmware/govmomi/govc/flags"
    29  	"github.com/vmware/govmomi/object"
    30  	"github.com/vmware/govmomi/property"
    31  	"github.com/vmware/govmomi/view"
    32  	"github.com/vmware/govmomi/vim25"
    33  	"github.com/vmware/govmomi/vim25/mo"
    34  	"github.com/vmware/govmomi/vim25/types"
    35  )
    36  
    37  type info struct {
    38  	*flags.ClientFlag
    39  	*flags.OutputFlag
    40  	*flags.DatacenterFlag
    41  }
    42  
    43  func init() {
    44  	cli.Register("datacenter.info", &info{})
    45  }
    46  
    47  func (cmd *info) Register(ctx context.Context, f *flag.FlagSet) {
    48  	cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
    49  	cmd.ClientFlag.Register(ctx, f)
    50  
    51  	cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
    52  	cmd.OutputFlag.Register(ctx, f)
    53  
    54  	cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx)
    55  	cmd.DatacenterFlag.Register(ctx, f)
    56  }
    57  
    58  func (cmd *info) Process(ctx context.Context) error {
    59  	if err := cmd.ClientFlag.Process(ctx); err != nil {
    60  		return err
    61  	}
    62  	if err := cmd.OutputFlag.Process(ctx); err != nil {
    63  		return err
    64  	}
    65  	if err := cmd.DatacenterFlag.Process(ctx); err != nil {
    66  		return err
    67  	}
    68  	return nil
    69  }
    70  
    71  func (cmd *info) Usage() string {
    72  	return "[PATH]..."
    73  }
    74  
    75  func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error {
    76  	c, err := cmd.Client()
    77  	if err != nil {
    78  		return err
    79  	}
    80  
    81  	finder, err := cmd.Finder()
    82  	if err != nil {
    83  		return err
    84  	}
    85  
    86  	args := f.Args()
    87  	if len(args) == 0 {
    88  		args = []string{"*"}
    89  	}
    90  
    91  	var props []string
    92  	res := infoResult{
    93  		finder: finder,
    94  		ctx:    ctx,
    95  		client: c,
    96  	}
    97  
    98  	if !cmd.OutputFlag.All() {
    99  		props = []string{
   100  			"name",
   101  			"vmFolder",
   102  			"hostFolder",
   103  			"datastoreFolder",
   104  			"networkFolder",
   105  			"datastore",
   106  			"network",
   107  		}
   108  	}
   109  
   110  	for _, arg := range args {
   111  		objects, err := finder.DatacenterList(ctx, arg)
   112  		if err != nil {
   113  			return err
   114  		}
   115  		res.objects = append(res.objects, objects...)
   116  	}
   117  
   118  	if len(res.objects) != 0 {
   119  		refs := make([]types.ManagedObjectReference, 0, len(res.objects))
   120  		for _, o := range res.objects {
   121  			refs = append(refs, o.Reference())
   122  		}
   123  
   124  		pc := property.DefaultCollector(c)
   125  		err = pc.Retrieve(ctx, refs, props, &res.Datacenters)
   126  		if err != nil {
   127  			return err
   128  		}
   129  	}
   130  
   131  	return cmd.WriteResult(&res)
   132  }
   133  
   134  type infoResult struct {
   135  	Datacenters []mo.Datacenter `json:"datacenters"`
   136  	objects     []*object.Datacenter
   137  	finder      *find.Finder
   138  	ctx         context.Context
   139  	client      *vim25.Client
   140  }
   141  
   142  func (r *infoResult) Write(w io.Writer) error {
   143  	// Maintain order via r.objects as Property collector does not always return results in order.
   144  	objects := make(map[types.ManagedObjectReference]mo.Datacenter, len(r.Datacenters))
   145  	for _, o := range r.Datacenters {
   146  		objects[o.Reference()] = o
   147  	}
   148  
   149  	tw := tabwriter.NewWriter(w, 2, 0, 2, ' ', 0)
   150  
   151  	for _, o := range r.objects {
   152  		dc := objects[o.Reference()]
   153  		fmt.Fprintf(tw, "Name:\t%s\n", dc.Name)
   154  		fmt.Fprintf(tw, "  Path:\t%s\n", o.InventoryPath)
   155  
   156  		r.finder.SetDatacenter(o)
   157  
   158  		hosts, _ := r.finder.HostSystemList(r.ctx, "*")
   159  		fmt.Fprintf(tw, "  Hosts:\t%d\n", len(hosts))
   160  
   161  		clusters, _ := r.finder.ClusterComputeResourceList(r.ctx, "*")
   162  		fmt.Fprintf(tw, "  Clusters:\t%d\n", len(clusters))
   163  
   164  		manager := view.NewManager(r.client)
   165  
   166  		v, err := manager.CreateContainerView(r.ctx, o.Reference(), []string{"VirtualMachine"}, true)
   167  		if err != nil {
   168  			return err
   169  		}
   170  
   171  		var vms []mo.VirtualMachine
   172  		err = v.Retrieve(r.ctx, []string{"VirtualMachine"}, []string{"summary.config.template"}, &vms)
   173  		if err != nil {
   174  			return err
   175  		}
   176  
   177  		defer func() {
   178  			_ = v.Destroy(r.ctx)
   179  		}()
   180  
   181  		totalVms := 0
   182  		for _, vm := range vms {
   183  			if vm.Summary.Config.Template {
   184  				continue
   185  			}
   186  			totalVms++
   187  		}
   188  
   189  		fmt.Fprintf(tw, "  Virtual Machines:\t%d\n", totalVms)
   190  
   191  		fmt.Fprintf(tw, "  Networks:\t%d\n", len(dc.Network))
   192  		fmt.Fprintf(tw, "  Datastores:\t%d\n", len(dc.Datastore))
   193  	}
   194  
   195  	return tw.Flush()
   196  }