github.com/vmware/govmomi@v0.43.0/govc/flags/datacenter.go (about)

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