Skip to content

Commit

Permalink
feat: adding possibility to run commands only on a specific detection (
Browse files Browse the repository at this point in the history
  • Loading branch information
MatisseB authored Nov 21, 2024
1 parent 357a76e commit 86846b4
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 25 deletions.
19 changes: 15 additions & 4 deletions crates/common/src/detections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,21 @@ impl Detection {
}
}

pub fn map_plugin_detections() -> Result<HashMap<String, HashSet<DetectionState>>> {
let entries: Vec<PathBuf> = fs::read_dir(LGC_RULES_DIR)?
.filter_map(|file| file.ok().map(|f| f.path()))
.collect();
pub fn map_plugin_detections(
detection_id: Option<String>,
) -> Result<HashMap<String, HashSet<DetectionState>>> {
let entries: Vec<PathBuf> = if let Some(detection_id) = detection_id {
let detection_path = PathBuf::from(format!("{}/{}.yaml", LGC_RULES_DIR, detection_id));
if detection_path.is_file() {
vec![detection_path]
} else {
bail!("detection `{}` does not exist", detection_id)
}
} else {
fs::read_dir(LGC_RULES_DIR)?
.filter_map(|file| file.ok().map(|f| f.path()))
.collect()
};

let plugins: DashMap<String, HashSet<DetectionState>> = DashMap::new();

Expand Down
42 changes: 26 additions & 16 deletions crates/common/src/state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,26 +51,36 @@ impl State {
}
}

pub fn missing_rules(&self, detections: &ServiceDetections, silent: bool) -> ServiceDetections {
pub fn missing_rules(
&self,
detections: &ServiceDetections,
silent: bool,
detection_name: Option<String>,
) -> ServiceDetections {
let to_remove: DashMap<String, HashSet<DetectionState>> = DashMap::new();

detections.par_iter().for_each(|(service_id, rules)| {
if let Some(state_rules) = self.services.get(service_id) {
state_rules.difference(rules).for_each(|rule| {
to_remove
.entry(service_id.clone())
.and_modify(|s| {
s.insert(rule.clone());
})
.or_insert(HashSet::from([rule.clone()]));
if !silent {
println!(
"[-] rule: `{}` will be deleted from `{}`",
style(&rule.name).red(),
&service_id
);
}
});
state_rules
.difference(rules)
.filter(|rule| {
detection_name.is_none() || detection_name.as_ref().unwrap() == &rule.name
})
.for_each(|rule| {
to_remove
.entry(service_id.clone())
.and_modify(|s| {
s.insert(rule.clone());
})
.or_insert(HashSet::from([rule.clone()]));
if !silent {
println!(
"[-] rule: `{}` will be deleted from `{}`",
style(&rule.name).red(),
&service_id
);
}
});
}
});

Expand Down
12 changes: 10 additions & 2 deletions src/commands/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ pub struct DeployCommand {
#[clap(short, long)]
pub service_id: Option<String>,

/// Show differences for this detection path
#[clap(short, long)]
pub detection_id: Option<String>,

/// Skip interactive approval of changes deployment
#[clap(long)]
pub auto_approve: bool,
Expand All @@ -37,7 +41,7 @@ pub struct DeployCommand {
impl DeployCommand {
pub async fn run(self, config: &ProjectConfiguration) -> Result<()> {
// Load all detections
let detections = map_plugin_detections()?;
let detections = map_plugin_detections(self.detection_id.clone())?;

// Prompt theme
let prompt_theme = ColorfulTheme::default();
Expand Down Expand Up @@ -149,7 +153,11 @@ impl DeployCommand {
}

let mut state = config.state.load().await?;
let to_remove = state.missing_rules(&returned_rules, self.auto_approve);
let to_remove = state.missing_rules(
&returned_rules,
self.auto_approve,
self.detection_id.clone(),
);
let changed =
compare_detections(&detections, &returned_rules, &services, !self.auto_approve);

Expand Down
8 changes: 6 additions & 2 deletions src/commands/diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,16 @@ pub struct DiffCommand {
/// Show differences from this target service
#[clap(short, long)]
pub service_id: Option<String>,

/// Show differences for this detection path
#[clap(short, long)]
pub detection_id: Option<String>,
}

impl DiffCommand {
pub async fn run(self, config: &ProjectConfiguration) -> Result<()> {
// Load all detections
let detections: PluginDetections = map_plugin_detections()?;
let detections: PluginDetections = map_plugin_detections(self.detection_id.clone())?;

// Prompt theme
let prompt_theme = ColorfulTheme::default();
Expand Down Expand Up @@ -151,7 +155,7 @@ impl DiffCommand {
.state
.load()
.await?
.missing_rules(&returned_rules, false)
.missing_rules(&returned_rules, false, self.detection_id)
.is_empty()
&& changes
&& !has_diff
Expand Down
2 changes: 1 addition & 1 deletion src/commands/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub struct ValidateCommand;
impl ValidateCommand {
pub async fn run(self, config: &ProjectConfiguration) -> Result<()> {
// Load all detections
let detections = map_plugin_detections()?;
let detections = map_plugin_detections(None)?;

// Load plugins
let plugin_manager = PluginManager::new()?;
Expand Down

0 comments on commit 86846b4

Please sign in to comment.