* 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:
Olof hagsand 2018-03-18 18:06:02 +00:00
parent 52e510cfdf
commit efa72e9e6f
26 changed files with 1196 additions and 475 deletions

View file

@ -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

View file

@ -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:

View file

@ -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;