github.com/hashicorp/vault/sdk@v0.13.0/logical/events.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package logical
     5  
     6  import (
     7  	"context"
     8  
     9  	"github.com/hashicorp/go-uuid"
    10  	"google.golang.org/protobuf/types/known/structpb"
    11  )
    12  
    13  // common event metadata keys
    14  const (
    15  	// EventMetadataDataPath is used in event metadata to show the API path that can be used to fetch any underlying
    16  	// data. For example, the KV plugin would set this to `data/mysecret`. The event system will automatically prepend
    17  	// the plugin mount to this path, if present, so it would become `secret/data/mysecret`, for example.
    18  	// If this is an auth plugin event, this will additionally be prepended with `auth/`.
    19  	EventMetadataDataPath = "data_path"
    20  	// EventMetadataOperation is used in event metadata to express what operation was performed that generated the
    21  	// event, e.g., `read` or `write`.
    22  	EventMetadataOperation = "operation"
    23  	// EventMetadataModified is used in event metadata when the event attests that the underlying data has been modified
    24  	// and might need to be re-fetched (at the EventMetadataDataPath).
    25  	EventMetadataModified = "modified"
    26  
    27  	extraMetadataArgument = "EXTRA_VALUE_AT_END"
    28  )
    29  
    30  // ID is an alias to GetId() for CloudEvents compatibility.
    31  func (x *EventReceived) ID() string {
    32  	return x.Event.GetId()
    33  }
    34  
    35  // NewEvent returns an event with a new, random EID.
    36  func NewEvent() (*EventData, error) {
    37  	id, err := uuid.GenerateUUID()
    38  	if err != nil {
    39  		return nil, err
    40  	}
    41  	return &EventData{
    42  		Id: id,
    43  	}, nil
    44  }
    45  
    46  // EventType represents a topic, and is a wrapper around eventlogger.EventType.
    47  type EventType string
    48  
    49  // EventSender sends events to the common event bus.
    50  type EventSender interface {
    51  	SendEvent(ctx context.Context, eventType EventType, event *EventData) error
    52  }
    53  
    54  // SendEvent is a convenience method for plugins events to an EventSender, converting the
    55  // metadataPairs to the EventData structure.
    56  func SendEvent(ctx context.Context, sender EventSender, eventType string, metadataPairs ...string) error {
    57  	ev, err := NewEvent()
    58  	if err != nil {
    59  		return err
    60  	}
    61  	ev.Metadata = &structpb.Struct{Fields: make(map[string]*structpb.Value, (len(metadataPairs)+1)/2)}
    62  	for i := 0; i < len(metadataPairs)-1; i += 2 {
    63  		ev.Metadata.Fields[metadataPairs[i]] = structpb.NewStringValue(metadataPairs[i+1])
    64  	}
    65  	if len(metadataPairs)%2 != 0 {
    66  		ev.Metadata.Fields[extraMetadataArgument] = structpb.NewStringValue(metadataPairs[len(metadataPairs)-1])
    67  	}
    68  	return sender.SendEvent(ctx, EventType(eventType), ev)
    69  }
    70  
    71  // EventReceivedBexpr is used for evaluating boolean expressions with go-bexpr.
    72  type EventReceivedBexpr struct {
    73  	EventType         string `bexpr:"event_type"`
    74  	Operation         string `bexpr:"operation"`
    75  	SourcePluginMount string `bexpr:"source_plugin_mount"`
    76  	DataPath          string `bexpr:"data_path"`
    77  	Namespace         string `bexpr:"namespace"`
    78  }
    79  
    80  // BexprDatum returns a copy of EventReceived formatted for use in evaluating go-bexpr boolean expressions.
    81  func (x *EventReceived) BexprDatum() any {
    82  	operation := ""
    83  	dataPath := ""
    84  
    85  	if x.Event != nil {
    86  		if x.Event.Metadata != nil {
    87  			operationValue := x.Event.Metadata.Fields[EventMetadataOperation]
    88  			if operationValue != nil {
    89  				operation = operationValue.GetStringValue()
    90  			}
    91  			dataPathValue := x.Event.Metadata.Fields[EventMetadataDataPath]
    92  			if dataPathValue != nil {
    93  				dataPath = dataPathValue.GetStringValue()
    94  			}
    95  		}
    96  	}
    97  
    98  	return &EventReceivedBexpr{
    99  		EventType:         x.EventType,
   100  		Operation:         operation,
   101  		SourcePluginMount: x.PluginInfo.MountPath,
   102  		DataPath:          dataPath,
   103  		Namespace:         x.Namespace,
   104  	}
   105  }