Pagination updated
* Pagination is updated to new drafts: * [https://datatracker.ietf.org/doc/html/draft-wwlh-netconf-list-pagination-00>] * [https://datatracker.ietf.org/doc/html/draft-wwlh-netconf-list-pagination-nc-02] * [https://datatracker.ietf.org/doc/html/draft-wwlh-netconf-list-pagination-rc-02] * See also updated [https://clixon-docs.readthedocs.io/en/latest/pagination.html] * Added IETF RFC:s (included by pagination): * ietf-netconf-nmda@2019-01-07.yang * ietf-origin@2018-02-14.yang * ietf-netconf-with-defaults@2011-06-01.yang * Dropped pcvec parameter to many restconf api functions
This commit is contained in:
parent
baa6e821a8
commit
a4b4dc97ce
28 changed files with 1011 additions and 527 deletions
|
|
@ -49,6 +49,13 @@ Thanks netgate for providing the dispatcher code!
|
||||||
|
|
||||||
Users may have to change how they access the system
|
Users may have to change how they access the system
|
||||||
|
|
||||||
|
* Pagination is updated to new drafts:
|
||||||
|
* [https://datatracker.ietf.org/doc/html/draft-wwlh-netconf-list-pagination-00>]
|
||||||
|
* Note removed import of system-capabilities.yang
|
||||||
|
* [https://datatracker.ietf.org/doc/html/draft-wwlh-netconf-list-pagination-nc-02]
|
||||||
|
* Note added presence to list-pagination container
|
||||||
|
* [https://datatracker.ietf.org/doc/html/draft-wwlh-netconf-list-pagination-rc-02]
|
||||||
|
* See also updated [https://clixon-docs.readthedocs.io/en/latest/pagination.html]
|
||||||
* NETCONF hello errors, such as wrong session-id, prefix, namespace terminates session
|
* NETCONF hello errors, such as wrong session-id, prefix, namespace terminates session
|
||||||
* Instead of returning an rpc-error reply
|
* Instead of returning an rpc-error reply
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -519,7 +519,7 @@ get_list_pagination(clicon_handle h,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* sort */
|
/* sort */
|
||||||
if (ret && (x = xml_find_type(xe, NULL, "sort", CX_ELMNT)) != NULL)
|
if (ret && (x = xml_find_type(xe, NULL, "sort-by", CX_ELMNT)) != NULL)
|
||||||
sort = xml_body(x);
|
sort = xml_body(x);
|
||||||
if (sort) {
|
if (sort) {
|
||||||
/* XXX: nothing yet */
|
/* XXX: nothing yet */
|
||||||
|
|
@ -721,12 +721,9 @@ get_common(clicon_handle h,
|
||||||
char *xpath0;
|
char *xpath0;
|
||||||
cbuf *cbreason = NULL;
|
cbuf *cbreason = NULL;
|
||||||
int list_pagination = 0;
|
int list_pagination = 0;
|
||||||
char *valstr;
|
cxobj **xvec = NULL;
|
||||||
cxobj *x;
|
size_t xlen;
|
||||||
#if 1
|
cxobj *xlistpag;
|
||||||
cxobj **xvec = NULL;
|
|
||||||
size_t xlen;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
clicon_debug(1, "%s", __FUNCTION__);
|
clicon_debug(1, "%s", __FUNCTION__);
|
||||||
username = clicon_username_get(h);
|
username = clicon_username_get(h);
|
||||||
|
|
@ -767,15 +764,15 @@ get_common(clicon_handle h,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Check if list pagination */
|
/* Check if list pagination */
|
||||||
if ((x = xml_find_type(xe, NULL, "list-pagination", CX_ELMNT)) != NULL &&
|
if ((xlistpag = xml_find_type(xe, NULL, "list-pagination", CX_ELMNT)) != NULL)
|
||||||
(valstr = xml_body(x)) != NULL &&
|
|
||||||
strcmp(valstr,"true")==0)
|
|
||||||
list_pagination = 1;
|
list_pagination = 1;
|
||||||
/* Sanity check for list pagination: path must be a list/leaf-list, if it is,
|
/* Sanity check for list pagination: path must be a list/leaf-list, if it is,
|
||||||
* check config/state
|
* check config/state
|
||||||
*/
|
*/
|
||||||
if (list_pagination){
|
if (list_pagination){
|
||||||
if (get_list_pagination(h, ce, xe, content, db,
|
if (get_list_pagination(h, ce,
|
||||||
|
xlistpag,
|
||||||
|
content, db,
|
||||||
depth, yspec, xpath, nsc, username,
|
depth, yspec, xpath, nsc, username,
|
||||||
cbret) < 0)
|
cbret) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
|
||||||
|
|
@ -46,15 +46,17 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
/*! RESTCONF media types
|
/*! RESTCONF media types
|
||||||
* @see http_media_map
|
* @see http_media_map
|
||||||
* @note DUPLICATED in clixon_lib.h
|
* @note DUPLICATED in restconf_lib.h
|
||||||
*/
|
*/
|
||||||
enum restconf_media{
|
enum restconf_media{
|
||||||
YANG_DATA_JSON, /* "application/yang-data+json" */
|
YANG_DATA_JSON, /* "application/yang-data+json" */
|
||||||
YANG_DATA_XML, /* "application/yang-data+xml" */
|
YANG_DATA_XML, /* "application/yang-data+xml" */
|
||||||
YANG_PATCH_JSON, /* "application/yang-patch+json" */
|
YANG_PATCH_JSON, /* "application/yang-patch+json" */
|
||||||
YANG_PATCH_XML, /* "application/yang-patch+xml" */
|
YANG_PATCH_XML, /* "application/yang-patch+xml" */
|
||||||
YANG_COLLECTION_XML, /* draft-wwlh-netconf-list-pagination-rc-01.txt */
|
YANG_PAGINATION_XML, /* draft-wwlh-netconf-list-pagination-rc-02.txt */
|
||||||
YANG_COLLECTION_JSON /* draft-wwlh-netconf-list-pagination-rc-01.txt */
|
/* For JSON, the existing "application/yang-data+json" media type is
|
||||||
|
sufficient, as the JSON format has built-in support for encoding
|
||||||
|
arrays. */
|
||||||
};
|
};
|
||||||
typedef enum restconf_media restconf_media;
|
typedef enum restconf_media restconf_media;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -275,7 +275,7 @@ api_return_err(clicon_handle h,
|
||||||
switch (media){
|
switch (media){
|
||||||
case YANG_DATA_XML:
|
case YANG_DATA_XML:
|
||||||
case YANG_PATCH_XML:
|
case YANG_PATCH_XML:
|
||||||
case YANG_COLLECTION_XML:
|
case YANG_PAGINATION_XML:
|
||||||
clicon_debug(1, "%s code:%d", __FUNCTION__, code);
|
clicon_debug(1, "%s code:%d", __FUNCTION__, code);
|
||||||
if (pretty){
|
if (pretty){
|
||||||
cprintf(cb, " <errors xmlns=\"urn:ietf:params:xml:ns:yang:ietf-restconf\">\n");
|
cprintf(cb, " <errors xmlns=\"urn:ietf:params:xml:ns:yang:ietf-restconf\">\n");
|
||||||
|
|
@ -292,7 +292,6 @@ api_return_err(clicon_handle h,
|
||||||
break;
|
break;
|
||||||
case YANG_DATA_JSON:
|
case YANG_DATA_JSON:
|
||||||
case YANG_PATCH_JSON:
|
case YANG_PATCH_JSON:
|
||||||
case YANG_COLLECTION_JSON:
|
|
||||||
clicon_debug(1, "%s code:%d", __FUNCTION__, code);
|
clicon_debug(1, "%s code:%d", __FUNCTION__, code);
|
||||||
if (pretty){
|
if (pretty){
|
||||||
cprintf(cb, "{\n\"ietf-restconf:errors\" : ");
|
cprintf(cb, "{\n\"ietf-restconf:errors\" : ");
|
||||||
|
|
|
||||||
|
|
@ -207,8 +207,7 @@ static const map_str2int http_media_map[] = {
|
||||||
{"application/yang-data+json", YANG_DATA_JSON},
|
{"application/yang-data+json", YANG_DATA_JSON},
|
||||||
{"application/yang-patch+xml", YANG_PATCH_XML},
|
{"application/yang-patch+xml", YANG_PATCH_XML},
|
||||||
{"application/yang-patch+json", YANG_PATCH_JSON},
|
{"application/yang-patch+json", YANG_PATCH_JSON},
|
||||||
{"application/yang-collection+xml", YANG_COLLECTION_XML}, /* XXX -data+xml-list?? */
|
{"application/yang-data+xml-list", YANG_PAGINATION_XML}, /* draft-wwlh-netconf-list-pagination-rc-02 */
|
||||||
{"application/yang-collection+json", YANG_COLLECTION_JSON},
|
|
||||||
{NULL, -1}
|
{NULL, -1}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,8 +53,7 @@ enum restconf_media{
|
||||||
YANG_DATA_XML, /* "application/yang-data+xml" */
|
YANG_DATA_XML, /* "application/yang-data+xml" */
|
||||||
YANG_PATCH_JSON, /* "application/yang-patch+json" */
|
YANG_PATCH_JSON, /* "application/yang-patch+json" */
|
||||||
YANG_PATCH_XML, /* "application/yang-patch+xml" */
|
YANG_PATCH_XML, /* "application/yang-patch+xml" */
|
||||||
YANG_COLLECTION_XML, /* draft-ietf-netconf-restconf-collection-00.txt */
|
YANG_PAGINATION_XML, /* draft-wwlh-netconf-list-pagination-rc-02.txt */
|
||||||
YANG_COLLECTION_JSON /* draft-ietf-netconf-restconf-collection-00.txt */
|
|
||||||
};
|
};
|
||||||
typedef enum restconf_media restconf_media;
|
typedef enum restconf_media restconf_media;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -191,7 +191,6 @@ int
|
||||||
api_data_write(clicon_handle h,
|
api_data_write(clicon_handle h,
|
||||||
void *req,
|
void *req,
|
||||||
char *api_path0,
|
char *api_path0,
|
||||||
cvec *pcvec,
|
|
||||||
int pi,
|
int pi,
|
||||||
cvec *qvec,
|
cvec *qvec,
|
||||||
char *data,
|
char *data,
|
||||||
|
|
@ -585,7 +584,6 @@ api_data_write(clicon_handle h,
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
* @param[in] req Generic Www handle
|
* @param[in] req Generic Www handle
|
||||||
* @param[in] api_path According to restconf (Sec 3.5.3.1 in rfc8040)
|
* @param[in] api_path According to restconf (Sec 3.5.3.1 in rfc8040)
|
||||||
* @param[in] pcvec Vector of path ie DOCUMENT_URI element
|
|
||||||
* @param[in] pi Offset, where to start pcvec
|
* @param[in] pi Offset, where to start pcvec
|
||||||
* @param[in] qvec Vector of query string (QUERY_STRING)
|
* @param[in] qvec Vector of query string (QUERY_STRING)
|
||||||
* @param[in] data Stream input data
|
* @param[in] data Stream input data
|
||||||
|
|
@ -620,7 +618,6 @@ int
|
||||||
api_data_put(clicon_handle h,
|
api_data_put(clicon_handle h,
|
||||||
void *req,
|
void *req,
|
||||||
char *api_path0,
|
char *api_path0,
|
||||||
cvec *pcvec,
|
|
||||||
int pi,
|
int pi,
|
||||||
cvec *qvec,
|
cvec *qvec,
|
||||||
char *data,
|
char *data,
|
||||||
|
|
@ -631,7 +628,7 @@ api_data_put(clicon_handle h,
|
||||||
restconf_media media_in;
|
restconf_media media_in;
|
||||||
|
|
||||||
media_in = restconf_content_type(h);
|
media_in = restconf_content_type(h);
|
||||||
return api_data_write(h, req, api_path0, pcvec, pi, qvec, data, pretty,
|
return api_data_write(h, req, api_path0, pi, qvec, data, pretty,
|
||||||
media_in, media_out, 0, ds);
|
media_in, media_out, 0, ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -639,8 +636,7 @@ api_data_put(clicon_handle h,
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
* @param[in] req Generic Www handle
|
* @param[in] req Generic Www handle
|
||||||
* @param[in] api_path According to restconf (Sec 3.5.3.1 in rfc8040)
|
* @param[in] api_path According to restconf (Sec 3.5.3.1 in rfc8040)
|
||||||
* @param[in] pcvec Vector of path ie DOCUMENT_URI element
|
* @param[in] pi Offset, where to start qvec
|
||||||
* @param[in] pi Offset, where to start pcvec
|
|
||||||
* @param[in] qvec Vector of query string (QUERY_STRING)
|
* @param[in] qvec Vector of query string (QUERY_STRING)
|
||||||
* @param[in] data Stream input data
|
* @param[in] data Stream input data
|
||||||
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
||||||
|
|
@ -657,7 +653,6 @@ int
|
||||||
api_data_patch(clicon_handle h,
|
api_data_patch(clicon_handle h,
|
||||||
void *req,
|
void *req,
|
||||||
char *api_path0,
|
char *api_path0,
|
||||||
cvec *pcvec,
|
|
||||||
int pi,
|
int pi,
|
||||||
cvec *qvec,
|
cvec *qvec,
|
||||||
char *data,
|
char *data,
|
||||||
|
|
@ -672,7 +667,7 @@ api_data_patch(clicon_handle h,
|
||||||
switch (media_in){
|
switch (media_in){
|
||||||
case YANG_DATA_XML:
|
case YANG_DATA_XML:
|
||||||
case YANG_DATA_JSON: /* plain patch */
|
case YANG_DATA_JSON: /* plain patch */
|
||||||
ret = api_data_write(h, req, api_path0, pcvec, pi, qvec, data, pretty,
|
ret = api_data_write(h, req, api_path0, pi, qvec, data, pretty,
|
||||||
media_in, media_out, 1, ds);
|
media_in, media_out, 1, ds);
|
||||||
break;
|
break;
|
||||||
case YANG_PATCH_JSON: /* RFC 8072 patch */
|
case YANG_PATCH_JSON: /* RFC 8072 patch */
|
||||||
|
|
|
||||||
|
|
@ -44,18 +44,18 @@
|
||||||
*/
|
*/
|
||||||
int api_data_options(clicon_handle h, void *req);
|
int api_data_options(clicon_handle h, void *req);
|
||||||
int api_data_write(clicon_handle h, void *req, char *api_path0,
|
int api_data_write(clicon_handle h, void *req, char *api_path0,
|
||||||
cvec *pcvec, int pi,
|
int pi,
|
||||||
cvec *qvec, char *data,
|
cvec *qvec, char *data,
|
||||||
int pretty, restconf_media media_in, restconf_media media_out,
|
int pretty, restconf_media media_in, restconf_media media_out,
|
||||||
int plain_patch, ietf_ds_t ds);
|
int plain_patch, ietf_ds_t ds);
|
||||||
|
|
||||||
int api_data_put(clicon_handle h, void *req, char *api_path,
|
int api_data_put(clicon_handle h, void *req, char *api_path,
|
||||||
cvec *pcvec, int pi,
|
int pi,
|
||||||
cvec *qvec, char *data,
|
cvec *qvec, char *data,
|
||||||
int pretty, restconf_media media_out, ietf_ds_t ds);
|
int pretty, restconf_media media_out, ietf_ds_t ds);
|
||||||
|
|
||||||
int api_data_patch(clicon_handle h, void *req, char *api_path,
|
int api_data_patch(clicon_handle h, void *req, char *api_path,
|
||||||
cvec *pcvec, int pi,
|
int pi,
|
||||||
cvec *qvec, char *data, int pretty,
|
cvec *qvec, char *data, int pretty,
|
||||||
restconf_media media_out, ietf_ds_t ds);
|
restconf_media media_out, ietf_ds_t ds);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,12 +63,14 @@
|
||||||
#include "restconf_err.h"
|
#include "restconf_err.h"
|
||||||
#include "restconf_methods_get.h"
|
#include "restconf_methods_get.h"
|
||||||
|
|
||||||
|
/* Forward */
|
||||||
|
static int api_data_pagination(clicon_handle h, void *req, char *api_path, int pi, cvec *qvec, int pretty, restconf_media media_out);
|
||||||
|
|
||||||
/*! Generic GET (both HEAD and GET)
|
/*! Generic GET (both HEAD and GET)
|
||||||
* According to restconf
|
* According to restconf
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
* @param[in] req Generic Www handle
|
* @param[in] req Generic Www handle
|
||||||
* @param[in] api_path According to restconf (Sec 3.5.3.1 in rfc8040)
|
* @param[in] api_path According to restconf (Sec 3.5.3.1 in rfc8040)
|
||||||
* @param[in] pcvec Vector of path ie DOCUMENT_URI element
|
|
||||||
* @param[in] pi Offset, where path starts
|
* @param[in] pi Offset, where path starts
|
||||||
* @param[in] qvec Vector of query string (QUERY_STRING)
|
* @param[in] qvec Vector of query string (QUERY_STRING)
|
||||||
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
||||||
|
|
@ -90,12 +92,12 @@
|
||||||
* encoding is used in the response, then an error response containing a
|
* encoding is used in the response, then an error response containing a
|
||||||
* "400 Bad Request" status-line MUST be returned by the server.
|
* "400 Bad Request" status-line MUST be returned by the server.
|
||||||
* Netconf: <get-config>, <get>
|
* Netconf: <get-config>, <get>
|
||||||
|
* @note there is an ad-hoc method to determine json pagination request instead of regular GET
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
api_data_get2(clicon_handle h,
|
api_data_get2(clicon_handle h,
|
||||||
void *req,
|
void *req,
|
||||||
char *api_path,
|
char *api_path,
|
||||||
cvec *pcvec, /* XXX remove? */
|
|
||||||
int pi,
|
int pi,
|
||||||
cvec *qvec,
|
cvec *qvec,
|
||||||
int pretty,
|
int pretty,
|
||||||
|
|
@ -148,6 +150,18 @@ api_data_get2(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
|
/* Ad-hoc method to determine json pagination request:
|
||||||
|
* address list and one of "item/offset/.." is defined
|
||||||
|
*/
|
||||||
|
if (!head &&
|
||||||
|
(yang_keyword_get(y) == Y_LIST || yang_keyword_get(y) == Y_LEAF_LIST) &&
|
||||||
|
(cvec_find(qvec, "where") || cvec_find(qvec, "sort-by") ||
|
||||||
|
cvec_find(qvec, "direction") || cvec_find(qvec, "offset") ||
|
||||||
|
cvec_find(qvec, "limit") || cvec_find(qvec, "sublist-limit"))){
|
||||||
|
if (api_data_pagination(h, req, api_path, 0, qvec, pretty, media_out) < 0)
|
||||||
|
goto done;
|
||||||
|
goto ok;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* Check for content attribute */
|
/* Check for content attribute */
|
||||||
if ((attr = cvec_find_str(qvec, "content")) != NULL){
|
if ((attr = cvec_find_str(qvec, "content")) != NULL){
|
||||||
|
|
@ -305,7 +319,6 @@ api_data_get2(clicon_handle h,
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
* @param[in] req Generic Www handle
|
* @param[in] req Generic Www handle
|
||||||
* @param[in] api_path According to restconf (Sec 3.5.3.1 in rfc8040)
|
* @param[in] api_path According to restconf (Sec 3.5.3.1 in rfc8040)
|
||||||
* @param[in] pcvec Vector of path ie DOCUMENT_URI element
|
|
||||||
* @param[in] pi Offset, where path starts
|
* @param[in] pi Offset, where path starts
|
||||||
* @param[in] qvec Vector of query string (QUERY_STRING)
|
* @param[in] qvec Vector of query string (QUERY_STRING)
|
||||||
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
||||||
|
|
@ -320,10 +333,9 @@ api_data_get2(clicon_handle h,
|
||||||
* @see draft-ietf-netconf-restconf-collection-00.txt
|
* @see draft-ietf-netconf-restconf-collection-00.txt
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
api_data_collection(clicon_handle h,
|
api_data_pagination(clicon_handle h,
|
||||||
void *req,
|
void *req,
|
||||||
char *api_path,
|
char *api_path,
|
||||||
cvec *pcvec, /* XXX remove? */
|
|
||||||
int pi,
|
int pi,
|
||||||
cvec *qvec,
|
cvec *qvec,
|
||||||
int pretty,
|
int pretty,
|
||||||
|
|
@ -392,7 +404,7 @@ api_data_collection(clicon_handle h,
|
||||||
if (yang_keyword_get(y) != Y_LIST && yang_keyword_get(y) != Y_LEAF_LIST){
|
if (yang_keyword_get(y) != Y_LIST && yang_keyword_get(y) != Y_LEAF_LIST){
|
||||||
if (netconf_bad_element_xml(&xerr, "application",
|
if (netconf_bad_element_xml(&xerr, "application",
|
||||||
yang_argument_get(y),
|
yang_argument_get(y),
|
||||||
"Element is not list or leaf-list which is required for GET collection") < 0)
|
"Element is not list or leaf-list which is required for GET paginate") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
|
||||||
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)");
|
||||||
|
|
@ -464,7 +476,7 @@ api_data_collection(clicon_handle h,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
direction = cvec_find_str(qvec, "direction");
|
direction = cvec_find_str(qvec, "direction");
|
||||||
sort = cvec_find_str(qvec, "sort");
|
sort = cvec_find_str(qvec, "sort-by");
|
||||||
where = cvec_find_str(qvec, "where");
|
where = cvec_find_str(qvec, "where");
|
||||||
if (clicon_rpc_get_pageable_list(h, "running", xpath, nsc, content,
|
if (clicon_rpc_get_pageable_list(h, "running", xpath, nsc, content,
|
||||||
depth, offset, limit, direction, sort, where,
|
depth, offset, limit, direction, sort, where,
|
||||||
|
|
@ -492,9 +504,9 @@ api_data_collection(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
if ((xpr = xml_new("yang-collection", NULL, CX_ELMNT)) == NULL)
|
if ((xpr = xml_new("xml-list", NULL, CX_ELMNT)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (xmlns_set(xpr, NULL, RESTCONF_PAGINATON_NAMESPACE) < 0)
|
if (xmlns_set(xpr, NULL, IETF_PAGINATON_NAMESPACE) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (xpath_vec(xret, nsc, "%s", &xvec, &xlen, xpath) < 0)
|
if (xpath_vec(xret, nsc, "%s", &xvec, &xlen, xpath) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -504,30 +516,30 @@ api_data_collection(clicon_handle h,
|
||||||
* Here we take the latter approach to return an empty list and do not
|
* Here we take the latter approach to return an empty list and do not
|
||||||
* handle the non-exist case differently.
|
* handle the non-exist case differently.
|
||||||
*/
|
*/
|
||||||
for (i=0; i<xlen; i++){
|
|
||||||
xp = xvec[i];
|
|
||||||
ns = NULL;
|
|
||||||
if (xml2ns(xp, NULL, &ns) < 0)
|
|
||||||
goto done;
|
|
||||||
if (ns != NULL){
|
|
||||||
if (xmlns_set(xp, NULL, ns) < 0)
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
if (xml_rm(xp) < 0)
|
|
||||||
goto done;
|
|
||||||
if (xml_insert(xpr, xp, INS_LAST, NULL, NULL) < 0)
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
/* Normal return, no error */
|
/* Normal return, no error */
|
||||||
if ((cbx = cbuf_new()) == NULL)
|
if ((cbx = cbuf_new()) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
switch (media_out){
|
switch (media_out){
|
||||||
case YANG_COLLECTION_XML:
|
case YANG_PAGINATION_XML:
|
||||||
|
for (i=0; i<xlen; i++){
|
||||||
|
xp = xvec[i];
|
||||||
|
ns = NULL;
|
||||||
|
if (xml2ns(xp, NULL, &ns) < 0)
|
||||||
|
goto done;
|
||||||
|
if (ns != NULL){
|
||||||
|
if (xmlns_set(xp, NULL, ns) < 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (xml_rm(xp) < 0)
|
||||||
|
goto done;
|
||||||
|
if (xml_insert(xpr, xp, INS_LAST, NULL, NULL) < 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
if (clicon_xml2cbuf(cbx, xpr, 0, pretty, -1) < 0) /* Dont print top object? */
|
if (clicon_xml2cbuf(cbx, xpr, 0, pretty, -1) < 0) /* Dont print top object? */
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case YANG_COLLECTION_JSON:
|
case YANG_DATA_JSON:
|
||||||
if (xml2json_cbuf(cbx, xpr, pretty) < 0)
|
if (xml2json_cbuf_vec(cbx, xvec, xlen, pretty) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -570,7 +582,6 @@ api_data_collection(clicon_handle h,
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
* @param[in] req Generic Www handle
|
* @param[in] req Generic Www handle
|
||||||
* @param[in] api_path According to restconf (Sec 3.5.3.1 in rfc8040)
|
* @param[in] api_path According to restconf (Sec 3.5.3.1 in rfc8040)
|
||||||
* @param[in] pcvec Vector of path ie DOCUMENT_URI element
|
|
||||||
* @param[in] pi Offset, where path starts
|
* @param[in] pi Offset, where path starts
|
||||||
* @param[in] qvec Vector of query string (QUERY_STRING)
|
* @param[in] qvec Vector of query string (QUERY_STRING)
|
||||||
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
||||||
|
|
@ -586,14 +597,13 @@ int
|
||||||
api_data_head(clicon_handle h,
|
api_data_head(clicon_handle h,
|
||||||
void *req,
|
void *req,
|
||||||
char *api_path,
|
char *api_path,
|
||||||
cvec *pcvec,
|
|
||||||
int pi,
|
int pi,
|
||||||
cvec *qvec,
|
cvec *qvec,
|
||||||
int pretty,
|
int pretty,
|
||||||
restconf_media media_out,
|
restconf_media media_out,
|
||||||
ietf_ds_t ds)
|
ietf_ds_t ds)
|
||||||
{
|
{
|
||||||
return api_data_get2(h, req, api_path, pcvec, pi, qvec, pretty, media_out, 1);
|
return api_data_get2(h, req, api_path, pi, qvec, pretty, media_out, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! REST GET method
|
/*! REST GET method
|
||||||
|
|
@ -625,7 +635,6 @@ int
|
||||||
api_data_get(clicon_handle h,
|
api_data_get(clicon_handle h,
|
||||||
void *req,
|
void *req,
|
||||||
char *api_path,
|
char *api_path,
|
||||||
cvec *pcvec,
|
|
||||||
int pi,
|
int pi,
|
||||||
cvec *qvec,
|
cvec *qvec,
|
||||||
int pretty,
|
int pretty,
|
||||||
|
|
@ -636,15 +645,13 @@ api_data_get(clicon_handle h,
|
||||||
|
|
||||||
switch (media_out){
|
switch (media_out){
|
||||||
case YANG_DATA_XML:
|
case YANG_DATA_XML:
|
||||||
case YANG_DATA_JSON:
|
case YANG_DATA_JSON: /* ad-hoc algorithm in get to determine if a paginated request */
|
||||||
if (api_data_get2(h, req, api_path, pcvec, pi, qvec, pretty, media_out, 0) < 0)
|
if (api_data_get2(h, req, api_path, pi, qvec, pretty, media_out, 0) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case YANG_COLLECTION_XML:
|
case YANG_PAGINATION_XML:
|
||||||
case YANG_COLLECTION_JSON:
|
if (api_data_pagination(h, req, api_path, pi, qvec, pretty, media_out) < 0)
|
||||||
if (api_data_collection(h, req, api_path, pcvec, pi, qvec, pretty, media_out) < 0)
|
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -657,7 +664,6 @@ api_data_get(clicon_handle h,
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
* @param[in] req Generic Www handle
|
* @param[in] req Generic Www handle
|
||||||
* @param[in] path According to restconf (Sec 3.5.1.1 in [draft])
|
* @param[in] path According to restconf (Sec 3.5.1.1 in [draft])
|
||||||
* @param[in] pcvec Vector of path ie DOCUMENT_URI element
|
|
||||||
* @param[in] pi Offset, where path starts
|
* @param[in] pi Offset, where path starts
|
||||||
* @param[in] qvec Vector of query string (QUERY_STRING)
|
* @param[in] qvec Vector of query string (QUERY_STRING)
|
||||||
* @param[in] data Stream input data
|
* @param[in] data Stream input data
|
||||||
|
|
|
||||||
|
|
@ -41,9 +41,9 @@
|
||||||
/*
|
/*
|
||||||
* Prototypes
|
* Prototypes
|
||||||
*/
|
*/
|
||||||
int api_data_head(clicon_handle h, void *req, char *api_path, cvec *pcvec, int pi,
|
int api_data_head(clicon_handle h, void *req, char *api_path, int pi,
|
||||||
cvec *qvec, int pretty, restconf_media media_out, ietf_ds_t ds);
|
cvec *qvec, int pretty, restconf_media media_out, ietf_ds_t ds);
|
||||||
int api_data_get(clicon_handle h, void *req, char *api_path, cvec *pcvec, int pi,
|
int api_data_get(clicon_handle h, void *req, char *api_path, int pi,
|
||||||
cvec *qvec, int pretty, restconf_media media_out, ietf_ds_t ds);
|
cvec *qvec, int pretty, restconf_media media_out, ietf_ds_t ds);
|
||||||
int api_operations_get(clicon_handle h, void *req,
|
int api_operations_get(clicon_handle h, void *req,
|
||||||
char *api_path, int pi, cvec *qvec, char *data,
|
char *api_path, int pi, cvec *qvec, char *data,
|
||||||
|
|
|
||||||
|
|
@ -188,7 +188,7 @@ yang_patch_strip_after_last_slash(char* val)
|
||||||
/*! YANG PATCH replace method
|
/*! YANG PATCH replace method
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
* @param[in] req Generic Www handle
|
* @param[in] req Generic Www handle
|
||||||
* @param[in] pi Offset, where to start pcvec
|
* @param[in] pi Offset, where to start api-path
|
||||||
* @param[in] qvec Vector of query string (QUERY_STRING)
|
* @param[in] qvec Vector of query string (QUERY_STRING)
|
||||||
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
||||||
* @param[in] media_out Output media
|
* @param[in] media_out Output media
|
||||||
|
|
@ -287,7 +287,7 @@ yang_patch_do_replace(clicon_handle h,
|
||||||
/*! YANG PATCH create method
|
/*! YANG PATCH create method
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
* @param[in] req Generic Www handle
|
* @param[in] req Generic Www handle
|
||||||
* @param[in] pi Offset, where to start pcvec
|
* @param[in] pi Offset, where to start api-path
|
||||||
* @param[in] qvec Vector of query string (QUERY_STRING)
|
* @param[in] qvec Vector of query string (QUERY_STRING)
|
||||||
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
||||||
* @param[in] media_out Output media
|
* @param[in] media_out Output media
|
||||||
|
|
@ -343,7 +343,7 @@ yang_patch_do_create(clicon_handle h,
|
||||||
/*! YANG PATCH insert method
|
/*! YANG PATCH insert method
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
* @param[in] req Generic Www handle
|
* @param[in] req Generic Www handle
|
||||||
* @param[in] pi Offset, where to start pcvec
|
* @param[in] pi Offset, where to start api-path
|
||||||
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
||||||
* @param[in] media_out Output media
|
* @param[in] media_out Output media
|
||||||
* @param[in] ds 0 if "data" resource, 1 if rfc8527 "ds" resource
|
* @param[in] ds 0 if "data" resource, 1 if rfc8527 "ds" resource
|
||||||
|
|
@ -431,8 +431,7 @@ yang_patch_do_insert(clicon_handle h,
|
||||||
/*! YANG PATCH merge method
|
/*! YANG PATCH merge method
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
* @param[in] req Generic Www handle
|
* @param[in] req Generic Www handle
|
||||||
* @param[in] pcvec Vector of path ie DOCUMENT_URI element
|
* @param[in] pi Offset, where to start api-path
|
||||||
* @param[in] pi Offset, where to start pcvec
|
|
||||||
* @param[in] qvec Vector of query string (QUERY_STRING)
|
* @param[in] qvec Vector of query string (QUERY_STRING)
|
||||||
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
||||||
* @param[in] media_out Output media
|
* @param[in] media_out Output media
|
||||||
|
|
@ -447,7 +446,6 @@ yang_patch_do_insert(clicon_handle h,
|
||||||
static int
|
static int
|
||||||
yang_patch_do_merge(clicon_handle h,
|
yang_patch_do_merge(clicon_handle h,
|
||||||
void *req,
|
void *req,
|
||||||
cvec *pcvec,
|
|
||||||
int pi,
|
int pi,
|
||||||
cvec *qvec,
|
cvec *qvec,
|
||||||
int pretty,
|
int pretty,
|
||||||
|
|
@ -484,7 +482,7 @@ yang_patch_do_merge(clicon_handle h,
|
||||||
if ((json_simple_patch = yang_patch_xml2json_modified_cbuf(x_simple_patch)) == NULL)
|
if ((json_simple_patch = yang_patch_xml2json_modified_cbuf(x_simple_patch)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
// Send the simple patch request
|
// Send the simple patch request
|
||||||
if (api_data_write(h, req, cbuf_get(simple_patch_request_uri), pcvec, pi, qvec, cbuf_get(json_simple_patch), pretty, YANG_DATA_JSON, media_out, 1, ds ) < 0)
|
if (api_data_write(h, req, cbuf_get(simple_patch_request_uri), pi, qvec, cbuf_get(json_simple_patch), pretty, YANG_DATA_JSON, media_out, 1, ds ) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (json_simple_patch){
|
if (json_simple_patch){
|
||||||
cbuf_free(json_simple_patch);
|
cbuf_free(json_simple_patch);
|
||||||
|
|
@ -509,7 +507,6 @@ yang_patch_do_merge(clicon_handle h,
|
||||||
static int
|
static int
|
||||||
yang_patch_do_value(clicon_handle h,
|
yang_patch_do_value(clicon_handle h,
|
||||||
void *req,
|
void *req,
|
||||||
cvec *pcvec,
|
|
||||||
int pi,
|
int pi,
|
||||||
cvec *qvec,
|
cvec *qvec,
|
||||||
int pretty,
|
int pretty,
|
||||||
|
|
@ -560,7 +557,7 @@ yang_patch_do_value(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case YANG_PATCH_OP_MERGE:
|
case YANG_PATCH_OP_MERGE:
|
||||||
if (yang_patch_do_merge(h, req, pcvec, pi, qvec, pretty, media_out, ds, simple_patch_request_uri, value_vec_len, value_vec, x_simple_patch, key_xn) < 0)
|
if (yang_patch_do_merge(h, req, pi, qvec, pretty, media_out, ds, simple_patch_request_uri, value_vec_len, value_vec, x_simple_patch, key_xn) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -579,8 +576,7 @@ yang_patch_do_value(clicon_handle h,
|
||||||
*
|
*
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
* @param[in] req Generic Www handle
|
* @param[in] req Generic Www handle
|
||||||
* @param[in] pcvec Vector of path ie DOCUMENT_URI element
|
* @param[in] pi Offset, where to start api-path
|
||||||
* @param[in] pi Offset, where to start pcvec
|
|
||||||
* @param[in] qvec Vector of query string (QUERY_STRING)
|
* @param[in] qvec Vector of query string (QUERY_STRING)
|
||||||
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
||||||
* @param[in] media_out Output media
|
* @param[in] media_out Output media
|
||||||
|
|
@ -591,7 +587,6 @@ yang_patch_do_value(clicon_handle h,
|
||||||
static int
|
static int
|
||||||
yang_patch_do_edit(clicon_handle h,
|
yang_patch_do_edit(clicon_handle h,
|
||||||
void *req,
|
void *req,
|
||||||
cvec *pcvec,
|
|
||||||
int pi,
|
int pi,
|
||||||
cvec *qvec,
|
cvec *qvec,
|
||||||
int pretty,
|
int pretty,
|
||||||
|
|
@ -693,7 +688,7 @@ yang_patch_do_edit(clicon_handle h,
|
||||||
|
|
||||||
// Loop through the values
|
// Loop through the values
|
||||||
for (i = 0; i < veclen; i++) {
|
for (i = 0; i < veclen; i++) {
|
||||||
if (yang_patch_do_value(h, req, pcvec, pi, qvec, pretty, media_out, ds,
|
if (yang_patch_do_value(h, req, pi, qvec, pretty, media_out, ds,
|
||||||
vec[i], modname,
|
vec[i], modname,
|
||||||
operation, where_val, point_val, simple_patch_request_uri, target_val,
|
operation, where_val, point_val, simple_patch_request_uri, target_val,
|
||||||
api_path, key_xn) < 0)
|
api_path, key_xn) < 0)
|
||||||
|
|
@ -729,8 +724,7 @@ yang_patch_do_edit(clicon_handle h,
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
* @param[in] req Generic Www handle
|
* @param[in] req Generic Www handle
|
||||||
* @param[in] api_path0 According to restconf (Sec 3.5.3.1 in rfc8040)
|
* @param[in] api_path0 According to restconf (Sec 3.5.3.1 in rfc8040)
|
||||||
* @param[in] pcvec Vector of path ie DOCUMENT_URI element
|
* @param[in] pi Offset, where to start api-path
|
||||||
* @param[in] pi Offset, where to start pcvec
|
|
||||||
* @param[in] qvec Vector of query string (QUERY_STRING)
|
* @param[in] qvec Vector of query string (QUERY_STRING)
|
||||||
* @param[in] data Stream input data
|
* @param[in] data Stream input data
|
||||||
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
||||||
|
|
@ -749,7 +743,6 @@ int
|
||||||
api_data_yang_patch(clicon_handle h,
|
api_data_yang_patch(clicon_handle h,
|
||||||
void *req,
|
void *req,
|
||||||
char *api_path0,
|
char *api_path0,
|
||||||
cvec *pcvec,
|
|
||||||
int pi,
|
int pi,
|
||||||
cvec *qvec,
|
cvec *qvec,
|
||||||
char *data,
|
char *data,
|
||||||
|
|
@ -828,7 +821,7 @@ api_data_yang_patch(clicon_handle h,
|
||||||
if (xpath_vec(xpatch, NULL, "yang-patch/edit", &vec, &veclen) < 0)
|
if (xpath_vec(xpatch, NULL, "yang-patch/edit", &vec, &veclen) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
for (i = 0; i < veclen; i++) {
|
for (i = 0; i < veclen; i++) {
|
||||||
if (yang_patch_do_edit(h, req, pcvec, pi, qvec, pretty, media_out, ds,
|
if (yang_patch_do_edit(h, req, pi, qvec, pretty, media_out, ds,
|
||||||
yspec,
|
yspec,
|
||||||
vec[i],
|
vec[i],
|
||||||
uripath0, api_path) < 0)
|
uripath0, api_path) < 0)
|
||||||
|
|
@ -854,7 +847,6 @@ int
|
||||||
api_data_yang_patch(clicon_handle h,
|
api_data_yang_patch(clicon_handle h,
|
||||||
void *req,
|
void *req,
|
||||||
char *api_path0,
|
char *api_path0,
|
||||||
cvec *pcvec,
|
|
||||||
int pi,
|
int pi,
|
||||||
cvec *qvec,
|
cvec *qvec,
|
||||||
char *data,
|
char *data,
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@
|
||||||
* Prototypes
|
* Prototypes
|
||||||
*/
|
*/
|
||||||
int api_data_yang_patch(clicon_handle h, void *req, char *api_path0,
|
int api_data_yang_patch(clicon_handle h, void *req, char *api_path0,
|
||||||
cvec *pcvec, int pi,
|
int pi,
|
||||||
cvec *qvec, char *data,
|
cvec *qvec, char *data,
|
||||||
int pretty, restconf_media media_in, restconf_media media_out,
|
int pretty, restconf_media media_in, restconf_media media_out,
|
||||||
ietf_ds_t ds);
|
ietf_ds_t ds);
|
||||||
|
|
|
||||||
|
|
@ -329,10 +329,10 @@ api_data(clicon_handle h,
|
||||||
if (dynamic)
|
if (dynamic)
|
||||||
retval = restconf_method_notallowed(h, req, "GET,POST", pretty, media_out);
|
retval = restconf_method_notallowed(h, req, "GET,POST", pretty, media_out);
|
||||||
else
|
else
|
||||||
retval = api_data_head(h, req, api_path, pcvec, pi, qvec, pretty, media_out, ds);
|
retval = api_data_head(h, req, api_path, pi, qvec, pretty, media_out, ds);
|
||||||
}
|
}
|
||||||
else if (strcmp(request_method, "GET")==0) {
|
else if (strcmp(request_method, "GET")==0) {
|
||||||
retval = api_data_get(h, req, api_path, pcvec, pi, qvec, pretty, media_out, ds);
|
retval = api_data_get(h, req, api_path, pi, qvec, pretty, media_out, ds);
|
||||||
}
|
}
|
||||||
else if (strcmp(request_method, "POST")==0) {
|
else if (strcmp(request_method, "POST")==0) {
|
||||||
retval = api_data_post(h, req, api_path, pi, qvec, data, pretty, restconf_content_type(h), media_out, ds);
|
retval = api_data_post(h, req, api_path, pi, qvec, data, pretty, restconf_content_type(h), media_out, ds);
|
||||||
|
|
@ -341,13 +341,13 @@ api_data(clicon_handle h,
|
||||||
if (read_only)
|
if (read_only)
|
||||||
retval = restconf_method_notallowed(h, req, "GET,POST", pretty, media_out);
|
retval = restconf_method_notallowed(h, req, "GET,POST", pretty, media_out);
|
||||||
else
|
else
|
||||||
retval = api_data_put(h, req, api_path, pcvec, pi, qvec, data, pretty, media_out, ds);
|
retval = api_data_put(h, req, api_path, pi, qvec, data, pretty, media_out, ds);
|
||||||
}
|
}
|
||||||
else if (strcmp(request_method, "PATCH")==0) {
|
else if (strcmp(request_method, "PATCH")==0) {
|
||||||
if (read_only) {
|
if (read_only) {
|
||||||
retval = restconf_method_notallowed(h, req, "GET,POST", pretty, media_out);
|
retval = restconf_method_notallowed(h, req, "GET,POST", pretty, media_out);
|
||||||
}
|
}
|
||||||
retval = api_data_patch(h, req, api_path, pcvec, pi, qvec, data, pretty, media_out, ds);
|
retval = api_data_patch(h, req, api_path, pi, qvec, data, pretty, media_out, ds);
|
||||||
}
|
}
|
||||||
else if (strcmp(request_method, "DELETE")==0) {
|
else if (strcmp(request_method, "DELETE")==0) {
|
||||||
if (read_only)
|
if (read_only)
|
||||||
|
|
|
||||||
|
|
@ -54,18 +54,18 @@
|
||||||
*/
|
*/
|
||||||
#define NETCONF_INPUT_CONFIG "config"
|
#define NETCONF_INPUT_CONFIG "config"
|
||||||
|
|
||||||
/* Collections namespace from draft-ietf-netconf-restconf-collection-00.txt
|
/* List pagination namespaces
|
||||||
* XXX: Obsolete but may come back in style
|
|
||||||
*/
|
*/
|
||||||
#define NETCONF_COLLECTION_NAMESPACE "urn:ietf:params:xml:ns:yang:ietf-netconf-list-pagination"
|
|
||||||
|
|
||||||
/* Collections namespace for Clixon
|
/* draft-wwlh-netconf-list-pagination-00.txt
|
||||||
|
* ietf-list-pagination@2021-10-25.yang
|
||||||
*/
|
*/
|
||||||
#define CLIXON_PAGINATON_NAMESPACE "http://clicon.org/clixon-netconf-list-pagination"
|
#define IETF_PAGINATON_NAMESPACE "urn:ietf:params:xml:ns:yang:ietf-list-pagination"
|
||||||
|
|
||||||
/* Collections namespace for restconf
|
/* draft-wwlh-netconf-list-pagination-nc-02.txt
|
||||||
|
* ietf-list-pagination-nc@2021-10-25.yang
|
||||||
*/
|
*/
|
||||||
#define RESTCONF_PAGINATON_NAMESPACE "urn:ietf:params:xml:ns:yang:ietf-restconf-list-pagination"
|
#define IETF_PAGINATON_NC_NAMESPACE "urn:ietf:params:xml:ns:yang:ietf-list-pagination-nc"
|
||||||
|
|
||||||
/* Output symbol for netconf get/get-config
|
/* Output symbol for netconf get/get-config
|
||||||
* ietf-netconf.yang defines it as output:
|
* ietf-netconf.yang defines it as output:
|
||||||
|
|
|
||||||
|
|
@ -1039,7 +1039,8 @@ xml2json1_cbuf(cbuf *cb,
|
||||||
* goto err;
|
* goto err;
|
||||||
* cbuf_free(cb);
|
* cbuf_free(cb);
|
||||||
* @endcode
|
* @endcode
|
||||||
* @see clicon_xml2cbuf
|
* @see clicon_xml2cbuf XML corresponding function
|
||||||
|
* @see xml2json_cbuf_vec Top symbol is list
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xml2json_cbuf(cbuf *cb,
|
xml2json_cbuf(cbuf *cb,
|
||||||
|
|
@ -1082,7 +1083,7 @@ xml2json_cbuf(cbuf *cb,
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
* @note This only works if the vector is uniform, ie same object name.
|
* @note This only works if the vector is uniform, ie same object name.
|
||||||
* Example: <b/><c/> --> <a><b/><c/></a> --> {"b" : null,"c" : null}
|
* Example: <b/><c/> --> <a><b/><c/></a> --> {"b" : null,"c" : null}
|
||||||
* @see xml2json1_cbuf
|
* @see xml2json_cbuf
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xml2json_cbuf_vec(cbuf *cb,
|
xml2json_cbuf_vec(cbuf *cb,
|
||||||
|
|
|
||||||
|
|
@ -1530,11 +1530,11 @@ netconf_module_load(clicon_handle h)
|
||||||
if (clicon_option_bool(h, "CLICON_NETCONF_MESSAGE_ID_OPTIONAL") == 1)
|
if (clicon_option_bool(h, "CLICON_NETCONF_MESSAGE_ID_OPTIONAL") == 1)
|
||||||
xml_bind_netconf_message_id_optional(1);
|
xml_bind_netconf_message_id_optional(1);
|
||||||
#endif
|
#endif
|
||||||
/* Load clixon netconf list pagination */
|
/* Load ietf list pagination */
|
||||||
if (yang_spec_parse_module(h, "clixon-netconf-list-pagination", NULL, yspec)< 0)
|
if (yang_spec_parse_module(h, "ietf-list-pagination", NULL, yspec)< 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* Load restconf list pagination */
|
/* Load ietf list pagination netconf */
|
||||||
if (yang_spec_parse_module(h, "ietf-restconf-list-pagination", NULL, yspec)< 0)
|
if (yang_spec_parse_module(h, "ietf-list-pagination-nc", NULL, yspec)< 0)
|
||||||
goto done;
|
goto done;
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
|
||||||
|
|
@ -944,8 +944,7 @@ clicon_rpc_get_pageable_list(clicon_handle h,
|
||||||
/* Clixon extension, depth=<level> */
|
/* Clixon extension, depth=<level> */
|
||||||
if (depth != -1)
|
if (depth != -1)
|
||||||
cprintf(cb, " depth=\"%d\"", depth);
|
cprintf(cb, " depth=\"%d\"", depth);
|
||||||
/* declare cp prefix in get, so sub-elements dont need to */
|
/* declare lp prefix in get, so sub-elements dont need to */
|
||||||
cprintf(cb, " xmlns:cp=\"%s\"", CLIXON_PAGINATON_NAMESPACE);
|
|
||||||
cprintf(cb, ">"); /* get */
|
cprintf(cb, ">"); /* get */
|
||||||
/* If xpath, add a filter */
|
/* If xpath, add a filter */
|
||||||
if (xpath && strlen(xpath)) {
|
if (xpath && strlen(xpath)) {
|
||||||
|
|
@ -957,17 +956,18 @@ clicon_rpc_get_pageable_list(clicon_handle h,
|
||||||
cprintf(cb, "/>");
|
cprintf(cb, "/>");
|
||||||
}
|
}
|
||||||
/* Explicit use of list-pagination */
|
/* Explicit use of list-pagination */
|
||||||
cprintf(cb, "<cp:list-pagination>true</cp:list-pagination>");
|
cprintf(cb, "<list-pagination xmlns=\"%s\">", IETF_PAGINATON_NC_NAMESPACE);
|
||||||
if (offset != 0)
|
if (offset != 0)
|
||||||
cprintf(cb, "<cp:offset>%u</cp:offset>", offset);
|
cprintf(cb, "<offset>%u</offset>", offset);
|
||||||
if (limit != 0)
|
if (limit != 0)
|
||||||
cprintf(cb, "<cp:limit>%u</cp:limit>", limit);
|
cprintf(cb, "<limit>%u</limit>", limit);
|
||||||
if (direction)
|
if (direction)
|
||||||
cprintf(cb, "<cp:direction>%s</cp:direction>", direction);
|
cprintf(cb, "<direction>%s</direction>", direction);
|
||||||
if (sort)
|
if (sort)
|
||||||
cprintf(cb, "<cp:sort>%s</cp:sort>", sort);
|
cprintf(cb, "<sort>%s</sort>", sort);
|
||||||
if (where)
|
if (where)
|
||||||
cprintf(cb, "<cp:where>%s</cp:where>", where);
|
cprintf(cb, "<where>%s</where>", where);
|
||||||
|
cprintf(cb, "</list-pagination>");
|
||||||
cprintf(cb, "</get>");
|
cprintf(cb, "</get>");
|
||||||
cprintf(cb, "</rpc>");
|
cprintf(cb, "</rpc>");
|
||||||
if ((msg = clicon_msg_encode(session_id, "%s", cbuf_get(cb))) == NULL)
|
if ((msg = clicon_msg_encode(session_id, "%s", cbuf_get(cb))) == NULL)
|
||||||
|
|
|
||||||
|
|
@ -286,9 +286,9 @@ function testlimit()
|
||||||
el="<uint8-numbers>$li</uint8-numbers>"
|
el="<uint8-numbers>$li</uint8-numbers>"
|
||||||
el2="<uint8-numbers xmlns=\"http://example.com/ns/example-social\">$li</uint8-numbers>"
|
el2="<uint8-numbers xmlns=\"http://example.com/ns/example-social\">$li</uint8-numbers>"
|
||||||
else
|
else
|
||||||
el="<uint8-numbers cp:remaining=\"$remaining\" xmlns:cp=\"http://clicon.org/clixon-netconf-list-pagination\">$li</uint8-numbers>"
|
el="<uint8-numbers lp:remaining=\"$remaining\" xmlns:lp=\"urn:ietf:params:xml:ns:yang:ietf-list-pagination\">$li</uint8-numbers>"
|
||||||
el2="<uint8-numbers cp:remaining=\"$remaining\" xmlns:cp=\"http://clicon.org/clixon-netconf-list-pagination\" xmlns=\"http://example.com/ns/example-social\">$li</uint8-numbers>"
|
el2="<uint8-numbers lp:remaining=\"$remaining\" xmlns:lp=\"urn:ietf:params:xml:ns:yang:ietf-list-pagination\" xmlns=\"http://example.com/ns/example-social\">$li</uint8-numbers>"
|
||||||
jsonmeta=",\"@example-social:uint8-numbers\":\[{\"clixon-netconf-list-pagination:remaining\":$remaining}\]"
|
jsonmeta=",\"@example-social:uint8-numbers\":\[{\"ietf-list-pagination:remaining\":$remaining}\]"
|
||||||
fi
|
fi
|
||||||
jsonlist="$li"
|
jsonlist="$li"
|
||||||
else
|
else
|
||||||
|
|
@ -304,13 +304,13 @@ function testlimit()
|
||||||
if [ $limit -eq 0 ]; then
|
if [ $limit -eq 0 ]; then
|
||||||
limitxmlstr=""
|
limitxmlstr=""
|
||||||
else
|
else
|
||||||
limitxmlstr="<limit xmlns=\"http://clicon.org/clixon-netconf-list-pagination\">$limit</limit>"
|
limitxmlstr="<limit>$limit</limit>"
|
||||||
jsonstr="?limit=$limit"
|
jsonstr="?limit=$limit"
|
||||||
fi
|
fi
|
||||||
if [ $offset -eq 0 ]; then
|
if [ $offset -eq 0 ]; then
|
||||||
offsetxmlstr=""
|
offsetxmlstr=""
|
||||||
else
|
else
|
||||||
offsetxmlstr="<offset xmlns=\"http://clicon.org/clixon-netconf-list-pagination\">$offset</offset>"
|
offsetxmlstr="<offset>$offset</offset>"
|
||||||
if [ -z "$jsonstr" ]; then
|
if [ -z "$jsonstr" ]; then
|
||||||
jsonstr="?offset=$offset"
|
jsonstr="?offset=$offset"
|
||||||
else
|
else
|
||||||
|
|
@ -324,7 +324,7 @@ function testlimit()
|
||||||
reply="<rpc-reply $DEFAULTNS><data><members xmlns=\"http://example.com/ns/example-social\"><member><member-id>alice</member-id><privacy-settings><post-visibility>public</post-visibility></privacy-settings><favorites>$xmllist</favorites></member></members></data></rpc-reply>]]>]]>$"
|
reply="<rpc-reply $DEFAULTNS><data><members xmlns=\"http://example.com/ns/example-social\"><member><member-id>alice</member-id><privacy-settings><post-visibility>public</post-visibility></privacy-settings><favorites>$xmllist</favorites></member></members></data></rpc-reply>]]>]]>$"
|
||||||
fi
|
fi
|
||||||
new "limit=$limit offset=$offset NETCONF get-config"
|
new "limit=$limit offset=$offset NETCONF get-config"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get-config><source><running/></source><filter type=\"xpath\" select=\"/es:members/es:member[es:member-id='alice']/es:favorites/es:uint8-numbers\" xmlns:es=\"http://example.com/ns/example-social\"/><list-pagination xmlns=\"http://clicon.org/clixon-netconf-list-pagination\">true</list-pagination>$limitxmlstr$offsetxmlstr</get-config></rpc>]]>]]>" "$reply"
|
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get-config><source><running/></source><filter type=\"xpath\" select=\"/es:members/es:member[es:member-id='alice']/es:favorites/es:uint8-numbers\" xmlns:es=\"http://example.com/ns/example-social\"/><list-pagination xmlns=\"urn:ietf:params:xml:ns:yang:ietf-list-pagination-nc\">$limitxmlstr$offsetxmlstr</list-pagination></get-config></rpc>]]>]]>" "$reply"
|
||||||
|
|
||||||
if [ -z "$list" ]; then
|
if [ -z "$list" ]; then
|
||||||
reply="<rpc-reply $DEFAULTNS><data/></rpc-reply>]]>]]>$"
|
reply="<rpc-reply $DEFAULTNS><data/></rpc-reply>]]>]]>$"
|
||||||
|
|
@ -332,24 +332,23 @@ function testlimit()
|
||||||
reply="<rpc-reply $DEFAULTNS><data><members xmlns=\"http://example.com/ns/example-social\"><member><member-id>alice</member-id><privacy-settings><post-visibility>public</post-visibility></privacy-settings><favorites>$xmllist</favorites></member></members></data></rpc-reply>]]>]]>$"
|
reply="<rpc-reply $DEFAULTNS><data><members xmlns=\"http://example.com/ns/example-social\"><member><member-id>alice</member-id><privacy-settings><post-visibility>public</post-visibility></privacy-settings><favorites>$xmllist</favorites></member></members></data></rpc-reply>]]>]]>$"
|
||||||
fi
|
fi
|
||||||
new "limit=$limit offset=$offset NETCONF get"
|
new "limit=$limit offset=$offset NETCONF get"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get><filter type=\"xpath\" select=\"/es:members/es:member[es:member-id='alice']/es:favorites/es:uint8-numbers\" xmlns:es=\"http://example.com/ns/example-social\"/><list-pagination xmlns=\"http://clicon.org/clixon-netconf-list-pagination\">true</list-pagination>$limitxmlstr$offsetxmlstr</get></rpc>]]>]]>" "$reply"
|
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get><filter type=\"xpath\" select=\"/es:members/es:member[es:member-id='alice']/es:favorites/es:uint8-numbers\" xmlns:es=\"http://example.com/ns/example-social\"/><list-pagination xmlns=\"urn:ietf:params:xml:ns:yang:ietf-list-pagination-nc\">$limitxmlstr$offsetxmlstr</list-pagination></get></rpc>]]>]]>" "$reply"
|
||||||
|
|
||||||
if [ -z "$list" ]; then
|
if [ -z "$list" ]; then
|
||||||
reply="<yang-collection xmlns=\"urn:ietf:params:xml:ns:yang:ietf-restconf-list-pagination\"/>"
|
reply="<xml-list xmlns=\"urn:ietf:params:xml:ns:yang:ietf-list-pagination\"/>"
|
||||||
else
|
else
|
||||||
reply="<yang-collection xmlns=\"urn:ietf:params:xml:ns:yang:ietf-restconf-list-pagination\">$xmllist2</yang-collection>"
|
reply="<xml-list xmlns=\"urn:ietf:params:xml:ns:yang:ietf-list-pagination\">$xmllist2</xml-list>"
|
||||||
fi
|
fi
|
||||||
new "limit=$limit offset=$offset Parameter RESTCONF xml"
|
new "limit=$limit offset=$offset Parameter RESTCONF xml"
|
||||||
expectpart "$(curl $CURLOPTS -X GET -H "Accept: application/yang-collection+xml" $RCPROTO://localhost/restconf/data/example-social:members/member=alice/favorites/uint8-numbers${jsonstr})" 0 "HTTP/$HVER 200" "Content-Type: application/yang-collection+xml" "$reply"
|
expectpart "$(curl $CURLOPTS -X GET -H "Accept: application/yang-data+xml-list" $RCPROTO://localhost/restconf/data/example-social:members/member=alice/favorites/uint8-numbers${jsonstr})" 0 "HTTP/$HVER 200" "Content-Type: application/yang-data+xml-list" "$reply"
|
||||||
|
|
||||||
if [ -z "$list" ]; then
|
if [ -z "$list" ]; then
|
||||||
reply="{\"yang-collection\":{}}"
|
# reply="{\"xml-list\":{}}"
|
||||||
|
reply="{}"
|
||||||
else
|
else
|
||||||
reply="{\"yang-collection\":{\"example-social:uint8-numbers\":\[$jsonlist\]$jsonmeta}"
|
reply="{\"example-social:uint8-numbers\":\[$jsonlist\]}"
|
||||||
fi
|
fi
|
||||||
new "limit=$limit offset=$offset Parameter RESTCONF json"
|
new "limit=$limit offset=$offset Parameter RESTCONF json"
|
||||||
expectpart "$(curl $CURLOPTS -X GET -H "Accept: application/yang-collection+json" $RCPROTO://localhost/restconf/data/example-social:members/member=alice/favorites/uint8-numbers${jsonstr})" 0 "HTTP/$HVER 200" "Content-Type: application/yang-collection+json" "$reply"
|
expectpart "$(curl $CURLOPTS -X GET -H "Accept: application/yang-data+json" $RCPROTO://localhost/restconf/data/example-social:members/member=alice/favorites/uint8-numbers${jsonstr})" 0 "HTTP/$HVER 200" "Content-Type: application/yang-data+json" "$reply" --not-- "xml-list"
|
||||||
|
|
||||||
} # testlimit
|
} # testlimit
|
||||||
|
|
||||||
new "test params: -f $cfg -s startup -- -sS $fstate"
|
new "test params: -f $cfg -s startup -- -sS $fstate"
|
||||||
|
|
@ -380,7 +379,6 @@ fi
|
||||||
new "wait restconf"
|
new "wait restconf"
|
||||||
wait_restconf
|
wait_restconf
|
||||||
|
|
||||||
|
|
||||||
new "A.3.1.1. limit=1"
|
new "A.3.1.1. limit=1"
|
||||||
testlimit 0 1 5 "17"
|
testlimit 0 1 5 "17"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -135,15 +135,15 @@ xpath="$xpath0/es:numbers"
|
||||||
testrun_start $xpath
|
testrun_start $xpath
|
||||||
|
|
||||||
new "NETCONF get leaf-list member/numbers 0-10 alice"
|
new "NETCONF get leaf-list member/numbers 0-10 alice"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get content=\"nonconfig\"><filter type=\"xpath\" select=\"$xpath\" xmlns:es=\"http://example.com/ns/example-social\"/><list-pagination xmlns=\"http://clicon.org/clixon-netconf-list-pagination\">true</list-pagination><offset xmlns=\"http://clicon.org/clixon-netconf-list-pagination\">0</offset><limit xmlns=\"http://clicon.org/clixon-netconf-list-pagination\">10</limit></get></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data><members xmlns=\"http://example.com/ns/example-social\"><member><member-id>alice</member-id><privacy-settings><post-visibility>public</post-visibility></privacy-settings><stats><numbers>3</numbers><numbers>4</numbers><numbers>5</numbers><numbers>6</numbers><numbers>7</numbers><numbers>8</numbers></stats></member></members></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get content=\"nonconfig\"><filter type=\"xpath\" select=\"$xpath\" xmlns:es=\"http://example.com/ns/example-social\"/><list-pagination xmlns=\"urn:ietf:params:xml:ns:yang:ietf-list-pagination-nc\"><offset>0</offset><limit>10</limit></list-pagination></get></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data><members xmlns=\"http://example.com/ns/example-social\"><member><member-id>alice</member-id><privacy-settings><post-visibility>public</post-visibility></privacy-settings><stats><numbers>3</numbers><numbers>4</numbers><numbers>5</numbers><numbers>6</numbers><numbers>7</numbers><numbers>8</numbers></stats></member></members></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
# negative
|
# negative
|
||||||
new "NETCONF get container, expect fail"
|
new "NETCONF get container, expect fail"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get content=\"nonconfig\"><filter type=\"xpath\" select=\"$xpath0\" xmlns:es=\"http://example.com/ns/example-social\"/><list-pagination xmlns=\"http://clicon.org/clixon-netconf-list-pagination\">true</list-pagination><offset xmlns=\"http://clicon.org/clixon-netconf-list-pagination\">0</offset><limit xmlns=\"http://clicon.org/clixon-netconf-list-pagination\">10</limit></get></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><rpc-error><error-type>application</error-type><error-tag>invalid-value</error-tag><error-severity>error</error-severity><error-message>list-pagination is enabled but target is not list or leaf-list</error-message></rpc-error></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get content=\"nonconfig\"><filter type=\"xpath\" select=\"$xpath0\" xmlns:es=\"http://example.com/ns/example-social\"/><list-pagination xmlns=\"urn:ietf:params:xml:ns:yang:ietf-list-pagination-nc\"><offset>0</offset><limit>10</limit></list-pagination></get></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><rpc-error><error-type>application</error-type><error-tag>invalid-value</error-tag><error-severity>error</error-severity><error-message>list-pagination is enabled but target is not list or leaf-list</error-message></rpc-error></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
xpath="/es:members/es:member[es:member-id='bob']/es:stats/es:numbers"
|
xpath="/es:members/es:member[es:member-id='bob']/es:stats/es:numbers"
|
||||||
new "NETCONF get leaf-list member/numbers 0-10 bob"
|
new "NETCONF get leaf-list member/numbers 0-10 bob"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get content=\"nonconfig\"><filter type=\"xpath\" select=\"$xpath\" xmlns:es=\"http://example.com/ns/example-social\"/><list-pagination xmlns=\"http://clicon.org/clixon-netconf-list-pagination\">true</list-pagination><offset xmlns=\"http://clicon.org/clixon-netconf-list-pagination\">0</offset><limit xmlns=\"http://clicon.org/clixon-netconf-list-pagination\">10</limit></get></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data><members xmlns=\"http://example.com/ns/example-social\"><member><member-id>bob</member-id><privacy-settings><post-visibility>public</post-visibility></privacy-settings><stats><numbers>13</numbers><numbers>14</numbers><numbers>15</numbers><numbers>16</numbers><numbers>17</numbers><numbers>18</numbers></stats></member></members></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get content=\"nonconfig\"><filter type=\"xpath\" select=\"$xpath\" xmlns:es=\"http://example.com/ns/example-social\"/><list-pagination xmlns=\"urn:ietf:params:xml:ns:yang:ietf-list-pagination-nc\"><offset>0</offset><limit>10</limit></list-pagination></get></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data><members xmlns=\"http://example.com/ns/example-social\"><member><member-id>bob</member-id><privacy-settings><post-visibility>public</post-visibility></privacy-settings><stats><numbers>13</numbers><numbers>14</numbers><numbers>15</numbers><numbers>16</numbers><numbers>17</numbers><numbers>18</numbers></stats></member></members></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
testrun_stop
|
testrun_stop
|
||||||
|
|
||||||
|
|
@ -152,7 +152,7 @@ xpath="/es:members/es:member/es:stats/es:numbers"
|
||||||
testrun_start $xpath
|
testrun_start $xpath
|
||||||
|
|
||||||
new "NETCONF get leaf-list member/numbers all"
|
new "NETCONF get leaf-list member/numbers all"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get content=\"nonconfig\"><filter type=\"xpath\" select=\"$xpath\" xmlns:es=\"http://example.com/ns/example-social\"/><list-pagination xmlns=\"http://clicon.org/clixon-netconf-list-pagination\">true</list-pagination><offset xmlns=\"http://clicon.org/clixon-netconf-list-pagination\">0</offset><limit xmlns=\"http://clicon.org/clixon-netconf-list-pagination\">10</limit></get></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data><members xmlns=\"http://example.com/ns/example-social\"><member><member-id>alice</member-id><privacy-settings><post-visibility>public</post-visibility></privacy-settings><stats><numbers>3</numbers><numbers>4</numbers><numbers>5</numbers><numbers>6</numbers><numbers>7</numbers><numbers>8</numbers></stats></member><member><member-id>bob</member-id><privacy-settings><post-visibility>public</post-visibility></privacy-settings><stats><numbers>13</numbers><numbers>14</numbers><numbers>15</numbers><numbers>16</numbers></stats></member></members></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get content=\"nonconfig\"><filter type=\"xpath\" select=\"$xpath\" xmlns:es=\"http://example.com/ns/example-social\"/><list-pagination xmlns=\"urn:ietf:params:xml:ns:yang:ietf-list-pagination-nc\"><offset>0</offset><limit>10</limit></list-pagination></get></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data><members xmlns=\"http://example.com/ns/example-social\"><member><member-id>alice</member-id><privacy-settings><post-visibility>public</post-visibility></privacy-settings><stats><numbers>3</numbers><numbers>4</numbers><numbers>5</numbers><numbers>6</numbers><numbers>7</numbers><numbers>8</numbers></stats></member><member><member-id>bob</member-id><privacy-settings><post-visibility>public</post-visibility></privacy-settings><stats><numbers>13</numbers><numbers>14</numbers><numbers>15</numbers><numbers>16</numbers></stats></member></members></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
testrun_stop
|
testrun_stop
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,6 @@ YANGSPECS += clixon-lib@2021-03-08.yang # 5.1
|
||||||
YANGSPECS += clixon-rfc5277@2008-07-01.yang
|
YANGSPECS += clixon-rfc5277@2008-07-01.yang
|
||||||
YANGSPECS += clixon-xml-changelog@2019-03-21.yang
|
YANGSPECS += clixon-xml-changelog@2019-03-21.yang
|
||||||
YANGSPECS += clixon-restconf@2021-05-20.yang # 5.2
|
YANGSPECS += clixon-restconf@2021-05-20.yang # 5.2
|
||||||
YANGSPECS += clixon-netconf-list-pagination@2021-08-27.yang
|
|
||||||
|
|
||||||
APPNAME = clixon # subdir ehere these files are installed
|
APPNAME = clixon # subdir ehere these files are installed
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,182 +0,0 @@
|
||||||
module clixon-netconf-list-pagination {
|
|
||||||
yang-version 1.1;
|
|
||||||
namespace "http://clicon.org/clixon-netconf-list-pagination";
|
|
||||||
prefix cp;
|
|
||||||
|
|
||||||
import ietf-yang-types {
|
|
||||||
prefix yang;
|
|
||||||
reference
|
|
||||||
"RFC 6991: Common YANG Data Types";
|
|
||||||
}
|
|
||||||
import ietf-yang-metadata {
|
|
||||||
prefix "md";
|
|
||||||
reference
|
|
||||||
"RFC 7952: Defining and Using Metadata with YANG";
|
|
||||||
}
|
|
||||||
import ietf-netconf {
|
|
||||||
prefix nc;
|
|
||||||
reference
|
|
||||||
"RFC 6241: Network Configuration Protocol (NETCONF)";
|
|
||||||
}
|
|
||||||
|
|
||||||
organization
|
|
||||||
"IETF NETCONF (Network Configuration) Working Group";
|
|
||||||
contact
|
|
||||||
"WG Web: <http://tools.ietf.org/wg/netconf/>
|
|
||||||
WG List: <mailto:netconf@ietf.org>
|
|
||||||
|
|
||||||
Editor:
|
|
||||||
|
|
||||||
Editor:
|
|
||||||
|
|
||||||
Editor: ";
|
|
||||||
description
|
|
||||||
"This module define a new operation -- <get-collection>
|
|
||||||
to support YANG based pagination.
|
|
||||||
|
|
||||||
The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL', 'SHALL
|
|
||||||
NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED', 'NOT RECOMMENDED',
|
|
||||||
'MAY', and 'OPTIONAL' in this document are to be interpreted as
|
|
||||||
described in BCP 14 (RFC 2119) (RFC 8174) when, and only when,
|
|
||||||
they appear in all capitals, as shown here.
|
|
||||||
|
|
||||||
Copyright (c) 2019 IETF Trust and the persons identified as
|
|
||||||
authors of the code. All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or
|
|
||||||
without modification, is permitted pursuant to, and subject to
|
|
||||||
the license terms contained in, the Simplified BSD License set
|
|
||||||
forth in Section 4.c of the IETF Trust's Legal Provisions
|
|
||||||
Relating to IETF Documents
|
|
||||||
(https://trustee.ietf.org/license-info).
|
|
||||||
|
|
||||||
This version of this YANG module is part of RFC 8526; see
|
|
||||||
the RFC itself for full legal notices.
|
|
||||||
|
|
||||||
Clixon:
|
|
||||||
- changed get-pagable -> get-pageable
|
|
||||||
- renamed count -> limit
|
|
||||||
- renamed skip -> offset
|
|
||||||
- added import ietf-yang-metadata
|
|
||||||
- added md:annotation remaining
|
|
||||||
";
|
|
||||||
revision 2021-08-27 {
|
|
||||||
description
|
|
||||||
"Dervied from ietf-netconf-list-pagination@2020-10-30.";
|
|
||||||
reference
|
|
||||||
"RFC XXXX: YANG Based Pagination.";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Annotations
|
|
||||||
md:annotation remaining {
|
|
||||||
type uint32;
|
|
||||||
description
|
|
||||||
"This annotation contains the number of elements removed
|
|
||||||
from a result set after a 'limit' or 'sublist-limit'
|
|
||||||
operation. If no elements were removed, this annotation
|
|
||||||
MUST NOT appear. The minimum value (0), which never
|
|
||||||
occurs in normal operation, is reserved to represent
|
|
||||||
'unknown'. The maximum value (2^32-1) is reserved to
|
|
||||||
represent any value greater than or equal to 2^32-1
|
|
||||||
elements.";
|
|
||||||
}
|
|
||||||
grouping pagination-parameters {
|
|
||||||
leaf list-pagination {
|
|
||||||
type boolean;
|
|
||||||
default false;
|
|
||||||
description
|
|
||||||
"NETCONF get / get-config needs some way to know that this is a pagination
|
|
||||||
request, in which case the target is a list/leaf-list and the elements below
|
|
||||||
(limit/offset/...) are valid.
|
|
||||||
RESTCONF list pagination has a specific media-type for this purpose.
|
|
||||||
This is an experimental proposal to make this property explicit.
|
|
||||||
Possibly there is a better way (annotation?) to signal that this is in fact a
|
|
||||||
list pagination request.
|
|
||||||
It is also possible to determine this using heurestics (ie a 'limit' property exixts),
|
|
||||||
but it seems not 100% deterministic.";
|
|
||||||
}
|
|
||||||
leaf limit {
|
|
||||||
type union {
|
|
||||||
type uint32;
|
|
||||||
type string {
|
|
||||||
pattern 'unbounded';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default "unbounded";
|
|
||||||
description
|
|
||||||
"The maximum number of list entries to return. The
|
|
||||||
value of the 'limit' parameter is either an integer
|
|
||||||
greater than or equal to 1, or the string 'unbounded'.
|
|
||||||
The string 'unbounded' is the default value.";
|
|
||||||
}
|
|
||||||
leaf offset {
|
|
||||||
type union {
|
|
||||||
type uint32;
|
|
||||||
type string {
|
|
||||||
pattern 'none';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default "none";
|
|
||||||
description
|
|
||||||
"The first list item to return.
|
|
||||||
the 'offset' parameter is either an integer greater than
|
|
||||||
or equal to 1, or the string 'unbounded'. The string
|
|
||||||
'none' is the default value.";
|
|
||||||
}
|
|
||||||
leaf direction {
|
|
||||||
type enumeration {
|
|
||||||
enum forward;
|
|
||||||
enum reverse;
|
|
||||||
}
|
|
||||||
default "forward";
|
|
||||||
description
|
|
||||||
"Direction relative to the 'sort' order through list
|
|
||||||
or leaf-list. It can be forward direction or reverse
|
|
||||||
direction.";
|
|
||||||
}
|
|
||||||
leaf sort {
|
|
||||||
type union {
|
|
||||||
type string {
|
|
||||||
length "1..max" {
|
|
||||||
description
|
|
||||||
"The name of a descendent node to sort on. For
|
|
||||||
'Config false' lists and leaf-lists, the node SHOULD
|
|
||||||
have the 'TBD' extension indicating that it has been
|
|
||||||
indexed, enabling efficient sorts.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
type enumeration {
|
|
||||||
enum default {
|
|
||||||
description
|
|
||||||
"Indicates that the 'default' order is assumed. For
|
|
||||||
'ordered-by user' lists and leaf-lists, the default order
|
|
||||||
is the user-configured order. For 'ordered-by system'
|
|
||||||
lists and leaf-lists, the default order is specified by the
|
|
||||||
system.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default "default";
|
|
||||||
description
|
|
||||||
"Indicates how the entries in a list are to be sorted.";
|
|
||||||
}
|
|
||||||
leaf where {
|
|
||||||
type yang:xpath1.0;
|
|
||||||
description
|
|
||||||
"The boolean filter to select data instances to return from
|
|
||||||
the list or leaf-list target. The Xpath expression MAY be
|
|
||||||
constrained either server-wide, by datastore, by 'config'
|
|
||||||
status, or per list or leaf-list. Details regarding how
|
|
||||||
constraints are communicated are TBD. This parameter
|
|
||||||
is optional; no filtering is applied when it is not
|
|
||||||
specified.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
augment /nc:get-config/nc:input {
|
|
||||||
uses pagination-parameters;
|
|
||||||
}
|
|
||||||
// extending the get operation
|
|
||||||
augment /nc:get/nc:input {
|
|
||||||
uses pagination-parameters;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -53,10 +53,18 @@ YANGSPECS += ietf-datastores@2018-02-14.yang
|
||||||
YANGSPECS += ietf-yang-patch@2017-02-22.yang
|
YANGSPECS += ietf-yang-patch@2017-02-22.yang
|
||||||
# For remaining attribute in list-pagination:
|
# For remaining attribute in list-pagination:
|
||||||
YANGSPECS += ietf-yang-metadata@2016-08-05.yang
|
YANGSPECS += ietf-yang-metadata@2016-08-05.yang
|
||||||
# in draft-wwlh-netconf-list-pagination:
|
# XXX brings in NACM which breaks tests
|
||||||
YANGSPECS += ietf-netconf-list-pagination@2020-10-30.yang
|
# YANGSPECS += ietf-system-capabilities@2021-04-02.yang
|
||||||
# in draft-wwlh-netconf-list-pagination-rc:
|
# For remaining attribute in list-pagination-nc:
|
||||||
YANGSPECS += ietf-restconf-list-pagination@2015-01-30.yang
|
YANGSPECS += ietf-netconf-nmda@2019-01-07.yang
|
||||||
|
# For remaining attribute in ietf-netconf-nmda
|
||||||
|
YANGSPECS += ietf-origin@2018-02-14.yang
|
||||||
|
YANGSPECS += ietf-netconf-with-defaults@2011-06-01.yang
|
||||||
|
|
||||||
|
# in draft-wwlh-netconf-list-pagination-00.txt
|
||||||
|
YANGSPECS += ietf-list-pagination@2021-10-25.yang
|
||||||
|
# in draft-wwlh-netconf-list-pagination-nc-02.txt
|
||||||
|
YANGSPECS += ietf-list-pagination-nc@2021-10-25.yang
|
||||||
|
|
||||||
all:
|
all:
|
||||||
|
|
||||||
|
|
|
||||||
101
yang/mandatory/ietf-list-pagination-nc@2021-10-25.yang
Normal file
101
yang/mandatory/ietf-list-pagination-nc@2021-10-25.yang
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
module ietf-list-pagination-nc {
|
||||||
|
yang-version 1.1;
|
||||||
|
namespace "urn:ietf:params:xml:ns:yang:ietf-list-pagination-nc";
|
||||||
|
prefix lpgnc;
|
||||||
|
|
||||||
|
import ietf-netconf {
|
||||||
|
prefix nc;
|
||||||
|
reference
|
||||||
|
"RFC 6241: Network Configuration Protocol (NETCONF)";
|
||||||
|
}
|
||||||
|
|
||||||
|
import ietf-netconf-nmda {
|
||||||
|
prefix ncds;
|
||||||
|
reference
|
||||||
|
"RFC 8526: NETCONF Extensions to Support the
|
||||||
|
Network Management Datastore Architecture";
|
||||||
|
}
|
||||||
|
|
||||||
|
import ietf-list-pagination {
|
||||||
|
prefix lp;
|
||||||
|
reference
|
||||||
|
"RFC XXXX: List Pagination for YANG-driven Protocols";
|
||||||
|
}
|
||||||
|
|
||||||
|
organization
|
||||||
|
"IETF NETCONF (Network Configuration) Working Group";
|
||||||
|
|
||||||
|
contact
|
||||||
|
"WG Web: <http://tools.ietf.org/wg/netconf/>
|
||||||
|
WG List: <mailto:netconf@ietf.org>";
|
||||||
|
|
||||||
|
description
|
||||||
|
"This module augments the <get>, <get-config>, and <get-data>
|
||||||
|
'rpc' statements to support list pagination.
|
||||||
|
|
||||||
|
Copyright (c) 2021 IETF Trust and the persons identified
|
||||||
|
as authors of the code. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with
|
||||||
|
or without modification, is permitted pursuant to, and
|
||||||
|
subject to the license terms contained in, the Simplified
|
||||||
|
BSD License set forth in Section 4.c of the IETF Trust's
|
||||||
|
Legal Provisions Relating to IETF Documents
|
||||||
|
(https://trustee.ietf.org/license-info).
|
||||||
|
|
||||||
|
This version of this YANG module is part of RFC XXXX
|
||||||
|
(https://www.rfc-editor.org/info/rfcXXXX); see the RFC
|
||||||
|
itself for full legal notices.
|
||||||
|
|
||||||
|
The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL',
|
||||||
|
'SHALL NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED',
|
||||||
|
'NOT RECOMMENDED', 'MAY', and 'OPTIONAL' in this document
|
||||||
|
are to be interpreted as described in BCP 14 (RFC 2119)
|
||||||
|
(RFC 8174) when, and only when, they appear in all
|
||||||
|
capitals, as shown here.";
|
||||||
|
|
||||||
|
revision 2021-10-25 {
|
||||||
|
description
|
||||||
|
"Initial revision.";
|
||||||
|
reference
|
||||||
|
"RFC XXXX: NETCONF Extensions to Support List Pagination";
|
||||||
|
}
|
||||||
|
|
||||||
|
grouping pagination-parameters {
|
||||||
|
description "A grouping for list pagination parameters.";
|
||||||
|
container list-pagination {
|
||||||
|
description "List pagination parameters.";
|
||||||
|
presence "Flag that request contains pagination parameters";
|
||||||
|
uses lp:where-param-grouping;
|
||||||
|
uses lp:sort-by-param-grouping;
|
||||||
|
uses lp:direction-param-grouping;
|
||||||
|
uses lp:offset-param-grouping;
|
||||||
|
uses lp:limit-param-grouping;
|
||||||
|
uses lp:sublist-limit-param-grouping;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
augment "/nc:get/nc:input" {
|
||||||
|
description
|
||||||
|
"Allow the 'get' operation to use content filter
|
||||||
|
parameter for specifying the YANG list or leaf-list
|
||||||
|
that is to be retrieved";
|
||||||
|
uses pagination-parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
augment "/nc:get-config/nc:input" {
|
||||||
|
description
|
||||||
|
"Allow the 'get-config' operation to use content filter
|
||||||
|
parameter for specifying the YANG list or leaf-list
|
||||||
|
that is to be retrieved";
|
||||||
|
uses pagination-parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
augment "/ncds:get-data/ncds:input" {
|
||||||
|
description
|
||||||
|
"Allow the 'get-data' operation to use content filter
|
||||||
|
parameter for specifying the YANG list or leaf-list
|
||||||
|
that is to be retrieved";
|
||||||
|
uses pagination-parameters;
|
||||||
|
}
|
||||||
|
}
|
||||||
299
yang/mandatory/ietf-list-pagination@2021-10-25.yang
Normal file
299
yang/mandatory/ietf-list-pagination@2021-10-25.yang
Normal file
|
|
@ -0,0 +1,299 @@
|
||||||
|
module ietf-list-pagination {
|
||||||
|
yang-version 1.1;
|
||||||
|
namespace
|
||||||
|
"urn:ietf:params:xml:ns:yang:ietf-list-pagination";
|
||||||
|
prefix lpg;
|
||||||
|
|
||||||
|
import ietf-yang-types {
|
||||||
|
prefix yang;
|
||||||
|
reference
|
||||||
|
"RFC 6991: Common YANG Data Types";
|
||||||
|
}
|
||||||
|
|
||||||
|
import ietf-yang-metadata {
|
||||||
|
prefix md;
|
||||||
|
reference
|
||||||
|
"RFC 7952: Defining and Using Metadata with YANG";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX system-capabilities brings in NACM that breaks clixon testing
|
||||||
|
import ietf-system-capabilities {
|
||||||
|
prefix sysc;
|
||||||
|
reference
|
||||||
|
"draft-ietf-netconf-notification-capabilities:
|
||||||
|
YANG Modules describing Capabilities for
|
||||||
|
Systems and Datastore Update Notifications";
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
organization
|
||||||
|
"IETF NETCONF (Network Configuration) Working Group";
|
||||||
|
|
||||||
|
contact
|
||||||
|
"WG Web: <http://tools.ietf.org/wg/netconf/>
|
||||||
|
WG List: <mailto:netconf@ietf.org>";
|
||||||
|
|
||||||
|
description
|
||||||
|
"This module is used by servers to 1) indicate they support
|
||||||
|
pagination on 'list' and 'leaf-list' resources, 2) define a
|
||||||
|
grouping for each list-pagination parameter, and 3) indicate
|
||||||
|
which 'config false' lists have constrained 'where' and
|
||||||
|
'sort-by' parameters and how they may be used, if at all.
|
||||||
|
|
||||||
|
Copyright (c) 2021 IETF Trust and the persons identified
|
||||||
|
as authors of the code. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with
|
||||||
|
or without modification, is permitted pursuant to, and
|
||||||
|
subject to the license terms contained in, the Simplified
|
||||||
|
BSD License set forth in Section 4.c of the IETF Trust's
|
||||||
|
Legal Provisions Relating to IETF Documents
|
||||||
|
(https://trustee.ietf.org/license-info).
|
||||||
|
|
||||||
|
This version of this YANG module is part of RFC XXXX
|
||||||
|
(https://www.rfc-editor.org/info/rfcXXXX); see the RFC
|
||||||
|
itself for full legal notices.
|
||||||
|
|
||||||
|
The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL',
|
||||||
|
'SHALL NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED',
|
||||||
|
'NOT RECOMMENDED', 'MAY', and 'OPTIONAL' in this document
|
||||||
|
are to be interpreted as described in BCP 14 (RFC 2119)
|
||||||
|
(RFC 8174) when, and only when, they appear in all
|
||||||
|
capitals, as shown here.";
|
||||||
|
|
||||||
|
revision 2021-10-25 {
|
||||||
|
description
|
||||||
|
"Initial revision.";
|
||||||
|
reference
|
||||||
|
"RFC XXXX: List Pagination for YANG-driven Protocols";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Annotations
|
||||||
|
|
||||||
|
md:annotation remaining {
|
||||||
|
type union {
|
||||||
|
type uint32;
|
||||||
|
type enumeration {
|
||||||
|
enum "unknown" {
|
||||||
|
description
|
||||||
|
"Indicates that number of remaining entries is unknown
|
||||||
|
to the server in case, e.g., the server has determined
|
||||||
|
that counting would be prohibitively expensive.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
description
|
||||||
|
"This annotation contains the number of elements not included
|
||||||
|
in the result set (a positive value) due to a 'limit' or
|
||||||
|
'sublist-limit' operation. If no elements were removed,
|
||||||
|
this annotation MUST NOT appear. The minimum value (0),
|
||||||
|
which never occurs in normal operation, is reserved to
|
||||||
|
represent 'unknown'. The maximum value (2^32-1) is
|
||||||
|
reserved to represent any value greater than or equal
|
||||||
|
to 2^32-1 elements.";
|
||||||
|
}
|
||||||
|
// Identities
|
||||||
|
|
||||||
|
identity list-pagination-error {
|
||||||
|
description
|
||||||
|
"Base identity for list-pagination errors.";
|
||||||
|
}
|
||||||
|
|
||||||
|
identity offset-out-of-range {
|
||||||
|
base list-pagination-error;
|
||||||
|
description
|
||||||
|
"The 'offset' query parameter value is greater than the number
|
||||||
|
of instances in the target list or leaf-list resource.";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Groupings
|
||||||
|
|
||||||
|
grouping where-param-grouping {
|
||||||
|
description
|
||||||
|
"This grouping may be used by protocol-specific YANG modules
|
||||||
|
to define a protocol-specific query parameter.";
|
||||||
|
leaf where {
|
||||||
|
type union {
|
||||||
|
type yang:xpath1.0;
|
||||||
|
type enumeration {
|
||||||
|
enum "unfiltered" {
|
||||||
|
description
|
||||||
|
"Indicates that no entries are to be filtered
|
||||||
|
from the working result-set.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default "unfiltered";
|
||||||
|
description
|
||||||
|
"The 'where' parameter specifies a boolean expression
|
||||||
|
that result-set entries must match.
|
||||||
|
|
||||||
|
It is an error if the XPath expression references a node
|
||||||
|
identifier that does not exist in the schema, is optional
|
||||||
|
or conditional in the schema or, for constrained 'config
|
||||||
|
false' lists and leaf-lists, if the node identifier does
|
||||||
|
not point to a node having the 'indexed' extension
|
||||||
|
statement applied to it (see RFC XXXX).";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
grouping sort-by-param-grouping {
|
||||||
|
description
|
||||||
|
"This grouping may be used by protocol-specific YANG modules
|
||||||
|
to define a protocol-specific query parameter.";
|
||||||
|
leaf sort-by {
|
||||||
|
type union {
|
||||||
|
type string {
|
||||||
|
// An RFC 7950 'descendant-schema-nodeid'.
|
||||||
|
pattern '([0-9a-fA-F]*:)?[0-9a-fA-F]*'
|
||||||
|
+ '(/([0-9a-fA-F]*:)?[0-9a-fA-F]*)*';
|
||||||
|
}
|
||||||
|
type enumeration {
|
||||||
|
enum "none" {
|
||||||
|
description
|
||||||
|
"Indicates that the list or leaf-list's default
|
||||||
|
order is to be used, per the YANG 'ordered-by'
|
||||||
|
statement.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default "none";
|
||||||
|
description
|
||||||
|
"The 'sort-by' parameter indicates the node in the
|
||||||
|
working result-set (i.e., after the 'where' parameter
|
||||||
|
has been applied) that entries should be sorted by.
|
||||||
|
|
||||||
|
Sorts are in ascending order (e.g., '1' before '9',
|
||||||
|
'a' before 'z', etc.). Missing values are sorted to
|
||||||
|
the end (e.g., after all nodes having values).";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
grouping direction-param-grouping {
|
||||||
|
description
|
||||||
|
"This grouping may be used by protocol-specific YANG modules
|
||||||
|
to define a protocol-specific query parameter.";
|
||||||
|
leaf direction {
|
||||||
|
type enumeration {
|
||||||
|
enum forwards {
|
||||||
|
description
|
||||||
|
"Indicates that entries should be traversed from
|
||||||
|
the first to last item in the working result set.";
|
||||||
|
}
|
||||||
|
enum backwards {
|
||||||
|
description
|
||||||
|
"Indicates that entries should be traversed from
|
||||||
|
the last to first item in the working result set.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default "forwards";
|
||||||
|
description
|
||||||
|
"The 'direction' parameter indicates how the entries in the
|
||||||
|
working result-set (i.e., after the 'sort-by' parameter
|
||||||
|
has been applied) should be traversed.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
grouping offset-param-grouping {
|
||||||
|
description
|
||||||
|
"This grouping may be used by protocol-specific YANG modules
|
||||||
|
to define a protocol-specific query parameter.";
|
||||||
|
leaf offset {
|
||||||
|
type uint32;
|
||||||
|
default 0;
|
||||||
|
description
|
||||||
|
"The 'offset' parameter indicates the number of entries
|
||||||
|
in the working result-set (i.e., after the 'direction'
|
||||||
|
parameter has been applied) that should be skipped over
|
||||||
|
when preparing the response.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
grouping limit-param-grouping {
|
||||||
|
description
|
||||||
|
"This grouping may be used by protocol-specific YANG modules
|
||||||
|
to define a protocol-specific query parameter.";
|
||||||
|
leaf limit {
|
||||||
|
type union {
|
||||||
|
type uint32 {
|
||||||
|
range "1..max";
|
||||||
|
}
|
||||||
|
type enumeration {
|
||||||
|
enum "unbounded" {
|
||||||
|
description
|
||||||
|
"Indicates that the number of entries that may be
|
||||||
|
returned is unbounded.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default "unbounded";
|
||||||
|
description
|
||||||
|
"The 'limit' parameter limits the number of entries returned
|
||||||
|
from the working result-set (i.e., after the 'offset'
|
||||||
|
parameter has been applied).
|
||||||
|
|
||||||
|
Any result-set that is limited includes, somewhere in its
|
||||||
|
encoding, the metadata value 'remaining' to indicate the
|
||||||
|
number entries not included in the result set.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
grouping sublist-limit-param-grouping {
|
||||||
|
description
|
||||||
|
"This grouping may be used by protocol-specific YANG modules
|
||||||
|
to define a protocol-specific query parameter.";
|
||||||
|
leaf sublist-limit {
|
||||||
|
type union {
|
||||||
|
type uint32 {
|
||||||
|
range "1..max";
|
||||||
|
}
|
||||||
|
type enumeration {
|
||||||
|
enum "unbounded" {
|
||||||
|
description
|
||||||
|
"Indicates that the number of entries that may be
|
||||||
|
returned is unbounded.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default "unbounded";
|
||||||
|
description
|
||||||
|
"The 'sublist-limit' parameter limits the number of entries
|
||||||
|
for descendent lists and leaf-lists.
|
||||||
|
|
||||||
|
Any result-set that is limited includes, somewhere in
|
||||||
|
its encoding, the metadata value 'remaining' to indicate
|
||||||
|
the number entries not included in the result set.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Protocol-accessible nodes
|
||||||
|
/* XXX system-capabilities brings in NACM that breaks clixon testing
|
||||||
|
augment // FIXME: ensure datastore == <operational>
|
||||||
|
"/sysc:system-capabilities/sysc:datastore-capabilities"
|
||||||
|
+ "/sysc:per-node-capabilities" {
|
||||||
|
description
|
||||||
|
"Defines some leafs that MAY be used by the server to
|
||||||
|
describe constraints imposed of the 'where' filters and
|
||||||
|
'sort-by' parameters used in list pagination queries.";
|
||||||
|
leaf constrained {
|
||||||
|
type empty;
|
||||||
|
description
|
||||||
|
"Indicates that 'where' filters and 'sort-by' parameters
|
||||||
|
on the targeted 'config false' list node are constrained.
|
||||||
|
If a list is not 'constrained', then full XPath 1.0
|
||||||
|
expressions may be used in 'where' filters and all node
|
||||||
|
identifiers are usable by 'sort-by'.";
|
||||||
|
}
|
||||||
|
leaf indexed {
|
||||||
|
type empty;
|
||||||
|
description
|
||||||
|
"Indicates that the targeted descendent node of a
|
||||||
|
'constrained' list (see the 'constrained' leaf) may be
|
||||||
|
used in 'where' filters and/or 'sort-by' parameters.
|
||||||
|
If a descendent node of a 'constrained' list is not
|
||||||
|
'indexed', then it MUST NOT be used in 'where' filters
|
||||||
|
or 'sort-by' parameters.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,30 @@
|
||||||
module ietf-netconf-list-pagination {
|
module ietf-netconf-nmda {
|
||||||
yang-version 1.1;
|
yang-version 1.1;
|
||||||
namespace "urn:ietf:params:xml:ns:yang:ietf-netconf-list-pagination";
|
namespace "urn:ietf:params:xml:ns:yang:ietf-netconf-nmda";
|
||||||
prefix ycoll;
|
prefix ncds;
|
||||||
|
|
||||||
|
import ietf-yang-types {
|
||||||
|
prefix yang;
|
||||||
|
reference
|
||||||
|
"RFC 6991: Common YANG Data Types";
|
||||||
|
}
|
||||||
|
import ietf-inet-types {
|
||||||
|
prefix inet;
|
||||||
|
reference
|
||||||
|
"RFC 6991: Common YANG Data Types";
|
||||||
|
}
|
||||||
|
import ietf-datastores {
|
||||||
|
prefix ds;
|
||||||
|
reference
|
||||||
|
"RFC 8342: Network Management Datastore Architecture
|
||||||
|
(NMDA)";
|
||||||
|
}
|
||||||
|
import ietf-origin {
|
||||||
|
prefix or;
|
||||||
|
reference
|
||||||
|
"RFC 8342: Network Management Datastore Architecture
|
||||||
|
(NMDA)";
|
||||||
|
}
|
||||||
import ietf-netconf {
|
import ietf-netconf {
|
||||||
prefix nc;
|
prefix nc;
|
||||||
reference
|
reference
|
||||||
|
|
@ -13,43 +35,32 @@ module ietf-netconf-list-pagination {
|
||||||
reference
|
reference
|
||||||
"RFC 6243: With-defaults Capability for NETCONF";
|
"RFC 6243: With-defaults Capability for NETCONF";
|
||||||
}
|
}
|
||||||
import ietf-yang-types {
|
|
||||||
prefix yang;
|
|
||||||
reference
|
|
||||||
"RFC 6991: Common YANG Data Types";
|
|
||||||
}
|
|
||||||
import ietf-datastores {
|
|
||||||
prefix ds;
|
|
||||||
reference
|
|
||||||
"RFC 8342: Network Management Datastore Architecture
|
|
||||||
(NMDA)";
|
|
||||||
}
|
|
||||||
import ietf-origin {
|
|
||||||
prefix or;
|
|
||||||
reference
|
|
||||||
"RFC 8342: Network Management Datastore Architecture
|
|
||||||
(NMDA)";
|
|
||||||
}
|
|
||||||
import ietf-yang-metadata {
|
|
||||||
prefix "md";
|
|
||||||
reference
|
|
||||||
"RFC 7952: Defining and Using Metadata with YANG";
|
|
||||||
}
|
|
||||||
|
|
||||||
organization
|
organization
|
||||||
"IETF NETCONF (Network Configuration) Working Group";
|
"IETF NETCONF Working Group";
|
||||||
|
|
||||||
contact
|
contact
|
||||||
"WG Web: <http://tools.ietf.org/wg/netconf/>
|
"WG Web: <https://datatracker.ietf.org/wg/netconf/>
|
||||||
|
|
||||||
WG List: <mailto:netconf@ietf.org>
|
WG List: <mailto:netconf@ietf.org>
|
||||||
|
|
||||||
Editor:
|
Author: Martin Bjorklund
|
||||||
|
<mailto:mbj@tail-f.com>
|
||||||
|
|
||||||
Editor:
|
Author: Juergen Schoenwaelder
|
||||||
|
<mailto:j.schoenwaelder@jacobs-university.de>
|
||||||
|
|
||||||
Editor: ";
|
Author: Phil Shafer
|
||||||
|
<mailto:phil@juniper.net>
|
||||||
|
|
||||||
|
Author: Kent Watsen
|
||||||
|
<mailto:kent+ietf@watsen.net>
|
||||||
|
|
||||||
|
Author: Robert Wilton
|
||||||
|
<mailto:rwilton@cisco.com>";
|
||||||
description
|
description
|
||||||
"This module define a new operation -- <get-collection>
|
"This YANG module defines a set of NETCONF operations to support
|
||||||
to support YANG based pagination.
|
the Network Management Datastore Architecture (NMDA).
|
||||||
|
|
||||||
The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL', 'SHALL
|
The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL', 'SHALL
|
||||||
NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED', 'NOT RECOMMENDED',
|
NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED', 'NOT RECOMMENDED',
|
||||||
|
|
@ -68,20 +79,14 @@ module ietf-netconf-list-pagination {
|
||||||
(https://trustee.ietf.org/license-info).
|
(https://trustee.ietf.org/license-info).
|
||||||
|
|
||||||
This version of this YANG module is part of RFC 8526; see
|
This version of this YANG module is part of RFC 8526; see
|
||||||
the RFC itself for full legal notices.
|
the RFC itself for full legal notices.";
|
||||||
|
|
||||||
Clixon:
|
revision 2019-01-07 {
|
||||||
- changed get-pagable -> get-pageable
|
|
||||||
- renamed count -> limit
|
|
||||||
- renamed skip -> offset
|
|
||||||
- added import ietf-yang-metadata
|
|
||||||
- added md:annotation remaining
|
|
||||||
";
|
|
||||||
revision 2020-10-30 {
|
|
||||||
description
|
description
|
||||||
"Initial revision.";
|
"Initial revision.";
|
||||||
reference
|
reference
|
||||||
"RFC XXXX: YANG Based Pagination.";
|
"RFC 8526: NETCONF Extensions to Support the Network Management
|
||||||
|
Datastore Architecture";
|
||||||
}
|
}
|
||||||
|
|
||||||
feature origin {
|
feature origin {
|
||||||
|
|
@ -100,28 +105,14 @@ module ietf-netconf-list-pagination {
|
||||||
reference
|
reference
|
||||||
"RFC 6243: With-defaults Capability for NETCONF, Section 4; and
|
"RFC 6243: With-defaults Capability for NETCONF, Section 4; and
|
||||||
RFC 8526: NETCONF Extensions to Support the Network Management
|
RFC 8526: NETCONF Extensions to Support the Network Management
|
||||||
Datastore Architecture, Section 3.1.1.2";
|
Datastore Architecture, Section 3.1.1.2";
|
||||||
}
|
|
||||||
// Annotations
|
|
||||||
md:annotation remaining {
|
|
||||||
type uint32;
|
|
||||||
description
|
|
||||||
"This annotation contains the number of elements removed
|
|
||||||
from a result set after a 'limit' or 'sublist-limit'
|
|
||||||
operation. If no elements were removed, this annotation
|
|
||||||
MUST NOT appear. The minimum value (0), which never
|
|
||||||
occurs in normal operation, is reserved to represent
|
|
||||||
'unknown'. The maximum value (2^32-1) is reserved to
|
|
||||||
represent any value greater than or equal to 2^32-1
|
|
||||||
elements.";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rpc get-pageable-list {
|
rpc get-data {
|
||||||
description
|
description
|
||||||
"Use enhanced filtering features to retrieve data from a
|
"Retrieve data from an NMDA datastore. The content returned
|
||||||
specific NMDA datastore. The content returned by get-data
|
by get-data must satisfy all filters, i.e., the filter
|
||||||
must satisfy all filters, i.e., the filter criteria are
|
criteria are logically ANDed.
|
||||||
logically ANDed.
|
|
||||||
|
|
||||||
Any ancestor nodes (including list keys) of nodes selected by
|
Any ancestor nodes (including list keys) of nodes selected by
|
||||||
the filters are included in the response.
|
the filters are included in the response.
|
||||||
|
|
@ -142,11 +133,12 @@ module ietf-netconf-list-pagination {
|
||||||
leaf datastore {
|
leaf datastore {
|
||||||
type ds:datastore-ref;
|
type ds:datastore-ref;
|
||||||
mandatory true;
|
mandatory true;
|
||||||
|
|
||||||
description
|
description
|
||||||
"Datastore from which to retrieve data.
|
"Datastore from which to retrieve data.
|
||||||
|
|
||||||
If the datastore is not supported by the server, then
|
If the datastore is not supported by the server, then the
|
||||||
the server MUST return an <rpc-error> element with an
|
server MUST return an <rpc-error> element with an
|
||||||
<error-tag> value of 'invalid-value'.";
|
<error-tag> value of 'invalid-value'.";
|
||||||
}
|
}
|
||||||
choice filter-spec {
|
choice filter-spec {
|
||||||
|
|
@ -209,6 +201,7 @@ module ietf-netconf-list-pagination {
|
||||||
System state nodes are not affected by origin-filters and
|
System state nodes are not affected by origin-filters and
|
||||||
thus not filtered. Note that system state nodes can be
|
thus not filtered. Note that system state nodes can be
|
||||||
filtered with the 'config-filter' leaf.";
|
filtered with the 'config-filter' leaf.";
|
||||||
|
|
||||||
leaf-list origin-filter {
|
leaf-list origin-filter {
|
||||||
type or:origin-ref;
|
type or:origin-ref;
|
||||||
description
|
description
|
||||||
|
|
@ -257,98 +250,138 @@ module ietf-netconf-list-pagination {
|
||||||
uses ncwd:with-defaults-parameters {
|
uses ncwd:with-defaults-parameters {
|
||||||
if-feature "with-defaults";
|
if-feature "with-defaults";
|
||||||
}
|
}
|
||||||
leaf list-target {
|
|
||||||
description
|
|
||||||
"Identifies the list object that is being retrieved.
|
|
||||||
This must be a path expression used to represent
|
|
||||||
a list data node or leaf-list data node. ";
|
|
||||||
mandatory true;
|
|
||||||
type string;
|
|
||||||
}
|
|
||||||
leaf limit {
|
|
||||||
type union {
|
|
||||||
type uint32;
|
|
||||||
type string {
|
|
||||||
pattern 'unbounded';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default "unbounded";
|
|
||||||
description
|
|
||||||
"The maximum number of list entries to return. The
|
|
||||||
value of the 'count' parameter is either an integer
|
|
||||||
greater than or equal to 1, or the string 'unbounded'.
|
|
||||||
The string 'unbounded' is the default value.";
|
|
||||||
}
|
|
||||||
leaf offset {
|
|
||||||
type union {
|
|
||||||
type uint32;
|
|
||||||
type string {
|
|
||||||
pattern 'none';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default "none";
|
|
||||||
description
|
|
||||||
"The first list item to return.
|
|
||||||
the 'skip' parameter is either an integer greater than
|
|
||||||
or equal to 1, or the string 'unbounded'. The string
|
|
||||||
'unbounded' is the default value.";
|
|
||||||
}
|
|
||||||
leaf direction {
|
|
||||||
type enumeration {
|
|
||||||
enum forward;
|
|
||||||
enum reverse;
|
|
||||||
}
|
|
||||||
default "forward";
|
|
||||||
description
|
|
||||||
"Direction relative to the 'sort' order through list
|
|
||||||
or leaf-list. It can be forward direction or reverse
|
|
||||||
direction.";
|
|
||||||
}
|
|
||||||
leaf sort {
|
|
||||||
type union {
|
|
||||||
type string {
|
|
||||||
length "1..max" {
|
|
||||||
description
|
|
||||||
"The name of a descendent node to sort on. For
|
|
||||||
'Config false' lists and leaf-lists, the node SHOULD
|
|
||||||
have the 'TBD' extension indicating that it has been
|
|
||||||
indexed, enabling efficient sorts.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
type enumeration {
|
|
||||||
enum default {
|
|
||||||
description
|
|
||||||
"Indicates that the 'default' order is assumed. For
|
|
||||||
'ordered-by user' lists and leaf-lists, the default order
|
|
||||||
is the user-configured order. For 'ordered-by system'
|
|
||||||
lists and leaf-lists, the default order is specified by the
|
|
||||||
system.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default "default";
|
|
||||||
description
|
|
||||||
"Indicates how the entries in a list are to be sorted.";
|
|
||||||
}
|
|
||||||
leaf where {
|
|
||||||
type yang:xpath1.0;
|
|
||||||
description
|
|
||||||
"The boolean filter to select data instances to return from
|
|
||||||
the list or leaf-list target. The Xpath expression MAY be
|
|
||||||
constrained either server-wide, by datastore, by 'config'
|
|
||||||
status, or per list or leaf-list. Details regarding how
|
|
||||||
constraints are communicated are TBD. This parameter
|
|
||||||
is optional; no filtering is applied when it is not
|
|
||||||
specified.";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
output {
|
output {
|
||||||
anyxml pageable-list {
|
anydata data {
|
||||||
description
|
description
|
||||||
"Return the list entries that were requested and matched
|
"Copy of the source datastore subset that matched
|
||||||
the filter criteria (if any). An empty data container
|
the filter criteria (if any). An empty data
|
||||||
indicates that the request did not produce any results.";
|
container indicates that the request did not
|
||||||
|
produce any results.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpc edit-data {
|
||||||
|
description
|
||||||
|
"Edit data in an NMDA datastore.
|
||||||
|
|
||||||
|
If an error condition occurs such that an error severity
|
||||||
|
<rpc-error> element is generated, the server will stop
|
||||||
|
processing the <edit-data> operation and restore the
|
||||||
|
specified configuration to its complete state at
|
||||||
|
the start of this <edit-data> operation.";
|
||||||
|
input {
|
||||||
|
leaf datastore {
|
||||||
|
type ds:datastore-ref;
|
||||||
|
mandatory true;
|
||||||
|
|
||||||
|
description
|
||||||
|
"Datastore that is the target of the <edit-data> operation.
|
||||||
|
|
||||||
|
If the target datastore is not writable, or is not
|
||||||
|
supported by the server, then the server MUST return an
|
||||||
|
<rpc-error> element with an <error-tag> value of
|
||||||
|
'invalid-value'.";
|
||||||
|
}
|
||||||
|
leaf default-operation {
|
||||||
|
type enumeration {
|
||||||
|
enum merge {
|
||||||
|
description
|
||||||
|
"The default operation is merge.";
|
||||||
|
}
|
||||||
|
enum replace {
|
||||||
|
description
|
||||||
|
"The default operation is replace.";
|
||||||
|
}
|
||||||
|
enum none {
|
||||||
|
description
|
||||||
|
"There is no default operation.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default "merge";
|
||||||
|
description
|
||||||
|
"The default operation to use.";
|
||||||
|
}
|
||||||
|
choice edit-content {
|
||||||
|
mandatory true;
|
||||||
|
description
|
||||||
|
"The content for the edit operation.";
|
||||||
|
anydata config {
|
||||||
|
description
|
||||||
|
"Inline config content.";
|
||||||
|
}
|
||||||
|
leaf url {
|
||||||
|
if-feature "nc:url";
|
||||||
|
type inet:uri;
|
||||||
|
description
|
||||||
|
"URL-based config content.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Augment the <lock> and <unlock> operations with a
|
||||||
|
* "datastore" parameter.
|
||||||
|
*/
|
||||||
|
|
||||||
|
augment "/nc:lock/nc:input/nc:target/nc:config-target" {
|
||||||
|
description
|
||||||
|
"Add NMDA datastore as target.";
|
||||||
|
leaf datastore {
|
||||||
|
type ds:datastore-ref;
|
||||||
|
description
|
||||||
|
"Datastore to lock.
|
||||||
|
|
||||||
|
The <lock> operation is only supported on writable
|
||||||
|
datastores.
|
||||||
|
|
||||||
|
If the <lock> operation is not supported by the server on
|
||||||
|
the specified target datastore, then the server MUST return
|
||||||
|
an <rpc-error> element with an <error-tag> value of
|
||||||
|
'invalid-value'.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
augment "/nc:unlock/nc:input/nc:target/nc:config-target" {
|
||||||
|
description
|
||||||
|
"Add NMDA datastore as target.";
|
||||||
|
leaf datastore {
|
||||||
|
type ds:datastore-ref;
|
||||||
|
description
|
||||||
|
"Datastore to unlock.
|
||||||
|
|
||||||
|
The <unlock> operation is only supported on writable
|
||||||
|
datastores.
|
||||||
|
|
||||||
|
If the <unlock> operation is not supported by the server on
|
||||||
|
the specified target datastore, then the server MUST return
|
||||||
|
an <rpc-error> element with an <error-tag> value of
|
||||||
|
'invalid-value'.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Augment the <validate> operation with a
|
||||||
|
* "datastore" parameter.
|
||||||
|
*/
|
||||||
|
|
||||||
|
augment "/nc:validate/nc:input/nc:source/nc:config-source" {
|
||||||
|
description
|
||||||
|
"Add NMDA datastore as source.";
|
||||||
|
leaf datastore {
|
||||||
|
type ds:datastore-ref;
|
||||||
|
description
|
||||||
|
"Datastore to validate.
|
||||||
|
|
||||||
|
The <validate> operation is supported only on configuration
|
||||||
|
datastores.
|
||||||
|
|
||||||
|
If the <validate> operation is not supported by the server
|
||||||
|
on the specified target datastore, then the server MUST
|
||||||
|
return an <rpc-error> element with an <error-tag> value of
|
||||||
|
'invalid-value'.";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
138
yang/mandatory/ietf-netconf-with-defaults@2011-06-01.yang
Normal file
138
yang/mandatory/ietf-netconf-with-defaults@2011-06-01.yang
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
module ietf-netconf-with-defaults {
|
||||||
|
|
||||||
|
namespace "urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults";
|
||||||
|
|
||||||
|
prefix ncwd;
|
||||||
|
|
||||||
|
import ietf-netconf { prefix nc; }
|
||||||
|
|
||||||
|
organization
|
||||||
|
"IETF NETCONF (Network Configuration Protocol) Working Group";
|
||||||
|
|
||||||
|
contact
|
||||||
|
"WG Web: <http://tools.ietf.org/wg/netconf/>
|
||||||
|
|
||||||
|
WG List: <netconf@ietf.org>
|
||||||
|
|
||||||
|
WG Chair: Bert Wijnen
|
||||||
|
<bertietf@bwijnen.net>
|
||||||
|
|
||||||
|
WG Chair: Mehmet Ersue
|
||||||
|
<mehmet.ersue@nsn.com>
|
||||||
|
|
||||||
|
Editor: Andy Bierman
|
||||||
|
<andy.bierman@brocade.com>
|
||||||
|
|
||||||
|
Editor: Balazs Lengyel
|
||||||
|
<balazs.lengyel@ericsson.com>";
|
||||||
|
|
||||||
|
description
|
||||||
|
"This module defines an extension to the NETCONF protocol
|
||||||
|
that allows the NETCONF client to control how default
|
||||||
|
values are handled by the server in particular NETCONF
|
||||||
|
operations.
|
||||||
|
|
||||||
|
Copyright (c) 2011 IETF Trust and the persons identified as
|
||||||
|
the document authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or
|
||||||
|
without modification, is permitted pursuant to, and subject
|
||||||
|
to the license terms contained in, the Simplified BSD License
|
||||||
|
set forth in Section 4.c of the IETF Trust's Legal Provisions
|
||||||
|
Relating to IETF Documents
|
||||||
|
(http://trustee.ietf.org/license-info).
|
||||||
|
|
||||||
|
This version of this YANG module is part of RFC 6243; see
|
||||||
|
the RFC itself for full legal notices.";
|
||||||
|
revision 2011-06-01 {
|
||||||
|
description
|
||||||
|
"Initial version.";
|
||||||
|
reference
|
||||||
|
"RFC 6243: With-defaults Capability for NETCONF";
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef with-defaults-mode {
|
||||||
|
description
|
||||||
|
"Possible modes to report default data.";
|
||||||
|
reference
|
||||||
|
"RFC 6243; Section 3.";
|
||||||
|
type enumeration {
|
||||||
|
enum report-all {
|
||||||
|
description
|
||||||
|
"All default data is reported.";
|
||||||
|
reference
|
||||||
|
"RFC 6243; Section 3.1";
|
||||||
|
}
|
||||||
|
enum report-all-tagged {
|
||||||
|
description
|
||||||
|
"All default data is reported.
|
||||||
|
Any nodes considered to be default data
|
||||||
|
will contain a 'default' XML attribute,
|
||||||
|
set to 'true' or '1'.";
|
||||||
|
reference
|
||||||
|
"RFC 6243; Section 3.4";
|
||||||
|
}
|
||||||
|
enum trim {
|
||||||
|
description
|
||||||
|
"Values are not reported if they contain the default.";
|
||||||
|
reference
|
||||||
|
"RFC 6243; Section 3.2";
|
||||||
|
}
|
||||||
|
enum explicit {
|
||||||
|
description
|
||||||
|
"Report values that contain the definition of
|
||||||
|
explicitly set data.";
|
||||||
|
reference
|
||||||
|
"RFC 6243; Section 3.3";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
grouping with-defaults-parameters {
|
||||||
|
description
|
||||||
|
"Contains the <with-defaults> parameter for control
|
||||||
|
of defaults in NETCONF retrieval operations.";
|
||||||
|
leaf with-defaults {
|
||||||
|
description
|
||||||
|
"The explicit defaults processing mode requested.";
|
||||||
|
reference
|
||||||
|
"RFC 6243; Section 4.5.1";
|
||||||
|
|
||||||
|
type with-defaults-mode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// extending the get-config operation
|
||||||
|
augment /nc:get-config/nc:input {
|
||||||
|
description
|
||||||
|
"Adds the <with-defaults> parameter to the
|
||||||
|
input of the NETCONF <get-config> operation.";
|
||||||
|
reference
|
||||||
|
"RFC 6243; Section 4.5.1";
|
||||||
|
|
||||||
|
uses with-defaults-parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
// extending the get operation
|
||||||
|
augment /nc:get/nc:input {
|
||||||
|
description
|
||||||
|
"Adds the <with-defaults> parameter to
|
||||||
|
the input of the NETCONF <get> operation.";
|
||||||
|
reference
|
||||||
|
"RFC 6243; Section 4.5.1";
|
||||||
|
|
||||||
|
uses with-defaults-parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
// extending the copy-config operation
|
||||||
|
augment /nc:copy-config/nc:input {
|
||||||
|
description
|
||||||
|
"Adds the <with-defaults> parameter to
|
||||||
|
the input of the NETCONF <copy-config> operation.";
|
||||||
|
reference
|
||||||
|
"RFC 6243; Section 4.5.1";
|
||||||
|
|
||||||
|
uses with-defaults-parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
147
yang/mandatory/ietf-origin@2018-02-14.yang
Normal file
147
yang/mandatory/ietf-origin@2018-02-14.yang
Normal file
|
|
@ -0,0 +1,147 @@
|
||||||
|
module ietf-origin {
|
||||||
|
yang-version 1.1;
|
||||||
|
namespace "urn:ietf:params:xml:ns:yang:ietf-origin";
|
||||||
|
prefix or;
|
||||||
|
|
||||||
|
import ietf-yang-metadata {
|
||||||
|
prefix md;
|
||||||
|
}
|
||||||
|
|
||||||
|
organization
|
||||||
|
"IETF Network Modeling (NETMOD) Working Group";
|
||||||
|
|
||||||
|
contact
|
||||||
|
"WG Web: <https://datatracker.ietf.org/wg/netmod/>
|
||||||
|
|
||||||
|
WG List: <mailto:netmod@ietf.org>
|
||||||
|
|
||||||
|
Author: Martin Bjorklund
|
||||||
|
<mailto:mbj@tail-f.com>
|
||||||
|
|
||||||
|
Author: Juergen Schoenwaelder
|
||||||
|
<mailto:j.schoenwaelder@jacobs-university.de>
|
||||||
|
|
||||||
|
Author: Phil Shafer
|
||||||
|
<mailto:phil@juniper.net>
|
||||||
|
|
||||||
|
Author: Kent Watsen
|
||||||
|
<mailto:kwatsen@juniper.net>
|
||||||
|
|
||||||
|
Author: Rob Wilton
|
||||||
|
<rwilton@cisco.com>";
|
||||||
|
|
||||||
|
description
|
||||||
|
"This YANG module defines an 'origin' metadata annotation and a
|
||||||
|
set of identities for the origin value.
|
||||||
|
|
||||||
|
Copyright (c) 2018 IETF Trust and the persons identified as
|
||||||
|
authors of the code. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or
|
||||||
|
without modification, is permitted pursuant to, and subject to
|
||||||
|
the license terms contained in, the Simplified BSD License set
|
||||||
|
forth in Section 4.c of the IETF Trust's Legal Provisions
|
||||||
|
Relating to IETF Documents
|
||||||
|
(https://trustee.ietf.org/license-info).
|
||||||
|
|
||||||
|
This version of this YANG module is part of RFC 8342
|
||||||
|
(https://www.rfc-editor.org/info/rfc8342); see the RFC itself
|
||||||
|
for full legal notices.";
|
||||||
|
|
||||||
|
revision 2018-02-14 {
|
||||||
|
description
|
||||||
|
"Initial revision.";
|
||||||
|
reference
|
||||||
|
"RFC 8342: Network Management Datastore Architecture (NMDA)";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Identities
|
||||||
|
*/
|
||||||
|
|
||||||
|
identity origin {
|
||||||
|
description
|
||||||
|
"Abstract base identity for the origin annotation.";
|
||||||
|
}
|
||||||
|
|
||||||
|
identity intended {
|
||||||
|
base origin;
|
||||||
|
description
|
||||||
|
"Denotes configuration from the intended configuration
|
||||||
|
datastore.";
|
||||||
|
}
|
||||||
|
|
||||||
|
identity dynamic {
|
||||||
|
base origin;
|
||||||
|
description
|
||||||
|
"Denotes configuration from a dynamic configuration
|
||||||
|
datastore.";
|
||||||
|
}
|
||||||
|
|
||||||
|
identity system {
|
||||||
|
base origin;
|
||||||
|
description
|
||||||
|
"Denotes configuration originated by the system itself.
|
||||||
|
|
||||||
|
Examples of system configuration include applied configuration
|
||||||
|
for an always-existing loopback interface, or interface
|
||||||
|
configuration that is auto-created due to the hardware
|
||||||
|
currently present in the device.";
|
||||||
|
}
|
||||||
|
|
||||||
|
identity learned {
|
||||||
|
base origin;
|
||||||
|
description
|
||||||
|
"Denotes configuration learned from protocol interactions with
|
||||||
|
other devices, instead of via either the intended
|
||||||
|
configuration datastore or any dynamic configuration
|
||||||
|
datastore.
|
||||||
|
|
||||||
|
Examples of protocols that provide learned configuration
|
||||||
|
include link-layer negotiations, routing protocols, and
|
||||||
|
DHCP.";
|
||||||
|
}
|
||||||
|
|
||||||
|
identity default {
|
||||||
|
base origin;
|
||||||
|
description
|
||||||
|
"Denotes configuration that does not have a configured or
|
||||||
|
learned value but has a default value in use. Covers both
|
||||||
|
values defined in a 'default' statement and values defined
|
||||||
|
via an explanation in a 'description' statement.";
|
||||||
|
}
|
||||||
|
|
||||||
|
identity unknown {
|
||||||
|
base origin;
|
||||||
|
description
|
||||||
|
"Denotes configuration for which the system cannot identify the
|
||||||
|
origin.";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Type definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef origin-ref {
|
||||||
|
type identityref {
|
||||||
|
base origin;
|
||||||
|
}
|
||||||
|
description
|
||||||
|
"An origin identity reference.";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Metadata annotations
|
||||||
|
*/
|
||||||
|
|
||||||
|
md:annotation origin {
|
||||||
|
type origin-ref;
|
||||||
|
description
|
||||||
|
"The 'origin' annotation can be present on any configuration
|
||||||
|
data node in the operational state datastore. It specifies
|
||||||
|
from where the node originated. If not specified for a given
|
||||||
|
configuration data node, then the origin is the same as the
|
||||||
|
origin of its parent node in the data tree. The origin for
|
||||||
|
any top-level configuration data nodes must be specified.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
module ietf-restconf-list-pagination {
|
|
||||||
namespace "urn:ietf:params:xml:ns:yang:ietf-restconf-list-pagination";
|
|
||||||
prefix rlpg;
|
|
||||||
import ietf-restconf {
|
|
||||||
prefix rc;
|
|
||||||
}
|
|
||||||
organization
|
|
||||||
"IETF NETCONF (Network Configuration) Working Group";
|
|
||||||
contact
|
|
||||||
"WG Web: <http://tools.ietf.org/wg/netconf/>
|
|
||||||
WG List: <mailto:netconf@ietf.org>";
|
|
||||||
|
|
||||||
description
|
|
||||||
"This module contains conceptual YANG specifications
|
|
||||||
for the RESTCONF Collection resource type.
|
|
||||||
Note that the YANG definitions within this module do not
|
|
||||||
represent configuration data of any kind.
|
|
||||||
The YANG grouping statements provide a normative syntax
|
|
||||||
for XML and JSON message encoding purposes.
|
|
||||||
|
|
||||||
Copyright (c) 2015 IETF Trust and the persons identified as
|
|
||||||
authors of the code. All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or
|
|
||||||
without modification, is permitted pursuant to, and subject
|
|
||||||
to the license terms contained in, the Simplified BSD License
|
|
||||||
set forth in Section 4.c of the IETF Trust's Legal Provisions
|
|
||||||
Relating to IETF Documents
|
|
||||||
(http://trustee.ietf.org/license-info).
|
|
||||||
|
|
||||||
This version of this YANG module is part of RFC XXXX; see
|
|
||||||
the RFC itself for full legal notices.";
|
|
||||||
|
|
||||||
revision 2015-01-30 {
|
|
||||||
description
|
|
||||||
"Initial revision.";
|
|
||||||
reference
|
|
||||||
"RFC XXXX: RESTCONF Collection Resource.";
|
|
||||||
}
|
|
||||||
rc:yang-data yang-collection {
|
|
||||||
uses collection;
|
|
||||||
}
|
|
||||||
|
|
||||||
grouping collection {
|
|
||||||
description
|
|
||||||
"Conceptual container representing the
|
|
||||||
yang-collection resource type.";
|
|
||||||
container yang-collection {
|
|
||||||
description
|
|
||||||
"Container representing the yang-collection
|
|
||||||
resource type.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue