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 BurnRateThreshold,
70 BurnRateTypeDual,
71 BurnRateTypeSingle,
72 DayOfWeek as AlertDayOfWeek,
73 DayOfWeek,
74 DurationUnit,
75 ErrorBudgetThreshold,
76 FlowStages,
77 FlowStagesGroup,
78 FlowStagesGroups,
79 FlowStagesGroupsAlertDefs,
80 FlowType,
81 IntegrationType,
82 LabelFilterType,
83 LabelFilters,
84 LogFilterOperationType,
85 LogSeverity,
86 LogsAnomalyCondition,
87 LogsAnomalyConditionType,
88 LogsAnomalyRule,
89 LogsAnomalyType,
90 LogsFilter,
91 LogsImmediateType,
92 LogsNewValueCondition,
93 LogsNewValueRule,
94 LogsNewValueTimeWindow,
95 LogsNewValueTimeWindowValue,
96 LogsNewValueType,
97 LogsRatioCondition,
98 LogsRatioRules,
99 LogsRatioThresholdType,
100 LogsRatioTimeWindow,
101 LogsSimpleFilter,
102 LogsThresholdCondition,
103 LogsThresholdConditionType,
104 LogsThresholdRule,
105 LogsThresholdType,
106 LogsTimeRelativeCondition,
107 LogsTimeRelativeConditionType,
108 LogsTimeRelativeRule,
109 LogsTimeRelativeThresholdType,
110 LogsTimeWindow,
111 LogsTimeWindowValue,
112 LogsUniqueCountCondition,
113 LogsUniqueCountRule,
114 LogsUniqueCountType,
115 MetricAnomalyCondition,
116 MetricAnomalyRule,
117 MetricAnomalyType,
118 MetricMissingValues,
119 MetricThresholdType,
120 MetricTimeWindow,
121 MetricTimeWindowValue,
122 NextOp,
123 NotificationDestination,
124 NotificationRouter,
125 NotifyOn,
126 Recipients,
127 SloDefinition,
128 SloThresholdCondition,
129 SloThresholdRule,
130 SloThresholdType,
131 TimeDuration,
132 TimeOfDay,
133 TimeframeType,
134 TracingFilter,
135 TracingFilterOperationType,
136 TracingImmediateType,
137 TracingSimpleFilter,
138 TracingThresholdCondition,
139 TracingThresholdRule,
140 TracingThresholdType,
141 TracingTimeWindow,
142 TracingTimeWindowValue,
143 UndetectedValuesManagement,
144 alert_def_properties::{
145 Schedule,
146 TypeDefinition,
147 },
148 alert_def_webhooks_settings::*,
149 burn_rate_threshold::Type as BurnRateThresholdType,
150 integration_type,
151 logs_filter::FilterType,
152 logs_time_window::Type as LogsTimeWindowType,
153 metric_missing_values::MissingValues,
154 slo_threshold_type::Threshold,
155};
156
157const ALERTS_FEATURE_GROUP_ID: &str = "alerts";
158
159pub enum DefaultLabels {
161 SdkVersion,
163 Custom(HashMap<String, String>),
165}
166
167pub struct AlertsClient {
171 metadata_map: MetadataMap,
172 service_client: Mutex<AlertDefsServiceClient<Channel>>,
173 default_labels: HashMap<String, String>,
174}
175
176impl AlertsClient {
177 pub fn new(
183 region: CoralogixRegion,
184 auth_context: AuthContext,
185 default_labels: Option<DefaultLabels>,
186 ) -> Result<Self> {
187 let channel: Channel = Endpoint::from_str(®ion.grpc_endpoint())?
188 .tls_config(ClientTlsConfig::new().with_native_roots())?
189 .connect_lazy();
190 let request_metadata: CallProperties = (&auth_context.team_level_api_key).into();
191
192 let default_labels: HashMap<String, String> = match default_labels.as_ref() {
193 Some(labels) => match labels {
194 DefaultLabels::SdkVersion => default_label_hashmap(),
195 DefaultLabels::Custom(hash_map) => hash_map.clone(),
196 },
197 None => HashMap::new(),
198 };
199
200 Ok(Self {
201 metadata_map: request_metadata.to_metadata_map(),
202 service_client: Mutex::new(AlertDefsServiceClient::new(channel)),
203 default_labels,
204 })
205 }
206
207 pub async fn get(&self, alert_id: String) -> Result<GetAlertDefResponse> {
212 let request = make_request_with_metadata(
213 GetAlertDefRequest { id: Some(alert_id) },
214 &self.metadata_map,
215 );
216 {
217 let mut client = self.service_client.lock().await.clone();
218
219 client
220 .get_alert_def(request)
221 .await
222 .map(|r| r.into_inner())
223 .map_err(|status| {
224 SdkError::ApiError(SdkApiError {
225 status,
226 endpoint: "/com.coralogixapis.alerts.v3.AlertDefsService/GetAlertDef"
227 .into(),
228 feature_group: ALERTS_FEATURE_GROUP_ID.into(),
229 })
230 })
231 }
232 }
233
234 pub async fn list(&self) -> Result<ListAlertDefsResponse> {
236 let request = make_request_with_metadata(
237 ListAlertDefsRequest {
238 pagination: None,
239 query_filter: None,
240 ..Default::default()
241 },
242 &self.metadata_map,
243 );
244 {
245 let mut client = self.service_client.lock().await.clone();
246
247 client
248 .list_alert_defs(request)
249 .await
250 .map(|r| r.into_inner())
251 .map_err(|status| {
252 SdkError::ApiError(SdkApiError {
253 status,
254 endpoint: "/com.coralogixapis.alerts.v3.AlertDefsService/ListAlertDefs"
255 .into(),
256 feature_group: ALERTS_FEATURE_GROUP_ID.into(),
257 })
258 })
259 }
260 }
261
262 pub async fn create(&self, alert: AlertDef) -> Result<CreateAlertDefResponse> {
267 let request = make_request_with_metadata(
268 CreateAlertDefRequest {
269 alert_def_properties: alert.alert_def_properties.clone(),
270 },
271 &self.metadata_map,
272 );
273 {
274 let mut client = self.service_client.lock().await.clone();
275 let mut alert = alert;
276 if let Some(alert_def) = &mut alert.alert_def_properties {
277 let _ = self
278 .default_labels
279 .clone()
280 .into_iter()
281 .map(|(k, v)| alert_def.entity_labels.insert(k, v));
282 }
283 client
284 .create_alert_def(request)
285 .await
286 .map(|r| r.into_inner())
287 .map_err(|status| {
288 SdkError::ApiError(SdkApiError {
289 status,
290 endpoint: "/com.coralogixapis.alerts.v3.AlertDefsService/CreateAlertDef"
291 .into(),
292 feature_group: ALERTS_FEATURE_GROUP_ID.into(),
293 })
294 })
295 }
296 }
297
298 pub async fn replace(&self, alert: AlertDef) -> Result<ReplaceAlertDefResponse> {
302 let mut alert = alert;
303 if let Some(alert_def) = &mut alert.alert_def_properties {
304 let _ = self
305 .default_labels
306 .clone()
307 .into_iter()
308 .map(|(k, v)| alert_def.entity_labels.insert(k, v));
309 }
310
311 let request = make_request_with_metadata(
312 ReplaceAlertDefRequest {
313 alert_def_properties: alert.alert_def_properties,
314 id: alert.id,
315 },
316 &self.metadata_map,
317 );
318 {
319 let mut client = self.service_client.lock().await.clone();
320
321 client
322 .replace_alert_def(request)
323 .await
324 .map(|r| r.into_inner())
325 .map_err(|status| {
326 SdkError::ApiError(SdkApiError {
327 status,
328 endpoint: "/com.coralogixapis.alerts.v3.AlertDefsService/ReplaceAlertDef"
329 .into(),
330 feature_group: ALERTS_FEATURE_GROUP_ID.into(),
331 })
332 })
333 }
334 }
335
336 pub async fn delete(&self, alert_id: String) -> Result<()> {
340 let request = make_request_with_metadata(
341 DeleteAlertDefRequest { id: Some(alert_id) },
342 &self.metadata_map,
343 );
344 {
345 let mut client = self.service_client.lock().await.clone();
346 client
347 .delete_alert_def(request)
348 .await
349 .map(|_| ())
350 .map_err(|status| {
351 SdkError::ApiError(SdkApiError {
352 status,
353 endpoint: "/com.coralogixapis.alerts.v3.AlertDefsService/DeleteAlertDef"
354 .into(),
355 feature_group: ALERTS_FEATURE_GROUP_ID.into(),
356 })
357 })
358 }
359 }
360
361 pub async fn set(&self, id: String, active: bool) -> Result<()> {
366 let request = make_request_with_metadata(
367 SetActiveRequest {
368 id: Some(id),
369 active: Some(active),
370 },
371 &self.metadata_map,
372 );
373 {
374 let mut client = self.service_client.lock().await.clone();
375 client
376 .set_active(request)
377 .await
378 .map(|_| ())
379 .map_err(|status| {
380 SdkError::ApiError(SdkApiError {
381 status,
382 endpoint: "/com.coralogixapis.alerts.v3.AlertDefsService/SetActive".into(),
383 feature_group: ALERTS_FEATURE_GROUP_ID.into(),
384 })
385 })
386 }
387 }
388}
389
390fn default_label_hashmap() -> HashMap<String, String> {
391 let mut hm = HashMap::new();
392 hm.insert(SDK_VERSION_HEADER_NAME.to_string(), SDK_VERSION.to_string());
393 hm
394}