diff --git a/apps/backend/backend_client.c b/apps/backend/backend_client.c index d4f63a82..1f0058f5 100644 --- a/apps/backend/backend_client.c +++ b/apps/backend/backend_client.c @@ -1340,6 +1340,7 @@ from_client_kill_session(clicon_handle h, * If not "unbounded", parse and set a numeric value * @param[in] h Clixon handle * @param[in] name Name of attribute + * @param[in] defaultstr Default string which is accepted and sets value to 0 * @param[in,out] cbret Output buffer for internal RPC message * @param[out] value Value * @retval -1 Error @@ -1350,6 +1351,7 @@ static int element2value(clicon_handle h, cxobj *xe, char *name, + char *defaultstr, cbuf *cbret, uint32_t *value) { @@ -1362,14 +1364,14 @@ element2value(clicon_handle h, *value = 0; if ((x = xml_find_type(xe, NULL, name, CX_ELMNT)) != NULL && (valstr = xml_body(x)) != NULL && - strcmp(valstr, "unbounded") != 0){ + strcmp(valstr, defaultstr) != 0){ if ((ret = parse_uint32(valstr, value, &reason)) < 0){ clicon_err(OE_XML, errno, "parse_uint32"); goto done; } if (ret == 0){ - if (netconf_bad_attribute(cbret, "application", - "count", "Unrecognized value of count attribute") < 0) + if (netconf_bad_element(cbret, "application", + name, "Unrecognized value") < 0) goto done; goto fail; } @@ -1397,11 +1399,11 @@ element2value(clicon_handle h, * @see from_client_get */ static int -from_client_get_collection(clicon_handle h, - cxobj *xe, - cbuf *cbret, - void *arg, - void *regarg) +from_client_get_pageable_list(clicon_handle h, + cxobj *xe, + cbuf *cbret, + void *arg, + void *regarg) { int retval = -1; cxobj *x; @@ -1428,10 +1430,10 @@ from_client_get_collection(clicon_handle h, char *reason = NULL; cbuf *cb = NULL; cxobj *xtop = NULL; - cxobj *xbot = NULL; yang_stmt *y; - char *api_path = NULL; char *ns; + clixon_path *path_tree = NULL; + clixon_path *cp; clicon_debug(1, "%s", __FUNCTION__); username = clicon_username_get(h); @@ -1456,10 +1458,10 @@ from_client_get_collection(clicon_handle h, } } /* count */ - if ((ret = element2value(h, xe, "count", cbret, &count)) < 0) + if ((ret = element2value(h, xe, "count", "unbounded", cbret, &count)) < 0) goto done; /* skip */ - if (ret && (ret = element2value(h, xe, "skip", cbret, &skip)) < 0) + if (ret && (ret = element2value(h, xe, "skip", "none", cbret, &skip)) < 0) goto done; /* direction */ if (ret && (x = xml_find_type(xe, NULL, "direction", CX_ELMNT)) != NULL){ @@ -1479,35 +1481,45 @@ from_client_get_collection(clicon_handle h, if (ret && (x = xml_find_type(xe, NULL, "where", CX_ELMNT)) != NULL) where = xml_body(x); /* datastore */ - if (ret && (x = xml_find_type(xe, NULL, "datastore", CX_ELMNT)) != NULL) - datastore = xml_body(x); + if (ret && (x = xml_find_type(xe, NULL, "datastore", CX_ELMNT)) != NULL){ + if (nodeid_split(xml_body(x), NULL, &datastore) < 0) + goto done; + } if (ret == 0) goto ok; - /* list-target, create (xml and) yang to check if is state (CF) or config (CT) */ - if (ret && (x = xml_find_type(xe, NULL, "list-target", CX_ELMNT)) != NULL) - api_path = xml_body(x); + /* list-target, create (xml and) yang to check if is state (CF) or config (CT) + * is mandatory + */ + if (ret && (x = xml_find_type(xe, NULL, "list-target", CX_ELMNT)) != NULL){ + xpath = xml_body(x); + if (xml_nsctx_node(x, &nsc) < 0) + goto done; + } if ((xtop = xml_new("top", NULL, CX_ELMNT)) == NULL) goto done; - if ((ret = api_path2xml(api_path, yspec, xtop, YC_DATANODE, 0, &xbot, &y, &xerr)) < 0) - goto done; + if ((ret = clixon_instance_id_parse(yspec, &path_tree, "%s", xpath)) < 0) + goto done; if (ret == 0){ if (clicon_xml2cbuf(cbret, xerr, 0, 0, -1) < 0) goto done; goto ok; } + /* get last element */ + if ((cp = PREVQ(clixon_path *, path_tree)) == NULL){ + if (netconf_bad_element(cbret, "application", "list-target", "path invalid") < 0) + goto done; + goto ok; + } + if ((y = cp->cp_yang) == NULL){ + if (netconf_bad_element(cbret, "application", "list-target", "No yang associated with path") < 0) + goto done; + goto ok; + } if (yang_keyword_get(y) != Y_LIST && yang_keyword_get(y) != Y_LEAF_LIST){ if (netconf_bad_element(cbret, "application", "list-target", "path invalid") < 0) goto done; goto ok; } - /* Create xpath from api-path for the datastore API */ - if ((ret = api_path2xpath(api_path, yspec, &xpath, &nsc, &xerr)) < 0) - goto done; - if (ret == 0){ - if (clicon_xml2cbuf(cbret, xerr, 0, 0, -1) < 0) - goto done; - goto ok; - } /* Build a "predicate" cbuf */ if ((cb = cbuf_new()) == NULL){ clicon_err(OE_UNIX, errno, "cbuf_new"); @@ -1600,7 +1612,7 @@ from_client_get_collection(clicon_handle h, if (nacm_datanode_read(h, xret, xvec, xlen, username, xnacm) < 0) goto done; } - cprintf(cbret, "", + cprintf(cbret, "", NETCONF_BASE_NAMESPACE, NETCONF_COLLECTION_NAMESPACE); /* OK */ if ((ns = yang_find_mynamespace(y)) != NULL) for (i=0; i0?depth+1:depth) < 0) goto done; } - cprintf(cbret, ""); + cprintf(cbret, ""); ok: retval = 0; done: clicon_debug(1, "%s retval:%d", __FUNCTION__, retval); + if (datastore) + free(datastore); + if (path_tree) + clixon_path_free(path_tree); if (xtop) xml_free(xtop); if (cb) @@ -2260,8 +2276,8 @@ backend_rpc_init(clicon_handle h) NETCONF_BASE_NAMESPACE, "validate") < 0) goto done; /* draft-ietf-netconf-restconf-collection-00 */ - if (rpc_callback_register(h, from_client_get_collection, NULL, - NETCONF_COLLECTION_NAMESPACE, "get-collection") < 0) + if (rpc_callback_register(h, from_client_get_pageable_list, NULL, + NETCONF_COLLECTION_NAMESPACE, "get-pageable-list") < 0) goto done; /* In backend_client.? RPC from RFC 5277 */ if (rpc_callback_register(h, from_client_create_subscription, NULL, diff --git a/lib/clixon/clixon_path.h b/lib/clixon/clixon_path.h index e736d012..06b7d8fb 100644 --- a/lib/clixon/clixon_path.h +++ b/lib/clixon/clixon_path.h @@ -75,6 +75,7 @@ typedef struct { /* * Prototypes */ +int clixon_path_free(clixon_path *cplist); int xml_yang_root(cxobj *x, cxobj **xr); int yang2api_path_fmt(yang_stmt *ys, int inclkey, char **api_path_fmt); int api_path_fmt2api_path(const char *api_path_fmt, cvec *cvv, char **api_path, int *cvvi); @@ -90,10 +91,12 @@ int clixon_xml_find_api_path(cxobj *xt, yang_stmt *yt, cxobj ***xvec, int *xlen, int clixon_xml_find_instance_id(cxobj *xt, yang_stmt *yt, cxobj ***xvec, int *xlen, const char *format, ...) __attribute__ ((format (printf, 5, 6)));; int clixon_instance_id_bind(yang_stmt *yt, cvec *nsctx, const char *format, ...) __attribute__ ((format (printf, 3, 4))); +int clixon_instance_id_parse(yang_stmt *yt, clixon_path **cplistp, const char *format, ...) __attribute__ ((format (printf, 3, 4))); #else int clixon_xml_find_api_path(cxobj *xt, yang_stmt *yt, cxobj ***xvec, int *xlen, const char *format, ...); int clixon_xml_find_instance_id(cxobj *xt, yang_stmt *yt, cxobj ***xvec, int *xlen, const char *format, ...); int clixon_instance_id_bind(yang_stmt *yt, cvec *nsctx, const char *format, ...); +int clixon_instance_id_parse(yang_stmt *yt, clixon_path **cplistp, const char *format, ...); #endif #endif /* _CLIXON_PATH_H_ */ diff --git a/lib/clixon/clixon_xml.h b/lib/clixon/clixon_xml.h index 2aba4d99..5ea3e82f 100644 --- a/lib/clixon/clixon_xml.h +++ b/lib/clixon/clixon_xml.h @@ -56,7 +56,7 @@ /* Collections namespace from draft-ietf-netconf-restconf-collection-00.txt */ -#define NETCONF_COLLECTION_NAMESPACE "urn:ietf:params:xml:ns:yang:ietf-netconf-collection" +#define NETCONF_COLLECTION_NAMESPACE "urn:ietf:params:xml:ns:yang:ietf-netconf-list-pagination" /* Output symbol for netconf get/get-config * ietf-netconf.yang defines it as output: diff --git a/lib/src/clixon_netconf_lib.c b/lib/src/clixon_netconf_lib.c index 13eb0eff..291d106c 100644 --- a/lib/src/clixon_netconf_lib.c +++ b/lib/src/clixon_netconf_lib.c @@ -1527,7 +1527,7 @@ netconf_module_load(clicon_handle h) xml_bind_netconf_message_id_optional(1); #endif /* Load restconf collection */ - if (yang_spec_parse_module(h, "ietf-netconf-collection", NULL, yspec)< 0) + if (yang_spec_parse_module(h, "ietf-netconf-list-pagination", NULL, yspec)< 0) goto done; retval = 0; diff --git a/lib/src/clixon_path.c b/lib/src/clixon_path.c index 4dfacdb5..4c23cb03 100644 --- a/lib/src/clixon_path.c +++ b/lib/src/clixon_path.c @@ -196,7 +196,7 @@ instance_id_parse(char *path, return retval; } -static int +int clixon_path_free(clixon_path *cplist) { clixon_path *cp; @@ -1765,7 +1765,7 @@ clixon_xml_find_instance_id(cxobj *xt, * example. * @param[in] yt Yang statement of top symbol (can be yang-spec if top-level) * @param[out] nsctx Namespace context (should be created on entry) - * @param[in] format Format string for api-path syntax + * @param[in] format Format string for xpath syntax * @retval -1 Error * @retval 0 Non-fatal failure, yang bind failures, etc, * @retval 1 OK with found xml nodes in xvec (if any) @@ -1850,3 +1850,68 @@ clixon_instance_id_bind(yang_stmt *yt, retval = 0; goto done; } + +/*! Given (instance-id) path and YANG, parse path, resolve YANG and return parse-tree + * + * Instance-identifier is a subset of XML XPaths and defined in Yang, used in NACM for + * example. + * @param[in] yt Yang statement of top symbol (can be yang-spec if top-level) + * @param[out] cplistp Path parse-tree + * @param[in] format Format string for xpath syntax + * @retval -1 Error + * @retval 0 Non-fatal failure, yang bind failures, etc, + * @retval 1 OK with found xml nodes in xvec (if any) + */ +int +clixon_instance_id_parse(yang_stmt *yt, + clixon_path **cplistp, + const char *format, + ...) +{ + int retval = -1; + va_list ap; + size_t len; + char *path = NULL; + clixon_path *cplist = NULL; + int ret; + + va_start(ap, format); + len = vsnprintf(NULL, 0, format, ap); + va_end(ap); + /* allocate a path string exactly fitting the length */ + if ((path = malloc(len+1)) == NULL){ + clicon_err(OE_UNIX, errno, "malloc"); + goto done; + } + /* second round: actually compute api-path string content */ + va_start(ap, format); + if (vsnprintf(path, len+1, format, ap) < 0){ + clicon_err(OE_UNIX, errno, "vsnprintf"); + va_end(ap); + goto done; + } + va_end(ap); + if (instance_id_parse(path, &cplist) < 0) + goto done; + if (clicon_debug_get()) + clixon_path_print(stderr, cplist); + /* Resolve module:name to pointer to yang-stmt, fail if not successful */ + if ((ret = instance_id_resolve(cplist, yt)) < 0) + goto done; + if (ret == 0) + goto fail; + if (cplistp){ + *cplistp = cplist; + cplist = NULL; + } + retval = 1; + done: + if (cplist) + clixon_path_free(cplist); + if (path) + free(path); + return retval; + fail: + retval = 0; + goto done; +} diff --git a/lib/src/clixon_validate.c b/lib/src/clixon_validate.c index 99fc11d8..b7a7bd3c 100644 --- a/lib/src/clixon_validate.c +++ b/lib/src/clixon_validate.c @@ -1028,13 +1028,14 @@ xml_yang_validate_add(clicon_handle h, cxobj *xt, cxobj **xret) { - int retval = -1; - cg_var *cv = NULL; - char *reason = NULL; - yang_stmt *yt; /* yang spec of xt going in */ - char *body; - int ret; - cxobj *x; + int retval = -1; + cg_var *cv = NULL; + char *reason = NULL; + yang_stmt *yt; /* yang spec of xt going in */ + char *body; + int ret; + cxobj *x; + cg_var *cv0; enum cv_type cvtype; /* if not given by argument (overide) use default link @@ -1054,7 +1055,9 @@ xml_yang_validate_add(clicon_handle h, /* fall thru */ case Y_LEAF_LIST: /* validate value against ranges, etc */ - if ((cv = cv_dup(yang_cv_get(yt))) == NULL){ + if ((cv0 = yang_cv_get(yt)) == NULL) + break; + if ((cv = cv_dup(cv0)) == NULL){ clicon_err(OE_UNIX, errno, "cv_dup"); goto done; } diff --git a/lib/src/clixon_yang.c b/lib/src/clixon_yang.c index 49101cc5..c9085f67 100644 --- a/lib/src/clixon_yang.c +++ b/lib/src/clixon_yang.c @@ -1834,15 +1834,13 @@ yang_deviation(yang_stmt *ys, */ static int ys_populate_leaf(clicon_handle h, - yang_stmt *ys) + yang_stmt *ys) { int retval = -1; cg_var *cv = NULL; - yang_stmt *yparent; yang_stmt *ydef; enum cv_type cvtype = CGV_ERR; int cvret; - int ret; char *reason = NULL; yang_stmt *yrestype; /* resolved type */ char *restype; /* resolved type */ @@ -1851,7 +1849,6 @@ ys_populate_leaf(clicon_handle h, int options = 0x0; yang_stmt *ytypedef; /* where type is define */ - yparent = ys->ys_parent; /* Find parent: list/container */ /* 1. Find type specification and set cv type accordingly */ if (yang_type_get(ys, &origtype, &yrestype, &options, NULL, NULL, NULL, &fraction_digits) < 0) goto done; diff --git a/test/test_pagination.sh b/test/test_pagination.sh index 5debe9a3..3f5c55cf 100755 --- a/test/test_pagination.sh +++ b/test/test_pagination.sh @@ -1,13 +1,14 @@ #!/usr/bin/env bash # Restconf RFC8040 Appendix A and B "jukebox" example -# For collection / scaling activity +# For pagination / scaling I-D activity # Magic line must be first in script (see README.md) s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi APPNAME=example cfg=$dir/conf.xml -fjukebox=$dir/example-jukebox.yang +fexample=$dir/example-module.yang +fstate=$dir/mystate.xml cat < $cfg @@ -25,42 +26,250 @@ cat < $cfg EOF -cat < $dir/startup_db +cat <<'EOF' > $dir/startup_db - - - - Foo Fighters - - Crime and Punishment - 1995 - - - One by One - 2002 - - - The Color and the Shape - 1997 - - - There is Nothing Left to Loose - 1999 - - - White and Black - 1998 - - - - + + + Alice + permit + alice@example.com + $0$1543 + + 1 + 2 + + + Customer Service + 99 + + + Problem Solving + 90 + + + + Bob + limited + bob@example.com + $0$2789 + + 2 + 3 + + + Problem Solving + 98 + + + Conflict Resolution + 93 + + + + Joe + permit + joe@example.com + $0$6523 + + 1 + 4 + + + Management + 96 + + + Collaboration + 92 + + + + Frank + deny + frank@example.com + $0$4030 + + 5 + 9 + + + Organization + 90 + + + Negotiation + 80 + + + + Tom + permit + tom@example.com + $0$2376 + + 2 + 5 + + + Adaptability. + 98 + + + Active Listening + 85 + + + + + + SvrA-http + 92.0.2.0/24 + forwarding + + + SvrA-ftp + 203.0.113.1/32 + forwarding + + + p2p + p2p + logging + + + any + any + logging + + + SvrA-tcp + 80 + forwarding + + + + + 10.0.0.0/8 + 17 + 18 + + + 2000:1::/48 + 48 + 48 + + + 2000:2::/48 + 48 + 48 + + + 2000:3::/48 + 16 + 16 + + + ::/0 + 0 + 128 + + EOF -# Common Jukebox spec (fjukebox must be set) -. ./jukebox.sh +cat< $fstate + + + Alice + Available + + + Bob + Busy + + + Joe + Do Not Disturb + + + Frank + Offline + + + Tom + Do Not Disturb + + + + + Cloud-IoT-Device-A + 2020-07-08T12:38:32Z + 2020-07-08T12:37:12Z + Upload contains 6 datapoints + + + Cloud-IoT-Device-B + 2020-07-08T16:20:54Z + 2020-07-08T16:20:14Z + Upload successful + + + Cloud-IoT-Device-C + 2020-07-08T17:30:34Z + 2020-07-08T17:30:12Z + Receive a configuration update + + + Cloud-IoT-Device-D + 2020-07-08T18:40:13Z + 2020-07-08T18:40:00Z + Keep-alive ping sent to server + + + Cloud-IoT-Device-E + 2020-07-08T19:48:34Z + 2020-07-08T19:48:00Z + Uploading data to DataPoint + + + + + 192.168.0.92 + 2020-11-01T06:47:59Z + User-logged-out + true + + + 192.168.0.92 + 2020-11-01T06:49:03Z + User-logged-in + true + + + 192.168.0.92 + 2020-11-01T06:51:34Z + Patron-card-viewed + false + + + 192.168.0.92 + 2020-11-01T06:53:01Z + User-logged-out + true + + + 192.168.0.92 + 2020-11-01T06:56:22Z + User-logged-in + false + + +EOF -new "test params: -f $cfg -- -s" # XXX: -sS state file +# Common example-module spec (fexample must be set) +. ./example_module.sh + +new "test params: -f $cfg -s startup -- -sS $fstate" if [ $BE -ne 0 ]; then new "kill old backend" @@ -69,8 +278,8 @@ if [ $BE -ne 0 ]; then err fi sudo pkill -f clixon_backend # to be sure - new "start backend -s startup -f $cfg" - start_backend -s startup -f "$cfg" + new "start backend -s startup -f $cfg -- -sS $mystate" + start_backend -s startup -f $cfg -- -sS $fstate fi new "waiting" @@ -87,12 +296,13 @@ if [ $RC -ne 0 ]; then wait_restconf fi +new "C.1. 'count' Parameter NETCONF" +expecteof "$clixon_netconf -qf $cfg" 0 "ds:running/exm:admins/exm:admin[exm:name='Bob']/exm:skill2]]>]]>" 'Conflict Resolution93Problem Solving98]]>]]>$' + +if false; then # XXX notyet new "C.1. 'count' Parameter RESTCONF" expectpart "$(curl $CURLOPTS -X GET -H "Accept: application/yang.collection+xml" $RCPROTO://localhost/restconf/data/example-jukebox:jukebox/library/artist=Foo%20Fighters/album/?count=2)" 0 "HTTP/1.1 200 OK" "application/yang.collection+xml" 'Crime and Punishment1995One by One2002' - -new "C.1. 'count' Parameter NETCONF" -expecteof "$clixon_netconf -qf $cfg" 0 "runningexample-jukebox/example-jukebox:jukebox/library/artist=Foo Fighters/album2]]>]]>" '^Crime and Punishment1995One by One2002]]>]]>$' - +fi if [ $RC -ne 0 ]; then new "Kill restconf daemon" stop_restconf diff --git a/yang/mandatory/Makefile.in b/yang/mandatory/Makefile.in index f2fb8c9d..a1ef6281 100644 --- a/yang/mandatory/Makefile.in +++ b/yang/mandatory/Makefile.in @@ -50,7 +50,14 @@ YANGSPECS += ietf-restconf-monitoring@2017-01-26.yang YANGSPECS += ietf-yang-library@2019-01-04.yang YANGSPECS += ietf-yang-types@2013-07-15.yang YANGSPECS += ietf-datastores@2018-02-14.yang +<<<<<<< HEAD YANGSPECS += ietf-yang-patch@2017-02-22.yang +======= +YANGSPECS += ietf-netconf-list-pagination@2020-10-30.yang +YANGSPECS += ietf-origin@2018-02-14.yang +YANGSPECS += ietf-yang-metadata@2016-08-05.yang +YANGSPECS += ietf-netconf-with-defaults@2011-06-01.yang +>>>>>>> Pagination draft all: diff --git a/yang/mandatory/ietf-netconf-list-pagination@2020-10-30.yang b/yang/mandatory/ietf-netconf-list-pagination@2020-10-30.yang new file mode 100644 index 00000000..d7e421aa --- /dev/null +++ b/yang/mandatory/ietf-netconf-list-pagination@2020-10-30.yang @@ -0,0 +1,329 @@ +module ietf-netconf-list-pagination { + yang-version 1.1; + namespace "urn:ietf:params:xml:ns:yang:ietf-netconf-list-pagination"; + prefix ycoll; + + 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-netconf { + prefix nc; + reference + "RFC 6241: Network Configuration Protocol (NETCONF)"; + } + import ietf-netconf-with-defaults { + prefix ncwd; + reference + "RFC 6243: With-defaults Capability for NETCONF"; + } + + organization + "IETF NETCONF (Network Configuration) Working Group"; + contact + "WG Web: + WG List: + + Editor: + + Editor: + + Editor: "; + description + "This module define a new operation -- + 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."; + + revision 2020-10-30 { + description + "Initial revision."; + reference + "RFC XXXX: YANG Based Pagination."; + } + + feature origin { + description + "Indicates that the server supports the 'origin' annotation."; + reference + "RFC 8342: Network Management Datastore Architecture (NMDA)"; + } + + feature with-defaults { + description + "NETCONF :with-defaults capability. If the server advertises + the :with-defaults capability for a session, then this + feature must also be enabled for that session. Otherwise, + this feature must not be enabled."; + 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"; + } + + rpc get-pageable-list { + 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. + + Any ancestor nodes (including list keys) of nodes selected by + the filters are included in the response. + + The 'with-origin' parameter is only valid for an operational + datastore. If 'with-origin' is used with an invalid + datastore, then the server MUST return an element + with an value of 'invalid-value'. + + The 'with-defaults' parameter only applies to the operational + datastore if the NETCONF :with-defaults and + :with-operational-defaults capabilities are both advertised. + If the 'with-defaults' parameter is present in a request for + which it is not supported, then the server MUST return an + element with an value of + 'invalid-value'."; + input { + 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 element with an + value of 'invalid-value'."; + } + choice filter-spec { + description + "The content filter specification for this request."; + anydata subtree-filter { + description + "This parameter identifies the portions of the + target datastore to retrieve."; + reference + "RFC 6241: Network Configuration Protocol (NETCONF), + Section 6"; + } + leaf xpath-filter { + if-feature "nc:xpath"; + type yang:xpath1.0; + description + "This parameter contains an XPath expression identifying + the portions of the target datastore to retrieve. + + If the expression returns a node-set, all nodes in the + node-set are selected by the filter. Otherwise, if the + expression does not return a node-set, then the + operation fails. + + The expression is evaluated in the following XPath + context: + + o The set of namespace declarations are those in + scope on the 'xpath-filter' leaf element. + + o The set of variable bindings is empty. + + o The function library is the core function library, + and the XPath functions are defined in Section 10 + of RFC 7950. + + o The context node is the root node of the target + datastore."; + } + } + leaf config-filter { + type boolean; + description + "Filter for nodes with the given value for their 'config' + property. When this leaf is set to 'true', only 'config + true' nodes are selected, and when set to 'false', only + 'config false' nodes are selected. If this leaf is not + present, no nodes are filtered."; + } + choice origin-filters { + when 'derived-from-or-self(datastore, "ds:operational")'; + if-feature "origin"; + description + "Filters configuration nodes based on the 'origin' + annotation. Configuration nodes that do not have an + 'origin' annotation are treated as if they have the + 'origin' annotation 'or:unknown'. + + 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 + "Filter based on the 'origin' annotation. A + configuration node matches the filter if its 'origin' + annotation is derived from or equal to any of the given + filter values."; + } + leaf-list negated-origin-filter { + type or:origin-ref; + description + "Filter based on the 'origin' annotation. A + configuration node matches the filter if its 'origin' + annotation is neither derived from nor equal to any of + the given filter values."; + } + } + leaf max-depth { + type union { + type uint16 { + range "1..65535"; + } + type enumeration { + enum unbounded { + description + "All descendant nodes are included."; + } + } + } + default "unbounded"; + description + "For each node selected by the filters, this parameter + selects how many conceptual subtree levels should be + returned in the reply. If the depth is 1, the reply + includes just the selected nodes but no children. If the + depth is 'unbounded', all descendant nodes are included."; + } + leaf with-origin { + when 'derived-from-or-self(../datastore, "ds:operational")'; + if-feature "origin"; + type empty; + description + "If this parameter is present, the server will return + the 'origin' annotation for the nodes that have one."; + } + 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 count { + 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 skip { + 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 { + 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."; + } + } + } +} diff --git a/yang/mandatory/ietf-netconf-with-defaults@2011-06-01.yang b/yang/mandatory/ietf-netconf-with-defaults@2011-06-01.yang new file mode 100644 index 00000000..8a7be8c2 --- /dev/null +++ b/yang/mandatory/ietf-netconf-with-defaults@2011-06-01.yang @@ -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: + + WG List: + + WG Chair: Bert Wijnen + + + WG Chair: Mehmet Ersue + + + Editor: Andy Bierman + + + Editor: Balazs Lengyel + "; + + 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 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 parameter to the + input of the NETCONF operation."; + reference + "RFC 6243; Section 4.5.1"; + + uses with-defaults-parameters; + } + + // extending the get operation + augment /nc:get/nc:input { + description + "Adds the parameter to + the input of the NETCONF 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 parameter to + the input of the NETCONF operation."; + reference + "RFC 6243; Section 4.5.1"; + + uses with-defaults-parameters; + } + +} diff --git a/yang/mandatory/ietf-origin@2018-02-14.yang b/yang/mandatory/ietf-origin@2018-02-14.yang new file mode 100644 index 00000000..3080c911 --- /dev/null +++ b/yang/mandatory/ietf-origin@2018-02-14.yang @@ -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: + + WG List: + + Author: Martin Bjorklund + + + Author: Juergen Schoenwaelder + + + Author: Phil Shafer + + + Author: Kent Watsen + + + Author: Rob Wilton + "; + + 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."; + } +} diff --git a/yang/mandatory/ietf-yang-metadata@2016-08-05.yang b/yang/mandatory/ietf-yang-metadata@2016-08-05.yang new file mode 100644 index 00000000..5939eebe --- /dev/null +++ b/yang/mandatory/ietf-yang-metadata@2016-08-05.yang @@ -0,0 +1,84 @@ +module ietf-yang-metadata { + + namespace "urn:ietf:params:xml:ns:yang:ietf-yang-metadata"; + + prefix "md"; + + organization + "IETF NETMOD (NETCONF Data Modeling Language) Working Group"; + + contact + "WG Web: + + WG List: + + WG Chair: Lou Berger + + + WG Chair: Kent Watsen + + + Editor: Ladislav Lhotka + "; + + description + "This YANG module defines an 'extension' statement that allows + for defining metadata annotations. + + Copyright (c) 2016 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 7952 + (http://www.rfc-editor.org/info/rfc7952); see the RFC itself + for full legal notices."; + + revision 2016-08-05 { + description + "Initial revision."; + reference + "RFC 7952: Defining and Using Metadata with YANG"; + } + + extension annotation { + argument name; + description + "This extension allows for defining metadata annotations in + YANG modules. The 'md:annotation' statement can appear only + at the top level of a YANG module or submodule, i.e., it + becomes a new alternative in the ABNF production rule for + 'body-stmts' (Section 14 in RFC 7950). + + The argument of the 'md:annotation' statement defines the name + of the annotation. Syntactically, it is a YANG identifier as + defined in Section 6.2 of RFC 7950. + + An annotation defined with this 'extension' statement inherits + the namespace and other context from the YANG module in which + it is defined. + + The data type of the annotation value is specified in the same + way as for a leaf data node using the 'type' statement. + + The semantics of the annotation and other documentation can be + specified using the following standard YANG substatements (all + are optional): 'description', 'if-feature', 'reference', + 'status', and 'units'. + + A server announces support for a particular annotation by + including the module in which the annotation is defined among + the advertised YANG modules, e.g., in a NETCONF + message or in the YANG library (RFC 7950). The annotation can + then be attached to any instance of a data node defined in any + YANG module that is advertised by the server. + + XML encoding and JSON encoding of annotations are defined in + RFC 7952."; + } +} diff --git a/yang/optional/Makefile.in b/yang/optional/Makefile.in index 9733e39b..a7b3e1e3 100644 --- a/yang/optional/Makefile.in +++ b/yang/optional/Makefile.in @@ -47,6 +47,7 @@ YANGSPECS += ietf-interfaces@2018-02-20.yang YANGSPECS += ietf-ip@2014-06-16.yang YANGSPECS += ietf-netconf-monitoring@2010-10-04.yang YANGSPECS += ietf-routing@2018-03-13.yang +YANGSPECS += iana-crypt-hash@2014-08-06.yang # collection example-module all: diff --git a/yang/optional/iana-crypt-hash@2014-08-06.yang b/yang/optional/iana-crypt-hash@2014-08-06.yang new file mode 100644 index 00000000..44c4674f --- /dev/null +++ b/yang/optional/iana-crypt-hash@2014-08-06.yang @@ -0,0 +1,120 @@ +module iana-crypt-hash { + namespace "urn:ietf:params:xml:ns:yang:iana-crypt-hash"; + prefix ianach; + + organization "IANA"; + contact + " Internet Assigned Numbers Authority + + Postal: ICANN + 12025 Waterfront Drive, Suite 300 + Los Angeles, CA 90094-2536 + United States + + Tel: +1 310 301 5800 + E-Mail: iana@iana.org>"; + description + "This YANG module defines a type for storing passwords + using a hash function and features to indicate which hash + functions are supported by an implementation. + + The latest revision of this YANG module can be obtained from + the IANA web site. + + Requests for new values should be made to IANA via + email (iana@iana.org). + + Copyright (c) 2014 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). + + The initial version of this YANG module is part of RFC 7317; + see the RFC itself for full legal notices."; + + revision 2014-08-06 { + description + "Initial revision."; + reference + "RFC 7317: A YANG Data Model for System Management"; + } + + typedef crypt-hash { + type string { + pattern + '$0$.*' + + '|$1$[a-zA-Z0-9./]{1,8}$[a-zA-Z0-9./]{22}' + + '|$5$(rounds=\d+$)?[a-zA-Z0-9./]{1,16}$[a-zA-Z0-9./]{43}' + + '|$6$(rounds=\d+$)?[a-zA-Z0-9./]{1,16}$[a-zA-Z0-9./]{86}'; + } + description + "The crypt-hash type is used to store passwords using + a hash function. The algorithms for applying the hash + function and encoding the result are implemented in + various UNIX systems as the function crypt(3). + + A value of this type matches one of the forms: + + $0$ + $$$ + $$$$ + + The '$0$' prefix signals that the value is clear text. When + such a value is received by the server, a hash value is + calculated, and the string '$$$' or + $$$$ is prepended to the result. This + value is stored in the configuration data store. + If a value starting with '$$', where is not '0', is + received, the server knows that the value already represents a + hashed value and stores it 'as is' in the data store. + + When a server needs to verify a password given by a user, it + finds the stored password hash string for that user, extracts + the salt, and calculates the hash with the salt and given + password as input. If the calculated hash value is the same + as the stored value, the password given by the client is + accepted. + + This type defines the following hash functions: + + id | hash function | feature + ---+---------------+------------------- + 1 | MD5 | crypt-hash-md5 + 5 | SHA-256 | crypt-hash-sha-256 + 6 | SHA-512 | crypt-hash-sha-512 + + The server indicates support for the different hash functions + by advertising the corresponding feature."; + reference + "IEEE Std 1003.1-2008 - crypt() function + RFC 1321: The MD5 Message-Digest Algorithm + FIPS.180-4.2012: Secure Hash Standard (SHS)"; + } + + feature crypt-hash-md5 { + description + "Indicates that the device supports the MD5 + hash function in 'crypt-hash' values."; + reference "RFC 1321: The MD5 Message-Digest Algorithm"; + } + + feature crypt-hash-sha-256 { + description + "Indicates that the device supports the SHA-256 + hash function in 'crypt-hash' values."; + reference "FIPS.180-4.2012: Secure Hash Standard (SHS)"; + } + + feature crypt-hash-sha-512 { + description + "Indicates that the device supports the SHA-512 + hash function in 'crypt-hash' values."; + reference "FIPS.180-4.2012: Secure Hash Standard (SHS)"; + } + +}