github.com/vmware/govmomi@v0.51.0/cli/vm/check/flag.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 check 6 7 import ( 8 "context" 9 "flag" 10 "fmt" 11 "io" 12 "os" 13 "slices" 14 "strings" 15 "text/tabwriter" 16 17 "github.com/vmware/govmomi/cli/flags" 18 "github.com/vmware/govmomi/find" 19 "github.com/vmware/govmomi/object" 20 "github.com/vmware/govmomi/vim25/types" 21 "github.com/vmware/govmomi/vim25/xml" 22 ) 23 24 var checkTestTypesList = []string{ 25 string(types.CheckTestTypeDatastoreTests), 26 string(types.CheckTestTypeHostTests), 27 string(types.CheckTestTypeNetworkTests), 28 string(types.CheckTestTypeResourcePoolTests), 29 string(types.CheckTestTypeSourceTests), 30 } 31 32 type checkTestTypes []types.CheckTestType 33 34 func (c *checkTestTypes) String() string { 35 return fmt.Sprint(*c) 36 } 37 38 func (c *checkTestTypes) Set(value string) error { 39 if !slices.Contains(checkTestTypesList, value) { 40 return fmt.Errorf("invalid CheckTestType value %q", value) 41 } 42 *c = append(*c, types.CheckTestType(value)) 43 return nil 44 } 45 46 type checkFlag struct { 47 *flags.VirtualMachineFlag 48 *flags.HostSystemFlag 49 *flags.ResourcePoolFlag 50 51 Machine, Host, Pool *types.ManagedObjectReference 52 53 testTypes checkTestTypes 54 } 55 56 func (cmd *checkFlag) Register(ctx context.Context, f *flag.FlagSet) { 57 cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx) 58 cmd.VirtualMachineFlag.Register(ctx, f) 59 cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx) 60 cmd.HostSystemFlag.Register(ctx, f) 61 cmd.ResourcePoolFlag, ctx = flags.NewResourcePoolFlag(ctx) 62 cmd.ResourcePoolFlag.Register(ctx, f) 63 64 f.Var(&cmd.testTypes, "test", fmt.Sprintf("The set of tests to run (%s)", strings.Join(checkTestTypesList, ","))) 65 } 66 67 func (cmd *checkFlag) Process(ctx context.Context) error { 68 if err := cmd.VirtualMachineFlag.Process(ctx); err != nil { 69 return err 70 } 71 if err := cmd.HostSystemFlag.Process(ctx); err != nil { 72 return err 73 } 74 if err := cmd.ResourcePoolFlag.Process(ctx); err != nil { 75 return err 76 } 77 78 vm, err := cmd.VirtualMachine() 79 if err != nil { 80 return err 81 } 82 if vm != nil { 83 cmd.Machine = types.NewReference(vm.Reference()) 84 } 85 86 host, err := cmd.HostSystemIfSpecified() 87 if err != nil { 88 return err 89 } 90 if host != nil { 91 cmd.Host = types.NewReference(host.Reference()) 92 } 93 94 pool, err := cmd.ResourcePoolIfSpecified() 95 if err != nil { 96 return err 97 } 98 if pool != nil { 99 cmd.Pool = types.NewReference(pool.Reference()) 100 } 101 102 return nil 103 } 104 105 func (cmd *checkFlag) provChecker() (*object.VmProvisioningChecker, error) { 106 c, err := cmd.VirtualMachineFlag.Client() 107 if err != nil { 108 return nil, err 109 } 110 111 return object.NewVmProvisioningChecker(c), nil 112 } 113 114 func (cmd *checkFlag) compatChecker() (*object.VmCompatibilityChecker, error) { 115 c, err := cmd.VirtualMachineFlag.Client() 116 if err != nil { 117 return nil, err 118 } 119 120 return object.NewVmCompatibilityChecker(c), nil 121 } 122 123 func (cmd *checkFlag) Spec(spec any) error { 124 dec := xml.NewDecoder(os.Stdin) 125 dec.TypeFunc = types.TypeFunc() 126 return dec.Decode(spec) 127 } 128 129 // return cmd.VirtualMachineFlag.WriteResult(&checkResult{res, ctx, cmd.VirtualMachineFlag}) 130 func (cmd *checkFlag) result(ctx context.Context, res []types.CheckResult) error { 131 return cmd.VirtualMachineFlag.WriteResult(&checkResult{res, ctx, cmd.VirtualMachineFlag}) 132 } 133 134 type checkResult struct { 135 Result []types.CheckResult `json:"result"` 136 ctx context.Context 137 vm *flags.VirtualMachineFlag 138 } 139 140 func (res *checkResult) Write(w io.Writer) error { 141 tw := tabwriter.NewWriter(w, 2, 0, 2, ' ', 0) 142 143 c, err := res.vm.Client() 144 if err != nil { 145 return err 146 } 147 148 for _, r := range res.Result { 149 fields := []struct { 150 name string 151 moid *types.ManagedObjectReference 152 fault []types.LocalizedMethodFault 153 }{ 154 {"VM", r.Vm, nil}, 155 {"Host", r.Host, nil}, 156 {"Warning", nil, r.Warning}, 157 {"Error", nil, r.Error}, 158 } 159 160 for _, f := range fields { 161 var val string 162 if f.moid == nil { 163 var msgs []string 164 for _, m := range f.fault { 165 msgs = append(msgs, m.LocalizedMessage) 166 } 167 val = strings.Join(slices.Compact(msgs), "\n\t") 168 } else { 169 val, err = find.InventoryPath(res.ctx, c, *f.moid) 170 if err != nil { 171 return err 172 } 173 } 174 fmt.Fprintf(tw, "%s:\t%s\n", f.name, val) 175 } 176 } 177 178 return tw.Flush() 179 }