dragonfly_client_rs/
main.rs

1mod app_config;
2mod client;
3mod exts;
4mod scanner;
5mod utils;
6
7use std::time::Duration;
8
9use client::DragonflyClient;
10use color_eyre::eyre::Result;
11use tracing::{error, info, span, trace, Level};
12use tracing_subscriber::EnvFilter;
13
14use crate::{
15    app_config::APP_CONFIG,
16    client::{Job, ScanResult, SubmitJobResultsError},
17    scanner::{scan_all_distributions, PackageScanResults},
18};
19
20fn scan_package(client: &DragonflyClient, job: Job) -> ScanResult {
21    let span = span!(Level::INFO, "Job", name = job.name, version = job.version);
22    let _enter = span.enter();
23
24    match scan_all_distributions(client.get_http_client(), &client.rules_state.rules, &job) {
25        Ok(results) => {
26            let package_scan_results =
27                PackageScanResults::new(job.name, job.version, results, job.hash);
28            let body = package_scan_results.build_body();
29
30            Ok(body)
31        }
32        Err(err) => Err(SubmitJobResultsError {
33            name: job.name,
34            version: job.version,
35            reason: format!("{err}"),
36        }),
37    }
38}
39
40fn main() -> Result<()> {
41    color_eyre::install()?;
42
43    let default_env_filter = EnvFilter::builder()
44        .parse("warn,dragonfly_client_rs=info")
45        .unwrap();
46    let env_filter = EnvFilter::try_from_default_env().unwrap_or(default_env_filter);
47
48    tracing_subscriber::fmt().with_env_filter(env_filter).init();
49    let mut client = DragonflyClient::new()?;
50
51    loop {
52        info!("Fetching job");
53        match client.get_job() {
54            Ok(Some(job)) => {
55                trace!("Successfully fetched job");
56
57                info!("Starting scan of {} v{}", job.name, job.version);
58                if job.hash != client.rules_state.hash {
59                    info!(
60                        "Must update rules, updating from {} to {}",
61                        client.rules_state.hash, job.hash
62                    );
63
64                    if let Err(err) = client.update_rules() {
65                        error!("Error while updating rules: {err}");
66                    }
67                }
68
69                let scan_result = scan_package(&client, job);
70                let http_result = client.send_result(scan_result);
71                if let Err(err) = http_result {
72                    error!("Error while sending response to API: {err}");
73                }
74            }
75
76            Ok(None) => {
77                info!("No job found");
78                std::thread::sleep(Duration::from_secs(APP_CONFIG.load_duration));
79            }
80
81            Err(err) => {
82                error!("Unexpected HTTP error: {err}");
83                std::thread::sleep(Duration::from_secs(APP_CONFIG.load_duration));
84            }
85        }
86    }
87}