Skip to content

Commit

Permalink
Rework netconf rpc-error reporting
Browse files Browse the repository at this point in the history
An XML version was needed, and it had much in common with the
netconf_common_xml() function, so make a common XML function for
generating rpc-error output.

Signed-off-by: Corey Minyard <corey@minyard.net>
  • Loading branch information
cminyard committed Nov 23, 2024
1 parent 629cd60 commit 9dc4b28
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 24 deletions.
20 changes: 20 additions & 0 deletions apps/backend/backend_commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,26 @@ netconf_gen_rpc_err(cbuf *cbret)
return ret;
}

int
netconf_gen_rpc_err_xml(cxobj **xret)
{
char *type = _plugin_rpc_err_type;
int ret;

/* Type marks it as set, clear it before handling. */
_plugin_rpc_err_type = NULL;
ret = netconf_common_rpc_err_xml(xret, _plugin_rpc_err_ns,
type,
_plugin_rpc_err_tag,
_plugin_rpc_err_severity,
NULL,
_plugin_rpc_err_info,
cbuf_get(_plugin_rpc_err_message));
free(type);

return ret;
}


/*! Start a validate transaction
*
Expand Down
14 changes: 7 additions & 7 deletions apps/backend/backend_plugin.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,20 +350,20 @@ clixon_plugin_statedata_all(clixon_handle h,
if ((ret = clixon_plugin_statedata_one(cp, h, nsc, xpath, &x)) < 0)
goto done;
if (ret == 0){
if ((cberr = cbuf_new()) == NULL){
clixon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
if (plugin_rpc_err_set()) {
if (netconf_gen_rpc_err(cberr) < 0)
if (netconf_gen_rpc_err_xml(&xerr) < 0)
goto done;
} else {
if ((cberr = cbuf_new()) == NULL){
clixon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
/* error reason should be in clixon_err_reason */
cprintf(cberr, "Internal error, state callback in plugin %s returned invalid XML: %s",
clixon_plugin_name_get(cp), clixon_err_reason());
if (netconf_operation_failed_xml(&xerr, "application", cbuf_get(cberr)) < 0)
goto done;
}
if (netconf_operation_failed_xml(&xerr, "application", cbuf_get(cberr)) < 0)
goto done;
xml_free(*xret);
*xret = xerr;
xerr = NULL;
Expand Down
1 change: 1 addition & 0 deletions apps/backend/clixon_backend_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,5 +138,6 @@ int plugin_rpc_err(clixon_handle h, const char *ns,
const char *severity, const char *fmt, ...);
int plugin_rpc_err_set(void);
int netconf_gen_rpc_err(cbuf *cbret);
int netconf_gen_rpc_err_xml(cxobj **xret);

#endif /* _CLIXON_BACKEND_PLUGIN_H_ */
3 changes: 3 additions & 0 deletions lib/clixon/clixon_netconf_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@ int netconf_bad_attribute_xml(cxobj **xret, char *type, char *info, char *messag
int netconf_unknown_attribute(cbuf *cb, char *type, char *info, char *message);
int netconf_common_rpc_err(cbuf *cb, char *ns, char *type, char *tag, char *info,
char *severity, char *message);
int netconf_common_rpc_err_xml(cxobj **xret, char *ns, char *type, char *tag,
char *severity, char *infotag, char *info,
char *message);
int netconf_missing_element(cbuf *cb, char *type, char *element, char *message);
int netconf_missing_yang_xml(cxobj **xret, char *path, char *app_tag, char *info, char *message);
int netconf_missing_element_xml(cxobj **xret, char *type, char *element, char *message);
Expand Down
86 changes: 69 additions & 17 deletions lib/src/clixon_netconf_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -543,23 +543,29 @@ netconf_common_rpc_err(cbuf *cb,
goto done;
}

/*! Common Netconf element XML tree according to RFC 6241 App A
/*! Common Netconf element XML tree according to RFC 6241 App A, allow a
* passed in namespace.
*
* @param[out] xret Error XML tree. Free with xml_free after use
* @param[in] ns Namespace to use, if NULL it will use the default
* @param[in] type Error type: "application" or "protocol"
* @param[in] tag Error tag
* @param[in] element bad-element xml
* @param[in] message Error message (will be XML encoded)
* @param[in] severity Message severity
* @param[in] infotag Tag for the info, may be NULL if not tag required
* @param[in] info info, may be NULL if no info
* @param[in] message Error message (will be XML encoded), may be NULL
* @retval 0 OK
* @retval -1 Error
*/
static int
netconf_common_xml(cxobj **xret,
char *type,
char *tag,
char *infotag,
char *element,
char *message)
int
netconf_common_rpc_err_xml(cxobj **xret,
char *ns,
char *type,
char *tag,
char *severity,
char *infotag,
char *info,
char *message)
{
int retval =-1;
cxobj *xerr;
Expand All @@ -569,22 +575,45 @@ netconf_common_xml(cxobj **xret,
clixon_err(OE_NETCONF, EINVAL, "xret is NULL");
goto done;
}

if (!ns)
ns = NETCONF_BASE_NAMESPACE;

if (*xret == NULL){
if ((*xret = xml_new("rpc-reply", NULL, CX_ELMNT)) == NULL)
goto done;
if (xml_add_attr(*xret, "xmlns", NETCONF_BASE_NAMESPACE, NULL, NULL) == NULL)
if (xml_add_attr(*xret, "xmlns", ns, NULL, NULL) == NULL)
goto done;
}
else if (xml_name_set(*xret, "rpc-reply") < 0)
goto done;
if ((xerr = xml_new("rpc-error", *xret, CX_ELMNT)) == NULL)
goto done;
if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL, "<error-type>%s</error-type>"
"<error-tag>%s</error-tag>"
"<error-info><%s>%s</%s></error-info>"
"<error-severity>error</error-severity>",
type, tag, infotag, element, infotag) < 0)
goto done;
if (infotag) {
if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL,
"<error-type>%s</error-type>"
"<error-tag>%s</error-tag>"
"<error-info><%s>%s</%s></error-info>"
"<error-severity>%s</error-severity>",
type, tag, infotag, info, infotag,
severity) < 0)
goto done;
} else if (info) {
if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL,
"<error-type>%s</error-type>"
"<error-tag>%s</error-tag>"
"<error-info>%s</error-info>"
"<error-severity>%s</error-severity>",
type, tag, info, severity) < 0)
goto done;
} else {
if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL,
"<error-type>%s</error-type>"
"<error-tag>%s</error-tag>"
"<error-severity>%s</error-severity>",
type, tag, severity) < 0)
goto done;
}
if (message){
if (xml_chardata_encode(&encstr, 0, "%s", message) < 0)
goto done;
Expand All @@ -597,6 +626,29 @@ netconf_common_xml(cxobj **xret,
if (encstr)
free(encstr);
return retval;
}

/*! Common Netconf element XML tree according to RFC 6241 App A
*
* @param[out] xret Error XML tree. Free with xml_free after use
* @param[in] type Error type: "application" or "protocol"
* @param[in] tag Error tag
* @param[in] element bad-element xml
* @param[in] message Error message (will be XML encoded)
* @retval 0 OK
* @retval -1 Error
*/
static int
netconf_common_xml(cxobj **xret,
char *type,
char *tag,
char *infotag,
char *element,
char *message)
{
return netconf_common_rpc_err_xml(xret, NETCONF_BASE_NAMESPACE,
type, tag, "error", infotag, element,
message);
}

/*! Create Netconf missing-element error XML tree according to RFC 6241 App A
Expand Down

0 comments on commit 9dc4b28

Please sign in to comment.