github.com/vmware/govmomi@v0.37.2/govc/ls/command.go (about)

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