* 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:
Olof hagsand 2020-12-01 12:13:46 +01:00
parent 26a4b14060
commit c32950c8a9
20 changed files with 119 additions and 56 deletions

View file

@ -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

View file

@ -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;

View file

@ -1108,7 +1108,10 @@ 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") &&
yang_spec_parse_module(h, "ietf-restconf-monitoring", NULL, yspec)< 0) yang_spec_parse_module(h, "ietf-restconf-monitoring", NULL, yspec)< 0)
@ -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);

View file

@ -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.";

View file

@ -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) {

View file

@ -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),

View file

@ -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_ */

View file

@ -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 */

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
}

View file

@ -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

View file

@ -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>]]>]]>$"

View file

@ -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

View file

@ -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

View file

@ -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&amp;module-set-id=42</capability><capability>urn:ietf:params:netconf:capability:candidate:1.0</capability><capability>urn:ietf:params:netconf:capability:validate:1.1</capability><capability>urn:ietf:params:netconf:capability:startup:1.0</capability><capability>urn:ietf:params:netconf:capability:xpath:1.0</capability><capability>urn:ietf:params:netconf:capability:notification:1.0</capability></capabilities><session-id>[0-9]*</session-id></hello>]]>]]>$" expecteof "$clixon_netconf -f $cfg" 0 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><hello $DEFAULTNS><capabilities><capability>urn:ietf:params:netconf:base:1.0</capability></capabilities></hello>]]>]]>" "^<hello $DEFAULTNS><capabilities><capability>urn:ietf:params:netconf:base:1.0</capability><capability>urn:ietf:params:netconf:capability:yang-library:1.0?revision=2019-01-04&amp;module-set-id=42</capability><capability>urn:ietf:params:netconf:capability:candidate:1.0</capability><capability>urn:ietf:params:netconf:capability:validate:1.1</capability><capability>urn:ietf:params:netconf:capability:startup:1.0</capability><capability>urn:ietf:params:netconf:capability:xpath:1.0</capability><capability>urn:ietf:params:netconf:capability:notification:1.0</capability></capabilities><session-id>[0-9]*</session-id></hello>]]>]]>$"
new "netconf rcv hello, disable RFC7895/ietf-yang-library" 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>"

View file

@ -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"

View file

@ -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"}}}'

View file

@ -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."

View file

@ -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"