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(ListAlertDefsRequest {}, &self.metadata_map);
237 {
238 let mut client = self.service_client.lock().await.clone();
239
240 client
241 .list_alert_defs(request)
242 .await
243 .map(|r| r.into_inner())
244 .map_err(|status| {
245 SdkError::ApiError(SdkApiError {
246 status,
247 endpoint: "/com.coralogixapis.alerts.v3.AlertDefsService/ListAlertDefs"
248 .into(),
249 feature_group: ALERTS_FEATURE_GROUP_ID.into(),
250 })
251 })
252 }
253 }
254
255 pub async fn create(&self, alert: AlertDef) -> Result<CreateAlertDefResponse> {
260 let request = make_request_with_metadata(
261 CreateAlertDefRequest {
262 alert_def_properties: alert.alert_def_properties.clone(),
263 },
264 &self.metadata_map,
265 );
266 {
267 let mut client = self.service_client.lock().await.clone();
268 let mut alert = alert;
269 if let Some(alert_def) = &mut alert.alert_def_properties {
270 let _ = self
271 .default_labels
272 .clone()
273 .into_iter()
274 .map(|(k, v)| alert_def.entity_labels.insert(k, v));
275 }
276 client
277 .create_alert_def(request)
278 .await
279 .map(|r| r.into_inner())
280 .map_err(|status| {
281 SdkError::ApiError(SdkApiError {
282 status,
283 endpoint: "/com.coralogixapis.alerts.v3.AlertDefsService/CreateAlertDef"
284 .into(),
285 feature_group: ALERTS_FEATURE_GROUP_ID.into(),
286 })
287 })
288 }
289 }
290
291 pub async fn replace(&self, alert: AlertDef) -> Result<ReplaceAlertDefResponse> {
295 let mut alert = alert;
296 if let Some(alert_def) = &mut alert.alert_def_properties {
297 let _ = self
298 .default_labels
299 .clone()
300 .into_iter()
301 .map(|(k, v)| alert_def.entity_labels.insert(k, v));
302 }
303
304 let request = make_request_with_metadata(
305 ReplaceAlertDefRequest {
306 alert_def_properties: alert.alert_def_properties,
307 id: alert.id,
308 },
309 &self.metadata_map,
310 );
311 {
312 let mut client = self.service_client.lock().await.clone();
313
314 client
315 .replace_alert_def(request)
316 .await
317 .map(|r| r.into_inner())
318 .map_err(|status| {
319 SdkError::ApiError(SdkApiError {
320 status,
321 endpoint: "/com.coralogixapis.alerts.v3.AlertDefsService/ReplaceAlertDef"
322 .into(),
323 feature_group: ALERTS_FEATURE_GROUP_ID.into(),
324 })
325 })
326 }
327 }
328
329 pub async fn delete(&self, alert_id: String) -> Result<()> {
333 let request = make_request_with_metadata(
334 DeleteAlertDefRequest { id: Some(alert_id) },
335 &self.metadata_map,
336 );
337 {
338 let mut client = self.service_client.lock().await.clone();
339 client
340 .delete_alert_def(request)
341 .await
342 .map(|_| ())
343 .map_err(|status| {
344 SdkError::ApiError(SdkApiError {
345 status,
346 endpoint: "/com.coralogixapis.alerts.v3.AlertDefsService/DeleteAlertDef"
347 .into(),
348 feature_group: ALERTS_FEATURE_GROUP_ID.into(),
349 })
350 })
351 }
352 }
353
354 pub async fn set(&self, id: String, active: bool) -> Result<()> {
359 let request = make_request_with_metadata(
360 SetActiveRequest {
361 id: Some(id),
362 active: Some(active),
363 },
364 &self.metadata_map,
365 );
366 {
367 let mut client = self.service_client.lock().await.clone();
368 client
369 .set_active(request)
370 .await
371 .map(|_| ())
372 .map_err(|status| {
373 SdkError::ApiError(SdkApiError {
374 status,
375 endpoint: "/com.coralogixapis.alerts.v3.AlertDefsService/SetActive".into(),
376 feature_group: ALERTS_FEATURE_GROUP_ID.into(),
377 })
378 })
379 }
380 }
381}
382
383fn default_label_hashmap() -> HashMap<String, String> {
384 let mut hm = HashMap::new();
385 hm.insert(SDK_VERSION_HEADER_NAME.to_string(), SDK_VERSION.to_string());
386 hm
387}