1use crate::error::{
16 SdkApiError,
17 SdkError,
18};
19use crate::{
20 CoralogixRegion,
21 auth::AuthContext,
22 error::Result,
23 metadata::CallProperties,
24 util::make_request_with_metadata,
25};
26use crate::{
27 SDK_VERSION,
28 SDK_VERSION_HEADER_NAME,
29};
30use cx_api::proto::com::coralogixapis::alerts::v3::alert_defs_service_client::AlertDefsServiceClient;
31use cx_api::proto::com::coralogixapis::alerts::v3::{
32 CreateAlertDefRequest,
33 CreateAlertDefResponse,
34 DeleteAlertDefRequest,
35 GetAlertDefRequest,
36 GetAlertDefResponse,
37 ListAlertDefsRequest,
38 ListAlertDefsResponse,
39 ReplaceAlertDefRequest,
40 ReplaceAlertDefResponse,
41 SetActiveRequest,
42};
43
44use std::collections::HashMap;
45use std::str::FromStr;
46use tokio::sync::Mutex;
47use tonic::{
48 metadata::MetadataMap,
49 transport::{
50 Channel,
51 ClientTlsConfig,
52 Endpoint,
53 },
54};
55
56pub use cx_api::proto::com::coralogixapis::alerts::v3::{
57 ActivitySchedule,
58 ActivitySchedule as AlertDefActivitySchedule,
59 AlertDef,
60 AlertDefIncidentSettings,
61 AlertDefNotificationGroup,
62 AlertDefOverride,
63 AlertDefPriority,
64 AlertDefProperties,
65 AlertDefType,
66 AlertDefWebhooksSettings,
67 AlertsOp,
68 AutoRetireTimeframe,
69 DayOfWeek as AlertDayOfWeek,
70 DayOfWeek,
71 FlowStages,
72 FlowStagesGroup,
73 FlowStagesGroups,
74 FlowStagesGroupsAlertDefs,
75 FlowType,
76 IntegrationType,
77 LabelFilterType,
78 LabelFilters,
79 LogFilterOperationType,
80 LogSeverity,
81 LogsAnomalyCondition,
82 LogsAnomalyConditionType,
83 LogsAnomalyRule,
84 LogsAnomalyType,
85 LogsFilter,
86 LogsImmediateType,
87 LogsNewValueCondition,
88 LogsNewValueRule,
89 LogsNewValueTimeWindow,
90 LogsNewValueTimeWindowValue,
91 LogsNewValueType,
92 LogsRatioCondition,
93 LogsRatioRules,
94 LogsRatioThresholdType,
95 LogsRatioTimeWindow,
96 LogsSimpleFilter,
97 LogsThresholdCondition,
98 LogsThresholdConditionType,
99 LogsThresholdRule,
100 LogsThresholdType,
101 LogsTimeRelativeCondition,
102 LogsTimeRelativeConditionType,
103 LogsTimeRelativeRule,
104 LogsTimeRelativeThresholdType,
105 LogsTimeWindow,
106 LogsTimeWindowValue,
107 LogsUniqueCountCondition,
108 LogsUniqueCountRule,
109 LogsUniqueCountType,
110 MetricAnomalyCondition,
111 MetricAnomalyRule,
112 MetricAnomalyType,
113 MetricMissingValues,
114 MetricThresholdType,
115 MetricTimeWindow,
116 MetricTimeWindowValue,
117 NextOp,
118 NotificationDestination,
119 NotificationRouter,
120 NotifyOn,
121 Recipients,
122 TimeOfDay,
123 TimeframeType,
124 TracingFilter,
125 TracingFilterOperationType,
126 TracingImmediateType,
127 TracingSimpleFilter,
128 TracingThresholdCondition,
129 TracingThresholdRule,
130 TracingThresholdType,
131 TracingTimeWindow,
132 TracingTimeWindowValue,
133 UndetectedValuesManagement,
134 alert_def_properties::{
135 Schedule,
136 TypeDefinition,
137 },
138 alert_def_webhooks_settings::*,
139 integration_type,
140 logs_filter::FilterType,
141 logs_time_window::Type as LogsTimeWindowType,
142 metric_missing_values::MissingValues,
143};
144
145const ALERTS_FEATURE_GROUP_ID: &str = "alerts";
146
147pub enum DefaultLabels {
149 SdkVersion,
151 Custom(HashMap<String, String>),
153}
154
155pub struct AlertsClient {
159 metadata_map: MetadataMap,
160 service_client: Mutex<AlertDefsServiceClient<Channel>>,
161 default_labels: HashMap<String, String>,
162}
163
164impl AlertsClient {
165 pub fn new(
171 region: CoralogixRegion,
172 auth_context: AuthContext,
173 default_labels: Option<DefaultLabels>,
174 ) -> Result<Self> {
175 let channel: Channel = Endpoint::from_str(®ion.grpc_endpoint())?
176 .tls_config(ClientTlsConfig::new().with_native_roots())?
177 .connect_lazy();
178 let request_metadata: CallProperties = (&auth_context.team_level_api_key).into();
179
180 let default_labels: HashMap<String, String> = match default_labels.as_ref() {
181 Some(labels) => match labels {
182 DefaultLabels::SdkVersion => default_label_hashmap(),
183 DefaultLabels::Custom(hash_map) => hash_map.clone(),
184 },
185 None => HashMap::new(),
186 };
187
188 Ok(Self {
189 metadata_map: request_metadata.to_metadata_map(),
190 service_client: Mutex::new(AlertDefsServiceClient::new(channel)),
191 default_labels,
192 })
193 }
194
195 pub async fn get(&self, alert_id: String) -> Result<GetAlertDefResponse> {
200 let request = make_request_with_metadata(
201 GetAlertDefRequest { id: Some(alert_id) },
202 &self.metadata_map,
203 );
204 {
205 let mut client = self.service_client.lock().await.clone();
206
207 client
208 .get_alert_def(request)
209 .await
210 .map(|r| r.into_inner())
211 .map_err(|status| {
212 SdkError::ApiError(SdkApiError {
213 status,
214 endpoint: "/com.coralogixapis.alerts.v3.AlertDefsService/GetAlertDef"
215 .into(),
216 feature_group: ALERTS_FEATURE_GROUP_ID.into(),
217 })
218 })
219 }
220 }
221
222 pub async fn list(&self) -> Result<ListAlertDefsResponse> {
224 let request = make_request_with_metadata(ListAlertDefsRequest {}, &self.metadata_map);
225 {
226 let mut client = self.service_client.lock().await.clone();
227
228 client
229 .list_alert_defs(request)
230 .await
231 .map(|r| r.into_inner())
232 .map_err(|status| {
233 SdkError::ApiError(SdkApiError {
234 status,
235 endpoint: "/com.coralogixapis.alerts.v3.AlertDefsService/ListAlertDefs"
236 .into(),
237 feature_group: ALERTS_FEATURE_GROUP_ID.into(),
238 })
239 })
240 }
241 }
242
243 pub async fn create(&self, alert: AlertDef) -> Result<CreateAlertDefResponse> {
248 let request = make_request_with_metadata(
249 CreateAlertDefRequest {
250 alert_def_properties: alert.alert_def_properties.clone(),
251 },
252 &self.metadata_map,
253 );
254 {
255 let mut client = self.service_client.lock().await.clone();
256 let mut alert = alert;
257 if let Some(alert_def) = &mut alert.alert_def_properties {
258 let _ = self
259 .default_labels
260 .clone()
261 .into_iter()
262 .map(|(k, v)| alert_def.entity_labels.insert(k, v));
263 }
264 client
265 .create_alert_def(request)
266 .await
267 .map(|r| r.into_inner())
268 .map_err(|status| {
269 SdkError::ApiError(SdkApiError {
270 status,
271 endpoint: "/com.coralogixapis.alerts.v3.AlertDefsService/CreateAlertDef"
272 .into(),
273 feature_group: ALERTS_FEATURE_GROUP_ID.into(),
274 })
275 })
276 }
277 }
278
279 pub async fn replace(&self, alert: AlertDef) -> Result<ReplaceAlertDefResponse> {
283 let mut alert = alert;
284 if let Some(alert_def) = &mut alert.alert_def_properties {
285 let _ = self
286 .default_labels
287 .clone()
288 .into_iter()
289 .map(|(k, v)| alert_def.entity_labels.insert(k, v));
290 }
291
292 let request = make_request_with_metadata(
293 ReplaceAlertDefRequest {
294 alert_def_properties: alert.alert_def_properties,
295 id: alert.id,
296 },
297 &self.metadata_map,
298 );
299 {
300 let mut client = self.service_client.lock().await.clone();
301
302 client
303 .replace_alert_def(request)
304 .await
305 .map(|r| r.into_inner())
306 .map_err(|status| {
307 SdkError::ApiError(SdkApiError {
308 status,
309 endpoint: "/com.coralogixapis.alerts.v3.AlertDefsService/ReplaceAlertDef"
310 .into(),
311 feature_group: ALERTS_FEATURE_GROUP_ID.into(),
312 })
313 })
314 }
315 }
316
317 pub async fn delete(&self, alert_id: String) -> Result<()> {
321 let request = make_request_with_metadata(
322 DeleteAlertDefRequest { id: Some(alert_id) },
323 &self.metadata_map,
324 );
325 {
326 let mut client = self.service_client.lock().await.clone();
327 client
328 .delete_alert_def(request)
329 .await
330 .map(|_| ())
331 .map_err(|status| {
332 SdkError::ApiError(SdkApiError {
333 status,
334 endpoint: "/com.coralogixapis.alerts.v3.AlertDefsService/DeleteAlertDef"
335 .into(),
336 feature_group: ALERTS_FEATURE_GROUP_ID.into(),
337 })
338 })
339 }
340 }
341
342 pub async fn set(&self, id: String, active: bool) -> Result<()> {
347 let request = make_request_with_metadata(
348 SetActiveRequest {
349 id: Some(id),
350 active: Some(active),
351 },
352 &self.metadata_map,
353 );
354 {
355 let mut client = self.service_client.lock().await.clone();
356 client
357 .set_active(request)
358 .await
359 .map(|_| ())
360 .map_err(|status| {
361 SdkError::ApiError(SdkApiError {
362 status,
363 endpoint: "/com.coralogixapis.alerts.v3.AlertDefsService/SetActive".into(),
364 feature_group: ALERTS_FEATURE_GROUP_ID.into(),
365 })
366 })
367 }
368 }
369}
370
371fn default_label_hashmap() -> HashMap<String, String> {
372 let mut hm = HashMap::new();
373 hm.insert(SDK_VERSION_HEADER_NAME.to_string(), SDK_VERSION.to_string());
374 hm
375}