From 51801599e6b3727cf41f4a1376398dc9d8e21e7b Mon Sep 17 00:00:00 2001 From: Partha Dutta Date: Sat, 21 Sep 2019 12:02:19 +0530 Subject: [PATCH 1/4] CVL changes for SONiC YANG --- Makefile | 1 + src/cvl/cvl.go | 30 +- src/cvl/internal/yparser/yparser.go | 8 +- src/cvl/schema/sonic-acl.yang | 257 +++++++++--------- src/cvl/schema/sonic-common.yang | 47 +--- src/cvl/schema/sonic-extension.yang | 61 +++++ src/cvl/schema/sonic-interface.yang | 22 +- src/cvl/schema/sonic-mirror-session.yang | 47 ++-- src/cvl/schema/sonic-port.yang | 80 +++--- src/cvl/testdata/schema/sonic-acl-dev.yang | 13 - .../testdata/schema/sonic-bgp-neighbor.yang | 86 +++--- src/cvl/testdata/schema/sonic-buffer-pg.yang | 53 ++-- .../testdata/schema/sonic-buffer-pool.yang | 51 ++-- .../testdata/schema/sonic-buffer-profile.yang | 67 ++--- .../testdata/schema/sonic-cablelength.yang | 52 ++-- .../schema/sonic-device-metadata.yang | 94 ++++--- .../schema/sonic-device-neighbor.yang | 84 +++--- .../testdata/schema/sonic-dscp-tc-map.yang | 50 ++-- src/cvl/testdata/schema/sonic-pf-limits.yang | 14 +- .../schema/sonic-pfc-priority-queue-map.yang | 46 ++-- .../testdata/schema/sonic-port-qos-map.yang | 20 +- .../schema/sonic-portchannel-interface.yang | 34 +-- .../testdata/schema/sonic-portchannel.yang | 66 ++--- src/cvl/testdata/schema/sonic-queue.yang | 56 ++-- src/cvl/testdata/schema/sonic-scheduler.yang | 48 ++-- .../schema/sonic-tc-priority-group-map.yang | 45 ++- .../testdata/schema/sonic-tc-queue-map.yang | 46 ++-- src/cvl/testdata/schema/sonic-vlan-dev.yang | 6 +- .../testdata/schema/sonic-vlan-interface.yang | 34 +-- src/cvl/testdata/schema/sonic-vlan.yang | 100 +++---- .../testdata/schema/sonic-wred-profile.yang | 96 ++++--- 31 files changed, 841 insertions(+), 873 deletions(-) create mode 100644 src/cvl/schema/sonic-extension.yang diff --git a/Makefile b/Makefile index 01d0a951db..39dc969576 100644 --- a/Makefile +++ b/Makefile @@ -63,6 +63,7 @@ cli: rest-server cvl: go-deps $(MAKE) -C src/cvl $(MAKE) -C src/cvl/schema + $(MAKE) -C src/cvl/testdata/schema cvl-test: $(MAKE) -C src/cvl gotest diff --git a/src/cvl/cvl.go b/src/cvl/cvl.go index f90486ecd9..859d78043f 100644 --- a/src/cvl/cvl.go +++ b/src/cvl/cvl.go @@ -227,14 +227,17 @@ func storeModelInfo(modelFile string, module *yparser.YParserModule) { //such mo modelInfo.modelNs[modelName] = modelNs //Store metadata present in each list - nodes = xmlquery.Find(root, "//module/container/list") + nodes = xmlquery.Find(root, "//module/container/container/list") if (nodes == nil) { return } for _, node := range nodes { - //for each list + //for each list, remove "_LIST" suffix tableName := node.Attr[0].Value + if (strings.HasSuffix(tableName, "_LIST")) { + tableName = tableName[0:len(tableName) - len("_LIST")] + } tableInfo := modelTableInfo{modelName: modelName} //Store the reference for list node to be used later listNode := node @@ -244,6 +247,7 @@ func storeModelInfo(modelFile string, module *yparser.YParserModule) { //such mo tableInfo.dbNum = CONFIG_DB //default delim '|' tableInfo.redisKeyDelim = "|" + modelInfo.allKeyDelims[tableInfo.redisKeyDelim] = true fieldCount := 0 @@ -510,9 +514,9 @@ func (c *CVL) checkPathForTableEntry(tableName string, currentValue string, cfgD //Table name should appear like "../VLAN_MEMBER/tagging_mode' or ' // "/prt:PORT/prt:ifname" //re := regexp.MustCompile(fmt.Sprintf(".*[/]([a-zA-Z]*:)?%s[\\[/]", tblNameSrch)) - tblSrchIdx := strings.Index(xpath, fmt.Sprintf("/%s", tblNameSrch)) //no preifx + tblSrchIdx := strings.Index(xpath, fmt.Sprintf("/%s_LIST", tblNameSrch)) //no preifx if (tblSrchIdx < 0) { - tblSrchIdx = strings.Index(xpath, fmt.Sprintf(":%s", tblNameSrch)) //with prefix + tblSrchIdx = strings.Index(xpath, fmt.Sprintf(":%s_LIST", tblNameSrch)) //with prefix } if (tblSrchIdx < 0) { continue @@ -986,14 +990,16 @@ func (c *CVL) addLeafRef(config bool, tableName string, name string, value strin //only key is there, value wil be fetched and stored here, //if value can't fetched this entry will be deleted that time - if (c.tmpDbCache[refTableName] == nil) { - c.tmpDbCache[refTableName] = map[string]interface{}{redisKey: nil} + //Strip "_LIST" suffix + refRedisTableName := refTableName[0:len(refTableName) - len("_LIST")] + if (c.tmpDbCache[refRedisTableName] == nil) { + c.tmpDbCache[refRedisTableName] = map[string]interface{}{redisKey: nil} } else { - tblMap := c.tmpDbCache[refTableName] + tblMap := c.tmpDbCache[refRedisTableName] _, exist := tblMap.(map[string]interface{})[redisKey] if (exist == false) { tblMap.(map[string]interface{})[redisKey] = nil - c.tmpDbCache[refTableName] = tblMap + c.tmpDbCache[refRedisTableName] = tblMap } } } @@ -1307,10 +1313,16 @@ func (c *CVL) generateTableData(config bool, jsonNode *jsonquery.Node)(*yparser. tableName := fmt.Sprintf("%s",jsonNode.Data) c.batchLeaf = "" + //Every Redis table is mapped as list within a container, + //E.g. ACL_RULE is mapped as + // container ACL_RULE { list ACL_RULE_LIST {} } var topNode *yparser.YParserNode + topNode = c.yp.AddChildNode(modelInfo.tableInfo[tableName].module, nil, modelInfo.tableInfo[tableName].modelName) + listConatinerNode := c.yp.AddChildNode(modelInfo.tableInfo[tableName].module, + topNode, tableName) //Traverse each key instance for jsonNode = jsonNode.FirstChild; jsonNode != nil; jsonNode = jsonNode.NextSibling { @@ -1334,7 +1346,7 @@ func (c *CVL) generateTableData(config bool, jsonNode *jsonquery.Node)(*yparser. for ; totalKeyComb > 0 ; totalKeyComb-- { //Add table i.e. create list element - listNode := c.addChildNode(tableName, topNode, tableName) //Add the list to the top node + listNode := c.addChildNode(tableName, listConatinerNode, tableName + "_LIST") //Add the list to the top node //For each key combination //Add keys as leaf to the list diff --git a/src/cvl/internal/yparser/yparser.go b/src/cvl/internal/yparser/yparser.go index a41a058507..dff83d01c7 100644 --- a/src/cvl/internal/yparser/yparser.go +++ b/src/cvl/internal/yparser/yparser.go @@ -76,15 +76,15 @@ int lyd_data_validate_all(const char *data, const char *depData, const char *oth int lyd_multi_new_leaf(struct lyd_node *parent, const struct lys_module *module, const char *leafVal) { char s[4048]; - char *name, *val; + char *name, *val, *saveptr; strcpy(s, leafVal); - name = strtok(s, "#"); + name = strtok_r(s, "#", &saveptr); while (name != NULL) { - val = strtok(NULL, "#"); + val = strtok_r(NULL, "#", &saveptr); if (val != NULL) { if (NULL == lyd_new_leaf(parent, module, name, val)) @@ -93,7 +93,7 @@ int lyd_multi_new_leaf(struct lyd_node *parent, const struct lys_module *module, } } - name = strtok(NULL, "#"); + name = strtok_r(NULL, "#", &saveptr); } return 0; diff --git a/src/cvl/schema/sonic-acl.yang b/src/cvl/schema/sonic-acl.yang index fc65e5ac4a..d778e8da5f 100644 --- a/src/cvl/schema/sonic-acl.yang +++ b/src/cvl/schema/sonic-acl.yang @@ -12,7 +12,7 @@ module sonic-acl { } import sonic-common { - prefix scommon; + prefix cmn; } import sonic-port { @@ -39,181 +39,186 @@ module sonic-acl { container sonic-acl { - list ACL_TABLE { - key "aclname"; + container ACL_TABLE { + list ACL_TABLE_LIST { + key "aclname"; - leaf aclname { - type string { - pattern '[a-zA-Z0-9]{1}([-a-zA-Z0-9_]{0,71})'; - length 1..72; + leaf aclname { + type string { + pattern '[a-zA-Z0-9]{1}([-a-zA-Z0-9_]{0,71})'; + length 1..72; + } } - } - leaf policy_desc { - type string { - length 1..255 { - error-app-tag policy-desc-invalid-length; + leaf policy_desc { + type string { + length 1..255 { + error-app-tag policy-desc-invalid-length; + } } } - } - leaf stage { - type enumeration { - enum INGRESS; - enum EGRESS; + leaf stage { + type enumeration { + enum INGRESS; + enum EGRESS; + } } - } - leaf type { - type enumeration { - enum MIRROR; - enum L2; - enum L3; - enum L3V6; + leaf type { + type enumeration { + enum MIRROR; + enum L2; + enum L3; + enum L3V6; + } } - } - leaf-list ports { - type leafref { - path "/prt:sonic-port/prt:PORT/prt:ifname"; + leaf-list ports { + type leafref { + path "/prt:sonic-port/prt:PORT/prt:PORT_LIST/prt:ifname"; + } } } } - list ACL_RULE { - key "aclname rulename"; + container ACL_RULE { - leaf aclname { - type leafref { - path "../../ACL_TABLE/aclname"; - } - must "(/scommon:operation/scommon:operation != 'DELETE') or " + - "count(current()/../../ACL_TABLE[aclname=current()]/ports) = 0" { - error-message "Ports are already bound to this rule."; - } - } + list ACL_RULE_LIST { + key "aclname rulename"; - leaf rulename { - type string; - } + leaf aclname { + type leafref { + path "../../../ACL_TABLE/ACL_TABLE_LIST/aclname"; + } + must "(/cmn:operation/cmn:operation != 'DELETE') or " + + "count(current()/../../../ACL_TABLE/ACL_TABLE_LIST[aclname=current()]/ports) = 0" { + error-message "Ports are already bound to this rule."; + } + } - leaf PRIORITY { - type uint16 { - range "1..65535"{ - error-message "Invalid ACL rule priority."; - } + leaf rulename { + type string; } - } - - leaf RULE_DESCRIPTION { - type string; - } - leaf PACKET_ACTION { - type enumeration { - enum FORWARD; - enum DROP; - enum REDIRECT; + leaf PRIORITY { + type uint16 { + range "1..65535"{ + error-message "Invalid ACL rule priority."; + } + } } - } - leaf MIRROR_ACTION { - type leafref { - path "/sms:sonic-mirror-session/sms:MIRROR_SESSION/sms:name"; + leaf RULE_DESCRIPTION { + type string; } - } - leaf IP_TYPE { - type enumeration { - enum ANY; - enum IP; - enum IPV4; - enum IPV4ANY; - enum NON_IPV4; - enum IPV6ANY; - enum NON_IPV6; + leaf PACKET_ACTION { + type enumeration { + enum FORWARD; + enum DROP; + enum REDIRECT; + } } - } - leaf IP_PROTOCOL { - type uint8 { - range "1|2|6|17|46|47|51|103|115"; + leaf MIRROR_ACTION { + type leafref { + path "/sms:sonic-mirror-session/sms:MIRROR_SESSION/sms:MIRROR_SESSION_LIST/sms:name"; + } } - } - leaf ETHER_TYPE { - type string { - pattern "(0x88CC)|(0x8100)|(0x8915)|(0x0806)|(0x0800)|(0x86DD)|(0x8847)" { - error-message "Invalid ACL Rule Ether Type"; - error-app-tag ether-type-invalid; + leaf IP_TYPE { + type enumeration { + enum ANY; + enum IP; + enum IPV4; + enum IPV4ANY; + enum NON_IPV4; + enum IPV6ANY; + enum NON_IPV6; } } - } - choice ip_src_dst { - case ipv4_src_dst { - //when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV4' or .='IPV4ANY'])"; - leaf SRC_IP { - mandatory true; - type inet:ipv4-prefix; + leaf IP_PROTOCOL { + type uint8 { + range "1|2|6|17|46|47|51|103|115"; } - leaf DST_IP { - mandatory true; - type inet:ipv4-prefix; + } + + leaf ETHER_TYPE { + type string { + pattern "(0x88CC)|(0x8100)|(0x8915)|(0x0806)|(0x0800)|(0x86DD)|(0x8847)" { + error-message "Invalid ACL Rule Ether Type"; + error-app-tag ether-type-invalid; + } } } - case ipv6_src_dst { - //when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV6' or .='IPV6ANY'])"; - leaf SRC_IPV6 { - mandatory true; - type inet:ipv6-prefix; + + choice ip_src_dst { + case ipv4_src_dst { + //when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV4' or .='IPV4ANY'])"; + leaf SRC_IP { + mandatory true; + type inet:ipv4-prefix; + } + leaf DST_IP { + mandatory true; + type inet:ipv4-prefix; + } } - leaf DST_IPV6 { - mandatory true; - type inet:ipv6-prefix; + case ipv6_src_dst { + //when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV6' or .='IPV6ANY'])"; + leaf SRC_IPV6 { + mandatory true; + type inet:ipv6-prefix; + } + leaf DST_IPV6 { + mandatory true; + type inet:ipv6-prefix; + } } } - } - choice src_port { - case l4_src_port { - leaf L4_SRC_PORT { - type uint16; + choice src_port { + case l4_src_port { + leaf L4_SRC_PORT { + type uint16; + } } - } - case l4_src_port_range { - leaf L4_SRC_PORT_RANGE { - type string { - pattern "[0-9]{1,5}(-)[0-9]{1,5}"; + case l4_src_port_range { + leaf L4_SRC_PORT_RANGE { + type string { + pattern "[0-9]{1,5}(-)[0-9]{1,5}"; + } } } } - } - choice dst_port { - case l4_dst_port { - leaf L4_DST_PORT { - type uint16; + choice dst_port { + case l4_dst_port { + leaf L4_DST_PORT { + type uint16; + } } - } - case l4_dst_port_range { - leaf L4_DST_PORT_RANGE { - type string { - pattern "[0-9]{1,5}(-)[0-9]{1,5}"; + case l4_dst_port_range { + leaf L4_DST_PORT_RANGE { + type string { + pattern "[0-9]{1,5}(-)[0-9]{1,5}"; + } } } } - } - leaf TCP_FLAGS { - type string { - pattern "0[xX][0-9a-fA-F]{2}[/]0[xX][0-9a-fA-F]{2}"; + leaf TCP_FLAGS { + type string { + pattern "0[xX][0-9a-fA-F]{2}[/]0[xX][0-9a-fA-F]{2}"; + } } - } - leaf DSCP { - type uint8; + leaf DSCP { + type uint8; + } } } } diff --git a/src/cvl/schema/sonic-common.yang b/src/cvl/schema/sonic-common.yang index 329d40c537..77a81c5f84 100644 --- a/src/cvl/schema/sonic-common.yang +++ b/src/cvl/schema/sonic-common.yang @@ -1,11 +1,7 @@ module sonic-common { namespace "http://github.com/Azure/sonic-common"; - prefix sv; - - import ietf-yang-types { - prefix yang; - } + prefix scommon; organization "SONiC"; @@ -36,47 +32,6 @@ module sonic-common { } } - extension custom-handler { - description - "Node should be handled by custom handler"; - argument "name"; - } - - extension db-name { - description - "DB name, e.g. APPL_DB, CONFIG_DB"; - argument "value"; - } - - extension key-delim { - description - "Key delimeter, e.g. - |, :"; - argument "value"; - } - - extension key-pattern { - description - "Key pattern, e.g. - ACL_RULE|{aclname}|{rulename}"; - argument "value"; - } - - extension map-list { - description - "If it is a map list"; - argument "value"; - } - - extension map-leaf { - description - "Map leaf names"; - argument "value"; - } - - extension pf-check { - description - "Platform specific validation"; - argument "handler"; - } container operation { leaf operation { diff --git a/src/cvl/schema/sonic-extension.yang b/src/cvl/schema/sonic-extension.yang new file mode 100644 index 0000000000..f488809586 --- /dev/null +++ b/src/cvl/schema/sonic-extension.yang @@ -0,0 +1,61 @@ + +module sonic-extension { + namespace "http://github.com/Azure/sonic-extension"; + prefix sonic-ext; + + organization + "SONiC"; + + contact + "SONiC"; + + description + "SONIC Extension"; + + revision 2019-09-18 { + description + "Initial revision."; + } + + extension custom-handler { + description + "Node should be handled by custom handler"; + argument "name"; + } + + extension db-name { + description + "DB name, e.g. APPL_DB, CONFIG_DB"; + argument "value"; + } + + extension key-delim { + description + "Key delimeter, e.g. - |, :"; + argument "value"; + } + + extension key-pattern { + description + "Key pattern, e.g. - ACL_RULE|{aclname}|{rulename}"; + argument "value"; + } + + extension map-list { + description + "If it is a map list"; + argument "value"; + } + + extension map-leaf { + description + "Map leaf names"; + argument "value"; + } + + extension pf-check { + description + "Platform specific validation"; + argument "handler"; + } +} diff --git a/src/cvl/schema/sonic-interface.yang b/src/cvl/schema/sonic-interface.yang index 540b3a16b8..79ca4832e8 100644 --- a/src/cvl/schema/sonic-interface.yang +++ b/src/cvl/schema/sonic-interface.yang @@ -33,19 +33,23 @@ module sonic-interface { } container sonic-interface { - list INTERFACE { - key "portname ip_prefix"; - leaf portname{ - type leafref { - path "/prt:sonic-port/prt:PORT/prt:ifname"; + container INTERFACE { + + list INTERFACE_LIST { + key "portname ip_prefix"; + + leaf portname{ + type leafref { + path "/prt:sonic-port/prt:PORT/prt:PORT_LIST/prt:ifname"; + } } - } - leaf ip_prefix { - mandatory true; - type inet:ip-prefix; + leaf ip_prefix { + mandatory true; + type inet:ip-prefix; + } } } } diff --git a/src/cvl/schema/sonic-mirror-session.yang b/src/cvl/schema/sonic-mirror-session.yang index 1a2591cc0c..9805a121fa 100644 --- a/src/cvl/schema/sonic-mirror-session.yang +++ b/src/cvl/schema/sonic-mirror-session.yang @@ -30,35 +30,38 @@ module sonic-mirror-session { container sonic-mirror-session { - list MIRROR_SESSION { - key "name"; + container MIRROR_SESSION { - leaf name { - type string; - } + list MIRROR_SESSION_LIST { + key "name"; - leaf src_ip { - type inet:ipv4-address; - } + leaf name { + type string; + } - leaf dst_ip { - type inet:ipv4-address; - } + leaf src_ip { + type inet:ipv4-address; + } - leaf gre_type { - type string; - } + leaf dst_ip { + type inet:ipv4-address; + } - leaf dscp { - type uint8; - } + leaf gre_type { + type string; + } - leaf ttl { - type uint8; - } + leaf dscp { + type uint8; + } + + leaf ttl { + type uint8; + } - leaf queue { - type uint8; + leaf queue { + type uint8; + } } } } diff --git a/src/cvl/schema/sonic-port.yang b/src/cvl/schema/sonic-port.yang index 3d99d0534f..ba0959f3b6 100644 --- a/src/cvl/schema/sonic-port.yang +++ b/src/cvl/schema/sonic-port.yang @@ -2,10 +2,6 @@ module sonic-port { namespace "http://github.com/Azure/sonic-port"; prefix prt; - import ietf-yang-types { - prefix yang; - } - import sonic-common { prefix scommon; } @@ -26,53 +22,57 @@ module sonic-port { container sonic-port { - list PORT { - key "ifname"; - - leaf ifname { - type string { - pattern "Ethernet([1-3][0-9]{3}|[1-9][0-9]{2}|[1-9][0-9]|[0-9])"{ - error-message "Invalid interface name"; - error-app-tag interface-name-invalid; - } + + container PORT { + + list PORT_LIST { + key "ifname"; + + leaf ifname { + type string { + pattern "Ethernet([1-3][0-9]{3}|[1-9][0-9]{2}|[1-9][0-9]|[0-9])" { + error-message "Invalid interface name"; + error-app-tag interface-name-invalid; + } + } } - } - leaf index { - type uint16; - } + leaf index { + type uint16; + } - leaf speed { - type uint64; - } + leaf speed { + type uint64; + } - leaf valid_speeds { - type string; - } + leaf valid_speeds { + type string; + } - leaf alias { - type string; - } + leaf alias { + type string; + } - leaf description { - type string; - } + leaf description { + type string; + } - leaf mtu{ - type uint32 { - range "1312..9216" { - error-message "Invalid MTU value"; - error-app-tag mtu-invalid; + leaf mtu{ + type uint32 { + range "1312..9216" { + error-message "Invalid MTU value"; + error-app-tag mtu-invalid; + } } } - } - leaf lanes { - type string; - } + leaf lanes { + type string; + } - leaf admin_status { - type scommon:admin-status; + leaf admin_status { + type scommon:admin-status; + } } } } diff --git a/src/cvl/testdata/schema/sonic-acl-dev.yang b/src/cvl/testdata/schema/sonic-acl-dev.yang index 7fcf99f931..d11b40a95c 100644 --- a/src/cvl/testdata/schema/sonic-acl-dev.yang +++ b/src/cvl/testdata/schema/sonic-acl-dev.yang @@ -3,23 +3,10 @@ module sonic-acl-dev { prefix acld; yang-version 1.1; - import ietf-yang-types { - prefix yang; - } - - import ietf-inet-types { - prefix inet; - } - import sonic-acl { prefix sacl; } - import sonic-common { - prefix scommon; - } - - organization "SONiC"; diff --git a/src/cvl/testdata/schema/sonic-bgp-neighbor.yang b/src/cvl/testdata/schema/sonic-bgp-neighbor.yang index 2264e5238e..14504d6f9b 100644 --- a/src/cvl/testdata/schema/sonic-bgp-neighbor.yang +++ b/src/cvl/testdata/schema/sonic-bgp-neighbor.yang @@ -2,22 +2,14 @@ module sonic-bgp-neighbor { namespace "http://github.com/Azure/sonic-bgp-neighbor"; prefix sbn; - import ietf-yang-types { - prefix yang; - } - import ietf-inet-types { - prefix inet; - } + prefix inet; + } import sonic-common { prefix scommon; } - import sonic-port { - prefix prt; - } - organization "SONiC"; @@ -33,54 +25,58 @@ module sonic-bgp-neighbor { } container sonic-bgp-neighbor { - list BGP_NEIGHBOR { - key "ipaddress"; - leaf ipaddress{ - type inet:ip-address; - } + container BGP_NEIGHBOR { - leaf rrclient { - type uint8 { - range "0..255"; + list BGP_NEIGHBOR_LIST { + key "ipaddress"; + + leaf ipaddress{ + type inet:ip-address; } - } - leaf admin_status{ - type scommon:admin-status; - } + leaf rrclient { + type uint8 { + range "0..255"; + } + } - leaf peer_addr{ - type inet:ip-address; - } + leaf admin_status{ + type scommon:admin-status; + } - leaf name { - type string; - } + leaf peer_addr{ + type inet:ip-address; + } - leaf local_addr { - type inet:ipv4-address; - } + leaf name { + type string; + } - leaf nhopself { - type uint8 { - range "0..255"; + leaf local_addr { + type inet:ipv4-address; } - } - leaf holdtime { - type uint8 { - range "0..255"; + leaf nhopself { + type uint8 { + range "0..255"; + } } - } - leaf asn { - type uint64; - } + leaf holdtime { + type uint8 { + range "0..255"; + } + } + + leaf asn { + type uint64; + } - leaf keepalive { - type uint8 { - range "0..255"; + leaf keepalive { + type uint8 { + range "0..255"; + } } } } diff --git a/src/cvl/testdata/schema/sonic-buffer-pg.yang b/src/cvl/testdata/schema/sonic-buffer-pg.yang index 61b5013fed..27918081e8 100644 --- a/src/cvl/testdata/schema/sonic-buffer-pg.yang +++ b/src/cvl/testdata/schema/sonic-buffer-pg.yang @@ -2,16 +2,8 @@ module sonic-buffer-pg { namespace "http://github.com/Azure/sonic-buffer-pg"; prefix bpg; - import ietf-yang-types { - prefix yang; - } - - import ietf-inet-types { - prefix inet; - } - - import sonic-common { - prefix scommon; + import sonic-extension { + prefix sonic-ext; } import sonic-port { @@ -38,32 +30,37 @@ module sonic-buffer-pg { container sonic-buffer-pg { - list BUFFER_PG { - key "ifname pg_num"; - scommon:key-pattern "BUFFER_PG|({ifname},)*|{pg_num}"; //special pattern used for extracting keys from redis-key and fill populate the yang instance - // Total list instance = number(key1) * number(key2) * number(key3) - leaf ifname { - type leafref { - path "/prt:sonic-port/prt:PORT/prt:ifname"; + container BUFFER_PG { + + list BUFFER_PG_LIST { + key "ifname pg_num"; + sonic-ext:key-pattern "BUFFER_PG|({ifname},)*|{pg_num}"; //special pattern used for extracting keys from + //redis-key and fill populate the yang instance + // Total list instance = number(key1) * number(key2) * number(key3) + + leaf ifname { + type leafref { + path "/prt:sonic-port/prt:PORT/prt:PORT_LIST/prt:ifname"; + } } - } - leaf pg_num { - type string { - pattern "[0-7]((-)[0-7])?"{ - error-message "Invalid Buffer PG number"; - error-app-tag pg-num-invalid; + leaf pg_num { + type string { + pattern "[0-7]((-)[0-7])?" { + error-message "Invalid Buffer PG number"; + error-app-tag pg-num-invalid; + } } } - } - leaf profile { //Hash reference key - type leafref { - path "/bpf:sonic-buffer-profile/bpf:BUFFER_PROFILE/bpf:name"; + leaf profile { //Hash reference key + type leafref { + path "/bpf:sonic-buffer-profile/bpf:BUFFER_PROFILE/bpf:BUFFER_PROFILE_LIST/bpf:name"; + } } - } + } } } } diff --git a/src/cvl/testdata/schema/sonic-buffer-pool.yang b/src/cvl/testdata/schema/sonic-buffer-pool.yang index 130c28287f..5f935b3f94 100644 --- a/src/cvl/testdata/schema/sonic-buffer-pool.yang +++ b/src/cvl/testdata/schema/sonic-buffer-pool.yang @@ -2,18 +2,6 @@ module sonic-buffer-pool { namespace "http://github.com/Azure/sonic-buffer-pool"; prefix bpl; - import ietf-yang-types { - prefix yang; - } - - import ietf-inet-types { - prefix inet; - } - - import sonic-common { - prefix scommon; - } - organization "SONiC"; @@ -30,31 +18,34 @@ module sonic-buffer-pool { container sonic-buffer-pool { - list BUFFER_POOL { - key "name"; + container BUFFER_POOL { - leaf name { - type string; - } + list BUFFER_POOL_LIST { + key "name"; - leaf type { - type enumeration { - enum ingress; - enum egress; + leaf name { + type string; } - } - leaf mode { - type enumeration { - enum static; - enum dynamic; + leaf type { + type enumeration { + enum ingress; + enum egress; + } } - } - leaf size { - type uint64; - } + leaf mode { + type enumeration { + enum static; + enum dynamic; + } + } + leaf size { + type uint64; + } + + } } } } diff --git a/src/cvl/testdata/schema/sonic-buffer-profile.yang b/src/cvl/testdata/schema/sonic-buffer-profile.yang index 895def38c4..71f077654d 100644 --- a/src/cvl/testdata/schema/sonic-buffer-profile.yang +++ b/src/cvl/testdata/schema/sonic-buffer-profile.yang @@ -2,18 +2,6 @@ module sonic-buffer-profile { namespace "http://github.com/Azure/sonic-buffer-profile"; prefix bpf; - import ietf-yang-types { - prefix yang; - } - - import ietf-inet-types { - prefix inet; - } - - import sonic-common { - prefix scommon; - } - import sonic-buffer-pool { prefix bpl; } @@ -35,41 +23,44 @@ module sonic-buffer-profile { container sonic-buffer-profile { - list BUFFER_PROFILE { - key "name"; + container BUFFER_PROFILE { - leaf name { - type string; - } + list BUFFER_PROFILE_LIST { + key "name"; - leaf static_th { - type uint64; - } + leaf name { + type string; + } - leaf dynamic_th { - type int64; - } + leaf static_th { + type uint64; + } - leaf size { - type uint64; - } + leaf dynamic_th { + type int64; + } - leaf pool { - type leafref { - path "/bpl:sonic-buffer-pool/bpl:BUFFER_POOL/bpl:name"; + leaf size { + type uint64; } - } - leaf xon_offset { - type uint64; - } + leaf pool { + type leafref { + path "/bpl:sonic-buffer-pool/bpl:BUFFER_POOL/bpl:BUFFER_POOL_LIST/bpl:name"; + } + } - leaf xon { - type uint64; - } + leaf xon_offset { + type uint64; + } - leaf xoff { - type uint64; + leaf xon { + type uint64; + } + + leaf xoff { + type uint64; + } } } } diff --git a/src/cvl/testdata/schema/sonic-cablelength.yang b/src/cvl/testdata/schema/sonic-cablelength.yang index e4eeed031c..af4746211b 100644 --- a/src/cvl/testdata/schema/sonic-cablelength.yang +++ b/src/cvl/testdata/schema/sonic-cablelength.yang @@ -2,16 +2,8 @@ module sonic-cablelength { namespace "http://github.com/Azure/sonic-cablelength"; prefix scl; - import ietf-yang-types { - prefix yang; - } - - import ietf-inet-types { - prefix inet; - } - - import sonic-common { - prefix scommon; + import sonic-extension { + prefix sonic-ext; } import sonic-port { @@ -33,32 +25,36 @@ module sonic-cablelength { } container sonic-cablelength { - list CABLE_LENGTH { - key "name"; - scommon:map-list true; //special conversion for map tables - scommon:map-leaf "port length"; //every key:value pair is mapped to list keys, e.g. "1":"7" ==> tc_num=1, dscp=7 - leaf name { - type string; - } - - list CABLE_LENGTH { //this is list inside list for storing mapping between two fields - key "port length"; + container CABLE_LENGTH { - leaf port { - type leafref { - path "/prt:sonic-port/prt:PORT/prt:ifname"; - } + list CABLE_LENGTH_LIST { + key "name"; + sonic-ext:map-list true; //special conversion for map tables + sonic-ext:map-leaf "port length"; //every key:value pair is mapped to list keys, e.g. "1":"7" ==> tc_num=1, dscp=7 + leaf name { + type string; } - leaf length { - type string { - pattern "[0-9]?[0-9]m"; + list CABLE_LENGTH { //this is list inside list for storing mapping between two fields + key "port length"; + + leaf port { + type leafref { + path "/prt:sonic-port/prt:PORT/prt:PORT_LIST/prt:ifname"; + } + + } + + leaf length { + type string { + pattern "[0-9]?[0-9]m"; + } } } - } + } } } } diff --git a/src/cvl/testdata/schema/sonic-device-metadata.yang b/src/cvl/testdata/schema/sonic-device-metadata.yang index 0bd953836b..014f88cd47 100644 --- a/src/cvl/testdata/schema/sonic-device-metadata.yang +++ b/src/cvl/testdata/schema/sonic-device-metadata.yang @@ -29,64 +29,68 @@ module sonic-device-metadata { } container sonic-device-metadata { - list DEVICE_METADATA { - key "name"; - leaf name{ - type string; - } + container DEVICE_METADATA { - leaf hwsku { - type string; - } + list DEVICE_METADATA_LIST { + key "name"; - leaf hostname { - type string; - } + leaf name{ + type string; + } - leaf platform { - type string; - } + leaf hwsku { + type string; + } - leaf mac { - type yang:mac-address; - } + leaf hostname { + type string; + } - leaf bgp_asn { - type leafref { - path "/sbn:sonic-bgp-neighbor/sbn:BGP_NEIGHBOR/sbn:asn"; + leaf platform { + type string; } - } - leaf default_pfcwd_status { - type enumeration { - enum enable; - enum disable; - } - } + leaf mac { + type yang:mac-address; + } - leaf default_bgp_status { - type scommon:admin-status; - } + leaf bgp_asn { + type leafref { + path "/sbn:sonic-bgp-neighbor/sbn:BGP_NEIGHBOR/sbn:BGP_NEIGHBOR_LIST/sbn:asn"; + } + } - leaf docker_routing_config_mode { - type enumeration { - enum unified; - enum separated; - } - } + leaf default_pfcwd_status { + type enumeration { + enum enable; + enum disable; + } + } - leaf deployment_id { - type uint8 { - range "0..255"; + leaf default_bgp_status { + type scommon:admin-status; } - } - leaf type { - type enumeration { - enum ToRRouter; - enum LeafRouter; - } + leaf docker_routing_config_mode { + type enumeration { + enum unified; + enum separated; + } + } + + leaf deployment_id { + type uint8 { + range "0..255"; + } + } + + leaf type { + type enumeration { + enum ToRRouter; + enum LeafRouter; + } + } } } } diff --git a/src/cvl/testdata/schema/sonic-device-neighbor.yang b/src/cvl/testdata/schema/sonic-device-neighbor.yang index 9dc28187ef..a91302ac24 100644 --- a/src/cvl/testdata/schema/sonic-device-neighbor.yang +++ b/src/cvl/testdata/schema/sonic-device-neighbor.yang @@ -2,16 +2,8 @@ module sonic-device-neighbor { namespace "http://github.com/Azure/sonic-device-neighbor"; prefix sdn; - import ietf-yang-types { - prefix yang; - } - import ietf-inet-types { - prefix inet; - } - - import sonic-common { - prefix scommon; + prefix inet; } import sonic-port { @@ -34,42 +26,46 @@ module sonic-device-neighbor { } container sonic-device-neighbor { - list DEVICE_NEIGHBOR { - key "name"; - - leaf name{ - type string; - } - - leaf mgmt_addr{ - type inet:ip-address; - } - - leaf hwsku { - type string; - } - - leaf lo_addr { - type inet:ip-address; - } - - leaf local_port { - type leafref { - path "/prt:sonic-port/prt:PORT/prt:ifname"; - } - } - - leaf type { - type enumeration { - enum ToRRouter; - enum LeafRouter; - } - } - leaf port { - type leafref { - path "/prt:sonic-port/prt:PORT/prt:ifname"; - } + container DEVICE_NEIGHBOR { + + list DEVICE_NEIGHBOR_LIST { + key "name"; + + leaf name{ + type string; + } + + leaf mgmt_addr{ + type inet:ip-address; + } + + leaf hwsku { + type string; + } + + leaf lo_addr { + type inet:ip-address; + } + + leaf local_port { + type leafref { + path "/prt:sonic-port/prt:PORT/prt:PORT_LIST/prt:ifname"; + } + } + + leaf type { + type enumeration { + enum ToRRouter; + enum LeafRouter; + } + } + + leaf port { + type leafref { + path "/prt:sonic-port/prt:PORT/prt:PORT_LIST/prt:ifname"; + } + } } } } diff --git a/src/cvl/testdata/schema/sonic-dscp-tc-map.yang b/src/cvl/testdata/schema/sonic-dscp-tc-map.yang index 481cfbece0..9ec41b4f15 100644 --- a/src/cvl/testdata/schema/sonic-dscp-tc-map.yang +++ b/src/cvl/testdata/schema/sonic-dscp-tc-map.yang @@ -2,12 +2,8 @@ module sonic-dscp-tc-map { namespace "http://github.com/Azure/sonic-dscp-tc-map"; prefix dtm; - import ietf-yang-types { - prefix yang; - } - - import sonic-common { - prefix scommon; + import sonic-extension { + prefix sonic-ext; } import sonic-port { @@ -29,34 +25,38 @@ module sonic-dscp-tc-map { } container sonic-dscp-tc-map { - list DSCP_TO_TC_MAP { - key "name"; - scommon:map-list true; //special conversion for map tables - scommon:map-leaf "dscp tc_num"; //every key:value pair is mapped to list keys, e.g. "1":"7" ==> tc_num=1, dscp=7 - leaf name { - type string; - } + container DSCP_TO_TC_MAP { + + list DSCP_TO_TC_MAP_LIST { + key "name"; + sonic-ext:map-list true; //special conversion for map tables + sonic-ext:map-leaf "dscp tc_num"; //every key:value pair is mapped to list keys, e.g. "1":"7" ==> tc_num=1, dscp=7 + + leaf name { + type string; + } - list DSCP_TO_TC_MAP { //this is list inside list for storing mapping between two fields - key "dscp tc_num"; + list DSCP_TO_TC_MAP { //this is list inside list for storing mapping between two fields + key "dscp tc_num"; - leaf tc_num { - type string { - pattern "[0-9]?"{ - error-message "Invalid Traffic Class number"; - error-app-tag tc-num-invalid; + leaf tc_num { + type string { + pattern "[0-9]?"{ + error-message "Invalid Traffic Class number"; + error-app-tag tc-num-invalid; + } } } - } - leaf dscp { - type string { - pattern "[1-9][0-9]?|[0-9]?"; + leaf dscp { + type string { + pattern "[1-9][0-9]?|[0-9]?"; + } } } - } + } } } } diff --git a/src/cvl/testdata/schema/sonic-pf-limits.yang b/src/cvl/testdata/schema/sonic-pf-limits.yang index 6b92e97dba..658a6e9a8d 100644 --- a/src/cvl/testdata/schema/sonic-pf-limits.yang +++ b/src/cvl/testdata/schema/sonic-pf-limits.yang @@ -3,16 +3,8 @@ module sonic-pf-limits { prefix spf; yang-version 1.1; - import ietf-yang-types { - prefix yang; - } - - import ietf-inet-types { - prefix inet; - } - - import sonic-common { - prefix scommon; + import sonic-extension { + prefix sonic-ext; } organization @@ -30,7 +22,7 @@ module sonic-pf-limits { } container sonic-pf-limits { - scommon:db-name "APPL_DB"; + sonic-ext:db-name "APPL_DB"; container acl { leaf MAX_ACL_RULES { diff --git a/src/cvl/testdata/schema/sonic-pfc-priority-queue-map.yang b/src/cvl/testdata/schema/sonic-pfc-priority-queue-map.yang index b5c8952e6b..ad51874d69 100644 --- a/src/cvl/testdata/schema/sonic-pfc-priority-queue-map.yang +++ b/src/cvl/testdata/schema/sonic-pfc-priority-queue-map.yang @@ -2,12 +2,8 @@ module sonic-pfc-priority-queue-map { namespace "http://github.com/Azure/sonic-pfc-priority-queue-map"; prefix ppq; - import ietf-yang-types { - prefix yang; - } - - import sonic-common { - prefix scommon; + import sonic-extension { + prefix sonic-ext; } organization @@ -25,31 +21,35 @@ module sonic-pfc-priority-queue-map { } container sonic-pfc-priority-queue-map { - list MAP_PFC_PRIORITY_TO_QUEUE { - key "name"; - scommon:map-list true; //special conversion for map tables - scommon:map-leaf "pfc_priority qindex"; //every key:value pair is mapped to list keys, e.g. "1":"7" ==> tc_num=1, dscp=7 - leaf name { - type string; - } + container MAP_PFC_PRIORITY_TO_QUEUE { - list MAP_PFC_PRIORITY_TO_QUEUE { //this is list inside list for storing mapping between two fields - key "pfc_priority qindex"; + list MAP_PFC_PRIORITY_TO_QUEUE_LIST { + key "name"; + sonic-ext:map-list true; //special conversion for map tables + sonic-ext:map-leaf "pfc_priority qindex"; //every key:value pair is mapped to list keys, e.g. "1":"7" ==> tc_num=1, dscp=7 - leaf pfc_priority { - type string { - pattern "[0-9]?"; - } + leaf name { + type string; } - leaf qindex { - type string { - pattern "[0-9]?"; + list MAP_PFC_PRIORITY_TO_QUEUE { //this is list inside list for storing mapping between two fields + key "pfc_priority qindex"; + + leaf pfc_priority { + type string { + pattern "[0-9]?"; + } + } + + leaf qindex { + type string { + pattern "[0-9]?"; + } } } - } + } } } } diff --git a/src/cvl/testdata/schema/sonic-port-qos-map.yang b/src/cvl/testdata/schema/sonic-port-qos-map.yang index eeb5ca0bbc..f9785cb46a 100644 --- a/src/cvl/testdata/schema/sonic-port-qos-map.yang +++ b/src/cvl/testdata/schema/sonic-port-qos-map.yang @@ -2,12 +2,8 @@ module sonic-port-qos-map { namespace "http://github.com/Azure/sonic-port-qos-map"; prefix pqm; - import ietf-yang-types { - prefix yang; - } - - import sonic-common { - prefix scommon; + import sonic-extension { + prefix sonic-ext; } import sonic-port { @@ -48,24 +44,24 @@ module sonic-port-qos-map { list PORT_QOS_MAP { key "ifname"; - scommon:key-pattern "PORT_QOS_MAP|({ifname},)*"; //special pattern used for extracting keys from redis-key and fill populate the yang instance + sonic-ext:key-pattern "PORT_QOS_MAP|({ifname},)*"; //special pattern used for extracting keys from redis-key and fill populate the yang instance // Total list instance = number(key1) * number(key2) * number(key3) leaf ifname { type leafref { - path "/prt:sonic-port/prt:PORT/prt:ifname"; + path "/prt:sonic-port/prt:PORT/prt:PORT_LIST/prt:ifname"; } } leaf tc_to_pg_map { type leafref { - path "/tpg:sonic-tc-priority-group-map/tpg:TC_TO_PRIORITY_GROUP_MAP/tpg:name"; + path "/tpg:sonic-tc-priority-group-map/tpg:TC_TO_PRIORITY_GROUP_MAP/tpg:TC_TO_PRIORITY_GROUP_MAP_LIST/tpg:name"; } } leaf tc_to_queue_map { type leafref { - path "/tqm:sonic-tc-queue-map/tqm:TC_TO_QUEUE_MAP/tqm:name"; + path "/tqm:sonic-tc-queue-map/tqm:TC_TO_QUEUE_MAP/tqm:TC_TO_QUEUE_MAP_LIST/tqm:name"; } } @@ -77,13 +73,13 @@ module sonic-port-qos-map { leaf pfc_to_queue_map { type leafref { - path "/ppq:sonic-pfc-priority-queue-map/ppq:MAP_PFC_PRIORITY_TO_QUEUE/ppq:name"; + path "/ppq:sonic-pfc-priority-queue-map/ppq:MAP_PFC_PRIORITY_TO_QUEUE/ppq:MAP_PFC_PRIORITY_TO_QUEUE_LIST/ppq:name"; } } leaf dscp_to_tc_map { type leafref { - path "/dtm:sonic-dscp-tc-map/dtm:DSCP_TO_TC_MAP/dtm:name"; + path "/dtm:sonic-dscp-tc-map/dtm:DSCP_TO_TC_MAP/dtm:DSCP_TO_TC_MAP_LIST/dtm:name"; } } } diff --git a/src/cvl/testdata/schema/sonic-portchannel-interface.yang b/src/cvl/testdata/schema/sonic-portchannel-interface.yang index 305fd6ae76..45d92787d2 100644 --- a/src/cvl/testdata/schema/sonic-portchannel-interface.yang +++ b/src/cvl/testdata/schema/sonic-portchannel-interface.yang @@ -2,16 +2,8 @@ module sonic-portchannel-interface { namespace "http://github.com/Azure/sonic-portchannel-interface"; prefix spchint; - import ietf-yang-types { - prefix yang; - } - import ietf-inet-types { - prefix inet; - } - - import sonic-common { - prefix scommon; + prefix inet; } import sonic-portchannel { @@ -33,19 +25,23 @@ module sonic-portchannel-interface { } container sonic-portchannel-interface { - list PORTCHANNEL_INTERFACE { - key "pch_name ip_prefix"; - leaf pch_name{ - type leafref { - path "/spc:sonic-portchannel/spc:PORTCHANNEL/spc:name"; - } - } + container PORTCHANNEL_INTERFACE { + + list PORTCHANNEL_INTERFACE_LIST { + key "pch_name ip_prefix"; + + leaf pch_name{ + type leafref { + path "/spc:sonic-portchannel/spc:PORTCHANNEL/spc:PORTCHANNEL_LIST/spc:name"; + } + } - leaf ip_prefix { - mandatory true; - type inet:ip-prefix; + leaf ip_prefix { + mandatory true; + type inet:ip-prefix; + } } } } diff --git a/src/cvl/testdata/schema/sonic-portchannel.yang b/src/cvl/testdata/schema/sonic-portchannel.yang index 4ecd3a33d6..afe308f4e5 100644 --- a/src/cvl/testdata/schema/sonic-portchannel.yang +++ b/src/cvl/testdata/schema/sonic-portchannel.yang @@ -2,10 +2,6 @@ module sonic-portchannel { namespace "http://github.com/Azure/sonic-portchannel"; prefix spc; - import ietf-yang-types { - prefix yang; - } - import sonic-common { prefix scommon; } @@ -30,48 +26,52 @@ module sonic-portchannel { container sonic-portchannel { - list PORTCHANNEL { - key "name"; + container PORTCHANNEL { - max-elements 3; + list PORTCHANNEL_LIST { + key "name"; - leaf name { - type string; - } + max-elements 3; - leaf admin_status { - type scommon:admin-status; - } + leaf name { + type string; + } - leaf mtu { - type uint16; - } + leaf admin_status { + type scommon:admin-status; + } - leaf min_links { - type uint8; - } + leaf mtu { + type uint16; + } + + leaf min_links { + type uint8; + } - leaf fallback { - type boolean; + leaf fallback { + type boolean; + } } } - list PORTCHANNEL_MEMBER { - key "name ifname"; - scommon:key-delim "|"; - scommon:key-pattern "PORTCHANNEL|{name}|{ifname}"; + container PORTCHANNEL_MEMBER { - leaf name { - type leafref { - path "../../PORTCHANNEL/name"; + list PORTCHANNEL_MEMBER_LIST { + key "name ifname"; + + leaf name { + type leafref { + path "../../../PORTCHANNEL/PORTCHANNEL_LIST/name"; + } } - } - leaf ifname { - type leafref { - path "/prt:sonic-port/prt:PORT/prt:ifname"; + leaf ifname { + type leafref { + path "/prt:sonic-port/prt:PORT/prt:PORT_LIST/prt:ifname"; + } } } } - } + } } diff --git a/src/cvl/testdata/schema/sonic-queue.yang b/src/cvl/testdata/schema/sonic-queue.yang index fb55793443..92a7f4c96f 100644 --- a/src/cvl/testdata/schema/sonic-queue.yang +++ b/src/cvl/testdata/schema/sonic-queue.yang @@ -2,12 +2,8 @@ module sonic-queue { namespace "http://github.com/Azure/sonic-queue"; prefix squeue; - import ietf-yang-types { - prefix yang; - } - - import sonic-common { - prefix scommon; + import sonic-extension { + prefix sonic-ext; } import sonic-port { @@ -38,35 +34,39 @@ module sonic-queue { container sonic-queue { - list QUEUE { - key "ifname qindex"; - scommon:key-pattern "QUEUE|({ifname},)*|{qindex}"; //special pattern used for extracting keys from redis-key and populate the yang instance - // Total list instances = number(key1) * number(key2) * number(key3) - - leaf ifname { - type leafref { - path "/prt:sonic-port/prt:PORT/prt:ifname"; + + container QUEUE { + + list QUEUE_LIST { + key "ifname qindex"; + sonic-ext:key-pattern "QUEUE|({ifname},)*|{qindex}"; //special pattern used for extracting keys from redis-key and populate the yang instance + // Total list instances = number(key1) * number(key2) * number(key3) + + leaf ifname { + type leafref { + path "/prt:sonic-port/prt:PORT/prt:PORT_LIST/prt:ifname"; + } } - } - leaf qindex { - type string { - pattern "[0-8]((-)[0-8])?"{ - error-message "Invalid Q-index"; - error-app-tag qindex-invalid; + leaf qindex { + type string { + pattern "[0-8]((-)[0-8])?"{ + error-message "Invalid Q-index"; + error-app-tag qindex-invalid; + } } } - } - leaf scheduler { - type leafref { - path "/sch:sonic-scheduler/sch:SCHEDULER/sch:name"; + leaf scheduler { + type leafref { + path "/sch:sonic-scheduler/sch:SCHEDULER/sch:SCHEDULER_LIST/sch:name"; + } } - } - leaf wred_profile { - type leafref { - path "/wrd:sonic-wred-profile/wrd:WRED_PROFILE/wrd:name"; + leaf wred_profile { + type leafref { + path "/wrd:sonic-wred-profile/wrd:WRED_PROFILE/wrd:WRED_PROFILE_LIST/wrd:name"; + } } } } diff --git a/src/cvl/testdata/schema/sonic-scheduler.yang b/src/cvl/testdata/schema/sonic-scheduler.yang index d1e26ab359..2fc7997f71 100644 --- a/src/cvl/testdata/schema/sonic-scheduler.yang +++ b/src/cvl/testdata/schema/sonic-scheduler.yang @@ -2,14 +2,6 @@ module sonic-scheduler { namespace "http://github.com/Azure/sonic-scheduler"; prefix sch; - import ietf-yang-types { - prefix yang; - } - - import sonic-common { - prefix scommon; - } - organization "SONiC"; @@ -25,30 +17,34 @@ module sonic-scheduler { } container sonic-scheduler { - list SCHEDULER { - key "name"; - leaf name{ - type string; - } + container SCHEDULER { - leaf type { - type enumeration { - enum DWRR; - enum WRR; - enum PRIORITY; + list SCHEDULER_LIST { + key "name"; + + leaf name{ + type string; } - } - leaf weight { - type uint8 { - range "0..255"; + leaf type { + type enumeration { + enum DWRR; + enum WRR; + enum PRIORITY; + } + } + + leaf weight { + type uint8 { + range "0..255"; + } } - } - leaf priority { - type uint8 { - range "0..9"; + leaf priority { + type uint8 { + range "0..9"; + } } } } diff --git a/src/cvl/testdata/schema/sonic-tc-priority-group-map.yang b/src/cvl/testdata/schema/sonic-tc-priority-group-map.yang index 253ed0f47b..ed89a281ec 100644 --- a/src/cvl/testdata/schema/sonic-tc-priority-group-map.yang +++ b/src/cvl/testdata/schema/sonic-tc-priority-group-map.yang @@ -2,12 +2,8 @@ module sonic-tc-priority-group-map { namespace "http://github.com/Azure/sonic-tc-priority-group-map"; prefix tpg; - import ietf-yang-types { - prefix yang; - } - - import sonic-common { - prefix scommon; + import sonic-extension { + prefix sonic-ext; } organization @@ -25,31 +21,34 @@ module sonic-tc-priority-group-map { } container sonic-tc-priority-group-map { - list TC_TO_PRIORITY_GROUP_MAP { - key "name"; - scommon:map-list "true"; //special conversion for map tables - scommon:map-leaf "tc_num pg_num"; //every key:value pair is mapped to list keys, e.g. "1":"7" ==> tc_num=1, dscp=7 - leaf name { - type string; - } + container TC_TO_PRIORITY_GROUP_MAP { - list TC_TO_PRIORITY_GROUP_MAP { //this is list inside list for storing mapping between two fields - key "tc_num pg_num"; + list TC_TO_PRIORITY_GROUP_MAP_LIST { + key "name"; + sonic-ext:map-list "true"; //special conversion for map tables + sonic-ext:map-leaf "tc_num pg_num"; //every key:value pair is mapped to list keys, e.g. "1":"7" ==> tc_num=1, dscp=7 - leaf tc_num { - type string { - pattern "[0-9]?"; - } + leaf name { + type string; } - leaf pg_num { - type string { - pattern "[0-7]?"; + list TC_TO_PRIORITY_GROUP_MAP { //this is list inside list for storing mapping between two fields + key "tc_num pg_num"; + + leaf tc_num { + type string { + pattern "[0-9]?"; + } + } + + leaf pg_num { + type string { + pattern "[0-7]?"; + } } } } - } } } diff --git a/src/cvl/testdata/schema/sonic-tc-queue-map.yang b/src/cvl/testdata/schema/sonic-tc-queue-map.yang index 385b9edfac..37ab1c8113 100644 --- a/src/cvl/testdata/schema/sonic-tc-queue-map.yang +++ b/src/cvl/testdata/schema/sonic-tc-queue-map.yang @@ -2,12 +2,8 @@ module sonic-tc-queue-map { namespace "http://github.com/Azure/sonic-tc-queue-map"; prefix tqm; - import ietf-yang-types { - prefix yang; - } - - import sonic-common { - prefix scommon; + import sonic-extension { + prefix sonic-ext; } organization @@ -25,31 +21,35 @@ module sonic-tc-queue-map { } container sonic-tc-queue-map { - list TC_TO_QUEUE_MAP { - key "name"; - scommon:map-list "true"; //special conversion for map tables - scommon:map-leaf "tc_num qindex"; //every key:value pair is mapped to list keys, e.g. "1":"7" ==> tc_num=1, qindex=7 - leaf name { - type string; - } + container TC_TO_QUEUE_MAP { - list TC_TO_QUEUE_MAP { //this is list inside list for storing mapping between two fields - key "tc_num qindex"; + list TC_TO_QUEUE_MAP_LIST { + key "name"; + sonic-ext:map-list "true"; //special conversion for map tables + sonic-ext:map-leaf "tc_num qindex"; //every key:value pair is mapped to list keys, e.g. "1":"7" ==> tc_num=1, qindex=7 - leaf tc_num { - type string { - pattern "[0-9]?"; - } + leaf name { + type string; } - leaf qindex { - type string { - pattern "[0-9]?"; + list TC_TO_QUEUE_MAP { //this is list inside list for storing mapping between two fields + key "tc_num qindex"; + + leaf tc_num { + type string { + pattern "[0-9]?"; + } + } + + leaf qindex { + type string { + pattern "[0-9]?"; + } } } - } + } } } } diff --git a/src/cvl/testdata/schema/sonic-vlan-dev.yang b/src/cvl/testdata/schema/sonic-vlan-dev.yang index dcb6531126..7cc5784851 100644 --- a/src/cvl/testdata/schema/sonic-vlan-dev.yang +++ b/src/cvl/testdata/schema/sonic-vlan-dev.yang @@ -3,13 +3,11 @@ module sonic-vlan-dev { prefix svd; yang-version 1.1; - import ietf-yang-types { - prefix yang; - } - + /* import sonic-vlan { prefix svlan; } + */ organization "SONiC"; diff --git a/src/cvl/testdata/schema/sonic-vlan-interface.yang b/src/cvl/testdata/schema/sonic-vlan-interface.yang index 86b9f8c0f3..554feb1f58 100644 --- a/src/cvl/testdata/schema/sonic-vlan-interface.yang +++ b/src/cvl/testdata/schema/sonic-vlan-interface.yang @@ -2,16 +2,8 @@ module sonic-vlan-interface { namespace "http://github.com/Azure/sonic-vlan-interface"; prefix svint; - import ietf-yang-types { - prefix yang; - } - import ietf-inet-types { - prefix inet; - } - - import sonic-common { - prefix scommon; + prefix inet; } import sonic-vlan { @@ -33,19 +25,23 @@ module sonic-vlan-interface { } container sonic-vlan-interface { - list VLAN_INTERFACE { - key "portname ip_prefix"; - leaf portname{ - type leafref { - path "/svlan:sonic-vlan/svlan:VLAN/svlan:name"; - } - } + container VLAN_INTERFACE { + + list VLAN_INTERFACE_LIST { + key "portname ip_prefix"; + + leaf portname{ + type leafref { + path "/svlan:sonic-vlan/svlan:VLAN/svlan:VLAN_LIST/svlan:name"; + } + } - leaf ip_prefix { - mandatory true; - type inet:ip-prefix; + leaf ip_prefix { + mandatory true; + type inet:ip-prefix; + } } } } diff --git a/src/cvl/testdata/schema/sonic-vlan.yang b/src/cvl/testdata/schema/sonic-vlan.yang index 5a043b5f22..1170960df1 100644 --- a/src/cvl/testdata/schema/sonic-vlan.yang +++ b/src/cvl/testdata/schema/sonic-vlan.yang @@ -3,10 +3,6 @@ module sonic-vlan { prefix svlan; yang-version 1.1; - import ietf-yang-types { - prefix yang; - } - import sonic-common { prefix scommon; } @@ -36,72 +32,76 @@ module sonic-vlan { container sonic-vlan { - list VLAN { - key "name"; - must "./name = concat('Vlan', string(./vlanid))"{ - error-app-tag vlan-invalid; - } + container VLAN { - leaf name { - type string { - pattern "Vlan(409[0-5]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{2}|[1-9][0-9]|[1-9])" { - error-message "Invalid Vlan name pattern"; - error-app-tag vlan-name-invalid; + list VLAN_LIST { + key "name"; + must "./name = concat('Vlan', string(./vlanid))"{ + error-app-tag vlan-invalid; + } + + leaf name { + type string { + pattern "Vlan(409[0-5]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{2}|[1-9][0-9]|[1-9])" { + error-message "Invalid Vlan name pattern"; + error-app-tag vlan-name-invalid; + } } } - } - leaf vlanid { - mandatory true; - type uint16 { - range "1..4095" { - error-message "Vlan ID out of range"; - error-app-tag vlanid-invalid; + leaf vlanid { + mandatory true; + type uint16 { + range "1..4095" { + error-message "Vlan ID out of range"; + error-app-tag vlanid-invalid; + } } } - } - leaf-list members { - must "count(../members[text()=/spc:sonic-portchannel/" + - "spc:PORTCHANNEL_MEMBER[spc:ifname=current()]/spc:name]) = 0 and " + - "count(../members[text()=/spc:sonic-portchannel/" + - "spc:PORTCHANNEL_MEMBER[spc:name=current()]/spc:ifname]) = 0 " { - error-message "A vlan interface member cannot be part of portchannel which is already a vlan member"; - } + leaf-list members { + must "count(../members[text()=/spc:sonic-portchannel/spc:PORTCHANNEL_MEMBER/" + + "spc:PORTCHANNEL_MEMBER_LIST[spc:ifname=current()]/spc:name]) = 0 and " + + "count(../members[text()=/spc:sonic-portchannel/spc:PORTCHANNEL_MEMBER/" + + "spc:PORTCHANNEL_MEMBER_LIST[spc:name=current()]/spc:ifname]) = 0 " { + error-message "A vlan interface member cannot be part of portchannel which is already a vlan member"; + } - type union { - type leafref { - path "/prt:sonic-port/prt:PORT/prt:ifname"; - } - type leafref { - path "/spc:sonic-portchannel/spc:PORTCHANNEL/spc:name"; + type union { + type leafref { + path "/prt:sonic-port/prt:PORT/prt:PORT_LIST/prt:ifname"; + } + type leafref { + path "/spc:sonic-portchannel/spc:PORTCHANNEL/spc:PORTCHANNEL_LIST/spc:name"; + } } } } } - list VLAN_MEMBER { - key "name ifname"; + container VLAN_MEMBER { - leaf name { - type leafref { - path "../../VLAN/name"; + list VLAN_MEMBER_LIST { + key "name ifname"; + + leaf name { + type leafref { + path "../../../VLAN/VLAN_LIST/name"; + } } - } - leaf ifname { - type leafref { - path "/prt:sonic-port/prt:PORT/prt:ifname"; + leaf ifname { + type leafref { + path "/prt:sonic-port/prt:PORT/prt:PORT_LIST/prt:ifname"; + } } - } - leaf tagging_mode { - type scommon:tagging_mode; - default tagged; + leaf tagging_mode { + type scommon:tagging_mode; + default tagged; + } } } - } - } diff --git a/src/cvl/testdata/schema/sonic-wred-profile.yang b/src/cvl/testdata/schema/sonic-wred-profile.yang index 89b9c90ef5..e3c5abe363 100644 --- a/src/cvl/testdata/schema/sonic-wred-profile.yang +++ b/src/cvl/testdata/schema/sonic-wred-profile.yang @@ -2,14 +2,6 @@ module sonic-wred-profile { namespace "http://github.com/Azure/sonic-wred-profile"; prefix wrd; - import ietf-yang-types { - prefix yang; - } - - import sonic-common { - prefix scommon; - } - organization "SONiC"; @@ -25,59 +17,63 @@ module sonic-wred-profile { } container sonic-wred-profile { - list WRED_PROFILE { - key "name"; - leaf name{ - type string; - } + container WRED_PROFILE { - leaf yellow_min_threshold { - type uint64; - } + list WRED_PROFILE_LIST { + key "name"; - leaf green_min_threshold { - type uint64; - } + leaf name{ + type string; + } - leaf red_min_threshold { - type uint64; - } - leaf yellow_max_threshold { - type uint64; - } + leaf yellow_min_threshold { + type uint64; + } - leaf green_max_threshold { - type uint64; - } + leaf green_min_threshold { + type uint64; + } - leaf red_max_threshold { - type uint64; - } + leaf red_min_threshold { + type uint64; + } + leaf yellow_max_threshold { + type uint64; + } - leaf ecn { - type enumeration { - enum ecn_none; - enum ecn_green; - enum ecn_yellow; - enum ecn_red; - enum ecn_green_yellow; - enum ecn_green_red; - enum ecn_yellow_red; - enum ecn_all; + leaf green_max_threshold { + type uint64; } - } - leaf wred_green_enable { - type boolean; - } + leaf red_max_threshold { + type uint64; + } - leaf wred_yellow_enable { - type boolean; - } + leaf ecn { + type enumeration { + enum ecn_none; + enum ecn_green; + enum ecn_yellow; + enum ecn_red; + enum ecn_green_yellow; + enum ecn_green_red; + enum ecn_yellow_red; + enum ecn_all; + } + } + + leaf wred_green_enable { + type boolean; + } - leaf wred_red_enable { - type boolean; + leaf wred_yellow_enable { + type boolean; + } + + leaf wred_red_enable { + type boolean; + } } } } From 58da2b578f8f735eddf037b5b13c6cc04a928ec7 Mon Sep 17 00:00:00 2001 From: Partha Dutta Date: Sat, 21 Sep 2019 12:02:19 +0530 Subject: [PATCH 2/4] CVL changes for SONiC YANG --- src/cvl/schema/Makefile | 4 +- src/cvl/schema/sonic-interface.yang | 8 - src/cvl/schema/sonic-mirror-session.yang | 8 - tools/pyang/pyang_plugins/yin_cvl.py | 179 +++++++++++++++++++++++ 4 files changed, 180 insertions(+), 19 deletions(-) create mode 100644 tools/pyang/pyang_plugins/yin_cvl.py diff --git a/src/cvl/schema/Makefile b/src/cvl/schema/Makefile index 1408bb1f58..fe23d1ce71 100644 --- a/src/cvl/schema/Makefile +++ b/src/cvl/schema/Makefile @@ -10,9 +10,7 @@ schema: $(out) @echo "Generating $@ ..." @devFile="`echo $< | cut -d . -f1`-dev.yang"; \ if [ -f $$devFile ] ; then devOpt="--deviation-module $$devFile"; fi; \ - pyang -p ./ietf/ -f yin $$devOpt $< -o $@.tmp - @xmllint --noblanks $@.tmp > $@ - @rm -rf $@.tmp + pyang -p ./ietf/ --plugindir ../../../tools/pyang/pyang_plugins/ -f yin-cvl $$devOpt $< -o $@ %.tree:%.yang @echo "Generating $@ ..." diff --git a/src/cvl/schema/sonic-interface.yang b/src/cvl/schema/sonic-interface.yang index 79ca4832e8..f51a37f43a 100644 --- a/src/cvl/schema/sonic-interface.yang +++ b/src/cvl/schema/sonic-interface.yang @@ -2,18 +2,10 @@ module sonic-interface { namespace "http://github.com/Azure/sonic-interface"; prefix sint; - import ietf-yang-types { - prefix yang; - } - import ietf-inet-types { prefix inet; } - import sonic-common { - prefix scommon; - } - import sonic-port { prefix prt; } diff --git a/src/cvl/schema/sonic-mirror-session.yang b/src/cvl/schema/sonic-mirror-session.yang index 9805a121fa..ff18b5a14a 100644 --- a/src/cvl/schema/sonic-mirror-session.yang +++ b/src/cvl/schema/sonic-mirror-session.yang @@ -2,18 +2,10 @@ module sonic-mirror-session { namespace "http://github.com/Azure/sonic-mirror-session"; prefix sms; - import ietf-yang-types { - prefix yang; - } - import ietf-inet-types { prefix inet; } - import sonic-common { - prefix scommon; - } - organization "SONiC"; diff --git a/tools/pyang/pyang_plugins/yin_cvl.py b/tools/pyang/pyang_plugins/yin_cvl.py new file mode 100644 index 0000000000..7e03b3a0c0 --- /dev/null +++ b/tools/pyang/pyang_plugins/yin_cvl.py @@ -0,0 +1,179 @@ +################################################################################ +# # +# Copyright 2019 Broadcom. The term Broadcom refers to Broadcom Inc. and/or # +# its subsidiaries. # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +# # +################################################################################ +"""CVL YIN output plugin""" + +from xml.sax.saxutils import quoteattr +from xml.sax.saxutils import escape + +import optparse +import re + +from pyang import plugin +from pyang import util +from pyang import grammar +from pyang import syntax +from pyang import statements + +new_line='' #replace with '\n' for adding new line +indent_space= '' #replace with ' ' for indentation +ns_indent_space= '' #replace with ' ' for indentation +yin_namespace = "urn:ietf:params:xml:ns:yang:yin:1" +revision_added = False + +def pyang_plugin_init(): + plugin.register_plugin(YINPluginCVL()) + +class YINPluginCVL(plugin.PyangPlugin): + def add_output_format(self, fmts): + fmts['yin-cvl'] = self + def emit(self, ctx, modules, fd): + module = modules[0] + emit_yin(ctx, module, fd) + +def emit_yin(ctx, module, fd): + fd.write('' + new_line) + fd.write(('<%s name="%s"' + new_line) % (module.keyword, module.arg)) + fd.write(ns_indent_space * len(module.keyword) + ns_indent_space + ' xmlns="%s"' % yin_namespace) + + prefix = module.search_one('prefix') + if prefix is not None: + namespace = module.search_one('namespace') + fd.write('' + new_line) + fd.write(ns_indent_space * len(module.keyword)) + fd.write(ns_indent_space + ' xmlns:' + prefix.arg + '=' + + quoteattr(namespace.arg)) + else: + belongs_to = module.search_one('belongs-to') + if belongs_to is not None: + prefix = belongs_to.search_one('prefix') + if prefix is not None: + # read the parent module in order to find the namespace uri + res = ctx.read_module(belongs_to.arg, extra={'no_include':True}) + if res is not None: + namespace = res.search_one('namespace') + if namespace is None or namespace.arg is None: + pass + else: + # success - namespace found + fd.write('' + new_line) + fd.write(sonic-acl.yin * len(module.keyword)) + fd.write(sonic-acl.yin + ' xmlns:' + prefix.arg + '=' + + quoteattr(namespace.arg)) + + for imp in module.search('import'): + prefix = imp.search_one('prefix') + if prefix is not None: + rev = None + r = imp.search_one('revision-date') + if r is not None: + rev = r.arg + mod = statements.modulename_to_module(module, imp.arg, rev) + if mod is not None: + ns = mod.search_one('namespace') + if ns is not None: + fd.write('' + new_line) + fd.write(ns_indent_space * len(module.keyword)) + fd.write(ns_indent_space + ' xmlns:' + prefix.arg + '=' + + quoteattr(ns.arg)) + fd.write('>' + new_line) + + substmts = module.substmts + for s in substmts: + emit_stmt(ctx, module, s, fd, indent_space, indent_space) + fd.write(('' + new_line) % module.keyword) + +def emit_stmt(ctx, module, stmt, fd, indent, indentstep): + global revision_added + + if stmt.raw_keyword == "revision" and revision_added == False: + revision_added = True + elif stmt.raw_keyword == "revision" and revision_added == True: + #Only add the latest revision + return + + #Don't keep the following keywords as they are not used in CVL + # stmt.raw_keyword == "revision" or + if ((stmt.raw_keyword == "organization" or + stmt.raw_keyword == "contact" or + stmt.raw_keyword == "rpc" or + stmt.raw_keyword == "notification" or + stmt.raw_keyword == "description") or + (len(stmt.substmts) > 0 and stmt.substmts[0].raw_keyword == "config" and + stmt.substmts[0].arg == "false")): + return + + if util.is_prefixed(stmt.raw_keyword): + # this is an extension. need to find its definition + (prefix, identifier) = stmt.raw_keyword + tag = prefix + ':' + identifier + if stmt.i_extension is not None: + ext_arg = stmt.i_extension.search_one('argument') + if ext_arg is not None: + yin_element = ext_arg.search_one('yin-element') + if yin_element is not None and yin_element.arg == 'true': + argname = prefix + ':' + ext_arg.arg + argiselem = True + else: + # explicit false or no yin-element given + argname = ext_arg.arg + argiselem = False + else: + argiselem = False + argname = None + else: + argiselem = False + argname = None + else: + (argname, argiselem) = syntax.yin_map[stmt.raw_keyword] + tag = stmt.raw_keyword + if argiselem == False or argname is None: + if argname is None: + attr = '' + else: + attr = ' ' + argname + '=' + quoteattr(stmt.arg) + if len(stmt.substmts) == 0: + fd.write(indent + '<' + tag + attr + '/>' + new_line) + else: + fd.write(indent + '<' + tag + attr + '>' + new_line) + for s in stmt.substmts: + emit_stmt(ctx, module, s, fd, indent + indentstep, + indentstep) + fd.write(indent + '' + new_line) + else: + fd.write(indent + '<' + tag + '>' + new_line) + fd.write(indent + indentstep + '<' + argname + '>' + \ + escape(stmt.arg) + \ + '' + new_line) + substmts = stmt.substmts + + for s in substmts: + emit_stmt(ctx, module, s, fd, indent + indentstep, indentstep) + + fd.write(indent + '' + new_line) + +def fmt_text(indent, data): + res = [] + for line in re.split("(\n)", escape(data)): + if line == '': + continue + if line == '' + new_line: + res.extend(line) + else: + res.extend(indent + line) + return ''.join(res) From e1d4cf7378fafcdc625cf5a8203e466215ef51bc Mon Sep 17 00:00:00 2001 From: Partha Dutta Date: Thu, 26 Sep 2019 23:27:43 +0530 Subject: [PATCH 3/4] More changes for CVL YANG --- models/yang/sonic/Makefile | 53 ++ .../sonic/common/ietf/ietf-inet-types.yang | 457 +++++++++++++++++ .../sonic/common/ietf/ietf-yang-types.yang | 474 ++++++++++++++++++ .../yang/sonic/common}/sonic-common.yang | 0 .../yang/sonic/common}/sonic-extension.yang | 0 .../yang/sonic}/sonic-acl.yang | 4 - .../yang/sonic}/sonic-interface.yang | 15 + .../yang/sonic}/sonic-mirror-session.yang | 0 .../yang/sonic}/sonic-port.yang | 0 src/cvl/cvl.go | 89 +++- src/cvl/cvl_api.go | 3 +- src/cvl/schema/Makefile | 40 +- src/cvl/testdata/schema/Makefile | 18 +- ...-acl-dev.yang => sonic-acl-deviation.yang} | 4 +- .../testdata/schema/sonic-dscp-tc-map.yang | 4 - ...lan-dev.yang => sonic-vlan-deviation.yang} | 4 +- tools/pyang/pyang_plugins/yin_cvl.py | 6 +- 17 files changed, 1129 insertions(+), 42 deletions(-) create mode 100644 models/yang/sonic/Makefile create mode 100644 models/yang/sonic/common/ietf/ietf-inet-types.yang create mode 100644 models/yang/sonic/common/ietf/ietf-yang-types.yang rename {src/cvl/schema => models/yang/sonic/common}/sonic-common.yang (100%) rename {src/cvl/schema => models/yang/sonic/common}/sonic-extension.yang (100%) rename {src/cvl/schema => models/yang/sonic}/sonic-acl.yang (98%) rename {src/cvl/schema => models/yang/sonic}/sonic-interface.yang (74%) rename {src/cvl/schema => models/yang/sonic}/sonic-mirror-session.yang (100%) rename {src/cvl/schema => models/yang/sonic}/sonic-port.yang (100%) rename src/cvl/testdata/schema/{sonic-acl-dev.yang => sonic-acl-deviation.yang} (85%) rename src/cvl/testdata/schema/{sonic-vlan-dev.yang => sonic-vlan-deviation.yang} (83%) diff --git a/models/yang/sonic/Makefile b/models/yang/sonic/Makefile new file mode 100644 index 0000000000..9141ff952a --- /dev/null +++ b/models/yang/sonic/Makefile @@ -0,0 +1,53 @@ +TOPDIR := ../../../ +SONIC_YANGAPI_DIR := $(TOPDIR)/build/yaml +SONIC_YANGDIR := $(TOPDIR)/models/yang/sonic +SONIC_YANGDIR_DEVIATION := $(TOPDIR)/models/yang/sonic/deviation +SONIC_YANGDIR_COMMON := $(TOPDIR)/models/yang/sonic/common +SONIC_YANGDIR_COMMON_IETF := $(TOPDIR)/models/yang/sonic/common/ietf +SONIC_YANG_MOD_FILES := $(shell find $(SONIC_YANGDIR) -maxdepth 1 -name '*.yang' | sort) +SONIC_YANG_COMMON_FILES := $(shell find $(SONIC_YANGDIR_COMMON) -name '*.yang' | sort) +SONIC_YANG_COMMON_FILES += $(shell find $(SONIC_YANGDIR_COMMON_IETF) -name '*.yang' | sort) + +SONIC_TOOLS_DIR := $(TOPDIR)/tools +SONIC_PYANG_DIR := $(SONIC_TOOLS_DIR)/pyang +SONIC_PYANG_PLUGIN_DIR := $(SONIC_PYANG_DIR)/pyang_plugins +SONIC_PYANG_BIN := pyang + +all: yamlGen allyangs.tree allyangs_tree.html + +#yamlGen: $(SONIC_YANGAPI_DIR)/.done + +allyangs.tree: $(SONIC_YANG_MOD_FILES) $(SONIC_YANG_COMMON_FILES) + $(SONIC_PYANG_BIN) \ + -f tree \ + -o $(SONIC_YANGDIR)/$@ \ + -p $(SONIC_YANGDIR_COMMON):$(SONIC_YANGDIR) \ + $(SONIC_YANG_MOD_FILES) + @echo "+++++ Generation of YANG tree for Sonic Yang modules completed +++++" + +allyangs_tree.html: $(SONIC_YANG_MOD_FILES) $(SONIC_YANG_COMMON_FILES) + $(SONIC_PYANG_BIN) \ + -f jstree \ + -o $(SONIC_YANGDIR)/$@ \ + -p $(SONIC_YANGDIR_COMMON):$(SONIC_YANGDIR) \ + $(SONIC_YANG_MOD_FILES) + @echo "+++++ Generation of HTML tree for Sonic Yang modules completed +++++" + +#====================================================================== +# Generate YAML files for SONiC YANG modules +#====================================================================== +yamlGen: + @echo "+++++ Generating YAML files for Sonic Yang modules +++++" + mkdir -p $(SONIC_YANGAPI_DIR) + $(SONIC_PYANG_BIN) \ + -f swaggerapi \ + --outdir $(SONIC_YANGAPI_DIR) \ + --plugindir $(SONIC_PYANG_PLUGIN_DIR) \ + -p $(SONIC_YANGDIR_COMMON):$(SONIC_YANGDIR) \ + $(SONIC_YANG_MOD_FILES) + @echo "+++++ Generation of YAML files for Sonic Yang modules completed +++++" + +clean: + @echo "Removing files ..." + rm -rf $(SONIC_YANGAPI_DIR) + rm -rf allyangs.tree allyangs_tree.html diff --git a/models/yang/sonic/common/ietf/ietf-inet-types.yang b/models/yang/sonic/common/ietf/ietf-inet-types.yang new file mode 100644 index 0000000000..2f14270dec --- /dev/null +++ b/models/yang/sonic/common/ietf/ietf-inet-types.yang @@ -0,0 +1,457 @@ +module ietf-inet-types { + + namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types"; + prefix "inet"; + + organization + "IETF NETMOD (NETCONF Data Modeling Language) Working Group"; + + contact + "WG Web: + WG List: + + WG Chair: David Kessens + + + WG Chair: Juergen Schoenwaelder + + + Editor: Juergen Schoenwaelder + "; + + description + "This module contains a collection of generally useful derived + YANG data types for Internet addresses and related things. + + Copyright (c) 2013 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (http://trustee.ietf.org/license-info). + + This version of this YANG module is part of RFC 6991; see + the RFC itself for full legal notices."; + + revision 2013-07-15 { + description + "This revision adds the following new data types: + - ip-address-no-zone + - ipv4-address-no-zone + - ipv6-address-no-zone"; + reference + "RFC 6991: Common YANG Data Types"; + } + + revision 2010-09-24 { + description + "Initial revision."; + reference + "RFC 6021: Common YANG Data Types"; + } + + /*** collection of types related to protocol fields ***/ + + typedef ip-version { + type enumeration { + enum unknown { + value "0"; + description + "An unknown or unspecified version of the Internet + protocol."; + } + enum ipv4 { + value "1"; + description + "The IPv4 protocol as defined in RFC 791."; + } + enum ipv6 { + value "2"; + description + "The IPv6 protocol as defined in RFC 2460."; + } + } + description + "This value represents the version of the IP protocol. + + In the value set and its semantics, this type is equivalent + to the InetVersion textual convention of the SMIv2."; + reference + "RFC 791: Internet Protocol + RFC 2460: Internet Protocol, Version 6 (IPv6) Specification + RFC 4001: Textual Conventions for Internet Network Addresses"; + } + + typedef dscp { + type uint8 { + range "0..63"; + } + description + "The dscp type represents a Differentiated Services Code Point + that may be used for marking packets in a traffic stream. + In the value set and its semantics, this type is equivalent + to the Dscp textual convention of the SMIv2."; + reference + "RFC 3289: Management Information Base for the Differentiated + Services Architecture + RFC 2474: Definition of the Differentiated Services Field + (DS Field) in the IPv4 and IPv6 Headers + RFC 2780: IANA Allocation Guidelines For Values In + the Internet Protocol and Related Headers"; + } + + typedef ipv6-flow-label { + type uint32 { + range "0..1048575"; + } + description + "The ipv6-flow-label type represents the flow identifier or Flow + Label in an IPv6 packet header that may be used to + discriminate traffic flows. + + In the value set and its semantics, this type is equivalent + to the IPv6FlowLabel textual convention of the SMIv2."; + reference + "RFC 3595: Textual Conventions for IPv6 Flow Label + RFC 2460: Internet Protocol, Version 6 (IPv6) Specification"; + } + + typedef port-number { + type uint16 { + range "0..65535"; + } + description + "The port-number type represents a 16-bit port number of an + Internet transport-layer protocol such as UDP, TCP, DCCP, or + SCTP. Port numbers are assigned by IANA. A current list of + all assignments is available from . + + Note that the port number value zero is reserved by IANA. In + situations where the value zero does not make sense, it can + be excluded by subtyping the port-number type. + In the value set and its semantics, this type is equivalent + to the InetPortNumber textual convention of the SMIv2."; + reference + "RFC 768: User Datagram Protocol + RFC 793: Transmission Control Protocol + RFC 4960: Stream Control Transmission Protocol + RFC 4340: Datagram Congestion Control Protocol (DCCP) + RFC 4001: Textual Conventions for Internet Network Addresses"; + } + + /*** collection of types related to autonomous systems ***/ + + typedef as-number { + type uint32; + description + "The as-number type represents autonomous system numbers + which identify an Autonomous System (AS). An AS is a set + of routers under a single technical administration, using + an interior gateway protocol and common metrics to route + packets within the AS, and using an exterior gateway + protocol to route packets to other ASes. IANA maintains + the AS number space and has delegated large parts to the + regional registries. + + Autonomous system numbers were originally limited to 16 + bits. BGP extensions have enlarged the autonomous system + number space to 32 bits. This type therefore uses an uint32 + base type without a range restriction in order to support + a larger autonomous system number space. + + In the value set and its semantics, this type is equivalent + to the InetAutonomousSystemNumber textual convention of + the SMIv2."; + reference + "RFC 1930: Guidelines for creation, selection, and registration + of an Autonomous System (AS) + RFC 4271: A Border Gateway Protocol 4 (BGP-4) + RFC 4001: Textual Conventions for Internet Network Addresses + RFC 6793: BGP Support for Four-Octet Autonomous System (AS) + Number Space"; + } + + /*** collection of types related to IP addresses and hostnames ***/ + + typedef ip-address { + type union { + type inet:ipv4-address; + type inet:ipv6-address; + } + description + "The ip-address type represents an IP address and is IP + version neutral. The format of the textual representation + implies the IP version. This type supports scoped addresses + by allowing zone identifiers in the address format."; + reference + "RFC 4007: IPv6 Scoped Address Architecture"; + } + + typedef ipv4-address { + type string { + pattern + '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}' + + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])' + + '(%[\p{N}\p{L}]+)?'; + } + description + "The ipv4-address type represents an IPv4 address in + dotted-quad notation. The IPv4 address may include a zone + index, separated by a % sign. + + The zone index is used to disambiguate identical address + values. For link-local addresses, the zone index will + typically be the interface index number or the name of an + interface. If the zone index is not present, the default + zone of the device will be used. + + The canonical format for the zone index is the numerical + format"; + } + + typedef ipv6-address { + type string { + pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}' + + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|' + + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}' + + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))' + + '(%[\p{N}\p{L}]+)?'; + pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|' + + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)' + + '(%.+)?'; + } + description + "The ipv6-address type represents an IPv6 address in full, + mixed, shortened, and shortened-mixed notation. The IPv6 + address may include a zone index, separated by a % sign. + + The zone index is used to disambiguate identical address + values. For link-local addresses, the zone index will + typically be the interface index number or the name of an + interface. If the zone index is not present, the default + zone of the device will be used. + + The canonical format of IPv6 addresses uses the textual + representation defined in Section 4 of RFC 5952. The + canonical format for the zone index is the numerical + format as described in Section 11.2 of RFC 4007."; + reference + "RFC 4291: IP Version 6 Addressing Architecture + RFC 4007: IPv6 Scoped Address Architecture + RFC 5952: A Recommendation for IPv6 Address Text + Representation"; + } + + typedef ip-address-no-zone { + type union { + type inet:ipv4-address-no-zone; + type inet:ipv6-address-no-zone; + } + description + "The ip-address-no-zone type represents an IP address and is + IP version neutral. The format of the textual representation + implies the IP version. This type does not support scoped + addresses since it does not allow zone identifiers in the + address format."; + reference + "RFC 4007: IPv6 Scoped Address Architecture"; + } + + typedef ipv4-address-no-zone { + type inet:ipv4-address { + pattern '[0-9\.]*'; + } + description + "An IPv4 address without a zone index. This type, derived from + ipv4-address, may be used in situations where the zone is + known from the context and hence no zone index is needed."; + } + + typedef ipv6-address-no-zone { + type inet:ipv6-address { + pattern '[0-9a-fA-F:\.]*'; + } + description + "An IPv6 address without a zone index. This type, derived from + ipv6-address, may be used in situations where the zone is + known from the context and hence no zone index is needed."; + reference + "RFC 4291: IP Version 6 Addressing Architecture + RFC 4007: IPv6 Scoped Address Architecture + RFC 5952: A Recommendation for IPv6 Address Text + Representation"; + } + + typedef ip-prefix { + type union { + type inet:ipv4-prefix; + type inet:ipv6-prefix; + } + description + "The ip-prefix type represents an IP prefix and is IP + version neutral. The format of the textual representations + implies the IP version."; + } + + typedef ipv4-prefix { + type string { + pattern + '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}' + + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])' + + '/(([0-9])|([1-2][0-9])|(3[0-2]))'; + } + description + "The ipv4-prefix type represents an IPv4 address prefix. + The prefix length is given by the number following the + slash character and must be less than or equal to 32. + + A prefix length value of n corresponds to an IP address + mask that has n contiguous 1-bits from the most + significant bit (MSB) and all other bits set to 0. + + The canonical format of an IPv4 prefix has all bits of + the IPv4 address set to zero that are not part of the + IPv4 prefix."; + } + + typedef ipv6-prefix { + type string { + pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}' + + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|' + + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}' + + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))' + + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'; + pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|' + + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)' + + '(/.+)'; + } + description + "The ipv6-prefix type represents an IPv6 address prefix. + The prefix length is given by the number following the + slash character and must be less than or equal to 128. + + A prefix length value of n corresponds to an IP address + mask that has n contiguous 1-bits from the most + significant bit (MSB) and all other bits set to 0. + + The IPv6 address should have all bits that do not belong + to the prefix set to zero. + + The canonical format of an IPv6 prefix has all bits of + the IPv6 address set to zero that are not part of the + IPv6 prefix. Furthermore, the IPv6 address is represented + as defined in Section 4 of RFC 5952."; + reference + "RFC 5952: A Recommendation for IPv6 Address Text + Representation"; + } + + /*** collection of domain name and URI types ***/ + + typedef domain-name { + type string { + length "1..253"; + pattern + '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*' + + '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)' + + '|\.'; + } + description + "The domain-name type represents a DNS domain name. The + name SHOULD be fully qualified whenever possible. + + Internet domain names are only loosely specified. Section + 3.5 of RFC 1034 recommends a syntax (modified in Section + 2.1 of RFC 1123). The pattern above is intended to allow + for current practice in domain name use, and some possible + future expansion. It is designed to hold various types of + domain names, including names used for A or AAAA records + (host names) and other records, such as SRV records. Note + that Internet host names have a stricter syntax (described + in RFC 952) than the DNS recommendations in RFCs 1034 and + 1123, and that systems that want to store host names in + schema nodes using the domain-name type are recommended to + adhere to this stricter standard to ensure interoperability. + + The encoding of DNS names in the DNS protocol is limited + to 255 characters. Since the encoding consists of labels + prefixed by a length bytes and there is a trailing NULL + byte, only 253 characters can appear in the textual dotted + notation. + + The description clause of schema nodes using the domain-name + type MUST describe when and how these names are resolved to + IP addresses. Note that the resolution of a domain-name value + may require to query multiple DNS records (e.g., A for IPv4 + and AAAA for IPv6). The order of the resolution process and + which DNS record takes precedence can either be defined + explicitly or may depend on the configuration of the + resolver. + + Domain-name values use the US-ASCII encoding. Their canonical + format uses lowercase US-ASCII characters. Internationalized + domain names MUST be A-labels as per RFC 5890."; + reference + "RFC 952: DoD Internet Host Table Specification + RFC 1034: Domain Names - Concepts and Facilities + RFC 1123: Requirements for Internet Hosts -- Application + and Support + RFC 2782: A DNS RR for specifying the location of services + (DNS SRV) + RFC 5890: Internationalized Domain Names in Applications + (IDNA): Definitions and Document Framework"; + } + + typedef host { + type union { + type inet:ip-address; + type inet:domain-name; + } + description + "The host type represents either an IP address or a DNS + domain name."; + } + + typedef uri { + type string; + description + "The uri type represents a Uniform Resource Identifier + (URI) as defined by STD 66. + + Objects using the uri type MUST be in US-ASCII encoding, + and MUST be normalized as described by RFC 3986 Sections + 6.2.1, 6.2.2.1, and 6.2.2.2. All unnecessary + percent-encoding is removed, and all case-insensitive + characters are set to lowercase except for hexadecimal + digits, which are normalized to uppercase as described in + Section 6.2.2.1. + + The purpose of this normalization is to help provide + unique URIs. Note that this normalization is not + sufficient to provide uniqueness. Two URIs that are + textually distinct after this normalization may still be + equivalent. + + Objects using the uri type may restrict the schemes that + they permit. For example, 'data:' and 'urn:' schemes + might not be appropriate. + + A zero-length URI is not a valid URI. This can be used to + express 'URI absent' where required. + + In the value set and its semantics, this type is equivalent + to the Uri SMIv2 textual convention defined in RFC 5017."; + reference + "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax + RFC 3305: Report from the Joint W3C/IETF URI Planning Interest + Group: Uniform Resource Identifiers (URIs), URLs, + and Uniform Resource Names (URNs): Clarifications + and Recommendations + RFC 5017: MIB Textual Conventions for Uniform Resource + Identifiers (URIs)"; + } + +} diff --git a/models/yang/sonic/common/ietf/ietf-yang-types.yang b/models/yang/sonic/common/ietf/ietf-yang-types.yang new file mode 100644 index 0000000000..ee58fa3ab0 --- /dev/null +++ b/models/yang/sonic/common/ietf/ietf-yang-types.yang @@ -0,0 +1,474 @@ +module ietf-yang-types { + + namespace "urn:ietf:params:xml:ns:yang:ietf-yang-types"; + prefix "yang"; + + organization + "IETF NETMOD (NETCONF Data Modeling Language) Working Group"; + + contact + "WG Web: + WG List: + + WG Chair: David Kessens + + + WG Chair: Juergen Schoenwaelder + + + Editor: Juergen Schoenwaelder + "; + + description + "This module contains a collection of generally useful derived + YANG data types. + + Copyright (c) 2013 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (http://trustee.ietf.org/license-info). + + This version of this YANG module is part of RFC 6991; see + the RFC itself for full legal notices."; + + revision 2013-07-15 { + description + "This revision adds the following new data types: + - yang-identifier + - hex-string + - uuid + - dotted-quad"; + reference + "RFC 6991: Common YANG Data Types"; + } + + revision 2010-09-24 { + description + "Initial revision."; + reference + "RFC 6021: Common YANG Data Types"; + } + + /*** collection of counter and gauge types ***/ + + typedef counter32 { + type uint32; + description + "The counter32 type represents a non-negative integer + that monotonically increases until it reaches a + maximum value of 2^32-1 (4294967295 decimal), when it + wraps around and starts increasing again from zero. + + Counters have no defined 'initial' value, and thus, a + single value of a counter has (in general) no information + content. Discontinuities in the monotonically increasing + value normally occur at re-initialization of the + management system, and at other times as specified in the + description of a schema node using this type. If such + other times can occur, for example, the creation of + a schema node of type counter32 at times other than + re-initialization, then a corresponding schema node + should be defined, with an appropriate type, to indicate + the last discontinuity. + + The counter32 type should not be used for configuration + schema nodes. A default statement SHOULD NOT be used in + combination with the type counter32. + + In the value set and its semantics, this type is equivalent + to the Counter32 type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 + (SMIv2)"; + } + + typedef zero-based-counter32 { + type yang:counter32; + default "0"; + description + "The zero-based-counter32 type represents a counter32 + that has the defined 'initial' value zero. + + A schema node of this type will be set to zero (0) on creation + and will thereafter increase monotonically until it reaches + a maximum value of 2^32-1 (4294967295 decimal), when it + wraps around and starts increasing again from zero. + + Provided that an application discovers a new schema node + of this type within the minimum time to wrap, it can use the + 'initial' value as a delta. It is important for a management + station to be aware of this minimum time and the actual time + between polls, and to discard data if the actual time is too + long or there is no defined minimum time. + + In the value set and its semantics, this type is equivalent + to the ZeroBasedCounter32 textual convention of the SMIv2."; + reference + "RFC 4502: Remote Network Monitoring Management Information + Base Version 2"; + } + + typedef counter64 { + type uint64; + description + "The counter64 type represents a non-negative integer + that monotonically increases until it reaches a + maximum value of 2^64-1 (18446744073709551615 decimal), + when it wraps around and starts increasing again from zero. + + Counters have no defined 'initial' value, and thus, a + single value of a counter has (in general) no information + content. Discontinuities in the monotonically increasing + value normally occur at re-initialization of the + management system, and at other times as specified in the + description of a schema node using this type. If such + other times can occur, for example, the creation of + a schema node of type counter64 at times other than + re-initialization, then a corresponding schema node + should be defined, with an appropriate type, to indicate + the last discontinuity. + + The counter64 type should not be used for configuration + schema nodes. A default statement SHOULD NOT be used in + combination with the type counter64. + + In the value set and its semantics, this type is equivalent + to the Counter64 type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 + (SMIv2)"; + } + + typedef zero-based-counter64 { + type yang:counter64; + default "0"; + description + "The zero-based-counter64 type represents a counter64 that + has the defined 'initial' value zero. + + A schema node of this type will be set to zero (0) on creation + and will thereafter increase monotonically until it reaches + a maximum value of 2^64-1 (18446744073709551615 decimal), + when it wraps around and starts increasing again from zero. + + Provided that an application discovers a new schema node + of this type within the minimum time to wrap, it can use the + 'initial' value as a delta. It is important for a management + station to be aware of this minimum time and the actual time + between polls, and to discard data if the actual time is too + long or there is no defined minimum time. + + In the value set and its semantics, this type is equivalent + to the ZeroBasedCounter64 textual convention of the SMIv2."; + reference + "RFC 2856: Textual Conventions for Additional High Capacity + Data Types"; + } + + typedef gauge32 { + type uint32; + description + "The gauge32 type represents a non-negative integer, which + may increase or decrease, but shall never exceed a maximum + value, nor fall below a minimum value. The maximum value + cannot be greater than 2^32-1 (4294967295 decimal), and + the minimum value cannot be smaller than 0. The value of + a gauge32 has its maximum value whenever the information + being modeled is greater than or equal to its maximum + value, and has its minimum value whenever the information + being modeled is smaller than or equal to its minimum value. + If the information being modeled subsequently decreases + below (increases above) the maximum (minimum) value, the + gauge32 also decreases (increases). + + In the value set and its semantics, this type is equivalent + to the Gauge32 type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 + (SMIv2)"; + } + + typedef gauge64 { + type uint64; + description + "The gauge64 type represents a non-negative integer, which + may increase or decrease, but shall never exceed a maximum + value, nor fall below a minimum value. The maximum value + cannot be greater than 2^64-1 (18446744073709551615), and + the minimum value cannot be smaller than 0. The value of + a gauge64 has its maximum value whenever the information + being modeled is greater than or equal to its maximum + value, and has its minimum value whenever the information + being modeled is smaller than or equal to its minimum value. + If the information being modeled subsequently decreases + below (increases above) the maximum (minimum) value, the + gauge64 also decreases (increases). + + In the value set and its semantics, this type is equivalent + to the CounterBasedGauge64 SMIv2 textual convention defined + in RFC 2856"; + reference + "RFC 2856: Textual Conventions for Additional High Capacity + Data Types"; + } + + /*** collection of identifier-related types ***/ + + typedef object-identifier { + type string { + pattern '(([0-1](\.[1-3]?[0-9]))|(2\.(0|([1-9]\d*))))' + + '(\.(0|([1-9]\d*)))*'; + } + description + "The object-identifier type represents administratively + assigned names in a registration-hierarchical-name tree. + + Values of this type are denoted as a sequence of numerical + non-negative sub-identifier values. Each sub-identifier + value MUST NOT exceed 2^32-1 (4294967295). Sub-identifiers + are separated by single dots and without any intermediate + whitespace. + + The ASN.1 standard restricts the value space of the first + sub-identifier to 0, 1, or 2. Furthermore, the value space + of the second sub-identifier is restricted to the range + 0 to 39 if the first sub-identifier is 0 or 1. Finally, + the ASN.1 standard requires that an object identifier + has always at least two sub-identifiers. The pattern + captures these restrictions. + + Although the number of sub-identifiers is not limited, + module designers should realize that there may be + implementations that stick with the SMIv2 limit of 128 + sub-identifiers. + + This type is a superset of the SMIv2 OBJECT IDENTIFIER type + since it is not restricted to 128 sub-identifiers. Hence, + this type SHOULD NOT be used to represent the SMIv2 OBJECT + IDENTIFIER type; the object-identifier-128 type SHOULD be + used instead."; + reference + "ISO9834-1: Information technology -- Open Systems + Interconnection -- Procedures for the operation of OSI + Registration Authorities: General procedures and top + arcs of the ASN.1 Object Identifier tree"; + } + + typedef object-identifier-128 { + type object-identifier { + pattern '\d*(\.\d*){1,127}'; + } + description + "This type represents object-identifiers restricted to 128 + sub-identifiers. + + In the value set and its semantics, this type is equivalent + to the OBJECT IDENTIFIER type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 + (SMIv2)"; + } + + typedef yang-identifier { + type string { + length "1..max"; + pattern '[a-zA-Z_][a-zA-Z0-9\-_.]*'; + pattern '.|..|[^xX].*|.[^mM].*|..[^lL].*'; + } + description + "A YANG identifier string as defined by the 'identifier' + rule in Section 12 of RFC 6020. An identifier must + start with an alphabetic character or an underscore + followed by an arbitrary sequence of alphabetic or + numeric characters, underscores, hyphens, or dots. + + A YANG identifier MUST NOT start with any possible + combination of the lowercase or uppercase character + sequence 'xml'."; + reference + "RFC 6020: YANG - A Data Modeling Language for the Network + Configuration Protocol (NETCONF)"; + } + + /*** collection of types related to date and time***/ + + typedef date-and-time { + type string { + pattern '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?' + + '(Z|[\+\-]\d{2}:\d{2})'; + } + description + "The date-and-time type is a profile of the ISO 8601 + standard for representation of dates and times using the + Gregorian calendar. The profile is defined by the + date-time production in Section 5.6 of RFC 3339. + + The date-and-time type is compatible with the dateTime XML + schema type with the following notable exceptions: + + (a) The date-and-time type does not allow negative years. + + (b) The date-and-time time-offset -00:00 indicates an unknown + time zone (see RFC 3339) while -00:00 and +00:00 and Z + all represent the same time zone in dateTime. + + (c) The canonical format (see below) of data-and-time values + differs from the canonical format used by the dateTime XML + schema type, which requires all times to be in UTC using + the time-offset 'Z'. + + This type is not equivalent to the DateAndTime textual + convention of the SMIv2 since RFC 3339 uses a different + separator between full-date and full-time and provides + higher resolution of time-secfrac. + + The canonical format for date-and-time values with a known time + zone uses a numeric time zone offset that is calculated using + the device's configured known offset to UTC time. A change of + the device's offset to UTC time will cause date-and-time values + to change accordingly. Such changes might happen periodically + in case a server follows automatically daylight saving time + (DST) time zone offset changes. The canonical format for + date-and-time values with an unknown time zone (usually + referring to the notion of local time) uses the time-offset + -00:00."; + reference + "RFC 3339: Date and Time on the Internet: Timestamps + RFC 2579: Textual Conventions for SMIv2 + XSD-TYPES: XML Schema Part 2: Datatypes Second Edition"; + } + + typedef timeticks { + type uint32; + description + "The timeticks type represents a non-negative integer that + represents the time, modulo 2^32 (4294967296 decimal), in + hundredths of a second between two epochs. When a schema + node is defined that uses this type, the description of + the schema node identifies both of the reference epochs. + + In the value set and its semantics, this type is equivalent + to the TimeTicks type of the SMIv2."; + reference + "RFC 2578: Structure of Management Information Version 2 + (SMIv2)"; + } + + typedef timestamp { + type yang:timeticks; + description + "The timestamp type represents the value of an associated + timeticks schema node at which a specific occurrence + happened. The specific occurrence must be defined in the + description of any schema node defined using this type. When + the specific occurrence occurred prior to the last time the + associated timeticks attribute was zero, then the timestamp + value is zero. Note that this requires all timestamp values + to be reset to zero when the value of the associated timeticks + attribute reaches 497+ days and wraps around to zero. + + The associated timeticks schema node must be specified + in the description of any schema node using this type. + + In the value set and its semantics, this type is equivalent + to the TimeStamp textual convention of the SMIv2."; + reference + "RFC 2579: Textual Conventions for SMIv2"; + } + + /*** collection of generic address types ***/ + + typedef phys-address { + type string { + pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?'; + } + + description + "Represents media- or physical-level addresses represented + as a sequence octets, each octet represented by two hexadecimal + numbers. Octets are separated by colons. The canonical + representation uses lowercase characters. + + In the value set and its semantics, this type is equivalent + to the PhysAddress textual convention of the SMIv2."; + reference + "RFC 2579: Textual Conventions for SMIv2"; + } + + typedef mac-address { + type string { + pattern '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'; + } + description + "The mac-address type represents an IEEE 802 MAC address. + The canonical representation uses lowercase characters. + + In the value set and its semantics, this type is equivalent + to the MacAddress textual convention of the SMIv2."; + reference + "IEEE 802: IEEE Standard for Local and Metropolitan Area + Networks: Overview and Architecture + RFC 2579: Textual Conventions for SMIv2"; + } + + /*** collection of XML-specific types ***/ + + typedef xpath1.0 { + type string; + description + "This type represents an XPATH 1.0 expression. + + When a schema node is defined that uses this type, the + description of the schema node MUST specify the XPath + context in which the XPath expression is evaluated."; + reference + "XPATH: XML Path Language (XPath) Version 1.0"; + } + + /*** collection of string types ***/ + + typedef hex-string { + type string { + pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?'; + } + description + "A hexadecimal string with octets represented as hex digits + separated by colons. The canonical representation uses + lowercase characters."; + } + + typedef uuid { + type string { + pattern '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-' + + '[0-9a-fA-F]{4}-[0-9a-fA-F]{12}'; + } + description + "A Universally Unique IDentifier in the string representation + defined in RFC 4122. The canonical representation uses + lowercase characters. + + The following is an example of a UUID in string representation: + f81d4fae-7dec-11d0-a765-00a0c91e6bf6 + "; + reference + "RFC 4122: A Universally Unique IDentifier (UUID) URN + Namespace"; + } + + typedef dotted-quad { + type string { + pattern + '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}' + + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'; + } + description + "An unsigned 32-bit number expressed in the dotted-quad + notation, i.e., four octets written as decimal numbers + and separated with the '.' (full stop) character."; + } +} diff --git a/src/cvl/schema/sonic-common.yang b/models/yang/sonic/common/sonic-common.yang similarity index 100% rename from src/cvl/schema/sonic-common.yang rename to models/yang/sonic/common/sonic-common.yang diff --git a/src/cvl/schema/sonic-extension.yang b/models/yang/sonic/common/sonic-extension.yang similarity index 100% rename from src/cvl/schema/sonic-extension.yang rename to models/yang/sonic/common/sonic-extension.yang diff --git a/src/cvl/schema/sonic-acl.yang b/models/yang/sonic/sonic-acl.yang similarity index 98% rename from src/cvl/schema/sonic-acl.yang rename to models/yang/sonic/sonic-acl.yang index d778e8da5f..6c57edcbba 100644 --- a/src/cvl/schema/sonic-acl.yang +++ b/models/yang/sonic/sonic-acl.yang @@ -3,10 +3,6 @@ module sonic-acl { prefix sacl; yang-version 1.1; - import ietf-yang-types { - prefix yang; - } - import ietf-inet-types { prefix inet; } diff --git a/src/cvl/schema/sonic-interface.yang b/models/yang/sonic/sonic-interface.yang similarity index 74% rename from src/cvl/schema/sonic-interface.yang rename to models/yang/sonic/sonic-interface.yang index f51a37f43a..30f1f02c42 100644 --- a/src/cvl/schema/sonic-interface.yang +++ b/models/yang/sonic/sonic-interface.yang @@ -29,6 +29,21 @@ module sonic-interface { container INTERFACE { list INTERFACE_LIST { + key "portname"; + + leaf portname{ + type leafref { + path "/prt:sonic-port/prt:PORT/prt:PORT_LIST/prt:ifname"; + } + } + + leaf vrf-name { + type string; + } + + } + + list INTERFACE_IPADDR_LIST { key "portname ip_prefix"; leaf portname{ diff --git a/src/cvl/schema/sonic-mirror-session.yang b/models/yang/sonic/sonic-mirror-session.yang similarity index 100% rename from src/cvl/schema/sonic-mirror-session.yang rename to models/yang/sonic/sonic-mirror-session.yang diff --git a/src/cvl/schema/sonic-port.yang b/models/yang/sonic/sonic-port.yang similarity index 100% rename from src/cvl/schema/sonic-port.yang rename to models/yang/sonic/sonic-port.yang diff --git a/src/cvl/cvl.go b/src/cvl/cvl.go index 859d78043f..4d44b35b7a 100644 --- a/src/cvl/cvl.go +++ b/src/cvl/cvl.go @@ -51,6 +51,7 @@ var luaScripts map[string]*redis.Script type modelTableInfo struct { dbNum uint8 modelName string + redisTableName string //To which Redis table it belongs to, used for 1 Redis to N Yang List module *yparser.YParserModule keys []string redisKeyDelim string @@ -92,8 +93,9 @@ type modelNamespace struct { } type modelDataInfo struct { - modelNs map[string]modelNamespace//model namespace - tableInfo map[string]modelTableInfo //redis table to model name and keys + modelNs map[string]modelNamespace //model namespace + tableInfo map[string]*modelTableInfo //redis table to model name and keys + redisTableToYangList map[string][]string //Redis table to all YANG lists when it is not 1:1 mapping allKeyDelims map[string]bool } @@ -226,12 +228,17 @@ func storeModelInfo(modelFile string, module *yparser.YParserModule) { //such mo modelInfo.modelNs[modelName] = modelNs - //Store metadata present in each list + //Store metadata present in each list. + //Each list represent one Redis table in general. + //However when one Redis table is mapped to multiple + //YANG lists need to store the information in redisTableToYangList map nodes = xmlquery.Find(root, "//module/container/container/list") if (nodes == nil) { return } + //number list under one table container i.e. ACL_TABLE container + //has only one ACL_TABLE_LIST list for _, node := range nodes { //for each list, remove "_LIST" suffix tableName := node.Attr[0].Value @@ -239,6 +246,8 @@ func storeModelInfo(modelFile string, module *yparser.YParserModule) { //such mo tableName = tableName[0:len(tableName) - len("_LIST")] } tableInfo := modelTableInfo{modelName: modelName} + //Store Redis table name + tableInfo.redisTableName = node.Parent.Attr[0].Value //Store the reference for list node to be used later listNode := node node = node.FirstChild @@ -294,10 +303,20 @@ func storeModelInfo(modelFile string, module *yparser.YParserModule) { //such mo } */ + //If container has more than one list, it means one Redis table is mapped to + //multiple lists, store the info in redisTableToYangList + allLists := xmlquery.Find(listNode.Parent, "/list") + if len(allLists) > 1 { + yangList := modelInfo.redisTableToYangList[tableInfo.redisTableName] + yangList = append(yangList, tableName) + //Update the map + modelInfo.redisTableToYangList[tableInfo.redisTableName] = yangList + } + leafRefNodes := xmlquery.Find(listNode, "//type[@name='leafref']") if (leafRefNodes == nil) { //Store the tableInfo in global data - modelInfo.tableInfo[tableName] = tableInfo + modelInfo.tableInfo[tableName] = &tableInfo continue } @@ -325,11 +344,11 @@ func storeModelInfo(modelFile string, module *yparser.YParserModule) { //such mo } } - //Find all 'must' expression and store the agains its parent node + //Find all 'must' expression and store the against its parent node mustExps := xmlquery.Find(listNode, "//must") if (mustExps == nil) { //Update the tableInfo in global data - modelInfo.tableInfo[tableName] = tableInfo + modelInfo.tableInfo[tableName] = &tableInfo continue } @@ -353,7 +372,8 @@ func storeModelInfo(modelFile string, module *yparser.YParserModule) { //such mo } //Update the tableInfo in global data - modelInfo.tableInfo[tableName] = tableInfo + modelInfo.tableInfo[tableName] = &tableInfo + } } @@ -438,6 +458,48 @@ func splitRedisKey(key string) (string, string) { return tblName, key[prefixLen:] } +//Get the YANG list name from Redis key +//This just returns same YANG list name as Redis table name +//when 1:1 mapping is there. For one Redis table to +//multiple YANG list, it returns appropriate YANG list name +//INTERFACE:Ethernet12 returns ==> INTERFACE +//INTERFACE:Ethernet12:1.1.1.0/32 ==> INTERFACE_IPADDR +func getRedisKeyToYangList(tableName, key string) string { + mapArr, exists := modelInfo.redisTableToYangList[tableName] + + if exists == false { + //1:1 mapping case + return tableName + } + + //As of now determine the mapping based on number of keys + var foundIdx int = -1 + numOfKeys := 1 //Assume only one key initially + for keyDelim, _ := range modelInfo.allKeyDelims { + foundIdx = strings.Index(key, keyDelim) + if (foundIdx >= 0) { + //Matched with key delim + keyComps := strings.Split(key, keyDelim) + numOfKeys = len(keyComps) + break + } + } + + //Check which list has number of keys as 'numOfKeys' + for i := 0; i < len(mapArr); i++ { + tblInfo, exists := modelInfo.tableInfo[mapArr[i]] + if exists == true { + if (len(tblInfo.keys) == numOfKeys) { + //Found the YANG list matching the number of keys + return mapArr[i] + } + } + } + + //No matches + return tableName +} + //Convert Redis key to Yang keys, if multiple key components are there, //they are separated based on Yang schema func getRedisToYangKeys(tableName string, redisKey string)[]keyValuePairStruct{ @@ -1310,6 +1372,7 @@ parent *yparser.YParserNode) CVLRetCode { func (c *CVL) generateTableData(config bool, jsonNode *jsonquery.Node)(*yparser.YParserNode, CVLErrorInfo) { var cvlErrObj CVLErrorInfo + tableName := fmt.Sprintf("%s",jsonNode.Data) c.batchLeaf = "" @@ -1318,9 +1381,15 @@ func (c *CVL) generateTableData(config bool, jsonNode *jsonquery.Node)(*yparser. // container ACL_RULE { list ACL_RULE_LIST {} } var topNode *yparser.YParserNode + // Add top most conatiner e.g. 'container sonic-acl {...}' + if _, exists := modelInfo.tableInfo[tableName]; exists == false { + return nil, cvlErrObj + } topNode = c.yp.AddChildNode(modelInfo.tableInfo[tableName].module, nil, modelInfo.tableInfo[tableName].modelName) + //Add the container node for each list + //e.g. 'container ACL_TABLE { list ACL_TABLE_LIST ...} listConatinerNode := c.yp.AddChildNode(modelInfo.tableInfo[tableName].module, topNode, tableName) @@ -1330,6 +1399,9 @@ func (c *CVL) generateTableData(config bool, jsonNode *jsonquery.Node)(*yparser. //For each field check if is key //If it is key, create list as child of top container // Get all key name/value pairs + if yangListName := getRedisKeyToYangList(tableName, jsonNode.Data); yangListName!= "" { + tableName = yangListName + } keyValuePair := getRedisToYangKeys(tableName, jsonNode.Data) keyCompCount := len(keyValuePair) totalKeyComb := 1 @@ -1344,6 +1416,9 @@ func (c *CVL) generateTableData(config bool, jsonNode *jsonquery.Node)(*yparser. } for ; totalKeyComb > 0 ; totalKeyComb-- { + //Get the YANG list name from Redis table name + //Ideally they are same except when one Redis table is split + //into multiple YANG lists //Add table i.e. create list element listNode := c.addChildNode(tableName, listConatinerNode, tableName + "_LIST") //Add the list to the top node diff --git a/src/cvl/cvl_api.go b/src/cvl/cvl_api.go index 26bc6ea7f7..d4bfe7ee2b 100644 --- a/src/cvl/cvl_api.go +++ b/src/cvl/cvl_api.go @@ -104,8 +104,9 @@ func Initialize() CVLRetCode { yparser.Initialize() modelInfo.modelNs = make(map[string]modelNamespace) //redis table to model name - modelInfo.tableInfo = make(map[string]modelTableInfo) //model namespace + modelInfo.tableInfo = make(map[string]*modelTableInfo) //model namespace modelInfo.allKeyDelims = make(map[string]bool) //all key delimiter + modelInfo.redisTableToYangList = make(map[string][]string) //Redis table to Yang list map dbNameToDbNum = map[string]uint8{"APPL_DB": APPL_DB, "CONFIG_DB": CONFIG_DB} /* schema */ diff --git a/src/cvl/schema/Makefile b/src/cvl/schema/Makefile index fe23d1ce71..911ab84184 100644 --- a/src/cvl/schema/Makefile +++ b/src/cvl/schema/Makefile @@ -1,24 +1,40 @@ -src_files=$(wildcard *.yang) -out=$(patsubst %.yang, %.yin, $(src_files)) -out_ext=$(patsubst %.yang, %.tree, $(src_files)) +sonic_yang=../../../models/yang/sonic +sonic_yang_common=../../../models/yang/sonic/common +pyang_plugin_dir=../../../tools/pyang/pyang_plugins + +src_files=$(wildcard $(sonic_yang)/*.yang) +src_files += $(wildcard $(sonic_yang_common)/*.yang) +out=$(patsubst %.yang, %.yin, $(shell ls -1 $(sonic_yang)/*.yang | cut -d'/' -f7)) +out_common=$(patsubst %.yang, %.yin, $(shell ls -1 $(sonic_yang_common)/*.yang | cut -d'/' -f8)) +out_tree=$(patsubst %.yang, %.tree, $(src_files)) +search_path=$(sonic_yang):$(sonic_yang_common):$(sonic_yang_common)/ietf + all:schema -schema: $(out) +schema: $(out) $(out_common) -%.yin:%.yang - @echo "Generating $@ ..." - @devFile="`echo $< | cut -d . -f1`-dev.yang"; \ +schema-tree: $(out_tree) + +%.yin:$(sonic_yang)/%.yang + @echo "Generating `basename $@` ..." + @devFile="`echo $@ | cut -d . -f1`-deviation.yang"; \ if [ -f $$devFile ] ; then devOpt="--deviation-module $$devFile"; fi; \ - pyang -p ./ietf/ --plugindir ../../../tools/pyang/pyang_plugins/ -f yin-cvl $$devOpt $< -o $@ + pyang -p $(search_path) --plugindir $(pyang_plugin_dir) \ + -f yin-cvl $$devOpt $< -o `basename $@` +%.yin:$(sonic_yang_common)/%.yang + @echo "Generating `basename $@` ..." + @devFile="`echo $@ | cut -d . -f1`-deviation.yang"; \ + if [ -f $$devFile ] ; then devOpt="--deviation-module $$devFile"; fi; \ + pyang -p $(search_path) --plugindir $(pyang_plugin_dir) \ + -f yin-cvl $$devOpt $< -o `basename $@` %.tree:%.yang - @echo "Generating $@ ..." + @echo "Generating `basename $@` ..." @devFile="`echo $< | cut -d . -f1`-dev.yang"; \ if [ -f $$devFile ] ; then devOpt="--deviation-module $$devFile"; fi; \ - pyang -p ./ietf/ -f tree $$devOpt $< -o $@ + pyang -p $(search_path) -f tree $$devOpt $< -o `basename $@` clean: @echo "Removing files ..." - rm -rf $(out) - rm -rf $(out_ext) + rm -rf *.yin *.tree diff --git a/src/cvl/testdata/schema/Makefile b/src/cvl/testdata/schema/Makefile index 308b3eaf6b..43fee356bf 100644 --- a/src/cvl/testdata/schema/Makefile +++ b/src/cvl/testdata/schema/Makefile @@ -17,6 +17,8 @@ # # ################################################################################ +sonic_yang=../../../../models/yang/sonic +pyang_plugin_dir=../../../../tools/pyang/pyang_plugins src_files=$(wildcard *.yang) out=$(patsubst %.yang, %.yin, $(src_files)) out_ext=$(patsubst %.yang, %.tree, $(src_files)) @@ -25,20 +27,22 @@ all:schema schema: $(out) +schema-tree: $(out_ext) + %.yin:%.yang - @echo "Generating $@ ..." + @echo "Generating `basename $@` ..." @devFile="`echo $< | cut -d . -f1`-dev.yang"; \ if [ -f $$devFile ] ; then devOpt="--deviation-module $$devFile"; fi; \ - pyang -p ../../schema/:../../schema/ietf/ -f yin $$devOpt $< -o $@.tmp - @xmllint --noblanks $@.tmp > $@ - @rm -rf $@.tmp + pyang -p $(sonic_yang):$(sonic_yang)/common:$(sonic_yang)/common/ietf \ + --plugindir $(pyang_plugin_dir) -f yin-cvl $$devOpt $< -o `basename $@` %.tree:%.yang - @echo "Generating $@ ..." + @echo "Generating `basename $@` ..." @devFile="`echo $< | cut -d . -f1`-dev.yang"; \ if [ -f $$devFile ] ; then devOpt="--deviation-module $$devFile"; fi; \ - pyang -p ../../schema/:../../schema/ietf/ -f tree $$devOpt $< -o $@ + pyang -p $(sonic_yang):$(sonic_yang)/common:$(sonic_yang)/common/ietf \ + -f tree $$devOpt $< -o `basename $@` clean: @echo "Removing files ..." - rm -rf *.yin + rm -rf *.yin *.tree diff --git a/src/cvl/testdata/schema/sonic-acl-dev.yang b/src/cvl/testdata/schema/sonic-acl-deviation.yang similarity index 85% rename from src/cvl/testdata/schema/sonic-acl-dev.yang rename to src/cvl/testdata/schema/sonic-acl-deviation.yang index d11b40a95c..c1d701c29d 100644 --- a/src/cvl/testdata/schema/sonic-acl-dev.yang +++ b/src/cvl/testdata/schema/sonic-acl-deviation.yang @@ -1,5 +1,5 @@ -module sonic-acl-dev { - namespace "http://github.com/Azure/sonic-acl-dev"; +module sonic-acl-deviation { + namespace "http://github.com/Azure/sonic-acl-deviation"; prefix acld; yang-version 1.1; diff --git a/src/cvl/testdata/schema/sonic-dscp-tc-map.yang b/src/cvl/testdata/schema/sonic-dscp-tc-map.yang index 9ec41b4f15..14dccddd3d 100644 --- a/src/cvl/testdata/schema/sonic-dscp-tc-map.yang +++ b/src/cvl/testdata/schema/sonic-dscp-tc-map.yang @@ -6,10 +6,6 @@ module sonic-dscp-tc-map { prefix sonic-ext; } - import sonic-port { - prefix sif; - } - organization "SONiC"; diff --git a/src/cvl/testdata/schema/sonic-vlan-dev.yang b/src/cvl/testdata/schema/sonic-vlan-deviation.yang similarity index 83% rename from src/cvl/testdata/schema/sonic-vlan-dev.yang rename to src/cvl/testdata/schema/sonic-vlan-deviation.yang index 7cc5784851..ff426fb30c 100644 --- a/src/cvl/testdata/schema/sonic-vlan-dev.yang +++ b/src/cvl/testdata/schema/sonic-vlan-deviation.yang @@ -1,5 +1,5 @@ -module sonic-vlan-dev { - namespace "http://github.com/Azure/sonic-vlan-dev"; +module sonic-vlan-deviation { + namespace "http://github.com/Azure/sonic-vlan-deviation"; prefix svd; yang-version 1.1; diff --git a/tools/pyang/pyang_plugins/yin_cvl.py b/tools/pyang/pyang_plugins/yin_cvl.py index 7e03b3a0c0..71689003b0 100644 --- a/tools/pyang/pyang_plugins/yin_cvl.py +++ b/tools/pyang/pyang_plugins/yin_cvl.py @@ -30,9 +30,9 @@ from pyang import syntax from pyang import statements -new_line='' #replace with '\n' for adding new line -indent_space= '' #replace with ' ' for indentation -ns_indent_space= '' #replace with ' ' for indentation +new_line ='' #replace with '\n' for adding new line +indent_space = '' #replace with ' ' for indentation +ns_indent_space = '' #replace with ' ' for indentation yin_namespace = "urn:ietf:params:xml:ns:yang:yin:1" revision_added = False From 3fba930e7d9f8765b518c7d5e96447427c8d0333 Mon Sep 17 00:00:00 2001 From: Partha Dutta Date: Tue, 1 Oct 2019 11:03:54 +0530 Subject: [PATCH 4/4] Updated Makefile --- src/cvl/schema/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cvl/schema/Makefile b/src/cvl/schema/Makefile index 911ab84184..1844920d34 100644 --- a/src/cvl/schema/Makefile +++ b/src/cvl/schema/Makefile @@ -16,6 +16,7 @@ schema: $(out) $(out_common) schema-tree: $(out_tree) +#Build YANG models %.yin:$(sonic_yang)/%.yang @echo "Generating `basename $@` ..." @devFile="`echo $@ | cut -d . -f1`-deviation.yang"; \ @@ -23,6 +24,7 @@ schema-tree: $(out_tree) pyang -p $(search_path) --plugindir $(pyang_plugin_dir) \ -f yin-cvl $$devOpt $< -o `basename $@` +#Build common YANG models %.yin:$(sonic_yang_common)/%.yang @echo "Generating `basename $@` ..." @devFile="`echo $@ | cut -d . -f1`-deviation.yang"; \