@@ -24,6 +24,7 @@ use std::{
2424
2525use async_trait:: async_trait;
2626use base64:: Engine ;
27+ use bytes:: Bytes ;
2728use chrono:: Utc ;
2829use http:: { header:: AUTHORIZATION , HeaderMap , HeaderValue } ;
2930use humantime_serde:: re:: humantime;
@@ -35,7 +36,7 @@ use tracing::{error, trace, warn};
3536use ulid:: Ulid ;
3637use url:: Url ;
3738
38- use crate :: { alerts:: AlertError , parseable:: PARSEABLE } ;
39+ use crate :: { alerts:: AlertError , parseable:: PARSEABLE , storage :: object_storage :: target_json_path } ;
3940
4041use super :: ALERTS ;
4142
@@ -65,7 +66,12 @@ impl TargetConfigs {
6566
6667 pub async fn update ( & self , target : Target ) -> Result < ( ) , AlertError > {
6768 let id = target. id ;
68- self . target_configs . write ( ) . await . insert ( id, target) ;
69+ self . target_configs . write ( ) . await . insert ( id, target. clone ( ) ) ;
70+ let path = target_json_path ( & id) ;
71+
72+ let store = PARSEABLE . storage . get_object_store ( ) ;
73+ let target_bytes = serde_json:: to_vec ( & target) ?;
74+ store. put_object ( & path, Bytes :: from ( target_bytes) ) . await ?;
6975 Ok ( ( ) )
7076 }
7177
@@ -81,12 +87,20 @@ impl TargetConfigs {
8187 }
8288
8389 pub async fn get_target_by_id ( & self , target_id : & Ulid ) -> Result < Target , AlertError > {
84- self . target_configs
90+ let target = self
91+ . target_configs
8592 . read ( )
8693 . await
8794 . get ( target_id)
8895 . ok_or ( AlertError :: InvalidTargetID ( target_id. to_string ( ) ) )
89- . cloned ( )
96+ . cloned ( ) ?;
97+
98+ let path = target_json_path ( & target. id ) ;
99+
100+ let store = PARSEABLE . storage . get_object_store ( ) ;
101+ store. delete_object ( & path) . await ?;
102+
103+ Ok ( target)
90104 }
91105
92106 pub async fn delete ( & self , target_id : & Ulid ) -> Result < Target , AlertError > {
@@ -98,7 +112,7 @@ impl TargetConfigs {
98112 }
99113}
100114
101- #[ derive( Debug , Clone , Copy , serde:: Serialize , serde:: Deserialize ) ]
115+ #[ derive( Debug , Clone , Copy , serde:: Serialize , serde:: Deserialize , PartialEq ) ]
102116#[ serde( rename_all = "camelCase" ) ]
103117#[ serde( untagged) ]
104118pub enum Retry {
@@ -125,9 +139,19 @@ pub struct Target {
125139}
126140
127141impl Target {
128- pub async fn validate ( & self ) {
142+ pub async fn validate ( & self ) -> Result < ( ) , AlertError > {
129143 // just check for liveness
130144 // what if the target is not live yet but is added by the user?
145+ let targets = TARGETS . list ( ) . await ?;
146+ for target in targets {
147+ if target. target == self . target
148+ && target. timeout . interval == self . timeout . interval
149+ && target. timeout . times == self . timeout . times
150+ {
151+ return Err ( AlertError :: DuplicateTargetConfig ) ;
152+ }
153+ }
154+ Ok ( ( ) )
131155 }
132156
133157 pub fn call ( & self , context : Context ) {
0 commit comments