Add a way to report rpc-errors from a plugin
Add plugin_rpc_err(), which works something like clixon_err, but it saves error information from a plugin for reporting rpc-errors that need to be returned. Also add plugin_rpc_err_xml(), which does an XML formatted error. The plugin error is stored in the clixon_handle and retrieved from there. Signed-off-by: Corey Minyard <corey@minyard.net>
This commit is contained in:
parent
3a1aa4052f
commit
9bdacc8671
2 changed files with 211 additions and 0 deletions
|
|
@ -552,4 +552,11 @@ const char *clixon_auth_type_int2str(clixon_auth_type_t auth_type);
|
||||||
int clixon_plugin_module_init(clixon_handle h);
|
int clixon_plugin_module_init(clixon_handle h);
|
||||||
int clixon_plugin_module_exit(clixon_handle h);
|
int clixon_plugin_module_exit(clixon_handle h);
|
||||||
|
|
||||||
|
int clixon_plugin_rpc_err(clixon_handle h, const char *ns,
|
||||||
|
const char *type, const char *tag, const char *info,
|
||||||
|
const char *severity, const char *fmt, ...);
|
||||||
|
int clixon_plugin_rpc_err_set(clixon_handle h);
|
||||||
|
int clixon_plugin_report_err(clixon_handle h, cbuf *cbret);
|
||||||
|
int clixon_plugin_report_err_xml(clixon_handle h, cxobj **xreg, char *err, ...);
|
||||||
|
|
||||||
#endif /* _CLIXON_PLUGIN_H_ */
|
#endif /* _CLIXON_PLUGIN_H_ */
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@
|
||||||
#include "clixon_netconf_lib.h"
|
#include "clixon_netconf_lib.h"
|
||||||
#include "clixon_validate.h"
|
#include "clixon_validate.h"
|
||||||
#include "clixon_proc.h"
|
#include "clixon_proc.h"
|
||||||
|
#include "clixon_data.h"
|
||||||
#include "clixon_plugin.h"
|
#include "clixon_plugin.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1767,6 +1768,207 @@ clixon_auth_type_int2str(clixon_auth_type_t auth_type)
|
||||||
return clicon_int2str(clixon_auth_type, auth_type);
|
return clicon_int2str(clixon_auth_type, auth_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Save an RPC error to be reported by clixon.
|
||||||
|
*
|
||||||
|
* @param[in] h Clixon
|
||||||
|
* @param[in] ns Namespace. If NULL the netconf base ns will be used
|
||||||
|
* @param[in] type Error type: "rpc", "application" or "protocol"
|
||||||
|
* @param[in] severity Severity: "error" or "warning"
|
||||||
|
* @param[in] tag Error tag, like "invalid-value" or "unknown-attribute"
|
||||||
|
* @param[in] info bad-attribute or bad-element xml. If NULL not included.
|
||||||
|
* @param[in] fmt Error message format. May be NULL.
|
||||||
|
* @retval 0 Success
|
||||||
|
* @retval -1 Error
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
clixon_plugin_rpc_err(clixon_handle h,
|
||||||
|
const char *ns,
|
||||||
|
const char *type,
|
||||||
|
const char *tag,
|
||||||
|
const char *info,
|
||||||
|
const char *severity,
|
||||||
|
const char *fmt, ...)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
int err;
|
||||||
|
cvec *cvv = NULL;
|
||||||
|
cvec *old_cvv = clicon_data_cvec_get(h, "rpc_err");
|
||||||
|
|
||||||
|
cvv = cvec_new(0);
|
||||||
|
if (!cvv)
|
||||||
|
goto done;
|
||||||
|
if (ns) {
|
||||||
|
if (cvec_add_string(cvv, "ns", ns))
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (cvec_add_string(cvv, "type", type))
|
||||||
|
goto done;
|
||||||
|
if (cvec_add_string(cvv, "tag", tag))
|
||||||
|
goto done;
|
||||||
|
if (info) {
|
||||||
|
if (cvec_add_string(cvv, "info", info))
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (cvec_add_string(cvv, "severity", severity))
|
||||||
|
goto done;
|
||||||
|
if (fmt) {
|
||||||
|
va_list args;
|
||||||
|
cbuf *cb;
|
||||||
|
|
||||||
|
cb = cbuf_new();
|
||||||
|
if (!cb)
|
||||||
|
goto done;
|
||||||
|
va_start(args, fmt);
|
||||||
|
err = vcprintf(cb, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
if (err < 0) {
|
||||||
|
cbuf_free(cb);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
cvec_add_string(cvv, "message", cbuf_get(cb));
|
||||||
|
cbuf_free(cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
err = clicon_data_cvec_set(h, "rpc_err", cvv);
|
||||||
|
if (err)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
retval = 0;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (retval && cvv)
|
||||||
|
cvec_free(cvv);
|
||||||
|
if (!retval && old_cvv)
|
||||||
|
cvec_free(old_cvv);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Frees memory associated with clixon_rpc_err().
|
||||||
|
*
|
||||||
|
* @param[in] h Clixon
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
clixon_plugin_rpc_err_exit(clixon_handle h)
|
||||||
|
{
|
||||||
|
cvec *cvv = clicon_data_cvec_get(h, "rpc_err");
|
||||||
|
|
||||||
|
clicon_ptr_del(h, "rpc_err");
|
||||||
|
cvec_free(cvv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Returns if the rpc error has already been set.
|
||||||
|
*
|
||||||
|
* @param[in] h Clixon
|
||||||
|
*
|
||||||
|
* @retval 0 The rpc error is not set
|
||||||
|
* @retval 1 The rpc error is set
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
clixon_plugin_rpc_err_set(clixon_handle h)
|
||||||
|
{
|
||||||
|
return clicon_data_cvec_get(h, "rpc_err") != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
netconf_gen_rpc_err(clixon_handle h, cbuf *cbret)
|
||||||
|
{
|
||||||
|
cvec *cvv = clicon_data_cvec_get(h, "rpc_err");
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
/* Delete the pointer so the cvec doesn't get freed. */
|
||||||
|
clicon_ptr_del(h, "rpc_err");
|
||||||
|
retval = netconf_common_rpc_err(cbret,
|
||||||
|
cvec_find_str(cvv, "ns"),
|
||||||
|
cvec_find_str(cvv, "type"),
|
||||||
|
cvec_find_str(cvv, "tag"),
|
||||||
|
cvec_find_str(cvv, "severity"),
|
||||||
|
cvec_find_str(cvv, "info"),
|
||||||
|
cvec_find_str(cvv, "message"));
|
||||||
|
cvec_free(cvv);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
netconf_gen_rpc_err_xml(clixon_handle h, cxobj **xret)
|
||||||
|
{
|
||||||
|
cvec *cvv = clicon_data_cvec_get(h, "rpc_err");
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
/* Delete the pointer so the cvec doesn't get freed. */
|
||||||
|
clicon_ptr_del(h, "rpc_err");
|
||||||
|
retval = netconf_common_rpc_err_xml(xret,
|
||||||
|
cvec_find_str(cvv, "ns"),
|
||||||
|
cvec_find_str(cvv, "type"),
|
||||||
|
cvec_find_str(cvv, "tag"),
|
||||||
|
cvec_find_str(cvv, "severity"),
|
||||||
|
NULL,
|
||||||
|
cvec_find_str(cvv, "info"),
|
||||||
|
cvec_find_str(cvv, "message"));
|
||||||
|
cvec_free(cvv);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Report an error from a plugin.
|
||||||
|
*
|
||||||
|
* @param[in] h Clixon
|
||||||
|
* @param[out] cbret CLIgen buffer w error stmt if retval = 0
|
||||||
|
* @retval 0 Success
|
||||||
|
* @retval -1 Error
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
clixon_plugin_report_err(clixon_handle h,
|
||||||
|
cbuf *cbret)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (clixon_plugin_rpc_err_set(h)) {
|
||||||
|
if ((ret = netconf_gen_rpc_err(h, cbret)) < 0)
|
||||||
|
return ret;
|
||||||
|
} else if ((ret = netconf_operation_failed(cbret, "application",
|
||||||
|
clixon_err_reason())) < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Report an error from a plugin.
|
||||||
|
*
|
||||||
|
* @param[in] h Clixon
|
||||||
|
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||||
|
* @retval 0 Success
|
||||||
|
* @retval -1 Error
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
clixon_plugin_report_err_xml(clixon_handle h,
|
||||||
|
cxobj **xret,
|
||||||
|
char *err,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
cbuf *cberr;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
if (clixon_plugin_rpc_err_set(h)) {
|
||||||
|
ret = netconf_gen_rpc_err_xml(h, xret);
|
||||||
|
} else {
|
||||||
|
if ((cberr = cbuf_new()) == NULL) {
|
||||||
|
clixon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
va_start(ap, err);
|
||||||
|
vcprintf(cberr, err, ap);
|
||||||
|
ret = netconf_operation_failed_xml(xret, "application",
|
||||||
|
cbuf_get(cberr));
|
||||||
|
cbuf_free(cberr);
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*! Initialize plugin module by creating a handle holding plugin and callback lists
|
/*! Initialize plugin module by creating a handle holding plugin and callback lists
|
||||||
*
|
*
|
||||||
* This should be called once at start by every application
|
* This should be called once at start by every application
|
||||||
|
|
@ -1818,5 +2020,7 @@ clixon_plugin_module_exit(clixon_handle h)
|
||||||
free(ph);
|
free(ph);
|
||||||
plugin_module_struct_set(h, NULL);
|
plugin_module_struct_set(h, NULL);
|
||||||
}
|
}
|
||||||
|
/* Free memory associated with plugin_rpc_err() */
|
||||||
|
clixon_plugin_rpc_err_exit(h);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue