Olof hagsand 2021-11-09 17:38:17 +01:00
parent baa6e821a8
commit a4b4dc97ce
28 changed files with 1011 additions and 527 deletions

View file

@ -49,6 +49,13 @@ Thanks netgate for providing the dispatcher code!
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
* Instead of returning an rpc-error reply

View file

@ -519,7 +519,7 @@ get_list_pagination(clicon_handle h,
}
}
/* 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);
if (sort) {
/* XXX: nothing yet */
@ -721,12 +721,9 @@ get_common(clicon_handle h,
char *xpath0;
cbuf *cbreason = NULL;
int list_pagination = 0;
char *valstr;
cxobj *x;
#if 1
cxobj **xvec = NULL;
size_t xlen;
#endif
cxobj **xvec = NULL;
size_t xlen;
cxobj *xlistpag;
clicon_debug(1, "%s", __FUNCTION__);
username = clicon_username_get(h);
@ -767,15 +764,15 @@ get_common(clicon_handle h,
}
}
/* Check if list pagination */
if ((x = xml_find_type(xe, NULL, "list-pagination", CX_ELMNT)) != NULL &&
(valstr = xml_body(x)) != NULL &&
strcmp(valstr,"true")==0)
if ((xlistpag = xml_find_type(xe, NULL, "list-pagination", CX_ELMNT)) != NULL)
list_pagination = 1;
/* Sanity check for list pagination: path must be a list/leaf-list, if it is,
* check config/state
*/
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,
cbret) < 0)
goto done;

View file

@ -46,15 +46,17 @@ extern "C" {
*/
/*! RESTCONF media types
* @see http_media_map
* @note DUPLICATED in clixon_lib.h
* @note DUPLICATED in restconf_lib.h
*/
enum restconf_media{
YANG_DATA_JSON, /* "application/yang-data+json" */
YANG_DATA_XML, /* "application/yang-data+xml" */
YANG_PATCH_JSON, /* "application/yang-patch+json" */
YANG_PATCH_XML, /* "application/yang-patch+xml" */
YANG_COLLECTION_XML, /* draft-wwlh-netconf-list-pagination-rc-01.txt */
YANG_COLLECTION_JSON /* draft-wwlh-netconf-list-pagination-rc-01.txt */
YANG_PAGINATION_XML, /* draft-wwlh-netconf-list-pagination-rc-02.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;

View file

@ -275,7 +275,7 @@ api_return_err(clicon_handle h,
switch (media){
case YANG_DATA_XML:
case YANG_PATCH_XML:
case YANG_COLLECTION_XML:
case YANG_PAGINATION_XML:
clicon_debug(1, "%s code:%d", __FUNCTION__, code);
if (pretty){
cprintf(cb, " <errors xmlns=\"urn:ietf:params:xml:ns:yang:ietf-restconf\">\n");
@ -292,7 +292,6 @@ api_return_err(clicon_handle h,
break;
case YANG_DATA_JSON:
case YANG_PATCH_JSON:
case YANG_COLLECTION_JSON:
clicon_debug(1, "%s code:%d", __FUNCTION__, code);
if (pretty){
cprintf(cb, "{\n\"ietf-restconf:errors\" : ");

View file

@ -207,8 +207,7 @@ static const map_str2int http_media_map[] = {
{"application/yang-data+json", YANG_DATA_JSON},
{"application/yang-patch+xml", YANG_PATCH_XML},
{"application/yang-patch+json", YANG_PATCH_JSON},
{"application/yang-collection+xml", YANG_COLLECTION_XML}, /* XXX -data+xml-list?? */
{"application/yang-collection+json", YANG_COLLECTION_JSON},
{"application/yang-data+xml-list", YANG_PAGINATION_XML}, /* draft-wwlh-netconf-list-pagination-rc-02 */
{NULL, -1}
};

View file

@ -53,8 +53,7 @@ enum restconf_media{
YANG_DATA_XML, /* "application/yang-data+xml" */
YANG_PATCH_JSON, /* "application/yang-patch+json" */
YANG_PATCH_XML, /* "application/yang-patch+xml" */
YANG_COLLECTION_XML, /* draft-ietf-netconf-restconf-collection-00.txt */
YANG_COLLECTION_JSON /* draft-ietf-netconf-restconf-collection-00.txt */
YANG_PAGINATION_XML, /* draft-wwlh-netconf-list-pagination-rc-02.txt */
};
typedef enum restconf_media restconf_media;

View file

@ -191,7 +191,6 @@ int
api_data_write(clicon_handle h,
void *req,
char *api_path0,
cvec *pcvec,
int pi,
cvec *qvec,
char *data,
@ -585,7 +584,6 @@ api_data_write(clicon_handle h,
* @param[in] h Clixon handle
* @param[in] req Generic Www handle
* @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] qvec Vector of query string (QUERY_STRING)
* @param[in] data Stream input data
@ -620,7 +618,6 @@ int
api_data_put(clicon_handle h,
void *req,
char *api_path0,
cvec *pcvec,
int pi,
cvec *qvec,
char *data,
@ -631,7 +628,7 @@ api_data_put(clicon_handle h,
restconf_media media_in;
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);
}
@ -639,8 +636,7 @@ api_data_put(clicon_handle h,
* @param[in] h Clixon handle
* @param[in] req Generic Www handle
* @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 qvec
* @param[in] qvec Vector of query string (QUERY_STRING)
* @param[in] data Stream input data
* @param[in] pretty Set to 1 for pretty-printed xml/json output
@ -657,7 +653,6 @@ int
api_data_patch(clicon_handle h,
void *req,
char *api_path0,
cvec *pcvec,
int pi,
cvec *qvec,
char *data,
@ -672,7 +667,7 @@ api_data_patch(clicon_handle h,
switch (media_in){
case YANG_DATA_XML:
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);
break;
case YANG_PATCH_JSON: /* RFC 8072 patch */

View file

@ -44,18 +44,18 @@
*/
int api_data_options(clicon_handle h, void *req);
int api_data_write(clicon_handle h, void *req, char *api_path0,
cvec *pcvec, int pi,
int pi,
cvec *qvec, char *data,
int pretty, restconf_media media_in, restconf_media media_out,
int plain_patch, ietf_ds_t ds);
int api_data_put(clicon_handle h, void *req, char *api_path,
cvec *pcvec, int pi,
int pi,
cvec *qvec, char *data,
int pretty, restconf_media media_out, ietf_ds_t ds);
int api_data_patch(clicon_handle h, void *req, char *api_path,
cvec *pcvec, int pi,
int pi,
cvec *qvec, char *data, int pretty,
restconf_media media_out, ietf_ds_t ds);

View file

@ -63,12 +63,14 @@
#include "restconf_err.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)
* According to restconf
* @param[in] h Clixon handle
* @param[in] req Generic Www handle
* @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] qvec Vector of query string (QUERY_STRING)
* @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
* "400 Bad Request" status-line MUST be returned by the server.
* Netconf: <get-config>, <get>
* @note there is an ad-hoc method to determine json pagination request instead of regular GET
*/
static int
api_data_get2(clicon_handle h,
void *req,
char *api_path,
cvec *pcvec, /* XXX remove? */
int pi,
cvec *qvec,
int pretty,
@ -148,6 +150,18 @@ api_data_get2(clicon_handle h,
goto done;
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 */
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] req Generic Www handle
* @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] qvec Vector of query string (QUERY_STRING)
* @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
*/
static int
api_data_collection(clicon_handle h,
api_data_pagination(clicon_handle h,
void *req,
char *api_path,
cvec *pcvec, /* XXX remove? */
int pi,
cvec *qvec,
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 (netconf_bad_element_xml(&xerr, "application",
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;
if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){
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");
sort = cvec_find_str(qvec, "sort");
sort = cvec_find_str(qvec, "sort-by");
where = cvec_find_str(qvec, "where");
if (clicon_rpc_get_pageable_list(h, "running", xpath, nsc, content,
depth, offset, limit, direction, sort, where,
@ -492,9 +504,9 @@ api_data_collection(clicon_handle h,
goto done;
goto ok;
}
if ((xpr = xml_new("yang-collection", NULL, CX_ELMNT)) == NULL)
if ((xpr = xml_new("xml-list", NULL, CX_ELMNT)) == NULL)
goto done;
if (xmlns_set(xpr, NULL, RESTCONF_PAGINATON_NAMESPACE) < 0)
if (xmlns_set(xpr, NULL, IETF_PAGINATON_NAMESPACE) < 0)
goto done;
if (xpath_vec(xret, nsc, "%s", &xvec, &xlen, xpath) < 0)
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
* 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 */
if ((cbx = cbuf_new()) == NULL)
goto done;
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? */
goto done;
break;
case YANG_COLLECTION_JSON:
if (xml2json_cbuf(cbx, xpr, pretty) < 0)
case YANG_DATA_JSON:
if (xml2json_cbuf_vec(cbx, xvec, xlen, pretty) < 0)
goto done;
break;
default:
@ -570,7 +582,6 @@ api_data_collection(clicon_handle h,
* @param[in] h Clixon handle
* @param[in] req Generic Www handle
* @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] qvec Vector of query string (QUERY_STRING)
* @param[in] pretty Set to 1 for pretty-printed xml/json output
@ -586,14 +597,13 @@ int
api_data_head(clicon_handle h,
void *req,
char *api_path,
cvec *pcvec,
int pi,
cvec *qvec,
int pretty,
restconf_media media_out,
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
@ -625,7 +635,6 @@ int
api_data_get(clicon_handle h,
void *req,
char *api_path,
cvec *pcvec,
int pi,
cvec *qvec,
int pretty,
@ -636,15 +645,13 @@ api_data_get(clicon_handle h,
switch (media_out){
case YANG_DATA_XML:
case YANG_DATA_JSON:
if (api_data_get2(h, req, api_path, pcvec, pi, qvec, pretty, media_out, 0) < 0)
case YANG_DATA_JSON: /* ad-hoc algorithm in get to determine if a paginated request */
if (api_data_get2(h, req, api_path, pi, qvec, pretty, media_out, 0) < 0)
goto done;
break;
case YANG_COLLECTION_XML:
case YANG_COLLECTION_JSON:
if (api_data_collection(h, req, api_path, pcvec, pi, qvec, pretty, media_out) < 0)
case YANG_PAGINATION_XML:
if (api_data_pagination(h, req, api_path, pi, qvec, pretty, media_out) < 0)
goto done;
break;
default:
break;
}
@ -657,7 +664,6 @@ api_data_get(clicon_handle h,
* @param[in] h Clixon handle
* @param[in] req Generic Www handle
* @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] qvec Vector of query string (QUERY_STRING)
* @param[in] data Stream input data

View file

@ -41,9 +41,9 @@
/*
* 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);
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);
int api_operations_get(clicon_handle h, void *req,
char *api_path, int pi, cvec *qvec, char *data,

View file

@ -188,7 +188,7 @@ yang_patch_strip_after_last_slash(char* val)
/*! YANG PATCH replace method
* @param[in] h Clixon 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] pretty Set to 1 for pretty-printed xml/json output
* @param[in] media_out Output media
@ -287,7 +287,7 @@ yang_patch_do_replace(clicon_handle h,
/*! YANG PATCH create method
* @param[in] h Clixon 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] pretty Set to 1 for pretty-printed xml/json output
* @param[in] media_out Output media
@ -343,7 +343,7 @@ yang_patch_do_create(clicon_handle h,
/*! YANG PATCH insert method
* @param[in] h Clixon 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] media_out Output media
* @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
* @param[in] h Clixon handle
* @param[in] req Generic Www handle
* @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 api-path
* @param[in] qvec Vector of query string (QUERY_STRING)
* @param[in] pretty Set to 1 for pretty-printed xml/json output
* @param[in] media_out Output media
@ -447,7 +446,6 @@ yang_patch_do_insert(clicon_handle h,
static int
yang_patch_do_merge(clicon_handle h,
void *req,
cvec *pcvec,
int pi,
cvec *qvec,
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)
goto done;
// 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;
if (json_simple_patch){
cbuf_free(json_simple_patch);
@ -509,7 +507,6 @@ yang_patch_do_merge(clicon_handle h,
static int
yang_patch_do_value(clicon_handle h,
void *req,
cvec *pcvec,
int pi,
cvec *qvec,
int pretty,
@ -560,7 +557,7 @@ yang_patch_do_value(clicon_handle h,
goto done;
break;
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;
break;
default:
@ -579,8 +576,7 @@ yang_patch_do_value(clicon_handle h,
*
* @param[in] h Clixon handle
* @param[in] req Generic Www handle
* @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 api-path
* @param[in] qvec Vector of query string (QUERY_STRING)
* @param[in] pretty Set to 1 for pretty-printed xml/json output
* @param[in] media_out Output media
@ -591,7 +587,6 @@ yang_patch_do_value(clicon_handle h,
static int
yang_patch_do_edit(clicon_handle h,
void *req,
cvec *pcvec,
int pi,
cvec *qvec,
int pretty,
@ -693,7 +688,7 @@ yang_patch_do_edit(clicon_handle h,
// Loop through the values
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,
operation, where_val, point_val, simple_patch_request_uri, target_val,
api_path, key_xn) < 0)
@ -729,8 +724,7 @@ yang_patch_do_edit(clicon_handle h,
* @param[in] h Clixon handle
* @param[in] req Generic Www handle
* @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 pcvec
* @param[in] pi Offset, where to start api-path
* @param[in] qvec Vector of query string (QUERY_STRING)
* @param[in] data Stream input data
* @param[in] pretty Set to 1 for pretty-printed xml/json output
@ -749,7 +743,6 @@ int
api_data_yang_patch(clicon_handle h,
void *req,
char *api_path0,
cvec *pcvec,
int pi,
cvec *qvec,
char *data,
@ -828,7 +821,7 @@ api_data_yang_patch(clicon_handle h,
if (xpath_vec(xpatch, NULL, "yang-patch/edit", &vec, &veclen) < 0)
goto done;
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,
vec[i],
uripath0, api_path) < 0)
@ -854,7 +847,6 @@ int
api_data_yang_patch(clicon_handle h,
void *req,
char *api_path0,
cvec *pcvec,
int pi,
cvec *qvec,
char *data,

View file

@ -44,7 +44,7 @@
* Prototypes
*/
int api_data_yang_patch(clicon_handle h, void *req, char *api_path0,
cvec *pcvec, int pi,
int pi,
cvec *qvec, char *data,
int pretty, restconf_media media_in, restconf_media media_out,
ietf_ds_t ds);

View file

@ -329,10 +329,10 @@ api_data(clicon_handle h,
if (dynamic)
retval = restconf_method_notallowed(h, req, "GET,POST", pretty, media_out);
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) {
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) {
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)
retval = restconf_method_notallowed(h, req, "GET,POST", pretty, media_out);
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) {
if (read_only) {
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) {
if (read_only)

View file

@ -54,18 +54,18 @@
*/
#define NETCONF_INPUT_CONFIG "config"
/* Collections namespace from draft-ietf-netconf-restconf-collection-00.txt
* XXX: Obsolete but may come back in style
/* List pagination namespaces
*/
#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
* ietf-netconf.yang defines it as output:

View file

@ -1039,7 +1039,8 @@ xml2json1_cbuf(cbuf *cb,
* goto err;
* cbuf_free(cb);
* @endcode
* @see clicon_xml2cbuf
* @see clicon_xml2cbuf XML corresponding function
* @see xml2json_cbuf_vec Top symbol is list
*/
int
xml2json_cbuf(cbuf *cb,
@ -1082,7 +1083,7 @@ xml2json_cbuf(cbuf *cb,
* @retval -1 Error
* @note This only works if the vector is uniform, ie same object name.
* Example: <b/><c/> --> <a><b/><c/></a> --> {"b" : null,"c" : null}
* @see xml2json1_cbuf
* @see xml2json_cbuf
*/
int
xml2json_cbuf_vec(cbuf *cb,

View file

@ -1530,11 +1530,11 @@ netconf_module_load(clicon_handle h)
if (clicon_option_bool(h, "CLICON_NETCONF_MESSAGE_ID_OPTIONAL") == 1)
xml_bind_netconf_message_id_optional(1);
#endif
/* Load clixon netconf list pagination */
if (yang_spec_parse_module(h, "clixon-netconf-list-pagination", NULL, yspec)< 0)
/* Load ietf list pagination */
if (yang_spec_parse_module(h, "ietf-list-pagination", NULL, yspec)< 0)
goto done;
/* Load restconf list pagination */
if (yang_spec_parse_module(h, "ietf-restconf-list-pagination", NULL, yspec)< 0)
/* Load ietf list pagination netconf */
if (yang_spec_parse_module(h, "ietf-list-pagination-nc", NULL, yspec)< 0)
goto done;
retval = 0;
done:

View file

@ -944,8 +944,7 @@ clicon_rpc_get_pageable_list(clicon_handle h,
/* Clixon extension, depth=<level> */
if (depth != -1)
cprintf(cb, " depth=\"%d\"", depth);
/* declare cp prefix in get, so sub-elements dont need to */
cprintf(cb, " xmlns:cp=\"%s\"", CLIXON_PAGINATON_NAMESPACE);
/* declare lp prefix in get, so sub-elements dont need to */
cprintf(cb, ">"); /* get */
/* If xpath, add a filter */
if (xpath && strlen(xpath)) {
@ -957,17 +956,18 @@ clicon_rpc_get_pageable_list(clicon_handle h,
cprintf(cb, "/>");
}
/* 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)
cprintf(cb, "<cp:offset>%u</cp:offset>", offset);
cprintf(cb, "<offset>%u</offset>", offset);
if (limit != 0)
cprintf(cb, "<cp:limit>%u</cp:limit>", limit);
cprintf(cb, "<limit>%u</limit>", limit);
if (direction)
cprintf(cb, "<cp:direction>%s</cp:direction>", direction);
cprintf(cb, "<direction>%s</direction>", direction);
if (sort)
cprintf(cb, "<cp:sort>%s</cp:sort>", sort);
cprintf(cb, "<sort>%s</sort>", sort);
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, "</rpc>");
if ((msg = clicon_msg_encode(session_id, "%s", cbuf_get(cb))) == NULL)

View file

@ -286,9 +286,9 @@ function testlimit()
el="<uint8-numbers>$li</uint8-numbers>"
el2="<uint8-numbers xmlns=\"http://example.com/ns/example-social\">$li</uint8-numbers>"
else
el="<uint8-numbers cp:remaining=\"$remaining\" xmlns:cp=\"http://clicon.org/clixon-netconf-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>"
jsonmeta=",\"@example-social:uint8-numbers\":\[{\"clixon-netconf-list-pagination:remaining\":$remaining}\]"
el="<uint8-numbers lp:remaining=\"$remaining\" xmlns:lp=\"urn:ietf:params:xml:ns:yang:ietf-list-pagination\">$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\":\[{\"ietf-list-pagination:remaining\":$remaining}\]"
fi
jsonlist="$li"
else
@ -304,13 +304,13 @@ function testlimit()
if [ $limit -eq 0 ]; then
limitxmlstr=""
else
limitxmlstr="<limit xmlns=\"http://clicon.org/clixon-netconf-list-pagination\">$limit</limit>"
limitxmlstr="<limit>$limit</limit>"
jsonstr="?limit=$limit"
fi
if [ $offset -eq 0 ]; then
offsetxmlstr=""
else
offsetxmlstr="<offset xmlns=\"http://clicon.org/clixon-netconf-list-pagination\">$offset</offset>"
offsetxmlstr="<offset>$offset</offset>"
if [ -z "$jsonstr" ]; then
jsonstr="?offset=$offset"
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>]]>]]>$"
fi
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
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>]]>]]>$"
fi
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
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
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
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
reply="{\"yang-collection\":{}}"
# reply="{\"xml-list\":{}}"
reply="{}"
else
reply="{\"yang-collection\":{\"example-social:uint8-numbers\":\[$jsonlist\]$jsonmeta}"
reply="{\"example-social:uint8-numbers\":\[$jsonlist\]}"
fi
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
new "test params: -f $cfg -s startup -- -sS $fstate"
@ -380,7 +379,6 @@ fi
new "wait restconf"
wait_restconf
new "A.3.1.1. limit=1"
testlimit 0 1 5 "17"

View file

@ -135,15 +135,15 @@ xpath="$xpath0/es:numbers"
testrun_start $xpath
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
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"
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
@ -152,7 +152,7 @@ xpath="/es:members/es:member/es:stats/es:numbers"
testrun_start $xpath
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

View file

@ -46,7 +46,6 @@ YANGSPECS += clixon-lib@2021-03-08.yang # 5.1
YANGSPECS += clixon-rfc5277@2008-07-01.yang
YANGSPECS += clixon-xml-changelog@2019-03-21.yang
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

View file

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

View file

@ -53,10 +53,18 @@ YANGSPECS += ietf-datastores@2018-02-14.yang
YANGSPECS += ietf-yang-patch@2017-02-22.yang
# For remaining attribute in list-pagination:
YANGSPECS += ietf-yang-metadata@2016-08-05.yang
# in draft-wwlh-netconf-list-pagination:
YANGSPECS += ietf-netconf-list-pagination@2020-10-30.yang
# in draft-wwlh-netconf-list-pagination-rc:
YANGSPECS += ietf-restconf-list-pagination@2015-01-30.yang
# XXX brings in NACM which breaks tests
# YANGSPECS += ietf-system-capabilities@2021-04-02.yang
# For remaining attribute in list-pagination-nc:
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:

View 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;
}
}

View 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.";
}
}
*/
}

View file

@ -1,8 +1,30 @@
module ietf-netconf-list-pagination {
module ietf-netconf-nmda {
yang-version 1.1;
namespace "urn:ietf:params:xml:ns:yang:ietf-netconf-list-pagination";
prefix ycoll;
namespace "urn:ietf:params:xml:ns:yang:ietf-netconf-nmda";
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 {
prefix nc;
reference
@ -13,43 +35,32 @@ module ietf-netconf-list-pagination {
reference
"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
"IETF NETCONF (Network Configuration) Working Group";
"IETF NETCONF Working Group";
contact
"WG Web: <http://tools.ietf.org/wg/netconf/>
"WG Web: <https://datatracker.ietf.org/wg/netconf/>
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
"This module define a new operation -- <get-collection>
to support YANG based pagination.
"This YANG module defines a set of NETCONF operations to support
the Network Management Datastore Architecture (NMDA).
The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL', 'SHALL
NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED', 'NOT RECOMMENDED',
@ -68,20 +79,14 @@ module ietf-netconf-list-pagination {
(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.
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 2020-10-30 {
revision 2019-01-07 {
description
"Initial revision.";
reference
"RFC XXXX: YANG Based Pagination.";
"RFC 8526: NETCONF Extensions to Support the Network Management
Datastore Architecture";
}
feature origin {
@ -100,28 +105,14 @@ module ietf-netconf-list-pagination {
reference
"RFC 6243: With-defaults Capability for NETCONF, Section 4; and
RFC 8526: NETCONF Extensions to Support the Network Management
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.";
Datastore Architecture, Section 3.1.1.2";
}
rpc get-pageable-list {
rpc get-data {
description
"Use enhanced filtering features to retrieve data from a
specific NMDA datastore. The content returned by get-data
must satisfy all filters, i.e., the filter criteria are
logically ANDed.
"Retrieve data from an NMDA datastore. The content returned
by get-data must satisfy all filters, i.e., the filter
criteria are logically ANDed.
Any ancestor nodes (including list keys) of nodes selected by
the filters are included in the response.
@ -142,11 +133,12 @@ module ietf-netconf-list-pagination {
leaf datastore {
type ds:datastore-ref;
mandatory true;
description
"Datastore from which to retrieve data.
If the datastore is not supported by the server, then
the server MUST return an <rpc-error> element with an
If the datastore is not supported by the server, then the
server MUST return an <rpc-error> element with an
<error-tag> value of 'invalid-value'.";
}
choice filter-spec {
@ -209,6 +201,7 @@ module ietf-netconf-list-pagination {
System state nodes are not affected by origin-filters and
thus not filtered. Note that system state nodes can be
filtered with the 'config-filter' leaf.";
leaf-list origin-filter {
type or:origin-ref;
description
@ -257,98 +250,138 @@ module ietf-netconf-list-pagination {
uses ncwd:with-defaults-parameters {
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 {
anyxml pageable-list {
anydata data {
description
"Return the list entries that were requested and matched
the filter criteria (if any). An empty data container
indicates that the request did not produce any results.";
"Copy of the source datastore subset that matched
the filter criteria (if any). An empty data
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'.";
}
}
}

View 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;
}
}

View 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.";
}
}

View file

@ -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.";
}
}
}