Merge branch 'benavrhm-topic_benavrhm_rfc8527a_20201103'
This commit is contained in:
commit
5c7d67dab4
26 changed files with 921 additions and 792 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -51,11 +51,12 @@ build-root/*.rpm
|
||||||
build-root/rpmbuild
|
build-root/rpmbuild
|
||||||
|
|
||||||
util/clixon_util_datastore
|
util/clixon_util_datastore
|
||||||
util/clixon_util_insert
|
util/clixon_util_grpc
|
||||||
util/clixon_util_json
|
util/clixon_util_json
|
||||||
util/clixon_util_path
|
util/clixon_util_path
|
||||||
util/clixon_util_regexp
|
util/clixon_util_regexp
|
||||||
util/clixon_util_socket
|
util/clixon_util_socket
|
||||||
|
util/clixon_util_ssl
|
||||||
util/clixon_util_stream
|
util/clixon_util_stream
|
||||||
util/clixon_util_xml
|
util/clixon_util_xml
|
||||||
util/clixon_util_xml_mod
|
util/clixon_util_xml_mod
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,18 @@ enum restconf_media{
|
||||||
};
|
};
|
||||||
typedef enum restconf_media 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
|
* Prototypes
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -230,6 +230,7 @@ match_list_keys(yang_stmt *y,
|
||||||
* PUT: If it does not, set op to create, otherwise replace
|
* PUT: If it does not, set op to create, otherwise replace
|
||||||
* PATCH: If it does not, fail, otherwise replace/merge
|
* 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] 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
|
static int
|
||||||
api_data_write(clicon_handle h,
|
api_data_write(clicon_handle h,
|
||||||
|
|
@ -242,7 +243,8 @@ api_data_write(clicon_handle h,
|
||||||
int pretty,
|
int pretty,
|
||||||
restconf_media media_in,
|
restconf_media media_in,
|
||||||
restconf_media media_out,
|
restconf_media media_out,
|
||||||
int plain_patch)
|
int plain_patch,
|
||||||
|
ietf_ds_t ds)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
enum operation_type op;
|
enum operation_type op;
|
||||||
|
|
@ -596,12 +598,12 @@ api_data_write(clicon_handle h,
|
||||||
NETCONF_BASE_NAMESPACE); /* bind nc to netconf namespace */
|
NETCONF_BASE_NAMESPACE); /* bind nc to netconf namespace */
|
||||||
cprintf(cbx, "<edit-config");
|
cprintf(cbx, "<edit-config");
|
||||||
/* RFC8040 Sec 1.4:
|
/* RFC8040 Sec 1.4:
|
||||||
* If the NETCONF server supports :startup, the RESTCONF server MUST
|
* If this is a "data" request and the NETCONF server supports :startup,
|
||||||
* automatically update the non-volatile startup configuration
|
* the RESTCONF server MUST automatically update the non-volatile startup
|
||||||
* datastore, after the "running" datastore has been altered as a
|
* configuration datastore, after the "running" datastore has been altered
|
||||||
* consequence of a RESTCONF edit operation.
|
* 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, " copystartup=\"true\"");
|
||||||
cprintf(cbx, " autocommit=\"true\"");
|
cprintf(cbx, " autocommit=\"true\"");
|
||||||
cprintf(cbx, "><target><candidate /></target>");
|
cprintf(cbx, "><target><candidate /></target>");
|
||||||
|
|
@ -695,13 +697,14 @@ api_data_put(clicon_handle h,
|
||||||
cvec *qvec,
|
cvec *qvec,
|
||||||
char *data,
|
char *data,
|
||||||
int pretty,
|
int pretty,
|
||||||
restconf_media media_out)
|
restconf_media media_out,
|
||||||
|
ietf_ds_t ds)
|
||||||
{
|
{
|
||||||
restconf_media media_in;
|
restconf_media media_in;
|
||||||
|
|
||||||
media_in = restconf_content_type(h);
|
media_in = restconf_content_type(h);
|
||||||
return api_data_write(h, req, api_path0, pcvec, pi, qvec, data, pretty,
|
return api_data_write(h, req, api_path0, pcvec, pi, qvec, data, pretty,
|
||||||
media_in, media_out, 0);
|
media_in, media_out, 0, ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Generic REST PATCH method for plain patch
|
/*! Generic REST PATCH method for plain patch
|
||||||
|
|
@ -730,7 +733,8 @@ api_data_patch(clicon_handle h,
|
||||||
cvec *qvec,
|
cvec *qvec,
|
||||||
char *data,
|
char *data,
|
||||||
int pretty,
|
int pretty,
|
||||||
restconf_media media_out)
|
restconf_media media_out,
|
||||||
|
ietf_ds_t ds)
|
||||||
{
|
{
|
||||||
restconf_media media_in;
|
restconf_media media_in;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
@ -740,7 +744,7 @@ api_data_patch(clicon_handle h,
|
||||||
case YANG_DATA_XML:
|
case YANG_DATA_XML:
|
||||||
case YANG_DATA_JSON: /* plain patch */
|
case YANG_DATA_JSON: /* plain patch */
|
||||||
ret = api_data_write(h, req, api_path0, pcvec, pi, qvec, data, pretty,
|
ret = api_data_write(h, req, api_path0, pcvec, pi, qvec, data, pretty,
|
||||||
media_in, media_out, 1);
|
media_in, media_out, 1, ds);
|
||||||
break;
|
break;
|
||||||
case YANG_PATCH_XML:
|
case YANG_PATCH_XML:
|
||||||
case YANG_PATCH_JSON: /* RFC 8072 patch */
|
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] pi Offset, where path starts
|
||||||
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
||||||
* @param[in] media_out Output media
|
* @param[in] media_out Output media
|
||||||
|
* @param[in] ds 0 if "data" resource, 1 if rfc8527 "ds" resource
|
||||||
* See RFC 8040 Sec 4.7
|
* See RFC 8040 Sec 4.7
|
||||||
* Example:
|
* Example:
|
||||||
* curl -X DELETE http://127.0.0.1/restconf/data/interfaces/interface=eth0
|
* 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,
|
char *api_path,
|
||||||
int pi,
|
int pi,
|
||||||
int pretty,
|
int pretty,
|
||||||
restconf_media media_out)
|
restconf_media media_out,
|
||||||
|
ietf_ds_t ds)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
int i;
|
int i;
|
||||||
|
|
@ -834,12 +840,12 @@ api_data_delete(clicon_handle h,
|
||||||
|
|
||||||
cprintf(cbx, "<edit-config");
|
cprintf(cbx, "<edit-config");
|
||||||
/* RFC8040 Sec 1.4:
|
/* RFC8040 Sec 1.4:
|
||||||
* If the NETCONF server supports :startup, the RESTCONF server MUST
|
* If this is a "data" request and the NETCONF server supports :startup,
|
||||||
* automatically update the non-volatile startup configuration
|
* the RESTCONF server MUST automatically update the non-volatile startup
|
||||||
* datastore, after the "running" datastore has been altered as a
|
* configuration datastore, after the "running" datastore has been altered
|
||||||
* consequence of a RESTCONF edit operation.
|
* 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, " copystartup=\"true\"");
|
||||||
cprintf(cbx, " autocommit=\"true\"");
|
cprintf(cbx, " autocommit=\"true\"");
|
||||||
cprintf(cbx, "><target><candidate /></target>");
|
cprintf(cbx, "><target><candidate /></target>");
|
||||||
|
|
|
||||||
|
|
@ -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,
|
int api_data_put(clicon_handle h, void *req, char *api_path,
|
||||||
cvec *pcvec, int pi,
|
cvec *pcvec, int pi,
|
||||||
cvec *qvec, char *data,
|
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,
|
int api_data_patch(clicon_handle h, void *req, char *api_path,
|
||||||
cvec *pcvec, int pi,
|
cvec *pcvec, int pi,
|
||||||
cvec *qvec, char *data, int pretty,
|
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 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_ */
|
#endif /* _RESTCONF_METHODS_H_ */
|
||||||
|
|
|
||||||
|
|
@ -363,7 +363,8 @@ api_data_head(clicon_handle h,
|
||||||
int pi,
|
int pi,
|
||||||
cvec *qvec,
|
cvec *qvec,
|
||||||
int pretty,
|
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);
|
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,
|
int pi,
|
||||||
cvec *qvec,
|
cvec *qvec,
|
||||||
int pretty,
|
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);
|
return api_data_get2(h, req, api_path, pcvec, pi, qvec, pretty, media_out, 0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,9 +42,9 @@
|
||||||
* Prototypes
|
* Prototypes
|
||||||
*/
|
*/
|
||||||
int api_data_head(clicon_handle h, void *req, char *api_path, cvec *pcvec, int pi,
|
int api_data_head(clicon_handle h, void *req, char *api_path, 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,
|
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,
|
int api_operations_get(clicon_handle h, void *req,
|
||||||
char *api_path, int pi, cvec *qvec, char *data,
|
char *api_path, int pi, cvec *qvec, char *data,
|
||||||
int pretty, restconf_media media_out);
|
int pretty, restconf_media media_out);
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,8 @@ api_data_post(clicon_handle h,
|
||||||
cvec *qvec,
|
cvec *qvec,
|
||||||
char *data,
|
char *data,
|
||||||
int pretty,
|
int pretty,
|
||||||
restconf_media media_out)
|
restconf_media media_out,
|
||||||
|
ietf_ds_t ds)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
enum operation_type op = OP_CREATE;
|
enum operation_type op = OP_CREATE;
|
||||||
|
|
@ -377,12 +378,12 @@ api_data_post(clicon_handle h,
|
||||||
|
|
||||||
cprintf(cbx, "<edit-config");
|
cprintf(cbx, "<edit-config");
|
||||||
/* RFC8040 Sec 1.4:
|
/* RFC8040 Sec 1.4:
|
||||||
* If the NETCONF server supports :startup, the RESTCONF server MUST
|
* If this is a "data" request and the NETCONF server supports :startup,
|
||||||
* automatically update the non-volatile startup configuration
|
* the RESTCONF server MUST automatically update the non-volatile startup
|
||||||
* datastore, after the "running" datastore has been altered as a
|
* configuration datastore, after the "running" datastore has been altered
|
||||||
* consequence of a RESTCONF edit operation.
|
* 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, " copystartup=\"true\"");
|
||||||
cprintf(cbx, " autocommit=\"true\"");
|
cprintf(cbx, " autocommit=\"true\"");
|
||||||
cprintf(cbx, "><target><candidate /></target>");
|
cprintf(cbx, "><target><candidate /></target>");
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@
|
||||||
int api_data_post(clicon_handle h, void *req, char *api_path,
|
int api_data_post(clicon_handle h, void *req, char *api_path,
|
||||||
int pi, cvec *qvec, char *data,
|
int pi, cvec *qvec, char *data,
|
||||||
int pretty,
|
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 api_operations_post(clicon_handle h, void *req, char *api_path,
|
||||||
int pi, cvec *qvec, char *data,
|
int pi, cvec *qvec, char *data,
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,8 @@ api_root_restconf_exact(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if (clixon_xml_parse_string("<restconf xmlns=\"urn:ietf:params:xml:ns:yang:ietf-restconf\"><data/>"
|
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)
|
YB_MODULE, yspec, &xt, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
|
@ -187,6 +188,24 @@ api_root_restconf_exact(clicon_handle h,
|
||||||
return retval;
|
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
|
* See https://tools.ietf.org/html/rfc7895
|
||||||
*/
|
*/
|
||||||
|
|
@ -200,7 +219,6 @@ api_yang_library_version(clicon_handle h,
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
cxobj *xt = NULL;
|
cxobj *xt = NULL;
|
||||||
cbuf *cb = NULL;
|
cbuf *cb = NULL;
|
||||||
char *ietf_yang_library_revision = "2016-06-21"; /* XXX */
|
|
||||||
|
|
||||||
clicon_debug(1, "%s", __FUNCTION__);
|
clicon_debug(1, "%s", __FUNCTION__);
|
||||||
if (restconf_reply_header(req, "Content-Type", "%s", restconf_media_int2str(media_out)) < 0)
|
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;
|
goto done;
|
||||||
if (clixon_xml_parse_va(YB_NONE, NULL, &xt, NULL,
|
if (clixon_xml_parse_va(YB_NONE, NULL, &xt, NULL,
|
||||||
"<yang-library-version>%s</yang-library-version>",
|
"<yang-library-version>%s</yang-library-version>",
|
||||||
ietf_yang_library_revision) < 0)
|
IETF_YANG_LIBRARY_REVISION) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (xml_rootchild(xt, 0, &xt) < 0)
|
if (xml_rootchild(xt, 0, &xt) < 0)
|
||||||
goto done;
|
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] pretty Set to 1 for pretty-printed xml/json output
|
||||||
* @param[in] media_in Input media
|
* @param[in] media_in Input media
|
||||||
* @param[in] media_out Output media
|
* @param[in] media_out Output media
|
||||||
|
* @param[in] ds 0 if "data" resource, 1 if rfc8527 "ds" resource
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
api_data(clicon_handle h,
|
api_data(clicon_handle h,
|
||||||
|
|
@ -260,28 +279,58 @@ api_data(clicon_handle h,
|
||||||
cvec *qvec,
|
cvec *qvec,
|
||||||
char *data,
|
char *data,
|
||||||
int pretty,
|
int pretty,
|
||||||
restconf_media media_out)
|
restconf_media media_out,
|
||||||
|
ietf_ds_t ds)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
int read_only = 0, dynamic = 0;
|
||||||
char *request_method;
|
char *request_method;
|
||||||
|
|
||||||
clicon_debug(1, "%s", __FUNCTION__);
|
clicon_debug(1, "%s", __FUNCTION__);
|
||||||
request_method = restconf_param_get(h, "REQUEST_METHOD");
|
request_method = restconf_param_get(h, "REQUEST_METHOD");
|
||||||
clicon_debug(1, "%s method:%s", __FUNCTION__, 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)
|
if (strcmp(request_method, "OPTIONS")==0)
|
||||||
retval = api_data_options(h, req);
|
retval = api_data_options(h, req);
|
||||||
else if (strcmp(request_method, "HEAD")==0)
|
else if (strcmp(request_method, "HEAD")==0) {
|
||||||
retval = api_data_head(h, req, api_path, pcvec, pi, qvec, pretty, media_out);
|
if (dynamic) {
|
||||||
else if (strcmp(request_method, "GET")==0)
|
retval = restconf_method_notallowed(req, "GET,POST");
|
||||||
retval = api_data_get(h, req, api_path, pcvec, pi, qvec, pretty, media_out);
|
}
|
||||||
else if (strcmp(request_method, "POST")==0)
|
retval = api_data_head(h, req, api_path, pcvec, pi, qvec, pretty, media_out, ds);
|
||||||
retval = api_data_post(h, req, api_path, pi, qvec, data, pretty, media_out);
|
}
|
||||||
else if (strcmp(request_method, "PUT")==0)
|
else if (strcmp(request_method, "GET")==0) {
|
||||||
retval = api_data_put(h, req, api_path, pcvec, pi, qvec, data, pretty, media_out);
|
retval = api_data_get(h, req, api_path, pcvec, pi, qvec, pretty, media_out, ds);
|
||||||
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, "POST")==0) {
|
||||||
else if (strcmp(request_method, "DELETE")==0)
|
retval = api_data_post(h, req, api_path, pi, qvec, data, pretty, media_out, ds);
|
||||||
retval = api_data_delete(h, req, api_path, pi, pretty, media_out);
|
}
|
||||||
|
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
|
else
|
||||||
retval = restconf_notfound(h, req);
|
retval = restconf_notfound(h, req);
|
||||||
clicon_debug(1, "%s retval:%d", __FUNCTION__, retval);
|
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 */
|
else if (strcmp(api_resource, "data") == 0){ /* restconf, skip /api/data */
|
||||||
if (api_data(h, req, path, pcvec, 2, qvec, indata,
|
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;
|
goto done;
|
||||||
}
|
}
|
||||||
else if (strcmp(api_resource, "operations") == 0){ /* rpc */
|
else if (strcmp(api_resource, "operations") == 0){ /* rpc */
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@
|
||||||
* Constants
|
* Constants
|
||||||
*/
|
*/
|
||||||
#define RESTCONF_API "restconf"
|
#define RESTCONF_API "restconf"
|
||||||
|
#define IETF_YANG_LIBRARY_REVISION "2019-01-04"
|
||||||
|
|
||||||
/* RESTCONF enables deployments to specify where the RESTCONF API is
|
/* RESTCONF enables deployments to specify where the RESTCONF API is
|
||||||
located. The client discovers this by getting the "/.well-known/host-meta"
|
located. The client discovers this by getting the "/.well-known/host-meta"
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ As restconf using curl on exposed port 80:
|
||||||
"ietf-restconf:restconf": {
|
"ietf-restconf:restconf": {
|
||||||
"data": {},
|
"data": {},
|
||||||
"operations": {},
|
"operations": {},
|
||||||
"yang-library-version": "2016-06-21"
|
"yang-library-version": "2019-01-04"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,9 @@ module clixon-example {
|
||||||
import iana-if-type {
|
import iana-if-type {
|
||||||
prefix ianaift;
|
prefix ianaift;
|
||||||
}
|
}
|
||||||
|
import ietf-datastores {
|
||||||
|
prefix ds;
|
||||||
|
}
|
||||||
|
|
||||||
/* Example interface type for tests, local callbacks, etc */
|
/* Example interface type for tests, local callbacks, etc */
|
||||||
identity eth {
|
identity eth {
|
||||||
|
|
|
||||||
24
test/all.sh
24
test/all.sh
|
|
@ -1,13 +1,27 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Run, eg as:
|
# Run test_*.sh tests, stop on error, verbose logging, no pass/fail summary.
|
||||||
# ./all.sh 2>&1 | tee test.log # break on first test
|
#
|
||||||
|
# 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}
|
: ${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
|
if [ $# -gt 0 ]; then
|
||||||
echo "usage: $0 # detailed logs and stop on first error. Use pattern=\"\" $0 to"
|
echo "Usage:"
|
||||||
echo " Use pattern=<pattern> $0 to narrow down test cases"
|
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
|
exit -1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
||||||
45
test/lib.sh
45
test/lib.sh
|
|
@ -1,5 +1,9 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Define test functions.
|
# 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"
|
# Create working dir as variable "dir"
|
||||||
# The functions are somewhat wildgrown, a little too many:
|
# The functions are somewhat wildgrown, a little too many:
|
||||||
# - expectfn
|
# - expectfn
|
||||||
|
|
@ -17,8 +21,11 @@
|
||||||
# Testfile (not including path)
|
# Testfile (not including path)
|
||||||
: ${testfile:=$(basename $0)}
|
: ${testfile:=$(basename $0)}
|
||||||
|
|
||||||
# Add test to this list that you dont want run
|
# SKIPLIST lists the filenames of the test files that you do *not* want to run.
|
||||||
# Typically add them in your site file
|
# 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:=""}
|
: ${SKIPLIST:=""}
|
||||||
|
|
||||||
# Some tests (openconfig/yang_models) just test for the cli to return a version
|
# 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
|
||||||
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
|
# Sanity nginx running on systemd platforms
|
||||||
if systemctl > /dev/null; then
|
if systemctl > /dev/null; then
|
||||||
nginxactive=$(systemctl show nginx |grep ActiveState=active)
|
nginxactive=$(systemctl show nginx |grep ActiveState=active)
|
||||||
|
|
@ -66,6 +58,7 @@ if systemctl > /dev/null; then
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi # systemctl
|
fi # systemctl
|
||||||
|
|
||||||
# Test number from start
|
# Test number from start
|
||||||
: ${testnr:=0}
|
: ${testnr:=0}
|
||||||
|
|
||||||
|
|
@ -139,7 +132,6 @@ fi
|
||||||
|
|
||||||
# Standard IETF RFC yang files.
|
# Standard IETF RFC yang files.
|
||||||
: ${IETFRFC=../yang/standard}
|
: ${IETFRFC=../yang/standard}
|
||||||
#: ${IETFRFC=$YANGMODELS/standard/ietf/RFC}
|
|
||||||
|
|
||||||
# Backend user
|
# Backend user
|
||||||
BUSER=clicon
|
BUSER=clicon
|
||||||
|
|
@ -158,6 +150,23 @@ BUSER=clicon
|
||||||
|
|
||||||
: ${clixon_backend:=clixon_backend}
|
: ${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
|
dir=/var/tmp/$0
|
||||||
if [ ! -d $dir ]; then
|
if [ ! -d $dir ]; then
|
||||||
mkdir $dir
|
mkdir $dir
|
||||||
|
|
|
||||||
22
test/site.sh
Normal file
22
test/site.sh
Normal 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
|
||||||
|
|
||||||
27
test/sum.sh
27
test/sum.sh
|
|
@ -1,15 +1,30 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Run, eg as:
|
# Run test_*.sh tests, continue on error, no logging, print pass/fail summary.
|
||||||
# ./sum.sh # to run all tests and print
|
#
|
||||||
|
# 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
|
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
|
exit -1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Pattern to run tests, default is all, but you may want to narrow it down
|
|
||||||
: ${pattern:=test_*.sh}
|
|
||||||
|
|
||||||
err=0
|
err=0
|
||||||
for testfile in $pattern; do # For lib.sh the variable must be called testfile
|
for testfile in $pattern; do # For lib.sh the variable must be called testfile
|
||||||
echo "Running $testfile"
|
echo "Running $testfile"
|
||||||
|
|
|
||||||
|
|
@ -248,7 +248,7 @@ match=`echo "$ret" | grep --null -Go "$expect"`
|
||||||
if [ -z "$match" ]; then
|
if [ -z "$match" ]; then
|
||||||
err "$expect" "$ret"
|
err "$expect" "$ret"
|
||||||
fi
|
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"`
|
match=`echo "$ret" | grep --null -Go "$expect"`
|
||||||
if [ -z "$match" ]; then
|
if [ -z "$match" ]; then
|
||||||
err "$expect" "$ret"
|
err "$expect" "$ret"
|
||||||
|
|
|
||||||
|
|
@ -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>]]>]]>" '^$'
|
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"
|
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&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&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"
|
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>]]>]]>$"
|
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>]]>]]>$"
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,6 @@ testrun()
|
||||||
new "kill old restconf daemon"
|
new "kill old restconf daemon"
|
||||||
stop_restconf_pre
|
stop_restconf_pre
|
||||||
|
|
||||||
|
|
||||||
if $USEBACKEND; then
|
if $USEBACKEND; then
|
||||||
new "start restconf daemon -b"
|
new "start restconf daemon -b"
|
||||||
start_restconf -f $cfg -b
|
start_restconf -f $cfg -b
|
||||||
|
|
@ -84,7 +83,6 @@ testrun()
|
||||||
new "start restconf daemon"
|
new "start restconf daemon"
|
||||||
start_restconf -f $cfg
|
start_restconf -f $cfg
|
||||||
fi
|
fi
|
||||||
|
|
||||||
fi
|
fi
|
||||||
new "wait restconf"
|
new "wait restconf"
|
||||||
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>"
|
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)"
|
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)"
|
new "restconf get restconf resource. RFC 8040 3.3 (xml)"
|
||||||
# Get XML instead of JSON?
|
# 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>'
|
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
|
# Should be alphabetically ordered
|
||||||
new "restconf get restconf/operations. RFC8040 3.3.2 (json)"
|
new "restconf get restconf/operations. RFC8040 3.3.2 (json)"
|
||||||
|
|
@ -112,11 +110,11 @@ testrun()
|
||||||
fi
|
fi
|
||||||
|
|
||||||
new "restconf get restconf/yang-library-version. RFC8040 3.3.3"
|
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)"
|
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)
|
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"`
|
match=`echo $ret | grep --null -Eo "$expect"`
|
||||||
if [ -z "$match" ]; then
|
if [ -z "$match" ]; then
|
||||||
err "$expect" "$ret"
|
err "$expect" "$ret"
|
||||||
|
|
|
||||||
|
|
@ -91,12 +91,12 @@ fi
|
||||||
new "B.1.1. Retrieve the Top-Level API Resource root"
|
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>"
|
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"
|
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"
|
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)"
|
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
|
# This just catches the header and the jukebox module, the RFC has foo and bar which
|
||||||
# seems wrong to recreate
|
# seems wrong to recreate
|
||||||
|
|
|
||||||
|
|
@ -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>'
|
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>'
|
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>"
|
ALL="<config>$MODSTATE$XML</config>"
|
||||||
|
|
|
||||||
|
|
@ -46,8 +46,9 @@ YANGSPECS += ietf-netconf@2011-06-01.yang
|
||||||
YANGSPECS += ietf-netconf-acm@2018-02-14.yang
|
YANGSPECS += ietf-netconf-acm@2018-02-14.yang
|
||||||
YANGSPECS += ietf-restconf@2017-01-26.yang
|
YANGSPECS += ietf-restconf@2017-01-26.yang
|
||||||
YANGSPECS += ietf-restconf-monitoring@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-yang-types@2013-07-15.yang
|
||||||
|
YANGSPECS += ietf-datastores@2018-02-14.yang
|
||||||
|
|
||||||
all:
|
all:
|
||||||
|
|
||||||
|
|
|
||||||
117
yang/mandatory/ietf-datastores@2018-02-14.yang
Normal file
117
yang/mandatory/ietf-datastores@2018-02-14.yang
Normal 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.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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)";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
544
yang/mandatory/ietf-yang-library@2019-01-04.yang
Normal file
544
yang/mandatory/ietf-yang-library@2019-01-04.yang
Normal 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.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue