* RESTCONF "depth" query parameter supported

* C API change: Added `depth` parameter to function `clicon_xml2cbuf`, default is -1.
This commit is contained in:
Olof hagsand 2019-08-17 10:54:13 +02:00
parent 10a2dbe8ec
commit ee329ee382
31 changed files with 289 additions and 117 deletions

View file

@ -496,7 +496,7 @@ api_return_err(clicon_handle h,
FCGX_FPrintF(r->out, "Content-Type: %s\r\n\r\n", restconf_media_int2str(media));
switch (media){
case YANG_DATA_XML:
if (clicon_xml2cbuf(cb, xerr, 2, pretty) < 0)
if (clicon_xml2cbuf(cb, xerr, 2, pretty, -1) < 0)
goto done;
clicon_debug(1, "%s code:%d err:%s", __FUNCTION__, code, cbuf_get(cb));
if (pretty){

View file

@ -242,7 +242,7 @@ api_root(clicon_handle h,
goto done;
switch (media_out){
case YANG_DATA_XML:
if (clicon_xml2cbuf(cb, xt, 0, pretty) < 0)
if (clicon_xml2cbuf(cb, xt, 0, pretty, -1) < 0)
goto done;
break;
case YANG_DATA_JSON:
@ -292,7 +292,7 @@ api_yang_library_version(clicon_handle h,
}
switch (media_out){
case YANG_DATA_XML:
if (clicon_xml2cbuf(cb, xt, 0, pretty) < 0)
if (clicon_xml2cbuf(cb, xt, 0, pretty, -1) < 0)
goto done;
break;
case YANG_DATA_JSON:

View file

@ -326,7 +326,7 @@ api_data_write(clicon_handle h,
#if 0
if (debug){
cbuf *ccc=cbuf_new();
if (clicon_xml2cbuf(ccc, xret, 0, 0) < 0)
if (clicon_xml2cbuf(ccc, xret, 0, 0, -1) < 0)
goto done;
clicon_debug(1, "%s XRET: %s", __FUNCTION__, cbuf_get(ccc));
cbuf_free(ccc);
@ -457,7 +457,7 @@ api_data_write(clicon_handle h,
#if 0
if (debug){
cbuf *ccc=cbuf_new();
if (clicon_xml2cbuf(ccc, xdata, 0, 0) < 0)
if (clicon_xml2cbuf(ccc, xdata, 0, 0, -1) < 0)
goto done;
clicon_debug(1, "%s DATA:%s", __FUNCTION__, cbuf_get(ccc));
cbuf_free(ccc);
@ -620,7 +620,7 @@ api_data_write(clicon_handle h,
NETCONF_BASE_NAMESPACE); /* bind nc to netconf namespace */
cprintf(cbx, "<edit-config><target><candidate /></target>");
cprintf(cbx, "<default-operation>none</default-operation>");
if (clicon_xml2cbuf(cbx, xtop, 0, 0) < 0)
if (clicon_xml2cbuf(cbx, xtop, 0, 0, -1) < 0)
goto done;
cprintf(cbx, "</edit-config></rpc>");
clicon_debug(1, "%s xml: %s api_path:%s",__FUNCTION__, cbuf_get(cbx), api_path);
@ -891,7 +891,7 @@ api_data_delete(clicon_handle h,
NETCONF_BASE_NAMESPACE); /* bind nc to netconf namespace */
cprintf(cbx, "<edit-config><target><candidate /></target>");
cprintf(cbx, "<default-operation>none</default-operation>");
if (clicon_xml2cbuf(cbx, xtop, 0, 0) < 0)
if (clicon_xml2cbuf(cbx, xtop, 0, 0, -1) < 0)
goto done;
cprintf(cbx, "</edit-config></rpc>");
if (clicon_rpc_netconf(h, cbuf_get(cbx), &xret, NULL) < 0)

View file

@ -114,8 +114,9 @@ api_data_get2(clicon_handle h,
int ret;
char *namespace = NULL;
cvec *nsc = NULL;
char *str;
char *attr; /* attribute value string */
netconf_content content = CONTENT_ALL;
int32_t depth = -1; /* Nr of levels to print, -1 is all, 0 is none */
clicon_debug(1, "%s", __FUNCTION__);
if ((yspec = clicon_dbspec_yang(h)) == NULL){
@ -123,9 +124,9 @@ api_data_get2(clicon_handle h,
goto done;
}
/* Check for content attribute */
if ((str = cvec_find_str(qvec, "content")) != NULL){
clicon_debug(1, "%s content=%s", __FUNCTION__, str);
if ((content = netconf_content_str2int(str)) == -1){
if ((attr = cvec_find_str(qvec, "content")) != NULL){
clicon_debug(1, "%s content=%s", __FUNCTION__, attr);
if ((content = netconf_content_str2int(attr)) == -1){
if (netconf_bad_attribute_xml(&xerr, "application",
"<bad-attribute>content</bad-attribute>", "Unrecognized value of content attribute") < 0)
goto done;
@ -138,7 +139,29 @@ api_data_get2(clicon_handle h,
goto ok;
}
}
/* Check for depth attribute */
if ((attr = cvec_find_str(qvec, "depth")) != NULL){
clicon_debug(1, "%s depth=%s", __FUNCTION__, attr);
if (strcmp(attr, "unbounded") != 0){
char *reason = NULL;
if ((ret = parse_int32(attr, &depth, &reason)) < 0){
clicon_err(OE_XML, errno, "parse_int32");
goto done;
}
if (ret==0){
if (netconf_bad_attribute_xml(&xerr, "application",
"<bad-attribute>depth</bad-attribute>", "Unrecognized value of depth attribute") < 0)
goto done;
if ((xe = xpath_first(xerr, "rpc-error")) == NULL){
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
goto done;
}
if (api_return_err(h, r, xe, pretty, media_out, 0) < 0)
goto done;
goto ok;
}
}
}
if ((cbpath = cbuf_new()) == NULL)
goto done;
cprintf(cbpath, "/");
@ -165,13 +188,13 @@ api_data_get2(clicon_handle h,
goto done;
switch (content){
case CONTENT_CONFIG:
ret = clicon_rpc_get_config(h, "running", xpath, namespace, &xret);
ret = clicon_rpc_get(h, xpath, namespace, CONTENT_CONFIG, depth, &xret);
break;
case CONTENT_NONCONFIG:
ret = clicon_rpc_get(h, xpath, namespace, CONTENT_NONCONFIG, &xret);
ret = clicon_rpc_get(h, xpath, namespace, CONTENT_NONCONFIG, depth, &xret);
break;
case CONTENT_ALL:
ret = clicon_rpc_get(h, xpath, namespace, CONTENT_ALL, &xret);
ret = clicon_rpc_get(h, xpath, namespace, CONTENT_ALL, depth, &xret);
break;
default:
clicon_err(OE_XML, EINVAL, "Invalid content attribute %d", content);
@ -196,7 +219,7 @@ api_data_get2(clicon_handle h,
#if 0 /* DEBUG */
if (debug){
cbuf *cb = cbuf_new();
clicon_xml2cbuf(cb, xret, 0, 0);
clicon_xml2cbuf(cb, xret, 0, 0, -1);
clicon_debug(1, "%s xret:%s", __FUNCTION__, cbuf_get(cb));
cbuf_free(cb);
}
@ -219,7 +242,7 @@ api_data_get2(clicon_handle h,
if (xpath==NULL || strcmp(xpath,"/")==0){ /* Special case: data root */
switch (media_out){
case YANG_DATA_XML:
if (clicon_xml2cbuf(cbx, xret, 0, pretty) < 0) /* Dont print top object? */
if (clicon_xml2cbuf(cbx, xret, 0, pretty, -1) < 0) /* Dont print top object? */
goto done;
break;
case YANG_DATA_JSON:
@ -268,7 +291,7 @@ api_data_get2(clicon_handle h,
if (namespace2 && xmlns_set(x, prefix, namespace2) < 0)
goto done;
}
if (clicon_xml2cbuf(cbx, x, 0, pretty) < 0) /* Dont print top object? */
if (clicon_xml2cbuf(cbx, x, 0, pretty, -1) < 0) /* Dont print top object? */
goto done;
}
break;

View file

@ -164,7 +164,7 @@ api_data_post(clicon_handle h,
#if 1
if (debug){
cbuf *ccc=cbuf_new();
if (clicon_xml2cbuf(ccc, xtop, 0, 0) < 0)
if (clicon_xml2cbuf(ccc, xtop, 0, 0, -1) < 0)
goto done;
clicon_debug(1, "%s XURI:%s", __FUNCTION__, cbuf_get(ccc));
cbuf_free(ccc);
@ -309,7 +309,7 @@ api_data_post(clicon_handle h,
#if 1
if (debug){
cbuf *ccc=cbuf_new();
if (clicon_xml2cbuf(ccc, xdata, 0, 0) < 0)
if (clicon_xml2cbuf(ccc, xdata, 0, 0, -1) < 0)
goto done;
clicon_debug(1, "%s XDATA:%s", __FUNCTION__, cbuf_get(ccc));
cbuf_free(ccc);
@ -330,7 +330,7 @@ api_data_post(clicon_handle h,
NETCONF_BASE_NAMESPACE); /* bind nc to netconf namespace */
cprintf(cbx, "<edit-config><target><candidate /></target>");
cprintf(cbx, "<default-operation>none</default-operation>");
if (clicon_xml2cbuf(cbx, xtop, 0, 0) < 0)
if (clicon_xml2cbuf(cbx, xtop, 0, 0, -1) < 0)
goto done;
cprintf(cbx, "</edit-config></rpc>");
clicon_debug(1, "%s xml: %s api_path:%s",__FUNCTION__, cbuf_get(cbx), api_path);
@ -507,7 +507,7 @@ api_operations_post_input(clicon_handle h,
#if 1
if (debug){
cbuf *ccc=cbuf_new();
if (clicon_xml2cbuf(ccc, xdata, 0, 0) < 0)
if (clicon_xml2cbuf(ccc, xdata, 0, 0, -1) < 0)
goto done;
clicon_debug(1, "%s DATA:%s", __FUNCTION__, cbuf_get(ccc));
cbuf_free(ccc);
@ -614,7 +614,7 @@ api_operations_post_output(clicon_handle h,
#if 1
if (debug){
cbuf *ccc=cbuf_new();
if (clicon_xml2cbuf(ccc, xoutput, 0, 0) < 0)
if (clicon_xml2cbuf(ccc, xoutput, 0, 0, -1) < 0)
goto done;
clicon_debug(1, "%s XOUTPUT:%s", __FUNCTION__, cbuf_get(ccc));
cbuf_free(ccc);
@ -855,7 +855,7 @@ api_operations_post(clicon_handle h,
#if 1
if (debug){
cbuf *ccc=cbuf_new();
if (clicon_xml2cbuf(ccc, xtop, 0, 0) < 0)
if (clicon_xml2cbuf(ccc, xtop, 0, 0, -1) < 0)
goto done;
clicon_debug(1, "%s 5. Translate input args: %s",
__FUNCTION__, cbuf_get(ccc));
@ -882,7 +882,7 @@ api_operations_post(clicon_handle h,
#if 0
if (debug){
cbuf *ccc=cbuf_new();
if (clicon_xml2cbuf(ccc, xtop, 0, 0) < 0)
if (clicon_xml2cbuf(ccc, xtop, 0, 0, -1) < 0)
goto done;
clicon_debug(1, "%s 6. Validate and defaults:%s", __FUNCTION__, cbuf_get(ccc));
cbuf_free(ccc);
@ -922,7 +922,7 @@ api_operations_post(clicon_handle h,
#if 1
if (debug){
cbuf *ccc=cbuf_new();
if (clicon_xml2cbuf(ccc, xret, 0, 0) < 0)
if (clicon_xml2cbuf(ccc, xret, 0, 0, -1) < 0)
goto done;
clicon_debug(1, "%s 8. Receive reply:%s", __FUNCTION__, cbuf_get(ccc));
cbuf_free(ccc);
@ -942,7 +942,7 @@ api_operations_post(clicon_handle h,
cbuf_reset(cbret);
switch (media_out){
case YANG_DATA_XML:
if (clicon_xml2cbuf(cbret, xoutput, 0, pretty) < 0)
if (clicon_xml2cbuf(cbret, xoutput, 0, pretty, -1) < 0)
goto done;
/* xoutput should now look: <output xmlns="uri"><x>0</x></output> */
break;

View file

@ -201,7 +201,7 @@ restconf_stream_cb(int s,
FCGX_FPrintF(r->out, "M#id: %02d:0\r\n", tv.tv_sec);
}
#endif
if (clicon_xml2cbuf(cb, xn, 0, pretty) < 0)
if (clicon_xml2cbuf(cb, xn, 0, pretty, -1) < 0)
goto done;
FCGX_FPrintF(r->out, "data: %s\r\n", cbuf_get(cb));
FCGX_FPrintF(r->out, "\r\n");