@@ -348,64 +348,47 @@ impl Service {
348348 ) -> anyhow:: Result < ( ) > {
349349 debug ! ( "Applying config for runtime id {}" , cfg_dir. runtime_id( ) ?) ;
350350
351+ let new_configs = cfg_dir
352+ . iter ( )
353+ . map_err ( |e| {
354+ let any_error = e. context ( "Failed to start iteration over configs" ) ;
355+ self . log_general_rc_error ( & any_error) ;
356+ any_error
357+ } ) ?
358+ . map ( |res_cfg| {
359+ res_cfg
360+ . map_err ( |e| {
361+ let any_error = e. context ( "Failure during config iteration" ) ;
362+ self . log_general_rc_error ( & any_error) ;
363+ any_error
364+ } )
365+ . map ( |cfg| cfg. rc_path ( ) . clone ( ) )
366+ } )
367+ . collect :: < Result < HashSet < _ > , anyhow:: Error > > ( ) ?;
368+
351369 let mut new_snapshot = ( * * self . config_snapshot . load ( ) ) . clone ( ) ;
352- let mut new_configs = HashSet :: new ( ) ;
353370 let mut waf_changed = false ;
354371 let mut all_diagnostics = Vec :: new ( ) ;
355372 let mut rules_version: Option < String > = None ;
356373
357- let maybe_cfg_iter = cfg_dir. iter ( ) ;
358- match maybe_cfg_iter {
359- Ok ( cfg_iter) => {
360- for maybe_cfg in cfg_iter {
361- // Handle each new/updated config
362- let cfg = maybe_cfg?;
363- let rc_path = cfg. rc_path ( ) ;
364- new_configs. insert ( rc_path. to_string ( ) ) ;
365-
366- let result = self . apply_config_file (
367- & cfg,
368- rc_path,
369- state,
370- & mut all_diagnostics,
371- & mut rules_version,
372- & mut new_snapshot,
373- & mut waf_changed,
374- ) ;
375- if let Err ( e) = result {
376- self . log_product_rc_error ( rc_path, & self . logs_collector , e) ;
377- }
378- }
379- }
380- Err ( e) => {
381- self . log_general_rc_error ( e. context ( "Failed to iterate over configs" ) ) ;
382- }
383- }
384-
385- for maybe_cfg in cfg_dir. iter ( ) ? {
386- let cfg = maybe_cfg?;
387- let rc_path = cfg. rc_path ( ) ;
388- new_configs. insert ( rc_path. to_string ( ) ) ;
389- }
390-
391374 // Handle removal of configs
392375 for old_path in state. last_configs . difference ( & new_configs) {
393- if old_path. contains ( "/ASM_FEATURES/" ) {
376+ if old_path. as_str ( ) . contains ( "/ASM_FEATURES/" ) {
394377 state. asm_feature_config_manager . remove ( old_path) ;
395378 } else {
396- let res = self . waf . remove_config ( old_path) ;
379+ let res = self . waf . remove_config ( old_path. as_str ( ) ) ;
397380 match res {
398381 Ok ( true ) => {
399- debug ! ( "Removed WAF config: {}" , old_path) ;
382+ debug ! ( "Removed WAF config: {:? }" , old_path) ;
400383 waf_changed = true ;
401384 }
402385 Ok ( false ) => {
403- warning ! ( "No WAF config found to remove: {}" , old_path) ;
386+ warning ! ( "No WAF config found to remove: {:? }" , old_path) ;
404387 }
405388 Err ( e) => {
406- self . log_general_rc_error ( e. context ( format ! (
389+ self . log_general_rc_error ( & e. context ( format ! (
407390 concat!(
408- "Failed to remove WAF config {}; " ,
391+ "Failed to remove WAF config {:? }; " ,
409392 "this should happen only when reading the default config"
410393 ) ,
411394 old_path
@@ -414,6 +397,28 @@ impl Service {
414397 }
415398 }
416399 }
400+
401+ // cfg_dir iteration worked above, so it will presumably work here too
402+ let cfg_iter = cfg_dir. iter ( ) ?;
403+ for maybe_cfg in cfg_iter {
404+ // Handle each config in the new config directory
405+ let cfg = maybe_cfg?;
406+ let rc_path = cfg. rc_path ( ) ;
407+
408+ let result = self . apply_config_file (
409+ & cfg,
410+ rc_path,
411+ state,
412+ & mut all_diagnostics,
413+ & mut rules_version,
414+ & mut new_snapshot,
415+ & mut waf_changed,
416+ ) ;
417+ if let Err ( e) = result {
418+ self . log_product_rc_error ( rc_path, & self . logs_collector , e) ;
419+ }
420+ }
421+
417422 state. last_configs = new_configs;
418423
419424 // Telemetry waf.config_errors metrics and telemetry logs - always process
@@ -445,7 +450,7 @@ impl Service {
445450 }
446451 Err ( e) => {
447452 self . log_general_rc_error (
448- e. context ( "Failed to rebuild WAF after config update" ) ,
453+ & e. context ( "Failed to rebuild WAF after config update" ) ,
449454 ) ;
450455 false
451456 }
@@ -496,19 +501,24 @@ impl Service {
496501 fn apply_config_file (
497502 & self ,
498503 cfg : & rc:: Config ,
499- rc_path : & str ,
504+ rc_path : & rc :: RcPath ,
500505 state : & mut RcUpdateState ,
501506 all_diagnostics : & mut Vec < (
502- String ,
507+ rc :: RcPath ,
503508 libddwaf:: object:: WafOwnedDefaultAllocator < libddwaf:: object:: WafMap > ,
504509 ) > ,
505510 rules_version : & mut Option < String > ,
506511 new_snapshot : & mut ConfigSnapshot ,
507512 waf_changed : & mut bool ,
508513 ) -> anyhow:: Result < ( ) > {
509514 let product = cfg. product ( ) ;
515+ if state. last_configs . contains ( rc_path) {
516+ debug ! ( "Config already applied on previous update: {:?}" , rc_path) ;
517+ return Ok ( ( ) ) ;
518+ }
519+
510520 debug ! (
511- "Processing config: rc_path={}, product={}" ,
521+ "Processing config: rc_path={:? }, product={}" ,
512522 rc_path,
513523 product. name( )
514524 ) ;
@@ -518,33 +528,35 @@ impl Service {
518528 let data = unsafe { shmem. as_slice ( ) } ;
519529 state
520530 . asm_feature_config_manager
521- . add ( rc_path. to_string ( ) , data) ?;
531+ . add ( rc_path. as_str ( ) . to_string ( ) , data) ?;
522532 Ok ( ( ) )
523533 }
524534 "ASM_DD" | "ASM" | "ASM_DATA" => {
525535 let shmem = cfg. read ( ) ?;
526536 let data = unsafe { shmem. as_slice ( ) } ;
527537
528538 let ruleset = waf_ruleset:: WafRuleset :: from_slice ( data)
529- . with_context ( || format ! ( "Failed to parse WAF config for {}" , rc_path) ) ?;
539+ . with_context ( || format ! ( "Failed to parse WAF config for {:? }" , rc_path) ) ?;
530540
531541 let waf_obj: libddwaf:: object:: WafObject = ruleset. into ( ) ;
532542 let mut diagnostics = Default :: default ( ) ;
533543
534- let upd_result =
535- self . waf
536- . add_or_update_config ( rc_path, & waf_obj, Some ( & mut diagnostics) ) ;
544+ let upd_result = self . waf . add_or_update_config (
545+ rc_path. as_str ( ) ,
546+ & waf_obj,
547+ Some ( & mut diagnostics) ,
548+ ) ;
537549
538550 if upd_result. is_ok ( ) {
539- debug ! ( "Added/updated WAF config: {}" , rc_path) ;
551+ debug ! ( "Added/updated WAF config: {:? }" , rc_path) ;
540552 if product. name ( ) == "ASM_DD" {
541553 * rules_version = waf_diag:: extract_ruleset_version ( & diagnostics) ;
542554 * new_snapshot = new_snapshot. with_new_rules_version ( rules_version. clone ( ) ) ;
543555 }
544556 * waf_changed = true ;
545557 }
546558
547- all_diagnostics. push ( ( rc_path. to_string ( ) , diagnostics) ) ;
559+ all_diagnostics. push ( ( rc_path. clone ( ) , diagnostics) ) ;
548560 upd_result
549561 }
550562 _ => {
@@ -556,12 +568,12 @@ impl Service {
556568
557569 fn log_product_rc_error (
558570 & self ,
559- rc_path : & str ,
571+ rc_path : & rc :: RcPath ,
560572 logs_submitter : & TelemetryLogsCollector ,
561573 error : anyhow:: Error ,
562574 ) {
563575 let message = format ! (
564- "Failed to apply config {} in service with config {:?}: {:#}" ,
576+ "Failed to apply config {:? } in service with config {:?}: {:#}" ,
565577 rc_path, self . fixed_config, error
566578 ) ;
567579
@@ -589,13 +601,13 @@ impl Service {
589601 } ) ;
590602 } else {
591603 error ! (
592- "Can't parse RC path: {}; no submission of telemetry log" ,
604+ "Can't parse RC path: {:? }; no submission of telemetry log" ,
593605 rc_path
594606 ) ;
595607 }
596608 }
597609
598- fn log_general_rc_error ( & self , error : anyhow:: Error ) {
610+ fn log_general_rc_error ( & self , error : & anyhow:: Error ) {
599611 let message = format ! (
600612 "Failed to apply config for service with config {:?}: {:#}" ,
601613 self . fixed_config, error
@@ -755,7 +767,7 @@ impl ServiceManagerInner {
755767
756768struct RcUpdateState {
757769 poller : Option < rc:: ConfigPoller > ,
758- last_configs : HashSet < String > ,
770+ last_configs : HashSet < rc :: RcPath > ,
759771 asm_feature_config_manager : AsmFeatureConfigManager ,
760772 pending_telemetry_metrics : TelemetryMetricsCollector ,
761773 pending_init_diagnostics_legacy : Option < InitDiagnosticsLegacy > ,
0 commit comments