diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d3eeee9..9efccfc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,8 @@ * Added libgen.h for baseline() ### Corrected Bugs +* [Identityref inside augment statement](https://github.com/clicon/clixon/issues/77) + * Yang-stmt enhanced with "shortcut" to original module * Yang augment created multiple augmented children (no side-effect) * XML prefixed attribute names were not copied into the datastore * [yang type range statement does not support multiple values](https://github.com/clicon/clixon/issues/59) diff --git a/README.md b/README.md index 75d0a2a6..603a47e5 100644 --- a/README.md +++ b/README.md @@ -112,12 +112,11 @@ However, the following YANG syntax modules are not implemented: - min/max-elements - unique - action +- refine Restrictions on Yang types are as follows: -- The range statement for built-in integers does not support multiple values (RFC7950 9.2.4) -- The length statement for built-in strings does not support multiple values (RFC7950 9.4.4) - Submodules cannot re-use a prefix in an import statement that is already used for another imported module in the module that the submodule belongs to. (see https://github.com/clicon/clixon/issues/60) -- default values on leaf-lists are not supported (RFC7950 7.7.2) +- Default values on leaf-lists are not supported (RFC7950 7.7.2) ## XML diff --git a/lib/clixon/clixon_yang.h b/lib/clixon/clixon_yang.h index 935c886d..3781a799 100644 --- a/lib/clixon/clixon_yang.h +++ b/lib/clixon/clixon_yang.h @@ -198,6 +198,10 @@ struct yang_stmt{ char *ys_argument; /* String / argument depending on keyword */ int ys_flags; /* Flags according to YANG_FLAG_* above */ /*--------------here common for all -------*/ + yang_stmt *ys_module; /* Shortcut to "my" module. Augmented + nodes can belong to other + modules than the ancestor module */ + char *ys_extra; /* For unknown */ cg_var *ys_cv; /* cligen variable. See ys_populate() Following stmts have cv:s: diff --git a/lib/src/clixon_xml_map.c b/lib/src/clixon_xml_map.c index 0eb54de4..7b4da105 100644 --- a/lib/src/clixon_xml_map.c +++ b/lib/src/clixon_xml_map.c @@ -316,6 +316,7 @@ validate_leafref(cxobj *xt, * @retval 0 Validation failed * @retval -1 Error * @see ys_populate_identity where the derived types are set + * @see yang_augment_node * @see RFC7950 Sec 9.10.2: */ static int diff --git a/lib/src/clixon_yang.c b/lib/src/clixon_yang.c index d1869665..386ba3fa 100644 --- a/lib/src/clixon_yang.c +++ b/lib/src/clixon_yang.c @@ -773,6 +773,7 @@ ys_module_by_xml(yang_spec *ysp, * @param[in] ys Any yang statement in a yang tree * @retval ymod The top module or sub-module * @see ys_spec + * @note For an augmented node, the original module is returned */ yang_stmt * ys_module(yang_stmt *ys) @@ -786,6 +787,10 @@ ys_module(yang_stmt *ys) while (ys != NULL && ys->ys_keyword != Y_MODULE && ys->ys_keyword != Y_SUBMODULE){ + if (ys->ys_module){ /* shortcut due to augment */ + ys = ys->ys_module; + break; + } yn = ys->ys_parent; /* Some extra stuff to ensure ys is a stmt */ if (yn && yn->yn_keyword == Y_SPEC) @@ -800,6 +805,7 @@ ys_module(yang_stmt *ys) * @param[in] ys Any yang statement in a yang tree * @retval yspec The top yang specification * @see ys_module + * @see ys_yang_augment_node where shortcut is set */ yang_spec * ys_spec(yang_stmt *ys) @@ -1640,7 +1646,12 @@ yang_augment_node(yang_stmt *ys, yang_stmt *ytarget = NULL; yang_stmt *yc; int i; - + yang_stmt *ymod; + + if ((ymod = ys_module(ys)) == NULL){ + clicon_err(OE_YANG, 0, "My yang module not found"); + goto done; + } schema_nodeid = ys->ys_argument; clicon_debug(2, "%s %s", __FUNCTION__, schema_nodeid); /* Find the target */ @@ -1654,7 +1665,7 @@ yang_augment_node(yang_stmt *ys, for (i=0; iys_len; i++){ if ((yc = ys_dup(ys->ys_stmt[i])) == NULL) goto done; - /* XXX: use prefix of origin */ + yc->ys_module = ymod; if (yn_insert((yang_node*)ytarget, yc) < 0) goto done; } diff --git a/lib/src/clixon_yang_type.c b/lib/src/clixon_yang_type.c index f537716d..e182b02b 100644 --- a/lib/src/clixon_yang_type.c +++ b/lib/src/clixon_yang_type.c @@ -772,7 +772,7 @@ ys_typedef_up(yang_stmt *ys) identityref's base identity. 1. (base) identity must exist (be found). This is a sanity check of the specification and also necessary for identity statements. - (This is what is dine here) + (This is what is done here) 2. Check if a given node has value derived from base identity. This is a run-time check necessary when validating eg netconf. (This is validation) diff --git a/test/test_augment.yang b/test/test_augment.sh similarity index 57% rename from test/test_augment.yang rename to test/test_augment.sh index bc2fe89e..84bf2bd2 100755 --- a/test/test_augment.yang +++ b/test/test_augment.sh @@ -6,7 +6,6 @@ # both defined in the basic ietf-interfaces module (type) as well as the main # module through the augmented module () # The ietf-interfaces is very restricted (not original). -# Work-in-progress # Magic line must be first in script (see README.md) s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi @@ -36,6 +35,8 @@ cat < $cfg EOF # Stub ietf-interfaces for test +# This is the target module (where the augment is applied to) +# The grouping is from rfc7950 Sec 7.12 with simplified types cat < $fyang2 module ietf-interfaces { yang-version 1.1; @@ -47,9 +48,6 @@ module ietf-interfaces { "Base identity from which specific interface types are derived."; } - identity eth { - base interface-type; - } identity fddi { base interface-type; } @@ -68,11 +66,21 @@ module ietf-interfaces { } } } + grouping endpoint { + description "A reusable endpoint group."; + leaf mip { + type string; + } + leaf mport { + type uint16; + } + } } EOF # From rfc7950 sec 7.17 # Note "when" is not present +# This is the main module where the augment exists cat < $fyang module example-augment { yang-version 1.1; @@ -85,12 +93,47 @@ module example-augment { identity some-new-iftype { base if:interface-type; } + identity my-type { + description "an identity based in the main module"; + } + identity you { + base my-type; + } + grouping mypoint { + description "A reusable endpoint group."; + leaf ip { + type string; + } + leaf port { + type uint16; + } + } augment "/if:interfaces/if:interface" { /* when 'derived-from-or-self(if:type, "mymod:some-new-iftype")'; */ leaf mandatory-leaf { mandatory true; type string; } + leaf me { + type identityref { + base mymod:my-type; + } + } + leaf other { + type identityref { + base if:interface-type; + } + } + uses if:endpoint { + refine port { + default 80; + } + } + uses mypoint { + refine mport { + default 8080; + } + } } } EOF @@ -113,14 +156,45 @@ fi # mandatory-leaf See RFC7950 Sec 7.17 # Error1: the xml should have xmlns for "mymod" # XMLNS_YANG_ONLY must be undeffed -new "netconf set new if my w augmented type" -expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 'mymymod:some-new-iftypetrue]]>]]>' "^]]>]]>$" +new "netconf set interface with augmented type and mandatory leaf" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 ' + + e1 + mymod:some-new-iftype + true + ]]>]]>' "^]]>]]>$" + +new "netconf validate ok" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" '^]]>]]>$' + +new "netconf set identity defined in other" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 ' + + e2 + fddi + true + if:fddi + ]]>]]>' "^]]>]]>$" + +new "netconf validate ok" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" '^]]>]]>$' + +new "netconf set identity defined in main" +expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 ' + + e3 + fddi + true + mymod:you + ]]>]]>' "^]]>]]>$" new "netconf validate ok" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" '^]]>]]>$' expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^]]>]]>$" +exit + if [ $BE -eq 0 ]; then exit # BE fi @@ -135,6 +209,4 @@ fi stop_backend -f $cfg sudo pkill -u root -f clixon_backend - - rm -rf $dir