create_analyzer_job

Function create_analyzer_job 

Source
pub async fn create_analyzer_job(
    configuration: &Configuration,
    worker_id: &str,
    job_create_request: JobCreateRequest,
) -> Result<Job, Error<CreateAnalyzerJobError>>
Examples found in repository?
examples/abuseipdb_example.rs (line 102)
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}
More examples
Hide additional examples
examples/common.rs (line 105)
90pub async fn run_job_and_wait_for_report(
91    config: &cortex_client::apis::configuration::Configuration,
92    analyzer_worker_id: &str,
93    job_request: cortex_client::models::JobCreateRequest,
94    analyzer_name_for_log: &str, // For clearer log messages
95    observable_for_log: &str,    // For clearer log messages
96) -> Result<cortex_client::models::JobReportResponse, Box<dyn std::error::Error>> {
97    use cortex_client::apis::job_api;
98    use std::time::Duration;
99
100    println!(
101        "Submitting job to analyzer '{}' (ID: '{}') for observable: {}...",
102        analyzer_name_for_log, analyzer_worker_id, observable_for_log
103    );
104
105    match job_api::create_analyzer_job(config, analyzer_worker_id, job_request).await {
106        Ok(job_response) => {
107            println!(
108                "Successfully created job. Job ID: {}, Status: {:?}",
109                job_response._id.as_ref().unwrap_or(&"unknown".to_string()),
110                job_response.status
111            );
112
113            if let Some(job_id) = job_response._id {
114                println!(
115                    "\nAttempting to fetch report for job ID: {} with retries...",
116                    job_id
117                );
118
119                let max_retries = 3;
120                let retry_delay = Duration::from_secs(15);
121
122                for attempt in 1..=max_retries {
123                    println!(
124                        "\nAttempt {} of {} to check job status...",
125                        attempt, max_retries
126                    );
127                    match job_api::get_job_by_id(config, &job_id).await {
128                        Ok(job_details) => {
129                            println!("Current job status: {:?}", job_details.status);
130                            match job_details.status {
131                                Some(cortex_client::models::job::Status::Success) => {
132                                    println!(
133                                        "Job status is Success. Attempting to fetch report..."
134                                    );
135                                    match job_api::get_job_report(config, &job_id).await {
136                                        Ok(report_response) => {
137                                            println!("\n✅ Successfully fetched job report!");
138                                            return Ok(report_response);
139                                        }
140                                        Err(e) => {
141                                            let err_msg = format!("Error fetching job report even though status was Success: {:?}", e);
142                                            eprintln!("{}", err_msg);
143                                            // Decide if to break or retry. For now, break on report fetch error.
144                                            return Err(err_msg.into());
145                                        }
146                                    }
147                                }
148                                Some(cortex_client::models::job::Status::Failure) => {
149                                    let err_msg = format!(
150                                        "Job failed. Error message: {:?}",
151                                        job_details.error_message.unwrap_or_else(|| Some(
152                                            "No error message provided.".to_string()
153                                        ))
154                                    );
155                                    eprintln!("{}", err_msg);
156                                    return Err(err_msg.into());
157                                }
158                                Some(cortex_client::models::job::Status::InProgress)
159                                | Some(cortex_client::models::job::Status::Waiting) => {
160                                    if attempt < max_retries {
161                                        println!("Job is still {:?}. Waiting for {} seconds before next attempt...", job_details.status.unwrap(), retry_delay.as_secs());
162                                        tokio::time::sleep(retry_delay).await;
163                                    } else {
164                                        let info_msg = format!("Job did not complete (still {:?}) after {} attempts. Job ID: {}", job_details.status.unwrap(), max_retries, job_id);
165                                        println!("{}", info_msg);
166                                        // Return an error indicating timeout after retries
167                                        return Err(info_msg.into());
168                                    }
169                                }
170                                Some(cortex_client::models::job::Status::Deleted) => {
171                                    let err_msg = format!(
172                                        "Job has been deleted. Cannot fetch report. Job ID: {}",
173                                        job_id
174                                    );
175                                    eprintln!("{}", err_msg);
176                                    return Err(err_msg.into());
177                                }
178                                None => {
179                                    let warn_msg = format!("Job status is unknown. Cannot determine if report is ready. Job ID: {}", job_id);
180                                    eprintln!("{}", warn_msg);
181                                    if attempt < max_retries {
182                                        tokio::time::sleep(retry_delay).await;
183                                    } else {
184                                        let info_msg = format!("Job status remained unknown after {} attempts. Job ID: {}", max_retries, job_id);
185                                        println!("{}", info_msg);
186                                        return Err(info_msg.into());
187                                    }
188                                }
189                            }
190                        }
191                        Err(e) => {
192                            eprintln!(
193                                "\nError fetching job details on attempt {}: {:?}",
194                                attempt, e
195                            );
196                            if attempt == max_retries {
197                                let err_msg = format!("Could not fetch job details after {} attempts for job ID: {}. Error: {:?}", max_retries, job_id, e);
198                                eprintln!("{}", err_msg);
199                                return Err(err_msg.into());
200                            } else {
201                                tokio::time::sleep(retry_delay).await;
202                            }
203                        }
204                    }
205                }
206                let final_err_msg = format!(
207                    "\nCould not retrieve job report for job ID {} after {} attempts.",
208                    job_id, max_retries
209                );
210                eprintln!("{}", final_err_msg);
211                Err(final_err_msg.into())
212            } else {
213                let err_msg = "\nJob created, but no job ID was returned in the response. Cannot fetch report.".to_string();
214                eprintln!("{}", err_msg);
215                Err(err_msg.into())
216            }
217        }
218        Err(e) => {
219            let err_msg = format!(
220                "\nError creating analyzer job for '{}' on '{}': {:?}",
221                analyzer_name_for_log, observable_for_log, e
222            );
223            eprintln!("{}", err_msg);
224            Err(err_msg.into())
225        }
226    }
227}