github.com/vmware/govmomi@v0.51.0/cli/flags/datacenter.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 flags
     6  
     7  import (
     8  	"context"
     9  	"flag"
    10  	"fmt"
    11  	"os"
    12  	"strings"
    13  
    14  	"github.com/vmware/govmomi/find"
    15  	"github.com/vmware/govmomi/object"
    16  	"github.com/vmware/govmomi/property"
    17  	"github.com/vmware/govmomi/vim25/types"
    18  )
    19  
    20  type DatacenterFlag struct {
    21  	common
    22  
    23  	*ClientFlag
    24  	*OutputFlag
    25  
    26  	Name   string
    27  	dc     *object.Datacenter
    28  	finder *find.Finder
    29  	err    error
    30  }
    31  
    32  var datacenterFlagKey = flagKey("datacenter")
    33  
    34  func NewDatacenterFlag(ctx context.Context) (*DatacenterFlag, context.Context) {
    35  	if v := ctx.Value(datacenterFlagKey); v != nil {
    36  		return v.(*DatacenterFlag), ctx
    37  	}
    38  
    39  	v := &DatacenterFlag{}
    40  	v.ClientFlag, ctx = NewClientFlag(ctx)
    41  	v.OutputFlag, ctx = NewOutputFlag(ctx)
    42  	ctx = context.WithValue(ctx, datacenterFlagKey, v)
    43  	return v, ctx
    44  }
    45  
    46  func (flag *DatacenterFlag) Register(ctx context.Context, f *flag.FlagSet) {
    47  	flag.RegisterOnce(func() {
    48  		flag.ClientFlag.Register(ctx, f)
    49  		flag.OutputFlag.Register(ctx, f)
    50  
    51  		env := "GOVC_DATACENTER"
    52  		value := os.Getenv(env)
    53  		usage := fmt.Sprintf("Datacenter [%s]", env)
    54  		f.StringVar(&flag.Name, "dc", value, usage)
    55  	})
    56  }
    57  
    58  func (flag *DatacenterFlag) Process(ctx context.Context) error {
    59  	return flag.ProcessOnce(func() error {
    60  		if err := flag.ClientFlag.Process(ctx); err != nil {
    61  			return err
    62  		}
    63  		if err := flag.OutputFlag.Process(ctx); err != nil {
    64  			return err
    65  		}
    66  		return nil
    67  	})
    68  }
    69  
    70  func (flag *DatacenterFlag) Finder(all ...bool) (*find.Finder, error) {
    71  	if flag.finder != nil {
    72  		return flag.finder, nil
    73  	}
    74  
    75  	c, err := flag.Client()
    76  	if err != nil {
    77  		return nil, err
    78  	}
    79  
    80  	allFlag := false
    81  	if len(all) == 1 {
    82  		allFlag = all[0]
    83  	}
    84  	finder := find.NewFinder(c, allFlag)
    85  
    86  	// Datacenter is not required (ls command for example).
    87  	// Set for relative func if dc flag is given or
    88  	// if there is a single (default) Datacenter
    89  	ctx := context.TODO()
    90  	if flag.Name == "" {
    91  		flag.dc, flag.err = finder.DefaultDatacenter(ctx)
    92  	} else {
    93  		if flag.dc, err = finder.Datacenter(ctx, flag.Name); err != nil {
    94  			return nil, err
    95  		}
    96  	}
    97  
    98  	finder.SetDatacenter(flag.dc)
    99  
   100  	flag.finder = finder
   101  
   102  	return flag.finder, nil
   103  }
   104  
   105  func (flag *DatacenterFlag) Datacenter() (*object.Datacenter, error) {
   106  	if flag.dc != nil {
   107  		return flag.dc, nil
   108  	}
   109  
   110  	_, err := flag.Finder()
   111  	if err != nil {
   112  		return nil, err
   113  	}
   114  
   115  	if flag.err != nil {
   116  		// Should only happen if no dc is specified and len(dcs) > 1
   117  		return nil, flag.err
   118  	}
   119  
   120  	return flag.dc, err
   121  }
   122  
   123  func (flag *DatacenterFlag) DatacenterIfSpecified() (*object.Datacenter, error) {
   124  	if flag.Name == "" {
   125  		return nil, nil
   126  	}
   127  	return flag.Datacenter()
   128  }
   129  
   130  func (flag *DatacenterFlag) ManagedObject(ctx context.Context, arg string) (types.ManagedObjectReference, error) {
   131  	var ref types.ManagedObjectReference
   132  
   133  	finder, err := flag.Finder()
   134  	if err != nil {
   135  		return ref, err
   136  	}
   137  
   138  	if ref.FromString(arg) {
   139  		if strings.HasPrefix(ref.Type, "com.vmware.content.") {
   140  			return ref, nil // special case for content library
   141  		}
   142  		pc := property.DefaultCollector(flag.client)
   143  		var content []types.ObjectContent
   144  		err = pc.RetrieveOne(ctx, ref, []string{"name"}, &content)
   145  		if err == nil {
   146  			return ref, nil
   147  		}
   148  	}
   149  
   150  	l, err := finder.ManagedObjectList(ctx, arg)
   151  	if err != nil {
   152  		return ref, err
   153  	}
   154  
   155  	switch len(l) {
   156  	case 0:
   157  		return ref, fmt.Errorf("%s not found", arg)
   158  	case 1:
   159  		return l[0].Object.Reference(), nil
   160  	default:
   161  		var objs []types.ManagedObjectReference
   162  		for _, o := range l {
   163  			objs = append(objs, o.Object.Reference())
   164  		}
   165  		return ref, fmt.Errorf("%d objects match %q: %s (unique inventory path required)", len(l), arg, objs)
   166  	}
   167  }
   168  
   169  func (flag *DatacenterFlag) ManagedObjects(ctx context.Context, args []string) ([]types.ManagedObjectReference, error) {
   170  	var refs []types.ManagedObjectReference
   171  
   172  	c, err := flag.Client()
   173  	if err != nil {
   174  		return nil, err
   175  	}
   176  
   177  	if len(args) == 0 {
   178  		refs = append(refs, c.ServiceContent.RootFolder)
   179  		return refs, nil
   180  	}
   181  
   182  	finder, err := flag.Finder()
   183  	if err != nil {
   184  		return nil, err
   185  	}
   186  
   187  	for _, arg := range args {
   188  		elements, err := finder.ManagedObjectList(ctx, arg)
   189  		if err != nil {
   190  			return nil, err
   191  		}
   192  
   193  		if len(elements) == 0 {
   194  			return nil, fmt.Errorf("object '%s' not found", arg)
   195  		}
   196  
   197  		if len(elements) > 1 && !strings.Contains(arg, "/") {
   198  			return nil, fmt.Errorf("%q must be qualified with a path", arg)
   199  		}
   200  
   201  		for _, e := range elements {
   202  			refs = append(refs, e.Object.Reference())
   203  		}
   204  	}
   205  
   206  	return refs, nil
   207  }