* Restconf with startup feature will now copy all edit changes to startup db (as it should according to RFC 8040)
* See [Restconf does not handle startup datastore according to the RFC](https://github.com/clicon/clixon/issues/74) * Netconf Startup feature is no longer hardcoded, you need to explicitly enable it (See RFC 6241, Section 8.7) * Enable in config file with: `<CLICON_FEATURE>ietf-netconf:startup</CLICON_FEATURE>`, or use `*:*`
This commit is contained in:
parent
161ef9c7b0
commit
6bf2a74e24
26 changed files with 270 additions and 128 deletions
|
|
@ -616,6 +616,13 @@ main(int argc,
|
|||
clicon_log(LOG_ERR, "Startup mode undefined. Specify option CLICON_STARTUP_MODE or specify -s option to clicon_backend.");
|
||||
goto done;
|
||||
}
|
||||
/* Check that netconf :startup is enabled */
|
||||
if (startup_mode == SM_STARTUP &&
|
||||
!if_feature(yspec, "ietf-netconf", "startup")){
|
||||
clicon_log(LOG_ERR, "Startup mode selected but Netconf :startup feature is not enabled. Enable with option: <CLICON_FEATURE>ietf-netconf:startup</CLICON_FEATURE>");
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Init running db if it is not there
|
||||
*/
|
||||
if (xmldb_exists(h, "running") != 1)
|
||||
|
|
|
|||
|
|
@ -485,6 +485,10 @@ main(int argc, char **argv)
|
|||
if (yang_modules_init(h) < 0)
|
||||
goto done;
|
||||
|
||||
/* Add netconf yang spec, used as internal protocol */
|
||||
if (netconf_module_load(h) < 0)
|
||||
goto done;
|
||||
|
||||
/* Create tree generated from dataspec. If no other trees exists, this is
|
||||
* the only one.
|
||||
* The following code creates the tree @datamodel
|
||||
|
|
|
|||
|
|
@ -668,6 +668,11 @@ main(int argc,
|
|||
/* Load yang module library, RFC7895 */
|
||||
if (yang_modules_init(h) < 0)
|
||||
goto done;
|
||||
|
||||
/* Add netconf yang spec, used as internal protocol */
|
||||
if (netconf_module_load(h) < 0)
|
||||
goto done;
|
||||
|
||||
/* Add system modules */
|
||||
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC8040") &&
|
||||
yang_spec_parse_module(h, "ietf-restconf-monitoring", NULL, yspec)< 0)
|
||||
|
|
@ -675,6 +680,11 @@ main(int argc,
|
|||
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC5277") &&
|
||||
yang_spec_parse_module(h, "clixon-rfc5277", NULL, yspec)< 0)
|
||||
goto done;
|
||||
|
||||
/* Dump configuration options on debug */
|
||||
if (debug)
|
||||
clicon_option_dump(h, debug);
|
||||
|
||||
/* Call start function in all plugins before we go interactive
|
||||
*/
|
||||
if (clixon_plugin_start(h) < 0)
|
||||
|
|
|
|||
|
|
@ -588,6 +588,25 @@ api_data_post(clicon_handle h,
|
|||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
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\">", NACM_RECOVERY_USER);
|
||||
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, "//rpc-error")) != NULL){
|
||||
|
||||
clicon_log(LOG_WARNING, "%s: copy-config running->startup failed", __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
FCGX_SetExitStatus(201, r->out); /* Created */
|
||||
FCGX_FPrintF(r->out, "Content-Type: text/plain\r\n");
|
||||
FCGX_FPrintF(r->out, "\r\n");
|
||||
|
|
@ -914,6 +933,24 @@ api_data_put(clicon_handle h,
|
|||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
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\">", NACM_RECOVERY_USER);
|
||||
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, "//rpc-error")) != NULL){
|
||||
|
||||
clicon_log(LOG_WARNING, "%s: copy-config running->startup failed", __FUNCTION__);
|
||||
}
|
||||
}
|
||||
FCGX_SetExitStatus(201, r->out); /* Created */
|
||||
FCGX_FPrintF(r->out, "Content-Type: text/plain\r\n");
|
||||
FCGX_FPrintF(r->out, "\r\n");
|
||||
|
|
@ -1071,6 +1108,24 @@ api_data_delete(clicon_handle h,
|
|||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
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\">", NACM_RECOVERY_USER);
|
||||
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, "//rpc-error")) != NULL){
|
||||
|
||||
clicon_log(LOG_WARNING, "%s: copy-config running->startup failed", __FUNCTION__);
|
||||
}
|
||||
}
|
||||
FCGX_SetExitStatus(201, r->out);
|
||||
FCGX_FPrintF(r->out, "Content-Type: text/plain\r\n");
|
||||
FCGX_FPrintF(r->out, "\r\n");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue