Fixed: The auto-cli identityref did not expand identities in grouping/usecases properly.

This commit is contained in:
Olof hagsand 2021-08-03 11:15:45 +02:00
parent babdc6f496
commit 4d265d63bd
3 changed files with 109 additions and 47 deletions

View file

@ -51,6 +51,7 @@ Users may have to change how they access the system
### Corrected Bugs ### Corrected Bugs
* Fixed: The auto-cli identityref did not expand identities in grouping/usecases properly.
* Fixed: [OpenConfig BGP afi-safi and when condition issues #249](https://github.com/clicon/clixon/issues/249) * Fixed: [OpenConfig BGP afi-safi and when condition issues #249](https://github.com/clicon/clixon/issues/249)
* YANG when was not properly implemented for default values * YANG when was not properly implemented for default values
* Fixed: SEGV in clixon_netconf_lib functions from internal errors including validation. * Fixed: SEGV in clixon_netconf_lib functions from internal errors including validation.

View file

@ -184,7 +184,7 @@ yang2cli_helptext(cbuf *cb,
/*! Generate identityref statements for CLI variables /*! Generate identityref statements for CLI variables
* @param[in] ys Yang statement * @param[in] ys Yang statement
* @param[in] ytype Yang union type being resolved * @param[in] ytype Resolved yang type.
* @param[in] helptext CLI help text * @param[in] helptext CLI help text
* @param[out] cb Buffer where cligen code is written * @param[out] cb Buffer where cligen code is written
* @see yang2cli_var_sub Its sub-function * @see yang2cli_var_sub Its sub-function
@ -208,8 +208,10 @@ yang2cli_var_identityref(yang_stmt *ys,
yang_stmt *yprefix; yang_stmt *yprefix;
yang_stmt *yspec; yang_stmt *yspec;
if ((ybaseref = yang_find(ytype, Y_BASE, NULL)) != NULL && if ((ybaseref = yang_find(ytype, Y_BASE, NULL)) == NULL)
(ybaseid = yang_find_identity(ys, yang_argument_get(ybaseref))) != NULL){ goto ok;
if ((ybaseid = yang_find_identity(ytype, yang_argument_get(ybaseref))) == NULL)
goto ok;
idrefvec = yang_cvec_get(ybaseid); idrefvec = yang_cvec_get(ybaseid);
if (cvec_len(idrefvec) > 0){ if (cvec_len(idrefvec) > 0){
/* Add a wildchar string first -let validate take it for default prefix */ /* Add a wildchar string first -let validate take it for default prefix */
@ -243,7 +245,7 @@ yang2cli_var_identityref(yang_stmt *ys,
} }
} }
} }
} ok:
retval = 0; retval = 0;
done: done:
if (prefix) if (prefix)
@ -371,7 +373,7 @@ static int yang2cli_var_union(clicon_handle h, yang_stmt *ys, char *origtype,
* patterns, (eg regexp:"[0.9]*"). * patterns, (eg regexp:"[0.9]*").
* @param[in] h Clixon handle * @param[in] h Clixon handle
* @param[in] ys Yang statement * @param[in] ys Yang statement
* @param[in] ytype Yang union type being resolved * @param[in] ytype Resolved yang type.
* @param[in] helptext CLI help text * @param[in] helptext CLI help text
* @param[in] cvtype * @param[in] cvtype
* @param[in] options Flags field of optional values, see YANG_OPTIONS_* * @param[in] options Flags field of optional values, see YANG_OPTIONS_*

View file

@ -1,6 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Identity and identityref tests # Identity and identityref tests
# Example from RFC7950 Sec 7.18 and 9.10 # Example from RFC7950 Sec 7.18 and 9.10
# Extended with a submodule
# Magic line must be first in script (see README.md) # Magic line must be first in script (see README.md)
s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi
@ -60,7 +61,6 @@ cat <<EOF > $dir/example-crypto-base.yang
algorithms."; algorithms.";
} }
} }
EOF EOF
cat <<EOF > $dir/example-des.yang cat <<EOF > $dir/example-des.yang
@ -85,10 +85,11 @@ cat <<EOF > $dir/example-des.yang
EOF EOF
cat <<EOF > $fyang cat <<EOF > $fyang
module example { module example-my-crypto {
yang-version 1.1; yang-version 1.1;
namespace "urn:example:my-crypto"; namespace "urn:example:my-crypto";
prefix mc; prefix mc;
include "example-sub";
import "example-crypto-base" { import "example-crypto-base" {
prefix "crypto"; prefix "crypto";
} }
@ -141,6 +142,45 @@ cat <<EOF > $fyang
base mc:empty; base mc:empty;
} }
} }
uses myname;
}
EOF
# Only included from sub-module
# Introduce an identity only visible by example-sub submodule
cat <<EOF > $dir/example-extra.yang
module example-extra {
yang-version 1.1;
namespace "urn:example:extra";
prefix ee;
identity extra-base;
identity extra-new{
base ee:extra-base;
}
identity extra-old{
base ee:extra-base;
}
}
EOF
# Sub-module
cat <<EOF > $dir/example-sub.yang
submodule example-sub {
yang-version 1.1;
belongs-to example-my-crypto {
prefix mc;
}
import example-extra {
prefix ee;
}
grouping myname {
leaf sub-name {
description "Uses identity accessed by only the submodule";
type identityref {
base ee:extra-base;
}
}
}
} }
EOF EOF
@ -269,42 +309,61 @@ expectpart "$($clixon_cli -1 -f $cfg -l o validate)" 255 "Validate failed. Edit
new "netconf discard-changes" new "netconf discard-changes"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><discard-changes/></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><discard-changes/></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
# Special case sub-module
new "auto-cli cli expansion submodule identity"
expectpart "$(echo "set sub-name ?" | $clixon_cli -f $cfg 2>&1)" 0 "set sub-name" "ee:extra-new" "ee:extra-old"
new "cli add identity"
expectpart "$($clixon_cli -1 -f $cfg -l o set sub-name ee:extra-new)" 0 ""
new "cli validate submodule identity"
expectpart "$($clixon_cli -1 -f $cfg -l o validate)" 0 ""
new "cli add wrong identity"
expectpart "$($clixon_cli -1 -f $cfg -l o set sub-name ee:foo)" 0 ""
new "cli validate wrong id (expect fail)"
expectpart "$($clixon_cli -1 -f $cfg -l o validate 2>&1)" 255 "Identityref validation failed, ee:foo not derived from extra-base"
new "netconf discard-changes"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><discard-changes/></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
# restconf and identities: # restconf and identities:
# 1. set identity in own module with restconf (PUT and POST), read it with restconf and netconf # 1. set identity in own module with restconf (PUT and POST), read it with restconf and netconf
# 2. set identity in other module with restconf , read it with restconf and netconf # 2. set identity in other module with restconf , read it with restconf and netconf
# 3. set identity in other module with netconf, read it with restconf and netconf # 3. set identity in other module with netconf, read it with restconf and netconf
new "restconf add own identity" new "restconf add own identity"
expectpart "$(curl $CURLOPTS -X PUT -H "Content-Type: application/yang-data+json" $RCPROTO://localhost/restconf/data/example:crypto -d '{"example:crypto":"example:aes"}')" 0 "HTTP/$HVER 201" expectpart "$(curl $CURLOPTS -X PUT -H "Content-Type: application/yang-data+json" $RCPROTO://localhost/restconf/data/example-my-crypto:crypto -d '{"example-my-crypto:crypto":"example-my-crypto:aes"}')" 0 "HTTP/$HVER 201"
new "restconf get own identity" new "restconf get own identity"
expectpart "$(curl $CURLOPTS -X GET $RCPROTO://localhost/restconf/data/example:crypto)" 0 "HTTP/$HVER 200" '{"example:crypto":"aes"}' expectpart "$(curl $CURLOPTS -X GET $RCPROTO://localhost/restconf/data/example-my-crypto:crypto)" 0 "HTTP/$HVER 200" '{"example-my-crypto:crypto":"aes"}'
new "netconf get own identity as set by restconf" new "netconf get own identity as set by restconf"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get-config><source><running/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data><crypto xmlns=\"urn:example:my-crypto\">aes</crypto>" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get-config><source><running/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data><crypto xmlns=\"urn:example:my-crypto\">aes</crypto>"
new "restconf delete identity" new "restconf delete identity"
expectpart "$(curl $CURLOPTS -X DELETE $RCPROTO://localhost/restconf/data/example:crypto)" 0 "HTTP/$HVER 204" expectpart "$(curl $CURLOPTS -X DELETE $RCPROTO://localhost/restconf/data/example-my-crypto:crypto)" 0 "HTTP/$HVER 204"
# 2. set identity in other module with restconf , read it with restconf and netconf # 2. set identity in other module with restconf , read it with restconf and netconf
if ! $YANG_UNKNOWN_ANYDATA ; then if ! $YANG_UNKNOWN_ANYDATA ; then
new "restconf add POST instead of PUT (should fail)" new "restconf add POST instead of PUT (should fail)"
expectpart "$(curl $CURLOPTS -X POST -H "Content-Type: application/yang-data+json" $RCPROTO://localhost/restconf/data/example:crypto -d '{"example:crypto":"example-des:des3"}')" 0 "HTTP/$HVER 400" '{"ietf-restconf:errors":{"error":{"error-type":"application","error-tag":"unknown-element","error-info":{"bad-element":"crypto"},"error-severity":"error","error-message":"Failed to find YANG spec of XML node: crypto with parent: crypto in namespace: urn:example:my-crypto"}}}' expectpart "$(curl $CURLOPTS -X POST -H "Content-Type: application/yang-data+json" $RCPROTO://localhost/restconf/data/example-my-crypto:crypto -d '{"example-my-crypto:crypto":"example-des:des3"}')" 0 "HTTP/$HVER 400" '{"ietf-restconf:errors":{"error":{"error-type":"application","error-tag":"unknown-element","error-info":{"bad-element":"crypto"},"error-severity":"error","error-message":"Failed to find YANG spec of XML node: crypto with parent: crypto in namespace: urn:example:my-crypto"}}}'
fi fi
# Alternative error: # Alternative error:
#'{"ietf-restconf:errors":{"error":{"error-type":"application","error-tag":"unknown-element","error-info":{"bad-element":"crypto"},"error-severity":"error","error-message":"Leaf contains sub-element"}}}' #'{"ietf-restconf:errors":{"error":{"error-type":"application","error-tag":"unknown-element","error-info":{"bad-element":"crypto"},"error-severity":"error","error-message":"Leaf contains sub-element"}}}'
new "restconf add other (des) identity using POST" new "restconf add other (des) identity using POST"
expectpart "$(curl $CURLOPTS -X POST -H "Content-Type: application/yang-data+json" $RCPROTO://localhost/restconf/data -d '{"example:crypto":"example-des:des3"}')" 0 "HTTP/$HVER 201" "Location: $RCPROTO://localhost/restconf/data/example:crypto" expectpart "$(curl $CURLOPTS -X POST -H "Content-Type: application/yang-data+json" $RCPROTO://localhost/restconf/data -d '{"example-my-crypto:crypto":"example-des:des3"}')" 0 "HTTP/$HVER 201" "Location: $RCPROTO://localhost/restconf/data/example-my-crypto:crypto"
new "restconf get other identity" new "restconf get other identity"
expectpart "$(curl $CURLOPTS -X GET $RCPROTO://localhost/restconf/data/example:crypto)" 0 "HTTP/$HVER 200" '{"example:crypto":"example-des:des3"}' expectpart "$(curl $CURLOPTS -X GET $RCPROTO://localhost/restconf/data/example-my-crypto:crypto)" 0 "HTTP/$HVER 200" '{"example-my-crypto:crypto":"example-des:des3"}'
new "netconf get other identity" new "netconf get other identity"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get-config><source><running/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data><crypto xmlns=\"urn:example:my-crypto\" xmlns:des=\"urn:example:des\">des:des3</crypto>" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get-config><source><running/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data><crypto xmlns=\"urn:example:my-crypto\" xmlns:des=\"urn:example:des\">des:des3</crypto>"
new "restconf delete identity" new "restconf delete identity"
expectpart "$(curl $CURLOPTS -X DELETE $RCPROTO://localhost/restconf/data/example:crypto)" 0 "HTTP/$HVER 204" expectpart "$(curl $CURLOPTS -X DELETE $RCPROTO://localhost/restconf/data/example-my-crypto:crypto)" 0 "HTTP/$HVER 204"
# 3. set identity in other module with netconf, read it with restconf and netconf # 3. set identity in other module with netconf, read it with restconf and netconf
new "netconf set other identity" new "netconf set other identity"
@ -314,7 +373,7 @@ new "netconf commit"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><commit/></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><commit/></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
new "restconf get other identity (set by netconf)" new "restconf get other identity (set by netconf)"
expectpart "$(curl $CURLOPTS -X GET $RCPROTO://localhost/restconf/data/example:crypto)" 0 "HTTP/$HVER 200" '{"example:crypto":"example-des:des3"}' expectpart "$(curl $CURLOPTS -X GET $RCPROTO://localhost/restconf/data/example-my-crypto:crypto)" 0 "HTTP/$HVER 200" '{"example-my-crypto:crypto":"example-des:des3"}'
new "netconf get other identity" new "netconf get other identity"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get-config><source><running/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data><crypto xmlns=\"urn:example:my-crypto\" xmlns:des=\"urn:example:des\">des:des3</crypto>" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get-config><source><running/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data><crypto xmlns=\"urn:example:my-crypto\" xmlns:des=\"urn:example:des\">des:des3</crypto>"