Fixed IDENTITYREF_KLUDGE removal #2

This commit is contained in:
Olof hagsand 2022-11-07 09:19:29 +01:00
parent b0f898cf66
commit 4b21a05bcc
5 changed files with 62 additions and 17 deletions

View file

@ -211,6 +211,53 @@ dbxml_body(cxobj *xbot,
return retval;
}
/*! Special handling of identityref:s whose body may be: <namespace prefix>:<id>
* Ensure the namespace is declared if it exists in YANG
*/
static int
identityref_add_ns(cxobj *x,
void *arg)
{
int retval = -1;
yang_stmt *yspec = (yang_stmt *)arg;
yang_stmt *y;
yang_stmt *yrestype; /* resolved type */
char *restype; /* resolved type */
char *origtype = NULL; /* original type */
char *pf = NULL;
yang_stmt *yns;
char *ns = NULL;
if ((y = xml_spec(x)) != NULL &&
yang_keyword_get(y) == Y_LEAF){
if (yang_type_get(y, &origtype, &yrestype, NULL, NULL, NULL, NULL, NULL) < 0)
goto done;
restype = yrestype?yang_argument_get(yrestype):NULL;
if (strcmp(restype, "identityref") == 0){
if (nodeid_split(xml_body(x), &pf, NULL) < 0)
goto done;
// search if already defined
if (pf != NULL){
if (xml2ns(x, pf, &ns) < 0)
goto done;
if (ns == NULL &&
(yns = yang_find_module_by_prefix_yspec(yspec, pf)) != NULL){
if ((ns = yang_find_mynamespace(yns)) != NULL)
if (xmlns_set(x, pf, ns) < 0)
goto done;
}
}
}
}
retval = 0;
done:
if (origtype)
free(origtype);
if (pf)
free(pf);
return retval;
}
/*! Modify xml datastore from a callback using xml key format strings
* @param[in] h Clicon handle
* @param[in] cvv Vector of cli string and instantiated variables
@ -229,7 +276,7 @@ dbxml_body(cxobj *xbot,
* @see cli_callback_generate where arg is generated
* @note The last value may require namespace binding present in nsctx. Note that the nsctx
* cannot normally be supplied by the clispec functions, such as cli_set, but need to be
* generated by afunction such as clixon_instance_id_bind() or other programmatically.
* generated by a function such as clixon_instance_id_bind() or other programmatically.
*/
int
cli_dbxml(clicon_handle h,
@ -270,7 +317,6 @@ cli_dbxml(clicon_handle h,
/* Transform template format string + cvv to actual api-path
* cvv_i indicates if all cvv entries were used
*/
if (api_path_fmt2api_path(api_path_fmt, cvv, &api_path, &cvv_i) < 0)
goto done;
/* Create config top-of-tree */
@ -321,6 +367,11 @@ cli_dbxml(clicon_handle h,
goto done;
}
}
/* Special handling of identityref:s whose body may be: <namespace prefix>:<id>
* Ensure the namespace is declared if it exists in YANG
*/
if ((ret = xml_apply0(xbot, CX_ELMNT, identityref_add_ns, yspec)) < 0)
goto done;
if ((cb = cbuf_new()) == NULL){
clicon_err(OE_XML, errno, "cbuf_new");
goto done;

View file

@ -113,8 +113,8 @@
* Problem is that the tree is in an intermediate state so that a when condition may not see the
* full context.
* More specifically, new nodes (x0) are created without hooking them into the existing parent (x0p)
* and thus an xpath on the form ".."/PARENT may not be evaluated as they should. x0 is eventually
* added to its parent but then it is more difficult to check trhe when condition.
* and thus an xpath on the form "../PARENT" may not be evaluated as they should. x0 is eventually
* added to its parent but then it is more difficult to check the when condition.
* This fix add the parent x0p as a "candidate" so that the xpath-eval function can use it as
* an alernative if it exists.
* Note although this solves many usecases involving parents and absolute paths, it still does not

View file

@ -163,7 +163,6 @@ check_body_namespace(cxobj *x0,
cxobj *x;
int isroot;
cbuf *cberr = NULL;
int ret;
/* XXX: need to identify root better than hiereustics and strcmp,... */
isroot = xml_parent(x0p)==NULL &&
@ -221,6 +220,7 @@ bad-attribue?
#endif
else{ /* Namespace does not exist in x0: error */
#ifdef IDENTITYREF_KLUDGE
int ret;
if (ns1 == NULL){
if ((ret = yang_find_namespace_by_prefix(y, prefix, &ns0)) < 0)
goto done;

View file

@ -347,17 +347,11 @@ json2xml_decode_identityref(cxobj *x,
__FUNCTION__, prefix, body, ns);
if (!xml_nsctx_get_prefix(nsc, ns, &prefix2)){
/* (no) insert a xmlns:<prefix> statement
* Get yang prefix from import statement of my mod */
if (yang_find_prefix_by_namespace(y, ns, &prefix2) == 0){
#ifndef IDENTITYREF_KLUDGE
/* Just get the prefix from the module's own namespace */
if (xerr && netconf_unknown_namespace_xml(xerr, "application",
ns,
"No local prefix corresponding to namespace") < 0)
goto done;
goto fail;
#endif
}
* Get yang prefix from import statement of my mod
* I am not sure this is correct
*/
if (yang_find_prefix_by_namespace(y, ns, &prefix2) < 0)
goto done;
/* if prefix2 is NULL here, we get the canonical prefix */
if (prefix2 == NULL)
prefix2 = yang_find_myprefix(ymod);

View file

@ -280,7 +280,7 @@ new "cli validate"
expectpart "$($clixon_cli -1 -f $cfg -l o validate)" 0 "^$"
new "Netconf set acl-type"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><acls xmlns=\"urn:example:my-crypto\"><acl><name>x</name><type>mc:ipv4-acl-type</type></acl></acls></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><acls xmlns=\"urn:example:my-crypto\"><acl><name>x</name><type xmlns:mc=\"urn:example:my-crypto\">mc:ipv4-acl-type</type></acl></acls></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
new "netconf validate "
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"