* Limited support of RFC 7895 YANG Module Library to list modules:
* That is, limited support of: ietf-yang-library.yang * For example: `<module><name>example</name><revision/></module><module><name>ietf-restconf-monitoring</name><revision>2017-01-26</revision></module>...` * Comply to RFC 8040 3.5.3.1 rule: api-identifier = [module-name ":"] identifier * The "module-name" was a no-op before. * This means that there was no difference between eg: GET /restconf/data/ietf-yang-library:modules-state and GET /restconf/data/XXXX:modules-state
This commit is contained in:
parent
0631be19cb
commit
74fc0800ae
18 changed files with 921 additions and 120 deletions
13
CHANGELOG.md
13
CHANGELOG.md
|
|
@ -5,14 +5,23 @@
|
||||||
### Major New features
|
### Major New features
|
||||||
|
|
||||||
### API changes on existing features (you may need to change your code)
|
### API changes on existing features (you may need to change your code)
|
||||||
* Notification event streams enhancements
|
* Limited support of RFC 7895 YANG Module Library to list modules:
|
||||||
|
* That is, limited support of: ietf-yang-library.yang
|
||||||
|
* For example: `<module><name>example</name><revision/></module><module><name>ietf-restconf-monitoring</name><revision>2017-01-26</revision></module>...`
|
||||||
|
* Notification event stream enhancements
|
||||||
* Yang 1.1 notification support
|
* Yang 1.1 notification support
|
||||||
* Event stream discovery support according to RFC 5277 Sec 3.2.5.1 (netconf) and RFC 8040 (restconf)
|
* Event stream discovery support according to RFC 5277 Sec 3.2.5.1
|
||||||
|
* That is, support of ietf-restconf-monitoring.yang (mimics schema in 3.2.5.1)
|
||||||
|
* Event stream discovery support according to RFC 8040 (restconf)
|
||||||
|
* That is, support of ietf-netconf-notification.yang
|
||||||
* clixon_restconf and clixon_netconf now take -D <level> as command-line option instead of just -D
|
* clixon_restconf and clixon_netconf now take -D <level> as command-line option instead of just -D
|
||||||
* This aligns to clixon_cli and clixon_backend
|
* This aligns to clixon_cli and clixon_backend
|
||||||
* Application command option -S to clixon_netconf is obsolete. Use `clixon_netconf -l s` instead.
|
* Application command option -S to clixon_netconf is obsolete. Use `clixon_netconf -l s` instead.
|
||||||
|
|
||||||
### Minor changes
|
### Minor changes
|
||||||
|
* Comply to RFC 8040 3.5.3.1 rule: api-identifier = [module-name ":"] identifier
|
||||||
|
* The "module-name" was a no-op before.
|
||||||
|
* This means that there was no difference between eg: GET /restconf/data/ietf-yang-library:modules-state and GET /restconf/data/XXXX:modules-state
|
||||||
* Unified log handling for all clicon applications using -l e|o|s|f<file>.
|
* Unified log handling for all clicon applications using -l e|o|s|f<file>.
|
||||||
* The options stand for e:stderr, o:stdout, s: syslog, f:file
|
* The options stand for e:stderr, o:stdout, s: syslog, f:file
|
||||||
* Added file logging (`-l f` or `-l f<file>`) for cases where neither syslog nor stderr is useful.
|
* Added file logging (`-l f` or `-l f<file>`) for cases where neither syslog nor stderr is useful.
|
||||||
|
|
|
||||||
|
|
@ -261,6 +261,11 @@ from_client_get_config(clicon_handle h,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Get streams state according to RFC 5277 and RCC 8040
|
||||||
|
* @retval -1 Error (fatal)
|
||||||
|
* @retval 0 OK
|
||||||
|
* @retval 1 Statedata callback failed
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
client_get_streams(clicon_handle h,
|
client_get_streams(clicon_handle h,
|
||||||
char *xpath,
|
char *xpath,
|
||||||
|
|
@ -289,9 +294,18 @@ client_get_streams(clicon_handle h,
|
||||||
if (stream_get_xml(h, cb) < 0)
|
if (stream_get_xml(h, cb) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
cprintf(cb,"</restconf-state>");
|
cprintf(cb,"</restconf-state>");
|
||||||
/* XXX. yspec */
|
cprintf(cb,"<netconf xmlns=\"urn:ietf:params:xml:ns:netmod:notification\">");
|
||||||
if (xml_parse_string(cbuf_get(cb), NULL, &x) < 0)
|
if (stream_get_xml(h, cb) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
cprintf(cb,"</netconf>");
|
||||||
|
|
||||||
|
/* XXX. yspec */
|
||||||
|
if (xml_parse_string(cbuf_get(cb), NULL, &x) < 0){
|
||||||
|
if (netconf_operation_failed_xml(xtop, "protocol", clicon_err_reason)< 0)
|
||||||
|
goto done;
|
||||||
|
retval = 1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
if (xml_merge(*xtop, x, yspec, &reason) < 0)
|
if (xml_merge(*xtop, x, yspec, &reason) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (reason){
|
if (reason){
|
||||||
|
|
@ -299,11 +313,117 @@ client_get_streams(clicon_handle h,
|
||||||
xml_purge(xc);
|
xml_purge(xc);
|
||||||
if (netconf_operation_failed_xml(xtop, "rpc", reason)< 0)
|
if (netconf_operation_failed_xml(xtop, "rpc", reason)< 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
retval = 1;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
#ifdef notyet
|
retval = 0;
|
||||||
|
done:
|
||||||
|
if (cb)
|
||||||
|
cbuf_free(cb);
|
||||||
|
if (reason)
|
||||||
|
free(reason);
|
||||||
|
if (x)
|
||||||
|
xml_free(x);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Get modules state according to RFC 7895
|
||||||
|
* @retval -1 Error (fatal)
|
||||||
|
* @retval 0 OK
|
||||||
|
* @retval 1 Statedata callback failed
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
client_get_modules(clicon_handle h,
|
||||||
|
char *xpath,
|
||||||
|
cxobj **xtop)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
cxobj *x = NULL;
|
||||||
|
cxobj *xc;
|
||||||
|
char *reason = NULL;
|
||||||
|
yang_spec *yspec;
|
||||||
|
cbuf *cb;
|
||||||
|
yang_stmt *ymod = NULL;
|
||||||
|
yang_stmt *yrev;
|
||||||
|
|
||||||
|
if ((yspec = clicon_dbspec_yang(h)) == NULL){
|
||||||
|
clicon_err(OE_YANG, ENOENT, "No yang spec");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (*xtop==NULL){
|
||||||
|
clicon_err(OE_CFG, ENOENT, "XML tree expected");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if ((cb = cbuf_new()) == NULL){
|
||||||
|
clicon_err(OE_UNIX, 0, "clicon buffer");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
cprintf(cb,"<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">");
|
||||||
|
cprintf(cb,"<module-set-id>1</module-set-id>"); /* NYI */
|
||||||
|
|
||||||
|
while ((ymod = yn_each((yang_node*)yspec, ymod)) != NULL) {
|
||||||
|
cprintf(cb,"<module>");
|
||||||
|
cprintf(cb,"<name>%s</name>", ymod->ys_argument);
|
||||||
|
if ((yrev = yang_find((yang_node*)ymod, Y_REVISION, NULL)) != NULL)
|
||||||
|
cprintf(cb,"<revision>%s</revision>", yrev->ys_argument);
|
||||||
|
else
|
||||||
|
cprintf(cb,"<revision></revision>");
|
||||||
|
cprintf(cb,"</module>");
|
||||||
|
}
|
||||||
|
cprintf(cb,"</modules-state>");
|
||||||
|
|
||||||
|
/* XXX. yspec */
|
||||||
|
if (xml_parse_string(cbuf_get(cb), NULL, &x) < 0){
|
||||||
|
if (netconf_operation_failed_xml(xtop, "protocol", clicon_err_reason)< 0)
|
||||||
|
goto done;
|
||||||
|
retval = 1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (xml_merge(*xtop, x, yspec, &reason) < 0)
|
||||||
|
goto done;
|
||||||
|
if (reason){
|
||||||
|
while ((xc = xml_child_i(*xtop, 0)) != NULL)
|
||||||
|
xml_purge(xc);
|
||||||
|
if (netconf_operation_failed_xml(xtop, "rpc", reason)< 0)
|
||||||
|
goto done;
|
||||||
|
retval = 1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
if (cb)
|
||||||
|
cbuf_free(cb);
|
||||||
|
if (reason)
|
||||||
|
free(reason);
|
||||||
|
if (x)
|
||||||
|
xml_free(x);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Get system state-data, including streams and plugins
|
||||||
|
* @retval -1 Error (fatal)
|
||||||
|
* @retval 0 OK
|
||||||
|
* @retval 1 Statedata callback failed
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
client_statedata(clicon_handle h,
|
||||||
|
char *xpath,
|
||||||
|
cxobj **xret)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
cxobj **xvec = NULL;
|
||||||
|
size_t xlen;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if ((retval = client_get_streams(h, xpath, xret)) != 0)
|
||||||
|
goto done;
|
||||||
|
if ((retval = client_get_modules(h, xpath, xret)) != 0)
|
||||||
|
goto done;
|
||||||
|
if ((retval = clixon_plugin_statedata(h, xpath, xret)) != 0)
|
||||||
|
goto done;
|
||||||
|
#if 1
|
||||||
/* Code complex to filter out anything that is outside of xpath */
|
/* Code complex to filter out anything that is outside of xpath */
|
||||||
if (xpath_vec(*xtop, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
if (xpath_vec(*xret, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* If vectors are specified then mark the nodes found and
|
/* If vectors are specified then mark the nodes found and
|
||||||
|
|
@ -315,22 +435,17 @@ client_get_streams(clicon_handle h,
|
||||||
xml_flag_set(xvec[i], XML_FLAG_MARK);
|
xml_flag_set(xvec[i], XML_FLAG_MARK);
|
||||||
}
|
}
|
||||||
/* Remove everything that is not marked */
|
/* Remove everything that is not marked */
|
||||||
if (!xml_flag(*xtop, XML_FLAG_MARK))
|
if (!xml_flag(*xret, XML_FLAG_MARK))
|
||||||
if (xml_tree_prune_flagged_sub(*xtop, XML_FLAG_MARK, 1, NULL) < 0)
|
if (xml_tree_prune_flagged_sub(*xret, XML_FLAG_MARK, 1, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* reset flag */
|
/* reset flag */
|
||||||
if (xml_apply(*xtop, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset, (void*)XML_FLAG_MARK) < 0)
|
if (xml_apply(*xret, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset, (void*)XML_FLAG_MARK) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
#endif
|
#endif
|
||||||
ok:
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
if (cb)
|
if (xvec)
|
||||||
cbuf_free(cb);
|
free(xvec);
|
||||||
if (reason)
|
|
||||||
free(reason);
|
|
||||||
if (x)
|
|
||||||
xml_free(x);
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -348,29 +463,24 @@ from_client_get(clicon_handle h,
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
cxobj *xfilter;
|
cxobj *xfilter;
|
||||||
char *selector = "/";
|
char *xpath = "/";
|
||||||
cxobj *xret = NULL;
|
cxobj *xret = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
cbuf *cbx = NULL; /* Assist cbuf */
|
cbuf *cbx = NULL; /* Assist cbuf */
|
||||||
|
|
||||||
if ((xfilter = xml_find(xe, "filter")) != NULL)
|
if ((xfilter = xml_find(xe, "filter")) != NULL)
|
||||||
if ((selector = xml_find_value(xfilter, "select"))==NULL)
|
if ((xpath = xml_find_value(xfilter, "select"))==NULL)
|
||||||
selector="/";
|
xpath="/";
|
||||||
/* Get config */
|
/* Get config */
|
||||||
if (xmldb_get(h, "running", selector, 0, &xret) < 0){
|
if (xmldb_get(h, "running", xpath, 0, &xret) < 0){
|
||||||
if (netconf_operation_failed(cbret, "application", "read registry")< 0)
|
if (netconf_operation_failed(cbret, "application", "read registry")< 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
/* Get state data from plugins as defined by plugin_statedata(), if any */
|
/* Get state data from plugins as defined by plugin_statedata(), if any */
|
||||||
assert(xret);
|
assert(xret);
|
||||||
|
|
||||||
#if 1 /* get netconf state data */
|
|
||||||
if ((ret = client_get_streams(h, selector, &xret)) < 0)
|
|
||||||
goto done;
|
|
||||||
#endif
|
|
||||||
clicon_err_reset();
|
clicon_err_reset();
|
||||||
if ((ret = clixon_plugin_statedata(h, selector, &xret)) < 0)
|
if ((ret = client_statedata(h, xpath, &xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0){ /* OK */
|
if (ret == 0){ /* OK */
|
||||||
cprintf(cbret, "<rpc-reply>");
|
cprintf(cbret, "<rpc-reply>");
|
||||||
|
|
|
||||||
|
|
@ -775,6 +775,10 @@ main(int argc,
|
||||||
goto done;
|
goto done;
|
||||||
if (yang_spec_append(h, CLIXON_DATADIR, "ietf-restconf-monitoring", NULL)< 0)
|
if (yang_spec_append(h, CLIXON_DATADIR, "ietf-restconf-monitoring", NULL)< 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
if (yang_spec_append(h, CLIXON_DATADIR, "ietf-netconf-notification", NULL)< 0)
|
||||||
|
goto done;
|
||||||
|
if (yang_spec_append(h, CLIXON_DATADIR, "ietf-yang-library", NULL)< 0)
|
||||||
|
goto done;
|
||||||
/* Set options: database dir and yangspec (could be hidden in connect?)*/
|
/* Set options: database dir and yangspec (could be hidden in connect?)*/
|
||||||
if (xmldb_setopt(h, "dbdir", clicon_xmldb_dir(h)) < 0)
|
if (xmldb_setopt(h, "dbdir", clicon_xmldb_dir(h)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
|
||||||
|
|
@ -125,11 +125,8 @@ clixon_plugin_statedata(clicon_handle h,
|
||||||
cxobj **xtop)
|
cxobj **xtop)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
int i;
|
|
||||||
cxobj *x = NULL;
|
cxobj *x = NULL;
|
||||||
yang_spec *yspec;
|
yang_spec *yspec;
|
||||||
cxobj **xvec = NULL;
|
|
||||||
size_t xlen;
|
|
||||||
cxobj *xc;
|
cxobj *xc;
|
||||||
clixon_plugin *cp = NULL;
|
clixon_plugin *cp = NULL;
|
||||||
plgstatedata_t *fn; /* Plugin statedata fn */
|
plgstatedata_t *fn; /* Plugin statedata fn */
|
||||||
|
|
@ -168,25 +165,6 @@ clixon_plugin_statedata(clicon_handle h,
|
||||||
x = NULL;
|
x = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Code complex to filter out anything that is outside of xpath */
|
|
||||||
if (xpath_vec(*xtop, "%s", &xvec, &xlen, xpath?xpath:"/") < 0)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* If vectors are specified then mark the nodes found and
|
|
||||||
* then filter out everything else,
|
|
||||||
* otherwise return complete tree.
|
|
||||||
*/
|
|
||||||
if (xvec != NULL){
|
|
||||||
for (i=0; i<xlen; i++)
|
|
||||||
xml_flag_set(xvec[i], XML_FLAG_MARK);
|
|
||||||
}
|
|
||||||
/* Remove everything that is not marked */
|
|
||||||
if (!xml_flag(*xtop, XML_FLAG_MARK))
|
|
||||||
if (xml_tree_prune_flagged_sub(*xtop, XML_FLAG_MARK, 1, NULL) < 0)
|
|
||||||
goto done;
|
|
||||||
/* reset flag */
|
|
||||||
if (xml_apply(*xtop, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset, (void*)XML_FLAG_MARK) < 0)
|
|
||||||
goto done;
|
|
||||||
ok:
|
ok:
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
@ -194,8 +172,6 @@ clixon_plugin_statedata(clicon_handle h,
|
||||||
free(reason);
|
free(reason);
|
||||||
if (x)
|
if (x)
|
||||||
xml_free(x);
|
xml_free(x);
|
||||||
if (xvec)
|
|
||||||
free(xvec);
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,6 @@
|
||||||
/*
|
/*
|
||||||
* Types
|
* Types
|
||||||
*/
|
*/
|
||||||
/* subscription callback */
|
|
||||||
typedef int (*subscription_fn_t)(clicon_handle, void *filter, void *arg);
|
|
||||||
|
|
||||||
/* Notification subscription info
|
/* Notification subscription info
|
||||||
* @see client_subscription in config_client.h
|
* @see client_subscription in config_client.h
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ curl -sX POST -d '{"interfaces":{"interface":{"name":"eth1","type":"eth","enable
|
||||||
|
|
||||||
Start the restconf fastcgi program with debug flag:
|
Start the restconf fastcgi program with debug flag:
|
||||||
```
|
```
|
||||||
sudo su -c "/www-data/clixon_restconf -D 1 f /usr/local/etc/example.xml" -s /bin/sh www-data
|
sudo su -c "/www-data/clixon_restconf -D 1 -f /usr/local/etc/example.xml" -s /bin/sh www-data
|
||||||
```
|
```
|
||||||
Look at syslog:
|
Look at syslog:
|
||||||
```
|
```
|
||||||
|
|
@ -79,3 +79,13 @@ Send command:
|
||||||
```
|
```
|
||||||
curl -G http://127.0.0.1/restconf/data/*
|
curl -G http://127.0.0.1/restconf/data/*
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can also run restconf in a debugger.
|
||||||
|
```
|
||||||
|
sudo gdb /www-data/clixon_restconf
|
||||||
|
(gdb) run -D 1 -f /usr/local/etc/example.xml
|
||||||
|
```
|
||||||
|
but you need to ensure /www-data/fastcgi_restconf.sock has the following access:
|
||||||
|
```
|
||||||
|
rwxr-xr-x 1 www-data www-data 0 sep 22 11:46 /www-data/fastcgi_restconf.sock
|
||||||
|
```
|
||||||
|
|
@ -34,6 +34,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* This program should be run as user www-data
|
||||||
|
*
|
||||||
* See draft-ietf-netconf-restconf-13.txt [draft]
|
* See draft-ietf-netconf-restconf-13.txt [draft]
|
||||||
|
|
||||||
* sudo apt-get install libfcgi-dev
|
* sudo apt-get install libfcgi-dev
|
||||||
|
|
@ -46,6 +48,10 @@
|
||||||
* api/test
|
* api/test
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "clixon_config.h" /* generated by config & autoconf */
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
@ -615,7 +621,13 @@ main(int argc,
|
||||||
/* Parse yang database spec file */
|
/* Parse yang database spec file */
|
||||||
if (yang_spec_main(h) == NULL)
|
if (yang_spec_main(h) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
/* Add system modules */
|
||||||
|
if (yang_spec_append(h, CLIXON_DATADIR, "ietf-restconf-monitoring", NULL)< 0)
|
||||||
|
goto done;
|
||||||
|
if (yang_spec_append(h, CLIXON_DATADIR, "ietf-netconf-notification", NULL)< 0)
|
||||||
|
goto done;
|
||||||
|
if (yang_spec_append(h, CLIXON_DATADIR, "ietf-yang-library", NULL)< 0)
|
||||||
|
goto done;
|
||||||
/* Call start function in all plugins before we go interactive
|
/* Call start function in all plugins before we go interactive
|
||||||
Pass all args after the standard options to plugin_start
|
Pass all args after the standard options to plugin_start
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -620,33 +620,51 @@ yang_find_schemanode(yang_node *yn,
|
||||||
*/
|
*/
|
||||||
yang_stmt *
|
yang_stmt *
|
||||||
yang_find_topnode(yang_spec *ysp,
|
yang_find_topnode(yang_spec *ysp,
|
||||||
char *argument,
|
char *nodeid,
|
||||||
yang_class class)
|
yang_class class)
|
||||||
{
|
{
|
||||||
yang_stmt *ys = NULL;
|
yang_stmt *ymod = NULL; /* module */
|
||||||
yang_stmt *yc = NULL;
|
yang_stmt *yres = NULL; /* result */
|
||||||
|
char *prefix = NULL;
|
||||||
|
char *id = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (yang_nodeid_split(nodeid, &prefix, &id) < 0)
|
||||||
|
goto done;
|
||||||
|
if (prefix){
|
||||||
|
if ((ymod = yang_find((yang_node*)ysp, Y_MODULE, prefix)) != NULL){
|
||||||
|
if ((yres = yang_find((yang_node*)ymod, 0, id)) != NULL)
|
||||||
|
goto ok;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* No prefix given - loop through and find first */
|
||||||
for (i=0; i<ysp->yp_len; i++){
|
for (i=0; i<ysp->yp_len; i++){
|
||||||
ys = ysp->yp_stmt[i];
|
ymod = ysp->yp_stmt[i];
|
||||||
switch (class){
|
switch (class){
|
||||||
case YC_NONE:
|
case YC_NONE:
|
||||||
if ((yc = yang_find((yang_node*)ys, 0, argument)) != NULL)
|
if ((yres = yang_find((yang_node*)ymod, 0, id)) != NULL)
|
||||||
return yc;
|
goto ok;
|
||||||
break;
|
break;
|
||||||
case YC_DATANODE:
|
case YC_DATANODE:
|
||||||
if ((yc = yang_find_datanode((yang_node*)ys, argument)) != NULL)
|
if ((yres = yang_find_datanode((yang_node*)ymod, id)) != NULL)
|
||||||
return yc;
|
goto ok;
|
||||||
break;
|
break;
|
||||||
case YC_SCHEMANODE:
|
case YC_SCHEMANODE:
|
||||||
if ((yc = yang_find_schemanode((yang_node*)ys, argument)) != NULL)
|
if ((yres = yang_find_schemanode((yang_node*)ymod, id)) != NULL)
|
||||||
return yc;
|
goto ok;
|
||||||
break;
|
break;
|
||||||
case YC_DATADEFINITION:
|
case YC_DATADEFINITION:
|
||||||
break; /* nyi */
|
break; /* nyi */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
ok:
|
||||||
|
done:
|
||||||
|
if (prefix)
|
||||||
|
free(prefix);
|
||||||
|
if (id)
|
||||||
|
free(id);
|
||||||
|
return yres;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Given a yang statement, find the prefix associated to this module
|
/*! Given a yang statement, find the prefix associated to this module
|
||||||
|
|
@ -822,7 +840,6 @@ yarg_prefix(yang_stmt *ys)
|
||||||
return prefix;
|
return prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! Split yang node identifier into prefix and identifer.
|
/*! Split yang node identifier into prefix and identifer.
|
||||||
* @param[in] node-id
|
* @param[in] node-id
|
||||||
* @param[out] prefix Malloced string. May be NULL.
|
* @param[out] prefix Malloced string. May be NULL.
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,7 @@ new "restconf DELETE whole datastore"
|
||||||
expecteq "$(curl -u adm1:bar -sS -X DELETE http://localhost/restconf/data)" ""
|
expecteq "$(curl -u adm1:bar -sS -X DELETE http://localhost/restconf/data)" ""
|
||||||
|
|
||||||
new2 "auth get"
|
new2 "auth get"
|
||||||
expecteq "$(curl -u adm1:bar -sS -X GET http://localhost/restconf/data)" '{"data": null}
|
expecteq "$(curl -u adm1:bar -sS -X GET http://localhost/restconf/data/x)" 'null
|
||||||
'
|
'
|
||||||
|
|
||||||
new "auth set authentication config"
|
new "auth set authentication config"
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ fyang=$dir/test.yang
|
||||||
fyangerr=$dir/err.yang
|
fyangerr=$dir/err.yang
|
||||||
nacmfile=$dir/nacmfile
|
nacmfile=$dir/nacmfile
|
||||||
|
|
||||||
|
# Note filter out example_backend_nacm.so in CLICON_BACKEND_REGEXP below
|
||||||
cat <<EOF > $cfg
|
cat <<EOF > $cfg
|
||||||
<config>
|
<config>
|
||||||
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
|
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
|
||||||
|
|
@ -190,7 +191,7 @@ new "restconf DELETE whole datastore"
|
||||||
expecteq "$(curl -u adm1:bar -sS -X DELETE http://localhost/restconf/data)" ""
|
expecteq "$(curl -u adm1:bar -sS -X DELETE http://localhost/restconf/data)" ""
|
||||||
|
|
||||||
new2 "auth get"
|
new2 "auth get"
|
||||||
expecteq "$(curl -u adm1:bar -sS -X GET http://localhost/restconf/data)" '{"data": {"interfaces-state": {"interface": [{"name": "eth0","type": "ex:eth","if-index": 42}]}}}
|
expecteq "$(curl -u adm1:bar -sS -X GET http://localhost/restconf/data/ietf-interfaces:interfaces-state)" '{"interfaces-state": {"interface": [{"name": "eth0","type": "ex:eth","if-index": 42}]}}
|
||||||
'
|
'
|
||||||
|
|
||||||
new "Set x to 0"
|
new "Set x to 0"
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ if [ $? -ne 0 ]; then
|
||||||
err
|
err
|
||||||
fi
|
fi
|
||||||
new "start backend -s init -f $cfg -y $fyang"
|
new "start backend -s init -f $cfg -y $fyang"
|
||||||
sudo $clixon_backend -s init -f $cfg -y $fyang -D 1
|
sudo $clixon_backend -s init -f $cfg -y $fyang # -D 1
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
err
|
err
|
||||||
|
|
@ -77,26 +77,21 @@ new "kill old restconf daemon"
|
||||||
sudo pkill -u www-data clixon_restconf
|
sudo pkill -u www-data clixon_restconf
|
||||||
|
|
||||||
new "start restconf daemon"
|
new "start restconf daemon"
|
||||||
sudo start-stop-daemon -S -q -o -b -x /www-data/clixon_restconf -d /www-data -c www-data -- -f $cfg # -D 1
|
sudo start-stop-daemon -S -q -o -b -x /www-data/clixon_restconf -d /www-data -c www-data -- -f $cfg -D 1
|
||||||
|
|
||||||
sleep 1
|
sleep 1
|
||||||
|
|
||||||
new "restconf tests"
|
|
||||||
|
|
||||||
# get the stream list using netconf
|
# get the stream list using netconf
|
||||||
new "netconf event stream discovery RFC5277 Sec 3.2.5"
|
new "netconf event stream discovery RFC5277 Sec 3.2.5"
|
||||||
echo "$clixon_netconf -qf $cfg -y $fyang"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get><filter type="xpath" select="netconf/streams" xmlns="urn:ietf:params:xml:ns:netmod:notification"/></get></rpc>]]>]]>' '<rpc-reply><data><netconf><streams><stream><name>NETCONF</name><description>default NETCONF event stream</description><replay-support>false</replay-support></stream><stream><name>CLICON</name><description>Clicon logs</description><replay-support>false</replay-support></stream></streams></netconf></data></rpc-reply>]]>]]>'
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get><filter type="xpath" selector="netconf/streams" xmlns="urn:ietf:params:xml:ns:netmod:notification"/></get></rpc>]]>]]>' '<rpc-reply><data><restconf-state><streams><stream><name>NETCONF</name><description>default NETCONF event stream</description><replay-support>false</replay-support></stream><stream><name>CLICON</name><description>Clicon logs</description><replay-support>false</replay-support></stream></streams></restconf-state></data></rpc-reply>]]>]]>'
|
|
||||||
|
|
||||||
#expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get><filter type="subtree"><netconf xmlns="urn:ietf:params:xml:ns:netmod:notification"><streams/></netconf></filter></get></rpc>]]>]]>' '<rpc-reply><data><netconf><streams><stream><name>NETCONF</name>'
|
new "netconf event stream discovery RFC8040 Sec 6.2"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get><filter type="xpath" select="restconf-state/streams" xmlns="urn:ietf:params:xml:ns:netmod:notification"/></get></rpc>]]>]]>' '<rpc-reply><data><restconf-state><streams><stream><name>NETCONF</name><description>default NETCONF event stream</description><replay-support>false</replay-support></stream><stream><name>CLICON</name><description>Clicon logs</description><replay-support>false</replay-support></stream></streams></restconf-state></data></rpc-reply>]]>]]>'
|
||||||
|
|
||||||
#expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><get><filter type="subtree"><netconf xmlns="urn:ietf:params:xml:ns:netmod:notification"><streams/></netconf></filter></get></rpc>]]>]]>' '<rpc-reply message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><data><netconf xmlns="urn:ietf:params:xml:ns:netmod:notification"><streams><stream><name>NETCONF</name>'
|
new "restconf event stream discovery RFC8040 Sec 6.2"
|
||||||
|
expectfn "curl -s -X GET http://localhost/restconf/data/ietf-restconf-monitoring:restconf-state/streams" 0 '{"streams": {"stream": \[{"name": "CLICON","description": "Clicon logs","replay-support": false},{ "name": "NETCONF","description": "default NETCONF event stream","replay-support": false}\]}}'
|
||||||
|
|
||||||
# get the stream list using restconf
|
#new "netconf subscription"
|
||||||
new "restconf GET datastore"
|
|
||||||
#expectfn "curl -s -X GET http://localhost/restconf/data/ietf-restconf-monitoring:restconf-state/streams" 0 '{"data": {"cont1": {"interface": \[{"name": "local0","type": "regular"}\]}}}'
|
|
||||||
|
|
||||||
new "netconf subscription"
|
|
||||||
#expectwait "$clixon_netconf -qf $cfg -y $fyang" "<rpc><create-subscription><stream>ROUTING</stream></create-subscription></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]><notification><event>Routing notification</event></notification>]]>]]>$" 30
|
#expectwait "$clixon_netconf -qf $cfg -y $fyang" "<rpc><create-subscription><stream>ROUTING</stream></create-subscription></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]><notification><event>Routing notification</event></notification>]]>]]>$" 30
|
||||||
|
|
||||||
new "Kill restconf daemon"
|
new "Kill restconf daemon"
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ APPNAME=example
|
||||||
# include err() and new() functions and creates $dir
|
# include err() and new() functions and creates $dir
|
||||||
. ./lib.sh
|
. ./lib.sh
|
||||||
|
|
||||||
exit 0 # NYI
|
|
||||||
|
|
||||||
cfg=$dir/conf_yang.xml
|
cfg=$dir/conf_yang.xml
|
||||||
fyang=$dir/test.yang
|
fyang=$dir/test.yang
|
||||||
|
|
@ -91,6 +91,8 @@ expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candid
|
||||||
new "minmax: empty"
|
new "minmax: empty"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><default-operation>replace</default-operation><config><c/></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><default-operation>replace</default-operation><config><c/></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
exit # NYI
|
||||||
|
|
||||||
new "minmax: validate should fail"
|
new "minmax: validate should fail"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,10 @@ if [ -z "$match" ]; then
|
||||||
err "$expect" "$ret"
|
err "$expect" "$ret"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
new "restconf schema resource, RFC 8040 sec 3.7 according to RFC 7895"
|
||||||
|
expecteq "$(curl -s -H 'Accept: application/yang-data+json' -G http://localhost/restconf/data/ietf-yang-library:modules-state/module=ietf-routing,2014-10-26/)" '{"module": [{"name": "ietf-routing","revision": "2014-10-26"}]}
|
||||||
|
'
|
||||||
|
|
||||||
new "restconf options. RFC 8040 4.1"
|
new "restconf options. RFC 8040 4.1"
|
||||||
expectfn "curl -i -s -X OPTIONS http://localhost/restconf/data" 0 "Allow: OPTIONS,HEAD,GET,POST,PUT,DELETE"
|
expectfn "curl -i -s -X OPTIONS http://localhost/restconf/data" 0 "Allow: OPTIONS,HEAD,GET,POST,PUT,DELETE"
|
||||||
|
|
||||||
|
|
@ -142,16 +146,23 @@ new "restconf head. RFC 8040 4.2"
|
||||||
expectfn "curl -s -I http://localhost/restconf/data" 0 "HTTP/1.1 200 OK"
|
expectfn "curl -s -I http://localhost/restconf/data" 0 "HTTP/1.1 200 OK"
|
||||||
#Content-Type: application/yang-data+json"
|
#Content-Type: application/yang-data+json"
|
||||||
|
|
||||||
new2 "restconf empty rpc"
|
new "restconf empty rpc"
|
||||||
expecteq "$(curl -s -X POST -d {\"input\":{\"name\":\"\"}} http://localhost/restconf/operations/example:empty)" ""
|
expecteq "$(curl -s -X POST -d {\"input\":{\"name\":\"\"}} http://localhost/restconf/operations/example:empty)" ""
|
||||||
|
|
||||||
new2 "restconf get empty config + state json"
|
new2 "restconf get empty config + state json"
|
||||||
expecteq "$(curl -sSG http://localhost/restconf/data)" '{"data": {"interfaces-state": {"interface": [{"name": "eth0","type": "ex:eth","if-index": 42}]}}}
|
expecteq "$(curl -sSG http://localhost/restconf/data/interfaces-state)" '{"interfaces-state": {"interface": [{"name": "eth0","type": "ex:eth","if-index": 42}]}}
|
||||||
'
|
'
|
||||||
|
|
||||||
|
new2 "restconf get empty config + state json with module name"
|
||||||
|
expecteq "$(curl -sSG http://localhost/restconf/data/ietf-interfaces:interfaces-state)" '{"interfaces-state": {"interface": [{"name": "eth0","type": "ex:eth","if-index": 42}]}}
|
||||||
|
'
|
||||||
|
|
||||||
|
new2 "restconf get empty config + state json with wrong module name"
|
||||||
|
expecteq "$(curl -sSG http://localhost/restconf/data/badmodule:interfaces-state)" '{"ietf-restconf:errors" : {"error": {"rpc-error": {"error-tag": "operation-failed","error-type": "protocol","error-severity": "error","error-message": "No yang node found: badmodule:interfaces-state"}}}}
'
|
||||||
|
|
||||||
new "restconf get empty config + state xml"
|
new "restconf get empty config + state xml"
|
||||||
ret=$(curl -s -H "Accept: application/yang-data+xml" -G http://localhost/restconf/data)
|
ret=$(curl -s -H "Accept: application/yang-data+xml" -G http://localhost/restconf/data/interfaces-state)
|
||||||
expect="<data><interfaces-state><interface><name>eth0</name><type>ex:eth</type><if-index>42</if-index></interface></interfaces-state></data>"
|
expect="<interfaces-state><interface><name>eth0</name><type>ex:eth</type><if-index>42</if-index></interface></interfaces-state>"
|
||||||
match=`echo $ret | grep -EZo "$expect"`
|
match=`echo $ret | grep -EZo "$expect"`
|
||||||
if [ -z "$match" ]; then
|
if [ -z "$match" ]; then
|
||||||
err "$expect" "$ret"
|
err "$expect" "$ret"
|
||||||
|
|
@ -184,7 +195,7 @@ if [ -z "$match" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
new2 "restconf GET datastore"
|
new2 "restconf GET datastore"
|
||||||
expecteq "$(curl -s -X GET http://localhost/restconf/data)" '{"data": {"interfaces-state": {"interface": [{"name": "eth0","type": "ex:eth","if-index": 42}]}}}
|
expecteq "$(curl -s -X GET http://localhost/restconf/data/interfaces-state)" '{"interfaces-state": {"interface": [{"name": "eth0","type": "ex:eth","if-index": 42}]}}
|
||||||
'
|
'
|
||||||
|
|
||||||
# Exact match
|
# Exact match
|
||||||
|
|
@ -201,19 +212,23 @@ new "restconf Check interfaces eth/0/0 added"
|
||||||
expectfn "curl -s -G http://localhost/restconf/data" 0 '{"interfaces": {"interface": \[{"name": "eth/0/0","type": "ex:eth","enabled": true}\]},"interfaces-state": {"interface": \[{"name": "eth0","type": "ex:eth","if-index": 42}\]}}
|
expectfn "curl -s -G http://localhost/restconf/data" 0 '{"interfaces": {"interface": \[{"name": "eth/0/0","type": "ex:eth","enabled": true}\]},"interfaces-state": {"interface": \[{"name": "eth0","type": "ex:eth","if-index": 42}\]}}
|
||||||
'
|
'
|
||||||
|
|
||||||
new2 "restconf delete interfaces"
|
new "restconf delete interfaces"
|
||||||
expecteq $(curl -s -X DELETE http://localhost/restconf/data/interfaces) ""
|
expecteq $(curl -s -X DELETE http://localhost/restconf/data/interfaces) ""
|
||||||
|
|
||||||
new "restconf Check empty config"
|
new "restconf Check empty config"
|
||||||
expectfn "curl -sG http://localhost/restconf/data" 0 "$state"
|
expectfn "curl -sG http://localhost/restconf/data/interfaces-state" 0 "$state"
|
||||||
|
|
||||||
new "restconf Add interfaces subtree eth/0/0 using POST"
|
new "restconf Add interfaces subtree eth/0/0 using POST"
|
||||||
expectfn 'curl -s -X POST -d {"interface":{"name":"eth/0/0","type":"ex:eth","enabled":true}} http://localhost/restconf/data/interfaces' 0 ""
|
expectfn 'curl -s -X POST -d {"interface":{"name":"eth/0/0","type":"ex:eth","enabled":true}} http://localhost/restconf/data/interfaces' 0 ""
|
||||||
# XXX cant get this to work
|
# XXX cant get this to work
|
||||||
#expecteq "$(curl -s -X POST -d '{"interface":{"name":"eth/0/0","type\":"ex:eth","enabled":true}}' http://localhost/restconf/data/interfaces)" ""
|
#expecteq "$(curl -s -X POST -d '{"interface":{"name":"eth/0/0","type\":"ex:eth","enabled":true}}' http://localhost/restconf/data/interfaces)" ""
|
||||||
|
|
||||||
new2 "restconf Check eth/0/0 added"
|
new2 "restconf Check eth/0/0 added config"
|
||||||
expecteq "$(curl -s -G http://localhost/restconf/data)" '{"data": {"interfaces": {"interface": [{"name": "eth/0/0","type": "ex:eth","enabled": true}]},"interfaces-state": {"interface": [{"name": "eth0","type": "ex:eth","if-index": 42}]}}}
|
expecteq "$(curl -s -G http://localhost/restconf/data/interfaces)" '{"interfaces": {"interface": [{"name": "eth/0/0","type": "ex:eth","enabled": true}]}}
|
||||||
|
'
|
||||||
|
|
||||||
|
new2 "restconf Check eth/0/0 added state"
|
||||||
|
expecteq "$(curl -s -G http://localhost/restconf/data/interfaces-state)" '{"interfaces-state": {"interface": [{"name": "eth0","type": "ex:eth","if-index": 42}]}}
|
||||||
'
|
'
|
||||||
|
|
||||||
new2 "restconf Re-post eth/0/0 which should generate error"
|
new2 "restconf Re-post eth/0/0 which should generate error"
|
||||||
|
|
@ -226,7 +241,7 @@ new "Add nothing using POST"
|
||||||
expectfn 'curl -s -X POST http://localhost/restconf/data/interfaces/interface=eth%2f0%2f0' 0 '"ietf-restconf:errors" : {"error": {"rpc-error": {"error-tag": "malformed-message","error-type": "rpc","error-severity": "error","error-message": " on line 1: syntax error at or before:'
|
expectfn 'curl -s -X POST http://localhost/restconf/data/interfaces/interface=eth%2f0%2f0' 0 '"ietf-restconf:errors" : {"error": {"rpc-error": {"error-tag": "malformed-message","error-type": "rpc","error-severity": "error","error-message": " on line 1: syntax error at or before:'
|
||||||
|
|
||||||
new2 "restconf Check description added"
|
new2 "restconf Check description added"
|
||||||
expecteq "$(curl -s -G http://localhost/restconf/data)" '{"data": {"interfaces": {"interface": [{"name": "eth/0/0","description": "The-first-interface","type": "ex:eth","enabled": true}]},"interfaces-state": {"interface": [{"name": "eth0","type": "ex:eth","if-index": 42}]}}}
|
expecteq "$(curl -s -G http://localhost/restconf/data/interfaces)" '{"interfaces": {"interface": [{"name": "eth/0/0","description": "The-first-interface","type": "ex:eth","enabled": true}]}}
|
||||||
'
|
'
|
||||||
|
|
||||||
new "restconf delete eth/0/0"
|
new "restconf delete eth/0/0"
|
||||||
|
|
@ -242,7 +257,7 @@ new "restconf Add subtree eth/0/0 using PUT"
|
||||||
expecteq "$(curl -s -X PUT -d '{"interface":{"name":"eth/0/0","type":"ex:eth","enabled":true}}' http://localhost/restconf/data/interfaces/interface=eth%2f0%2f0)" ""
|
expecteq "$(curl -s -X PUT -d '{"interface":{"name":"eth/0/0","type":"ex:eth","enabled":true}}' http://localhost/restconf/data/interfaces/interface=eth%2f0%2f0)" ""
|
||||||
|
|
||||||
new2 "restconf get subtree"
|
new2 "restconf get subtree"
|
||||||
expecteq "$(curl -s -G http://localhost/restconf/data)" '{"data": {"interfaces": {"interface": [{"name": "eth/0/0","type": "ex:eth","enabled": true}]},"interfaces-state": {"interface": [{"name": "eth0","type": "ex:eth","if-index": 42}]}}}
|
expecteq "$(curl -s -G http://localhost/restconf/data/interfaces)" '{"interfaces": {"interface": [{"name": "eth/0/0","type": "ex:eth","enabled": true}]}}
|
||||||
'
|
'
|
||||||
|
|
||||||
new2 "restconf rpc using POST json"
|
new2 "restconf rpc using POST json"
|
||||||
|
|
|
||||||
|
|
@ -69,8 +69,8 @@ new "restconf tests"
|
||||||
new "restconf POST initial tree"
|
new "restconf POST initial tree"
|
||||||
expectfn 'curl -s -X POST -d {"cont1":{"interface":{"name":"local0","type":"regular"}}} http://localhost/restconf/data' 0 ""
|
expectfn 'curl -s -X POST -d {"cont1":{"interface":{"name":"local0","type":"regular"}}} http://localhost/restconf/data' 0 ""
|
||||||
|
|
||||||
new "restconf GET datastore"
|
new "restconf GET datastore intial"
|
||||||
expectfn "curl -s -X GET http://localhost/restconf/data" 0 '{"data": {"cont1": {"interface": \[{"name": "local0","type": "regular"}\]}}}'
|
expectfn "curl -s -X GET http://localhost/restconf/data/cont1" 0 '{"cont1": {"interface": \[{"name": "local0","type": "regular"}\]}}'
|
||||||
|
|
||||||
new "restconf GET interface"
|
new "restconf GET interface"
|
||||||
expectfn "curl -s -X GET http://localhost/restconf/data/cont1/interface=local0" 0 '{"interface": \[{"name": "local0","type": "regular"}\]}'
|
expectfn "curl -s -X GET http://localhost/restconf/data/cont1/interface=local0" 0 '{"interface": \[{"name": "local0","type": "regular"}\]}'
|
||||||
|
|
@ -94,31 +94,31 @@ new "restconf DELETE"
|
||||||
expectfn 'curl -s -X DELETE http://localhost/restconf/data/cont1' 0 ""
|
expectfn 'curl -s -X DELETE http://localhost/restconf/data/cont1' 0 ""
|
||||||
|
|
||||||
new "restconf GET null datastore"
|
new "restconf GET null datastore"
|
||||||
expectfn "curl -s -X GET http://localhost/restconf/data" 0 '{"data": null}'
|
expectfn "curl -s -X GET http://localhost/restconf/data/cont1" 0 'null'
|
||||||
|
|
||||||
new "restconf POST initial tree"
|
new "restconf POST initial tree"
|
||||||
expectfn 'curl -s -X POST -d {"cont1":{"interface":{"name":"local0","type":"regular"}}} http://localhost/restconf/data' 0 ""
|
expectfn 'curl -s -X POST -d {"cont1":{"interface":{"name":"local0","type":"regular"}}} http://localhost/restconf/data' 0 ""
|
||||||
|
|
||||||
new "restconf GET initial tree"
|
new "restconf GET initial tree"
|
||||||
expectfn "curl -s -X GET http://localhost/restconf/data" 0 '{"data": {"cont1": {"interface": \[{"name": "local0","type": "regular"}\]}}}'
|
expectfn "curl -s -X GET http://localhost/restconf/data/cont1" 0 '{"cont1": {"interface": \[{"name": "local0","type": "regular"}\]}}'
|
||||||
|
|
||||||
new "restconf DELETE whole datastore"
|
new "restconf DELETE whole datastore"
|
||||||
expectfn 'curl -s -X DELETE http://localhost/restconf/data' 0 ""
|
expectfn 'curl -s -X DELETE http://localhost/restconf/data' 0 ""
|
||||||
|
|
||||||
new "restconf GET null datastore"
|
new "restconf GET null datastore"
|
||||||
expectfn "curl -s -X GET http://localhost/restconf/data" 0 '{"data": null}'
|
expectfn "curl -s -X GET http://localhost/restconf/data/cont1" 0 'null'
|
||||||
|
|
||||||
new "restconf PUT initial datastore"
|
new "restconf PUT initial datastore"
|
||||||
expectfn 'curl -s -X PUT -d {"data":{"cont1":{"interface":{"name":"local0","type":"regular"}}}} http://localhost/restconf/data' 0 ""
|
expectfn 'curl -s -X PUT -d {"data":{"cont1":{"interface":{"name":"local0","type":"regular"}}}} http://localhost/restconf/data' 0 ""
|
||||||
|
|
||||||
new "restconf GET datastore"
|
new "restconf GET datastore"
|
||||||
expectfn "curl -s -X GET http://localhost/restconf/data" 0 '{"data": {"cont1": {"interface": \[{"name": "local0","type": "regular"}\]}}}'
|
expectfn "curl -s -X GET http://localhost/restconf/data/cont1" 0 '{"cont1": {"interface": \[{"name": "local0","type": "regular"}\]}}'
|
||||||
|
|
||||||
new "restconf PUT replace datastore"
|
new "restconf PUT replace datastore"
|
||||||
expectfn 'curl -s -X PUT -d {"data":{"cont2":{"name":"foo"}}} http://localhost/restconf/data' 0 ""
|
expectfn 'curl -s -X PUT -d {"data":{"cont2":{"name":"foo"}}} http://localhost/restconf/data' 0 ""
|
||||||
|
|
||||||
new "restconf GET replaced datastore"
|
new "restconf GET replaced datastore"
|
||||||
expectfn "curl -s -X GET http://localhost/restconf/data" 0 '{"data": {"cont2": {"name": "foo"}}}'
|
expectfn "curl -s -X GET http://localhost/restconf/data/cont2" 0 '{"cont2": {"name": "foo"}}'
|
||||||
|
|
||||||
new "restconf PUT initial datastore again"
|
new "restconf PUT initial datastore again"
|
||||||
expectfn 'curl -s -X PUT -d {"data":{"cont1":{"interface":{"name":"local0","type":"regular"}}}} http://localhost/restconf/data' 0 ""
|
expectfn 'curl -s -X PUT -d {"data":{"cont1":{"interface":{"name":"local0","type":"regular"}}}} http://localhost/restconf/data' 0 ""
|
||||||
|
|
@ -126,9 +126,8 @@ expectfn 'curl -s -X PUT -d {"data":{"cont1":{"interface":{"name":"local0","type
|
||||||
new "restconf PUT change interface"
|
new "restconf PUT change interface"
|
||||||
expectfn 'curl -s -X PUT -d {"interface":{"name":"local0","type":"atm0"}} http://localhost/restconf/data/cont1/interface=local0' 0 ""
|
expectfn 'curl -s -X PUT -d {"interface":{"name":"local0","type":"atm0"}} http://localhost/restconf/data/cont1/interface=local0' 0 ""
|
||||||
|
|
||||||
|
|
||||||
new "restconf GET datastore atm"
|
new "restconf GET datastore atm"
|
||||||
expectfn "curl -s -X GET http://localhost/restconf/data" 0 '{"data": {"cont1": {"interface": \[{"name": "local0","type": "atm0"}\]}}}'
|
expectfn "curl -s -X GET http://localhost/restconf/data/cont1" 0 '{"cont1": {"interface": \[{"name": "local0","type": "atm0"}\]}}'
|
||||||
|
|
||||||
new "restconf PUT add interface"
|
new "restconf PUT add interface"
|
||||||
expectfn 'curl -s -X PUT -d {"interface":{"name":"TEST","type":"eth0"}} http://localhost/restconf/data/cont1/interface=TEST' 0 ""
|
expectfn 'curl -s -X PUT -d {"interface":{"name":"TEST","type":"eth0"}} http://localhost/restconf/data/cont1/interface=TEST' 0 ""
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,9 @@ new "cli not defined extension"
|
||||||
# This text yields an error, but the test cannot detect the error message yet
|
# This text yields an error, but the test cannot detect the error message yet
|
||||||
#expectfn "$clixon_cli -1f $cfg -y $fyangerr show version" 0 "Yang error: Extension ex:not-defined not found"
|
#expectfn "$clixon_cli -1f $cfg -y $fyangerr show version" 0 "Yang error: Extension ex:not-defined not found"
|
||||||
|
|
||||||
|
new "netconf schema resource, RFC 7895"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get><filter type="xpath" select="modules-state/module" xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library"/></get></rpc>]]>]]>' '<module><name>ietf-yang-library</name><revision>2016-06-21</revision></module>'
|
||||||
|
|
||||||
new "netconf edit config"
|
new "netconf edit config"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><x><y><a>1</a><b>2</b><c>5</c><val>one</val></y><d/></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><edit-config><target><candidate/></target><config><x><y><a>1</a><b>2</b><c>5</c><val>one</val></y><d/></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
|
@ -140,7 +143,7 @@ new "netconf get leaf-list path"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><candidate/></source><filter type=\"xpath\" select=\"/x/f[e='hej']\"/></get-config></rpc>]]>]]>" "^<rpc-reply><data><x><f><e>hej</e><e>hopp</e></f></x></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get-config><source><candidate/></source><filter type=\"xpath\" select=\"/x/f[e='hej']\"/></get-config></rpc>]]>]]>" "^<rpc-reply><data><x><f><e>hej</e><e>hopp</e></f></x></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get (should be some)"
|
new "netconf get (should be some)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get><filter type=\"xpath\" select=\"/\"/></get></rpc>]]>]]>" "^<rpc-reply><data><x><y><a>1</a><b>2</b><c>5</c><val>one</val></y><d/></x></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><get><filter type=\"xpath\" select=\"/\"/></get></rpc>]]>]]>" "^<rpc-reply><data><x><y><a>1</a><b>2</b><c>5</c><val>one</val></y><d/></x>"
|
||||||
|
|
||||||
new "cli set leaf-list"
|
new "cli set leaf-list"
|
||||||
expectfn "$clixon_cli -1f $cfg -y $fyang set x f e foo" 0 ""
|
expectfn "$clixon_cli -1f $cfg -y $fyang set x f e foo" 0 ""
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,8 @@ YANGSPECS += ietf-netconf-acm@2018-02-14.yang
|
||||||
YANGSPECS += ietf-inet-types@2013-07-15.yang
|
YANGSPECS += ietf-inet-types@2013-07-15.yang
|
||||||
YANGSPECS += ietf-yang-types@2013-07-15.yang
|
YANGSPECS += ietf-yang-types@2013-07-15.yang
|
||||||
YANGSPECS += ietf-restconf-monitoring@2017-01-26.yang
|
YANGSPECS += ietf-restconf-monitoring@2017-01-26.yang
|
||||||
|
YANGSPECS += ietf-netconf-notification@2008-07-01.yang
|
||||||
|
YANGSPECS += ietf-yang-library@2016-06-21.yang
|
||||||
|
|
||||||
APPNAME = clixon # subdir ehere these files are installed
|
APPNAME = clixon # subdir ehere these files are installed
|
||||||
|
|
||||||
|
|
|
||||||
555
yang/ietf-netconf-monitoring@2010-10-04.yang
Normal file
555
yang/ietf-netconf-monitoring@2010-10-04.yang
Normal file
|
|
@ -0,0 +1,555 @@
|
||||||
|
module ietf-netconf-monitoring {
|
||||||
|
|
||||||
|
namespace "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring";
|
||||||
|
prefix "ncm";
|
||||||
|
|
||||||
|
import ietf-yang-types { prefix yang; }
|
||||||
|
import ietf-inet-types { prefix inet; }
|
||||||
|
|
||||||
|
organization
|
||||||
|
"IETF NETCONF (Network Configuration) Working Group";
|
||||||
|
|
||||||
|
contact
|
||||||
|
"WG Web: <http://tools.ietf.org/wg/netconf/>
|
||||||
|
WG List: <mailto:netconf@ietf.org>
|
||||||
|
|
||||||
|
WG Chair: Mehmet Ersue
|
||||||
|
<mailto:mehmet.ersue@nsn.com>
|
||||||
|
|
||||||
|
WG Chair: Bert Wijnen
|
||||||
|
<mailto:bertietf@bwijnen.net>
|
||||||
|
|
||||||
|
Editor: Mark Scott
|
||||||
|
<mailto:mark.scott@ericsson.com>
|
||||||
|
|
||||||
|
Editor: Martin Bjorklund
|
||||||
|
<mailto:mbj@tail-f.com>";
|
||||||
|
|
||||||
|
description
|
||||||
|
"NETCONF Monitoring Module.
|
||||||
|
All elements in this module are read-only.
|
||||||
|
|
||||||
|
Copyright (c) 2010 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 6022; see
|
||||||
|
the RFC itself for full legal notices.";
|
||||||
|
|
||||||
|
revision 2010-10-04 {
|
||||||
|
description
|
||||||
|
"Initial revision.";
|
||||||
|
reference
|
||||||
|
"RFC 6022: YANG Module for NETCONF Monitoring";
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef netconf-datastore-type {
|
||||||
|
type enumeration {
|
||||||
|
enum running;
|
||||||
|
enum candidate;
|
||||||
|
enum startup;
|
||||||
|
}
|
||||||
|
description
|
||||||
|
"Enumeration of possible NETCONF datastore types.";
|
||||||
|
reference
|
||||||
|
"RFC 4741: NETCONF Configuration Protocol";
|
||||||
|
}
|
||||||
|
|
||||||
|
identity transport {
|
||||||
|
description
|
||||||
|
"Base identity for NETCONF transport types.";
|
||||||
|
}
|
||||||
|
|
||||||
|
identity netconf-ssh {
|
||||||
|
base transport;
|
||||||
|
description
|
||||||
|
"NETCONF over Secure Shell (SSH).";
|
||||||
|
reference
|
||||||
|
"RFC 4742: Using the NETCONF Configuration Protocol
|
||||||
|
over Secure SHell (SSH)";
|
||||||
|
}
|
||||||
|
|
||||||
|
identity netconf-soap-over-beep {
|
||||||
|
base transport;
|
||||||
|
description
|
||||||
|
"NETCONF over Simple Object Access Protocol (SOAP) over
|
||||||
|
Blocks Extensible Exchange Protocol (BEEP).";
|
||||||
|
reference
|
||||||
|
"RFC 4743: Using NETCONF over the Simple Object
|
||||||
|
Access Protocol (SOAP)";
|
||||||
|
}
|
||||||
|
|
||||||
|
identity netconf-soap-over-https {
|
||||||
|
base transport;
|
||||||
|
description
|
||||||
|
"NETCONF over Simple Object Access Protocol (SOAP)
|
||||||
|
over Hypertext Transfer Protocol Secure (HTTPS).";
|
||||||
|
reference
|
||||||
|
"RFC 4743: Using NETCONF over the Simple Object
|
||||||
|
Access Protocol (SOAP)";
|
||||||
|
}
|
||||||
|
|
||||||
|
identity netconf-beep {
|
||||||
|
base transport;
|
||||||
|
description
|
||||||
|
"NETCONF over Blocks Extensible Exchange Protocol (BEEP).";
|
||||||
|
reference
|
||||||
|
"RFC 4744: Using the NETCONF Protocol over the
|
||||||
|
Blocks Extensible Exchange Protocol (BEEP)";
|
||||||
|
}
|
||||||
|
|
||||||
|
identity netconf-tls {
|
||||||
|
base transport;
|
||||||
|
description
|
||||||
|
"NETCONF over Transport Layer Security (TLS).";
|
||||||
|
reference
|
||||||
|
"RFC 5539: NETCONF over Transport Layer Security (TLS)";
|
||||||
|
}
|
||||||
|
|
||||||
|
identity schema-format {
|
||||||
|
description
|
||||||
|
"Base identity for data model schema languages.";
|
||||||
|
}
|
||||||
|
|
||||||
|
identity xsd {
|
||||||
|
base schema-format;
|
||||||
|
description
|
||||||
|
"W3C XML Schema Definition.";
|
||||||
|
reference
|
||||||
|
"W3C REC REC-xmlschema-1-20041028:
|
||||||
|
XML Schema Part 1: Structures";
|
||||||
|
}
|
||||||
|
|
||||||
|
identity yang {
|
||||||
|
base schema-format;
|
||||||
|
description
|
||||||
|
"The YANG data modeling language for NETCONF.";
|
||||||
|
reference
|
||||||
|
"RFC 6020: YANG - A Data Modeling Language for the
|
||||||
|
Network Configuration Protocol (NETCONF)";
|
||||||
|
}
|
||||||
|
|
||||||
|
identity yin {
|
||||||
|
base schema-format;
|
||||||
|
description
|
||||||
|
"The YIN syntax for YANG.";
|
||||||
|
reference
|
||||||
|
"RFC 6020: YANG - A Data Modeling Language for the
|
||||||
|
Network Configuration Protocol (NETCONF)";
|
||||||
|
}
|
||||||
|
|
||||||
|
identity rng {
|
||||||
|
base schema-format;
|
||||||
|
description
|
||||||
|
"Regular Language for XML Next Generation (RELAX NG).";
|
||||||
|
reference
|
||||||
|
"ISO/IEC 19757-2:2008: RELAX NG";
|
||||||
|
}
|
||||||
|
|
||||||
|
identity rnc {
|
||||||
|
base schema-format;
|
||||||
|
description
|
||||||
|
"Relax NG Compact Syntax";
|
||||||
|
reference
|
||||||
|
"ISO/IEC 19757-2:2008: RELAX NG";
|
||||||
|
}
|
||||||
|
|
||||||
|
grouping common-counters {
|
||||||
|
description
|
||||||
|
"Counters that exist both per session, and also globally,
|
||||||
|
accumulated from all sessions.";
|
||||||
|
|
||||||
|
leaf in-rpcs {
|
||||||
|
type yang:zero-based-counter32;
|
||||||
|
description
|
||||||
|
"Number of correct <rpc> messages received.";
|
||||||
|
}
|
||||||
|
leaf in-bad-rpcs {
|
||||||
|
type yang:zero-based-counter32;
|
||||||
|
description
|
||||||
|
"Number of messages received when an <rpc> message was expected,
|
||||||
|
that were not correct <rpc> messages. This includes XML parse
|
||||||
|
errors and errors on the rpc layer.";
|
||||||
|
}
|
||||||
|
leaf out-rpc-errors {
|
||||||
|
type yang:zero-based-counter32;
|
||||||
|
description
|
||||||
|
"Number of <rpc-reply> messages sent that contained an
|
||||||
|
<rpc-error> element.";
|
||||||
|
}
|
||||||
|
leaf out-notifications {
|
||||||
|
type yang:zero-based-counter32;
|
||||||
|
description
|
||||||
|
"Number of <notification> messages sent.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
container netconf-state {
|
||||||
|
config false;
|
||||||
|
description
|
||||||
|
"The netconf-state container is the root of the monitoring
|
||||||
|
data model.";
|
||||||
|
|
||||||
|
container capabilities {
|
||||||
|
description
|
||||||
|
"Contains the list of NETCONF capabilities supported by the
|
||||||
|
server.";
|
||||||
|
|
||||||
|
leaf-list capability {
|
||||||
|
type inet:uri;
|
||||||
|
description
|
||||||
|
"List of NETCONF capabilities supported by the server.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
container datastores {
|
||||||
|
description
|
||||||
|
"Contains the list of NETCONF configuration datastores.";
|
||||||
|
|
||||||
|
list datastore {
|
||||||
|
key name;
|
||||||
|
description
|
||||||
|
"List of NETCONF configuration datastores supported by
|
||||||
|
the NETCONF server and related information.";
|
||||||
|
|
||||||
|
leaf name {
|
||||||
|
type netconf-datastore-type;
|
||||||
|
description
|
||||||
|
"Name of the datastore associated with this list entry.";
|
||||||
|
}
|
||||||
|
container locks {
|
||||||
|
presence
|
||||||
|
"This container is present only if the datastore
|
||||||
|
is locked.";
|
||||||
|
description
|
||||||
|
"The NETCONF <lock> and <partial-lock> operations allow
|
||||||
|
a client to lock specific resources in a datastore. The
|
||||||
|
NETCONF server will prevent changes to the locked
|
||||||
|
resources by all sessions except the one that acquired
|
||||||
|
the lock(s).
|
||||||
|
|
||||||
|
Monitoring information is provided for each datastore
|
||||||
|
entry including details such as the session that acquired
|
||||||
|
the lock, the type of lock (global or partial) and the
|
||||||
|
list of locked resources. Multiple locks per datastore
|
||||||
|
are supported.";
|
||||||
|
|
||||||
|
grouping lock-info {
|
||||||
|
description
|
||||||
|
"Lock related parameters, common to both global and
|
||||||
|
partial locks.";
|
||||||
|
|
||||||
|
leaf locked-by-session {
|
||||||
|
type uint32;
|
||||||
|
mandatory true;
|
||||||
|
description
|
||||||
|
"The session ID of the session that has locked
|
||||||
|
this resource. Both a global lock and a partial
|
||||||
|
lock MUST contain the NETCONF session-id.
|
||||||
|
|
||||||
|
If the lock is held by a session that is not managed
|
||||||
|
by the NETCONF server (e.g., a CLI session), a session
|
||||||
|
id of 0 (zero) is reported.";
|
||||||
|
reference
|
||||||
|
"RFC 4741: NETCONF Configuration Protocol";
|
||||||
|
}
|
||||||
|
leaf locked-time {
|
||||||
|
type yang:date-and-time;
|
||||||
|
mandatory true;
|
||||||
|
description
|
||||||
|
"The date and time of when the resource was
|
||||||
|
locked.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
choice lock-type {
|
||||||
|
description
|
||||||
|
"Indicates if a global lock or a set of partial locks
|
||||||
|
are set.";
|
||||||
|
|
||||||
|
container global-lock {
|
||||||
|
description
|
||||||
|
"Present if the global lock is set.";
|
||||||
|
uses lock-info;
|
||||||
|
}
|
||||||
|
|
||||||
|
list partial-lock {
|
||||||
|
key lock-id;
|
||||||
|
description
|
||||||
|
"List of partial locks.";
|
||||||
|
reference
|
||||||
|
"RFC 5717: Partial Lock Remote Procedure Call (RPC) for
|
||||||
|
NETCONF";
|
||||||
|
|
||||||
|
leaf lock-id {
|
||||||
|
type uint32;
|
||||||
|
description
|
||||||
|
"This is the lock id returned in the <partial-lock>
|
||||||
|
response.";
|
||||||
|
}
|
||||||
|
uses lock-info;
|
||||||
|
leaf-list select {
|
||||||
|
type yang:xpath1.0;
|
||||||
|
min-elements 1;
|
||||||
|
description
|
||||||
|
"The xpath expression that was used to request
|
||||||
|
the lock. The select expression indicates the
|
||||||
|
original intended scope of the lock.";
|
||||||
|
}
|
||||||
|
leaf-list locked-node {
|
||||||
|
type instance-identifier;
|
||||||
|
description
|
||||||
|
"The list of instance-identifiers (i.e., the
|
||||||
|
locked nodes).
|
||||||
|
|
||||||
|
The scope of the partial lock is defined by the list
|
||||||
|
of locked nodes.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
container schemas {
|
||||||
|
description
|
||||||
|
"Contains the list of data model schemas supported by the
|
||||||
|
server.";
|
||||||
|
|
||||||
|
list schema {
|
||||||
|
key "identifier version format";
|
||||||
|
|
||||||
|
description
|
||||||
|
"List of data model schemas supported by the server.";
|
||||||
|
|
||||||
|
leaf identifier {
|
||||||
|
type string;
|
||||||
|
description
|
||||||
|
"Identifier to uniquely reference the schema. The
|
||||||
|
identifier is used in the <get-schema> operation and may
|
||||||
|
be used for other purposes such as file retrieval.
|
||||||
|
|
||||||
|
For modeling languages that support or require a data
|
||||||
|
model name (e.g., YANG module name) the identifier MUST
|
||||||
|
match that name. For YANG data models, the identifier is
|
||||||
|
the name of the module or submodule. In other cases, an
|
||||||
|
identifier such as a filename MAY be used instead.";
|
||||||
|
}
|
||||||
|
leaf version {
|
||||||
|
type string;
|
||||||
|
description
|
||||||
|
"Version of the schema supported. Multiple versions MAY be
|
||||||
|
supported simultaneously by a NETCONF server. Each
|
||||||
|
version MUST be reported individually in the schema list,
|
||||||
|
i.e., with same identifier, possibly different location,
|
||||||
|
but different version.
|
||||||
|
|
||||||
|
For YANG data models, version is the value of the most
|
||||||
|
recent YANG 'revision' statement in the module or
|
||||||
|
submodule, or the empty string if no 'revision' statement
|
||||||
|
is present.";
|
||||||
|
}
|
||||||
|
leaf format {
|
||||||
|
type identityref {
|
||||||
|
base schema-format;
|
||||||
|
}
|
||||||
|
description
|
||||||
|
"The data modeling language the schema is written
|
||||||
|
in (currently xsd, yang, yin, rng, or rnc).
|
||||||
|
For YANG data models, 'yang' format MUST be supported and
|
||||||
|
'yin' format MAY also be provided.";
|
||||||
|
}
|
||||||
|
leaf namespace {
|
||||||
|
type inet:uri;
|
||||||
|
mandatory true;
|
||||||
|
description
|
||||||
|
"The XML namespace defined by the data model.
|
||||||
|
|
||||||
|
For YANG data models, this is the module's namespace.
|
||||||
|
If the list entry describes a submodule, this field
|
||||||
|
contains the namespace of the module to which the
|
||||||
|
submodule belongs.";
|
||||||
|
}
|
||||||
|
leaf-list location {
|
||||||
|
type union {
|
||||||
|
type enumeration {
|
||||||
|
enum "NETCONF";
|
||||||
|
}
|
||||||
|
type inet:uri;
|
||||||
|
}
|
||||||
|
description
|
||||||
|
"One or more locations from which the schema can be
|
||||||
|
retrieved. This list SHOULD contain at least one
|
||||||
|
entry per schema.
|
||||||
|
|
||||||
|
A schema entry may be located on a remote file system
|
||||||
|
(e.g., reference to file system for ftp retrieval) or
|
||||||
|
retrieved directly from a server supporting the
|
||||||
|
<get-schema> operation (denoted by the value 'NETCONF').";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
container sessions {
|
||||||
|
description
|
||||||
|
"The sessions container includes session-specific data for
|
||||||
|
NETCONF management sessions. The session list MUST include
|
||||||
|
all currently active NETCONF sessions.";
|
||||||
|
|
||||||
|
list session {
|
||||||
|
key session-id;
|
||||||
|
description
|
||||||
|
"All NETCONF sessions managed by the NETCONF server
|
||||||
|
MUST be reported in this list.";
|
||||||
|
|
||||||
|
leaf session-id {
|
||||||
|
type uint32 {
|
||||||
|
range "1..max";
|
||||||
|
}
|
||||||
|
description
|
||||||
|
"Unique identifier for the session. This value is the
|
||||||
|
NETCONF session identifier, as defined in RFC 4741.";
|
||||||
|
reference
|
||||||
|
"RFC 4741: NETCONF Configuration Protocol";
|
||||||
|
}
|
||||||
|
leaf transport {
|
||||||
|
type identityref {
|
||||||
|
base transport;
|
||||||
|
}
|
||||||
|
mandatory true;
|
||||||
|
description
|
||||||
|
"Identifies the transport for each session, e.g.,
|
||||||
|
'netconf-ssh', 'netconf-soap', etc.";
|
||||||
|
}
|
||||||
|
leaf username {
|
||||||
|
type string;
|
||||||
|
mandatory true;
|
||||||
|
description
|
||||||
|
"The username is the client identity that was authenticated
|
||||||
|
by the NETCONF transport protocol. The algorithm used to
|
||||||
|
derive the username is NETCONF transport protocol specific
|
||||||
|
and in addition specific to the authentication mechanism
|
||||||
|
used by the NETCONF transport protocol.";
|
||||||
|
}
|
||||||
|
leaf source-host {
|
||||||
|
type inet:host;
|
||||||
|
description
|
||||||
|
"Host identifier of the NETCONF client. The value
|
||||||
|
returned is implementation specific (e.g., hostname,
|
||||||
|
IPv4 address, IPv6 address)";
|
||||||
|
}
|
||||||
|
leaf login-time {
|
||||||
|
type yang:date-and-time;
|
||||||
|
mandatory true;
|
||||||
|
description
|
||||||
|
"Time at the server at which the session was established.";
|
||||||
|
}
|
||||||
|
uses common-counters {
|
||||||
|
description
|
||||||
|
"Per-session counters. Zero based with following reset
|
||||||
|
behaviour:
|
||||||
|
- at start of a session
|
||||||
|
- when max value is reached";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
container statistics {
|
||||||
|
description
|
||||||
|
"Statistical data pertaining to the NETCONF server.";
|
||||||
|
|
||||||
|
leaf netconf-start-time {
|
||||||
|
type yang:date-and-time;
|
||||||
|
description
|
||||||
|
"Date and time at which the management subsystem was
|
||||||
|
started.";
|
||||||
|
}
|
||||||
|
leaf in-bad-hellos {
|
||||||
|
type yang:zero-based-counter32;
|
||||||
|
description
|
||||||
|
"Number of sessions silently dropped because an
|
||||||
|
invalid <hello> message was received. This includes <hello>
|
||||||
|
messages with a 'session-id' attribute, bad namespace, and
|
||||||
|
bad capability declarations.";
|
||||||
|
}
|
||||||
|
leaf in-sessions {
|
||||||
|
type yang:zero-based-counter32;
|
||||||
|
description
|
||||||
|
"Number of sessions started. This counter is incremented
|
||||||
|
when a <hello> message with a <session-id> is sent.
|
||||||
|
|
||||||
|
'in-sessions' - 'in-bad-hellos' =
|
||||||
|
'number of correctly started netconf sessions'";
|
||||||
|
}
|
||||||
|
leaf dropped-sessions {
|
||||||
|
type yang:zero-based-counter32;
|
||||||
|
description
|
||||||
|
"Number of sessions that were abnormally terminated, e.g.,
|
||||||
|
due to idle timeout or transport close. This counter is not
|
||||||
|
incremented when a session is properly closed by a
|
||||||
|
<close-session> operation, or killed by a <kill-session>
|
||||||
|
operation.";
|
||||||
|
}
|
||||||
|
uses common-counters {
|
||||||
|
description
|
||||||
|
"Global counters, accumulated from all sessions.
|
||||||
|
Zero based with following reset behaviour:
|
||||||
|
- re-initialization of NETCONF server
|
||||||
|
- when max value is reached";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rpc get-schema {
|
||||||
|
description
|
||||||
|
"This operation is used to retrieve a schema from the
|
||||||
|
NETCONF server.
|
||||||
|
|
||||||
|
Positive Response:
|
||||||
|
The NETCONF server returns the requested schema.
|
||||||
|
|
||||||
|
Negative Response:
|
||||||
|
If requested schema does not exist, the <error-tag> is
|
||||||
|
'invalid-value'.
|
||||||
|
|
||||||
|
If more than one schema matches the requested parameters, the
|
||||||
|
<error-tag> is 'operation-failed', and <error-app-tag> is
|
||||||
|
'data-not-unique'.";
|
||||||
|
|
||||||
|
input {
|
||||||
|
leaf identifier {
|
||||||
|
type string;
|
||||||
|
mandatory true;
|
||||||
|
description
|
||||||
|
"Identifier for the schema list entry.";
|
||||||
|
}
|
||||||
|
leaf version {
|
||||||
|
type string;
|
||||||
|
description
|
||||||
|
"Version of the schema requested. If this parameter is not
|
||||||
|
present, and more than one version of the schema exists on
|
||||||
|
the server, a 'data-not-unique' error is returned, as
|
||||||
|
described above.";
|
||||||
|
}
|
||||||
|
leaf format {
|
||||||
|
type identityref {
|
||||||
|
base schema-format;
|
||||||
|
}
|
||||||
|
description
|
||||||
|
"The data modeling language of the schema. If this
|
||||||
|
parameter is not present, and more than one formats of
|
||||||
|
the schema exists on the server, a 'data-not-unique' error
|
||||||
|
is returned, as described above.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output {
|
||||||
|
anyxml data {
|
||||||
|
description
|
||||||
|
"Contains the schema content.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
94
yang/ietf-netconf-notification@2008-07-01.yang
Normal file
94
yang/ietf-netconf-notification@2008-07-01.yang
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
module ietf-restconf-monitoring {
|
||||||
|
namespace "urn:ietf:params:xml:ns:netconf:notification:1:0";
|
||||||
|
prefix "rcmon";
|
||||||
|
|
||||||
|
import ietf-yang-types { prefix yang; }
|
||||||
|
import ietf-inet-types { prefix inet; }
|
||||||
|
|
||||||
|
organization
|
||||||
|
"IETF NETCONF (Network Configuration) Working Group";
|
||||||
|
|
||||||
|
description
|
||||||
|
"Note this is a translation from RFC 5277 schema in section 4 to Yang.
|
||||||
|
RFC 5277 is Copyright (C) The IETF Trust (2008).";
|
||||||
|
|
||||||
|
revision 2008-07-01 {
|
||||||
|
description
|
||||||
|
"Initial revision.";
|
||||||
|
reference
|
||||||
|
"RFC 5277: NETCONF Event Notifications.";
|
||||||
|
}
|
||||||
|
|
||||||
|
container netconf {
|
||||||
|
config false;
|
||||||
|
description
|
||||||
|
"Contains NETCONF protocol monitoring information.";
|
||||||
|
|
||||||
|
container capabilities {
|
||||||
|
description
|
||||||
|
"Contains a list of protocol capability URIs.";
|
||||||
|
|
||||||
|
leaf-list capability {
|
||||||
|
type inet:uri;
|
||||||
|
description
|
||||||
|
"A RESTCONF protocol capability URI.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
container streams {
|
||||||
|
description
|
||||||
|
"Container representing the notification event streams
|
||||||
|
supported by the server.";
|
||||||
|
reference
|
||||||
|
"RFC 5277, Section 3.4, <streams> element.";
|
||||||
|
list stream {
|
||||||
|
key name;
|
||||||
|
description
|
||||||
|
"Each entry describes an event stream supported by
|
||||||
|
the server.";
|
||||||
|
|
||||||
|
leaf name {
|
||||||
|
type string;
|
||||||
|
description
|
||||||
|
"The stream name.";
|
||||||
|
reference
|
||||||
|
"RFC 5277, Section 3.4, <name> element.";
|
||||||
|
}
|
||||||
|
|
||||||
|
leaf description {
|
||||||
|
type string;
|
||||||
|
description
|
||||||
|
"Description of stream content.";
|
||||||
|
reference
|
||||||
|
"RFC 5277, Section 3.4, <description> element.";
|
||||||
|
}
|
||||||
|
|
||||||
|
leaf replay-support {
|
||||||
|
type boolean;
|
||||||
|
default false;
|
||||||
|
description
|
||||||
|
"Indicates if replay buffer is supported for this stream.
|
||||||
|
If 'true', then the server MUST support the 'start-time'
|
||||||
|
and 'stop-time' query parameters for this stream.";
|
||||||
|
reference
|
||||||
|
"RFC 5277, Section 3.4, <replaySupport> element.";
|
||||||
|
}
|
||||||
|
|
||||||
|
leaf replay-log-creation-time {
|
||||||
|
when "../replay-support" {
|
||||||
|
description
|
||||||
|
"Only present if notification replay is supported.";
|
||||||
|
}
|
||||||
|
type yang:date-and-time;
|
||||||
|
description
|
||||||
|
"Indicates the time the replay log for this stream
|
||||||
|
was created.";
|
||||||
|
reference
|
||||||
|
"RFC 5277, Section 3.4, <replayLogCreationTime>
|
||||||
|
element.";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue