falco_plugin/plugin/parse/mod.rs
1use crate::parse::EventInput;
2use crate::plugin::base::Plugin;
3use crate::plugin::error::last_error::LastError;
4use crate::plugin::parse::wrappers::ParsePluginExported;
5use crate::plugin::tables::vtable::writer::LazyTableWriter;
6use crate::tables::LazyTableReader;
7use falco_event::events::{AnyEventPayload, RawEvent};
8use falco_plugin_api::ss_plugin_event_parse_input;
9
10#[doc(hidden)]
11pub mod wrappers;
12
13/// Support for event parse plugins
14pub trait ParsePlugin: Plugin + ParsePluginExported {
15 /// # Parsed event type
16 ///
17 /// Events will be parsed into this type before being passed to the plugin, so you can
18 /// work directly on the deserialized form and don't need to worry about validating
19 /// the events.
20 ///
21 /// If an event fails this conversion, an error will be returned from [`EventInput::event`],
22 /// which you can propagate directly to the caller.
23 ///
24 /// If you don't want any specific validation/conversion to be performed, specify the type as
25 /// ```
26 /// type Event<'a> = falco_event::events::RawEvent<'a>;
27 /// ```
28 type Event<'a>: AnyEventPayload + TryFrom<&'a RawEvent<'a>>
29 where
30 Self: 'a;
31
32 /// # Parse an event
33 ///
34 /// Receives an event from the current capture and parses its content.
35 /// The plugin is guaranteed to receive an event at most once, after any
36 /// operation related to the event sourcing capability, and before
37 /// any operation related to the field extraction capability.
38 fn parse_event(
39 &mut self,
40 event: &EventInput<Self::Event<'_>>,
41 parse_input: &ParseInput,
42 ) -> anyhow::Result<()>;
43}
44
45/// # The input to a parse plugin
46///
47/// It has two fields containing the vtables needed to access tables imported through
48/// the [tables API](`crate::tables`).
49///
50/// You will pass these vtables to all methods that read or write data from tables,
51/// but you won't interact with them otherwise. They're effectively tokens proving
52/// you're in the right context to read/write tables.
53#[derive(Debug)]
54pub struct ParseInput<'t> {
55 /// Accessors to read table entries
56 pub reader: LazyTableReader<'t>,
57 /// Accessors to modify table entries
58 pub writer: LazyTableWriter<'t>,
59}
60
61impl ParseInput<'_> {
62 pub(in crate::plugin::parse) unsafe fn try_from(
63 value: *const ss_plugin_event_parse_input,
64 last_error: LastError,
65 ) -> Result<Self, anyhow::Error> {
66 let input = unsafe {
67 value
68 .as_ref()
69 .ok_or_else(|| anyhow::anyhow!("Got null event parse input"))?
70 };
71
72 let reader = unsafe {
73 input
74 .table_reader_ext
75 .as_ref()
76 .ok_or_else(|| anyhow::anyhow!("Got null reader vtable"))?
77 };
78 let writer = unsafe {
79 input
80 .table_writer_ext
81 .as_ref()
82 .ok_or_else(|| anyhow::anyhow!("Got null writer vtable"))?
83 };
84
85 let reader = LazyTableReader::new(reader, last_error.clone());
86 let writer = LazyTableWriter::try_from(writer, last_error)?;
87
88 Ok(Self { reader, writer })
89 }
90}