20
20
'CABLE_LENGTH_LIST'
21
21
]
22
22
23
+ # Workaround for those fields who is defined as leaf-list in YANG model but have string value in config DB.
24
+ # Dictinary structure key = (<table_name>, <field_name>), value = seperator
25
+ LEAF_LIST_WITH_STRING_VALUE_DICT = {
26
+ ('MIRROR_SESSION' , 'src_ip' ): ',' ,
27
+ ('NTP' , 'src_intf' ): ';' ,
28
+ ('BGP_ALLOWED_PREFIXES' , 'prefixes_v4' ): ',' ,
29
+ ('BGP_ALLOWED_PREFIXES' , 'prefixes_v6' ): ',' ,
30
+ ('BUFFER_PORT_EGRESS_PROFILE_LIST' , 'profile_list' ): ',' ,
31
+ ('BUFFER_PORT_INGRESS_PROFILE_LIST' , 'profile_list' ): ',' ,
32
+ ('PORT' , 'adv_speeds' ): ',' ,
33
+ ('PORT' , 'adv_interface_types' ): ',' ,
34
+ }
35
+
23
36
"""
24
37
This is the Exception thrown out of all public function of this class.
25
38
"""
@@ -407,6 +420,11 @@ def _yangConvert(val):
407
420
# if it is a leaf-list do it for each element
408
421
if leafDict [key ]['__isleafList' ]:
409
422
vValue = list ()
423
+ if isinstance (value , str ) and (self .elementPath [0 ], self .elementPath [- 1 ]) in LEAF_LIST_WITH_STRING_VALUE_DICT :
424
+ # For field defined as leaf-list but has string value in CONFIG DB, need do special handling here. For exampe:
425
+ # port.adv_speeds in CONFIG DB has value "100,1000,10000", it shall be transferred to [100,1000,10000] as YANG value here to
426
+ # make it align with its YANG definition.
427
+ value = (x .strip () for x in value .split (LEAF_LIST_WITH_STRING_VALUE_DICT [(self .elementPath [0 ], self .elementPath [- 1 ])]))
410
428
for v in value :
411
429
vValue .append (_yangConvert (v ))
412
430
else :
@@ -545,16 +563,21 @@ def _xlateList(self, model, yang, config, table, exceptionList):
545
563
primaryKeys = list (config .keys ())
546
564
for pkey in primaryKeys :
547
565
try :
566
+ self .elementPath .append (pkey )
548
567
vKey = None
549
568
self .sysLog (syslog .LOG_DEBUG , "xlateList Extract pkey:{}" .\
550
569
format (pkey ))
551
570
# Find and extracts key from each dict in config
552
571
keyDict = self ._extractKey (pkey , listKeys )
553
572
# fill rest of the values in keyDict
554
573
for vKey in config [pkey ]:
574
+ self .elementPath .append (vKey )
555
575
self .sysLog (syslog .LOG_DEBUG , "xlateList vkey {}" .format (vKey ))
556
- keyDict [vKey ] = self ._findYangTypedValue (vKey , \
557
- config [pkey ][vKey ], leafDict )
576
+ try :
577
+ keyDict [vKey ] = self ._findYangTypedValue (vKey , \
578
+ config [pkey ][vKey ], leafDict )
579
+ finally :
580
+ self .elementPath .pop ()
558
581
yang .append (keyDict )
559
582
# delete pkey from config, done to match one key with one list
560
583
del config [pkey ]
@@ -566,6 +589,8 @@ def _xlateList(self, model, yang, config, table, exceptionList):
566
589
exceptionList .append (str (e ))
567
590
# with multilist, we continue matching other keys.
568
591
continue
592
+ finally :
593
+ self .elementPath .pop ()
569
594
570
595
return
571
596
@@ -596,13 +621,17 @@ def _xlateContainerInContainer(self, model, yang, configC, table):
596
621
if ccName not in configC :
597
622
# Inner container doesn't exist in config
598
623
return
624
+
599
625
if len (configC [ccName ]) == 0 :
600
626
# Empty container, clean config and return
601
627
del configC [ccName ]
602
628
return
603
629
self .sysLog (msg = "xlateProcessListOfContainer: {}" .format (ccName ))
630
+ self .elementPath .append (ccName )
604
631
self ._xlateContainer (ccontainer , yang [ccName ], \
605
632
configC [ccName ], table )
633
+ self .elementPath .pop ()
634
+
606
635
# clean empty container
607
636
if len (yang [ccName ]) == 0 :
608
637
del yang [ccName ]
@@ -650,8 +679,10 @@ def _xlateContainer(self, model, yang, config, table):
650
679
for vKey in vKeys :
651
680
#vkey must be a leaf\leaf-list\choice in container
652
681
if leafDict .get (vKey ):
682
+ self .elementPath .append (vKey )
653
683
self .sysLog (syslog .LOG_DEBUG , "xlateContainer vkey {}" .format (vKey ))
654
684
yang [vKey ] = self ._findYangTypedValue (vKey , configC [vKey ], leafDict )
685
+ self .elementPath .pop ()
655
686
# delete entry from copy of config
656
687
del configC [vKey ]
657
688
@@ -681,8 +712,10 @@ def _xlateConfigDBtoYang(self, jIn, yangJ):
681
712
yangJ [key ] = dict () if yangJ .get (key ) is None else yangJ [key ]
682
713
yangJ [key ][subkey ] = dict ()
683
714
self .sysLog (msg = "xlateConfigDBtoYang {}:{}" .format (key , subkey ))
715
+ self .elementPath .append (table )
684
716
self ._xlateContainer (cmap ['container' ], yangJ [key ][subkey ], \
685
717
jIn [table ], table )
718
+ self .elementPath = []
686
719
687
720
return
688
721
@@ -739,9 +772,14 @@ def _revYangConvert(val):
739
772
740
773
# if it is a leaf-list do it for each element
741
774
if leafDict [key ]['__isleafList' ]:
742
- vValue = list ()
743
- for v in value :
744
- vValue .append (_revYangConvert (v ))
775
+ if isinstance (value , list ) and (self .elementPath [0 ], self .elementPath [- 1 ]) in LEAF_LIST_WITH_STRING_VALUE_DICT :
776
+ # For field defined as leaf-list but has string value in CONFIG DB, we need do special handling here:
777
+ # e.g. port.adv_speeds is [10,100,1000] in YANG, need to convert it into a string for CONFIG DB: "10,100,1000"
778
+ vValue = LEAF_LIST_WITH_STRING_VALUE_DICT [(self .elementPath [0 ], self .elementPath [- 1 ])].join ((_revYangConvert (x ) for x in value ))
779
+ else :
780
+ vValue = list ()
781
+ for v in value :
782
+ vValue .append (_revYangConvert (v ))
745
783
elif leafDict [key ]['type' ]['@name' ] == 'boolean' :
746
784
vValue = 'true' if value else 'false'
747
785
else :
@@ -850,12 +888,16 @@ def _revXlateList(self, model, yang, config, table):
850
888
# create key of config DB table
851
889
pkey , pkeydict = self ._createKey (entry , listKeys )
852
890
self .sysLog (syslog .LOG_DEBUG , "revXlateList pkey:{}" .format (pkey ))
891
+ self .elementPath .append (pkey )
853
892
config [pkey ]= dict ()
854
893
# fill rest of the entries
855
894
for key in entry :
856
895
if key not in pkeydict :
896
+ self .elementPath .append (key )
857
897
config [pkey ][key ] = self ._revFindYangTypedValue (key , \
858
898
entry [key ], leafDict )
899
+ self .elementPath .pop ()
900
+ self .elementPath .pop ()
859
901
860
902
return
861
903
@@ -879,8 +921,10 @@ def _revXlateContainerInContainer(self, model, yang, config, table):
879
921
if yang .get (modelContainer ['@name' ]):
880
922
config [modelContainer ['@name' ]] = dict ()
881
923
self .sysLog (msg = "revXlateContainerInContainer {}" .format (modelContainer ['@name' ]))
924
+ self .elementPath .append (modelContainer ['@name' ])
882
925
self ._revXlateContainer (modelContainer , yang [modelContainer ['@name' ]], \
883
926
config [modelContainer ['@name' ]], table )
927
+ self .elementPath .pop ()
884
928
return
885
929
886
930
"""
@@ -912,7 +956,9 @@ def _revXlateContainer(self, model, yang, config, table):
912
956
#vkey must be a leaf\leaf-list\choice in container
913
957
if leafDict .get (vKey ):
914
958
self .sysLog (syslog .LOG_DEBUG , "revXlateContainer vkey {}" .format (vKey ))
959
+ self .elementPath .append (vKey )
915
960
config [vKey ] = self ._revFindYangTypedValue (vKey , yang [vKey ], leafDict )
961
+ self .elementPath .pop ()
916
962
917
963
return
918
964
@@ -940,8 +986,10 @@ def _revXlateYangtoConfigDB(self, yangJ, cDbJson):
940
986
cDbJson [table ] = dict ()
941
987
#print(key + "--" + subkey)
942
988
self .sysLog (msg = "revXlateYangtoConfigDB {}" .format (table ))
989
+ self .elementPath .append (table )
943
990
self ._revXlateContainer (cmap ['container' ], yangJ [module_top ][container ], \
944
991
cDbJson [table ], table )
992
+ self .elementPath = []
945
993
946
994
return
947
995
0 commit comments