Fixed: [YANG 'when' does not work in multiple grouping](https://github.com/clicon/clixon/issues/572)
This commit is contained in:
parent
54a8f51bfd
commit
0307aa5374
6 changed files with 113 additions and 70 deletions
|
|
@ -69,6 +69,7 @@ Developers may need to change their code
|
||||||
|
|
||||||
### Corrected Busg
|
### Corrected Busg
|
||||||
|
|
||||||
|
* Fixed: [YANG 'when' does not work in multiple grouping](https://github.com/clicon/clixon/issues/572)
|
||||||
* Fixed: [Error when changing choice/case with different structure](https://github.com/clicon/clixon/issues/568)
|
* Fixed: [Error when changing choice/case with different structure](https://github.com/clicon/clixon/issues/568)
|
||||||
* Fixed: [Clixon handle if-feature incorrectly](https://github.com/clicon/clixon/issues/555)
|
* Fixed: [Clixon handle if-feature incorrectly](https://github.com/clicon/clixon/issues/555)
|
||||||
* Fixed: [Clixon fails to load yang with extension](https://github.com/clicon/clixon/issues/554)
|
* Fixed: [Clixon fails to load yang with extension](https://github.com/clicon/clixon/issues/554)
|
||||||
|
|
|
||||||
|
|
@ -363,11 +363,9 @@ main(int argc,
|
||||||
enum format_enum config_dump_format = FORMAT_XML;
|
enum format_enum config_dump_format = FORMAT_XML;
|
||||||
int print_version = 0;
|
int print_version = 0;
|
||||||
int32_t d;
|
int32_t d;
|
||||||
#if 1
|
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
size_t bufsize = 0;
|
size_t bufsize = 0;
|
||||||
int err;
|
int ret;
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Create handle */
|
/* Create handle */
|
||||||
if ((h = clixon_handle_init()) == NULL)
|
if ((h = clixon_handle_init()) == NULL)
|
||||||
|
|
@ -379,8 +377,6 @@ main(int argc,
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* Set username to clixon handle. Use in all communication to backend */
|
/* Set username to clixon handle. Use in all communication to backend */
|
||||||
#if 1
|
|
||||||
{
|
|
||||||
bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
|
bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
|
||||||
if (bufsize == -1){
|
if (bufsize == -1){
|
||||||
bufsize = 16384;
|
bufsize = 16384;
|
||||||
|
|
@ -389,25 +385,16 @@ main(int argc,
|
||||||
clixon_err(OE_UNIX, errno, "malloc");
|
clixon_err(OE_UNIX, errno, "malloc");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
err = getpwuid_r(getuid(), &pw, buf, bufsize, &pwresult);
|
ret = getpwuid_r(getuid(), &pw, buf, bufsize, &pwresult);
|
||||||
if (pwresult == NULL) {
|
if (pwresult == NULL) {
|
||||||
if (err == 0)
|
if (ret == 0)
|
||||||
clixon_err(OE_UNIX, errno, "getpwuid_r");
|
clixon_err(OE_UNIX, errno, "getpwuid_r");
|
||||||
else
|
else
|
||||||
clixon_err(OE_UNIX, err, "getpwuid_r");
|
clixon_err(OE_UNIX, ret, "getpwuid_r");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (clicon_username_set(h, pw.pw_name) < 0)
|
if (clicon_username_set(h, pw.pw_name) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
#else
|
|
||||||
if ((pw = getpwuid(getuid())) == NULL){
|
|
||||||
clixon_err(OE_UNIX, errno, "getpwuid");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
if (clicon_username_set(h, pw->pw_name) < 0)
|
|
||||||
goto done;
|
|
||||||
#endif
|
|
||||||
while ((c = getopt(argc, argv, SNMP_OPTS)) != -1)
|
while ((c = getopt(argc, argv, SNMP_OPTS)) != -1)
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'h' : /* help */
|
case 'h' : /* help */
|
||||||
|
|
@ -625,10 +612,8 @@ main(int argc,
|
||||||
ok:
|
ok:
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
#if 1
|
|
||||||
if (buf)
|
if (buf)
|
||||||
free(buf);
|
free(buf);
|
||||||
#endif
|
|
||||||
clixon_log_init(h, __PROGRAM__, LOG_INFO, 0); /* Log on syslog no stderr */
|
clixon_log_init(h, __PROGRAM__, LOG_INFO, 0); /* Log on syslog no stderr */
|
||||||
clixon_log(h, LOG_NOTICE, "%s: %u Terminated", __PROGRAM__, getpid());
|
clixon_log(h, LOG_NOTICE, "%s: %u Terminated", __PROGRAM__, getpid());
|
||||||
snmp_terminate(h);
|
snmp_terminate(h);
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@
|
||||||
#define YANG_FLAG_SPEC_MOUNT 0x400 /* Top-level spec is mounted by other top-level tree
|
#define YANG_FLAG_SPEC_MOUNT 0x400 /* Top-level spec is mounted by other top-level tree
|
||||||
*/
|
*/
|
||||||
#define YANG_FLAG_WHEN 0x800 /* Use external map to access when-info for
|
#define YANG_FLAG_WHEN 0x800 /* Use external map to access when-info for
|
||||||
* augment/grouping */
|
* augment/grouping. Only orig object */
|
||||||
#define YANG_FLAG_MYMODULE 0x1000 /* Use external map to access my-module for
|
#define YANG_FLAG_MYMODULE 0x1000 /* Use external map to access my-module for
|
||||||
* UNKNOWNS and augment/grouping */
|
* UNKNOWNS and augment/grouping */
|
||||||
#define YANG_FLAG_REFINE 0x2000 /* In derived trees from grouping and augments, this node
|
#define YANG_FLAG_REFINE 0x2000 /* In derived trees from grouping and augments, this node
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,7 @@ clixon_ptr2ptr(map_ptr2ptr *mptab,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Add pointer pairto mptab map
|
/*! Add pointer pair to mptab map
|
||||||
*
|
*
|
||||||
* @param[in] mptab Ptr to ptr map
|
* @param[in] mptab Ptr to ptr map
|
||||||
* @param[in] ptr0 Input pointer
|
* @param[in] ptr0 Input pointer
|
||||||
|
|
|
||||||
|
|
@ -518,14 +518,17 @@ yang_when_get(clixon_handle h,
|
||||||
yang_stmt *ys)
|
yang_stmt *ys)
|
||||||
{
|
{
|
||||||
map_ptr2ptr *mp = _yang_when_map;
|
map_ptr2ptr *mp = _yang_when_map;
|
||||||
|
yang_stmt *ys2;
|
||||||
|
|
||||||
if (mp == NULL){
|
if (mp == NULL){
|
||||||
clixon_log(h, LOG_WARNING, "when_map not defined, yang_init() not called?");
|
clixon_log(h, LOG_WARNING, "when_map not defined, yang_init() not called?");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (yang_flag_get(ys, YANG_FLAG_WHEN) != 0x0 && mp != NULL)
|
if ((ys2 = yang_orig_get(ys)) == NULL)
|
||||||
return clixon_ptr2ptr(mp, ys);
|
ys2 = ys;
|
||||||
|
if (yang_flag_get(ys2, YANG_FLAG_WHEN) != 0x0 && mp != NULL)
|
||||||
|
return clixon_ptr2ptr(mp, ys2);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -544,6 +547,7 @@ yang_when_set(clixon_handle h,
|
||||||
yang_stmt *ywhen)
|
yang_stmt *ywhen)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
yang_stmt *ys2;
|
||||||
map_ptr2ptr *mp = _yang_when_map;
|
map_ptr2ptr *mp = _yang_when_map;
|
||||||
|
|
||||||
if (mp == NULL){
|
if (mp == NULL){
|
||||||
|
|
@ -551,13 +555,16 @@ yang_when_set(clixon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (clixon_ptr2ptr(mp, ys) != NULL) {
|
if ((ys2 = yang_orig_get(ys)) == NULL)
|
||||||
clixon_err(OE_YANG, 0, "when pointer already set");
|
ys2 = ys;
|
||||||
|
if (clixon_ptr2ptr(mp, ys2) == NULL) {
|
||||||
|
assert(yang_flag_set(ys2, YANG_FLAG_WHEN)==0); // XXX
|
||||||
|
if (clixon_ptr2ptr_add(&_yang_when_map, ys2, ywhen) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
yang_flag_set(ys2, YANG_FLAG_WHEN);
|
||||||
}
|
}
|
||||||
if (clixon_ptr2ptr_add(&_yang_when_map, ys, ywhen) < 0)
|
else
|
||||||
goto done;
|
assert(yang_flag_set(ys2, YANG_FLAG_WHEN) == 0); // XXX
|
||||||
yang_flag_set(ys, YANG_FLAG_WHEN);
|
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
@ -2453,6 +2460,7 @@ yang_mounts_print(FILE *f,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Log/debug info about top-level (sub)modules no recursion
|
/* Log/debug info about top-level (sub)modules no recursion
|
||||||
|
*
|
||||||
* @param[in] yspec Yang spec
|
* @param[in] yspec Yang spec
|
||||||
* @param[in] dbglevel Debug level
|
* @param[in] dbglevel Debug level
|
||||||
*/
|
*/
|
||||||
|
|
@ -2537,6 +2545,7 @@ yang_print_cbuf(cbuf *cb,
|
||||||
else
|
else
|
||||||
cprintf(cb, " %s", arg);
|
cprintf(cb, " %s", arg);
|
||||||
}
|
}
|
||||||
|
// cprintf(cb, " %p ", yn); For debugging object ptr
|
||||||
if (yang_len_get(yn)){
|
if (yang_len_get(yn)){
|
||||||
cprintf(cb, " {");
|
cprintf(cb, " {");
|
||||||
if (pretty)
|
if (pretty)
|
||||||
|
|
|
||||||
|
|
@ -58,29 +58,48 @@ cat <<EOF > $fyang
|
||||||
module example {
|
module example {
|
||||||
namespace "urn:example:clixon";
|
namespace "urn:example:clixon";
|
||||||
prefix ex;
|
prefix ex;
|
||||||
grouping L3-top {
|
grouping L0-group {
|
||||||
leaf L3{
|
leaf L0{
|
||||||
type string;
|
type string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
grouping L2-top {
|
grouping L1-group {
|
||||||
|
list L1 {
|
||||||
|
key x;
|
||||||
|
leaf x {
|
||||||
|
type uint32;
|
||||||
|
}
|
||||||
|
uses L0-group {
|
||||||
|
when 'x=42';
|
||||||
|
// when 'false';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
container L2x {
|
||||||
|
description "Two-level";
|
||||||
|
list L1 {
|
||||||
|
key x;
|
||||||
|
leaf x {
|
||||||
|
type uint32;
|
||||||
|
}
|
||||||
|
uses L0-group {
|
||||||
|
when 'x=42';
|
||||||
|
// when 'false';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
container L2y {
|
||||||
|
description "Three levels";
|
||||||
|
uses L1-group;
|
||||||
|
}
|
||||||
|
grouping L2-group {
|
||||||
container L2 {
|
container L2 {
|
||||||
uses L3-top {
|
uses L1-group;
|
||||||
when 'false';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
container L1x {
|
|
||||||
/* Does not work */
|
|
||||||
uses L2-top;
|
|
||||||
}
|
|
||||||
container L1y {
|
|
||||||
/* Works */
|
|
||||||
container L2 {
|
|
||||||
uses L3-top {
|
|
||||||
when 'false';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
container L3 {
|
||||||
|
description "Four levels";
|
||||||
|
uses L2-group;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
@ -99,6 +118,35 @@ fi
|
||||||
new "wait backend"
|
new "wait backend"
|
||||||
wait_backend
|
wait_backend
|
||||||
|
|
||||||
|
new "CLI: L2 17, expect fail"
|
||||||
|
expectpart "$($clixon_cli -f $cfg -1 set L2x L1 17 L0 x 2>&1)" 255 "Node 'L0' tagged with 'when' condition 'x=42' in module 'example'"
|
||||||
|
|
||||||
|
new "CLI: L2 42, expect ok"
|
||||||
|
expectpart "$($clixon_cli -f $cfg -1 set L2x L1 42 L0 x 2>&1)" 0 ""
|
||||||
|
|
||||||
|
new "NETCONF: L2x, expect fail"
|
||||||
|
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><L2x xmlns=\"urn:example:clixon\"><L1><x>17</x><L0>x</L0></L1></L2x></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</error-type><error-tag>unknown-element</error-tag><error-info><bad-element>L0</bad-element></error-info><error-severity>error</error-severity><error-message>Node 'L0' tagged with 'when' condition 'x=42' in module 'example' evaluates to false in edit-config operation (see RFC 7950 Sec 8.3.2)</error-message></rpc-error></rpc-reply>"
|
||||||
|
|
||||||
|
new "NETCONF: L2x, expect ok"
|
||||||
|
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><L2x xmlns=\"urn:example:clixon\"><L1><x>42</x><L0>x</L0></L1></L2x></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||||
|
|
||||||
|
new "NETCONF validate, expect ok"
|
||||||
|
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||||
|
|
||||||
|
new "L2y grouping, expect fail"
|
||||||
|
expectpart "$($clixon_cli -f $cfg -1 set L2y L1 17 L0 x 2>&1)" 255 "Node 'L0' tagged with 'when' condition 'x=42' in module 'example'"
|
||||||
|
|
||||||
|
new "L2y grouping, expect ok"
|
||||||
|
expectpart "$($clixon_cli -f $cfg -1 set L2y L1 42 L0 x 2>&1)" 0 ""
|
||||||
|
|
||||||
|
new "NETCONF: L2y, expect fail"
|
||||||
|
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><L2y xmlns=\"urn:example:clixon\"><L1><x>17</x><L0>x</L0></L1></L2y></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</error-type><error-tag>unknown-element</error-tag><error-info><bad-element>L0</bad-element></error-info><error-severity>error</error-severity><error-message>Node 'L0' tagged with 'when' condition 'x=42' in module 'example' evaluates to false in edit-config operation (see RFC 7950 Sec 8.3.2)</error-message></rpc-error></rpc-reply>"
|
||||||
|
|
||||||
|
new "NETCONF: L2y, expect ok"
|
||||||
|
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><L2y xmlns=\"urn:example:clixon\"><L1><x>42</x><L0>x</L0></L1></L2y></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||||
|
|
||||||
|
new "L3, expect fail"
|
||||||
|
expectpart "$($clixon_cli -f $cfg -1 set L3 L2 L1 17 L0 x 2>&1)" 255 ""
|
||||||
|
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue