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