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
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}