github.com/vmware/govmomi@v0.51.0/cli/host/esxcli/model.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 esxcli 6 7 import ( 8 "context" 9 "encoding/json" 10 "flag" 11 "fmt" 12 "io" 13 "strings" 14 "text/tabwriter" 15 16 "github.com/vmware/govmomi/cli" 17 "github.com/vmware/govmomi/cli/esx" 18 "github.com/vmware/govmomi/cli/flags" 19 "github.com/vmware/govmomi/internal" 20 ) 21 22 type model struct { 23 *flags.HostSystemFlag 24 25 types bool 26 commands bool 27 instances bool 28 } 29 30 func init() { 31 cli.Register("host.esxcli.model", &model{}, true) 32 } 33 34 func (cmd *model) Usage() string { 35 return "[NAMESPACE]..." 36 } 37 38 func (cmd *model) Description() string { 39 return `Print esxcli model for HOST. 40 41 Examples: 42 govc host.esxcli.model # prints type model supported by vcsim 43 govc host.esxcli.model network.vm network.ip.connection # specific namespaces 44 govc host.esxcli.model -dump # generate simulator/esx/type_info.go 45 govc host.esxcli.model -c # prints commands supported by vcsim 46 govc host.esxcli.model -c network.vm` 47 } 48 49 func (cmd *model) Register(ctx context.Context, f *flag.FlagSet) { 50 cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx) 51 cmd.HostSystemFlag.Register(ctx, f) 52 53 f.BoolVar(&cmd.types, "t", true, "Print type info") 54 f.BoolVar(&cmd.commands, "c", false, "Print command info") 55 f.BoolVar(&cmd.instances, "i", false, "Print instances") 56 } 57 58 var namespaces = []string{ 59 "hardware.clock", 60 "hardware.platform", 61 "iscsi.software", 62 "network.firewall", 63 "network.ip.connection", 64 "network.nic.ring.current", 65 "network.nic.ring.preset", 66 "network.vm", 67 "software.vib", 68 "system.hostname", 69 "system.settings.advanced", 70 "system.stats.uptime", 71 "vm.process", 72 } 73 74 type modelInfo struct { 75 CommandInfo []esx.CommandInfo 76 TypeInfo internal.DynamicTypeMgrAllTypeInfo 77 Instances []internal.DynamicTypeMgrMoInstance 78 } 79 80 func (r modelInfo) Dump() any { 81 if len(r.CommandInfo) != 0 { 82 return r.CommandInfo 83 } 84 if len(r.Instances) != 0 { 85 return r.Instances 86 } 87 return r.TypeInfo 88 } 89 90 func (r modelInfo) MarshalJSON() ([]byte, error) { 91 return json.Marshal(r.Dump()) 92 } 93 94 func (r modelInfo) Write(w io.Writer) error { 95 for _, item := range r.CommandInfo { 96 ns := strings.ReplaceAll(item.Name, ".", " ") 97 98 for _, m := range item.Method { 99 tw := tabwriter.NewWriter(w, 2, 0, 2, ' ', 0) 100 fmt.Fprintf(tw, "%s %s\n", ns, m.Name) 101 102 for _, p := range m.Param { 103 fmt.Fprintf(tw, " %s\t%s\n", p.Name, p.Aliases) 104 } 105 106 _ = tw.Flush() 107 } 108 } 109 110 for _, obj := range r.TypeInfo.ManagedTypeInfo { 111 for _, m := range obj.Method { 112 if m.ReturnTypeInfo == nil { 113 continue 114 } 115 116 var param []string 117 for _, p := range m.ParamTypeInfo { 118 param = append(param, p.Name+" "+p.Type) 119 } 120 121 fmt.Fprintf(w, "func %s.%s(%s) %s\n", 122 obj.Name, m.Name, 123 strings.Join(param, ", "), 124 m.ReturnTypeInfo.Type) 125 } 126 } 127 128 tw := tabwriter.NewWriter(w, 2, 0, 2, ' ', 0) 129 for _, obj := range r.TypeInfo.DataTypeInfo { 130 fmt.Fprintf(tw, "type %s struct = {\n", obj.Name) 131 for _, p := range obj.Property { 132 fmt.Fprintf(tw, " %s\t%s\n", p.Name, p.Type) 133 } 134 fmt.Fprintln(tw, "}") 135 } 136 _ = tw.Flush() 137 138 return nil 139 } 140 141 func (cmd *model) typeInfo(ctx context.Context, e *esx.Executor, args []string) (internal.DynamicTypeMgrAllTypeInfo, error) { 142 var info internal.DynamicTypeMgrAllTypeInfo 143 144 for _, ns := range args { 145 req := internal.DynamicTypeMgrQueryTypeInfoRequest{ 146 This: e.DynamicTypeManager(), 147 FilterSpec: &internal.DynamicTypeMgrTypeFilterSpec{ 148 TypeSubstr: ns, 149 }, 150 } 151 152 res, err := internal.DynamicTypeMgrQueryTypeInfo(ctx, e.Client(), &req) 153 if err != nil { 154 return info, err 155 } 156 157 info.DataTypeInfo = append(info.DataTypeInfo, res.Returnval.DataTypeInfo...) 158 info.EnumTypeInfo = append(info.EnumTypeInfo, res.Returnval.EnumTypeInfo...) 159 info.ManagedTypeInfo = append(info.ManagedTypeInfo, res.Returnval.ManagedTypeInfo...) 160 } 161 162 return info, nil 163 } 164 165 func (cmd *model) commandInfo(ctx context.Context, e *esx.Executor, args []string) ([]esx.CommandInfo, error) { 166 var info []esx.CommandInfo 167 168 for _, ns := range args { 169 c, err := e.CommandInfo(ctx, ns) 170 if err != nil { 171 return nil, err 172 } 173 174 info = append(info, *c) 175 } 176 177 return info, nil 178 } 179 180 func (cmd *model) instanceInfo(ctx context.Context, e *esx.Executor, args []string) ([]internal.DynamicTypeMgrMoInstance, error) { 181 var info []internal.DynamicTypeMgrMoInstance 182 183 req := internal.DynamicTypeMgrQueryMoInstancesRequest{ 184 This: e.DynamicTypeManager(), 185 } 186 187 res, err := internal.DynamicTypeMgrQueryMoInstances(ctx, e.Client(), &req) 188 if err != nil { 189 return nil, err 190 } 191 192 for _, i := range res.Returnval { 193 for _, ns := range args { 194 if !strings.HasPrefix(ns, "vim.") { 195 ns = "vim.EsxCLI." + ns 196 } 197 198 if ns == i.MoType { 199 info = append(info, i) 200 break 201 } 202 } 203 } 204 205 return info, nil 206 } 207 208 func (cmd *model) Run(ctx context.Context, f *flag.FlagSet) error { 209 args := f.Args() 210 if len(args) == 0 { 211 args = namespaces 212 } 213 214 c, err := cmd.Client() 215 if err != nil { 216 return err 217 } 218 219 host, err := cmd.HostSystem() 220 if err != nil { 221 return err 222 } 223 224 e, err := esx.NewExecutor(ctx, c, host) 225 if err != nil { 226 return err 227 } 228 229 if cmd.commands || cmd.instances { 230 cmd.types = false 231 } 232 233 var res modelInfo 234 235 if cmd.commands { 236 res.CommandInfo, err = cmd.commandInfo(ctx, e, args) 237 if err != nil { 238 return err 239 } 240 } 241 242 if cmd.types { 243 res.TypeInfo, err = cmd.typeInfo(ctx, e, args) 244 if err != nil { 245 return err 246 } 247 } 248 249 if cmd.instances { 250 res.Instances, err = cmd.instanceInfo(ctx, e, args) 251 if err != nil { 252 return err 253 } 254 if !cmd.All() { 255 cmd.JSON = true 256 } 257 } 258 259 return cmd.WriteResult(&res) 260 }