mod_netconf: process <rpc-error> and provide data
Provide information about received <rpc-error> from the mod_netconf
daemon to the calling client via JSON format message.
diff --git a/src/mod_netconf.c b/src/mod_netconf.c
index bfb227c..69e5700 100644
--- a/src/mod_netconf.c
+++ b/src/mod_netconf.c
@@ -197,6 +197,32 @@
return;
}
+static json_object *err_reply = NULL;
+void netconf_callback_error_process(const char* tag,
+ const char* type,
+ const char* severity,
+ const char* apptag,
+ const char* path,
+ const char* message,
+ const char* attribute,
+ const char* element,
+ const char* ns,
+ const char* sid)
+{
+ err_reply = json_object_new_object();
+ json_object_object_add(err_reply, "type", json_object_new_int(REPLY_ERROR));
+ if (tag) json_object_object_add(err_reply, "error-tag", json_object_new_string(tag));
+ if (type) json_object_object_add(err_reply, "error-type", json_object_new_string(type));
+ if (severity) json_object_object_add(err_reply, "error-severity", json_object_new_string(severity));
+ if (apptag) json_object_object_add(err_reply, "error-app-tag", json_object_new_string(apptag));
+ if (path) json_object_object_add(err_reply, "error-path", json_object_new_string(path));
+ if (message) json_object_object_add(err_reply, "error-message", json_object_new_string(message));
+ if (attribute) json_object_object_add(err_reply, "bad-attribute", json_object_new_string(attribute));
+ if (element) json_object_object_add(err_reply, "bad-element", json_object_new_string(element));
+ if (ns) json_object_object_add(err_reply, "bad-namespace", json_object_new_string(ns));
+ if (sid) json_object_object_add(err_reply, "session-id", json_object_new_string(sid));
+}
+
static char* netconf_connect(server_rec* server, apr_pool_t* pool, apr_hash_t* conns, const char* host, const char* port, const char* user, const char* pass)
{
struct nc_session* session;
@@ -211,7 +237,10 @@
if (session != NULL) {
/* generate hash for the session */
sid = nc_session_get_id(session);
- session_key = gen_ncsession_hash(host, port, sid);
+ session_key = gen_ncsession_hash(
+ (host==NULL) ? "localhost" : host,
+ (port==NULL) ? "830" : port,
+ sid);
free(sid);
apr_hash_set(conns, apr_pstrdup(pool, session_key), APR_HASH_KEY_STRING, (void *) session);
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, server, "NETCONF session established");
@@ -491,6 +520,7 @@
nc_callback_ssh_host_authenticity_check(netconf_callback_ssh_hostkey_check);
nc_callback_sshauth_interactive(netconf_callback_sshauth_interactive);
nc_callback_sshauth_password(netconf_callback_sshauth_password);
+ nc_callback_error_reply(netconf_callback_error_process);
/* disable publickey authentication */
nc_ssh_pref(NC_SSH_AUTH_PUBLIC_KEYS, -1);
@@ -569,6 +599,10 @@
break;
}
+ /* null global JSON error-reply */
+ err_reply = NULL;
+
+ /* process required operation */
switch (operation) {
case MSG_CONNECT:
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Request: Connect");
@@ -584,8 +618,14 @@
reply = json_object_new_object();
if (session_key == NULL) {
/* negative reply */
- json_object_object_add(reply, "type", json_object_new_int(REPLY_ERROR));
- json_object_object_add(reply, "error-message", json_object_new_string("Connecting NETCONF server failed."));
+ if (err_reply == NULL) {
+ json_object_object_add(reply, "type", json_object_new_int(REPLY_ERROR));
+ json_object_object_add(reply, "error-message", json_object_new_string("Connecting NETCONF server failed."));
+ } else {
+ /* use filled err_reply from libnetconf's callback */
+ json_object_put(reply);
+ reply = err_reply;
+ }
} else {
/* positive reply */
json_object_object_add(reply, "type", json_object_new_int(REPLY_OK));
@@ -602,8 +642,14 @@
reply = json_object_new_object();
if ((data = netconf_get(server, netconf_sessions_list, session_key, filter)) == NULL) {
- json_object_object_add(reply, "type", json_object_new_int(REPLY_ERROR));
- json_object_object_add(reply, "error-message", json_object_new_string("get failed."));
+ if (err_reply == NULL) {
+ json_object_object_add(reply, "type", json_object_new_int(REPLY_ERROR));
+ json_object_object_add(reply, "error-message", json_object_new_string("get failed."));
+ } else {
+ /* use filled err_reply from libnetconf's callback */
+ json_object_put(reply);
+ reply = err_reply;
+ }
} else {
json_object_object_add(reply, "type", json_object_new_int(REPLY_DATA));
json_object_object_add(reply, "data", json_object_new_string(data));
@@ -630,8 +676,14 @@
}
if ((data = netconf_getconfig(server, netconf_sessions_list, session_key, ds_type1, filter)) == NULL) {
- json_object_object_add(reply, "type", json_object_new_int(REPLY_ERROR));
- json_object_object_add(reply, "error-message", json_object_new_string("get-config failed."));
+ if (err_reply == NULL) {
+ json_object_object_add(reply, "type", json_object_new_int(REPLY_ERROR));
+ json_object_object_add(reply, "error-message", json_object_new_string("get-config failed."));
+ } else {
+ /* use filled err_reply from libnetconf's callback */
+ json_object_put(reply);
+ reply = err_reply;
+ }
} else {
json_object_object_add(reply, "type", json_object_new_int(REPLY_DATA));
json_object_object_add(reply, "data", json_object_new_string(data));
@@ -680,8 +732,14 @@
json_object_object_add(reply, "error-message", json_object_new_string("invalid input parameters."));
} else {
if (netconf_copyconfig(server, netconf_sessions_list, session_key, ds_type1, ds_type2, config) != EXIT_SUCCESS) {
- json_object_object_add(reply, "type", json_object_new_int(REPLY_ERROR));
- json_object_object_add(reply, "error-message", json_object_new_string("copy-config failed."));
+ if (err_reply == NULL) {
+ json_object_object_add(reply, "type", json_object_new_int(REPLY_ERROR));
+ json_object_object_add(reply, "error-message", json_object_new_string("copy-config failed."));
+ } else {
+ /* use filled err_reply from libnetconf's callback */
+ json_object_put(reply);
+ reply = err_reply;
+ }
} else {
json_object_object_add(reply, "type", json_object_new_int(REPLY_OK));
}
@@ -692,8 +750,14 @@
reply = json_object_new_object();
if (netconf_close(server, netconf_sessions_list, session_key) != EXIT_SUCCESS) {
- json_object_object_add(reply, "type", json_object_new_int(REPLY_ERROR));
- json_object_object_add(reply, "error-message", json_object_new_string("Invalid session identifier."));
+ if (err_reply == NULL) {
+ json_object_object_add(reply, "type", json_object_new_int(REPLY_ERROR));
+ json_object_object_add(reply, "error-message", json_object_new_string("Invalid session identifier."));
+ } else {
+ /* use filled err_reply from libnetconf's callback */
+ json_object_put(reply);
+ reply = err_reply;
+ }
} else {
json_object_object_add(reply, "type", json_object_new_int(REPLY_OK));
}