github.com/vmware/govmomi@v0.51.0/cli/ls/command.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 ls 6 7 import ( 8 "context" 9 "flag" 10 "fmt" 11 "io" 12 "strings" 13 14 "github.com/vmware/govmomi/cli" 15 "github.com/vmware/govmomi/cli/flags" 16 "github.com/vmware/govmomi/list" 17 "github.com/vmware/govmomi/vim25/mo" 18 "github.com/vmware/govmomi/vim25/types" 19 ) 20 21 type ls struct { 22 *flags.DatacenterFlag 23 24 Long bool 25 Type string 26 ToRef bool 27 ToID bool 28 DeRef bool 29 } 30 31 func init() { 32 cli.Register("ls", &ls{}) 33 } 34 35 func (cmd *ls) Register(ctx context.Context, f *flag.FlagSet) { 36 cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx) 37 cmd.DatacenterFlag.Register(ctx, f) 38 39 f.BoolVar(&cmd.Long, "l", false, "Long listing format") 40 f.BoolVar(&cmd.ToRef, "i", false, "Print the managed object reference") 41 f.BoolVar(&cmd.ToID, "I", false, "Print the managed object ID") 42 f.BoolVar(&cmd.DeRef, "L", false, "Follow managed object references") 43 f.StringVar(&cmd.Type, "t", "", "Object type") 44 } 45 46 func (cmd *ls) Description() string { 47 return `List inventory items. 48 49 Examples: 50 govc ls -l '*' 51 govc ls -t ClusterComputeResource host 52 govc ls -t Datastore host/ClusterA/* | grep -v local | xargs -n1 basename | sort | uniq` 53 } 54 55 func (cmd *ls) Process(ctx context.Context) error { 56 if err := cmd.DatacenterFlag.Process(ctx); err != nil { 57 return err 58 } 59 return nil 60 } 61 62 func (cmd *ls) Usage() string { 63 return "[PATH]..." 64 } 65 66 func (cmd *ls) typeMatch(ref types.ManagedObjectReference) bool { 67 if cmd.Type == "" { 68 return true 69 } 70 71 return strings.EqualFold(cmd.Type, ref.Type) 72 } 73 74 func (cmd *ls) Run(ctx context.Context, f *flag.FlagSet) error { 75 finder, err := cmd.Finder(cmd.All()) 76 if err != nil { 77 return err 78 } 79 80 lr := listResult{ 81 ls: cmd, 82 Elements: nil, 83 } 84 85 args := f.Args() 86 if len(args) == 0 { 87 args = []string{"."} 88 } 89 90 var ref = new(types.ManagedObjectReference) 91 92 var types []string 93 if cmd.Type != "" { 94 // TODO: support multiple -t flags 95 types = []string{cmd.Type} 96 } 97 98 for _, arg := range args { 99 if cmd.DeRef && ref.FromString(arg) { 100 e, err := finder.Element(ctx, *ref) 101 if err == nil { 102 if cmd.typeMatch(*ref) { 103 if e.Path == "/" && ref.Type != "Folder" { 104 // Special case: when given a moref with no ancestors, 105 // just echo the moref. 106 e.Path = ref.String() 107 } 108 lr.Elements = append(lr.Elements, *e) 109 } 110 continue 111 } 112 } 113 114 es, err := finder.ManagedObjectListChildren(ctx, arg, types...) 115 if err != nil { 116 return err 117 } 118 119 for _, e := range es { 120 if cmd.typeMatch(e.Object.Reference()) { 121 lr.Elements = append(lr.Elements, e) 122 } 123 } 124 } 125 126 return cmd.WriteResult(lr) 127 } 128 129 type listResult struct { 130 *ls `json:"-" xml:"-"` 131 Elements []list.Element `json:"elements"` 132 } 133 134 func (l listResult) Write(w io.Writer) error { 135 var err error 136 137 for _, e := range l.Elements { 138 if l.ToRef || l.ToID { 139 ref := e.Object.Reference() 140 id := ref.String() 141 if l.ToID { 142 id = ref.Value 143 } 144 fmt.Fprint(w, id) 145 if l.Long { 146 fmt.Fprintf(w, " %s", e.Path) 147 } 148 fmt.Fprintln(w) 149 continue 150 } 151 152 if !l.Long { 153 fmt.Fprintf(w, "%s\n", e.Path) 154 continue 155 } 156 157 switch e.Object.(type) { 158 case mo.Folder: 159 if _, err = fmt.Fprintf(w, "%s/\n", e.Path); err != nil { 160 return err 161 } 162 default: 163 if _, err = fmt.Fprintf(w, "%s (%s)\n", e.Path, e.Object.Reference().Type); err != nil { 164 return err 165 } 166 } 167 } 168 169 return nil 170 }