* Added message-id attributes in error and hello replies
* See [namespace prefix nc is not supported in full #154](https://github.com/clicon/clixon/issues/154) * Removed mandatory loading of clixon_restconf.yang
This commit is contained in:
parent
26a4b14060
commit
c32950c8a9
20 changed files with 119 additions and 56 deletions
|
|
@ -72,6 +72,8 @@ Developers may need to change their code
|
||||||
|
|
||||||
### Corrected Bugs
|
### Corrected Bugs
|
||||||
|
|
||||||
|
* Added message-id attributes in error and hello replies
|
||||||
|
* See [namespace prefix nc is not supported in full #154](https://github.com/clicon/clixon/issues/154)
|
||||||
* Fixed [Clixon backend generates wrong XML on empty string value #144](https://github.com/clicon/clixon/issues/144)
|
* Fixed [Clixon backend generates wrong XML on empty string value #144](https://github.com/clicon/clixon/issues/144)
|
||||||
|
|
||||||
## 4.8.0
|
## 4.8.0
|
||||||
|
|
|
||||||
|
|
@ -1553,6 +1553,7 @@ from_client_hello(clicon_handle h,
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
|
char *msgid;
|
||||||
|
|
||||||
if (clicon_session_id_get(h, &id) < 0){
|
if (clicon_session_id_get(h, &id) < 0){
|
||||||
clicon_err(OE_NETCONF, ENOENT, "session_id not set");
|
clicon_err(OE_NETCONF, ENOENT, "session_id not set");
|
||||||
|
|
@ -1560,8 +1561,12 @@ from_client_hello(clicon_handle h,
|
||||||
}
|
}
|
||||||
id++;
|
id++;
|
||||||
clicon_session_id_set(h, id);
|
clicon_session_id_set(h, id);
|
||||||
cprintf(cbret, "<hello xmlns=\"%s\"><session-id>%u</session-id></hello>",
|
if ((msgid = xml_find_value(x, "message-id")) != NULL)
|
||||||
NETCONF_BASE_NAMESPACE, id);
|
cprintf(cbret, "<hello xmlns=\"%s\" message-id=\"%s\"><session-id>%u</session-id></hello>",
|
||||||
|
NETCONF_BASE_NAMESPACE, msgid, id);
|
||||||
|
else
|
||||||
|
cprintf(cbret, "<hello xmlns=\"%s\"><session-id>%u</session-id></hello>",
|
||||||
|
NETCONF_BASE_NAMESPACE, id);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
return retval;
|
return retval;
|
||||||
|
|
|
||||||
|
|
@ -1108,6 +1108,9 @@ restconf_config(clicon_handle h,
|
||||||
/* Add netconf yang spec, used as internal protocol */
|
/* Add netconf yang spec, used as internal protocol */
|
||||||
if (netconf_module_load(h) < 0)
|
if (netconf_module_load(h) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
/* Clixon restconf daemon config */
|
||||||
|
if (yang_spec_parse_module(h, "clixon-restconf", NULL, yspec)< 0)
|
||||||
|
goto done;
|
||||||
|
|
||||||
/* Add system modules */
|
/* Add system modules */
|
||||||
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC8040") &&
|
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC8040") &&
|
||||||
|
|
@ -1148,7 +1151,7 @@ restconf_config(clicon_handle h,
|
||||||
sleep(1);
|
sleep(1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// clicon_err(OE_UNIX, errno, "clicon_session_id_get");
|
clicon_err(OE_UNIX, errno, "clicon_session_id_get");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
clicon_session_id_set(h, id);
|
clicon_session_id_set(h, id);
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ module clixon-example {
|
||||||
import ietf-datastores {
|
import ietf-datastores {
|
||||||
prefix ds;
|
prefix ds;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Example interface type for tests, local callbacks, etc */
|
/* Example interface type for tests, local callbacks, etc */
|
||||||
identity eth {
|
identity eth {
|
||||||
base if:interface-type;
|
base if:interface-type;
|
||||||
|
|
@ -90,7 +89,6 @@ module clixon-example {
|
||||||
ex:e4 arg1{
|
ex:e4 arg1{
|
||||||
uses bar;
|
uses bar;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Example notification as used in RFC 5277 and RFC 8040 */
|
/* Example notification as used in RFC 5277 and RFC 8040 */
|
||||||
notification event {
|
notification event {
|
||||||
description "Example notification event.";
|
description "Example notification event.";
|
||||||
|
|
|
||||||
|
|
@ -297,14 +297,21 @@ example_rpc(clicon_handle h, /* Clicon handle */
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
cxobj *x = NULL;
|
cxobj *x = NULL;
|
||||||
|
cxobj *xp;
|
||||||
char *namespace;
|
char *namespace;
|
||||||
|
char *msgid;
|
||||||
|
|
||||||
/* get namespace from rpc name, return back in each output parameter */
|
/* get namespace from rpc name, return back in each output parameter */
|
||||||
if ((namespace = xml_find_type_value(xe, NULL, "xmlns", CX_ATTR)) == NULL){
|
if ((namespace = xml_find_type_value(xe, NULL, "xmlns", CX_ATTR)) == NULL){
|
||||||
clicon_err(OE_XML, ENOENT, "No namespace given in rpc %s", xml_name(xe));
|
clicon_err(OE_XML, ENOENT, "No namespace given in rpc %s", xml_name(xe));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
cprintf(cbret, "<rpc-reply xmlns=\"%s\">", NETCONF_BASE_NAMESPACE);
|
cprintf(cbret, "<rpc-reply xmlns=\"%s\"", NETCONF_BASE_NAMESPACE);
|
||||||
|
if ((xp = xml_parent(xe)) != NULL &&
|
||||||
|
(msgid = xml_find_value(xp, "message-id"))){
|
||||||
|
cprintf(cbret, " message-id=\"%s\">", msgid);
|
||||||
|
}
|
||||||
|
cprintf(cbret, ">");
|
||||||
if (!xml_child_nr_type(xe, CX_ELMNT))
|
if (!xml_child_nr_type(xe, CX_ELMNT))
|
||||||
cprintf(cbret, "<ok/>");
|
cprintf(cbret, "<ok/>");
|
||||||
else while ((x = xml_child_each(xe, x, CX_ELMNT)) != NULL) {
|
else while ((x = xml_child_each(xe, x, CX_ELMNT)) != NULL) {
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ example_client_rpc(clicon_handle h,
|
||||||
cva = cvec_find(cvv, "a"); /* get a cligen variable from vector */
|
cva = cvec_find(cvv, "a"); /* get a cligen variable from vector */
|
||||||
/* Create XML for example netconf RPC */
|
/* Create XML for example netconf RPC */
|
||||||
if (clixon_xml_parse_va(YB_NONE, NULL, &xtop, NULL,
|
if (clixon_xml_parse_va(YB_NONE, NULL, &xtop, NULL,
|
||||||
"<rpc message-id=\"101\" xmlns=\"%s\" username=\"%s\">"
|
"<rpc xmlns=\"%s\" username=\"%s\" message-id=\"101\">"
|
||||||
"<example xmlns=\"urn:example:clixon\"><x>%s</x></example></rpc>",
|
"<example xmlns=\"urn:example:clixon\"><x>%s</x></example></rpc>",
|
||||||
NETCONF_BASE_NAMESPACE,
|
NETCONF_BASE_NAMESPACE,
|
||||||
clicon_username_get(h),
|
clicon_username_get(h),
|
||||||
|
|
|
||||||
|
|
@ -60,5 +60,6 @@ int clixon_xml_parse_va(yang_bind yb, yang_stmt *yspec, cxobj **xt, cxobj **xerr
|
||||||
int clixon_xml_parse_va(yang_bind yb, yang_stmt *yspec, cxobj **xt, cxobj **xerr,
|
int clixon_xml_parse_va(yang_bind yb, yang_stmt *yspec, cxobj **xt, cxobj **xerr,
|
||||||
const char *format, ...);
|
const char *format, ...);
|
||||||
#endif
|
#endif
|
||||||
|
int clixon_xml_attr_copy(cxobj *xin, cxobj *xout, char *name);
|
||||||
|
|
||||||
#endif /* _CLIXON_XML_IO_H_ */
|
#endif /* _CLIXON_XML_IO_H_ */
|
||||||
|
|
|
||||||
|
|
@ -1379,9 +1379,6 @@ netconf_module_load(clicon_handle h)
|
||||||
if (clicon_option_bool(h, "CLICON_XML_CHANGELOG"))
|
if (clicon_option_bool(h, "CLICON_XML_CHANGELOG"))
|
||||||
if (yang_spec_parse_module(h, "clixon-xml-changelog", NULL, yspec)< 0)
|
if (yang_spec_parse_module(h, "clixon-xml-changelog", NULL, yspec)< 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* Clixon restconf daemon */
|
|
||||||
if (yang_spec_parse_module(h, "clixon-restconf", NULL, yspec)< 0)
|
|
||||||
goto done;
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
return retval;
|
return retval;
|
||||||
|
|
@ -1538,7 +1535,7 @@ netconf_hello_server(clicon_handle h,
|
||||||
|
|
||||||
module_set_id = clicon_option_str(h, "CLICON_MODULE_SET_ID");
|
module_set_id = clicon_option_str(h, "CLICON_MODULE_SET_ID");
|
||||||
|
|
||||||
cprintf(cb, "<hello xmlns=\"%s\">", NETCONF_BASE_NAMESPACE);
|
cprintf(cb, "<hello xmlns=\"%s\" message-id=\"%u\">", NETCONF_BASE_NAMESPACE, 42);
|
||||||
cprintf(cb, "<capabilities>");
|
cprintf(cb, "<capabilities>");
|
||||||
cprintf(cb, "<capability>urn:ietf:params:netconf:base:1.0</capability>");
|
cprintf(cb, "<capability>urn:ietf:params:netconf:base:1.0</capability>");
|
||||||
/* Check if RFC7895 loaded and revision found */
|
/* Check if RFC7895 loaded and revision found */
|
||||||
|
|
|
||||||
|
|
@ -790,8 +790,8 @@ clicon_rpc_close_session(clicon_handle h)
|
||||||
goto done;
|
goto done;
|
||||||
username = clicon_username_get(h);
|
username = clicon_username_get(h);
|
||||||
if ((msg = clicon_msg_encode(session_id,
|
if ((msg = clicon_msg_encode(session_id,
|
||||||
"<rpc xmlns=\"%s\" username=\"%s\"><close-session/></rpc>",
|
"<rpc xmlns=\"%s\" username=\"%s\" message-id=\"%u\"><close-session/></rpc>",
|
||||||
NETCONF_BASE_NAMESPACE, username?username:"")) == NULL)
|
NETCONF_BASE_NAMESPACE, username?username:"", 42)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -1084,7 +1084,7 @@ clicon_hello_req(clicon_handle h,
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
username = clicon_username_get(h);
|
username = clicon_username_get(h);
|
||||||
if ((msg = clicon_msg_encode(0, "<hello username=\"%s\" xmlns=\"%s\"><capabilities><capability>urn:ietf:params:netconf:base:1.0</capability></capabilities></hello>",
|
if ((msg = clicon_msg_encode(0, "<hello username=\"%s\" xmlns=\"%s\" message-id=\"42\"><capabilities><capability>urn:ietf:params:netconf:base:1.0</capability></capabilities></hello>",
|
||||||
username?username:"",
|
username?username:"",
|
||||||
NETCONF_BASE_NAMESPACE)) == NULL)
|
NETCONF_BASE_NAMESPACE)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -1111,5 +1111,3 @@ clicon_hello_req(clicon_handle h,
|
||||||
xml_free(xret);
|
xml_free(xret);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@
|
||||||
#include "clixon_netconf_lib.h"
|
#include "clixon_netconf_lib.h"
|
||||||
#include "clixon_options.h"
|
#include "clixon_options.h"
|
||||||
#include "clixon_xml_nsctx.h"
|
#include "clixon_xml_nsctx.h"
|
||||||
|
#include "clixon_xml_io.h"
|
||||||
#include "clixon_xpath_ctx.h"
|
#include "clixon_xpath_ctx.h"
|
||||||
#include "clixon_xpath.h"
|
#include "clixon_xpath.h"
|
||||||
#include "clixon_yang_module.h"
|
#include "clixon_yang_module.h"
|
||||||
|
|
@ -332,6 +333,7 @@ xml_yang_validate_rpc(clicon_handle h,
|
||||||
cxobj *xn; /* rpc name */
|
cxobj *xn; /* rpc name */
|
||||||
char *rpcprefix;
|
char *rpcprefix;
|
||||||
char *namespace = NULL;
|
char *namespace = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (strcmp(xml_name(xrpc), "rpc")){
|
if (strcmp(xml_name(xrpc), "rpc")){
|
||||||
clicon_err(OE_XML, EINVAL, "Expected RPC");
|
clicon_err(OE_XML, EINVAL, "Expected RPC");
|
||||||
|
|
@ -357,10 +359,14 @@ xml_yang_validate_rpc(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if ((retval = xml_yang_validate_all(h, xn, xret)) < 1)
|
if ((ret = xml_yang_validate_all(h, xn, xret)) < 0)
|
||||||
goto done; /* error or validation fail */
|
goto done; /* error or validation fail */
|
||||||
if ((retval = xml_yang_validate_add(h, xn, xret)) < 1)
|
if (ret == 0)
|
||||||
|
goto fail;
|
||||||
|
if ((ret = xml_yang_validate_add(h, xn, xret)) < 0)
|
||||||
goto done; /* error or validation fail */
|
goto done; /* error or validation fail */
|
||||||
|
if (ret == 0)
|
||||||
|
goto fail;
|
||||||
if (xml_default_recurse(xn, 0) < 0)
|
if (xml_default_recurse(xn, 0) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
@ -369,6 +375,8 @@ xml_yang_validate_rpc(clicon_handle h,
|
||||||
done:
|
done:
|
||||||
return retval;
|
return retval;
|
||||||
fail:
|
fail:
|
||||||
|
if (xret && *xret && clixon_xml_attr_copy(xrpc, *xret, "message-id") < 0)
|
||||||
|
goto done;
|
||||||
retval = 0;
|
retval = 0;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -526,8 +526,11 @@ _xml_parse(const char *str,
|
||||||
case YB_RPC:
|
case YB_RPC:
|
||||||
if ((ret = xml_bind_yang_rpc(x, yspec, xerr)) < 0)
|
if ((ret = xml_bind_yang_rpc(x, yspec, xerr)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0){ /* Add message-id */
|
||||||
|
if (*xerr && clixon_xml_attr_copy(x, *xerr, "message-id") < 0)
|
||||||
|
goto done;
|
||||||
failed++;
|
failed++;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
} /* switch */
|
} /* switch */
|
||||||
}
|
}
|
||||||
|
|
@ -769,3 +772,38 @@ clixon_xml_parse_va(yang_bind yb,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Copy an attribute value(eg message-id) from one xml (eg rpc input) to another xml (eg rpc outgoing)
|
||||||
|
* @param[in] xin Get attr value from this XML
|
||||||
|
* @param[in] xout Set attr value to this XML
|
||||||
|
* @param[in] name Attribute name
|
||||||
|
* @retval 0 OK
|
||||||
|
* @retval -1 Error
|
||||||
|
* Alternative is to use: char *val = xml_find_value(x, name);
|
||||||
|
* @code
|
||||||
|
* if (clixon_xml_attr_copy(xin, xout, "message-id") < 0)
|
||||||
|
* err;
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
clixon_xml_attr_copy(cxobj *xin,
|
||||||
|
cxobj *xout,
|
||||||
|
char *name)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
char *msgid;
|
||||||
|
cxobj *xa;
|
||||||
|
|
||||||
|
if (xin == NULL || xout == NULL){
|
||||||
|
clicon_err(OE_XML, EINVAL, "xin or xout NULL");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if ((msgid = xml_find_value(xin, "message-id")) != NULL){
|
||||||
|
if ((xa = xml_new("message-id", xout, CX_ATTR)) == NULL)
|
||||||
|
goto done;
|
||||||
|
if (xml_value_set(xa, msgid) < 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,9 @@ testname=
|
||||||
: ${RCLOG:=}
|
: ${RCLOG:=}
|
||||||
|
|
||||||
# Default netconf namespace statement, typically as placed on top-level <rpc xmlns=""
|
# Default netconf namespace statement, typically as placed on top-level <rpc xmlns=""
|
||||||
DEFAULTNS='xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"'
|
DEFAULTONLY='xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"'
|
||||||
|
# Default netconf namespace + message-id
|
||||||
|
DEFAULTNS="$DEFAULTONLY message-id=\"42\""
|
||||||
|
|
||||||
# Options passed to curl calls
|
# Options passed to curl calls
|
||||||
# -s : silent
|
# -s : silent
|
||||||
|
|
@ -164,7 +166,6 @@ fi
|
||||||
# This check is optional because some installs, such as vagrant make a non-systemd/direct
|
# This check is optional because some installs, such as vagrant make a non-systemd/direct
|
||||||
# start
|
# start
|
||||||
: ${NGINXCHECK:=false}
|
: ${NGINXCHECK:=false}
|
||||||
|
|
||||||
# Sanity nginx running on systemd platforms
|
# Sanity nginx running on systemd platforms
|
||||||
if $NGINXCHECK; then
|
if $NGINXCHECK; then
|
||||||
if systemctl > /dev/null 2>&1 ; then
|
if systemctl > /dev/null 2>&1 ; then
|
||||||
|
|
@ -295,7 +296,7 @@ wait_backend(){
|
||||||
reply=$(echo '<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101" xmlns="http://clicon.org/lib"><ping/></rpc>]]>]]>' | clixon_netconf -qef $cfg 2> /dev/null)
|
reply=$(echo '<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101" xmlns="http://clicon.org/lib"><ping/></rpc>]]>]]>' | clixon_netconf -qef $cfg 2> /dev/null)
|
||||||
echo "reply:$reply"
|
echo "reply:$reply"
|
||||||
let i++;
|
let i++;
|
||||||
echo "wait_backend $i"
|
# echo "wait_backend $i"
|
||||||
if [ $i -ge $DEMLOOP ]; then
|
if [ $i -ge $DEMLOOP ]; then
|
||||||
err "backend timeout $DEMWAIT seconds"
|
err "backend timeout $DEMWAIT seconds"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,7 @@ new "netconf commit protocol tcp"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><commit/></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><commit/></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf changing from TCP to UDP (RFC7950 7.9.6)"
|
new "netconf changing from TCP to UDP (RFC7950 7.9.6)"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS message-id=\"101\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><edit-config><target><candidate/></target><config><system xmlns=\"urn:example:config\"><protocol><udp nc:operation=\"create\"/></protocol></system></config></edit-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS message-id=\"101\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><edit-config><target><candidate/></target><config><system xmlns=\"urn:example:config\"><protocol><udp nc:operation=\"create\"/></protocol></system></config></edit-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get protocol udp"
|
new "netconf get protocol udp"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data><system xmlns=\"urn:example:config\"><protocol><udp/></protocol></system>"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data><system xmlns=\"urn:example:config\"><protocol><udp/></protocol></system>"
|
||||||
|
|
@ -216,7 +216,7 @@ new "netconf set shorthand tcp"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><system xmlns=\"urn:example:config\"><shorthand><tcp/></shorthand></system></config></edit-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><system xmlns=\"urn:example:config\"><shorthand><tcp/></shorthand></system></config></edit-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf changing from TCP to UDP (RFC7950 7.9.6)"
|
new "netconf changing from TCP to UDP (RFC7950 7.9.6)"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS message-id=\"101\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><edit-config><target><candidate/></target><config><system xmlns=\"urn:example:config\"><shorthand><udp/></shorthand></system></config></edit-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS message-id=\"101\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><edit-config><target><candidate/></target><config><system xmlns=\"urn:example:config\"><shorthand><udp/></shorthand></system></config></edit-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get shorthand udp"
|
new "netconf get shorthand udp"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data><system xmlns=\"urn:example:config\"><shorthand><udp/></shorthand></system></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data><system xmlns=\"urn:example:config\"><shorthand><udp/></shorthand></system></data></rpc-reply>]]>]]>$"
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,8 @@ new "cli debug reset"
|
||||||
expectfn "$clixon_cli -1 -f $cfg -l o debug level 0" 0 "^$"
|
expectfn "$clixon_cli -1 -f $cfg -l o debug level 0" 0 "^$"
|
||||||
|
|
||||||
new "cli rpc"
|
new "cli rpc"
|
||||||
expectpart "$($clixon_cli -1 -f $cfg -l o rpc ipv4)" 0 "<rpc-reply $DEFAULTNS><x xmlns=\"urn:example:clixon\">ipv4</x><y xmlns=\"urn:example:clixon\">42</y></rpc-reply>"
|
# We dont know which message-id the cli app uses
|
||||||
|
expectpart "$($clixon_cli -1 -f $cfg -l o rpc ipv4)" 0 "<rpc-reply $DEFAULTONLY message-id=" "><x xmlns=\"urn:example:clixon\">ipv4</x><y xmlns=\"urn:example:clixon\">42</y></rpc-reply>"
|
||||||
|
|
||||||
if [ $BE -eq 0 ]; then
|
if [ $BE -eq 0 ]; then
|
||||||
exit # BE
|
exit # BE
|
||||||
|
|
|
||||||
|
|
@ -88,10 +88,10 @@ expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><edit-config><target><ca
|
||||||
# Here startup and candidate are empty, only running has content
|
# Here startup and candidate are empty, only running has content
|
||||||
# test running->startup and running->candidate
|
# test running->startup and running->candidate
|
||||||
new "Check candidate empty"
|
new "Check candidate empty"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS message-id=\"101\"><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS message-id=\"101\"><data/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Check startup empty"
|
new "Check startup empty"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS message-id=\"101\"><get-config><source><startup/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS message-id=\"101\"><data/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><get-config><source><startup/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "copy running->startup"
|
new "copy running->startup"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><copy-config><target><startup/></target><source><running/></source></copy-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><copy-config><target><startup/></target><source><running/></source></copy-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
@ -101,10 +101,10 @@ expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><copy-config><target><ca
|
||||||
|
|
||||||
# Here startup and candidate have content
|
# Here startup and candidate have content
|
||||||
new "Check candidate content"
|
new "Check candidate content"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS message-id=\"101\"><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS message-id=\"101\"><data><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth/0/0</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth/0/0</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Check startup content"
|
new "Check startup content"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS message-id=\"101\"><get-config><source><startup/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS message-id=\"101\"><data><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth/0/0</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><get-config><source><startup/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth/0/0</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Delete startup"
|
new "Delete startup"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><delete-config><target><startup/></target></delete-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><delete-config><target><startup/></target></delete-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
@ -112,13 +112,13 @@ expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><delete-config><target><
|
||||||
# Here startup is empty and candidate has content
|
# Here startup is empty and candidate has content
|
||||||
# test candidate->startup
|
# test candidate->startup
|
||||||
new "Check startup empty"
|
new "Check startup empty"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS message-id=\"101\"><get-config><source><startup/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS message-id=\"101\"><data/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><get-config><source><startup/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "copy candidate->startup"
|
new "copy candidate->startup"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><copy-config><target><startup/></target><source><candidate/></source></copy-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><copy-config><target><startup/></target><source><candidate/></source></copy-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Check startup content"
|
new "Check startup content"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS message-id=\"101\"><get-config><source><startup/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS message-id=\"101\"><data><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth/0/0</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><get-config><source><startup/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth/0/0</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Delete candidate"
|
new "Delete candidate"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><interface nc:operation=\"delete\"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><interface nc:operation=\"delete\"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
@ -126,13 +126,13 @@ expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><edit-config><target><ca
|
||||||
# Here candidate is empty and startup has content
|
# Here candidate is empty and startup has content
|
||||||
# test startup->candidate
|
# test startup->candidate
|
||||||
new "Check candidate empty"
|
new "Check candidate empty"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS message-id=\"101\"><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS message-id=\"101\"><data/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "copy startup->candidate"
|
new "copy startup->candidate"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><copy-config><target><candidate/></target><source><startup/></source></copy-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><copy-config><target><candidate/></target><source><startup/></source></copy-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Check candidate content"
|
new "Check candidate content"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS message-id=\"101\"><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS message-id=\"101\"><data><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth/0/0</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth/0/0</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
# Negative test: check copying to running is not allowed
|
# Negative test: check copying to running is not allowed
|
||||||
new "Delete candidate"
|
new "Delete candidate"
|
||||||
|
|
@ -143,7 +143,7 @@ expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><commit/></rpc>]]>]]>" "
|
||||||
|
|
||||||
# Here running is empty
|
# Here running is empty
|
||||||
new "Check running empty"
|
new "Check running empty"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS message-id=\"101\"><get-config><source><running/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS message-id=\"101\"><data/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><get-config><source><running/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
# Add to candidate
|
# Add to candidate
|
||||||
new "copy startup->candidate"
|
new "copy startup->candidate"
|
||||||
|
|
@ -156,7 +156,7 @@ fi
|
||||||
|
|
||||||
# Here running is empty
|
# Here running is empty
|
||||||
new "Check running empty"
|
new "Check running empty"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS message-id=\"101\"><get-config><source><running/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS message-id=\"101\"><data/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><get-config><source><running/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
if [ $BE -eq 0 ]; then
|
if [ $BE -eq 0 ]; then
|
||||||
exit # BE
|
exit # BE
|
||||||
|
|
|
||||||
|
|
@ -59,10 +59,10 @@ expecteof "$clixon_netconf -qf $cfg" 0 "This is not XML]]>]]>" '<rpc-reply xmlns
|
||||||
fi
|
fi
|
||||||
|
|
||||||
new "Frame with two messages"
|
new "Frame with two messages"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<hello $DEFAULTNS><capabilities><capability>urn:ietf:params:netconf:base:1.0</capability></capabilities></hello><rpc $DEFAULTNS message-id=\"101\"><get-config><source><candidate/></source></get-config></rpc>]]>]]>" '<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><rpc-error><error-type>rpc</error-type><error-tag>malformed-message</error-tag><error-severity>error</error-severity><error-message>More than one message in netconf rpc frame</error-message></rpc-error></rpc-reply>]]>]]>'
|
expecteof "$clixon_netconf -qf $cfg" 0 "<hello $DEFAULTNS><capabilities><capability>urn:ietf:params:netconf:base:1.0</capability></capabilities></hello><rpc $DEFAULTNS><get-config><source><candidate/></source></get-config></rpc>]]>]]>" '<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><rpc-error><error-type>rpc</error-type><error-tag>malformed-message</error-tag><error-severity>error</error-severity><error-message>More than one message in netconf rpc frame</error-message></rpc-error></rpc-reply>]]>]]>'
|
||||||
|
|
||||||
new "Frame with unknown message"
|
new "Frame with unknown message"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<xxx $DEFAULTNS></xxx>]]>]]>" '^<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><rpc-error><error-type>protocol</error-type><error-tag>unknown-element</error-tag><error-info><bad-element>xxx</bad-element></error-info><error-severity>error</error-severity><error-message>Unrecognized netconf operation</error-message></rpc-error></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 "<xxx $DEFAULTNS></xxx>]]>]]>" "^<rpc-reply $DEFAULTNS><rpc-error><error-type>protocol</error-type><error-tag>unknown-element</error-tag><error-info><bad-element>xxx</bad-element></error-info><error-severity>error</error-severity><error-message>Unrecognized netconf operation</error-message></rpc-error></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
# Hello
|
# Hello
|
||||||
new "Netconf snd hello with xmldecl"
|
new "Netconf snd hello with xmldecl"
|
||||||
|
|
@ -78,22 +78,22 @@ 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=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>]]>]]>$"
|
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><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><data/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get-config prefix"
|
new "netconf get-config prefix"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<nc:rpc xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"101\"><nc:get-config><nc:source><nc:candidate/></nc:source></nc:get-config></nc:rpc>]]>]]>" "^<rpc-reply $DEFAULTNS xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"101\"><data/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<nc:rpc xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:message-id=\"42\"><nc:get-config><nc:source><nc:candidate/></nc:source></nc:get-config></nc:rpc>]]>]]>" "^<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:message-id=\"42\"><data/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get-config double quotes"
|
new "netconf get-config double quotes"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS message-id=\"101\"><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS message-id=\"101\"><data/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get-config single quotes"
|
new "netconf get-config single quotes"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS message-id='101'><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS message-id=\"101\"><data/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Add subtree eth/0/0 using none which should not change anything"
|
new "Add subtree eth/0/0 using none which should not change anything"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><edit-config><default-operation>none</default-operation><target><candidate/></target><config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth/0/0</name></interface></interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><edit-config><default-operation>none</default-operation><target><candidate/></target><config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth/0/0</name></interface></interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Check nothing added"
|
new "Check nothing added"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS message-id=\"101\"><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS message-id=\"101\"><data/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Add subtree eth/0/0 using none and create which should add eth/0/0"
|
new "Add subtree eth/0/0 using none and create which should add eth/0/0"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><interface nc:operation=\"create\"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><interface nc:operation=\"create\"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
@ -113,7 +113,7 @@ new "Delete eth/0/0 using none config"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><interface nc:operation=\"delete\"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><interface nc:operation=\"delete\"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Check deleted eth/0/0 (non-presence container)"
|
new "Check deleted eth/0/0 (non-presence container)"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS message-id=\"101\"><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS message-id=\"101\"><data/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "Re-Delete eth/0/0 using none should generate error"
|
new "Re-Delete eth/0/0 using none should generate error"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><interface nc:operation=\"delete\"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><rpc-error>"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><interface nc:operation=\"delete\"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><rpc-error>"
|
||||||
|
|
|
||||||
|
|
@ -22,12 +22,16 @@ APPNAME=example
|
||||||
|
|
||||||
cfg=$dir/conf.xml
|
cfg=$dir/conf.xml
|
||||||
|
|
||||||
|
# clixon-example and clixon-restconf is used, copy here
|
||||||
|
cp ../example/main/clixon-example@2020-03-11.yang $dir/
|
||||||
|
cp ../yang/clixon/clixon-restconf@2020-10-30.yang $dir/
|
||||||
|
|
||||||
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_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
|
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
|
||||||
<CLICON_YANG_DIR>$IETFRFC</CLICON_YANG_DIR>
|
<CLICON_YANG_DIR>$IETFRFC</CLICON_YANG_DIR>
|
||||||
<CLICON_YANG_MODULE_MAIN>clixon-example</CLICON_YANG_MODULE_MAIN>
|
<CLICON_YANG_MAIN_DIR>$dir</CLICON_YANG_MAIN_DIR>
|
||||||
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
|
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
|
||||||
<CLICON_BACKEND_DIR>/usr/local/lib/$APPNAME/backend</CLICON_BACKEND_DIR>
|
<CLICON_BACKEND_DIR>/usr/local/lib/$APPNAME/backend</CLICON_BACKEND_DIR>
|
||||||
<CLICON_BACKEND_REGEXP>example_backend.so$</CLICON_BACKEND_REGEXP>
|
<CLICON_BACKEND_REGEXP>example_backend.so$</CLICON_BACKEND_REGEXP>
|
||||||
|
|
@ -136,19 +140,19 @@ testrun()
|
||||||
expectpart "$(curl $CURLOPTS -X GET $proto://$addr/.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 $proto://$addr/.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" $proto://$addr/restconf)" 0 'HTTP/1.1 200 OK' '{"ietf-restconf:restconf":{"data":{},"operations":{},"yang-library-version":"2019-01-04"}}'
|
expectpart "$(curl $CURLOPTS -X GET -H "Accept: application/yang-data+json" $proto://$addr/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' $proto://$addr/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>'
|
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: application/yang-data+xml' $proto://$addr/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)"
|
||||||
expectpart "$(curl $CURLOPTS -X GET $proto://$addr/restconf/operations)" 0 'HTTP/1.1 200 OK' '{"operations":{"clixon-example:client-rpc":\[null\],"clixon-example:empty":\[null\],"clixon-example:optional":\[null\],"clixon-example:example":\[null\],"clixon-lib:debug":\[null\],"clixon-lib:ping":\[null\],"clixon-lib:stats":\[null\],"clixon-lib:restart-plugin":\[null\],"ietf-netconf:get-config":\[null\],"ietf-netconf:edit-config":\[null\],"ietf-netconf:copy-config":\[null\],"ietf-netconf:delete-config":\[null\],"ietf-netconf:lock":\[null\],"ietf-netconf:unlock":\[null\],"ietf-netconf:get":\[null\],"ietf-netconf:close-session":\[null\],"ietf-netconf:kill-session":\[null\],"ietf-netconf:commit":\[null\],"ietf-netconf:discard-changes":\[null\],"ietf-netconf:validate":\[null\]'
|
expectpart "$(curl $CURLOPTS -X GET $proto://$addr/restconf/operations)" 0 'HTTP/1.1 200 OK' '{"operations":{"clixon-example:client-rpc":\[null\],"clixon-example:empty":\[null\],"clixon-example:optional":\[null\],"clixon-example:example":\[null\]' '"clixon-lib:debug":\[null\],"clixon-lib:ping":\[null\],"clixon-lib:stats":\[null\],"clixon-lib:restart-plugin":\[null\],"ietf-netconf:get-config":\[null\],"ietf-netconf:edit-config":\[null\],"ietf-netconf:copy-config":\[null\],"ietf-netconf:delete-config":\[null\],"ietf-netconf:lock":\[null\],"ietf-netconf:unlock":\[null\],"ietf-netconf:get":\[null\],"ietf-netconf:close-session":\[null\],"ietf-netconf:kill-session":\[null\],"ietf-netconf:commit":\[null\],"ietf-netconf:discard-changes":\[null\],"ietf-netconf:validate":\[null\]'
|
||||||
|
|
||||||
new "restconf get restconf/operations. RFC8040 3.3.2 (xml)"
|
new "restconf get restconf/operations. RFC8040 3.3.2 (xml)"
|
||||||
ret=$(curl $CURLOPTS -X GET -H "Accept: application/yang-data+xml" $proto://$addr/restconf/operations)
|
ret=$(curl $CURLOPTS -X GET -H "Accept: application/yang-data+xml" $proto://$addr/restconf/operations)
|
||||||
expect='<operations><client-rpc xmlns="urn:example:clixon"/><empty xmlns="urn:example:clixon"/><optional xmlns="urn:example:clixon"/><example xmlns="urn:example:clixon"/><debug xmlns="http://clicon.org/lib"/><ping xmlns="http://clicon.org/lib"/><stats xmlns="http://clicon.org/lib"/><restart-plugin xmlns="http://clicon.org/lib"/><get-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"/><edit-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"/><copy-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"/><delete-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"/><lock xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"/><unlock xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"/><get xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"/><close-session xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"/><kill-session xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"/><commit xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"/><discard-changes xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"/><validate xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"/>'
|
expect='<operations><client-rpc xmlns="urn:example:clixon"/><empty xmlns="urn:example:clixon"/><optional xmlns="urn:example:clixon"/><example xmlns="urn:example:clixon"/>'
|
||||||
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"
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,7 @@ expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><edit-config xmlns=\"urn
|
||||||
|
|
||||||
# Negative errors (namespace/module missing)
|
# Negative errors (namespace/module missing)
|
||||||
new "netconf wrong rpc namespace: should fail"
|
new "netconf wrong rpc namespace: should fail"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc xmlns=\"urn:example:xxx\"><get/></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><rpc-error><error-type>application</error-type><error-tag>unknown-element</error-tag><error-info><bad-element>get</bad-element></error-info><error-severity>error</error-severity><error-message>Unrecognized RPC (wrong namespace?)</error-message></rpc-error></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc xmlns=\"urn:example:xxx\" message-id=\"42\"><get/></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><rpc-error><error-type>application</error-type><error-tag>unknown-element</error-tag><error-info><bad-element>get</bad-element></error-info><error-severity>error</error-severity><error-message>Unrecognized RPC (wrong namespace?)</error-message></rpc-error></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "restconf wrong rpc: should fail"
|
new "restconf wrong rpc: should fail"
|
||||||
expectpart "$(curl $CURLOPTS -X POST -H "Content-Type: application/yang-data+json" u $RCPROTO://localhost/restconf/operations/clixon-foo:get)" 0 'HTTP/1.1 412 Precondition Failed' '{"ietf-restconf:errors":{"error":{"error-type":"protocol","error-tag":"operation-failed","error-severity":"error","error-message":"yang module not found"}}}'
|
expectpart "$(curl $CURLOPTS -X POST -H "Content-Type: application/yang-data+json" u $RCPROTO://localhost/restconf/operations/clixon-foo:get)" 0 'HTTP/1.1 412 Precondition Failed' '{"ietf-restconf:errors":{"error":{"error-type":"protocol","error-tag":"operation-failed","error-severity":"error","error-message":"yang module not found"}}}'
|
||||||
|
|
|
||||||
|
|
@ -55,10 +55,10 @@ EOF
|
||||||
fi
|
fi
|
||||||
new "start backend -s init -f $cfg"
|
new "start backend -s init -f $cfg"
|
||||||
start_backend -s init -f $cfg
|
start_backend -s init -f $cfg
|
||||||
fi
|
|
||||||
|
|
||||||
new "waiting"
|
new "wait backend"
|
||||||
wait_backend
|
wait_backend
|
||||||
|
fi
|
||||||
|
|
||||||
new "$clixon_cli -1f $cfg show version"
|
new "$clixon_cli -1f $cfg show version"
|
||||||
expectfn "$clixon_cli -1f $cfg show version" 0 "$version."
|
expectfn "$clixon_cli -1f $cfg show version" 0 "$version."
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ testrun(){
|
||||||
fi
|
fi
|
||||||
|
|
||||||
new "check running defaults"
|
new "check running defaults"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS message-id=\"101\"><get-config><source><running/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS message-id=\"101\"><data><a xmlns=\"urn:example:default\"><b><c>0</c><d1>foo</d1><d2>42</d2></b></a></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><get-config><source><running/></source></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data><a xmlns=\"urn:example:default\"><b><c>0</c><d1>foo</d1><d2>42</d2></b></a></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
if [ $BE -ne 0 ]; then # Bring your own backend
|
if [ $BE -ne 0 ]; then # Bring your own backend
|
||||||
new "Kill backend"
|
new "Kill backend"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue