abuseipdb_example/
abuseipdb_example.rs

1//! # Cortex AbuseIPDB Analyzer Example
2//!
3//! This example demonstrates how to use the Rust client for the Cortex API
4//! to submit an IP address for analysis using a specific analyzer instance,
5//! in this case, an AbuseIPDB analyzer.
6//!
7//! ## Functionality
8//!
9//! 1.  **Configuration**: Sets up the API client configuration using `common::setup_configuration()`,
10//!     which reads the Cortex endpoint and API key from environment variables.
11//! 2.  **Analyzer Selection**: Specifies the name of the analyzer to run (e.g., "AbuseIPDB_1_0").
12//! 3.  **Analyzer ID Retrieval**: Uses `common::get_analyzer_id_by_name()` to find the
13//!     actual instance ID of the specified analyzer. This is crucial because Cortex
14//!     jobs are run against specific analyzer *instances*.
15//! 4.  **Job Creation**: Constructs a `JobCreateRequest` with the IP address to analyze,
16//!     data type ("ip"), TLP/PAP levels, and a descriptive message/label.
17//! 5.  **Job Submission**: Calls `job_api::create_analyzer_job()` to submit the analysis job.
18//! 6.  **Report Fetching**: If the job is submitted successfully and a job ID is returned,
19//!     it attempts to fetch the job report using `job_api::get_job_report()`.
20//!
21//! ## Prerequisites
22//!
23//! -   A running Cortex instance accessible via the network.
24//! -   The "AbuseIPDB" analyzer (or the one specified in `analyzer_name_to_run`)
25//!     must be enabled and configured in your Cortex instance.
26//! -   Environment variables `CORTEX_ENDPOINT` and `CORTEX_API_KEY` must be set.
27//!
28//! ## Usage
29//!
30//! ```sh
31//! # Set your Cortex API endpoint and key
32//! export CORTEX_ENDPOINT="http://your-cortex-host:9000/api"
33//! export CORTEX_API_KEY="your_cortex_api_key"
34//!
35//! # Run the example
36//! cargo run --example abuseipdb_example
37use cortex_client::apis::job_api;
38use cortex_client::models::JobCreateRequest;
39
40mod common;
41
42#[tokio::main]
43async fn main() -> Result<(), Box<dyn std::error::Error>> {
44    let config = match common::setup_configuration() {
45        Ok(cfg) => cfg,
46        Err(e) => {
47            eprintln!("Configuration error: {}", e);
48            eprintln!(
49                "Please ensure CORTEX_ENDPOINT and CORTEX_API_KEY environment variables are set."
50            );
51            eprintln!("Example usage:");
52            eprintln!("  export CORTEX_ENDPOINT=\"http://localhost:9000/api\"");
53            eprintln!("  export CORTEX_API_KEY=\"your_api_key_here\"");
54            eprintln!("  cargo run --example abuseipdb_example");
55            return Err(e.into());
56        }
57    };
58
59    let analyzer_name_to_run = "AbuseIPDB_1_0"; 
60
61    let ip_to_analyze = "8.8.8.8"; 
62    let data_type = "ip";
63
64    let analyzer_worker_id = match common::get_analyzer_id_by_name(&config, analyzer_name_to_run)
65        .await
66    {
67        Ok(Some(id)) => id,
68        Ok(None) => {
69            eprintln!("Could not find an analyzer instance named '{}'. Please check the name and ensure the analyzer is enabled in Cortex.", analyzer_name_to_run);
70            eprintln!("You can use the 'list_analyzers' example to see available analyzer names and their instance IDs.");
71            return Ok(()); // Or return an error
72        }
73        Err(e) => {
74            eprintln!(
75                "Error trying to get analyzer ID for '{}': {}",
76                analyzer_name_to_run, e
77            );
78            return Err(e);
79        }
80    };
81
82    println!(
83        "Attempting to run analyzer instance ID '{}' (resolved from name '{}') on IP: {}",
84        analyzer_worker_id, analyzer_name_to_run, ip_to_analyze
85    );
86
87    let job_request = JobCreateRequest {
88        data: Some(ip_to_analyze.to_string()),
89        data_type: Some(data_type.to_string()),
90        tlp: Some(2), // Traffic Light Protocol: AMBER (suitable for sharing with trusted partners)
91        pap: Some(2), // Permissible Actions Protocol: AMBER
92        message: Some(Some(format!(
93            "Running {} (instance ID {}) scan from example for IP {}",
94            analyzer_name_to_run, analyzer_worker_id, ip_to_analyze
95        ))),
96        parameters: None, // Add specific analyzer parameters here if needed (e.g., threshold for AbuseIPDB)
97        label: Some(Some("abuseipdb_example_scan".to_string())),
98        force: Some(false), // Set to true to bypass cache and force a new analysis
99        attributes: None,   // Legacy field, prefer direct fields like data, dataType, tlp, etc.
100    };
101
102    match job_api::create_analyzer_job(&config, &analyzer_worker_id, job_request).await {
103        Ok(job_response) => {
104            println!("\nSuccessfully created analyzer job:");
105            println!("{:#?}", job_response); 
106
107            if let Some(job_id) = job_response._id {
108                println!("\nJob status is Success. Attempting to fetch report directly using get_job_report for job ID: {}", job_id);
109
110                match job_api::get_job_report(&config, &job_id).await {
111                    Ok(report_response) => {
112                        println!("\nSuccessfully fetched job report:");
113                        match report_response {
114                            cortex_client::models::JobReportResponse::Object(json_report) => {
115                                println!("Report (JSON): {:#?}", json_report);
116                            }
117                            cortex_client::models::JobReportResponse::JobReportResponseOneOf(
118                                status_enum,
119                            ) => {
120                                println!("Job status from get_job_report: {:?}", status_enum);
121                                println!("This is unexpected if the job was marked 'Success' previously.");
122                            }
123                        }
124                    }
125                    Err(e) => {
126                        eprintln!("\nError fetching job report with get_job_report: {:?}", e);
127                    }
128                }
129            } else {
130                eprintln!("\nJob created, but no job ID was returned in the response. Cannot fetch report.");
131            }
132        }
133        Err(e) => {
134            eprintln!("\nError creating analyzer job: {:?}", e);
135            eprintln!("Please check:");
136            eprintln!(
137                "  1. The analyzer ID '{}' is correct and the analyzer is enabled in Cortex.",
138                analyzer_worker_id
139            );
140            eprintln!("  2. Cortex is running and accessible at the configured CORTEX_ENDPOINT.");
141            eprintln!("  3. Your CORTEX_API_KEY has the necessary permissions.");
142        }
143    }
144
145    Ok(())
146}