use crate::_osquery::{ExtensionPluginResponse, ExtensionResponse, ExtensionStatus};
use crate::plugin::{ExtensionResponseEnum, OsqueryPlugin, Registry};
use std::collections::{BTreeMap, HashMap};
use std::sync::Arc;
pub trait ConfigPlugin: Send + Sync + 'static {
fn name(&self) -> String;
fn gen_config(&self) -> Result<HashMap<String, String>, String>;
fn gen_pack(&self, name: &str, _value: &str) -> Result<String, String> {
Err(format!("Pack '{name}' not found"))
}
fn shutdown(&self) {}
}
#[derive(Clone)]
pub struct ConfigPluginWrapper {
plugin: Arc<dyn ConfigPlugin>,
}
impl ConfigPluginWrapper {
pub fn new<C: ConfigPlugin>(plugin: C) -> Self {
Self {
plugin: Arc::new(plugin),
}
}
}
impl OsqueryPlugin for ConfigPluginWrapper {
fn name(&self) -> String {
self.plugin.name()
}
fn registry(&self) -> Registry {
Registry::Config
}
fn routes(&self) -> ExtensionPluginResponse {
ExtensionPluginResponse::new()
}
fn ping(&self) -> ExtensionStatus {
ExtensionStatus::default()
}
fn handle_call(&self, request: crate::_osquery::ExtensionPluginRequest) -> ExtensionResponse {
let action = request.get("action").map(|s| s.as_str()).unwrap_or("");
match action {
"genConfig" => {
match self.plugin.gen_config() {
Ok(config_map) => {
let mut response = ExtensionPluginResponse::new();
let mut row = BTreeMap::new();
for (key, value) in config_map {
row.insert(key, value);
}
response.push(row);
let status = ExtensionStatus::default();
ExtensionResponse::new(status, response)
}
Err(e) => ExtensionResponseEnum::Failure(e).into(),
}
}
"genPack" => {
let name = request.get("name").cloned().unwrap_or_default();
let value = request.get("value").cloned().unwrap_or_default();
match self.plugin.gen_pack(&name, &value) {
Ok(pack_content) => {
let mut response = ExtensionPluginResponse::new();
let mut row = BTreeMap::new();
row.insert("pack".to_string(), pack_content);
response.push(row);
let status = ExtensionStatus::default();
ExtensionResponse::new(status, response)
}
Err(e) => ExtensionResponseEnum::Failure(e).into(),
}
}
_ => ExtensionResponseEnum::Failure(format!("Unknown config plugin action: {action}"))
.into(),
}
}
fn shutdown(&self) {
self.plugin.shutdown();
}
}