mod_netconf: provide information about NETCONF session
Add mod_netconf message type to provide information about the session.
diff --git a/src/README b/src/README
index 0033fb4..be81acb 100644
--- a/src/README
+++ b/src/README
@@ -51,10 +51,19 @@
key: bad-namespace (string)
key: session-id (string)
+4) INFO
+key: type (int), value: 3
+key: sid (string), value: session ID
+key: version (string), value: NETCONF protocol version
+key: host (string), value: hostname of the NETCONF server
+key: port (string), value: port of the NETCONF server
+key: user (string), value: username of the user holding the NETCONF session
+key: capabilities (array of strings), value: list of supported capabilities
+
Requests
~~~~~~~~
1) Request to create NETCONF session
-key: type (int), value: 3
+key: type (int), value: 4
key: user (string)
key: pass (string), value: plain text password
@@ -63,18 +72,18 @@
key: port (string), "830" if not specified
2) Request to close NETCONF session
-key: type (int), value: 4
+key: type (int), value: 5
key: session (string), value: unique session identifier
3) NETCONF <get>
-key: type (int), value: 5
+key: type (int), value: 6
key: session (string), value: unique session identifier
Optional:
key: filter (string), value: xml subtree filter
4) NETCONF <get-config>
-key: type (int), value: 6
+key: type (int), value: 7
key: session (string), value: unique session identifier
key: source (string), value: running|startup|candidate
@@ -82,7 +91,7 @@
key: filter (string), value: xml subtree filter
5) NETCONF <edit-config>
-key: type (int), value: 7
+key: type (int), value: 8
key: session (string), value: unique session identifier
key: target (string), value: running|startup|candidate
key: config (string), value: editing configuration data according to NETCONF RFC
@@ -92,7 +101,7 @@
key: error-option (string), value: stop-on-error|continue-on-error|rollback-on-error
6) NETCONF <copy-config>
-key: type (int), value: 8
+key: type (int), value: 9
key: session (string), value: unique session identifier
key: target (string), value: running|startup|candidate
@@ -101,23 +110,26 @@
key: config (string), value: new complete configuration data, if source not specified
7) NETCONF <delete-config>
-key: type (int), value: 9
-key: session (string), value: unique session identifier
-key: target (string), value: running|startup|candidate
-
-8) NETCONF <lock>
key: type (int), value: 10
key: session (string), value: unique session identifier
key: target (string), value: running|startup|candidate
-9) NETCONF <unlock>
+8) NETCONF <lock>
key: type (int), value: 11
key: session (string), value: unique session identifier
key: target (string), value: running|startup|candidate
-10) NETCONF <kill-session>
+9) NETCONF <unlock>
key: type (int), value: 12
key: session (string), value: unique session identifier
+key: target (string), value: running|startup|candidate
+
+10) NETCONF <kill-session>
+key: type (int), value: 13
+key: session (string), value: unique session identifier
key: session-id (string), value: ID of the session to kill
+11) Provide information about NETCONF session
+key: type (int), value: 14
+key: session (string), value: unique session identifier
diff --git a/src/mod_netconf.c b/src/mod_netconf.c
index e6f69ac..43080a8 100644
--- a/src/mod_netconf.c
+++ b/src/mod_netconf.c
@@ -97,6 +97,7 @@
REPLY_OK,
REPLY_DATA,
REPLY_ERROR,
+ REPLY_INFO,
MSG_CONNECT,
MSG_DISCONNECT,
MSG_GET,
@@ -106,7 +107,8 @@
MSG_DELETECONFIG,
MSG_LOCK,
MSG_UNLOCK,
- MSG_KILL
+ MSG_KILL,
+ MSG_INFO
} MSG_TYPE;
#define MSG_OK 0
@@ -522,12 +524,14 @@
struct pollfd fds;
int status;
mod_netconf_cfg *cfg;
- json_object *request, *reply;
+ json_object *request, *reply, *json_obj;
int operation;
char* session_key, *data;
const char *msgtext;
const char *host, *port, *user, *pass;
const char *target, *source, *filter, *config, *defop, *erropt, *sid;
+ struct nc_session *session = NULL;
+ struct nc_cpblts* cpblts;
NC_DATASTORE ds_type_s, ds_type_t;
NC_EDIT_DEFOP_TYPE defop_type = 0;
NC_EDIT_ERROPT_TYPE erropt_type = 0;
@@ -686,6 +690,9 @@
/* null global JSON error-reply */
err_reply = NULL;
+ /* prepare reply envelope */
+ reply = json_object_new_object();
+
/* process required operation */
switch (operation) {
case MSG_CONNECT:
@@ -724,8 +731,6 @@
filter = json_object_get_string(json_object_object_get(request, "filter"));
- reply = json_object_new_object();
-
if ((data = netconf_get(server, netconf_sessions_list, session_key, filter)) == NULL) {
if (err_reply == NULL) {
json_object_object_add(reply, "type", json_object_new_int(REPLY_ERROR));
@@ -745,8 +750,6 @@
filter = json_object_get_string(json_object_object_get(request, "filter"));
- reply = json_object_new_object();
-
if (ds_type_s == -1) {
json_object_object_add(reply, "type", json_object_new_int(REPLY_ERROR));
json_object_object_add(reply, "error-message", json_object_new_string("Invalid source repository type requested."));
@@ -770,8 +773,6 @@
case MSG_EDITCONFIG:
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Request: edit-config (session %s)", session_key);
- reply = json_object_new_object();
-
defop = json_object_get_string(json_object_object_get(request, "default-operation"));
if (defop != NULL) {
if (strcmp(defop, "merge") == 0) {
@@ -836,8 +837,6 @@
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Request: copy-config (session %s)", session_key);
config = NULL;
- reply = json_object_new_object();
-
if (source == NULL) {
/* no explicit source specified -> use config data */
ds_type_s = NC_DATASTORE_NONE;
@@ -887,8 +886,6 @@
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Request: unlock (session %s)", session_key);
}
- reply = json_object_new_object();
-
if (ds_type_t == -1) {
json_object_object_add(reply, "type", json_object_new_int(REPLY_ERROR));
json_object_object_add(reply, "error-message", json_object_new_string("Invalid target repository type requested."));
@@ -928,8 +925,6 @@
sid = json_object_get_string(json_object_object_get(request, "session-id"));
- reply = json_object_new_object();
-
if (sid == NULL) {
json_object_object_add(reply, "type", json_object_new_int(REPLY_ERROR));
json_object_object_add(reply, "error-message", json_object_new_string("Missing session-id parameter."));
@@ -952,7 +947,6 @@
case MSG_DISCONNECT:
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Request: Disconnect session %s", session_key);
- reply = json_object_new_object();
if (netconf_close(server, netconf_sessions_list, session_key) != EXIT_SUCCESS) {
if (err_reply == NULL) {
json_object_object_add(reply, "type", json_object_new_int(REPLY_ERROR));
@@ -966,6 +960,36 @@
json_object_object_add(reply, "type", json_object_new_int(REPLY_OK));
}
break;
+ case MSG_INFO:
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Request: get info about session %s", session_key);
+
+ session = (struct nc_session *)apr_hash_get(netconf_sessions_list, session_key, APR_HASH_KEY_STRING);
+ if (session != NULL) {
+ json_object_object_add(reply, "sid", json_object_new_string(data = nc_session_get_id(session)));
+ if (data) free(data);
+ json_object_object_add(reply, "version", json_object_new_string((nc_session_get_version(session) == 0)?"1.0":"1.1"));
+ json_object_object_add(reply, "host", json_object_new_string(data = nc_session_get_host(session)));
+ if (data) free(data);
+ json_object_object_add(reply, "port", json_object_new_string(data = nc_session_get_port(session)));
+ if (data) free(data);
+ json_object_object_add(reply, "user", json_object_new_string(data = nc_session_get_user(session)));
+ if (data) free(data);
+ cpblts = nc_session_get_cpblts (session);
+ if (cpblts != NULL) {
+ json_obj = json_object_new_array();
+ nc_cpblts_iter_start (cpblts);
+ while ((data = nc_cpblts_iter_next (cpblts)) != NULL) {
+ json_object_array_add(json_obj, json_object_new_string(data));
+ free (data);
+ }
+ json_object_object_add(reply, "capabilities", json_obj);
+ }
+ } else {
+ 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."));
+ }
+
+ break;
default:
ap_log_error(APLOG_MARK, APLOG_ERR, 0, server, "Unknown mod_netconf operation requested (%d)", operation);
reply = json_object_new_object();
diff --git a/src/test-client.c b/src/test-client.c
index 9723b0c..7dc121f 100644
--- a/src/test-client.c
+++ b/src/test-client.c
@@ -58,6 +58,7 @@
REPLY_OK,
REPLY_DATA,
REPLY_ERROR,
+ REPLY_INFO,
MSG_CONNECT,
MSG_DISCONNECT,
MSG_GET,
@@ -67,7 +68,8 @@
MSG_DELETECONFIG,
MSG_LOCK,
MSG_UNLOCK,
- MSG_KILL
+ MSG_KILL,
+ MSG_INFO
} MSG_TYPE;
void print_help(char* progname)
@@ -84,6 +86,7 @@
printf("\tkill-session\n");
printf("\tlock\n");
printf("\tunlock\n");
+ printf("\tinfo\n");
}
int main (int argc, char* argv[])
@@ -95,6 +98,7 @@
size_t len;
char buffer[BUFFER_SIZE];
char* line = NULL;
+ int i, alen;
if (argc != 2) {
print_help(argv[0]);
@@ -300,6 +304,16 @@
getline (&line, &len, stdin);
line[(strlen(line)-1)] = 0;
json_object_object_add(msg, "target", json_object_new_string(line));
+ } else if (strcmp(argv[1], "info") == 0) {
+ /*
+ * Get information about NETCONF session
+ */
+ msg = json_object_new_object();
+ json_object_object_add(msg, "type", json_object_new_int(MSG_INFO));
+ printf("Session: ");
+ getline (&line, &len, stdin);
+ line[(strlen(line)-1)] = 0;
+ json_object_object_add(msg, "session", json_object_new_string(line));
} else {
/*
* Unknown request
@@ -342,6 +356,13 @@
case json_type_int:
printf("%d\n", json_object_get_int(value));
break;
+ case json_type_array:
+ printf("\n");
+ alen = json_object_array_length(value);
+ for (i = 0; i < alen; i++) {
+ printf("\t(%d) %s\n", i, json_object_get_string(json_object_array_get_idx(value, i)));
+ }
+ break;
default:
printf("\n");
break;