From af3dea221eed43b4b25fb4938e5a4805a9730c08 Mon Sep 17 00:00:00 2001 From: faraazbrcm <52159605+faraazbrcm@users.noreply.github.com> Date: Mon, 4 Sep 2023 13:44:35 +0530 Subject: [PATCH 1/5] Enhanced Rule#18 to disallow LISTs with over-lapping List keys It is observed that guideline does not describe the rules for YANG list keys. Added rules to make YANG LIST unique. --- doc/mgmt/SONiC_YANG_Model_Guidelines.md | 222 ++++++++++++++++++++---- 1 file changed, 191 insertions(+), 31 deletions(-) diff --git a/doc/mgmt/SONiC_YANG_Model_Guidelines.md b/doc/mgmt/SONiC_YANG_Model_Guidelines.md index a2d7127dad6..a39e4ce9090 100644 --- a/doc/mgmt/SONiC_YANG_Model_Guidelines.md +++ b/doc/mgmt/SONiC_YANG_Model_Guidelines.md @@ -8,6 +8,7 @@ |:---:|:-----------:|:------------------:|-----------------------------------| | 1.0 | 22 Aug 2019 | Praveen Chaudhary | Initial version | | 1.0 | 11 Sep 2019 | Partha Dutta | Adding additional steps for SONiC YANG | + | 1.1 | 04 Sep 2023 | Mohammed Faraaz | Added rules for List Keys | ## References | References | Date/Version | Link | @@ -44,7 +45,7 @@ sonic-vlan.yang Example : #### YANG -``` +```yang module sonic-acl { container sonic-acl { ..... @@ -57,7 +58,7 @@ module sonic-acl { Example : #### YANG -``` +```yang module sonic-acl { namespace "http://github.com/Azure/sonic-acl"; ..... @@ -70,7 +71,7 @@ module sonic-acl { Example : #### YANG -``` +```yang module sonic-acl { revision 2019-09-02 { description @@ -92,7 +93,7 @@ Example: Table VLAN will translate to container VLAN. #### ABNF -``` +```yang "VLAN": { "Vlan100": { "vlanid": "100" @@ -103,7 +104,7 @@ will translate to: #### YANG -- -``` +```yang container VLAN { //"VLAN" mapped to a container list VLAN_LIST { key name; @@ -132,7 +133,7 @@ Leaf names are same PACKET_ACTION, IP_TYPE and PRIORITY, which are defined in AB ``` #### YANG -``` +```yang leaf PACKET_ACTION { ..... } @@ -148,7 +149,7 @@ Leaf names are same PACKET_ACTION, IP_TYPE and PRIORITY, which are defined in AB Example: #### YANG -``` +```yang leaf SRC_IP { type inet:ipv4-prefix; <<<< } @@ -182,7 +183,7 @@ For Example: ``` #### YANG In YANG, "Family" of VLAN_INTERFACE and "IP_TYPE" of ACL_RULE is at same level. -``` +```yang container VLAN_INTERFACE { description "VLAN_INTERFACE part of config_db.json"; list VLAN_INTERFACE_LIST { @@ -222,7 +223,7 @@ Example: VLAN_MEMBER dictionary in ABNF.json has both vlan-id and ifname part of key = VLAN_MEMBER_TABLE:"Vlan"vlanid:ifname ; #### YANG -``` +```yang container VLAN_MEMBER { description "VLAN_MEMBER part of config_db.json"; list ..... { @@ -242,7 +243,7 @@ key: ACL_RULE_TABLE:table_name:rule_name ..... ``` #### YANG -``` +```yang ..... container ACL_TABLE { list ACL_TABLE_LIST { @@ -289,7 +290,7 @@ queue = 1*DIGIT; queue index ``` #### YANG -``` +```yang container TC_TO_QUEUE_MAP { list TC_TO_QUEUE_MAP_LIST { key "name"; @@ -336,7 +337,7 @@ wred_profile = ref_hash_key_reference; reference to wred profile key ``` #### YANG -``` +```yang container sonic-queue { container QUEUE { list QUEUE_LIST { @@ -361,7 +362,7 @@ container sonic-queue { Example: #### YANG -``` +```yang must "(/sonic-ext:operation/sonic-ext:operation != 'DELETE') or " + "count(../../ACL_TABLE[aclname=current()]/ports) = 0" { error-message "Ports are already bound to this rule."; @@ -373,7 +374,7 @@ Example: Example: #### YANG -``` +```yang module sonic-vlan { .... .... @@ -422,7 +423,7 @@ Example of When Statement: Orchagent of SONiC will have unknown behavior if belo ``` #### YANG: -``` +```yang choice ip_prefix { case ip4_prefix { when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV4' or .='IPV4ANY' or .='ARP'])"; @@ -456,7 +457,7 @@ leaf L4_DST_PORT_RANGE { Example: #### YANG -``` +```yang leaf family { /* family leaf needed for backward compatibility Both ip4 and ip6 address are string in IETF RFC 6020, @@ -485,7 +486,7 @@ For Example: Below entries in PORTCHANNEL_INTERFACE Table must be part of List O ``` #### YANG -``` +```yang container PORTCHANNEL_INTERFACE { description "PORTCHANNEL_INTERFACE part of config_db.json"; @@ -497,9 +498,17 @@ container PORTCHANNEL_INTERFACE { } ``` -### 18. In some cases it may be required to split an ABNF table into multiple YANG lists based on the data stored in the ABNF table. +### 18. In some cases it may be required to split an ABNF table into multiple YANG lists based on the data stored in the ABNF table. In this case it is crucial to ensure that the List keys are non-overlapping, unique, and unambiguous. -Example : "INTERFACE" table stores VRF names to which an interface belongs, also it stores IP address of each interface. Hence it is needed to split them into two different YANG lists. +#### Strategies for Ensuring Unique and Unambiguous Keys + +1. **Composite Keys with Different Number of Elements**: Utilize composite keys that have a different number of key elements to distinguish lists. + +2. **Different Data Types with Constraints**: Use constraints like length, pattern, or range to make keys of different data types non-overlapping. + +3. **Pattern Constraints**: Implement regular expressions to define specific patterns that keys must match. + +4. **Length and Range Constraints**: Limit the length of strings or the range of integers to make them unique. #### ABNF ``` @@ -511,8 +520,11 @@ Example : "INTERFACE" table stores VRF names to which an interface belongs, also } } ``` -#### YANG -``` +#### Example 1: Composite Keys with Different Number of Elements(Allowed case) + +`INTERFACE` table stores VRF names to which an interface belongs, also it stores IP address of each interface. Hence it is needed to split them into two different YANG lists. + +```yang ...... container sonic-interface { container INTERFACE { @@ -550,12 +562,166 @@ container sonic-interface { ...... ``` +#### Example 2: Composite Keys with Same Number of Elements(NOT Allowed case) + +```yang +...... +container sonic-interface { + container INTERFACE { + list INTERFACE_LIST { // 1st list + key ifname; + leaf ifname { + type string; + } + // ... + } + + list INTERFACE_ANOTHER_LIST { // Negative case + key ifname; + leaf ifname { + type string; + } + // ... + } + } +} +...... +``` + +#### Example 3: Pattern Constraints (Allowed case) + +In this example, `INTERFACE_LIST` uses a key `ifname` that must start with "Eth", while `INTERFACE_IPADDR_LIST` uses a key `ifname` that must start with "Vlan". + +```yang +...... +container sonic-interface { + container INTERFACE { + list INTERFACE_LIST { // 1st list + key ifname; + leaf ifname { + type string { + pattern "Eth.*"; + } + } + // ... + } + + list INTERFACE_IPADDR_LIST { // 2nd list + key "ifname ip_addr"; + leaf ifname { + type string { + pattern "Vlan.*"; + } + } + // ... + } + } +} +...... +``` + +#### Example 4: Pattern Constraints (NOT Allowed case) + +Here, both INTERFACE_LIST and INTERFACE_ANOTHER_LIST use a key ifname with the same pattern constraint, making them potentially overlapping and ambiguous. + +```yang +...... +container sonic-interface { + container INTERFACE { + list INTERFACE_LIST { // 1st list + key ifname; + leaf ifname { + type string { + pattern "Eth.*"; + } + } + // ... + } + + list INTERFACE_ANOTHER_LIST { // Negative case + key ifname; + leaf ifname { + type string { + pattern "Eth.*"; + } + } + // ... + } + } +} +...... +``` + +#### Example 5: Length Constraints (Allowed case) + +In this example, `INTERFACE_LIST` uses a key ifname that must be exactly 3 characters long, while `INTERFACE_IPADDR_LIST` uses a key ifname that must be at least 4 characters long. + +```yang +...... +container sonic-interface { + container INTERFACE { + list INTERFACE_LIST { // 1st list + key ifname; + leaf ifname { + type string { + length "3..3"; + } + } + // ... + } + + list INTERFACE_IPADDR_LIST { // 2nd list + key "ifname ip_addr"; + leaf ifname { + type string { + length "4..max"; + } + } + // ... + } + } +} +...... +``` + +#### Example 6: Length Constraints (NOT Allowed case) + +Here, both `INTERFACE_LIST` and `INTERFACE_ANOTHER_LIST` use a key ifname with overlapping length constraints, making them potentially ambiguous. + +```yang +...... +container sonic-interface { + container INTERFACE { + list INTERFACE_LIST { // 1st list + key ifname; + leaf ifname { + type string { + length "3..5"; + } + } + // ... + } + + list INTERFACE_ANOTHER_LIST { // Negative case + key ifname; + leaf ifname { + type string { + length "4..6"; + } + } + // ... + } + } +} +...... +``` + ### 19. Add read-only nodes for state data using 'config false' statement. Define a separate top level container for state data. If state data is defined in other DB than CONFIG_DB, use extension 'sonic-ext:db-name' for defining the table present in other Redis DB. The default separator used in table key is "|", if it is different, use 'sonic-ext:key-delim {separator};' YANG extension. This step applies when SONiC YANG is used as Northbound YANG. Example: #### YANG -``` +```yang container ACL_RULE { list ACL_RULE_LIST { .... @@ -584,7 +750,7 @@ container ACL_RULE { Example: #### YANG -``` +```yang container sonic-acl { .... .... @@ -607,7 +773,7 @@ container sonic-acl { Example: #### YANG -``` +```yang module sonic-port { .... .... @@ -621,17 +787,11 @@ module sonic-port { } ``` - - - - - - ## APPENDIX ### Sample SONiC ACL YANG -``` +```yang module sonic-acl { namespace "http://github.com/Azure/sonic-acl"; prefix sacl; From c1422e6b4c522005033432ebff870324a7f21d2c Mon Sep 17 00:00:00 2001 From: faraazbrcm <52159605+faraazbrcm@users.noreply.github.com> Date: Wed, 20 Sep 2023 14:15:01 +0530 Subject: [PATCH 2/5] Update SONiC_YANG_Model_Guidelines.md --- doc/mgmt/SONiC_YANG_Model_Guidelines.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/doc/mgmt/SONiC_YANG_Model_Guidelines.md b/doc/mgmt/SONiC_YANG_Model_Guidelines.md index a39e4ce9090..2fc8e8e0c25 100644 --- a/doc/mgmt/SONiC_YANG_Model_Guidelines.md +++ b/doc/mgmt/SONiC_YANG_Model_Guidelines.md @@ -520,7 +520,7 @@ container PORTCHANNEL_INTERFACE { } } ``` -#### Example 1: Composite Keys with Different Number of Elements(Allowed case) +#### Example 1: Key with Different Number of Elements(composite keys - Allowed case) `INTERFACE` table stores VRF names to which an interface belongs, also it stores IP address of each interface. Hence it is needed to split them into two different YANG lists. @@ -561,8 +561,9 @@ container sonic-interface { } ...... ``` +*** In the example above if the config DB contains an INTERFACE table with single key element then it will be associted with the INTERFACE_LIST and if contains 2 key elements then it will be associated with INTERFACE_IPADDR_LIST *** -#### Example 2: Composite Keys with Same Number of Elements(NOT Allowed case) +#### Example 2: Keys with Same Number of Elements(NOT Allowed case) ```yang ...... @@ -588,6 +589,8 @@ container sonic-interface { ...... ``` +*** In the example above if the config DB contains an INTERFACE table with key Ethernet1 then it would match with both the list, this is an overlapping scenario. *** + #### Example 3: Pattern Constraints (Allowed case) In this example, `INTERFACE_LIST` uses a key `ifname` that must start with "Eth", while `INTERFACE_IPADDR_LIST` uses a key `ifname` that must start with "Vlan". @@ -606,7 +609,7 @@ container sonic-interface { // ... } - list INTERFACE_IPADDR_LIST { // 2nd list + list VLAN_LIST { // 2nd list key "ifname ip_addr"; leaf ifname { type string { @@ -620,6 +623,8 @@ container sonic-interface { ...... ``` +*** In the given example, if the configuration database has an INTERFACE table with the key "Ethernet1, it would correspond to the INTERFACE_LIST. Similarly, if the configuration database features an INTERFACE table with the key "Vlan10," it would align with the VLAN_LIST. In this context, each key uniquely identifies a specific list. *** + #### Example 4: Pattern Constraints (NOT Allowed case) Here, both INTERFACE_LIST and INTERFACE_ANOTHER_LIST use a key ifname with the same pattern constraint, making them potentially overlapping and ambiguous. @@ -651,6 +656,7 @@ container sonic-interface { } ...... ``` +*** In the given example, if the configuration database has an INTERFACE table with the key "Ethernet1, it would correspond to both the LIST, this is an overlapping scenario. ****** #### Example 5: Length Constraints (Allowed case) @@ -671,7 +677,7 @@ container sonic-interface { } list INTERFACE_IPADDR_LIST { // 2nd list - key "ifname ip_addr"; + key "ifname"; leaf ifname { type string { length "4..max"; From a343a391d3096bd677935f2a276885be351d9bb1 Mon Sep 17 00:00:00 2001 From: faraazbrcm <52159605+faraazbrcm@users.noreply.github.com> Date: Wed, 20 Sep 2023 14:19:59 +0530 Subject: [PATCH 3/5] Update SONiC_YANG_Model_Guidelines.md --- doc/mgmt/SONiC_YANG_Model_Guidelines.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/mgmt/SONiC_YANG_Model_Guidelines.md b/doc/mgmt/SONiC_YANG_Model_Guidelines.md index 2fc8e8e0c25..8d3b0b6be36 100644 --- a/doc/mgmt/SONiC_YANG_Model_Guidelines.md +++ b/doc/mgmt/SONiC_YANG_Model_Guidelines.md @@ -561,7 +561,7 @@ container sonic-interface { } ...... ``` -*** In the example above if the config DB contains an INTERFACE table with single key element then it will be associted with the INTERFACE_LIST and if contains 2 key elements then it will be associated with INTERFACE_IPADDR_LIST *** +***In the example above if the config DB contains an INTERFACE table with single key element then it will be associted with the INTERFACE_LIST and if contains 2 key elements then it will be associated with INTERFACE_IPADDR_LIST*** #### Example 2: Keys with Same Number of Elements(NOT Allowed case) @@ -589,7 +589,7 @@ container sonic-interface { ...... ``` -*** In the example above if the config DB contains an INTERFACE table with key Ethernet1 then it would match with both the list, this is an overlapping scenario. *** +***In the example above if the config DB contains an INTERFACE table with key Ethernet1 then it would match with both the list, this is an overlapping scenario.*** #### Example 3: Pattern Constraints (Allowed case) @@ -623,7 +623,7 @@ container sonic-interface { ...... ``` -*** In the given example, if the configuration database has an INTERFACE table with the key "Ethernet1, it would correspond to the INTERFACE_LIST. Similarly, if the configuration database features an INTERFACE table with the key "Vlan10," it would align with the VLAN_LIST. In this context, each key uniquely identifies a specific list. *** +***In the given example, if the configuration database has an INTERFACE table with the key "Ethernet1, it would correspond to the INTERFACE_LIST. Similarly, if the configuration database features an INTERFACE table with the key "Vlan10," it would align with the VLAN_LIST. In this context, each key uniquely identifies a specific list.*** #### Example 4: Pattern Constraints (NOT Allowed case) @@ -656,7 +656,7 @@ container sonic-interface { } ...... ``` -*** In the given example, if the configuration database has an INTERFACE table with the key "Ethernet1, it would correspond to both the LIST, this is an overlapping scenario. ****** +***In the given example, if the configuration database has an INTERFACE table with the key "Ethernet1, it would correspond to both the LIST, this is an overlapping scenario.****** #### Example 5: Length Constraints (Allowed case) From adb11d5644fee191ed2cb7e68810731b20c3a2de Mon Sep 17 00:00:00 2001 From: faraazbrcm <52159605+faraazbrcm@users.noreply.github.com> Date: Wed, 20 Sep 2023 14:23:12 +0530 Subject: [PATCH 4/5] Update SONiC_YANG_Model_Guidelines.md --- doc/mgmt/SONiC_YANG_Model_Guidelines.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/mgmt/SONiC_YANG_Model_Guidelines.md b/doc/mgmt/SONiC_YANG_Model_Guidelines.md index 8d3b0b6be36..28cb2624555 100644 --- a/doc/mgmt/SONiC_YANG_Model_Guidelines.md +++ b/doc/mgmt/SONiC_YANG_Model_Guidelines.md @@ -589,7 +589,7 @@ container sonic-interface { ...... ``` -***In the example above if the config DB contains an INTERFACE table with key Ethernet1 then it would match with both the list, this is an overlapping scenario.*** +***In the example above if the config DB contains an INTERFACE table with key Ethernet1 then it would match with both the list, this is an overlapping scenario*** #### Example 3: Pattern Constraints (Allowed case) @@ -623,7 +623,7 @@ container sonic-interface { ...... ``` -***In the given example, if the configuration database has an INTERFACE table with the key "Ethernet1, it would correspond to the INTERFACE_LIST. Similarly, if the configuration database features an INTERFACE table with the key "Vlan10," it would align with the VLAN_LIST. In this context, each key uniquely identifies a specific list.*** +***In the given example, if the configuration database has an INTERFACE table with the key "Ethernet1, it would correspond to the INTERFACE_LIST. Similarly, if the configuration database features an INTERFACE table with the key "Vlan10," it would align with the VLAN_LIST. In this context, each key uniquely identifies a specific list*** #### Example 4: Pattern Constraints (NOT Allowed case) @@ -656,7 +656,7 @@ container sonic-interface { } ...... ``` -***In the given example, if the configuration database has an INTERFACE table with the key "Ethernet1, it would correspond to both the LIST, this is an overlapping scenario.****** +***In the given example, if the configuration database has an INTERFACE table with the key "Ethernet1, it would correspond to both the LIST, this is an overlapping scenario****** #### Example 5: Length Constraints (Allowed case) From 236c6a13b0a9276c0a1f489a5c150039eaf1a781 Mon Sep 17 00:00:00 2001 From: faraazbrcm <52159605+faraazbrcm@users.noreply.github.com> Date: Wed, 27 Sep 2023 16:01:34 +0530 Subject: [PATCH 5/5] Update SONiC_YANG_Model_Guidelines.md Enhanced PR as per the discussion with YANG subgroup --- doc/mgmt/SONiC_YANG_Model_Guidelines.md | 300 ++++++++++++------------ 1 file changed, 154 insertions(+), 146 deletions(-) diff --git a/doc/mgmt/SONiC_YANG_Model_Guidelines.md b/doc/mgmt/SONiC_YANG_Model_Guidelines.md index 28cb2624555..f8bda3a292d 100644 --- a/doc/mgmt/SONiC_YANG_Model_Guidelines.md +++ b/doc/mgmt/SONiC_YANG_Model_Guidelines.md @@ -503,12 +503,8 @@ container PORTCHANNEL_INTERFACE { #### Strategies for Ensuring Unique and Unambiguous Keys 1. **Composite Keys with Different Number of Elements**: Utilize composite keys that have a different number of key elements to distinguish lists. - -2. **Different Data Types with Constraints**: Use constraints like length, pattern, or range to make keys of different data types non-overlapping. -3. **Pattern Constraints**: Implement regular expressions to define specific patterns that keys must match. - -4. **Length and Range Constraints**: Limit the length of strings or the range of integers to make them unique. +2. **Pattern Constraints**: Implement regular expressions to define specific patterns that keys must match (Only applicable to string datatype). #### ABNF ``` @@ -520,208 +516,220 @@ container PORTCHANNEL_INTERFACE { } } ``` -#### Example 1: Key with Different Number of Elements(composite keys - Allowed case) +#### Example 1: Key with different number of elements(composite keys - Allowed case) `INTERFACE` table stores VRF names to which an interface belongs, also it stores IP address of each interface. Hence it is needed to split them into two different YANG lists. ```yang ...... -container sonic-interface { - container INTERFACE { - list INTERFACE_LIST { // 1st list - key ifname; - - leaf ifname { - type leafref { - ...... - } +container INTERFACE { + list INTERFACE_LIST { // 1st list + key ifname; + + leaf ifname { + type leafref { + ...... } - leaf vrf-name { - type leafref { - ...... - } + } + leaf vrf-name { + type leafref { + ...... } - ...... } + ...... + } - list INTERFACE_IPADDR_LIST { //2nd list - key ifname, ip_addr; - - leaf ifname { - type leafref { - ...... - } - } - leaf ip_addr { - type inet:ipv4-prefix; - } + list INTERFACE_IPADDR_LIST { //2nd list + key ifname, ip_addr; + + leaf ifname { + type leafref { ...... + } } - } + leaf ip_addr { + type inet:ipv4-prefix; + } + ...... + } } ...... ``` ***In the example above if the config DB contains an INTERFACE table with single key element then it will be associted with the INTERFACE_LIST and if contains 2 key elements then it will be associated with INTERFACE_IPADDR_LIST*** -#### Example 2: Keys with Same Number of Elements(NOT Allowed case) +#### Example 2: Keys with same number of elements of same type (NOT Allowed case) ```yang ...... -container sonic-interface { - container INTERFACE { - list INTERFACE_LIST { // 1st list - key ifname; - leaf ifname { - type string; - } - // ... +container NOT_SUPPORTED_INTERFACE { + list NOT_SUPPORTED_INTERFACE_LIST { // 1st list + key ifname; + leaf ifname { + type string; } + // ... + } - list INTERFACE_ANOTHER_LIST { // Negative case - key ifname; - leaf ifname { - type string; - } - // ... + list NOT_SUPPORTED_INTERFACE_ANOTHER_LIST { // Negative case + key ifname; + leaf ifname { + type string; } - } -} + // ... + } +} ...... ``` -***In the example above if the config DB contains an INTERFACE table with key Ethernet1 then it would match with both the list, this is an overlapping scenario*** - -#### Example 3: Pattern Constraints (Allowed case) +***In the example above if the config DB contains an NOT_SUPPORTED_INTERFACE table with key Ethernet1 then it would match with both the list, this is an overlapping scenario*** -In this example, `INTERFACE_LIST` uses a key `ifname` that must start with "Eth", while `INTERFACE_IPADDR_LIST` uses a key `ifname` that must start with "Vlan". +#### Example 3: Pattern Constraints with same number of elements and same type(Allowed case) ```yang ...... -container sonic-interface { - container INTERFACE { - list INTERFACE_LIST { // 1st list - key ifname; - leaf ifname { - type string { - pattern "Eth.*"; - } - } - // ... - } +container TELEMETRY_CLIENT { + list TELEMETRY_CLIENT_DS_LIST { + key "prefix"; + + leaf prefix { + type string { + pattern "DestinationGroup_" + ".*"; + } + } - list VLAN_LIST { // 2nd list - key "ifname ip_addr"; - leaf ifname { - type string { - pattern "Vlan.*"; - } - } - // ... - } - } + leaf dst_addr { + type ipv4-port; + } + } + + list TELEMETRY_CLIENT_SUB_LIST { + key "prefix"; + + leaf prefix { + type string { + pattern "Subscription_" + ".*"; + } + } + + leaf dst_group { + must "(contains(../../TELEMETRY_CLIENT_DS_LIST/prefix, current()))"; + type string; + } + } } ...... ``` -***In the given example, if the configuration database has an INTERFACE table with the key "Ethernet1, it would correspond to the INTERFACE_LIST. Similarly, if the configuration database features an INTERFACE table with the key "Vlan10," it would align with the VLAN_LIST. In this context, each key uniquely identifies a specific list*** - -#### Example 4: Pattern Constraints (NOT Allowed case) +#### Example 4: Pattern Constraints with same number of elements and same type (NOT Allowed case) -Here, both INTERFACE_LIST and INTERFACE_ANOTHER_LIST use a key ifname with the same pattern constraint, making them potentially overlapping and ambiguous. +***In the given example, if the configuration database has an NOT_SUPPORTED_TELEMETRY_CLIENT table with the key "DestinationGroup_HS, it would correspond to the NOT_SUPPORTED_TELEMETRY_CLIENT_DS_LIST and NOT_SUPPORTED_TELEMETRY_CLIENT_SUB_LIST, this is an overlapping scenario. It is required to have pattern constraint for both the LISTs.*** ```yang ...... -container sonic-interface { - container INTERFACE { - list INTERFACE_LIST { // 1st list - key ifname; - leaf ifname { - type string { - pattern "Eth.*"; - } - } - // ... - } +container NOT_SUPPORTED_TELEMETRY_CLIENT { + list NOT_SUPPORTED_TELEMETRY_CLIENT_DS_LIST { + key "prefix"; + + leaf prefix { + type string { + pattern "DestinationGroup_" + ".*"; + } + } - list INTERFACE_ANOTHER_LIST { // Negative case - key ifname; - leaf ifname { - type string { - pattern "Eth.*"; - } - } - // ... - } - } + leaf dst_addr { + type ipv4-port; + } + } + + list NOT_SUPPORTED_TELEMETRY_CLIENT_SUB_LIST { + key "prefix"; + + leaf prefix { + type string; + } + + leaf dst_group { + must "(contains(../../TELEMETRY_CLIENT_DS_LIST/prefix, current()))"; + type string; + } + } } ...... ``` -***In the given example, if the configuration database has an INTERFACE table with the key "Ethernet1, it would correspond to both the LIST, this is an overlapping scenario****** -#### Example 5: Length Constraints (Allowed case) +#### Example 5: keys with same number of elements and different type(NOT Allowed case 1) -In this example, `INTERFACE_LIST` uses a key ifname that must be exactly 3 characters long, while `INTERFACE_IPADDR_LIST` uses a key ifname that must be at least 4 characters long. +***In the given example, if the configuration database has an NOT_SUPPORTED_TELEMETRY_CLIENT table with the key "1234, it would correspond to the NOT_SUPPORTED_TELEMETRY_CLIENT_DS_LIST and NOT_SUPPORTED_TELEMETRY_CLIENT_SUB_LIST, this is an overlapping scenario*** ```yang ...... -container sonic-interface { - container INTERFACE { - list INTERFACE_LIST { // 1st list - key ifname; - leaf ifname { - type string { - length "3..3"; - } - } - // ... - } +container NOT_SUPPORTED_TELEMETRY_CLIENT { + list NOT_SUPPORTED_TELEMETRY_CLIENT_DS_LIST { + key "prefix"; + + leaf prefix { + type string { + pattern ".*"; + } + } - list INTERFACE_IPADDR_LIST { // 2nd list - key "ifname"; - leaf ifname { - type string { - length "4..max"; - } - } - // ... - } - } + leaf dst_addr { + type ipv4-port; + } + } + + list NOT_SUPPORTED_TELEMETRY_CLIENT_SUB_LIST { + key "prefix"; + + leaf prefix { + type int32; + } + + leaf dst_group { + must "(contains(../../TELEMETRY_CLIENT_DS_LIST/prefix, current()))"; + type int32; + } + } } ...... ``` -#### Example 6: Length Constraints (NOT Allowed case) +#### Example 6: keys with same number of elements and different type(NOT Allowed case 2) -Here, both `INTERFACE_LIST` and `INTERFACE_ANOTHER_LIST` use a key ifname with overlapping length constraints, making them potentially ambiguous. +***In the given example, if the configuration database has an NOT_SUPPORTED_TELEMETRY_CLIENT table with the key "1234, it would correspond to the NOT_SUPPORTED_TELEMETRY_CLIENT_DS_LIST and NOT_SUPPORTED_TELEMETRY_CLIENT_SUB_LIST, this is an overlapping scenario*** ```yang ...... -container sonic-interface { - container INTERFACE { - list INTERFACE_LIST { // 1st list - key ifname; - leaf ifname { - type string { - length "3..5"; - } - } - // ... - } +container NOT_SUPPORTED_TELEMETRY_CLIENT { + list NOT_SUPPORTED_TELEMETRY_CLIENT_DS_LIST { + key "prefix"; - list INTERFACE_ANOTHER_LIST { // Negative case - key ifname; - leaf ifname { - type string { - length "4..6"; - } - } - // ... - } - } + leaf prefix { + type string; + } + + leaf dst_addr { + type ipv4-port; + } + } + + list NOT_SUPPORTED_TELEMETRY_CLIENT_SUB_LIST { + key "prefix"; + + leaf prefix { + type int32; + } + + leaf dst_group { + must "(contains(../../TELEMETRY_CLIENT_DS_LIST/prefix, current()))"; + type int32; + } + } } ...... ``` + ### 19. Add read-only nodes for state data using 'config false' statement. Define a separate top level container for state data. If state data is defined in other DB than CONFIG_DB, use extension 'sonic-ext:db-name' for defining the table present in other Redis DB. The default separator used in table key is "|", if it is different, use 'sonic-ext:key-delim {separator};' YANG extension. This step applies when SONiC YANG is used as Northbound YANG. Example: