When sending an event asynchronously, the original context used for
whatever generated the event (probably a synchronous, quick HTTP
context) is probably not what is wanted for sending the event, which
could face delays if a consumer is backed up.
I will admit myself to sometimes having "context blindness", where
I just take whatever context is incoming in a function and thread it
out to all calls. Normally this is the right thing to do when, say,
tying downstream API calls to an upstream HTTP timeout.
When making KV events, for example, we used the HTTP context for
`SendEvent()`, and this can cause the events to be dropped if they
aren't taken from the channel before the HTTP request finishes.
In retrospect, it was probably unnecessary to include a context in
the `SendEvent` interface.
We keep the context in place for backwards compability, but also in
case we want to use it for purposes other than timeouts and
cancellations in the future.
Co-authored-by: Christopher Swenson <christopher.swenson@hashicorp.com>
The [WebSockets spec](https://www.rfc-editor.org/rfc/rfc6455) states
that text messages must be valid UTF-8 encoded strings, which protobuf
messages virtually never are. This now correctly sends the protobuf events
as binary messages.
We change the format to correspond to CloudEvents, as originally intended,
and remove a redundant timestamp and newline.
We also bump the eventlogger to fix a race condition that this code triggers.
When subscriptions are too slow to accept messages on their channels,
then we should remove them from the fanout so that we don't have
dead subscriptions using up resources.
In addition, when a subscription is explicitly canceled, we should
also clean up after it remove the corresponding pipeline.
We also add a new metrics, `events.subscriptions`, to keep track
of the number of active subscriptions. This also helps us test.
Co-authored-by: Tom Proctor <tomhjp@users.noreply.github.com>
Also updates the event receieved to include a timestamp.
Websockets support both JSON and protobuf binary formats.
This can be used by either `wscat` or the new
`vault events subscribe`:
e.g.,
```sh
$ wscat -H "X-Vault-Token: $(vault print token)" --connect ws://127.0.0.1:8200/v1/sys/events/subscribe/abc?json=true
{"event":{"id":"5c5c8c83-bf43-7da5-fe88-fc3cac814b2e", "note":"testing"}, "eventType":"abc", "timestamp":"2023-02-07T18:40:50.598408Z"}
...
```
and
```sh
$ vault events subscribe abc
{"event":{"id":"5c5c8c83-bf43-7da5-fe88-fc3cac814b2e", "note":"testing"}, "eventType":"abc", "timestamp":"2023-02-07T18:40:50.598408Z"}
...
```
Co-authored-by: Tom Proctor <tomhjp@users.noreply.github.com>
This isn't perfect for sure, but it's solidifying and becoming a useful
base to work off.
This routes events sent from auth and secrets plugins to the main
`EventBus` in the Vault Core. Events sent from plugins are automatically
tagged with the namespace and plugin information associated with them.
For example, using:
```sh
vault server -dev -experiment events.beta1
```
Tested by checking that the events were enabled and disabled
when the `-experiment events.beta1` flag was present and absent.
Also added a small fix to pass the `hclog.Logger` in now so that
the logging hierarchy and levels are respected.
Creates a new `eventbus` package under `vault` with
an implementation of the `go-eventlogger` broker.
Also creates a stub of a common broker that will be accessible
in the core, and creates a simple event sending interface.