@@ -366,6 +366,9 @@ def create_xpath(self, tokens):
366
366
367
367
return f"{ PathAddressing .XPATH_SEPARATOR } { PathAddressing .XPATH_SEPARATOR .join (str (t ) for t in tokens )} "
368
368
369
+ def _create_sonic_yang_with_loaded_models (self ):
370
+ return self .config_wrapper .create_sonic_yang_with_loaded_models ()
371
+
369
372
def find_ref_paths (self , path , config ):
370
373
"""
371
374
Finds the paths referencing any line under the given 'path' within the given 'config'.
@@ -407,7 +410,7 @@ def find_ref_paths(self, path, config):
407
410
return self ._find_leafref_paths (path , config )
408
411
409
412
def _find_leafref_paths (self , path , config ):
410
- sy = self .config_wrapper . create_sonic_yang_with_loaded_models ()
413
+ sy = self ._create_sonic_yang_with_loaded_models ()
411
414
412
415
tmp_config = copy .deepcopy (config )
413
416
@@ -553,6 +556,13 @@ def _get_xpath_tokens_from_leaf(self, model, token_index, path_tokens, config):
553
556
# /module-name:container/leaf-list[.='val']
554
557
# Source: Check examples in https://netopeer.liberouter.org/doc/libyang/master/html/howto_x_path.html
555
558
return [f"{ token } [.='{ value } ']" ]
559
+
560
+ # checking 'uses' statement
561
+ if not isinstance (config [token ], list ): # leaf-list under uses is not supported yet in sonic_yang
562
+ table = path_tokens [0 ]
563
+ uses_leaf_model = self ._get_uses_leaf_model (model , table , token )
564
+ if uses_leaf_model :
565
+ return [token ]
556
566
557
567
raise ValueError (f"Path token not found.\n model: { model } \n token_index: { token_index } \n " + \
558
568
f"path_tokens: { path_tokens } \n config: { config } " )
@@ -719,6 +729,13 @@ def _get_path_tokens_from_leaf(self, model, token_index, xpath_tokens, config):
719
729
list_idx = list_config .index (leaf_list_value )
720
730
return [leaf_list_name , list_idx ]
721
731
732
+ # checking 'uses' statement
733
+ if not isinstance (config [leaf_list_name ], list ): # leaf-list under uses is not supported yet in sonic_yang
734
+ table = xpath_tokens [1 ]
735
+ uses_leaf_model = self ._get_uses_leaf_model (model , table , token )
736
+ if uses_leaf_model :
737
+ return [token ]
738
+
722
739
raise ValueError (f"Xpath token not found.\n model: { model } \n token_index: { token_index } \n " + \
723
740
f"xpath_tokens: { xpath_tokens } \n config: { config } " )
724
741
@@ -754,6 +771,45 @@ def _get_model(self, model, name):
754
771
755
772
return None
756
773
774
+ def _get_uses_leaf_model (self , model , table , token ):
775
+ """
776
+ Getting leaf model in uses model matching the given token.
777
+ """
778
+ uses_s = model .get ('uses' )
779
+ if not uses_s :
780
+ return None
781
+
782
+ # a model can be a single dict or a list of dictionaries, unify to a list of dictionaries
783
+ if not isinstance (uses_s , list ):
784
+ uses_s = [uses_s ]
785
+
786
+ sy = self ._create_sonic_yang_with_loaded_models ()
787
+ # find yang module for current table
788
+ table_module = sy .confDbYangMap [table ]['yangModule' ]
789
+ # uses Example: "@name": "bgpcmn:sonic-bgp-cmn"
790
+ for uses in uses_s :
791
+ if not isinstance (uses , dict ):
792
+ raise GenericConfigUpdaterError (f"'uses' is expected to be a dictionary found '{ type (uses )} '.\n " \
793
+ f" uses: { uses } \n model: { model } \n table: { table } \n token: { token } " )
794
+
795
+ # Assume ':' means reference to another module
796
+ if ':' in uses ['@name' ]:
797
+ name_parts = uses ['@name' ].split (':' )
798
+ prefix = name_parts [0 ].strip ()
799
+ uses_module_name = sy ._findYangModuleFromPrefix (prefix , table_module )
800
+ grouping = name_parts [- 1 ].strip ()
801
+ else :
802
+ uses_module_name = table_module ['@name' ]
803
+ grouping = uses ['@name' ]
804
+
805
+ leafs = sy .preProcessedYang ['grouping' ][uses_module_name ][grouping ]
806
+
807
+ leaf_model = self ._get_model (leafs , token )
808
+ if leaf_model :
809
+ return leaf_model
810
+
811
+ return None
812
+
757
813
class TitledLogger (logger .Logger ):
758
814
def __init__ (self , syslog_identifier , title , verbose , print_all_to_console ):
759
815
super ().__init__ (syslog_identifier )
0 commit comments