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 }