* Fix: XPath:s used in netconf (eg get-config) did not correctly access default values

This commit is contained in:
Olof hagsand 2021-05-07 13:07:34 +02:00
parent 0225488c39
commit ac51cb0293
7 changed files with 41 additions and 25 deletions

View file

@ -55,6 +55,7 @@ Users may have to change how they access the system
### Corrected Bugs ### Corrected Bugs
* Fix: XPath:s used in netconf (eg get-config) did not correctly access default values
* [RESTCONF GET request of single-key list with empty string returns all elements #213](https://github.com/clicon/clixon/issues/213) * [RESTCONF GET request of single-key list with empty string returns all elements #213](https://github.com/clicon/clixon/issues/213)
* [RESTCONF GETof lists with empty string keys does not work #214](https://github.com/clicon/clixon/issues/214) * [RESTCONF GETof lists with empty string keys does not work #214](https://github.com/clicon/clixon/issues/214)
* Fixed: [Multiple http requests in native restconf yields same reply #212](https://github.com/clicon/clixon/issues/212) * Fixed: [Multiple http requests in native restconf yields same reply #212](https://github.com/clicon/clixon/issues/212)

View file

@ -347,11 +347,11 @@ clixon_plugin_statedata_all(clicon_handle h,
} }
if (xml_sort_recurse(x) < 0) if (xml_sort_recurse(x) < 0)
goto done; goto done;
/* Mark non-presence containers as XML_FLAG_DEFAULT */ /* Mark non-presence containers */
if (xml_apply(x, CX_ELMNT, xml_nopresence_default_mark, (void*)XML_FLAG_DEFAULT) < 0) if (xml_apply(x, CX_ELMNT, xml_nopresence_default_mark, (void*)XML_FLAG_TRANSIENT) < 0)
goto done; goto done;
/* Clear XML tree of defaults */ /* Clear XML tree of defaults */
if (xml_tree_prune_flagged(x, XML_FLAG_DEFAULT, 1) < 0) if (xml_tree_prune_flagged(x, XML_FLAG_TRANSIENT, 1) < 0)
goto done; goto done;
/* clear mark and change */ /* clear mark and change */
xml_apply0(x, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset, xml_apply0(x, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset,

View file

@ -156,13 +156,15 @@ typedef struct clixon_xml_vec clixon_xvec; /* struct defined in clicon_xml_vec.c
/* /*
* xml_flag() flags: * xml_flag() flags:
*/ */
#define XML_FLAG_MARK 0x01 /* Marker for dynamic algorithms, eg expand */ #define XML_FLAG_MARK 0x01 /* General-purpose eg expand and xpath_vec selection and
#define XML_FLAG_ADD 0x02 /* Node is added (commits) or parent added rec*/ * diffs between candidate and running */
#define XML_FLAG_DEL 0x04 /* Node is deleted (commits) or parent deleted rec */ #define XML_FLAG_TRANSIENT 0x02 /* Marker for dynamic algorithms, unmark asap */
#define XML_FLAG_CHANGE 0x08 /* Node is changed (commits) or child changed rec */ #define XML_FLAG_ADD 0x04 /* Node is added (commits) or parent added rec*/
#define XML_FLAG_NONE 0x10 /* Node is added as NONE */ #define XML_FLAG_DEL 0x08 /* Node is deleted (commits) or parent deleted rec */
#define XML_FLAG_DEFAULT 0x20 /* Added when a value is set as default @see xml_default */ #define XML_FLAG_CHANGE 0x10 /* Node is changed (commits) or child changed rec */
#define XML_FLAG_TOP 0x40 /* Top datastore symbol */ #define XML_FLAG_NONE 0x20 /* Node is added as NONE */
#define XML_FLAG_DEFAULT 0x40 /* Added when a value is set as default @see xml_default */
#define XML_FLAG_TOP 0x80 /* Top datastore symbol */
/* /*
* Prototypes * Prototypes

View file

@ -504,6 +504,11 @@ xmldb_readfile(clicon_handle h,
if (singleconfigroot(x0, &x0) < 0) if (singleconfigroot(x0, &x0) < 0)
goto done; goto done;
} }
/* Purge all top-level body objects */
x = NULL;
while ((x = xml_find_type(x0, NULL, "body", CX_BODY)) != NULL)
xml_purge(x);
xml_flag_set(x0, XML_FLAG_TOP); xml_flag_set(x0, XML_FLAG_TOP);
if (xml_child_nr(x0) == 0 && de) if (xml_child_nr(x0) == 0 && de)
de->de_empty = 1; de->de_empty = 1;
@ -799,8 +804,15 @@ xmldb_get_cache(clicon_handle h,
goto done; goto done;
if (ret == 0) if (ret == 0)
; /* XXX */ ; /* XXX */
else {
/* Add default global values (to make xpath below include defaults) */
if (xml_global_defaults(h, x0t, nsc, xpath, yspec, 0) < 0)
goto done;
/* Add default recursive values */
if (xml_default_recurse(x0t, 0) < 0)
goto done;
}
} }
/* Here x0t looks like: <config>...</config> */ /* Here x0t looks like: <config>...</config> */
/* Given the xpath, return a vector of matches in xvec /* Given the xpath, return a vector of matches in xvec
* Can we do everything in one go? * Can we do everything in one go?
@ -848,11 +860,14 @@ xmldb_get_cache(clicon_handle h,
goto done; goto done;
} }
/* Remove global defaults from cache /* Remove global defaults from cache
* Mark non-presence containers as XML_FLAG_DEFAULT */ * Mark non-presence containers */
if (xml_apply(x0t, CX_ELMNT, xml_nopresence_default_mark, (void*)XML_FLAG_DEFAULT) < 0) if (xml_apply(x0t, CX_ELMNT, xml_nopresence_default_mark, (void*)XML_FLAG_TRANSIENT) < 0)
goto done;
/* clear XML tree of defaults */
if (xml_tree_prune_flagged(x0t, XML_FLAG_DEFAULT, 1) < 0)
goto done; goto done;
/* Clear XML tree of defaults */ /* Clear XML tree of defaults */
if (xml_tree_prune_flagged(x0t, XML_FLAG_DEFAULT, 1) < 0) if (xml_tree_prune_flagged(x0t, XML_FLAG_TRANSIENT, 1) < 0)
goto done; goto done;
if (yb != YB_NONE){ if (yb != YB_NONE){
/* Add default global values */ /* Add default global values */
@ -1120,11 +1135,11 @@ xmldb_get0_clear(clicon_handle h,
if (x == NULL) if (x == NULL)
goto ok; goto ok;
/* Mark non-presence containers as XML_FLAG_DEFAULT */ /* Mark non-presence containers */
if (xml_apply(x, CX_ELMNT, xml_nopresence_default_mark, (void*)XML_FLAG_DEFAULT) < 0) if (xml_apply(x, CX_ELMNT, xml_nopresence_default_mark, (void*)XML_FLAG_TRANSIENT) < 0)
goto done; goto done;
/* Clear XML tree of defaults */ /* Clear XML tree of defaults */
if (xml_tree_prune_flagged(x, XML_FLAG_DEFAULT, 1) < 0) if (xml_tree_prune_flagged(x, XML_FLAG_TRANSIENT, 1) < 0)
goto done; goto done;
/* clear mark and change */ /* clear mark and change */

View file

@ -994,11 +994,11 @@ xmldb_put(clicon_handle h,
if (xml_apply(x0, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset, if (xml_apply(x0, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset,
(void*)(XML_FLAG_NONE|XML_FLAG_MARK)) < 0) (void*)(XML_FLAG_NONE|XML_FLAG_MARK)) < 0)
goto done; goto done;
/* Mark non-presence containers as XML_FLAG_DEFAULT */ /* Mark non-presence containers */
if (xml_apply(x0, CX_ELMNT, xml_nopresence_default_mark, (void*)XML_FLAG_DEFAULT) < 0) if (xml_apply(x0, CX_ELMNT, xml_nopresence_default_mark, (void*)XML_FLAG_TRANSIENT) < 0)
goto done; goto done;
/* Clear XML tree of defaults */ /* Clear XML tree of defaults */
if (xml_tree_prune_flagged(x0, XML_FLAG_DEFAULT, 1) < 0) if (xml_tree_prune_flagged(x0, XML_FLAG_TRANSIENT, 1) < 0)
goto done; goto done;
#if 0 /* debug */ #if 0 /* debug */
if (xml_apply0(x0, -1, xml_sort_verify, NULL) < 0) if (xml_apply0(x0, -1, xml_sort_verify, NULL) < 0)

View file

@ -1409,9 +1409,9 @@ xml_nopresence_default(cxobj *xt)
* @param[in] x * @param[in] x
* @param[in] arg (flag value) * @param[in] arg (flag value)
* @code * @code
* if (xml_apply(xt, CX_ELMNT, xml_nopresence_default_mark, (void*)XML_FLAG_DEFAULT) < 0) * if (xml_apply(xt, CX_ELMNT, xml_nopresence_default_mark, (void*)XML_FLAG_TRANSIENT) < 0)
* err; * err;
* if (xml_tree_prune_flagged(xt, XML_FLAG_DEFAULT, 1) < 0) * if (xml_tree_prune_flagged(xt, XML_FLAG_TRANSIENT, 1) < 0)
* goto done; * goto done;
* @endcode * @endcode
*/ */

View file

@ -126,9 +126,7 @@ function testrun()
if $admindefault; then # add rule if $admindefault; then # add rule
new "Get type admin expected" new "Get type admin expected"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get-config><source><running/></source><filter type=\"xpath\" select=\"/base:system/base:user[base:name='bob']\" xmlns:base=\"urn:example:base\"/></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data><system xmlns=\"urn:example:base\"><user><name>bob</name><type>admin</type></user></system></data></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get-config><source><running/></source><filter type=\"xpath\" select=\"/base:system/base:user[base:name='bob']/base:type\" xmlns:base=\"urn:example:base\"/></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data><system xmlns=\"urn:example:base\"><user><name>bob</name><type>admin</type></user></system></data></rpc-reply>]]>]]>$"
# XXX Cannot select a default value??
# expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get-config><source><running/></source><filter type=\"xpath\" select=\"/base:system/base:user[base:name='bob']/base:type\" xmlns:base=\"urn:example:base\"/></get-config></rpc>]]>]]>" foo
else else
new "Get type none expected" new "Get type none expected"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get-config><source><running/></source><filter type=\"xpath\" select=\"/base:system/base:user[base:name='bob']/base:type\" xmlns:base=\"urn:example:base\"/></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get-config><source><running/></source><filter type=\"xpath\" select=\"/base:system/base:user[base:name='bob']/base:type\" xmlns:base=\"urn:example:base\"/></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data/></rpc-reply>]]>]]>$"