* Proper RFC 6241 Netconf error handling
* New functions added in clixon_netconf_lib.[ch] * Datastore code modified for RFC 6241 * Remaining: validate, generic restconf and netconf code
This commit is contained in:
parent
52e510cfdf
commit
efa72e9e6f
26 changed files with 1196 additions and 475 deletions
|
|
@ -180,7 +180,7 @@ backend_client_rm(clicon_handle h,
|
|||
return backend_client_delete(h, ce); /* actually purge it */
|
||||
}
|
||||
|
||||
/*! FInd target/source in netconf request. Assume sanity made so not finding is error */
|
||||
/*! Find target/source in netconf request. Assume sanity- not finding is error */
|
||||
static char*
|
||||
netconf_db_find(cxobj *xn,
|
||||
char *name)
|
||||
|
|
@ -214,31 +214,28 @@ from_client_get_config(clicon_handle h,
|
|||
cxobj *xfilter;
|
||||
char *selector = "/";
|
||||
cxobj *xret = NULL;
|
||||
cbuf *cbx = NULL; /* Assist cbuf */
|
||||
|
||||
if ((db = netconf_db_find(xe, "source")) == NULL){
|
||||
clicon_err(OE_XML, 0, "db not found");
|
||||
goto done;
|
||||
}
|
||||
if (xmldb_validate_db(db) < 0){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>invalid-value</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>No such database: %s</error-message>"
|
||||
"</rpc-error></rpc-reply>", db);
|
||||
if ((cbx = cbuf_new()) == NULL){
|
||||
clicon_err(OE_XML, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
cprintf(cbx, "No such database: %s", db);
|
||||
if (netconf_invalid_value(cbret, "protocol", cbuf_get(cbx))< 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
||||
if ((xfilter = xml_find(xe, "filter")) != NULL)
|
||||
if ((selector = xml_find_value(xfilter, "select"))==NULL)
|
||||
selector="/";
|
||||
if (xmldb_get(h, db, selector, 1, &xret) < 0){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>operation-failed</error-tag>"
|
||||
"<error-type>application</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-info>read-registry</error-info>"
|
||||
"</rpc-error></rpc-reply>");
|
||||
if (netconf_operation_failed(cbret, "application", "read registry")< 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
cprintf(cbret, "<rpc-reply>");
|
||||
|
|
@ -254,6 +251,8 @@ from_client_get_config(clicon_handle h,
|
|||
ok:
|
||||
retval = 0;
|
||||
done:
|
||||
if (cbx)
|
||||
cbuf_free(cbx);
|
||||
if (xret)
|
||||
xml_free(xret);
|
||||
return retval;
|
||||
|
|
@ -276,18 +275,15 @@ from_client_get(clicon_handle h,
|
|||
char *selector = "/";
|
||||
cxobj *xret = NULL;
|
||||
int ret;
|
||||
cbuf *cbx = NULL; /* Assist cbuf */
|
||||
|
||||
if ((xfilter = xml_find(xe, "filter")) != NULL)
|
||||
if ((selector = xml_find_value(xfilter, "select"))==NULL)
|
||||
selector="/";
|
||||
/* Get config */
|
||||
if (xmldb_get(h, "running", selector, 0, &xret) < 0){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>operation-failed</error-tag>"
|
||||
"<error-type>application</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-info>read-registry</error-info>"
|
||||
"</rpc-error></rpc-reply>");
|
||||
if (netconf_operation_failed(cbret, "application", "read registry")< 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
/* Get state data from plugins as defined by plugin_statedata(), if any */
|
||||
|
|
@ -308,23 +304,25 @@ from_client_get(clicon_handle h,
|
|||
cprintf(cbret, "</rpc-reply>");
|
||||
}
|
||||
else { /* 1 Error from callback */
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>operation-failed</error-tag>"
|
||||
"<error-type>rpc</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>Internal error:%s</error-message>"
|
||||
"</rpc-error></rpc-reply>", clicon_err_reason);
|
||||
if ((cbx = cbuf_new()) == NULL){
|
||||
clicon_err(OE_XML, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
cprintf(cbx, "Internal error:%s", clicon_err_reason);
|
||||
if (netconf_operation_failed(cbret, "rpc", cbuf_get(cbx))< 0)
|
||||
goto done;
|
||||
clicon_log(LOG_NOTICE, "%s Error in backend_statedata_call:%s", __FUNCTION__, xml_name(xe));
|
||||
}
|
||||
ok:
|
||||
retval = 0;
|
||||
done:
|
||||
if (cbx)
|
||||
cbuf_free(cbx);
|
||||
if (xret)
|
||||
xml_free(xret);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*! Internal message: edit-config
|
||||
*
|
||||
* @param[in] h Clicon handle
|
||||
|
|
@ -340,14 +338,13 @@ from_client_edit_config(clicon_handle h,
|
|||
{
|
||||
int retval = -1;
|
||||
char *target;
|
||||
cbuf *cb = NULL;
|
||||
cxobj *xret = NULL;
|
||||
cxobj *xc;
|
||||
cxobj *x;
|
||||
enum operation_type operation = OP_MERGE;
|
||||
int piddb;
|
||||
int non_config = 0;
|
||||
yang_spec *yspec;
|
||||
cbuf *cbx = NULL; /* Assist cbuf */
|
||||
|
||||
if ((yspec = clicon_dbspec_yang(h)) == NULL){
|
||||
clicon_err(OE_YANG, ENOENT, "No yang spec");
|
||||
|
|
@ -357,50 +354,44 @@ from_client_edit_config(clicon_handle h,
|
|||
clicon_err(OE_XML, 0, "db not found");
|
||||
goto done;
|
||||
}
|
||||
if ((cbx = cbuf_new()) == NULL){
|
||||
clicon_err(OE_XML, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
if (xmldb_validate_db(target) < 0){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>invalid-value</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>No such database: %s</error-message>"
|
||||
"</rpc-error></rpc-reply>", target);
|
||||
cprintf(cbx, "No such database: %s", target);
|
||||
if (netconf_invalid_value(cbret, "protocol", cbuf_get(cbx))< 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
/* Check if target locked by other client */
|
||||
piddb = xmldb_islocked(h, target);
|
||||
if (piddb && mypid != piddb){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>lock-denied</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>Operation failed, lock is already held</error-message>"
|
||||
"<error-info><session-id>%d</session-id></error-info>"
|
||||
"</rpc-error></rpc-reply>",
|
||||
piddb);
|
||||
cprintf(cbx, "<session-id>%d</session-id>", piddb);
|
||||
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Operation failed, lock is already held") < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
if ((x = xpath_first(xn, "default-operation")) != NULL){
|
||||
if (xml_operation(xml_body(x), &operation) < 0){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>invalid-value</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"</rpc-error></rpc-reply>");
|
||||
if (netconf_invalid_value(cbret, "protocol", "Wrong operation")< 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
}
|
||||
if ((xc = xpath_first(xn, "config")) != NULL){
|
||||
if ((xc = xpath_first(xn, "config")) == NULL){
|
||||
if (netconf_missing_element(cbret, "protocol", "<bad-element>config</bad-element>", NULL) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
else{
|
||||
if (xml_apply(xc, CX_ELMNT, xml_spec_populate, yspec) < 0)
|
||||
goto done;
|
||||
if (xml_apply(xc, CX_ELMNT, xml_non_config_data, &non_config) < 0)
|
||||
goto done;
|
||||
if (non_config){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>invalid-value</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>state data not allowed</error-message>"
|
||||
"</rpc-error></rpc-reply>");
|
||||
if (netconf_invalid_value(cbret, "protocol", "State data not allowed")< 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
/* Cant do this earlier since we dont have a yang spec to
|
||||
|
|
@ -408,35 +399,23 @@ from_client_edit_config(clicon_handle h,
|
|||
*/
|
||||
if (xml_child_sort && xml_apply0(xc, CX_ELMNT, xml_sort, NULL) < 0)
|
||||
goto done;
|
||||
if (xmldb_put(h, target, operation, xc) < 0){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>operation-failed</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>%s</error-message>"
|
||||
"</rpc-error></rpc-reply>", clicon_err_reason);
|
||||
if (xmldb_put(h, target, operation, xc, cbret) < 0){
|
||||
clicon_debug(1, "%s ERROR PUT", __FUNCTION__);
|
||||
if (netconf_operation_failed(cbret, "protocol", clicon_err_reason)< 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
}
|
||||
else{
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>missing-element</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-info><bad-element>config</bad-element></error-info>"
|
||||
"</rpc-error></rpc-reply>");
|
||||
goto ok;
|
||||
}
|
||||
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
|
||||
ok:
|
||||
if (!cbuf_len(cbret))
|
||||
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
|
||||
retval = 0;
|
||||
done:
|
||||
if (xret)
|
||||
xml_free(xret);
|
||||
if (cb)
|
||||
cbuf_free(cb);
|
||||
if (cbx)
|
||||
cbuf_free(cbx);
|
||||
clicon_debug(1, "%s done cbret:%s", __FUNCTION__, cbuf_get(cbret));
|
||||
return retval;
|
||||
}
|
||||
} /* from_client_edit_config */
|
||||
|
||||
/*! Internal message: Lock database
|
||||
*
|
||||
|
|
@ -454,26 +433,23 @@ from_client_lock(clicon_handle h,
|
|||
int retval = -1;
|
||||
char *db;
|
||||
int piddb;
|
||||
cbuf *cbx = NULL; /* Assist cbuf */
|
||||
|
||||
if ((db = netconf_db_find(xe, "target")) == NULL){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>missing-element</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-info><bad-element>target</bad-element></error-info>"
|
||||
"</rpc-error></rpc-reply>");
|
||||
if (netconf_missing_element(cbret, "protocol", "<bad-element>target</bad-element>", NULL) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
if ((cbx = cbuf_new()) == NULL){
|
||||
clicon_err(OE_XML, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
if (xmldb_validate_db(db) < 0){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>invalid-value</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>No such database: %s</error-message>"
|
||||
"</rpc-error></rpc-reply>", db);
|
||||
cprintf(cbx, "No such database: %s", db);
|
||||
if (netconf_invalid_value(cbret, "protocol", cbuf_get(cbx))< 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* A lock MUST not be granted if either of the following conditions is true:
|
||||
* 1) A lock is already held by any NETCONF session or another entity.
|
||||
|
|
@ -482,23 +458,21 @@ from_client_lock(clicon_handle h,
|
|||
*/
|
||||
piddb = xmldb_islocked(h, db);
|
||||
if (piddb){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>lock-denied</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>Lock failed, lock is already held</error-message>"
|
||||
"<error-info><session-id>%d</session-id></error-info>"
|
||||
"</rpc-error></rpc-reply>",
|
||||
piddb);
|
||||
cprintf(cbx, "<session-id>%d</session-id>", piddb);
|
||||
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Operation failed, lock is already held") < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
else{
|
||||
xmldb_lock(h, db, pid);
|
||||
if (xmldb_lock(h, db, pid) < 0)
|
||||
goto done;
|
||||
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
|
||||
}
|
||||
ok:
|
||||
retval = 0;
|
||||
// done:
|
||||
done:
|
||||
if (cbx)
|
||||
cbuf_free(cbx);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -518,23 +492,21 @@ from_client_unlock(clicon_handle h,
|
|||
int retval = -1;
|
||||
char *db;
|
||||
int piddb;
|
||||
cbuf *cbx = NULL; /* Assist cbuf */
|
||||
|
||||
if ((db = netconf_db_find(xe, "target")) == NULL){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>missing-element</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-info><bad-element>target</bad-element></error-info>"
|
||||
"</rpc-error></rpc-reply>");
|
||||
if (netconf_missing_element(cbret, "protocol", "<bad-element>target</bad-element>", NULL) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
if ((cbx = cbuf_new()) == NULL){
|
||||
clicon_err(OE_XML, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
if (xmldb_validate_db(db) < 0){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>invalid-value</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>No such database: %s</error-message>"
|
||||
"</rpc-error></rpc-reply>", db);
|
||||
cprintf(cbx, "No such database: %s", db);
|
||||
if (netconf_invalid_value(cbret, "protocol", cbuf_get(cbx))< 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
piddb = xmldb_islocked(h, db);
|
||||
|
|
@ -546,14 +518,9 @@ from_client_unlock(clicon_handle h,
|
|||
* session that obtained the lock
|
||||
*/
|
||||
if (piddb==0 || piddb != pid){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>lock-denied</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>Unlock failed, lock is already held</error-message>"
|
||||
"<error-info><session-id>pid=%d piddb=%d</session-id></error-info>"
|
||||
"</rpc-error></rpc-reply>",
|
||||
pid, piddb);
|
||||
cprintf(cbx, "<session-id>pid=%d piddb=%d</session-id>", pid, piddb);
|
||||
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Unlock failed, lock is already held") < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
else{
|
||||
|
|
@ -585,15 +552,11 @@ from_client_kill_session(clicon_handle h,
|
|||
struct client_entry *ce;
|
||||
char *db = "running"; /* XXX */
|
||||
cxobj *x;
|
||||
|
||||
|
||||
if ((x = xml_find(xe, "session-id")) == NULL ||
|
||||
(str = xml_find_value(x, "body")) == NULL){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>missing-element</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-info><bad-element>session-id</bad-element></error-info>"
|
||||
"</rpc-error></rpc-reply>");
|
||||
if (netconf_missing_element(cbret, "protocol", "<bad-element>session-id</bad-element>", NULL) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
pid = atoi(str);
|
||||
|
|
@ -618,18 +581,14 @@ from_client_kill_session(clicon_handle h,
|
|||
xmldb_unlock(h, db);
|
||||
}
|
||||
else{ /* failed to kill client */
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>operation-failed</error-tag>"
|
||||
"<error-type>application</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>Faile to kill session</error-message>"
|
||||
"</rpc-error></rpc-reply>");
|
||||
if (netconf_operation_failed(cbret, "application", "Failed to kill session")< 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
|
||||
ok:
|
||||
retval = 0;
|
||||
// done:
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -647,74 +606,57 @@ from_client_copy_config(clicon_handle h,
|
|||
int mypid,
|
||||
cbuf *cbret)
|
||||
{
|
||||
char *source;
|
||||
char *target;
|
||||
int retval = -1;
|
||||
int piddb;
|
||||
|
||||
char *source;
|
||||
char *target;
|
||||
int retval = -1;
|
||||
int piddb;
|
||||
cbuf *cbx = NULL; /* Assist cbuf */
|
||||
|
||||
if ((source = netconf_db_find(xe, "source")) == NULL){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>missing-element</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-info><bad-element>source</bad-element></error-info>"
|
||||
"</rpc-error></rpc-reply>");
|
||||
if (netconf_missing_element(cbret, "protocol", "<bad-element>source</bad-element>", NULL) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
if ((cbx = cbuf_new()) == NULL){
|
||||
clicon_err(OE_XML, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
if (xmldb_validate_db(source) < 0){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>invalid-value</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>No such database: %s</error-message>"
|
||||
"</rpc-error></rpc-reply>", source);
|
||||
cprintf(cbx, "No such database: %s", source);
|
||||
if (netconf_invalid_value(cbret, "protocol", cbuf_get(cbx))< 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
||||
if ((target = netconf_db_find(xe, "target")) == NULL){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>missing-element</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-info><bad-element>target</bad-element></error-info>"
|
||||
"</rpc-error></rpc-reply>");
|
||||
if (netconf_missing_element(cbret, "protocol", "<bad-element>target</bad-element>", NULL) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
if (xmldb_validate_db(target) < 0){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>invalid-value</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>No such database: %s</error-message>"
|
||||
"</rpc-error></rpc-reply>", target);
|
||||
cprintf(cbx, "No such database: %s", target);
|
||||
if (netconf_invalid_value(cbret, "protocol", cbuf_get(cbx))< 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
/* Check if target locked by other client */
|
||||
piddb = xmldb_islocked(h, target);
|
||||
if (piddb && mypid != piddb){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>lock-denied</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>Operation failed, lock is already held</error-message>"
|
||||
"<error-info><session-id>%d</session-id></error-info>"
|
||||
"</rpc-error></rpc-reply>",
|
||||
piddb);
|
||||
cprintf(cbx, "<session-id>%d</session-id>", piddb);
|
||||
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Copy failed, lock is already held") < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
if (xmldb_copy(h, source, target) < 0){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>operation-failed</error-tag>"
|
||||
"<error-type>application</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-info>read-registry</error-info>"
|
||||
"</rpc-error></rpc-reply>");
|
||||
if (netconf_operation_failed(cbret, "application", clicon_err_reason)< 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
|
||||
ok:
|
||||
retval = 0;
|
||||
// done:
|
||||
done:
|
||||
if (cbx)
|
||||
cbuf_free(cbx);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -732,67 +674,51 @@ from_client_delete_config(clicon_handle h,
|
|||
int mypid,
|
||||
cbuf *cbret)
|
||||
{
|
||||
int retval = -1;
|
||||
char *target;
|
||||
int piddb;
|
||||
int retval = -1;
|
||||
char *target;
|
||||
int piddb;
|
||||
cbuf *cbx = NULL; /* Assist cbuf */
|
||||
|
||||
if ((target = netconf_db_find(xe, "target")) == NULL||
|
||||
strcmp(target, "running")==0){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>missing-element</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-info><bad-element>target</bad-element></error-info>"
|
||||
"</rpc-error></rpc-reply>");
|
||||
if (netconf_missing_element(cbret, "protocol", "<bad-element>target</bad-element>", NULL) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
if ((cbx = cbuf_new()) == NULL){
|
||||
clicon_err(OE_XML, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
if (xmldb_validate_db(target) < 0){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>invalid-value</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>No such database: %s</error-message>"
|
||||
"</rpc-error></rpc-reply>", target);
|
||||
cprintf(cbx, "No such database: %s", target);
|
||||
if (netconf_invalid_value(cbret, "protocol", cbuf_get(cbx))< 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
|
||||
/* Check if target locked by other client */
|
||||
piddb = xmldb_islocked(h, target);
|
||||
if (piddb && mypid != piddb){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>lock-denied</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>Operation failed, lock is already held</error-message>"
|
||||
"<error-info><session-id>%d</session-id></error-info>"
|
||||
"</rpc-error></rpc-reply>",
|
||||
piddb);
|
||||
cprintf(cbx, "<session-id>%d</session-id>", piddb);
|
||||
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Operation failed, lock is already held") < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
if (xmldb_delete(h, target) < 0){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>operation-failed</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-info>Internal error</error-info>"
|
||||
"<error-message>%s</error-message>"
|
||||
"</rpc-error></rpc-reply>", clicon_err_reason);
|
||||
if (netconf_operation_failed(cbret, "protocol", clicon_err_reason)< 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
if (xmldb_create(h, target) < 0){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>operation-failed</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-info>Internal error</error-info>"
|
||||
"<error-message>%s</error-message>"
|
||||
"</rpc-error></rpc-reply>", clicon_err_reason);
|
||||
if (netconf_operation_failed(cbret, "protocol", clicon_err_reason)< 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
|
||||
ok:
|
||||
retval = 0;
|
||||
// done:
|
||||
done:
|
||||
if (cbx)
|
||||
cbuf_free(cbx);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -829,13 +755,8 @@ from_client_create_subscription(clicon_handle h,
|
|||
if ((ftype = xml_find_value(x, "type")) != NULL){
|
||||
/* Only accept xpath as filter type */
|
||||
if (strcmp(ftype, "xpath") != 0){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>operation-failed</error-tag>"
|
||||
"<error-type>application</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>only xpath filter type supported</error-message>"
|
||||
"<error-info>type</error-info>"
|
||||
"</rpc-error></rpc-reply>");
|
||||
if (netconf_operation_failed(cbret, "application", "Only xpath filter type supported")< 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
}
|
||||
|
|
@ -866,12 +787,8 @@ from_client_debug(clicon_handle h,
|
|||
char *valstr;
|
||||
|
||||
if ((valstr = xml_find_body(xe, "level")) == NULL){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>missing-element</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-info><bad-element>level</bad-element></error-info>"
|
||||
"</rpc-error></rpc-reply>");
|
||||
if (netconf_missing_element(cbret, "application", "<bad-element>level</bad-element>", NULL) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
level = atoi(valstr);
|
||||
|
|
@ -882,7 +799,7 @@ from_client_debug(clicon_handle h,
|
|||
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
|
||||
ok:
|
||||
retval = 0;
|
||||
//done:
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -917,23 +834,13 @@ from_client_msg(clicon_handle h,
|
|||
goto done;
|
||||
}
|
||||
if (clicon_msg_decode(msg, &xt) < 0){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>operation-failed</error-tag>"
|
||||
"<error-type>rpc</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>rpc expected</error-message>"
|
||||
"<error-info>Not recognized</error-info>"
|
||||
"</rpc-error></rpc-reply>");
|
||||
if (netconf_malformed_message(cbret, "Not recognized, rpc expected")< 0)
|
||||
goto done;
|
||||
goto reply;
|
||||
}
|
||||
if ((x = xpath_first(xt, "/rpc")) == NULL){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>operation-failed</error-tag>"
|
||||
"<error-type>rpc</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>rpc expected</error-message>"
|
||||
"<error-info>Not recognized</error-info>"
|
||||
"</rpc-error></rpc-reply>");
|
||||
if (netconf_malformed_message(cbret, "Not recognized, rpc expected")< 0)
|
||||
goto done;
|
||||
goto reply;
|
||||
}
|
||||
xe = NULL;
|
||||
|
|
@ -977,12 +884,8 @@ from_client_msg(clicon_handle h,
|
|||
}
|
||||
else if (strcmp(name, "validate") == 0){
|
||||
if ((db = netconf_db_find(xe, "source")) == NULL){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>missing-element</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-info><bad-element>source</bad-element></error-info>"
|
||||
"</rpc-error></rpc-reply>");
|
||||
if (netconf_missing_element(cbret, "protocol", "<bad-element>source</bad-element>", NULL) < 0)
|
||||
goto done;
|
||||
goto reply;
|
||||
}
|
||||
if (from_client_validate(h, db, cbret) < 0)
|
||||
|
|
@ -1007,34 +910,22 @@ from_client_msg(clicon_handle h,
|
|||
else{
|
||||
clicon_err_reset();
|
||||
if ((ret = backend_rpc_cb_call(h, xe, ce, cbret)) < 0){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>operation-failed</error-tag>"
|
||||
"<error-type>rpc</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>Internal error:%s</error-message>"
|
||||
"</rpc-error></rpc-reply>", clicon_err_reason);
|
||||
if (netconf_operation_failed(cbret, "application", clicon_err_reason)< 0)
|
||||
goto done;
|
||||
clicon_log(LOG_NOTICE, "%s Error in backend_rpc_call:%s", __FUNCTION__, xml_name(xe));
|
||||
goto reply; /* Dont quit here on user callbacks */
|
||||
}
|
||||
if (ret == 0) /* not handled by callback */
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>operation-failed</error-tag>"
|
||||
"<error-type>rpc</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>%s</error-message>"
|
||||
"<error-info>Not recognized</error-info>"
|
||||
"</rpc-error></rpc-reply>",
|
||||
name);
|
||||
if (ret == 0){ /* not handled by callback */
|
||||
if (netconf_operation_failed(cbret, "application", "Callback not recognized")< 0)
|
||||
goto done;
|
||||
goto reply;
|
||||
}
|
||||
}
|
||||
}
|
||||
reply:
|
||||
if (cbuf_len(cbret) == 0)
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>operation-failed</error-tag>"
|
||||
"<error-type>rpc</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>Internal error %s</error-message>"
|
||||
"</rpc-error></rpc-reply>",clicon_err_reason);
|
||||
if (netconf_operation_failed(cbret, "application", clicon_err_reason)< 0)
|
||||
goto done;
|
||||
clicon_debug(1, "%s cbret:%s", __FUNCTION__, cbuf_get(cbret));
|
||||
if (send_msg_reply(ce->ce_s, cbuf_get(cbret), cbuf_len(cbret)+1) < 0){
|
||||
switch (errno){
|
||||
|
|
@ -1055,7 +946,7 @@ from_client_msg(clicon_handle h,
|
|||
}
|
||||
// ok:
|
||||
retval = 0;
|
||||
done:
|
||||
done:
|
||||
if (xt)
|
||||
xml_free(xt);
|
||||
if (cbret)
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@ candidate_commit(clicon_handle h,
|
|||
|
||||
/* Optionally write (potentially modified) tree back to candidate */
|
||||
if (clicon_option_bool(h, "CLICON_TRANSACTION_MOD"))
|
||||
if (xmldb_put(h, candidate, OP_REPLACE, td->td_target) < 0)
|
||||
if (xmldb_put(h, candidate, OP_REPLACE, td->td_target, NULL) < 0)
|
||||
goto done;
|
||||
/* 8. Success: Copy candidate to running
|
||||
*/
|
||||
|
|
@ -282,35 +282,32 @@ from_client_commit(clicon_handle h,
|
|||
{
|
||||
int retval = -1;
|
||||
int piddb;
|
||||
cbuf *cbx = NULL; /* Assist cbuf */
|
||||
|
||||
/* Check if target locked by other client */
|
||||
piddb = xmldb_islocked(h, "running");
|
||||
if (piddb && mypid != piddb){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>lock-denied</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>Operation failed, lock is already held</error-message>"
|
||||
"<error-info><session-id>%d</session-id></error-info>"
|
||||
"</rpc-error></rpc-reply>",
|
||||
piddb);
|
||||
if ((cbx = cbuf_new()) == NULL){
|
||||
clicon_err(OE_XML, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
cprintf(cbx, "<session-id>%d</session-id>", piddb);
|
||||
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Operation failed, lock is already held") < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
if (candidate_commit(h, "candidate") < 0){ /* Assume validation fail, nofatal */
|
||||
clicon_debug(1, "Commit candidate failed");
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>invalid-value</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>%s</error-message>"
|
||||
"</rpc-error></rpc-reply>",
|
||||
clicon_err_reason);
|
||||
if (netconf_invalid_value(cbret, "protocol", clicon_err_reason)< 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
|
||||
ok:
|
||||
retval = 0;
|
||||
// done:
|
||||
done:
|
||||
if (cbx)
|
||||
cbuf_free(cbx);
|
||||
return retval; /* may be zero if we ignoring errors from commit */
|
||||
} /* from_client_commit */
|
||||
|
||||
|
|
@ -328,33 +325,31 @@ from_client_discard_changes(clicon_handle h,
|
|||
{
|
||||
int retval = -1;
|
||||
int piddb;
|
||||
|
||||
cbuf *cbx = NULL; /* Assist cbuf */
|
||||
|
||||
/* Check if target locked by other client */
|
||||
piddb = xmldb_islocked(h, "candidate");
|
||||
if (piddb && mypid != piddb){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>lock-denied</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>Operation failed, lock is already held</error-message>"
|
||||
"<error-info><session-id>%d</session-id></error-info>"
|
||||
"</rpc-error></rpc-reply>",
|
||||
piddb);
|
||||
if ((cbx = cbuf_new()) == NULL){
|
||||
clicon_err(OE_XML, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
cprintf(cbx, "<session-id>%d</session-id>", piddb);
|
||||
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Operation failed, lock is already held") < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
if (xmldb_copy(h, "running", "candidate") < 0){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>operation-failed</error-tag>"
|
||||
"<error-type>application</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-info>read-registry</error-info>"
|
||||
"</rpc-error></rpc-reply>");
|
||||
if (netconf_operation_failed(cbret, "application", clicon_err_reason)< 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
|
||||
ok:
|
||||
retval = 0;
|
||||
// done:
|
||||
done:
|
||||
if (cbx)
|
||||
cbuf_free(cbx);
|
||||
return retval; /* may be zero if we ignoring errors from commit */
|
||||
}
|
||||
|
||||
|
|
@ -374,11 +369,8 @@ from_client_validate(clicon_handle h,
|
|||
transaction_data_t *td = NULL;
|
||||
|
||||
if (strcmp(db, "candidate") != 0 && strcmp(db, "tmp") != 0){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>invalid-value</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"</rpc-error></rpc-reply>");
|
||||
if (netconf_invalid_value(cbret, "protocol", "No such database")< 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
clicon_debug(1, "Validate %s", db);
|
||||
|
|
@ -390,18 +382,13 @@ from_client_validate(clicon_handle h,
|
|||
if (validate_common(h, db, td) < 0){
|
||||
clicon_debug(1, "Validate %s failed", db);
|
||||
/* XXX: candidate_validate should have proper error handling */
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>missing-attribute</error-tag>"
|
||||
"<error-type>protocol</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>%s</error-message>"
|
||||
"</rpc-error></rpc-reply>",
|
||||
clicon_err_reason);
|
||||
if (netconf_operation_failed(cbret, "application", clicon_err_reason)< 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
/* Optionally write (potentially modified) tree back to candidate */
|
||||
if (clicon_option_bool(h, "CLICON_TRANSACTION_MOD"))
|
||||
if (xmldb_put(h, "candidate", OP_REPLACE, td->td_target) < 0)
|
||||
if (xmldb_put(h, "candidate", OP_REPLACE, td->td_target, NULL) < 0)
|
||||
goto done;
|
||||
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
|
||||
ok:
|
||||
|
|
|
|||
|
|
@ -174,8 +174,8 @@ db_merge(clicon_handle h,
|
|||
/* Get data as xml from db1 */
|
||||
if (xmldb_get(h, (char*)db1, NULL, 1, &xt) < 0)
|
||||
goto done;
|
||||
/* Merge xml into db2. WIthout commit */
|
||||
if (xmldb_put(h, (char*)db2, OP_MERGE, xt) < 0)
|
||||
/* Merge xml into db2. Without commit */
|
||||
if (xmldb_put(h, (char*)db2, OP_MERGE, xt, NULL) < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
|
|
@ -283,7 +283,7 @@ load_extraxml(clicon_handle h,
|
|||
if (xml_rootchild(xt, 0, &xt) < 0)
|
||||
goto done;
|
||||
/* Merge user reset state */
|
||||
if (xmldb_put(h, (char*)db, OP_MERGE, xt) < 0)
|
||||
if (xmldb_put(h, (char*)db, OP_MERGE, xt, NULL) < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
|
|
@ -703,43 +703,41 @@ main(int argc, char **argv)
|
|||
if ((xml_pretty = clicon_option_bool(h, "CLICON_XMLDB_PRETTY")) >= 0)
|
||||
if (xmldb_setopt(h, "pretty", (void*)(intptr_t)xml_pretty) < 0)
|
||||
goto done;
|
||||
/* If startup mode is not defined, eg via OPTION or -s, assume old method */
|
||||
/* Startup mode needs to be defined, */
|
||||
startup_mode = clicon_startup_mode(h);
|
||||
if (startup_mode == -1){
|
||||
clicon_log(LOG_ERR, "Startup mode undefined. Specify option CLICON_STARTUP_MODE or specify -s option to clicon_backend.\n");
|
||||
goto done;
|
||||
}
|
||||
else {
|
||||
/* Init running db if it is not there
|
||||
*/
|
||||
if (xmldb_exists(h, "running") != 1)
|
||||
if (xmldb_create(h, "running") < 0)
|
||||
return -1;
|
||||
switch (startup_mode){
|
||||
case SM_NONE:
|
||||
if (startup_mode_none(h) < 0)
|
||||
goto done;
|
||||
break;
|
||||
case SM_INIT: /* -I */
|
||||
if (startup_mode_init(h) < 0)
|
||||
goto done;
|
||||
break;
|
||||
case SM_RUNNING: /* -CIr */
|
||||
if (startup_mode_running(h, extraxml_file) < 0)
|
||||
goto done;
|
||||
break;
|
||||
case SM_STARTUP: /* startup configuration */
|
||||
if (startup_mode_startup(h, extraxml_file) < 0)
|
||||
goto done;
|
||||
break;
|
||||
}
|
||||
/* Initiate the shared candidate. */
|
||||
if (xmldb_copy(h, "running", "candidate") < 0)
|
||||
/* Init running db if it is not there
|
||||
*/
|
||||
if (xmldb_exists(h, "running") != 1)
|
||||
if (xmldb_create(h, "running") < 0)
|
||||
return -1;
|
||||
switch (startup_mode){
|
||||
case SM_NONE:
|
||||
if (startup_mode_none(h) < 0)
|
||||
goto done;
|
||||
/* Call plugin_start with user -- options */
|
||||
if (plugin_start_useroptions(h, argv0, argc, argv) <0)
|
||||
break;
|
||||
case SM_INIT: /* -I */
|
||||
if (startup_mode_init(h) < 0)
|
||||
goto done;
|
||||
break;
|
||||
case SM_RUNNING: /* -CIr */
|
||||
if (startup_mode_running(h, extraxml_file) < 0)
|
||||
goto done;
|
||||
break;
|
||||
case SM_STARTUP: /* startup configuration */
|
||||
if (startup_mode_startup(h, extraxml_file) < 0)
|
||||
goto done;
|
||||
break;
|
||||
}
|
||||
/* Initiate the shared candidate. */
|
||||
if (xmldb_copy(h, "running", "candidate") < 0)
|
||||
goto done;
|
||||
/* Call backend plugin_start with user -- options */
|
||||
if (plugin_start_useroptions(h, argv0, argc, argv) <0)
|
||||
goto done;
|
||||
if (once)
|
||||
goto done;
|
||||
|
||||
|
|
|
|||
|
|
@ -100,13 +100,9 @@ process_incoming_packet(clicon_handle h,
|
|||
/* Parse incoming XML message */
|
||||
if (xml_parse_string(str, NULL, &xreq) < 0){
|
||||
if ((cbret = cbuf_new()) == NULL){
|
||||
cprintf(cbret, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>operation-failed</error-tag>"
|
||||
"<error-type>rpc</error-type>"
|
||||
"<error-severity>error</error-severity>"
|
||||
"<error-message>internal error</error-message>"
|
||||
"</rpc-error></rpc-reply>");
|
||||
netconf_output(1, cb, "rpc-error");
|
||||
if (netconf_operation_failed(cbret, "rpc", "internal error")< 0)
|
||||
goto done;
|
||||
netconf_output(1, cbret, "rpc-error");
|
||||
}
|
||||
else
|
||||
clicon_log(LOG_ERR, "%s: cbuf_new", __FUNCTION__);
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@
|
|||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include <fcgi_stdio.h>
|
||||
#include <signal.h>
|
||||
#include <dlfcn.h>
|
||||
#include <sys/param.h>
|
||||
|
|
@ -55,6 +54,8 @@
|
|||
/* clicon */
|
||||
#include <clixon/clixon.h>
|
||||
|
||||
#include <fcgi_stdio.h> /* Need to be after clixon_xml-h due to attribute format */
|
||||
|
||||
#include "restconf_lib.h"
|
||||
|
||||
/* See RFC 8040 Section 7: Mapping from NETCONF<error-tag> to Status Code
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@
|
|||
#include <syslog.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <fcgi_stdio.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
|
|
@ -66,6 +66,8 @@
|
|||
/* clicon */
|
||||
#include <clixon/clixon.h>
|
||||
|
||||
#include <fcgi_stdio.h> /* Need to be after clixon_xml-h due to attribute format */
|
||||
|
||||
/* restconf */
|
||||
#include "restconf_lib.h"
|
||||
#include "restconf_methods.h"
|
||||
|
|
@ -208,9 +210,9 @@ api_well_known(clicon_handle h,
|
|||
FCGX_FPrintF(r->out, "Content-Type: application/xrd+xml\r\n");
|
||||
FCGX_FPrintF(r->out, "\r\n");
|
||||
FCGX_SetExitStatus(200, r->out); /* OK */
|
||||
FCGX_FPrintF(r->out, "<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>\r\n");
|
||||
FCGX_FPrintF(r->out, " <Link rel='restconf' href='/restconf'/>\r\n");
|
||||
FCGX_FPrintF(r->out, "</XRD>\r\n");
|
||||
FCGX_FPrintF(r->out, "<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>\n");
|
||||
FCGX_FPrintF(r->out, " <Link rel='restconf' href='/restconf'/>\n");
|
||||
FCGX_FPrintF(r->out, "</XRD>\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -258,7 +260,7 @@ api_root(clicon_handle h,
|
|||
if (xml2json_cbuf(cb, xt, pretty) < 0)
|
||||
goto done;
|
||||
FCGX_FPrintF(r->out, "%s", cb?cbuf_get(cb):"");
|
||||
FCGX_FPrintF(r->out, "\r\n\r\n");
|
||||
FCGX_FPrintF(r->out, "\n\n");
|
||||
retval = 0;
|
||||
done:
|
||||
if (cb)
|
||||
|
|
@ -307,8 +309,8 @@ api_yang_library_version(clicon_handle h,
|
|||
goto done;
|
||||
}
|
||||
clicon_debug(1, "%s cb%s", __FUNCTION__, cbuf_get(cb));
|
||||
FCGX_FPrintF(r->out, "%s\r\n", cb?cbuf_get(cb):"");
|
||||
FCGX_FPrintF(r->out, "\r\n\r\n");
|
||||
FCGX_FPrintF(r->out, "%s\n", cb?cbuf_get(cb):"");
|
||||
FCGX_FPrintF(r->out, "\n\n");
|
||||
retval = 0;
|
||||
done:
|
||||
if (cb)
|
||||
|
|
@ -599,7 +601,7 @@ main(int argc,
|
|||
}
|
||||
else
|
||||
clicon_debug(1, "NULL URI");
|
||||
FCGX_Finish_r(r);
|
||||
FCGX_Finish_r(r);
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
|
|
|
|||
|
|
@ -104,7 +104,6 @@ Mapping netconf error-tag -> status code
|
|||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
#include <fcgi_stdio.h>
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
|
|
@ -115,6 +114,8 @@ Mapping netconf error-tag -> status code
|
|||
/* clicon */
|
||||
#include <clixon/clixon.h>
|
||||
|
||||
#include <fcgi_stdio.h> /* Need to be after clixon_xml-h due to attribute format */
|
||||
|
||||
#include "restconf_lib.h"
|
||||
#include "restconf_methods.h"
|
||||
|
||||
|
|
@ -157,6 +158,7 @@ api_return_err(clicon_handle h,
|
|||
int retval = -1;
|
||||
cbuf *cb = NULL;
|
||||
cxobj *xtag;
|
||||
char *tagstr;
|
||||
int code;
|
||||
const char *reason_phrase;
|
||||
|
||||
|
|
@ -167,7 +169,8 @@ api_return_err(clicon_handle h,
|
|||
notfound(r); /* bad reply? */
|
||||
goto ok;
|
||||
}
|
||||
code = restconf_err2code(xml_body(xtag));
|
||||
tagstr = xml_body(xtag);
|
||||
code = restconf_err2code(tagstr);
|
||||
if ((reason_phrase = restconf_code2reason(code)) == NULL)
|
||||
reason_phrase="";
|
||||
if (xml_name_set(xerr, "error") < 0)
|
||||
|
|
@ -183,22 +186,29 @@ api_return_err(clicon_handle h,
|
|||
FCGX_FPrintF(r->out, "Content-Type: application/yang-data+%s\r\n\r\n",
|
||||
use_xml?"xml":"json");
|
||||
if (use_xml){
|
||||
FCGX_FPrintF(r->out, " <errors xmlns=\"urn:ietf:params:xml:ns:yang:ietf-restconf\">%s", cbuf_get(cb), pretty?"\r\n":"");
|
||||
FCGX_FPrintF(r->out, "%s", cbuf_get(cb));
|
||||
FCGX_FPrintF(r->out, " </errors>\r\n");
|
||||
if (pretty){
|
||||
FCGX_FPrintF(r->out, " <errors xmlns=\"urn:ietf:params:xml:ns:yang:ietf-restconf\">\n", cbuf_get(cb));
|
||||
FCGX_FPrintF(r->out, "%s", cbuf_get(cb));
|
||||
FCGX_FPrintF(r->out, " </errors>\n");
|
||||
}
|
||||
else {
|
||||
FCGX_FPrintF(r->out, "<errors xmlns=\"urn:ietf:params:xml:ns:yang:ietf-restconf\">", cbuf_get(cb));
|
||||
FCGX_FPrintF(r->out, "%s", cbuf_get(cb));
|
||||
FCGX_FPrintF(r->out, "</errors>\n");
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (pretty){
|
||||
FCGX_FPrintF(r->out, "{\r\n");
|
||||
FCGX_FPrintF(r->out, " \"ietf-restconf:errors\" : %s\r\n",
|
||||
FCGX_FPrintF(r->out, "{\n");
|
||||
FCGX_FPrintF(r->out, " \"ietf-restconf:errors\" : %s\n",
|
||||
cbuf_get(cb));
|
||||
FCGX_FPrintF(r->out, "}\r\n");
|
||||
FCGX_FPrintF(r->out, "}\n");
|
||||
}
|
||||
else{
|
||||
FCGX_FPrintF(r->out, "{");
|
||||
FCGX_FPrintF(r->out, "\"ietf-restconf:errors\" : ");
|
||||
FCGX_FPrintF(r->out, "%s", cbuf_get(cb));
|
||||
FCGX_FPrintF(r->out, "}\r\n");
|
||||
FCGX_FPrintF(r->out, "}\n");
|
||||
}
|
||||
}
|
||||
ok:
|
||||
|
|
@ -330,7 +340,7 @@ api_data_get2(clicon_handle h,
|
|||
|
||||
clicon_debug(1, "%s cbuf:%s", __FUNCTION__, cbuf_get(cbx));
|
||||
FCGX_FPrintF(r->out, "%s", cbx?cbuf_get(cbx):"");
|
||||
FCGX_FPrintF(r->out, "\r\n\r\n");
|
||||
FCGX_FPrintF(r->out, "\n\n");
|
||||
ok:
|
||||
retval = 0;
|
||||
done:
|
||||
|
|
@ -1010,9 +1020,9 @@ api_operations_get(clicon_handle h,
|
|||
clicon_debug(1, "%s ret:%s", __FUNCTION__, cbuf_get(cbx));
|
||||
FCGX_SetExitStatus(200, r->out); /* OK */
|
||||
FCGX_FPrintF(r->out, "Content-Type: application/yang-data+%s\r\n", use_xml?"xml":"json");
|
||||
FCGX_FPrintF(r->out, "\r\n");
|
||||
FCGX_FPrintF(r->out, "\n");
|
||||
FCGX_FPrintF(r->out, "%s", cbx?cbuf_get(cbx):"");
|
||||
FCGX_FPrintF(r->out, "\r\n\r\n");
|
||||
FCGX_FPrintF(r->out, "\n\n");
|
||||
// ok:
|
||||
retval = 0;
|
||||
done:
|
||||
|
|
@ -1183,7 +1193,7 @@ api_operations_post(clicon_handle h,
|
|||
goto done;
|
||||
clicon_debug(1, "%s xoutput:%s", __FUNCTION__, cbuf_get(cbx));
|
||||
FCGX_FPrintF(r->out, "%s", cbx?cbuf_get(cbx):"");
|
||||
FCGX_FPrintF(r->out, "\r\n\r\n");
|
||||
FCGX_FPrintF(r->out, "\n\n");
|
||||
}
|
||||
ok:
|
||||
retval = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue