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