* Ensured you can add multiple callbacks for any RPC, including basic ones.
* Extra RPC:s will be called _after_ the basic ones.
* One specific usecase is hook for `copy-config` (see [doc/ROADMAP.md] that can be implemented thus way.
* `rpc_callback_register` added a namespace parameter. Example:
```
rpc_callback_register(h, empty_rpc, NULL, "urn:example:clixon", "empty");
```
This commit is contained in:
parent
748c7282ea
commit
b1c74b5f1f
18 changed files with 755 additions and 514 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -60,5 +60,6 @@ struct client_entry{
|
|||
*/
|
||||
int backend_client_rm(clicon_handle h, struct client_entry *ce);
|
||||
int from_client(int fd, void *arg);
|
||||
int backend_rpc_init(clicon_handle h);
|
||||
|
||||
#endif /* _BACKEND_CLIENT_H_ */
|
||||
|
|
|
|||
|
|
@ -330,8 +330,6 @@ startup_validate(clicon_handle h,
|
|||
goto done;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*! Do a diff between candidate and running, then start a commit transaction
|
||||
*
|
||||
* The code reverts changes if the commit fails. But if the revert
|
||||
|
|
@ -408,25 +406,33 @@ candidate_commit(clicon_handle h,
|
|||
goto done;
|
||||
}
|
||||
|
||||
/*! Commit changes from candidate to running
|
||||
* @param[in] h Clicon handle
|
||||
* @param[out] cbret Return xml value cligen buffer
|
||||
* @retval 0 OK. This may indicate both ok and err msg back to client
|
||||
* @retval -1 (Local) Error
|
||||
* NACM: The server MUST determine the exact nodes in the running
|
||||
/*! Commit the candidate configuration as the device's new current configuration
|
||||
*
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] xe Request: <rpc><xn></rpc>
|
||||
* @param[out] cbret Return xml tree, eg <rpc-reply>..., <rpc-error..
|
||||
* @param[in] arg client-entry
|
||||
* @param[in] regarg User argument given at rpc_callback_register()
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* @note NACM: The server MUST determine the exact nodes in the running
|
||||
* configuration datastore that are actually different and only check
|
||||
* "create", "update", and "delete" access permissions for this set of
|
||||
* nodes, which could be empty.
|
||||
*/
|
||||
int
|
||||
from_client_commit(clicon_handle h,
|
||||
int mypid,
|
||||
cbuf *cbret)
|
||||
cxobj *xe,
|
||||
cbuf *cbret,
|
||||
void *arg,
|
||||
void *regarg)
|
||||
{
|
||||
int retval = -1;
|
||||
int piddb;
|
||||
cbuf *cbx = NULL; /* Assist cbuf */
|
||||
int ret;
|
||||
int retval = -1;
|
||||
struct client_entry *ce = (struct client_entry *)arg;
|
||||
int mypid = ce->ce_pid;
|
||||
int piddb;
|
||||
cbuf *cbx = NULL; /* Assist cbuf */
|
||||
int ret;
|
||||
|
||||
/* Check if target locked by other client */
|
||||
piddb = xmldb_islocked(h, "running");
|
||||
|
|
@ -457,22 +463,30 @@ from_client_commit(clicon_handle h,
|
|||
return retval; /* may be zero if we ignoring errors from commit */
|
||||
} /* from_client_commit */
|
||||
|
||||
/*! Discard all changes in candidate / revert to running
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] mypid Process/session id of calling client
|
||||
* @param[out] cbret Return xml value cligen buffer
|
||||
/*! Revert the candidate configuration to the current running configuration.
|
||||
*
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] xe Request: <rpc><xn></rpc>
|
||||
* @param[out] cbret Return xml tree, eg <rpc-reply>..., <rpc-error..
|
||||
* @param[in] arg client-entry
|
||||
* @param[in] regarg User argument given at rpc_callback_register()
|
||||
* @retval 0 OK. This may indicate both ok and err msg back to client
|
||||
* @retval -1 (Local) Error
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* NACM: No datastore permissions are needed.
|
||||
*/
|
||||
int
|
||||
from_client_discard_changes(clicon_handle h,
|
||||
int mypid,
|
||||
cbuf *cbret)
|
||||
cxobj *xe,
|
||||
cbuf *cbret,
|
||||
void *arg,
|
||||
void *regarg)
|
||||
{
|
||||
int retval = -1;
|
||||
int piddb;
|
||||
cbuf *cbx = NULL; /* Assist cbuf */
|
||||
int retval = -1;
|
||||
struct client_entry *ce = (struct client_entry *)arg;
|
||||
int mypid = ce->ce_pid;
|
||||
int piddb;
|
||||
cbuf *cbx = NULL; /* Assist cbuf */
|
||||
|
||||
/* Check if target locked by other client */
|
||||
piddb = xmldb_islocked(h, "candidate");
|
||||
|
|
@ -500,22 +514,60 @@ from_client_discard_changes(clicon_handle h,
|
|||
return retval; /* may be zero if we ignoring errors from commit */
|
||||
}
|
||||
|
||||
/*! Handle an incoming validate message from a client.
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] db Database name
|
||||
* @param[out] cbret Return xml value cligen buffer
|
||||
* @retval 0 OK. This may indicate both ok and err msg back to client (eg invalid)
|
||||
* @retval -1 (Local) Error
|
||||
/*! Cancel an ongoing confirmed commit.
|
||||
* If the confirmed commit is persistent, the parameter 'persist-id' must be
|
||||
* given, and it must match the value of the 'persist' parameter.
|
||||
*
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] xe Request: <rpc><xn></rpc>
|
||||
* @param[out] cbret Return xml tree, eg <rpc-reply>..., <rpc-error..
|
||||
* @param[in] arg client-entry
|
||||
* @param[in] regarg User argument given at rpc_callback_register()
|
||||
* @retval 0 OK. This may indicate both ok and err msg back to client
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* @see RFC 6241 Sec 8.4
|
||||
*/
|
||||
int
|
||||
from_client_cancel_commit(clicon_handle h,
|
||||
cxobj *xe,
|
||||
cbuf *cbret,
|
||||
void *arg,
|
||||
void *regarg)
|
||||
{
|
||||
int retval = -1;
|
||||
retval = 0;
|
||||
// done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Validates the contents of the specified configuration.
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] xe Request: <rpc><xn></rpc>
|
||||
* @param[out] cbret Return xml tree, eg <rpc-reply>..., <rpc-error..
|
||||
* @param[in] arg client-entry
|
||||
* @param[in] regarg User argument given at rpc_callback_register()
|
||||
* @retval 0 OK. This may indicate both ok and err msg back to client
|
||||
* (eg invalid)
|
||||
* @retval -1 Error
|
||||
*/
|
||||
int
|
||||
from_client_validate(clicon_handle h,
|
||||
char *db,
|
||||
cbuf *cbret)
|
||||
cxobj *xe,
|
||||
cbuf *cbret,
|
||||
void *arg,
|
||||
void *regarg)
|
||||
{
|
||||
int retval = -1;
|
||||
transaction_data_t *td = NULL;
|
||||
int ret;
|
||||
char *db;
|
||||
|
||||
if ((db = netconf_db_find(xe, "source")) == NULL){
|
||||
if (netconf_missing_element(cbret, "protocol", "source", NULL) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
if (strcmp(db, "candidate") != 0 && strcmp(db, "tmp") != 0){
|
||||
if (netconf_invalid_value(cbret, "protocol", "No such database")< 0)
|
||||
goto done;
|
||||
|
|
@ -552,3 +604,4 @@ from_client_validate(clicon_handle h,
|
|||
transaction_free(td);
|
||||
return retval;
|
||||
} /* from_client_validate */
|
||||
|
||||
|
|
|
|||
|
|
@ -40,10 +40,12 @@
|
|||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
int from_client_validate(clicon_handle h, char *db, cbuf *cbret);
|
||||
int from_client_commit(clicon_handle h, int pid, cbuf *cbret);
|
||||
int from_client_discard_changes(clicon_handle h, int pid, cbuf *cbret);
|
||||
int startup_validate(clicon_handle h, char *db, cbuf *cbret);
|
||||
int candidate_commit(clicon_handle h, char *db, cbuf *cbret);
|
||||
|
||||
int from_client_commit(clicon_handle h, cxobj *xe, cbuf *cbret, void *arg, void *regarg);
|
||||
int from_client_discard_changes(clicon_handle h, cxobj *xe, cbuf *cbret, void *arg, void *regarg);
|
||||
int from_client_cancel_commit(clicon_handle h, cxobj *xe, cbuf *cbret, void *arg, void *regarg);
|
||||
int from_client_validate(clicon_handle h, cxobj *xe, cbuf *cbret, void *arg, void *regarg);
|
||||
|
||||
#endif /* _BACKEND_COMMIT_H_ */
|
||||
|
|
|
|||
|
|
@ -635,6 +635,10 @@ main(int argc,
|
|||
if (xmldb_setopt(h, "nacm_xtree", (void*)clicon_nacm_ext(h)) < 0)
|
||||
goto done;
|
||||
|
||||
/* Initialize server socket and save it to handle */
|
||||
if (backend_rpc_init(h) < 0)
|
||||
goto done;
|
||||
|
||||
/* Save modules state of the backend (server). Compare with startup XML */
|
||||
if (startup_module_state(h, yspec) < 0)
|
||||
goto done;
|
||||
|
|
|
|||
|
|
@ -603,7 +603,7 @@ netconf_application_rpc(clicon_handle h,
|
|||
/* Look for local (client-side) netconf plugins. */
|
||||
if ((ret = rpc_callback_call(h, xn, cbret, NULL)) < 0)
|
||||
goto done;
|
||||
if (ret == 1){ /* Handled locally */
|
||||
if (ret > 0){ /* Handled locally */
|
||||
if (xml_parse_string(cbuf_get(cbret), NULL, xret) < 0)
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -692,6 +692,7 @@ netconf_rpc_dispatch(clicon_handle h,
|
|||
strcmp(xml_name(xe), "kill-session") == 0 ||
|
||||
strcmp(xml_name(xe), "validate") == 0 || /* :validate */
|
||||
strcmp(xml_name(xe), "commit") == 0 || /* :candidate */
|
||||
strcmp(xml_name(xe), "cancel-commit") == 0 ||
|
||||
strcmp(xml_name(xe), "discard-changes") == 0){
|
||||
if (clicon_rpc_netconf_xml(h, xml_parent(xe), xret, NULL) < 0)
|
||||
goto done;
|
||||
|
|
|
|||
|
|
@ -1674,7 +1674,7 @@ api_operations_post(clicon_handle h,
|
|||
*/
|
||||
if ((ret = rpc_callback_call(h, xbot, cbret, r)) < 0)
|
||||
goto done;
|
||||
if (ret == 1){ /* Handled locally */
|
||||
if (ret > 0){ /* Handled locally */
|
||||
if (xml_parse_string(cbuf_get(cbret), NULL, &xret) < 0)
|
||||
goto done;
|
||||
/* Local error: return it and quit */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue