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  }