Skip to content

Commit

Permalink
new(tables): support tables with predefined fields
Browse files Browse the repository at this point in the history
  • Loading branch information
gnosek committed Mar 20, 2024
1 parent 0d901c8 commit 0237401
Show file tree
Hide file tree
Showing 12 changed files with 574 additions and 47 deletions.
12 changes: 11 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[workspace]
members = ["falco_plugin_api", "falco_plugin", "falco_event_derive", "falco_event"]
members = ["falco_plugin_api", "falco_plugin", "falco_event_derive", "falco_event", "falco_plugin_derive"]
resolver = "2"
3 changes: 2 additions & 1 deletion falco_plugin/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "falco_plugin"
version = "0.1.0"
version = "0.1.1"
edition = "2021"
license = "Apache-2.0"
description = "High level bindings for the Falco plugin API"
Expand Down Expand Up @@ -36,6 +36,7 @@ crate_type = ["dylib"]
thiserror = "1.0.58"
falco_event = { path = "../falco_event", version = "0.1" }
falco_plugin_api = { path = "../falco_plugin_api", version = "0.1" }
falco_plugin_derive = { path = "../falco_plugin_derive", version = "0.1" }
serde = "1.0.197"
serde_json = "1.0.114"
schemars = "0.8.16"
Expand Down
42 changes: 39 additions & 3 deletions falco_plugin/examples/parse_plugin.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,46 @@
use std::ffi::CStr;
use std::ffi::{CStr, CString};

use anyhow::anyhow;

use falco_event::events::types::EventType;
use falco_plugin::base::{Plugin, TableInitInput};
use falco_plugin::parse::{EventParseInput, ParsePlugin};
use falco_plugin::tables::TypedTable;
use falco_plugin::tables::TypedTableField;
use falco_plugin::tables::{DynamicFieldValues, TypedTableField};
use falco_plugin::tables::{DynamicTable, TypedTable};
use falco_plugin::{c, parse_plugin, plugin, EventInput, FailureReason};
use falco_plugin_api::{ss_plugin_event_input, ss_plugin_event_parse_input, ss_plugin_init_input};
use falco_plugin_derive::TableValues;

#[derive(TableValues, Default)]
struct AnotherTable {
#[readonly]
int_field: u64,
string_field: CString,

#[hidden]
secret: Vec<u8>,

#[dynamic]
dynamic_fields: DynamicFieldValues,
}

#[derive(TableValues, Default)]
#[static_only]
struct TableWithStaticFieldsOnly {
#[readonly]
int_field: u64,
string_field: CString,

#[hidden]
secret: Vec<u8>,
}

pub struct DummyPlugin {
thread_table: TypedTable<i64>,
sample_field: TypedTableField<u64>,
new_table: &'static mut DynamicTable<u64>,
another_table: &'static mut DynamicTable<u64, AnotherTable>,
table_with_static_fields_only: &'static mut DynamicTable<u64, TableWithStaticFieldsOnly>,
}

impl Plugin for DummyPlugin {
Expand All @@ -26,9 +54,17 @@ impl Plugin for DummyPlugin {
let thread_table = input.get_table::<i64>(c!("threads"))?;
let sample_field = thread_table.add_field::<u64>(c!("sample"))?;

let new_table = input.add_table(DynamicTable::new(c!("sample")))?;
let another_table = input.add_table(DynamicTable::new(c!("another")))?;
let table_with_static_fields_only =
input.add_table(DynamicTable::new(c!("static_fields_only")))?;

Ok(DummyPlugin {
thread_table,
sample_field,
new_table,
another_table,
table_with_static_fields_only,
})
}
}
Expand Down
59 changes: 59 additions & 0 deletions falco_plugin/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,63 @@
#![deny(rustdoc::broken_intra_doc_links)]

// reexport dependencies
pub use falco_plugin_api as api;
pub use schemars;
pub use serde;

/// Mark a struct type as a table value
///
/// Tables in Falco plugins are effectively maps from a [key](`tables::TableData`)
/// to a (possibly dynamic) struct of values.
///
/// The default implementation for tables ([`tables::DynamicFieldValues`]) uses
/// dynamic fields only, but with this macro you can also define structs containing static
/// (predefined) fields that are accessible to your plugin without going through the Falco
/// plugin API.
///
/// A table can be fully static (no dynamic fields allowed). In this case, it must be tagged
/// with a `#[static_only]` attribute (to prevent accidental omission of the dynamic field values,
/// which would only get caught at runtime, possibly much later).
///
/// Alternatively, it can mark a single field as `#[dynamic]`. That field needs to implement
/// [`tables::TableValues`] and it will generally be of type [`tables::DynamicFieldValues`].
///
/// Fields tagged as `#[readonly]` won't be writable via the Falco API and fields tagged
/// as `#[hidden]` won't be exposed to the API at all. This is useful if you want to store data
/// that's incompatible with the Falco plugin API in your table.
///
/// # Example
/// ```
/// use std::ffi::CString;
/// use falco_plugin::tables::DynamicFieldValues;
/// use falco_plugin::TableValues;
///
/// #[derive(TableValues, Default)] // all table structs must implement Default
/// #[static_only] // no dynamic fields in this one
/// struct TableWithStaticFieldsOnly {
/// #[readonly]
/// int_field: u64, // this field cannot be modified with the Falco API
/// string_field: CString,
///
/// #[hidden]
/// secret: Vec<u8>, // this field is not visible via the Falco API
/// }
///
/// #[derive(TableValues, Default)]
/// struct AnotherTable {
/// #[readonly]
/// int_field: u64, // this field cannot be modified with the Falco API
/// string_field: CString,
///
/// #[hidden]
/// secret: Vec<u8>, // this field is not visible via the Falco API
///
/// #[dynamic]
/// dynamic_fields: DynamicFieldValues, // dynamically added fields have their values here
/// }
/// ```
pub use falco_plugin_derive::TableValues;

pub use crate::plugin::error::FailureReason;
pub use crate::plugin::event::EventInput;

Expand Down Expand Up @@ -440,15 +494,20 @@ pub mod source {
pub mod tables {
pub use crate::plugin::exported_tables::DynamicField;
pub use crate::plugin::exported_tables::DynamicFieldValue;
pub use crate::plugin::exported_tables::DynamicFieldValues;
pub use crate::plugin::exported_tables::DynamicTable;
pub use crate::plugin::exported_tables::ExportedTable;
pub use crate::plugin::exported_tables::FieldValue;
pub use crate::plugin::exported_tables::StaticField;
pub use crate::plugin::exported_tables::TableValues;
pub use crate::plugin::tables::data::Bool;
pub use crate::plugin::tables::data::TableData;
pub use crate::plugin::tables::data::TypedTableField;
pub use crate::plugin::tables::entry::TableEntry;
pub use crate::plugin::tables::entry::TableEntryReader;
pub use crate::plugin::tables::table::TypedTable;
pub use crate::plugin::tables::table_reader::TableReader;
pub use falco_event::fields::TypeId;
}

mod plugin;
Expand Down
Loading

0 comments on commit 0237401

Please sign in to comment.