Mount-point support for restconf
This commit is contained in:
parent
597cbe882b
commit
2e6d9167f2
9 changed files with 164 additions and 22 deletions
|
|
@ -275,7 +275,7 @@ identityref_add_ns(cxobj *x,
|
||||||
|
|
||||||
/*! Given a top-level yspec and mountpoint xpath compute a set of
|
/*! Given a top-level yspec and mountpoint xpath compute a set of
|
||||||
*
|
*
|
||||||
* Manipulate top-level and a mointpoint:
|
* Manipulate top-level and a mountpoint:
|
||||||
* YSPEC: yspec0 yspec1
|
* YSPEC: yspec0 yspec1
|
||||||
* XML: top0-->bot0-->top1-->bot1
|
* XML: top0-->bot0-->top1-->bot1
|
||||||
* API-PATH: api-path0 api-path1
|
* API-PATH: api-path0 api-path1
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
* [Systemd](#systemd)
|
* [Systemd](#systemd)
|
||||||
* [Docker](#docker)
|
* [Docker](#docker)
|
||||||
* [Plugins](#plugins)
|
* [Plugins](#plugins)
|
||||||
|
* [Mount-points](#mount-points)
|
||||||
|
|
||||||
## Background
|
## Background
|
||||||
|
|
||||||
|
|
@ -446,3 +447,27 @@ static clixon_plugin_api api = {
|
||||||
.ca_interrupt=NULL, /* cligen_interrupt_cb_t */
|
.ca_interrupt=NULL, /* cligen_interrupt_cb_t */
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Mount-points
|
||||||
|
|
||||||
|
You can set-up the example for a simple RFC 8528 Yang schema mount. A single top-level yang can be defined to be mounted.:
|
||||||
|
|
||||||
|
1. Enable CLICON_YANG_SCHEMA_MOUNT
|
||||||
|
2. Define the mount-point using the ietf-yang-schema-mount mount-point extension
|
||||||
|
3. Start the backend, cli and restconf with `-- -m <name> -M <urn>`, where `name` and `urn` is the name and namespace of the mounted YANG, respectively.
|
||||||
|
|
||||||
|
A simple example on how to define a mount-point
|
||||||
|
```
|
||||||
|
import ietf-yang-schema-mount {
|
||||||
|
prefix yangmnt;
|
||||||
|
}
|
||||||
|
container root{
|
||||||
|
presence "Otherwise root is not visible";
|
||||||
|
yangmnt:mount-point "mylabel"{
|
||||||
|
description "Root for other yang models";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
CLI completion of the mounted part is not implemented in the example, see the
|
||||||
|
clixon-controller `controller_cligen_treeref_wrap()` for an example.
|
||||||
|
|
@ -58,7 +58,7 @@
|
||||||
|
|
||||||
/*! Yang schema mount
|
/*! Yang schema mount
|
||||||
*
|
*
|
||||||
* Start backend with -- -m <yang> -M <namespace>
|
* Start cli with -- -m <yang> -M <namespace>
|
||||||
* Mount this yang on mountpoint
|
* Mount this yang on mountpoint
|
||||||
*/
|
*/
|
||||||
static char *_mount_yang = NULL;
|
static char *_mount_yang = NULL;
|
||||||
|
|
@ -313,6 +313,8 @@ clixon_plugin_init(clicon_handle h)
|
||||||
clicon_err(OE_PLUGIN, EINVAL, "Both -m and -M must be given for mounts");
|
clicon_err(OE_PLUGIN, EINVAL, "Both -m and -M must be given for mounts");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
/* XXX Not implemented: CLI completion for mountpoints, see clixon-controller
|
||||||
|
*/
|
||||||
return &api;
|
return &api;
|
||||||
done:
|
done:
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
||||||
|
|
@ -51,12 +51,20 @@
|
||||||
|
|
||||||
/* Command line options to be passed to getopt(3)
|
/* Command line options to be passed to getopt(3)
|
||||||
*/
|
*/
|
||||||
#define RESTCONF_EXAMPLE_OPTS ""
|
#define RESTCONF_EXAMPLE_OPTS "m:M:"
|
||||||
|
|
||||||
static const char Base64[] =
|
static const char Base64[] =
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
static const char Pad64 = '=';
|
static const char Pad64 = '=';
|
||||||
|
|
||||||
|
/*! Yang schema mount
|
||||||
|
*
|
||||||
|
* Start restconf with -- -m <yang> -M <namespace>
|
||||||
|
* Mount this yang on mountpoint
|
||||||
|
*/
|
||||||
|
static char *_mount_yang = NULL;
|
||||||
|
static char *_mount_namespace = NULL;
|
||||||
|
|
||||||
/* skips all whitespace anywhere.
|
/* skips all whitespace anywhere.
|
||||||
converts characters, four at a time, starting at (or after)
|
converts characters, four at a time, starting at (or after)
|
||||||
src from base - 64 numbers into three 8 bit bytes in the target area.
|
src from base - 64 numbers into three 8 bit bytes in the target area.
|
||||||
|
|
@ -350,6 +358,62 @@ example_restconf_start(clicon_handle h)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Example YANG schema mount
|
||||||
|
*
|
||||||
|
* Given an XML mount-point xt, return XML yang-lib modules-set
|
||||||
|
* @param[in] h Clixon handle
|
||||||
|
* @param[in] xt XML mount-point in XML tree
|
||||||
|
* @param[out] config If '0' all data nodes in the mounted schema are read-only
|
||||||
|
* @param[out] validate Do or dont do full RFC 7950 validation
|
||||||
|
* @param[out] yanglib XML yang-lib module-set tree
|
||||||
|
* @retval 0 OK
|
||||||
|
* @retval -1 Error
|
||||||
|
* XXX hardcoded to clixon-example@2022-11-01.yang regardless of xt
|
||||||
|
* @see RFC 8528
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
restconf_yang_mount(clicon_handle h,
|
||||||
|
cxobj *xt,
|
||||||
|
int *config,
|
||||||
|
validate_level *vl,
|
||||||
|
cxobj **yanglib)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
cbuf *cb = NULL;
|
||||||
|
|
||||||
|
if (config)
|
||||||
|
*config = 1;
|
||||||
|
if (vl)
|
||||||
|
*vl = VL_FULL;
|
||||||
|
if (yanglib && _mount_yang){
|
||||||
|
if ((cb = cbuf_new()) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
cprintf(cb, "<yang-library xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">");
|
||||||
|
cprintf(cb, "<module-set>");
|
||||||
|
cprintf(cb, "<name>mylabel</name>"); // XXX label in test_yang_schema_mount
|
||||||
|
cprintf(cb, "<module>");
|
||||||
|
/* In yang name+namespace is mandatory, but not revision */
|
||||||
|
cprintf(cb, "<name>%s</name>", _mount_yang); // mandatory
|
||||||
|
cprintf(cb, "<namespace>%s</namespace>", _mount_namespace); // mandatory
|
||||||
|
// cprintf(cb, "<revision>2022-11-01</revision>");
|
||||||
|
cprintf(cb, "</module>");
|
||||||
|
cprintf(cb, "</module-set>");
|
||||||
|
cprintf(cb, "</yang-library>");
|
||||||
|
if (clixon_xml_parse_string(cbuf_get(cb), YB_NONE, NULL, yanglib, NULL) < 0)
|
||||||
|
goto done;
|
||||||
|
if (xml_rootchild(*yanglib, 0, yanglib) < 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
if (cb)
|
||||||
|
cbuf_free(cb);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
clixon_plugin_api * clixon_plugin_init(clicon_handle h);
|
clixon_plugin_api * clixon_plugin_init(clicon_handle h);
|
||||||
|
|
||||||
static clixon_plugin_api api = {
|
static clixon_plugin_api api = {
|
||||||
|
|
@ -357,7 +421,8 @@ static clixon_plugin_api api = {
|
||||||
clixon_plugin_init, /* init */
|
clixon_plugin_init, /* init */
|
||||||
example_restconf_start,/* start */
|
example_restconf_start,/* start */
|
||||||
NULL, /* exit */
|
NULL, /* exit */
|
||||||
.ca_auth=example_restconf_credentials /* auth */
|
.ca_auth=example_restconf_credentials, /* auth */
|
||||||
|
.ca_yang_mount=restconf_yang_mount, /* RFC 8528 schema mount */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! Restconf plugin initialization
|
/*! Restconf plugin initialization
|
||||||
|
|
@ -382,11 +447,23 @@ clixon_plugin_init(clicon_handle h)
|
||||||
optind = 1;
|
optind = 1;
|
||||||
while ((c = getopt(argc, argv, RESTCONF_EXAMPLE_OPTS)) != -1)
|
while ((c = getopt(argc, argv, RESTCONF_EXAMPLE_OPTS)) != -1)
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
case 'm':
|
||||||
|
_mount_yang = optarg;
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
_mount_namespace = optarg;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if ((_mount_yang && !_mount_namespace) || (!_mount_yang && _mount_namespace)){
|
||||||
|
clicon_err(OE_PLUGIN, EINVAL, "Both -m and -M must be given for mounts");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
/* Register local netconf rpc client (note not backend rpc client) */
|
/* Register local netconf rpc client (note not backend rpc client) */
|
||||||
if (rpc_callback_register(h, restconf_client_rpc, NULL, "urn:example:clixon", "client-rpc") < 0)
|
if (rpc_callback_register(h, restconf_client_rpc, NULL, "urn:example:clixon", "client-rpc") < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
return &api;
|
return &api;
|
||||||
|
done:
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -808,21 +808,21 @@ api_path2xpath_cvv(cvec *api_path,
|
||||||
cprintf(xpath, "%s", name);
|
cprintf(xpath, "%s", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If x/y is mountpoint, pass moint yspec to children */
|
/* If x/y is mountpoint, pass mount yspec to children */
|
||||||
if ((ret = yang_schema_mount_point(y)) < 0)
|
if ((ret = yang_schema_mount_point(y)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 1){
|
if (ret == 1){
|
||||||
yang_stmt *y1 = NULL;
|
yang_stmt *y1 = NULL;
|
||||||
if (xml_nsctx_yangspec(yspec, &nsc) < 0)
|
if (xml_nsctx_yangspec(yspec, &nsc) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
/* cf xml_bind_yang0_opt/xml_yang_mount_get */
|
||||||
if (yang_mount_get(y, cbuf_get(xpath), &y1) < 0)
|
if (yang_mount_get(y, cbuf_get(xpath), &y1) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (y1 == NULL || yang_keyword_get(y1) != Y_SPEC){
|
if (y1 != NULL){
|
||||||
clicon_err(OE_YANG, 0, "No such mountpoint %s", cbuf_get(xpath));
|
y = y1;
|
||||||
goto done;
|
yspec = y1;
|
||||||
|
root = 1;
|
||||||
}
|
}
|
||||||
yspec = y1;
|
|
||||||
root = 1;
|
|
||||||
}
|
}
|
||||||
if (prefix){
|
if (prefix){
|
||||||
free(prefix);
|
free(prefix);
|
||||||
|
|
@ -1151,7 +1151,7 @@ api_path2xml_vec(char **vec,
|
||||||
if (xmlns_set(x, NULL, namespace) < 0)
|
if (xmlns_set(x, NULL, namespace) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* If x/y is mountpoint, pass moint yspec to children */
|
/* If x/y is mountpoint, pass mount yspec to children */
|
||||||
if ((ret = yang_schema_mount_point(y)) < 0)
|
if ((ret = yang_schema_mount_point(y)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 1){
|
if (ret == 1){
|
||||||
|
|
@ -1164,13 +1164,11 @@ api_path2xml_vec(char **vec,
|
||||||
clicon_err(OE_YANG, 0, "No xpath from xml");
|
clicon_err(OE_YANG, 0, "No xpath from xml");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (yang_mount_get(y, xpath, &y1) < 0)
|
/* cf xml_bind_yang0_opt/xml_yang_mount_get */
|
||||||
|
if (yang_mount_get(y, xpath, &y1) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (y1 == NULL){
|
if (y1 != NULL)
|
||||||
clicon_err(OE_YANG, 0, "No such mountpoint %s", xpath);
|
y = y1;
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
y = y1;
|
|
||||||
}
|
}
|
||||||
if ((retval = api_path2xml_vec(vec+1, nvec-1,
|
if ((retval = api_path2xml_vec(vec+1, nvec-1,
|
||||||
x, y,
|
x, y,
|
||||||
|
|
|
||||||
|
|
@ -1105,7 +1105,7 @@ xpath_traverse_canonical(xpath_tree *xs,
|
||||||
* if (reason) cbuf_free(reason);
|
* if (reason) cbuf_free(reason);
|
||||||
* @endcode
|
* @endcode
|
||||||
* @note Unsolvable issue of mountpoints, eg an xpath of //x:foo where foo is under one or several
|
* @note Unsolvable issue of mountpoints, eg an xpath of //x:foo where foo is under one or several
|
||||||
* mointpoints: a well-defined namespace cannot be determined. Therefore just allow
|
* mountpoints: a well-defined namespace cannot be determined. Therefore just allow
|
||||||
* inconsistencies and hope that it will be covered by other code
|
* inconsistencies and hope that it will be covered by other code
|
||||||
* @see xpath2xml
|
* @see xpath2xml
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -153,6 +153,7 @@ yang_mount_get(yang_stmt *y,
|
||||||
cvec *cvv = NULL;
|
cvec *cvv = NULL;
|
||||||
cg_var *cv;
|
cg_var *cv;
|
||||||
|
|
||||||
|
clicon_debug(CLIXON_DBG_DEFAULT, "%s %s %p", __FUNCTION__, xpath, y);
|
||||||
/* Special value in yang unknown node for mount-points: mapping from xpath->mounted yspec */
|
/* Special value in yang unknown node for mount-points: mapping from xpath->mounted yspec */
|
||||||
if ((cvv = yang_cvec_get(y)) != NULL &&
|
if ((cvv = yang_cvec_get(y)) != NULL &&
|
||||||
(cv = cvec_find(cvv, xpath)) != NULL &&
|
(cv = cvec_find(cvv, xpath)) != NULL &&
|
||||||
|
|
@ -181,6 +182,7 @@ yang_mount_set(yang_stmt *y,
|
||||||
cg_var *cv;
|
cg_var *cv;
|
||||||
cg_var *cv2;
|
cg_var *cv2;
|
||||||
|
|
||||||
|
clicon_debug(CLIXON_DBG_DEFAULT, "%s %s %p", __FUNCTION__, xpath, y);
|
||||||
if ((cvv = yang_cvec_get(y)) != NULL &&
|
if ((cvv = yang_cvec_get(y)) != NULL &&
|
||||||
(cv = cvec_find(cvv, xpath)) != NULL &&
|
(cv = cvec_find(cvv, xpath)) != NULL &&
|
||||||
(yspec0 = cv_void_get(cv)) != NULL){
|
(yspec0 = cv_void_get(cv)) != NULL){
|
||||||
|
|
@ -210,7 +212,7 @@ yang_mount_set(yang_stmt *y,
|
||||||
/*! Get yangspec mount-point
|
/*! Get yangspec mount-point
|
||||||
*
|
*
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
* @param[in] x XML moint-point node
|
* @param[in] x XML mount-point node
|
||||||
* @param[out] vallevel Do or dont do full RFC 7950 validation if given
|
* @param[out] vallevel Do or dont do full RFC 7950 validation if given
|
||||||
* @param[out] yspec YANG stmt spec
|
* @param[out] yspec YANG stmt spec
|
||||||
* @retval 1 x is a mount-point: yspec may be set
|
* @retval 1 x is a mount-point: yspec may be set
|
||||||
|
|
@ -274,7 +276,7 @@ xml_yang_mount_get(clicon_handle h,
|
||||||
/*! Set yangspec mount-point via XML mount-point node
|
/*! Set yangspec mount-point via XML mount-point node
|
||||||
*
|
*
|
||||||
* Stored in a separate structure (not in XML config tree)
|
* Stored in a separate structure (not in XML config tree)
|
||||||
* @param[in] x XML moint-point node
|
* @param[in] x XML mount-point node
|
||||||
* @param[in] yspec Yangspec for this mount-point (consumed)
|
* @param[in] yspec Yangspec for this mount-point (consumed)
|
||||||
* @retval 0 OK
|
* @retval 0 OK
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ new "xpath canonical form (no default should fail)"
|
||||||
expectpart "$($clixon_util_xpath -c -y $ydir -p /x/j:y -n i:urn:example:a -n j:urn:example:b 2>&1)" 0 "/x/j:y: No namespace found for prefix"
|
expectpart "$($clixon_util_xpath -c -y $ydir -p /x/j:y -n i:urn:example:a -n j:urn:example:b 2>&1)" 0 "/x/j:y: No namespace found for prefix"
|
||||||
|
|
||||||
if false; then
|
if false; then
|
||||||
# No, with mointpoints I cant fail unknown prefix, see comment in xpath2canonical
|
# No, with mountpoints I cant fail unknown prefix, see comment in xpath2canonical
|
||||||
new "xpath canonical form (wrong namespace should fail)"
|
new "xpath canonical form (wrong namespace should fail)"
|
||||||
expectpart "$($clixon_util_xpath -c -y $ydir -p /i:x/j:y -n i:urn:example:c -n j:urn:example:b 2>&1)" 0 "/i:x/j:y: No yang found for namespace"
|
expectpart "$($clixon_util_xpath -c -y $ydir -p /i:x/j:y -n i:urn:example:c -n j:urn:example:b 2>&1)" 0 "/i:x/j:y: No yang found for namespace"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -16,16 +16,23 @@ fyang0=$dir/clixon-mount0.yang
|
||||||
fyang1=$dir/clixon-mount1.yang
|
fyang1=$dir/clixon-mount1.yang
|
||||||
fyang2=$dir/clixon-mount2.yang
|
fyang2=$dir/clixon-mount2.yang
|
||||||
|
|
||||||
|
CFD=$dir/conf.d
|
||||||
|
test -d $CFD || mkdir -p $CFD
|
||||||
|
|
||||||
AUTOCLI=$(autocli_config clixon-\* kw-nokey false)
|
AUTOCLI=$(autocli_config clixon-\* kw-nokey false)
|
||||||
|
RESTCONFIG=$(restconf_config none false)
|
||||||
|
|
||||||
cat <<EOF > $cfg
|
cat <<EOF > $cfg
|
||||||
<clixon-config xmlns="http://clicon.org/config">
|
<clixon-config xmlns="http://clicon.org/config">
|
||||||
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
|
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
|
||||||
|
<CLICON_CONFIGDIR>$CFD</CLICON_CONFIGDIR>
|
||||||
|
<CLICON_FEATURE>clixon-restconf:allow-auth-none</CLICON_FEATURE> <!-- Use auth-type=none -->
|
||||||
<CLICON_YANG_DIR>${YANG_INSTALLDIR}</CLICON_YANG_DIR>
|
<CLICON_YANG_DIR>${YANG_INSTALLDIR}</CLICON_YANG_DIR>
|
||||||
<CLICON_YANG_DIR>${dir}</CLICON_YANG_DIR>
|
<CLICON_YANG_DIR>${dir}</CLICON_YANG_DIR>
|
||||||
<CLICON_YANG_MAIN_FILE>$fyang</CLICON_YANG_MAIN_FILE>
|
<CLICON_YANG_MAIN_FILE>$fyang</CLICON_YANG_MAIN_FILE>
|
||||||
<CLICON_YANG_LIBRARY>true</CLICON_YANG_LIBRARY>
|
<CLICON_YANG_LIBRARY>true</CLICON_YANG_LIBRARY>
|
||||||
<CLICON_CLISPEC_DIR>$dir</CLICON_CLISPEC_DIR>
|
<CLICON_CLISPEC_DIR>$dir</CLICON_CLISPEC_DIR>
|
||||||
|
<CLICON_RESTCONF_DIR>/usr/local/lib/$APPNAME/restconf</CLICON_RESTCONF_DIR>
|
||||||
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
|
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
|
||||||
<CLICON_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
|
<CLICON_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
|
||||||
<CLICON_SOCK>/usr/local/var/run/$APPNAME.sock</CLICON_SOCK>
|
<CLICON_SOCK>/usr/local/var/run/$APPNAME.sock</CLICON_SOCK>
|
||||||
|
|
@ -36,6 +43,11 @@ cat <<EOF > $cfg
|
||||||
<CLICON_VALIDATE_STATE_XML>true</CLICON_VALIDATE_STATE_XML>
|
<CLICON_VALIDATE_STATE_XML>true</CLICON_VALIDATE_STATE_XML>
|
||||||
<CLICON_STREAM_DISCOVERY_RFC5277>true</CLICON_STREAM_DISCOVERY_RFC5277>
|
<CLICON_STREAM_DISCOVERY_RFC5277>true</CLICON_STREAM_DISCOVERY_RFC5277>
|
||||||
<CLICON_YANG_SCHEMA_MOUNT>true</CLICON_YANG_SCHEMA_MOUNT>
|
<CLICON_YANG_SCHEMA_MOUNT>true</CLICON_YANG_SCHEMA_MOUNT>
|
||||||
|
</clixon-config>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat <<EOF > $CFD/autocli.xml
|
||||||
|
<clixon-config xmlns="http://clicon.org/config">
|
||||||
<autocli>
|
<autocli>
|
||||||
<module-default>false</module-default>
|
<module-default>false</module-default>
|
||||||
<list-keyword-default>kw-nokey</list-keyword-default>
|
<list-keyword-default>kw-nokey</list-keyword-default>
|
||||||
|
|
@ -48,7 +60,14 @@ cat <<EOF > $cfg
|
||||||
</autocli>
|
</autocli>
|
||||||
</clixon-config>
|
</clixon-config>
|
||||||
EOF
|
EOF
|
||||||
# ${AUTOCLI}
|
|
||||||
|
# Define default restconfig config: RESTCONFIG
|
||||||
|
|
||||||
|
cat <<EOF > $CFD/restconf.xml
|
||||||
|
<clixon-config xmlns="http://clicon.org/config">
|
||||||
|
$RESTCONFIG
|
||||||
|
</clixon-config>
|
||||||
|
EOF
|
||||||
|
|
||||||
cat <<EOF > $fyang
|
cat <<EOF > $fyang
|
||||||
module clixon-example{
|
module clixon-example{
|
||||||
|
|
@ -172,6 +191,17 @@ fi
|
||||||
new "wait backend"
|
new "wait backend"
|
||||||
wait_backend
|
wait_backend
|
||||||
|
|
||||||
|
if [ $RC -ne 0 ]; then
|
||||||
|
new "kill old restconf daemon"
|
||||||
|
stop_restconf_pre
|
||||||
|
|
||||||
|
new "start restconf daemon"
|
||||||
|
start_restconf -f $cfg -- -m clixon-mount0 -M urn:example:mount0
|
||||||
|
fi
|
||||||
|
|
||||||
|
new "wait restconf"
|
||||||
|
wait_restconf
|
||||||
|
|
||||||
new "Add two mountpoints: x and y"
|
new "Add two mountpoints: x and y"
|
||||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><top xmlns=\"urn:example:clixon\"><mylist><name>x</name><root/></mylist><mylist><name>y</name><root/></mylist></top></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><top xmlns=\"urn:example:clixon\"><mylist><name>x</name><root/></mylist><mylist><name>y</name><root/></mylist></top></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||||
|
|
||||||
|
|
@ -205,6 +235,14 @@ expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS>
|
||||||
new "cli show config"
|
new "cli show config"
|
||||||
expectpart "$($clixon_cli -1 -f $cfg show config xml -- -m clixon-mount0 -M urn:example:mount0)" 0 "<top xmlns=\"urn:example:clixon\"><mylist><name>x</name><root><mount1 xmlns=\"urn:example:mount1\"><mylist1><name1>x1</name1><options xmlns=\"urn:example:mount2\"><option2>bar</option2></options></mylist1></mount1></root></mylist><mylist><name>y</name><root/></mylist></top>"
|
expectpart "$($clixon_cli -1 -f $cfg show config xml -- -m clixon-mount0 -M urn:example:mount0)" 0 "<top xmlns=\"urn:example:clixon\"><mylist><name>x</name><root><mount1 xmlns=\"urn:example:mount1\"><mylist1><name1>x1</name1><options xmlns=\"urn:example:mount2\"><option2>bar</option2></options></mylist1></mount1></root></mylist><mylist><name>y</name><root/></mylist></top>"
|
||||||
|
|
||||||
|
new "restconf get config mntpoint"
|
||||||
|
expectpart "$(curl $CURLOPTS -X GET -H "Accept: application/yang-data+xml" $RCPROTO://localhost/restconf/data/clixon-example:top/mylist=x/root)" 0 "HTTP/$HVER 200" '<root xmlns="urn:example:clixon"><mount1 xmlns="urn:example:mount1"><mylist1><name1>x1</name1><options xmlns="urn:example:mount2"><option2>bar</option2></options></mylist1></mount1><yang-library xmlns="urn:ietf:params:xml:ns:yang:ietf-yang-library"><module-set><name>mylabel</name><module><name>clixon-mount0</name><namespace>urn:example:mount0</namespace></module></module-set></yang-library></root>'
|
||||||
|
|
||||||
|
if [ $RC -ne 0 ]; then
|
||||||
|
new "Kill restconf daemon"
|
||||||
|
stop_restconf
|
||||||
|
fi
|
||||||
|
|
||||||
if [ $BE -ne 0 ]; then
|
if [ $BE -ne 0 ]; then
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue