* Bundle internal NETCONF on RESTCONF: A RESTCONF operation could produce several (up to four) internal NETCONF messages between RESTCONF server and backend. These have now been bundled into one.

* NACM recovery user session is now properly enforced. This means that if `CLICON_NACM_CREDENTIALS` is `except` (default), then a specific `CLICON_NACM_RECOVERY_USER` can make any edits and bypass NACM rules.
* If a default value is replaced by an actual value, RESTCONF return values have changed from `204 No Content` to `201 Created`
* clixon-config.yang: Removed default valude of CLICON_NACM_RECOVERY_USER
This commit is contained in:
Olof hagsand 2020-08-11 14:46:53 +02:00
parent de85f20415
commit dc1ad560f9
12 changed files with 217 additions and 261 deletions

View file

@ -370,7 +370,18 @@ api_data_post(clicon_handle h,
username?username:"",
NETCONF_BASE_PREFIX,
NETCONF_BASE_NAMESPACE); /* bind nc to netconf namespace */
cprintf(cbx, "<edit-config><target><candidate /></target>");
cprintf(cbx, "<edit-config");
/* RFC8040 Sec 1.4:
* If the NETCONF server supports :startup, the RESTCONF server MUST
* automatically update the non-volatile startup configuration
* datastore, after the "running" datastore has been altered as a
* consequence of a RESTCONF edit operation.
*/
if (if_feature(yspec, "ietf-netconf", "startup"))
cprintf(cbx, " copystartup=\"true\"");
cprintf(cbx, " autocommit=\"true\"");
cprintf(cbx, "><target><candidate /></target>");
cprintf(cbx, "<default-operation>none</default-operation>");
if (clicon_xml2cbuf(cbx, xtop, 0, 0, -1) < 0)
goto done;
@ -383,49 +394,6 @@ api_data_post(clicon_handle h,
goto done;
goto ok;
}
/* Assume this is validation failed since commit includes validate */
cbuf_reset(cbx);
/* commit/discard should be done automaticaly by the system, therefore
* recovery user is used here (edit-config but not commit may be permitted
by NACM */
cprintf(cbx, "<rpc username=\"%s\">", clicon_nacm_recovery_user(h));
cprintf(cbx, "<commit/></rpc>");
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0)
goto done;
if ((xe = xpath_first(xretcom, NULL, "//rpc-error")) != NULL){
cbuf_reset(cbx);
cprintf(cbx, "<rpc username=\"%s\">", username?username:"");
cprintf(cbx, "<discard-changes/></rpc>");
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretdis, NULL) < 0)
goto done;
/* log errors from discard, but ignore */
if ((xpath_first(xretdis, NULL, "//rpc-error")) != NULL)
clicon_log(LOG_WARNING, "%s: discard-changes failed which may lead candidate in an inconsistent state", __FUNCTION__);
if (api_return_err(h, req, xe, pretty, media_out, 0) < 0) /* Use original xe */
goto done;
goto ok;
}
if (xretcom){ /* Clear: can be reused again below */
xml_free(xretcom);
xretcom = NULL;
}
if (if_feature(yspec, "ietf-netconf", "startup")){
/* RFC8040 Sec 1.4:
* If the NETCONF server supports :startup, the RESTCONF server MUST
* automatically update the non-volatile startup configuration
* datastore, after the "running" datastore has been altered as a
* consequence of a RESTCONF edit operation.
*/
cbuf_reset(cbx);
cprintf(cbx, "<rpc username=\"%s\">", clicon_nacm_recovery_user(h));
cprintf(cbx, "<copy-config><source><running/></source><target><startup/></target></copy-config></rpc>");
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xretcom, NULL) < 0)
goto done;
/* If copy-config failed, log and ignore (already committed) */
if ((xe = xpath_first(xretcom, NULL, "//rpc-error")) != NULL){
clicon_log(LOG_WARNING, "%s: copy-config running->startup failed", __FUNCTION__);
}
}
if (http_location_header(h, req, xdata) < 0)
goto done;
if (restconf_reply_send(req, 201, NULL) < 0)