github.com/choria-io/go-choria@v0.28.1-0.20240416190746-b3bf9c7d5a45/client/scoutclient/action_trigger.go (about) 1 // generated code; DO NOT EDIT 2 // 3 // Client for Choria RPC Agent 'scout' Version 0.28.0 generated using Choria version 0.28.0 4 5 package scoutclient 6 7 import ( 8 "context" 9 "encoding/json" 10 "fmt" 11 "io" 12 "sync" 13 14 "github.com/choria-io/go-choria/protocol" 15 rpcclient "github.com/choria-io/go-choria/providers/agent/mcorpc/client" 16 "github.com/choria-io/go-choria/providers/agent/mcorpc/ddl/agent" 17 "github.com/choria-io/go-choria/providers/agent/mcorpc/replyfmt" 18 ) 19 20 // TriggerRequester performs a RPC request to scout#trigger 21 type TriggerRequester struct { 22 r *requester 23 outc chan *TriggerOutput 24 } 25 26 // TriggerOutput is the output from the trigger action 27 type TriggerOutput struct { 28 details *ResultDetails 29 reply map[string]any 30 } 31 32 // TriggerResult is the result from a trigger action 33 type TriggerResult struct { 34 ddl *agent.DDL 35 stats *rpcclient.Stats 36 outputs []*TriggerOutput 37 rpcreplies []*replyfmt.RPCReply 38 mu sync.Mutex 39 } 40 41 func (d *TriggerResult) RenderResults(w io.Writer, format RenderFormat, displayMode DisplayMode, verbose bool, silent bool, colorize bool, log Log) error { 42 d.mu.Lock() 43 defer d.mu.Unlock() 44 45 if d.stats == nil { 46 return fmt.Errorf("result stats is not set, result was not completed") 47 } 48 49 results := &replyfmt.RPCResults{ 50 Agent: d.stats.Agent(), 51 Action: d.stats.Action(), 52 Replies: d.rpcreplies, 53 Stats: d.stats, 54 } 55 56 addl, err := d.ddl.ActionInterface(d.stats.Action()) 57 if err != nil { 58 return err 59 } 60 61 switch format { 62 case JSONFormat: 63 return results.RenderJSON(w, addl) 64 case TableFormat: 65 return results.RenderTable(w, addl) 66 case TXTFooter: 67 results.RenderTXTFooter(w, verbose) 68 return nil 69 default: 70 return results.RenderTXT(w, addl, verbose, silent, replyfmt.DisplayMode(displayMode), colorize, log) 71 } 72 } 73 74 // Stats is the rpc request stats 75 func (d *TriggerResult) Stats() Stats { 76 return d.stats 77 } 78 79 // ResultDetails is the details about the request 80 func (d *TriggerOutput) ResultDetails() *ResultDetails { 81 return d.details 82 } 83 84 // HashMap is the raw output data 85 func (d *TriggerOutput) HashMap() map[string]any { 86 return d.reply 87 } 88 89 // JSON is the JSON representation of the output data 90 func (d *TriggerOutput) JSON() ([]byte, error) { 91 return json.Marshal(d.reply) 92 } 93 94 // ParseTriggerOutput parses the result value from the Trigger action into target 95 func (d *TriggerOutput) ParseTriggerOutput(target any) error { 96 j, err := d.JSON() 97 if err != nil { 98 return fmt.Errorf("could not access payload: %s", err) 99 } 100 101 err = json.Unmarshal(j, target) 102 if err != nil { 103 return fmt.Errorf("could not unmarshal JSON payload: %s", err) 104 } 105 106 return nil 107 } 108 109 // Do performs the request 110 func (d *TriggerRequester) Do(ctx context.Context) (*TriggerResult, error) { 111 dres := &TriggerResult{ddl: d.r.client.ddl} 112 113 addl, err := dres.ddl.ActionInterface(d.r.action) 114 if err != nil { 115 return nil, err 116 } 117 118 handler := func(pr protocol.Reply, r *rpcclient.RPCReply) { 119 // filtered by expr filter 120 if r == nil { 121 return 122 } 123 124 output := &TriggerOutput{ 125 reply: make(map[string]any), 126 details: &ResultDetails{ 127 sender: pr.SenderID(), 128 code: int(r.Statuscode), 129 message: r.Statusmsg, 130 ts: pr.Time(), 131 }, 132 } 133 134 addl.SetOutputDefaults(output.reply) 135 136 err := json.Unmarshal(r.Data, &output.reply) 137 if err != nil { 138 d.r.client.errorf("Could not decode reply from %s: %s", pr.SenderID(), err) 139 } 140 141 // caller wants a channel so we dont return a resultset too (lots of memory etc) 142 // this is unused now, no support for setting a channel 143 if d.outc != nil { 144 d.outc <- output 145 return 146 } 147 148 // else prepare our result set 149 dres.mu.Lock() 150 dres.outputs = append(dres.outputs, output) 151 dres.rpcreplies = append(dres.rpcreplies, &replyfmt.RPCReply{ 152 Sender: pr.SenderID(), 153 RPCReply: r, 154 }) 155 dres.mu.Unlock() 156 } 157 158 res, err := d.r.do(ctx, handler) 159 if err != nil { 160 return nil, err 161 } 162 163 dres.stats = res 164 165 return dres, nil 166 } 167 168 // AllOutputs provide access to all outputs 169 func (d *TriggerResult) AllOutputs() []*TriggerOutput { 170 return d.outputs 171 } 172 173 // EachOutput iterates over all results received 174 func (d *TriggerResult) EachOutput(h func(r *TriggerOutput)) { 175 for _, resp := range d.outputs { 176 h(resp) 177 } 178 } 179 180 // Checks is an optional input to the trigger action 181 // 182 // Description: Check to trigger, empty means all 183 func (d *TriggerRequester) Checks(v []any) *TriggerRequester { 184 d.r.args["checks"] = v 185 186 return d 187 } 188 189 // Failed is the value of the failed output 190 // 191 // Description: List of checks that could not be triggered 192 func (d *TriggerOutput) Failed() []any { 193 val := d.reply["failed"] 194 195 return val.([]any) 196 197 } 198 199 // Skipped is the value of the skipped output 200 // 201 // Description: List of checks that was skipped 202 func (d *TriggerOutput) Skipped() []any { 203 val := d.reply["skipped"] 204 205 return val.([]any) 206 207 } 208 209 // Transitioned is the value of the transitioned output 210 // 211 // Description: List of checks that were triggered 212 func (d *TriggerOutput) Transitioned() []any { 213 val := d.reply["transitioned"] 214 215 return val.([]any) 216 217 }