github.com/vmware/govmomi@v0.37.1/govc/fields/info.go (about) 1 /* 2 Copyright (c) 2018-2023 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 fields 18 19 import ( 20 "context" 21 "flag" 22 "fmt" 23 "io" 24 "os" 25 "text/tabwriter" 26 27 "github.com/vmware/govmomi/govc/cli" 28 "github.com/vmware/govmomi/govc/flags" 29 "github.com/vmware/govmomi/object" 30 "github.com/vmware/govmomi/property" 31 "github.com/vmware/govmomi/vim25/mo" 32 "github.com/vmware/govmomi/vim25/types" 33 ) 34 35 type info struct { 36 *flags.DatacenterFlag 37 38 name string 39 } 40 41 func init() { 42 cli.Register("fields.info", &info{}) 43 } 44 45 func (cmd *info) Register(ctx context.Context, f *flag.FlagSet) { 46 cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx) 47 cmd.DatacenterFlag.Register(ctx, f) 48 49 f.StringVar(&cmd.name, "n", "", "Filter by custom field name") 50 } 51 52 func (cmd *info) Usage() string { 53 return "PATH..." 54 } 55 56 func (cmd *info) Description() string { 57 return `Display custom field values for PATH. 58 59 Also known as "Custom Attributes". 60 61 Examples: 62 govc fields.info vm/* 63 govc fields.info -n my-field-name vm/*` 64 } 65 66 type Info struct { 67 Object types.ManagedObjectReference `json:"object"` 68 Path string `json:"path"` 69 Name string `json:"name"` 70 Key string `json:"key"` 71 Value string `json:"value"` 72 } 73 74 type infoResult struct { 75 Info []Info `json:"info"` 76 } 77 78 func (r *infoResult) Write(w io.Writer) error { 79 tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0) 80 81 for _, info := range r.Info { 82 _, _ = fmt.Fprintf(tw, "%s\t%s\t%s\n", info.Path, info.Key, info.Value) 83 } 84 85 return tw.Flush() 86 } 87 88 func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error { 89 c, err := cmd.Client() 90 if err != nil { 91 return err 92 } 93 94 m, err := object.GetCustomFieldsManager(c) 95 if err != nil { 96 return err 97 } 98 99 paths := make(map[types.ManagedObjectReference]string) 100 var refs []types.ManagedObjectReference 101 102 finder, err := cmd.Finder() 103 if err != nil { 104 return err 105 } 106 107 for _, arg := range f.Args() { 108 elements, ferr := finder.ManagedObjectList(ctx, arg) 109 if ferr != nil { 110 return ferr 111 } 112 113 if len(elements) == 0 { 114 return fmt.Errorf("object '%s' not found", arg) 115 } 116 117 for _, e := range elements { 118 ref := e.Object.Reference() 119 refs = append(refs, ref) 120 paths[ref] = e.Path 121 } 122 } 123 124 var objs []mo.ManagedEntity 125 err = property.DefaultCollector(c).Retrieve(ctx, refs, []string{"name", "customValue"}, &objs) 126 if err != nil { 127 return err 128 } 129 130 matches := func(key int32) bool { 131 return true 132 } 133 134 if cmd.name != "" { 135 fkey, cerr := m.FindKey(ctx, cmd.name) 136 if cerr != nil { 137 return err 138 } 139 matches = func(key int32) bool { 140 return key == fkey 141 } 142 } 143 144 field, err := m.Field(ctx) 145 if err != nil { 146 return err 147 } 148 149 var res infoResult 150 151 for _, obj := range objs { 152 for i := range obj.CustomValue { 153 val := obj.CustomValue[i].(*types.CustomFieldStringValue) 154 155 if !matches(val.Key) { 156 continue 157 } 158 159 res.Info = append(res.Info, Info{ 160 Object: obj.Self, 161 Path: paths[obj.Self], 162 Name: obj.Name, 163 Key: field.ByKey(val.Key).Name, 164 Value: val.Value, 165 }) 166 } 167 } 168 169 return cmd.WriteResult(&res) 170 }