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