Fixed: [YANG min-elements within non-presence container does not work](https://github.com/clicon/clixon/issues/355)
This commit is contained in:
parent
ba9b313295
commit
ba39f88936
3 changed files with 91 additions and 18 deletions
|
|
@ -52,6 +52,7 @@ Expected: September 2022
|
|||
|
||||
### Corrected Bugs
|
||||
|
||||
* Fixed: [YANG min-elements within non-presence container does not work](https://github.com/clicon/clixon/issues/355)
|
||||
* Fixed: [Issues with ietf-snmp modules](https://github.com/clicon/clixon/issues/353)
|
||||
* Fixed: [Missing/no namespace error in YANG augments with default values](https://github.com/clicon/clixon/issues/354)
|
||||
* Fixed: [Validation of mandatory in choice/case does not work in some cases](https://github.com/clicon/clixon/issues/349)
|
||||
|
|
|
|||
|
|
@ -1223,6 +1223,52 @@ check_min_max(cxobj *xp,
|
|||
goto done;
|
||||
}
|
||||
|
||||
/*! Check if there is any empty list (no x elements) and check min-elements
|
||||
* Note recurse for non-presence container
|
||||
* @param[in] xt XML node
|
||||
* @param[in] yt YANG node
|
||||
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||
* @retval 1 Validation OK
|
||||
* @retval 0 Validation failed (xret set)
|
||||
* @retval -1 Error
|
||||
*/
|
||||
static int
|
||||
check_empty_list_minmax(cxobj *xt,
|
||||
yang_stmt *ye,
|
||||
cxobj **xret)
|
||||
{
|
||||
int retval = -1;
|
||||
int ret;
|
||||
yang_stmt *yprev = NULL;
|
||||
|
||||
if (yang_config(ye) == 1){
|
||||
if(yang_keyword_get(ye) == Y_CONTAINER &&
|
||||
yang_find(ye, Y_PRESENCE, NULL) == NULL){
|
||||
yprev = NULL;
|
||||
while ((yprev = yn_each(ye, yprev)) != NULL) {
|
||||
if ((ret = check_empty_list_minmax(xt, yprev, xret)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
else if (yang_keyword_get(ye) == Y_LIST ||
|
||||
yang_keyword_get(ye) == Y_LEAF_LIST){
|
||||
/* Check if the list length violates min/max */
|
||||
if ((ret = check_min_max(xt, ye, 0, xret)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
retval = 1;
|
||||
done:
|
||||
return retval;
|
||||
fail:
|
||||
retval = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*! Detect unique constraint for duplicates from parent node and minmax
|
||||
* @param[in] xt XML parent (may have lists w unique constraints as child)
|
||||
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||
|
|
@ -1289,7 +1335,7 @@ xml_yang_check_list_unique_minmax(cxobj *xt,
|
|||
* o Otherwise, it is enforced if the ancestor node exists.
|
||||
*/
|
||||
yt = xml_spec(xt); /* If yt == NULL, then no gap-analysis is done */
|
||||
/* Traverse all elemenents */
|
||||
/* Traverse all elements */
|
||||
while ((x = xml_child_each(xt, x, CX_ELMNT)) != NULL) {
|
||||
if ((y = xml_spec(x)) == NULL)
|
||||
continue;
|
||||
|
|
@ -1335,14 +1381,10 @@ xml_yang_check_list_unique_minmax(cxobj *xt,
|
|||
ye = yn_each(yt, ye);
|
||||
if (ye && ych != ye)
|
||||
do {
|
||||
if (yang_config(ye) == 1 &&
|
||||
(yang_keyword_get(ye) == Y_LIST || yang_keyword_get(ye) == Y_LEAF_LIST)){
|
||||
/* Check if the list length violates min/max */
|
||||
if ((ret = check_min_max(xt, ye, 0, xret)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
goto fail;
|
||||
}
|
||||
if ((ret = check_empty_list_minmax(xt, ye, xret)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
goto fail;
|
||||
ye = yn_each(yt, ye);
|
||||
} while(ye != NULL && /* to avoid livelock (shouldnt happen) */
|
||||
ye != ych);
|
||||
|
|
@ -1389,17 +1431,14 @@ xml_yang_check_list_unique_minmax(cxobj *xt,
|
|||
/* Check if there is any empty list between after last non-empty list
|
||||
* Note, does not detect empty lists within choice/case (too complicated)
|
||||
*/
|
||||
if ((ye = yn_each(yt, ye)) != NULL)
|
||||
if ((ye = yn_each(yt, ye)) != NULL){
|
||||
do {
|
||||
if (yang_config(ye) == 1 &&
|
||||
(yang_keyword_get(ye) == Y_LIST || yang_keyword_get(ye) == Y_LEAF_LIST)){
|
||||
/* Check if the list length violates min/max */
|
||||
if ((ret = check_min_max(xt, ye, 0, xret)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
goto fail;
|
||||
}
|
||||
if ((ret = check_empty_list_minmax(xt, ye, xret)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
goto fail;
|
||||
} while((ye = yn_each(yt, ye)) != NULL);
|
||||
}
|
||||
retval = 1;
|
||||
done:
|
||||
return retval;
|
||||
|
|
|
|||
|
|
@ -97,6 +97,24 @@ module $APPNAME{
|
|||
min-elements 1;
|
||||
max-elements 2;
|
||||
}
|
||||
container c3{
|
||||
list b2{
|
||||
description "RFC7950 7.7.5 : it is enforced if the ancestor node exists.";
|
||||
key kb;
|
||||
leaf kb {
|
||||
type string;
|
||||
}
|
||||
container b2c {
|
||||
leaf-list b2ll{
|
||||
min-elements 1;
|
||||
type string;
|
||||
}
|
||||
}
|
||||
leaf-list b3ll{
|
||||
type string;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
|
|
@ -244,6 +262,21 @@ expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS
|
|||
new "minmax: validate should fail empty list"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>protocol</error-type><error-tag>operation-failed</error-tag><error-app-tag>too-few-elements</error-app-tag><error-severity>error</error-severity><error-path>/c/a1</error-path></rpc-error></rpc-reply>"
|
||||
|
||||
new "delete c"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS $DEFAULTNS><edit-config><target><candidate/></target><default-operation>none</default-operation><config><c xmlns=\"urn:example:clixon\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"delete\"/></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
||||
new "add empty list entry with a min-element leaf within a non-presence container"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg -D 1 -l s" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS $DEFAULTNS><edit-config><target><candidate/></target><config><c3 xmlns=\"urn:example:clixon\"><b2><kb>0</kb></b2></c3></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
||||
new "minmax: validate should fail, there should be a b2ll trailing"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>" "<rpc-reply $DEFAULTNS><rpc-error><error-type>protocol</error-type><error-tag>operation-failed</error-tag><error-app-tag>too-few-elements</error-app-tag><error-severity>error</error-severity><error-path>/c3/b2\[kb=\"0\"\]/b2ll</error-path></rpc-error></rpc-reply>" ""
|
||||
|
||||
new "add b3ll after missing b2ll"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg -D 1 -l s" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS $DEFAULTNS><edit-config><target><candidate/></target><config><c3 xmlns=\"urn:example:clixon\"><b2><kb>0</kb><b3ll>42</b3ll></b2></c3></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
||||
new "minmax: validate should fail, there should be a b2ll before b3ll"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>" "<rpc-reply $DEFAULTNS><rpc-error><error-type>protocol</error-type><error-tag>operation-failed</error-tag><error-app-tag>too-few-elements</error-app-tag><error-severity>error</error-severity><error-path>/c3/b2\[kb=\"0\"\]/b2ll</error-path></rpc-error></rpc-reply>" ""
|
||||
|
||||
if [ $BE -ne 0 ]; then
|
||||
new "Kill backend"
|
||||
# Check if premature kill
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue