Merge branch 'topic_benavrhm_rfc8527a_20201103' of https://github.com/benavrhm/clixon into benavrhm-topic_benavrhm_rfc8527a_20201103

This commit is contained in:
Olof hagsand 2020-11-11 13:41:05 +01:00
commit a0006075c3
26 changed files with 921 additions and 792 deletions

5
.gitignore vendored
View file

@ -51,11 +51,12 @@ build-root/*.rpm
build-root/rpmbuild
util/clixon_util_datastore
util/clixon_util_insert
util/clixon_util_grpc
util/clixon_util_json
util/clixon_util_path
util/clixon_util_regexp
util/clixon_util_socket
util/clixon_util_ssl
util/clixon_util_stream
util/clixon_util_xml
util/clixon_util_xml_mod
@ -66,4 +67,4 @@ test/config.sh
test/site.sh
test/vagrant/site.mk
test/cicd/site.mk
doc/html
doc/html

View file

@ -56,6 +56,18 @@ enum restconf_media{
};
typedef enum restconf_media restconf_media;
/* @See https://tools.ietf.org/html/rfc8342, ietf-datastores@2018-02-14.yang */
enum ietf_ds {
IETF_DS_NONE = 0,
IETF_DS_RUNNING,
IETF_DS_CANDIDATE,
IETF_DS_STARTUP,
IETF_DS_INTENDED,
IETF_DS_DYNAMIC,
IETF_DS_OPERATIONAL
};
typedef enum ietf_ds ietf_ds_t;
/*
* Prototypes
*/

View file

@ -230,6 +230,7 @@ match_list_keys(yang_stmt *y,
* PUT: If it does not, set op to create, otherwise replace
* PATCH: If it does not, fail, otherwise replace/merge
* @param[in] plain_patch fail if object does not exists AND merge (not replace)
* @param[in] ds 0 if "data" resource, 1 if rfc8527 "ds" resource
*/
static int
api_data_write(clicon_handle h,
@ -242,7 +243,8 @@ api_data_write(clicon_handle h,
int pretty,
restconf_media media_in,
restconf_media media_out,
int plain_patch)
int plain_patch,
ietf_ds_t ds)
{
int retval = -1;
enum operation_type op;
@ -596,12 +598,12 @@ api_data_write(clicon_handle h,
NETCONF_BASE_NAMESPACE); /* bind nc to netconf namespace */
cprintf(cbx, "<edit-config");
/* RFC8040 Sec 1.4:
* If the NETCONF server supports :startup, the RESTCONF server MUST
* automatically update the non-volatile startup configuration
* datastore, after the "running" datastore has been altered as a
* consequence of a RESTCONF edit operation.
* If this is a "data" request and the NETCONF server supports :startup,
* the RESTCONF server MUST automatically update the non-volatile startup
* configuration datastore, after the "running" datastore has been altered
* as a consequence of a RESTCONF edit operation.
*/
if (if_feature(yspec, "ietf-netconf", "startup"))
if ((IETF_DS_NONE == ds) && if_feature(yspec, "ietf-netconf", "startup"))
cprintf(cbx, " copystartup=\"true\"");
cprintf(cbx, " autocommit=\"true\"");
cprintf(cbx, "><target><candidate /></target>");
@ -695,13 +697,14 @@ api_data_put(clicon_handle h,
cvec *qvec,
char *data,
int pretty,
restconf_media media_out)
restconf_media media_out,
ietf_ds_t ds)
{
restconf_media media_in;
media_in = restconf_content_type(h);
return api_data_write(h, req, api_path0, pcvec, pi, qvec, data, pretty,
media_in, media_out, 0);
media_in, media_out, 0, ds);
}
/*! Generic REST PATCH method for plain patch
@ -730,7 +733,8 @@ api_data_patch(clicon_handle h,
cvec *qvec,
char *data,
int pretty,
restconf_media media_out)
restconf_media media_out,
ietf_ds_t ds)
{
restconf_media media_in;
int ret;
@ -740,7 +744,7 @@ api_data_patch(clicon_handle h,
case YANG_DATA_XML:
case YANG_DATA_JSON: /* plain patch */
ret = api_data_write(h, req, api_path0, pcvec, pi, qvec, data, pretty,
media_in, media_out, 1);
media_in, media_out, 1, ds);
break;
case YANG_PATCH_XML:
case YANG_PATCH_JSON: /* RFC 8072 patch */
@ -760,6 +764,7 @@ api_data_patch(clicon_handle h,
* @param[in] pi Offset, where path starts
* @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
* See RFC 8040 Sec 4.7
* Example:
* curl -X DELETE http://127.0.0.1/restconf/data/interfaces/interface=eth0
@ -771,7 +776,8 @@ api_data_delete(clicon_handle h,
char *api_path,
int pi,
int pretty,
restconf_media media_out)
restconf_media media_out,
ietf_ds_t ds)
{
int retval = -1;
int i;
@ -834,12 +840,12 @@ api_data_delete(clicon_handle h,
cprintf(cbx, "<edit-config");
/* RFC8040 Sec 1.4:
* If the NETCONF server supports :startup, the RESTCONF server MUST
* automatically update the non-volatile startup configuration
* datastore, after the "running" datastore has been altered as a
* consequence of a RESTCONF edit operation.
* If this is a "data" request and the NETCONF server supports :startup,
* the RESTCONF server MUST automatically update the non-volatile startup
* configuration datastore, after the "running" datastore has been altered
* as a consequence of a RESTCONF edit operation.
*/
if (if_feature(yspec, "ietf-netconf", "startup"))
if ((IETF_DS_NONE == ds) && if_feature(yspec, "ietf-netconf", "startup"))
cprintf(cbx, " copystartup=\"true\"");
cprintf(cbx, " autocommit=\"true\"");
cprintf(cbx, "><target><candidate /></target>");

View file

@ -46,14 +46,14 @@ int api_data_options(clicon_handle h, void *req);
int api_data_put(clicon_handle h, void *req, char *api_path,
cvec *pcvec, int pi,
cvec *qvec, char *data,
int pretty, restconf_media media_out);
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,
cvec *qvec, char *data, int pretty,
restconf_media media_out);
restconf_media media_out, ietf_ds_t ds);
int api_data_delete(clicon_handle h, void *req, char *api_path, int pi,
int pretty, restconf_media media_out);
int pretty, restconf_media media_out, ietf_ds_t ds);
#endif /* _RESTCONF_METHODS_H_ */

View file

@ -363,7 +363,8 @@ api_data_head(clicon_handle h,
int pi,
cvec *qvec,
int pretty,
restconf_media media_out)
restconf_media media_out,
ietf_ds_t ds)
{
return api_data_get2(h, req, api_path, pcvec, pi, qvec, pretty, media_out, 1);
}
@ -402,7 +403,8 @@ api_data_get(clicon_handle h,
int pi,
cvec *qvec,
int pretty,
restconf_media media_out)
restconf_media media_out,
ietf_ds_t ds)
{
return api_data_get2(h, req, api_path, pcvec, pi, qvec, pretty, media_out, 0);
}

View file

@ -42,9 +42,9 @@
* Prototypes
*/
int api_data_head(clicon_handle h, void *req, char *api_path, cvec *pcvec, int pi,
cvec *qvec, int pretty, restconf_media media_out);
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,
cvec *qvec, int pretty, restconf_media media_out);
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,
int pretty, restconf_media media_out);

View file

@ -152,7 +152,8 @@ api_data_post(clicon_handle h,
cvec *qvec,
char *data,
int pretty,
restconf_media media_out)
restconf_media media_out,
ietf_ds_t ds)
{
int retval = -1;
enum operation_type op = OP_CREATE;
@ -377,12 +378,12 @@ api_data_post(clicon_handle h,
cprintf(cbx, "<edit-config");
/* RFC8040 Sec 1.4:
* If the NETCONF server supports :startup, the RESTCONF server MUST
* automatically update the non-volatile startup configuration
* datastore, after the "running" datastore has been altered as a
* consequence of a RESTCONF edit operation.
* If this is a "data" request and the NETCONF server supports :startup,
* the RESTCONF server MUST automatically update the non-volatile startup
* configuration datastore, after the "running" datastore has been altered
* as a consequence of a RESTCONF edit operation.
*/
if (if_feature(yspec, "ietf-netconf", "startup"))
if ((IETF_DS_NONE == ds) && if_feature(yspec, "ietf-netconf", "startup"))
cprintf(cbx, " copystartup=\"true\"");
cprintf(cbx, " autocommit=\"true\"");
cprintf(cbx, "><target><candidate /></target>");

View file

@ -44,7 +44,7 @@
int api_data_post(clicon_handle h, void *req, char *api_path,
int pi, cvec *qvec, char *data,
int pretty,
restconf_media media_out);
restconf_media media_out, ietf_ds_t ds);
int api_operations_post(clicon_handle h, void *req, char *api_path,
int pi, cvec *qvec, char *data,

View file

@ -153,7 +153,8 @@ api_root_restconf_exact(clicon_handle h,
goto done;
if (clixon_xml_parse_string("<restconf xmlns=\"urn:ietf:params:xml:ns:yang:ietf-restconf\"><data/>"
"<operations/><yang-library-version>2016-06-21</yang-library-version></restconf>",
"<operations/><yang-library-version>" IETF_YANG_LIBRARY_REVISION
"</yang-library-version></restconf>",
YB_MODULE, yspec, &xt, NULL) < 0)
goto done;
@ -187,6 +188,24 @@ api_root_restconf_exact(clicon_handle h,
return retval;
}
/** A stub implementation of the operational state datastore. The full
* implementation is required by https://tools.ietf.org/html/rfc8527#section-3.1
*/
static int
api_operational_state(clicon_handle h,
void *req,
char *request_method,
int pretty,
restconf_media media_out)
{
clicon_debug(1, "%s request method:%s", __FUNCTION__, request_method);
/* We are not implementing this method at this time, 20201105 despite it
* being mandatory https://tools.ietf.org/html/rfc8527#section-3.1 */
return restconf_notimplemented(req);
}
/*!
* See https://tools.ietf.org/html/rfc7895
*/
@ -200,7 +219,6 @@ api_yang_library_version(clicon_handle h,
int retval = -1;
cxobj *xt = NULL;
cbuf *cb = NULL;
char *ietf_yang_library_revision = "2016-06-21"; /* XXX */
clicon_debug(1, "%s", __FUNCTION__);
if (restconf_reply_header(req, "Content-Type", "%s", restconf_media_int2str(media_out)) < 0)
@ -209,7 +227,7 @@ api_yang_library_version(clicon_handle h,
goto done;
if (clixon_xml_parse_va(YB_NONE, NULL, &xt, NULL,
"<yang-library-version>%s</yang-library-version>",
ietf_yang_library_revision) < 0)
IETF_YANG_LIBRARY_REVISION) < 0)
goto done;
if (xml_rootchild(xt, 0, &xt) < 0)
goto done;
@ -250,6 +268,7 @@ api_yang_library_version(clicon_handle h,
* @param[in] pretty Set to 1 for pretty-printed xml/json output
* @param[in] media_in Input media
* @param[in] media_out Output media
* @param[in] ds 0 if "data" resource, 1 if rfc8527 "ds" resource
*/
static int
api_data(clicon_handle h,
@ -260,28 +279,58 @@ api_data(clicon_handle h,
cvec *qvec,
char *data,
int pretty,
restconf_media media_out)
restconf_media media_out,
ietf_ds_t ds)
{
int retval = -1;
int read_only = 0, dynamic = 0;
char *request_method;
clicon_debug(1, "%s", __FUNCTION__);
request_method = restconf_param_get(h, "REQUEST_METHOD");
clicon_debug(1, "%s method:%s", __FUNCTION__, request_method);
/* https://tools.ietf.org/html/rfc8527#section-3.2 */
/* We assume that dynamic datastores are read only at this time 20201105 */
if (IETF_DS_DYNAMIC == ds)
dynamic = 1;
if ((IETF_DS_INTENDED == ds) || (IETF_DS_RUNNING == ds)
|| (IETF_DS_DYNAMIC == ds) || (IETF_DS_OPERATIONAL == ds)) {
read_only = 1;
}
if (strcmp(request_method, "OPTIONS")==0)
retval = api_data_options(h, req);
else if (strcmp(request_method, "HEAD")==0)
retval = api_data_head(h, req, api_path, pcvec, pi, qvec, pretty, media_out);
else if (strcmp(request_method, "GET")==0)
retval = api_data_get(h, req, api_path, pcvec, pi, qvec, pretty, media_out);
else if (strcmp(request_method, "POST")==0)
retval = api_data_post(h, req, api_path, pi, qvec, data, pretty, media_out);
else if (strcmp(request_method, "PUT")==0)
retval = api_data_put(h, req, api_path, pcvec, pi, qvec, data, pretty, media_out);
else if (strcmp(request_method, "PATCH")==0)
retval = api_data_patch(h, req, api_path, pcvec, pi, qvec, data, pretty, media_out);
else if (strcmp(request_method, "DELETE")==0)
retval = api_data_delete(h, req, api_path, pi, pretty, media_out);
else if (strcmp(request_method, "HEAD")==0) {
if (dynamic) {
retval = restconf_method_notallowed(req, "GET,POST");
}
retval = api_data_head(h, req, api_path, pcvec, 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);
}
else if (strcmp(request_method, "POST")==0) {
retval = api_data_post(h, req, api_path, pi, qvec, data, pretty, media_out, ds);
}
else if (strcmp(request_method, "PUT")==0) {
if (read_only) {
retval = restconf_method_notallowed(req, "GET,POST");
}
retval = api_data_put(h, req, api_path, pcvec, pi, qvec, data, pretty, media_out, ds);
}
else if (strcmp(request_method, "PATCH")==0) {
if (read_only) {
retval = restconf_method_notallowed(req, "GET,POST");
}
retval = api_data_patch(h, req, api_path, pcvec, pi, qvec, data, pretty, media_out, ds);
}
else if (strcmp(request_method, "DELETE")==0) {
if (read_only) {
retval = restconf_method_notallowed(req, "GET,POST");
}
retval = api_data_delete(h, req, api_path, pi, pretty, media_out, ds);
}
else
retval = restconf_notfound(h, req);
clicon_debug(1, "%s retval:%d", __FUNCTION__, retval);
@ -441,7 +490,41 @@ api_root_restconf(clicon_handle h,
}
else if (strcmp(api_resource, "data") == 0){ /* restconf, skip /api/data */
if (api_data(h, req, path, pcvec, 2, qvec, indata,
pretty, media_out) < 0)
pretty, media_out, IETF_DS_NONE) < 0)
goto done;
}
else if (strcmp(api_resource, "ds") == 0) {
/* We should really be getting the supported datastore types from the
* application model, but at this time the datastore model of startup/
* running/cadidate is hardcoded into the clixon implementation. 20201104 */
ietf_ds_t ds = IETF_DS_NONE;
if (4 > pn) { /* Malformed request, no "ietf-datastores:<datastore>" component */
restconf_notfound(h, req);
goto done;
}
/* Assign ds; See https://tools.ietf.org/html/rfc8342#section-7 */
if (0 == strcmp(pvec[3], "ietf-datastores:running"))
ds = IETF_DS_RUNNING;
else if (0 == strcmp(pvec[3], "ietf-datastores:candidate"))
ds = IETF_DS_CANDIDATE;
else if (0 == strcmp(pvec[3], "ietf-datastores:startup"))
ds = IETF_DS_STARTUP;
else if (0 == strcmp(pvec[3], "ietf-datastores:operational")) {
/* See https://tools.ietf.org/html/rfc8527#section-3.1
* https://tools.ietf.org/html/rfc8342#section-5.3 */
if (0 > api_operational_state(h, req, request_method, pretty, media_out)) {
goto done;
}
goto ok;
}
else { /* Malformed request, unsupported datastore type */
restconf_notfound(h, req);
goto done;
}
/* ds is assigned at this point */
if (0 > api_data(h, req, path, pcvec, 3, qvec, indata, pretty, media_out, ds))
goto done;
}
else if (strcmp(api_resource, "operations") == 0){ /* rpc */

View file

@ -42,6 +42,7 @@
* Constants
*/
#define RESTCONF_API "restconf"
#define IETF_YANG_LIBRARY_REVISION "2019-01-04"
/* RESTCONF enables deployments to specify where the RESTCONF API is
located. The client discovers this by getting the "/.well-known/host-meta"

View file

@ -56,7 +56,7 @@ As restconf using curl on exposed port 80:
"ietf-restconf:restconf": {
"data": {},
"operations": {},
"yang-library-version": "2016-06-21"
"yang-library-version": "2019-01-04"
}
}
```

View file

@ -26,6 +26,9 @@ module clixon-example {
import iana-if-type {
prefix ianaift;
}
import ietf-datastores {
prefix ds;
}
/* Example interface type for tests, local callbacks, etc */
identity eth {

View file

@ -1,13 +1,27 @@
#!/usr/bin/env bash
# Run, eg as:
# ./all.sh 2>&1 | tee test.log # break on first test
# Run test_*.sh tests, stop on error, verbose logging, no pass/fail summary.
#
# This script requires the user to be in the sudo group.
#
# The 'pattern' variable determines which test files to execute.
# By default, run all the tests in the test_*.sh files in this directory.
# Pattern to run tests, default is all, but you may want to narrow it down
: ${pattern:=test_*.sh}
# You can specify tests files to exclude using the 'SKIPLIST' variable in a
# site.sh file. See example in README.md. Files excluded by the 'SKIPLIST'
# variable have precedence over files included by the 'pattern' variable.
# This script does not take arguments, so if arguments exist, print the Usage
# in http://docopt.org/ format.
if [ $# -gt 0 ]; then
echo "usage: $0 # detailed logs and stop on first error. Use pattern=\"\" $0 to"
echo " Use pattern=<pattern> $0 to narrow down test cases"
echo "Usage:"
echo " $0 # Run all 'test_*.sh' files"
echo " pattern=<Bash glob pattern> $0 # Run only files matching the pattern"
echo ""
echo "Example:"
echo " ${0} 2>&1 | tee test.log # Run all tests, output to 'test.log'"
echo " pattern=test_feature.sh ${0} # Run only the tests in 'test_feature.sh'"
exit -1
fi

View file

@ -1,5 +1,9 @@
#!/usr/bin/env bash
# Define test functions.
# See numerous configuration variables later on in this file that you can set
# in the environment or the site.sh file. The definitions in the site.sh file
# override
#
# Create working dir as variable "dir"
# The functions are somewhat wildgrown, a little too many:
# - expectfn
@ -17,8 +21,11 @@
# Testfile (not including path)
: ${testfile:=$(basename $0)}
# Add test to this list that you dont want run
# Typically add them in your site file
# SKIPLIST lists the filenames of the test files that you do *not* want to run.
# The format is a whitespace separated list of filenames. Specify the SKIPLIST
# either in the shell environment or in the site.sh file. Any SKIPLIST specified
# in site.sh overrides a SKIPLIST specified in the environment. If not specified
# in either the environment or the site.sh, then the default SKIPLIST is empty.
: ${SKIPLIST:=""}
# Some tests (openconfig/yang_models) just test for the cli to return a version
@ -34,21 +41,6 @@ if [ -f ./config.sh ]; then
fi
fi
# Site file, an example of this file in README.md
if [ -f ./site.sh ]; then
. ./site.sh
if [ $? -ne 0 ]; then
return -1 # skip
fi
# test skiplist.
for f in $SKIPLIST; do
if [ "$testfile" = "$f" ]; then
echo "...skipped (see site.sh)"
return -1 # skip
fi
done
fi
# Sanity nginx running on systemd platforms
if systemctl > /dev/null; then
nginxactive=$(systemctl show nginx |grep ActiveState=active)
@ -66,6 +58,7 @@ if systemctl > /dev/null; then
fi
fi
fi # systemctl
# Test number from start
: ${testnr:=0}
@ -139,7 +132,6 @@ fi
# Standard IETF RFC yang files.
: ${IETFRFC=../yang/standard}
#: ${IETFRFC=$YANGMODELS/standard/ietf/RFC}
# Backend user
BUSER=clicon
@ -158,6 +150,23 @@ BUSER=clicon
: ${clixon_backend:=clixon_backend}
# Source the site-specific definitions for test script variables, if site.sh
# exists. The variables defined in site.sh override any variables of the same
# names in the environment in the current execution.
if [ -f ./site.sh ]; then
. ./site.sh
if [ $? -ne 0 ]; then
return -1 # skip
fi
# test skiplist.
for f in $SKIPLIST; do
if [ "$testfile" = "$f" ]; then
echo "...skipped (see site.sh)"
return -1 # skip
fi
done
fi
dir=/var/tmp/$0
if [ ! -d $dir ]; then
mkdir $dir

22
test/site.sh Normal file
View file

@ -0,0 +1,22 @@
#!#/bin/sh
# Use this file to specify local site-specific env variables, or tests to
# skip. This file is sourced by lib.sh
#
# Add test filenames that you do not want to run to the SKIPLIST variable. The
# SKIPLIST is evaluated as a Bash glob in lib.sh, so you can use it to skip
# files from the begining of the file list up to a pattern by specifying an
# appropriate glob such as "test_[a-n]*\.sh".
#
# The SKIPLIST has precedence over the 'pattern' variable that you can use to
# specify included file when running the various test scripts such as "all.sh".
#SKIPLIST="test_[a-t]*\.sh test_openconfig.sh test_yangmodels.sh"
#
# Parse yang openconfig models from https://github.com/openconfig/public
#OPENCONFIG=/usr/local/share/openconfig/public
#
# Parse yangmodels from https://github.com/YangModels/yang
#YANGMODELS=/usr/local/share/yangmodels
#
# Specify alternative directory for the standard IETF RFC yang files.
#IETFRFC=$YANGMODELS/standard/ietf/RFC

View file

@ -1,15 +1,30 @@
#!/usr/bin/env bash
# Run, eg as:
# ./sum.sh # to run all tests and print
# Run test_*.sh tests, continue on error, no logging, print pass/fail summary.
#
# This script requires the user to be in the sudo group.
#
# The 'pattern' variable determines which test files are executed.
# By default, run all the tests in the test_*.sh files in this directory.
: ${pattern:=test_*.sh}
# You can specify tests files to exclude using the 'SKIPLIST' variable in a
# site.sh file. See example in README.md. Files excluded by the 'SKIPLIST'
# variable have precedence over files included by the 'pattern' variable.
# This script does not take arguments, so if arguments exist, print the Usage
# in http://docopt.org/ format.
if [ $# -gt 0 ]; then
echo "usage: $0 # pipe to dev/null and continue on error"
echo "Usage:"
echo " ${0} # Run all 'test_*.sh' files"
echo " pattern=<Bash glob pattern> ${0} # Run only files matching the pattern"
echo ""
echo "Example:"
echo " ${0} 2>&1 | tee test.log # Run all tests, output to 'test.log'"
echo " pattern=test_feature.sh ${0} # Run only the tests in 'test_feature.sh'"
exit -1
fi
# Pattern to run tests, default is all, but you may want to narrow it down
: ${pattern:=test_*.sh}
err=0
for testfile in $pattern; do # For lib.sh the variable must be called testfile
echo "Running $testfile"

View file

@ -248,7 +248,7 @@ match=`echo "$ret" | grep --null -Go "$expect"`
if [ -z "$match" ]; then
err "$expect" "$ret"
fi
expect="<module><name>ietf-yang-library</name><revision>2016-06-21</revision><namespace>urn:ietf:params:xml:ns:yang:ietf-yang-library</namespace><conformance-type>implement</conformance-type></module>"
expect="<module><name>ietf-yang-library</name><revision>2019-01-04</revision><namespace>urn:ietf:params:xml:ns:yang:ietf-yang-library</namespace><conformance-type>implement</conformance-type></module>"
match=`echo "$ret" | grep --null -Go "$expect"`
if [ -z "$match" ]; then
err "$expect" "$ret"

View file

@ -75,7 +75,7 @@ new "Netconf snd hello with prefix"
expecteof "$clixon_netconf -qf $cfg" 0 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><nc:hello xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><nc:capabilities><nc:capability>urn:ietf:params:netconf:base:1.0</nc:capability></nc:capabilities></nc:hello>]]>]]>" '^$'
new "netconf snd + rcv hello"
expecteof "$clixon_netconf -f $cfg" 0 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><hello $DEFAULTNS><capabilities><capability>urn:ietf:params:netconf:base:1.0</capability></capabilities></hello>]]>]]>" "^<hello $DEFAULTNS><capabilities><capability>urn:ietf:params:netconf:base:1.0</capability><capability>urn:ietf:params:netconf:capability:yang-library:1.0?revision=2016-06-21&amp;module-set-id=42</capability><capability>urn:ietf:params:netconf:capability:candidate:1.0</capability><capability>urn:ietf:params:netconf:capability:validate:1.1</capability><capability>urn:ietf:params:netconf:capability:startup:1.0</capability><capability>urn:ietf:params:netconf:capability:xpath:1.0</capability><capability>urn:ietf:params:netconf:capability:notification:1.0</capability></capabilities><session-id>[0-9]*</session-id></hello>]]>]]>$"
expecteof "$clixon_netconf -f $cfg" 0 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><hello $DEFAULTNS><capabilities><capability>urn:ietf:params:netconf:base:1.0</capability></capabilities></hello>]]>]]>" "^<hello $DEFAULTNS><capabilities><capability>urn:ietf:params:netconf:base:1.0</capability><capability>urn:ietf:params:netconf:capability:yang-library:1.0?revision=2019-01-04&amp;module-set-id=42</capability><capability>urn:ietf:params:netconf:capability:candidate:1.0</capability><capability>urn:ietf:params:netconf:capability:validate:1.1</capability><capability>urn:ietf:params:netconf:capability:startup:1.0</capability><capability>urn:ietf:params:netconf:capability:xpath:1.0</capability><capability>urn:ietf:params:netconf:capability:notification:1.0</capability></capabilities><session-id>[0-9]*</session-id></hello>]]>]]>$"
new "netconf rcv hello, disable RFC7895/ietf-yang-library"
expecteof "$clixon_netconf -f $cfg -o CLICON_MODULE_LIBRARY_RFC7895=0" 0 "<rpc $DEFAULTNS message-id=\"101\"><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<hello $DEFAULTNS><capabilities><capability>urn:ietf:params:netconf:base:1.0</capability><capability>urn:ietf:params:netconf:capability:candidate:1.0</capability><capability>urn:ietf:params:netconf:capability:validate:1.1</capability><capability>urn:ietf:params:netconf:capability:startup:1.0</capability><capability>urn:ietf:params:netconf:capability:xpath:1.0</capability><capability>urn:ietf:params:netconf:capability:notification:1.0</capability></capabilities><session-id>[0-9]*</session-id></hello>]]>]]><rpc-reply $DEFAULTNS message-id=\"101\"><data/></rpc-reply>]]>]]>$"

View file

@ -76,7 +76,6 @@ testrun()
new "kill old restconf daemon"
stop_restconf_pre
if $USEBACKEND; then
new "start restconf daemon -b"
start_restconf -f $cfg -b
@ -84,7 +83,6 @@ testrun()
new "start restconf daemon"
start_restconf -f $cfg
fi
fi
new "wait restconf"
wait_restconf
@ -93,11 +91,11 @@ testrun()
expectpart "$(curl $CURLOPTS -X GET $RCPROTO://localhost/.well-known/host-meta)" 0 'HTTP/1.1 200 OK' "<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>" "<Link rel='restconf' href='/restconf'/>" "</XRD>"
new "restconf get restconf resource. RFC 8040 3.3 (json)"
expectpart "$(curl $CURLOPTS -X GET -H "Accept: application/yang-data+json" $RCPROTO://localhost/restconf)" 0 'HTTP/1.1 200 OK' '{"ietf-restconf:restconf":{"data":{},"operations":{},"yang-library-version":"2016-06-21"}}'
expectpart "$(curl $CURLOPTS -X GET -H "Accept: application/yang-data+json" $RCPROTO://localhost/restconf)" 0 'HTTP/1.1 200 OK' '{"ietf-restconf:restconf":{"data":{},"operations":{},"yang-library-version":"2019-01-04"}}'
new "restconf get restconf resource. RFC 8040 3.3 (xml)"
# Get XML instead of JSON?
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: application/yang-data+xml' $RCPROTO://localhost/restconf)" 0 'HTTP/1.1 200 OK' '<restconf xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf"><data/><operations/><yang-library-version>2016-06-21</yang-library-version></restconf>'
new "restconf get restconf resource. RFC 8040 3.3 (xml)"
# Get XML instead of JSON?
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: application/yang-data+xml' $RCPROTO://localhost/restconf)" 0 'HTTP/1.1 200 OK' '<restconf xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf"><data/><operations/><yang-library-version>2019-01-04</yang-library-version></restconf>'
# Should be alphabetically ordered
new "restconf get restconf/operations. RFC8040 3.3.2 (json)"
@ -112,11 +110,11 @@ testrun()
fi
new "restconf get restconf/yang-library-version. RFC8040 3.3.3"
expectpart "$(curl $CURLOPTS -X GET $RCPROTO://localhost/restconf/yang-library-version)" 0 'HTTP/1.1 200 OK' '{"yang-library-version":"2016-06-21"}'
expectpart "$(curl $CURLOPTS -X GET $RCPROTO://localhost/restconf/yang-library-version)" 0 'HTTP/1.1 200 OK' '{"yang-library-version":"2019-01-04"}'
new "restconf get restconf/yang-library-version. RFC8040 3.3.3 (xml)"
ret=$(curl $CURLOPTS -X GET -H "Accept: application/yang-data+xml" $RCPROTO://localhost/restconf/yang-library-version)
expect="<yang-library-version>2016-06-21</yang-library-version>"
expect="<yang-library-version>2019-01-04</yang-library-version>"
match=`echo $ret | grep --null -Eo "$expect"`
if [ -z "$match" ]; then
err "$expect" "$ret"

View file

@ -91,12 +91,12 @@ fi
new "B.1.1. Retrieve the Top-Level API Resource root"
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: application/xrd+xml' $RCPROTO://localhost/.well-known/host-meta)" 0 "HTTP/1.1 200 OK" "Content-Type: application/xrd+xml" "<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>" "<Link rel='restconf' href='/restconf'/>" "</XRD>"
d='{"ietf-restconf:restconf":{"data":{},"operations":{},"yang-library-version":"2016-06-21"}}'
d='{"ietf-restconf:restconf":{"data":{},"operations":{},"yang-library-version":"2019-01-04"}}'
new "B.1.1. Retrieve the Top-Level API Resource /restconf json"
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: application/yang-data+json' $RCPROTO://localhost/restconf)" 0 "HTTP/1.1 200 OK" 'Cache-Control: no-cache' "Content-Type: application/yang-data+json" "$d"
new "B.1.1. Retrieve the Top-Level API Resource /restconf xml (not in RFC)"
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: application/yang-data+xml' $RCPROTO://localhost/restconf)" 0 "HTTP/1.1 200 OK" 'Cache-Control: no-cache' "Content-Type: application/yang-data+xml" '<restconf xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf"><data/><operations/><yang-library-version>2016-06-21</yang-library-version></restconf>'
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: application/yang-data+xml' $RCPROTO://localhost/restconf)" 0 "HTTP/1.1 200 OK" 'Cache-Control: no-cache' "Content-Type: application/yang-data+xml" '<restconf xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf"><data/><operations/><yang-library-version>2019-01-04</yang-library-version></restconf>'
# This just catches the header and the jukebox module, the RFC has foo and bar which
# seems wrong to recreate

View file

@ -305,7 +305,6 @@ MODSTATE1='<modules-state xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library">
MODSTATE2='<module><name>interfaces</name><revision>2018-02-20</revision><namespace>urn:example:interfaces</namespace></module>'
XML='<interfaces xmlns="urn:example:interfaces"><interface><name>e0</name><docs><descr>First interface</descr></docs><type>eth</type><admin-status>up</admin-status><statistics><in-octets>54326.432</in-octets><in-unicast-pkts>8458765</in-unicast-pkts></statistics></interface><interface><name>e1</name><type>eth</type><admin-status>down</admin-status></interface></interfaces>'
ALL="<config>$MODSTATE$XML</config>"

View file

@ -46,8 +46,9 @@ YANGSPECS += ietf-netconf@2011-06-01.yang
YANGSPECS += ietf-netconf-acm@2018-02-14.yang
YANGSPECS += ietf-restconf@2017-01-26.yang
YANGSPECS += ietf-restconf-monitoring@2017-01-26.yang
YANGSPECS += ietf-yang-library@2016-06-21.yang
YANGSPECS += ietf-yang-library@2019-01-04.yang
YANGSPECS += ietf-yang-types@2013-07-15.yang
YANGSPECS += ietf-datastores@2018-02-14.yang
all:

View file

@ -0,0 +1,117 @@
module ietf-datastores {
yang-version 1.1;
namespace "urn:ietf:params:xml:ns:yang:ietf-datastores";
prefix ds;
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 a set of identities for identifying
datastores.
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 datastore {
description
"Abstract base identity for datastore identities.";
}
identity conventional {
base datastore;
description
"Abstract base identity for conventional configuration
datastores.";
}
identity running {
base conventional;
description
"The running configuration datastore.";
}
identity candidate {
base conventional;
description
"The candidate configuration datastore.";
}
identity startup {
base conventional;
description
"The startup configuration datastore.";
}
identity intended {
base conventional;
description
"The intended configuration datastore.";
}
identity dynamic {
base datastore;
description
"Abstract base identity for dynamic configuration datastores.";
}
identity operational {
base datastore;
description
"The operational state datastore.";
}
/*
* Type definitions
*/
typedef datastore-ref {
type identityref {
base datastore;
}
description
"A datastore identity reference.";
}
}

View file

@ -1,457 +0,0 @@
module ietf-inet-types {
namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types";
prefix "inet";
organization
"IETF NETMOD (NETCONF Data Modeling Language) Working Group";
contact
"WG Web: <http://tools.ietf.org/wg/netmod/>
WG List: <mailto:netmod@ietf.org>
WG Chair: David Kessens
<mailto:david.kessens@nsn.com>
WG Chair: Juergen Schoenwaelder
<mailto:j.schoenwaelder@jacobs-university.de>
Editor: Juergen Schoenwaelder
<mailto:j.schoenwaelder@jacobs-university.de>";
description
"This module contains a collection of generally useful derived
YANG data types for Internet addresses and related things.
Copyright (c) 2013 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 6991; see
the RFC itself for full legal notices.";
revision 2013-07-15 {
description
"This revision adds the following new data types:
- ip-address-no-zone
- ipv4-address-no-zone
- ipv6-address-no-zone";
reference
"RFC 6991: Common YANG Data Types";
}
revision 2010-09-24 {
description
"Initial revision.";
reference
"RFC 6021: Common YANG Data Types";
}
/*** collection of types related to protocol fields ***/
typedef ip-version {
type enumeration {
enum unknown {
value "0";
description
"An unknown or unspecified version of the Internet
protocol.";
}
enum ipv4 {
value "1";
description
"The IPv4 protocol as defined in RFC 791.";
}
enum ipv6 {
value "2";
description
"The IPv6 protocol as defined in RFC 2460.";
}
}
description
"This value represents the version of the IP protocol.
In the value set and its semantics, this type is equivalent
to the InetVersion textual convention of the SMIv2.";
reference
"RFC 791: Internet Protocol
RFC 2460: Internet Protocol, Version 6 (IPv6) Specification
RFC 4001: Textual Conventions for Internet Network Addresses";
}
typedef dscp {
type uint8 {
range "0..63";
}
description
"The dscp type represents a Differentiated Services Code Point
that may be used for marking packets in a traffic stream.
In the value set and its semantics, this type is equivalent
to the Dscp textual convention of the SMIv2.";
reference
"RFC 3289: Management Information Base for the Differentiated
Services Architecture
RFC 2474: Definition of the Differentiated Services Field
(DS Field) in the IPv4 and IPv6 Headers
RFC 2780: IANA Allocation Guidelines For Values In
the Internet Protocol and Related Headers";
}
typedef ipv6-flow-label {
type uint32 {
range "0..1048575";
}
description
"The ipv6-flow-label type represents the flow identifier or Flow
Label in an IPv6 packet header that may be used to
discriminate traffic flows.
In the value set and its semantics, this type is equivalent
to the IPv6FlowLabel textual convention of the SMIv2.";
reference
"RFC 3595: Textual Conventions for IPv6 Flow Label
RFC 2460: Internet Protocol, Version 6 (IPv6) Specification";
}
typedef port-number {
type uint16 {
range "0..65535";
}
description
"The port-number type represents a 16-bit port number of an
Internet transport-layer protocol such as UDP, TCP, DCCP, or
SCTP. Port numbers are assigned by IANA. A current list of
all assignments is available from <http://www.iana.org/>.
Note that the port number value zero is reserved by IANA. In
situations where the value zero does not make sense, it can
be excluded by subtyping the port-number type.
In the value set and its semantics, this type is equivalent
to the InetPortNumber textual convention of the SMIv2.";
reference
"RFC 768: User Datagram Protocol
RFC 793: Transmission Control Protocol
RFC 4960: Stream Control Transmission Protocol
RFC 4340: Datagram Congestion Control Protocol (DCCP)
RFC 4001: Textual Conventions for Internet Network Addresses";
}
/*** collection of types related to autonomous systems ***/
typedef as-number {
type uint32;
description
"The as-number type represents autonomous system numbers
which identify an Autonomous System (AS). An AS is a set
of routers under a single technical administration, using
an interior gateway protocol and common metrics to route
packets within the AS, and using an exterior gateway
protocol to route packets to other ASes. IANA maintains
the AS number space and has delegated large parts to the
regional registries.
Autonomous system numbers were originally limited to 16
bits. BGP extensions have enlarged the autonomous system
number space to 32 bits. This type therefore uses an uint32
base type without a range restriction in order to support
a larger autonomous system number space.
In the value set and its semantics, this type is equivalent
to the InetAutonomousSystemNumber textual convention of
the SMIv2.";
reference
"RFC 1930: Guidelines for creation, selection, and registration
of an Autonomous System (AS)
RFC 4271: A Border Gateway Protocol 4 (BGP-4)
RFC 4001: Textual Conventions for Internet Network Addresses
RFC 6793: BGP Support for Four-Octet Autonomous System (AS)
Number Space";
}
/*** collection of types related to IP addresses and hostnames ***/
typedef ip-address {
type union {
type inet:ipv4-address;
type inet:ipv6-address;
}
description
"The ip-address type represents an IP address and is IP
version neutral. The format of the textual representation
implies the IP version. This type supports scoped addresses
by allowing zone identifiers in the address format.";
reference
"RFC 4007: IPv6 Scoped Address Architecture";
}
typedef ipv4-address {
type string {
pattern
'(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+ '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+ '(%[\p{N}\p{L}]+)?';
}
description
"The ipv4-address type represents an IPv4 address in
dotted-quad notation. The IPv4 address may include a zone
index, separated by a % sign.
The zone index is used to disambiguate identical address
values. For link-local addresses, the zone index will
typically be the interface index number or the name of an
interface. If the zone index is not present, the default
zone of the device will be used.
The canonical format for the zone index is the numerical
format";
}
typedef ipv6-address {
type string {
pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+ '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+ '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+ '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+ '(%[\p{N}\p{L}]+)?';
pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+ '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+ '(%.+)?';
}
description
"The ipv6-address type represents an IPv6 address in full,
mixed, shortened, and shortened-mixed notation. The IPv6
address may include a zone index, separated by a % sign.
The zone index is used to disambiguate identical address
values. For link-local addresses, the zone index will
typically be the interface index number or the name of an
interface. If the zone index is not present, the default
zone of the device will be used.
The canonical format of IPv6 addresses uses the textual
representation defined in Section 4 of RFC 5952. The
canonical format for the zone index is the numerical
format as described in Section 11.2 of RFC 4007.";
reference
"RFC 4291: IP Version 6 Addressing Architecture
RFC 4007: IPv6 Scoped Address Architecture
RFC 5952: A Recommendation for IPv6 Address Text
Representation";
}
typedef ip-address-no-zone {
type union {
type inet:ipv4-address-no-zone;
type inet:ipv6-address-no-zone;
}
description
"The ip-address-no-zone type represents an IP address and is
IP version neutral. The format of the textual representation
implies the IP version. This type does not support scoped
addresses since it does not allow zone identifiers in the
address format.";
reference
"RFC 4007: IPv6 Scoped Address Architecture";
}
typedef ipv4-address-no-zone {
type inet:ipv4-address {
pattern '[0-9\.]*';
}
description
"An IPv4 address without a zone index. This type, derived from
ipv4-address, may be used in situations where the zone is
known from the context and hence no zone index is needed.";
}
typedef ipv6-address-no-zone {
type inet:ipv6-address {
pattern '[0-9a-fA-F:\.]*';
}
description
"An IPv6 address without a zone index. This type, derived from
ipv6-address, may be used in situations where the zone is
known from the context and hence no zone index is needed.";
reference
"RFC 4291: IP Version 6 Addressing Architecture
RFC 4007: IPv6 Scoped Address Architecture
RFC 5952: A Recommendation for IPv6 Address Text
Representation";
}
typedef ip-prefix {
type union {
type inet:ipv4-prefix;
type inet:ipv6-prefix;
}
description
"The ip-prefix type represents an IP prefix and is IP
version neutral. The format of the textual representations
implies the IP version.";
}
typedef ipv4-prefix {
type string {
pattern
'(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+ '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+ '/(([0-9])|([1-2][0-9])|(3[0-2]))';
}
description
"The ipv4-prefix type represents an IPv4 address prefix.
The prefix length is given by the number following the
slash character and must be less than or equal to 32.
A prefix length value of n corresponds to an IP address
mask that has n contiguous 1-bits from the most
significant bit (MSB) and all other bits set to 0.
The canonical format of an IPv4 prefix has all bits of
the IPv4 address set to zero that are not part of the
IPv4 prefix.";
}
typedef ipv6-prefix {
type string {
pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+ '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+ '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+ '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+ '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))';
pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+ '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+ '(/.+)';
}
description
"The ipv6-prefix type represents an IPv6 address prefix.
The prefix length is given by the number following the
slash character and must be less than or equal to 128.
A prefix length value of n corresponds to an IP address
mask that has n contiguous 1-bits from the most
significant bit (MSB) and all other bits set to 0.
The IPv6 address should have all bits that do not belong
to the prefix set to zero.
The canonical format of an IPv6 prefix has all bits of
the IPv6 address set to zero that are not part of the
IPv6 prefix. Furthermore, the IPv6 address is represented
as defined in Section 4 of RFC 5952.";
reference
"RFC 5952: A Recommendation for IPv6 Address Text
Representation";
}
/*** collection of domain name and URI types ***/
typedef domain-name {
type string {
pattern
'((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*'
+ '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)'
+ '|\.';
length "1..253";
}
description
"The domain-name type represents a DNS domain name. The
name SHOULD be fully qualified whenever possible.
Internet domain names are only loosely specified. Section
3.5 of RFC 1034 recommends a syntax (modified in Section
2.1 of RFC 1123). The pattern above is intended to allow
for current practice in domain name use, and some possible
future expansion. It is designed to hold various types of
domain names, including names used for A or AAAA records
(host names) and other records, such as SRV records. Note
that Internet host names have a stricter syntax (described
in RFC 952) than the DNS recommendations in RFCs 1034 and
1123, and that systems that want to store host names in
schema nodes using the domain-name type are recommended to
adhere to this stricter standard to ensure interoperability.
The encoding of DNS names in the DNS protocol is limited
to 255 characters. Since the encoding consists of labels
prefixed by a length bytes and there is a trailing NULL
byte, only 253 characters can appear in the textual dotted
notation.
The description clause of schema nodes using the domain-name
type MUST describe when and how these names are resolved to
IP addresses. Note that the resolution of a domain-name value
may require to query multiple DNS records (e.g., A for IPv4
and AAAA for IPv6). The order of the resolution process and
which DNS record takes precedence can either be defined
explicitly or may depend on the configuration of the
resolver.
Domain-name values use the US-ASCII encoding. Their canonical
format uses lowercase US-ASCII characters. Internationalized
domain names MUST be A-labels as per RFC 5890.";
reference
"RFC 952: DoD Internet Host Table Specification
RFC 1034: Domain Names - Concepts and Facilities
RFC 1123: Requirements for Internet Hosts -- Application
and Support
RFC 2782: A DNS RR for specifying the location of services
(DNS SRV)
RFC 5890: Internationalized Domain Names in Applications
(IDNA): Definitions and Document Framework";
}
typedef host {
type union {
type inet:ip-address;
type inet:domain-name;
}
description
"The host type represents either an IP address or a DNS
domain name.";
}
typedef uri {
type string;
description
"The uri type represents a Uniform Resource Identifier
(URI) as defined by STD 66.
Objects using the uri type MUST be in US-ASCII encoding,
and MUST be normalized as described by RFC 3986 Sections
6.2.1, 6.2.2.1, and 6.2.2.2. All unnecessary
percent-encoding is removed, and all case-insensitive
characters are set to lowercase except for hexadecimal
digits, which are normalized to uppercase as described in
Section 6.2.2.1.
The purpose of this normalization is to help provide
unique URIs. Note that this normalization is not
sufficient to provide uniqueness. Two URIs that are
textually distinct after this normalization may still be
equivalent.
Objects using the uri type may restrict the schemes that
they permit. For example, 'data:' and 'urn:' schemes
might not be appropriate.
A zero-length URI is not a valid URI. This can be used to
express 'URI absent' where required.
In the value set and its semantics, this type is equivalent
to the Uri SMIv2 textual convention defined in RFC 5017.";
reference
"RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
RFC 3305: Report from the Joint W3C/IETF URI Planning Interest
Group: Uniform Resource Identifiers (URIs), URLs,
and Uniform Resource Names (URNs): Clarifications
and Recommendations
RFC 5017: MIB Textual Conventions for Uniform Resource
Identifiers (URIs)";
}
}

View file

@ -1,242 +0,0 @@
module ietf-yang-library {
namespace "urn:ietf:params:xml:ns:yang:ietf-yang-library";
prefix "yanglib";
import ietf-yang-types {
prefix yang;
}
import ietf-inet-types {
prefix inet;
}
organization
"IETF NETCONF (Network Configuration) Working Group";
contact
"WG Web: <https://datatracker.ietf.org/wg/netconf/>
WG List: <mailto:netconf@ietf.org>
WG Chair: Mehmet Ersue
<mailto:mehmet.ersue@nsn.com>
WG Chair: Mahesh Jethanandani
<mailto:mjethanandani@gmail.com>
Editor: Andy Bierman
<mailto:andy@yumaworks.com>
Editor: Martin Bjorklund
<mailto:mbj@tail-f.com>
Editor: Kent Watsen
<mailto:kwatsen@juniper.net>";
description
"This module contains monitoring information about the YANG
modules and submodules that are used within a YANG-based
server.
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 7895; see
the RFC itself for full legal notices.";
revision 2016-06-21 {
description
"Initial revision.";
reference
"RFC 7895: YANG Module Library.";
}
/*
* Typedefs
*/
typedef revision-identifier {
type string {
pattern '\d{4}-\d{2}-\d{2}';
}
description
"Represents a specific date in YYYY-MM-DD format.";
}
/*
* Groupings
*/
grouping module-list {
description
"The module data structure is represented as a grouping
so it can be reused in configuration or another monitoring
data structure.";
grouping common-leafs {
description
"Common parameters for YANG modules and submodules.";
leaf name {
type yang:yang-identifier;
description
"The YANG module or submodule name.";
}
leaf revision {
type union {
type revision-identifier;
type string { length 0; }
}
description
"The YANG module or submodule revision date.
A zero-length string is used if no revision statement
is present in the YANG module or submodule.";
}
}
grouping schema-leaf {
description
"Common schema leaf parameter for modules and submodules.";
leaf schema {
type inet:uri;
description
"Contains a URL that represents the YANG schema
resource for this module or submodule.
This leaf will only be present if there is a URL
available for retrieval of the schema for this entry.";
}
}
list module {
key "name revision";
description
"Each entry represents one revision of one module
currently supported by the server.";
uses common-leafs;
uses schema-leaf;
leaf namespace {
type inet:uri;
mandatory true;
description
"The XML namespace identifier for this module.";
}
leaf-list feature {
type yang:yang-identifier;
description
"List of YANG feature names from this module that are
supported by the server, regardless of whether they are
defined in the module or any included submodule.";
}
list deviation {
key "name revision";
description
"List of YANG deviation module names and revisions
used by this server to modify the conformance of
the module associated with this entry. Note that
the same module can be used for deviations for
multiple modules, so the same entry MAY appear
within multiple 'module' entries.
The deviation module MUST be present in the 'module'
list, with the same name and revision values.
The 'conformance-type' value will be 'implement' for
the deviation module.";
uses common-leafs;
}
leaf conformance-type {
type enumeration {
enum implement {
description
"Indicates that the server implements one or more
protocol-accessible objects defined in the YANG module
identified in this entry. This includes deviation
statements defined in the module.
For YANG version 1.1 modules, there is at most one
module entry with conformance type 'implement' for a
particular module name, since YANG 1.1 requires that,
at most, one revision of a module is implemented.
For YANG version 1 modules, there SHOULD NOT be more
than one module entry for a particular module name.";
}
enum import {
description
"Indicates that the server imports reusable definitions
from the specified revision of the module but does
not implement any protocol-accessible objects from
this revision.
Multiple module entries for the same module name MAY
exist. This can occur if multiple modules import the
same module but specify different revision dates in
the import statements.";
}
}
mandatory true;
description
"Indicates the type of conformance the server is claiming
for the YANG module identified by this entry.";
}
list submodule {
key "name revision";
description
"Each entry represents one submodule within the
parent module.";
uses common-leafs;
uses schema-leaf;
}
}
}
/*
* Operational state data nodes
*/
container modules-state {
config false;
description
"Contains YANG module monitoring information.";
leaf module-set-id {
type string;
mandatory true;
description
"Contains a server-specific identifier representing
the current set of modules and submodules. The
server MUST change the value of this leaf if the
information represented by the 'module' list instances
has changed.";
}
uses module-list;
}
/*
* Notifications
*/
notification yang-library-change {
description
"Generated when the set of modules and submodules supported
by the server has changed.";
leaf module-set-id {
type leafref {
path "/yanglib:modules-state/yanglib:module-set-id";
}
mandatory true;
description
"Contains the module-set-id value representing the
set of modules and submodules supported at the server at
the time the notification is generated.";
}
}
}

View file

@ -0,0 +1,544 @@
module ietf-yang-library {
yang-version 1.1;
namespace "urn:ietf:params:xml:ns:yang:ietf-yang-library";
prefix yanglib;
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)";
}
organization
"IETF NETCONF (Network Configuration) Working Group";
contact
"WG Web: <https://datatracker.ietf.org/wg/netconf/>
WG List: <mailto:netconf@ietf.org>
Author: Andy Bierman
<mailto:andy@yumaworks.com>
Author: Martin Bjorklund
<mailto:mbj@tail-f.com>
Author: Juergen Schoenwaelder
<mailto:j.schoenwaelder@jacobs-university.de>
Author: Kent Watsen
<mailto:kent+ietf@watsen.net>
Author: Robert Wilton
<mailto:rwilton@cisco.com>";
description
"This module provides information about the YANG modules,
datastores, and datastore schemas used by a network
management server.
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 8525; see
the RFC itself for full legal notices.";
revision 2019-01-04 {
description
"Added support for multiple datastores according to the
Network Management Datastore Architecture (NMDA).";
reference
"RFC 8525: YANG Library";
}
revision 2016-04-09 {
description
"Initial revision.";
reference
"RFC 7895: YANG Module Library";
}
/*
* Typedefs
*/
typedef revision-identifier {
type string {
pattern '\d{4}-\d{2}-\d{2}';
}
description
"Represents a specific date in YYYY-MM-DD format.";
}
/*
* Groupings
*/
grouping module-identification-leafs {
description
"Parameters for identifying YANG modules and submodules.";
leaf name {
type yang:yang-identifier;
mandatory true;
description
"The YANG module or submodule name.";
}
leaf revision {
type revision-identifier;
description
"The YANG module or submodule revision date. If no revision
statement is present in the YANG module or submodule, this
leaf is not instantiated.";
}
}
grouping location-leaf-list {
description
"Common leaf-list parameter for the locations of modules and
submodules.";
leaf-list location {
type inet:uri;
description
"Contains a URL that represents the YANG schema
resource for this module or submodule.
This leaf will only be present if there is a URL
available for retrieval of the schema for this entry.";
}
}
grouping module-implementation-parameters {
description
"Parameters for describing the implementation of a module.";
leaf-list feature {
type yang:yang-identifier;
description
"List of all YANG feature names from this module that are
supported by the server, regardless whether they are defined
in the module or any included submodule.";
}
leaf-list deviation {
type leafref {
path "../../module/name";
}
description
"List of all YANG deviation modules used by this server to
modify the conformance of the module associated with this
entry. Note that the same module can be used for deviations
for multiple modules, so the same entry MAY appear within
multiple 'module' entries.
This reference MUST NOT (directly or indirectly)
refer to the module being deviated.
Robust clients may want to make sure that they handle a
situation where a module deviates itself (directly or
indirectly) gracefully.";
}
}
grouping module-set-parameters {
description
"A set of parameters that describe a module set.";
leaf name {
type string;
description
"An arbitrary name of the module set.";
}
list module {
key "name";
description
"An entry in this list represents a module implemented by the
server, as per Section 5.6.5 of RFC 7950, with a particular
set of supported features and deviations.";
reference
"RFC 7950: The YANG 1.1 Data Modeling Language";
uses module-identification-leafs;
leaf namespace {
type inet:uri;
mandatory true;
description
"The XML namespace identifier for this module.";
}
uses location-leaf-list;
list submodule {
key "name";
description
"Each entry represents one submodule within the
parent module.";
uses module-identification-leafs;
uses location-leaf-list;
}
uses module-implementation-parameters;
}
list import-only-module {
key "name revision";
description
"An entry in this list indicates that the server imports
reusable definitions from the specified revision of the
module but does not implement any protocol-accessible
objects from this revision.
Multiple entries for the same module name MAY exist. This
can occur if multiple modules import the same module but
specify different revision dates in the import statements.";
leaf name {
type yang:yang-identifier;
description
"The YANG module name.";
}
leaf revision {
type union {
type revision-identifier;
type string {
length "0";
}
}
description
"The YANG module revision date.
A zero-length string is used if no revision statement
is present in the YANG module.";
}
leaf namespace {
type inet:uri;
mandatory true;
description
"The XML namespace identifier for this module.";
}
uses location-leaf-list;
list submodule {
key "name";
description
"Each entry represents one submodule within the
parent module.";
uses module-identification-leafs;
uses location-leaf-list;
}
}
}
grouping yang-library-parameters {
description
"The YANG library data structure is represented as a grouping
so it can be reused in configuration or another monitoring
data structure.";
list module-set {
key "name";
description
"A set of modules that may be used by one or more schemas.
A module set does not have to be referentially complete,
i.e., it may define modules that contain import statements
for other modules not included in the module set.";
uses module-set-parameters;
}
list schema {
key "name";
description
"A datastore schema that may be used by one or more
datastores.
The schema must be valid and referentially complete, i.e.,
it must contain modules to satisfy all used import
statements for all modules specified in the schema.";
leaf name {
type string;
description
"An arbitrary name of the schema.";
}
leaf-list module-set {
type leafref {
path "../../module-set/name";
}
description
"A set of module-sets that are included in this schema.
If a non-import-only module appears in multiple module
sets, then the module revision and the associated features
and deviations must be identical.";
}
}
list datastore {
key "name";
description
"A datastore supported by this server.
Each datastore indicates which schema it supports.
The server MUST instantiate one entry in this list per
specific datastore it supports.
Each datastore entry with the same datastore schema SHOULD
reference the same schema.";
leaf name {
type ds:datastore-ref;
description
"The identity of the datastore.";
}
leaf schema {
type leafref {
path "../../schema/name";
}
mandatory true;
description
"A reference to the schema supported by this datastore.
All non-import-only modules of the schema are implemented
with their associated features and deviations.";
}
}
}
/*
* Top-level container
*/
container yang-library {
config false;
description
"Container holding the entire YANG library of this server.";
uses yang-library-parameters;
leaf content-id {
type string;
mandatory true;
description
"A server-generated identifier of the contents of the
'/yang-library' tree. The server MUST change the value of
this leaf if the information represented by the
'/yang-library' tree, except '/yang-library/content-id', has
changed.";
}
}
/*
* Notifications
*/
notification yang-library-update {
description
"Generated when any YANG library information on the
server has changed.";
leaf content-id {
type leafref {
path "/yanglib:yang-library/yanglib:content-id";
}
mandatory true;
description
"Contains the YANG library content identifier for the updated
YANG library at the time the notification is generated.";
}
}
/*
* Legacy groupings
*/
grouping module-list {
status deprecated;
description
"The module data structure is represented as a grouping
so it can be reused in configuration or another monitoring
data structure.";
grouping common-leafs {
status deprecated;
description
"Common parameters for YANG modules and submodules.";
leaf name {
type yang:yang-identifier;
status deprecated;
description
"The YANG module or submodule name.";
}
leaf revision {
type union {
type revision-identifier;
type string {
length "0";
}
}
status deprecated;
description
"The YANG module or submodule revision date.
A zero-length string is used if no revision statement
is present in the YANG module or submodule.";
}
}
grouping schema-leaf {
status deprecated;
description
"Common schema leaf parameter for modules and submodules.";
leaf schema {
type inet:uri;
description
"Contains a URL that represents the YANG schema
resource for this module or submodule.
This leaf will only be present if there is a URL
available for retrieval of the schema for this entry.";
}
}
list module {
key "name revision";
status deprecated;
description
"Each entry represents one revision of one module
currently supported by the server.";
uses common-leafs {
status deprecated;
}
uses schema-leaf {
status deprecated;
}
leaf namespace {
type inet:uri;
mandatory true;
status deprecated;
description
"The XML namespace identifier for this module.";
}
leaf-list feature {
type yang:yang-identifier;
status deprecated;
description
"List of YANG feature names from this module that are
supported by the server, regardless of whether they are
defined in the module or any included submodule.";
}
list deviation {
key "name revision";
status deprecated;
description
"List of YANG deviation module names and revisions
used by this server to modify the conformance of
the module associated with this entry. Note that
the same module can be used for deviations for
multiple modules, so the same entry MAY appear
within multiple 'module' entries.
The deviation module MUST be present in the 'module'
list, with the same name and revision values.
The 'conformance-type' value will be 'implement' for
the deviation module.";
uses common-leafs {
status deprecated;
}
}
leaf conformance-type {
type enumeration {
enum implement {
description
"Indicates that the server implements one or more
protocol-accessible objects defined in the YANG module
identified in this entry. This includes deviation
statements defined in the module.
For YANG version 1.1 modules, there is at most one
'module' entry with conformance type 'implement' for a
particular module name, since YANG 1.1 requires that
at most one revision of a module is implemented.
For YANG version 1 modules, there SHOULD NOT be more
than one 'module' entry for a particular module
name.";
}
enum import {
description
"Indicates that the server imports reusable definitions
from the specified revision of the module but does
not implement any protocol-accessible objects from
this revision.
Multiple 'module' entries for the same module name MAY
exist. This can occur if multiple modules import the
same module but specify different revision dates in
the import statements.";
}
}
mandatory true;
status deprecated;
description
"Indicates the type of conformance the server is claiming
for the YANG module identified by this entry.";
}
list submodule {
key "name revision";
status deprecated;
description
"Each entry represents one submodule within the
parent module.";
uses common-leafs {
status deprecated;
}
uses schema-leaf {
status deprecated;
}
}
}
}
/*
* Legacy operational state data nodes
*/
container modules-state {
config false;
status deprecated;
description
"Contains YANG module monitoring information.";
leaf module-set-id {
type string;
mandatory true;
status deprecated;
description
"Contains a server-specific identifier representing
the current set of modules and submodules. The
server MUST change the value of this leaf if the
information represented by the 'module' list instances
has changed.";
}
uses module-list {
status deprecated;
}
}
/*
* Legacy notifications
*/
notification yang-library-change {
status deprecated;
description
"Generated when the set of modules and submodules supported
by the server has changed.";
leaf module-set-id {
type leafref {
path "/yanglib:modules-state/yanglib:module-set-id";
}
mandatory true;
status deprecated;
description
"Contains the module-set-id value representing the
set of modules and submodules supported at the server
at the time the notification is generated.";
}
}
}