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 }