Skip to content

Commit 236c6a1

Browse files
authored
Update SONiC_YANG_Model_Guidelines.md
Enhanced PR as per the discussion with YANG subgroup
1 parent adb11d5 commit 236c6a1

File tree

1 file changed

+154
-146
lines changed

1 file changed

+154
-146
lines changed

doc/mgmt/SONiC_YANG_Model_Guidelines.md

+154-146
Original file line numberDiff line numberDiff line change
@@ -503,12 +503,8 @@ container PORTCHANNEL_INTERFACE {
503503
#### Strategies for Ensuring Unique and Unambiguous Keys
504504

505505
1. **Composite Keys with Different Number of Elements**: Utilize composite keys that have a different number of key elements to distinguish lists.
506-
507-
2. **Different Data Types with Constraints**: Use constraints like length, pattern, or range to make keys of different data types non-overlapping.
508506

509-
3. **Pattern Constraints**: Implement regular expressions to define specific patterns that keys must match.
510-
511-
4. **Length and Range Constraints**: Limit the length of strings or the range of integers to make them unique.
507+
2. **Pattern Constraints**: Implement regular expressions to define specific patterns that keys must match (Only applicable to string datatype).
512508

513509
#### ABNF
514510
```
@@ -520,208 +516,220 @@ container PORTCHANNEL_INTERFACE {
520516
}
521517
}
522518
```
523-
#### Example 1: Key with Different Number of Elements(composite keys - Allowed case)
519+
#### Example 1: Key with different number of elements(composite keys - Allowed case)
524520

525521
`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.
526522

527523
```yang
528524
......
529-
container sonic-interface {
530-
container INTERFACE {
531-
list INTERFACE_LIST { // 1st list
532-
key ifname;
533-
534-
leaf ifname {
535-
type leafref {
536-
......
537-
}
525+
container INTERFACE {
526+
list INTERFACE_LIST { // 1st list
527+
key ifname;
528+
529+
leaf ifname {
530+
type leafref {
531+
......
538532
}
539-
leaf vrf-name {
540-
type leafref {
541-
......
542-
}
533+
}
534+
leaf vrf-name {
535+
type leafref {
536+
......
543537
}
544-
......
545538
}
539+
......
540+
}
546541
547-
list INTERFACE_IPADDR_LIST { //2nd list
548-
key ifname, ip_addr;
549-
550-
leaf ifname {
551-
type leafref {
552-
......
553-
}
554-
}
555-
leaf ip_addr {
556-
type inet:ipv4-prefix;
557-
}
542+
list INTERFACE_IPADDR_LIST { //2nd list
543+
key ifname, ip_addr;
544+
545+
leaf ifname {
546+
type leafref {
558547
......
548+
}
559549
}
560-
}
550+
leaf ip_addr {
551+
type inet:ipv4-prefix;
552+
}
553+
......
554+
}
561555
}
562556
......
563557
```
564558
***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***
565559

566-
#### Example 2: Keys with Same Number of Elements(NOT Allowed case)
560+
#### Example 2: Keys with same number of elements of same type (NOT Allowed case)
567561

568562
```yang
569563
......
570-
container sonic-interface {
571-
container INTERFACE {
572-
list INTERFACE_LIST { // 1st list
573-
key ifname;
574-
leaf ifname {
575-
type string;
576-
}
577-
// ...
564+
container NOT_SUPPORTED_INTERFACE {
565+
list NOT_SUPPORTED_INTERFACE_LIST { // 1st list
566+
key ifname;
567+
leaf ifname {
568+
type string;
578569
}
570+
// ...
571+
}
579572
580-
list INTERFACE_ANOTHER_LIST { // Negative case
581-
key ifname;
582-
leaf ifname {
583-
type string;
584-
}
585-
// ...
573+
list NOT_SUPPORTED_INTERFACE_ANOTHER_LIST { // Negative case
574+
key ifname;
575+
leaf ifname {
576+
type string;
586577
}
587-
}
588-
}
578+
// ...
579+
}
580+
}
589581
......
590582
```
591583

592-
***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***
593-
594-
#### Example 3: Pattern Constraints (Allowed case)
584+
***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***
595585

596-
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".
586+
#### Example 3: Pattern Constraints with same number of elements and same type(Allowed case)
597587

598588
```yang
599589
......
600-
container sonic-interface {
601-
container INTERFACE {
602-
list INTERFACE_LIST { // 1st list
603-
key ifname;
604-
leaf ifname {
605-
type string {
606-
pattern "Eth.*";
607-
}
608-
}
609-
// ...
610-
}
590+
container TELEMETRY_CLIENT {
591+
list TELEMETRY_CLIENT_DS_LIST {
592+
key "prefix";
593+
594+
leaf prefix {
595+
type string {
596+
pattern "DestinationGroup_" + ".*";
597+
}
598+
}
611599
612-
list VLAN_LIST { // 2nd list
613-
key "ifname ip_addr";
614-
leaf ifname {
615-
type string {
616-
pattern "Vlan.*";
617-
}
618-
}
619-
// ...
620-
}
621-
}
600+
leaf dst_addr {
601+
type ipv4-port;
602+
}
603+
}
604+
605+
list TELEMETRY_CLIENT_SUB_LIST {
606+
key "prefix";
607+
608+
leaf prefix {
609+
type string {
610+
pattern "Subscription_" + ".*";
611+
}
612+
}
613+
614+
leaf dst_group {
615+
must "(contains(../../TELEMETRY_CLIENT_DS_LIST/prefix, current()))";
616+
type string;
617+
}
618+
}
622619
}
623620
......
624621
```
625622

626-
***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***
627-
628-
#### Example 4: Pattern Constraints (NOT Allowed case)
623+
#### Example 4: Pattern Constraints with same number of elements and same type (NOT Allowed case)
629624

630-
Here, both INTERFACE_LIST and INTERFACE_ANOTHER_LIST use a key ifname with the same pattern constraint, making them potentially overlapping and ambiguous.
625+
***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.***
631626

632627
```yang
633628
......
634-
container sonic-interface {
635-
container INTERFACE {
636-
list INTERFACE_LIST { // 1st list
637-
key ifname;
638-
leaf ifname {
639-
type string {
640-
pattern "Eth.*";
641-
}
642-
}
643-
// ...
644-
}
629+
container NOT_SUPPORTED_TELEMETRY_CLIENT {
630+
list NOT_SUPPORTED_TELEMETRY_CLIENT_DS_LIST {
631+
key "prefix";
632+
633+
leaf prefix {
634+
type string {
635+
pattern "DestinationGroup_" + ".*";
636+
}
637+
}
645638
646-
list INTERFACE_ANOTHER_LIST { // Negative case
647-
key ifname;
648-
leaf ifname {
649-
type string {
650-
pattern "Eth.*";
651-
}
652-
}
653-
// ...
654-
}
655-
}
639+
leaf dst_addr {
640+
type ipv4-port;
641+
}
642+
}
643+
644+
list NOT_SUPPORTED_TELEMETRY_CLIENT_SUB_LIST {
645+
key "prefix";
646+
647+
leaf prefix {
648+
type string;
649+
}
650+
651+
leaf dst_group {
652+
must "(contains(../../TELEMETRY_CLIENT_DS_LIST/prefix, current()))";
653+
type string;
654+
}
655+
}
656656
}
657657
......
658658
```
659-
***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******
660659

661-
#### Example 5: Length Constraints (Allowed case)
660+
#### Example 5: keys with same number of elements and different type(NOT Allowed case 1)
662661

663-
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.
662+
***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***
664663

665664
```yang
666665
......
667-
container sonic-interface {
668-
container INTERFACE {
669-
list INTERFACE_LIST { // 1st list
670-
key ifname;
671-
leaf ifname {
672-
type string {
673-
length "3..3";
674-
}
675-
}
676-
// ...
677-
}
666+
container NOT_SUPPORTED_TELEMETRY_CLIENT {
667+
list NOT_SUPPORTED_TELEMETRY_CLIENT_DS_LIST {
668+
key "prefix";
669+
670+
leaf prefix {
671+
type string {
672+
pattern ".*";
673+
}
674+
}
678675
679-
list INTERFACE_IPADDR_LIST { // 2nd list
680-
key "ifname";
681-
leaf ifname {
682-
type string {
683-
length "4..max";
684-
}
685-
}
686-
// ...
687-
}
688-
}
676+
leaf dst_addr {
677+
type ipv4-port;
678+
}
679+
}
680+
681+
list NOT_SUPPORTED_TELEMETRY_CLIENT_SUB_LIST {
682+
key "prefix";
683+
684+
leaf prefix {
685+
type int32;
686+
}
687+
688+
leaf dst_group {
689+
must "(contains(../../TELEMETRY_CLIENT_DS_LIST/prefix, current()))";
690+
type int32;
691+
}
692+
}
689693
}
690694
......
691695
```
692696

693-
#### Example 6: Length Constraints (NOT Allowed case)
697+
#### Example 6: keys with same number of elements and different type(NOT Allowed case 2)
694698

695-
Here, both `INTERFACE_LIST` and `INTERFACE_ANOTHER_LIST` use a key ifname with overlapping length constraints, making them potentially ambiguous.
699+
***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***
696700

697701
```yang
698702
......
699-
container sonic-interface {
700-
container INTERFACE {
701-
list INTERFACE_LIST { // 1st list
702-
key ifname;
703-
leaf ifname {
704-
type string {
705-
length "3..5";
706-
}
707-
}
708-
// ...
709-
}
703+
container NOT_SUPPORTED_TELEMETRY_CLIENT {
704+
list NOT_SUPPORTED_TELEMETRY_CLIENT_DS_LIST {
705+
key "prefix";
710706
711-
list INTERFACE_ANOTHER_LIST { // Negative case
712-
key ifname;
713-
leaf ifname {
714-
type string {
715-
length "4..6";
716-
}
717-
}
718-
// ...
719-
}
720-
}
707+
leaf prefix {
708+
type string;
709+
}
710+
711+
leaf dst_addr {
712+
type ipv4-port;
713+
}
714+
}
715+
716+
list NOT_SUPPORTED_TELEMETRY_CLIENT_SUB_LIST {
717+
key "prefix";
718+
719+
leaf prefix {
720+
type int32;
721+
}
722+
723+
leaf dst_group {
724+
must "(contains(../../TELEMETRY_CLIENT_DS_LIST/prefix, current()))";
725+
type int32;
726+
}
727+
}
721728
}
722729
......
723730
```
724731

732+
725733
### 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.
726734

727735
Example:

0 commit comments

Comments
 (0)