github.com/vmware/govmomi@v0.51.0/cli/alarm/state.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 alarm 6 7 import ( 8 "context" 9 "encoding/json" 10 "flag" 11 "fmt" 12 "io" 13 "text/tabwriter" 14 "time" 15 16 "github.com/vmware/govmomi/alarm" 17 "github.com/vmware/govmomi/cli" 18 "github.com/vmware/govmomi/cli/flags" 19 "github.com/vmware/govmomi/vim25/types" 20 ) 21 22 type state struct { 23 *flags.DatacenterFlag 24 *flags.OutputFlag 25 26 ack bool 27 name string 28 alarm.StateInfoOptions 29 } 30 31 func init() { 32 cli.Register("alarms", &state{}) 33 } 34 35 func (cmd *state) Register(ctx context.Context, f *flag.FlagSet) { 36 cmd.DatacenterFlag, ctx = flags.NewDatacenterFlag(ctx) 37 cmd.DatacenterFlag.Register(ctx, f) 38 39 cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx) 40 cmd.OutputFlag.Register(ctx, f) 41 42 f.BoolVar(&cmd.ack, "ack", false, "Acknowledge alarms") 43 f.StringVar(&cmd.name, "n", "", "Filter by alarm name") 44 f.BoolVar(&cmd.Declared, "d", false, "Show declared alarms") 45 f.BoolVar(&cmd.InventoryPath, "l", false, "Long listing output") 46 } 47 48 func (cmd *state) Usage() string { 49 return "[PATH]" 50 } 51 52 func (cmd *state) Description() string { 53 return `Show triggered or declared alarms. 54 55 Triggered alarms: alarms triggered by this entity or by its descendants. 56 Triggered alarms are propagated up the inventory hierarchy so that a user 57 can readily tell when a descendant has triggered an alarm. 58 59 Declared alarms: alarms that apply to this managed entity. 60 Includes alarms defined on this entity and alarms inherited from the parent 61 entity, or from any ancestors in the inventory hierarchy. 62 63 PATH defaults to the root folder '/'. 64 When PATH is provided it should be an absolute inventory path or relative 65 to GOVC_DATACENTER. See also: 66 govc find -h 67 govc tree -h 68 69 Examples: 70 govc alarms 71 govc alarms vm/folder/vm-name 72 govc alarms /dc1/host/cluster1 73 govc alarms /dc1/host/cluster1 -d 74 75 govc alarms -n alarm.WCPRegisterVMFailedAlarm 76 govc alarms -ack /dc1/host/cluster1 77 govc alarms -ack -n alarm.WCPRegisterVMFailedAlarm vm/vm-name` 78 } 79 80 func (cmd *state) Process(ctx context.Context) error { 81 if err := cmd.DatacenterFlag.Process(ctx); err != nil { 82 return err 83 } 84 return cmd.OutputFlag.Process(ctx) 85 } 86 87 func (cmd *state) filterAlarms(ctx context.Context, m *alarm.Manager, obj types.ManagedObjectReference) ([]alarm.StateInfo, error) { 88 alarms, err := m.GetStateInfo(ctx, obj, cmd.StateInfoOptions) 89 if err != nil || cmd.name == "" { 90 return alarms, err 91 } 92 93 var match []alarm.StateInfo 94 for _, alarm := range alarms { 95 if alarm.Info.SystemName == cmd.name || alarm.Info.Name == cmd.name { 96 match = append(match, alarm) 97 } 98 } 99 100 return match, nil 101 } 102 103 type stateResult struct { 104 info []alarm.StateInfo 105 cmd *state 106 } 107 108 func (r *stateResult) Dump() any { 109 return r.info 110 } 111 112 func (r *stateResult) MarshalJSON() ([]byte, error) { 113 return json.Marshal(r.info) 114 } 115 116 func (r *stateResult) Write(w io.Writer) error { 117 tw := tabwriter.NewWriter(w, 2, 0, 2, ' ', 0) 118 119 fmt.Fprintf(tw, "Alarm Name\tObject\tSeverity\tTriggered Time\tAcknowledged Time\tAcknowledged By\n") 120 121 for _, a := range r.info { 122 name := a.Info.Name 123 tt := a.Time.Format(time.Stamp) 124 at := "" 125 by := a.AcknowledgedByUser 126 if a.AcknowledgedTime != nil { 127 at = a.AcknowledgedTime.Format(time.Stamp) 128 } 129 fmt.Fprintf(tw, "%s\t%s\t%s\t%s\t%s\t%s\n", name, a.Path, alarm.Severity[a.OverallStatus], tt, at, by) 130 } 131 132 return tw.Flush() 133 } 134 135 func (cmd *state) Run(ctx context.Context, f *flag.FlagSet) error { 136 if f.NArg() > 1 { 137 return flag.ErrHelp 138 } 139 if cmd.ack && cmd.Declared { 140 return flag.ErrHelp 141 } 142 143 c, err := cmd.Client() 144 if err != nil { 145 return err 146 } 147 148 obj := c.ServiceContent.RootFolder 149 if f.NArg() == 1 { 150 obj, err = cmd.ManagedObject(ctx, f.Arg(0)) 151 if err != nil { 152 return err 153 } 154 } 155 156 cmd.StateInfoOptions.Event = cmd.All() 157 158 m, err := alarm.GetManager(c) 159 if err != nil { 160 return err 161 } 162 163 alarms, err := cmd.filterAlarms(ctx, m, obj) 164 if err != nil { 165 return err 166 } 167 168 if cmd.ack { 169 for _, alarm := range alarms { 170 if alarm.Acknowledged != nil && *alarm.Acknowledged { 171 continue 172 } 173 if err := m.AcknowledgeAlarm(ctx, alarm.Alarm, alarm.Entity); err != nil { 174 return err 175 } 176 } 177 178 alarms, err = cmd.filterAlarms(ctx, m, obj) 179 if err != nil { 180 return err 181 } 182 } 183 184 return cmd.WriteResult(&stateResult{alarms, cmd}) 185 }