Netconf operation attribute namespace check is enforced

This commit is contained in:
Olof hagsand 2019-07-31 16:45:48 +02:00
parent 2d9d204f69
commit c97346921b
19 changed files with 86 additions and 73 deletions

View file

@ -1377,46 +1377,46 @@ backend_rpc_init(clicon_handle h)
/* In backend_client.? RFC 6241 */ /* In backend_client.? RFC 6241 */
if (rpc_callback_register(h, from_client_get_config, NULL, if (rpc_callback_register(h, from_client_get_config, NULL,
"urn:ietf:params:xml:ns:netconf:base:1.0", "get-config") < 0) NETCONF_BASE_NAMESPACE, "get-config") < 0)
goto done; goto done;
if (rpc_callback_register(h, from_client_edit_config, NULL, if (rpc_callback_register(h, from_client_edit_config, NULL,
"urn:ietf:params:xml:ns:netconf:base:1.0", "edit-config") < 0) NETCONF_BASE_NAMESPACE, "edit-config") < 0)
goto done; goto done;
if (rpc_callback_register(h, from_client_copy_config, NULL, if (rpc_callback_register(h, from_client_copy_config, NULL,
"urn:ietf:params:xml:ns:netconf:base:1.0", "copy-config") < 0) NETCONF_BASE_NAMESPACE, "copy-config") < 0)
goto done; goto done;
if (rpc_callback_register(h, from_client_delete_config, NULL, if (rpc_callback_register(h, from_client_delete_config, NULL,
"urn:ietf:params:xml:ns:netconf:base:1.0", "delete-config") < 0) NETCONF_BASE_NAMESPACE, "delete-config") < 0)
goto done; goto done;
if (rpc_callback_register(h, from_client_lock, NULL, if (rpc_callback_register(h, from_client_lock, NULL,
"urn:ietf:params:xml:ns:netconf:base:1.0", "lock") < 0) NETCONF_BASE_NAMESPACE, "lock") < 0)
goto done; goto done;
if (rpc_callback_register(h, from_client_unlock, NULL, if (rpc_callback_register(h, from_client_unlock, NULL,
"urn:ietf:params:xml:ns:netconf:base:1.0", "unlock") < 0) NETCONF_BASE_NAMESPACE, "unlock") < 0)
goto done; goto done;
if (rpc_callback_register(h, from_client_get, NULL, if (rpc_callback_register(h, from_client_get, NULL,
"urn:ietf:params:xml:ns:netconf:base:1.0", "get") < 0) NETCONF_BASE_NAMESPACE, "get") < 0)
goto done; goto done;
if (rpc_callback_register(h, from_client_close_session, NULL, if (rpc_callback_register(h, from_client_close_session, NULL,
"urn:ietf:params:xml:ns:netconf:base:1.0", "close-session") < 0) NETCONF_BASE_NAMESPACE, "close-session") < 0)
goto done; goto done;
if (rpc_callback_register(h, from_client_kill_session, NULL, if (rpc_callback_register(h, from_client_kill_session, NULL,
"urn:ietf:params:xml:ns:netconf:base:1.0", "kill-session") < 0) NETCONF_BASE_NAMESPACE, "kill-session") < 0)
goto done; goto done;
/* In backend_commit.? */ /* In backend_commit.? */
if (rpc_callback_register(h, from_client_commit, NULL, if (rpc_callback_register(h, from_client_commit, NULL,
"urn:ietf:params:xml:ns:netconf:base:1.0", "commit") < 0) NETCONF_BASE_NAMESPACE, "commit") < 0)
goto done; goto done;
if (rpc_callback_register(h, from_client_discard_changes, NULL, if (rpc_callback_register(h, from_client_discard_changes, NULL,
"urn:ietf:params:xml:ns:netconf:base:1.0", "discard-changes") < 0) NETCONF_BASE_NAMESPACE, "discard-changes") < 0)
goto done; goto done;
/* if-feature confirmed-commit */ /* if-feature confirmed-commit */
if (rpc_callback_register(h, from_client_cancel_commit, NULL, if (rpc_callback_register(h, from_client_cancel_commit, NULL,
"urn:ietf:params:xml:ns:netconf:base:1.0", "cancel-commit") < 0) NETCONF_BASE_NAMESPACE, "cancel-commit") < 0)
goto done; goto done;
/* if-feature validate */ /* if-feature validate */
if (rpc_callback_register(h, from_client_validate, NULL, if (rpc_callback_register(h, from_client_validate, NULL,
"urn:ietf:params:xml:ns:netconf:base:1.0", "validate") < 0) NETCONF_BASE_NAMESPACE, "validate") < 0)
goto done; goto done;
/* In backend_client.? RPC from RFC 5277 */ /* In backend_client.? RPC from RFC 5277 */

View file

@ -236,19 +236,15 @@ cli_dbxml(clicon_handle h,
enum operation_type op) enum operation_type op)
{ {
int retval = -1; int retval = -1;
// char *str = NULL; char *api_path_fmt; /* xml key format */
char *api_path_fmt; /* xml key format */
char *api_path = NULL; /* xml key */ char *api_path = NULL; /* xml key */
// cg_var *cval;
// int len;
cg_var *arg; cg_var *arg;
cbuf *cb = NULL; cbuf *cb = NULL;
yang_stmt *yspec; yang_stmt *yspec;
cxobj *xbot = NULL; /* xpath, NULL if datastore */ cxobj *xbot = NULL; /* xpath, NULL if datastore */
yang_stmt *y = NULL; /* yang spec of xpath */ yang_stmt *y = NULL; /* yang spec of xpath */
cxobj *xtop = NULL; /* xpath root */ cxobj *xtop = NULL; /* xpath root */
cxobj *xa; /* attribute */ cxobj *xa; /* attribute */
// cxobj *xb; /* body */
if (cvec_len(argv) != 1){ if (cvec_len(argv) != 1){
clicon_err(OE_PLUGIN, 0, "Requires one element to be xml key format string"); clicon_err(OE_PLUGIN, 0, "Requires one element to be xml key format string");
@ -271,6 +267,7 @@ cli_dbxml(clicon_handle h,
if ((xa = xml_new("operation", xbot, NULL)) == NULL) if ((xa = xml_new("operation", xbot, NULL)) == NULL)
goto done; goto done;
xml_type_set(xa, CX_ATTR); xml_type_set(xa, CX_ATTR);
xml_prefix_set(xa, NETCONF_BASE_PREFIX);
if (xml_value_set(xa, xml_operation2str(op)) < 0) if (xml_value_set(xa, xml_operation2str(op)) < 0)
goto done; goto done;
if (yang_keyword_get(y) != Y_LIST && yang_keyword_get(y) != Y_LEAF_LIST){ if (yang_keyword_get(y) != Y_LIST && yang_keyword_get(y) != Y_LEAF_LIST){

View file

@ -161,7 +161,7 @@ netconf_create_hello(clicon_handle h,
if ((ietf_yang_library_revision = yang_modules_revision(h)) == NULL) if ((ietf_yang_library_revision = yang_modules_revision(h)) == NULL)
goto done; goto done;
add_preamble(cb); add_preamble(cb);
cprintf(cb, "<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"); cprintf(cb, "<hello xmlns=\"%s\">", NETCONF_BASE_NAMESPACE);
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>");
if (xml_chardata_encode(&encstr, "urn:ietf:params:netconf:capability:yang-library:1.0?revision=%s&module-set-id=%s", if (xml_chardata_encode(&encstr, "urn:ietf:params:netconf:capability:yang-library:1.0?revision=%s&module-set-id=%s",

View file

@ -579,7 +579,7 @@ restconf_insert_attributes(cxobj *xdata,
if (xml_prefix_set(xa, "xmlns") < 0) if (xml_prefix_set(xa, "xmlns") < 0)
goto done; goto done;
xml_type_set(xa, CX_ATTR); xml_type_set(xa, CX_ATTR);
if (xml_value_set(xa, "urn:ietf:params:xml:ns:yang:1") < 0) if (xml_value_set(xa, YANG_XML_NAMESPACE) < 0)
goto done; goto done;
/* Then add insert attribute */ /* Then add insert attribute */
if ((xa = xml_new("insert", xdata, NULL)) == NULL) if ((xa = xml_new("insert", xdata, NULL)) == NULL)

View file

@ -290,8 +290,8 @@ api_data_put(clicon_handle h,
char *dname; char *dname;
int nullspec = 0; int nullspec = 0;
clicon_debug(1, "%s api_path:\"%s\" data:\"%s\"", clicon_debug(1, "%s api_path:\"%s\"", __FUNCTION__, api_path0);
__FUNCTION__, api_path0, data); clicon_debug(1, "%s data:\"%s\"", __FUNCTION__, data);
if ((yspec = clicon_dbspec_yang(h)) == NULL){ if ((yspec = clicon_dbspec_yang(h)) == NULL){
clicon_err(OE_FATAL, 0, "No DB_SPEC"); clicon_err(OE_FATAL, 0, "No DB_SPEC");
goto done; goto done;
@ -415,6 +415,7 @@ api_data_put(clicon_handle h,
if ((xa = xml_new("operation", xdata, NULL)) == NULL) if ((xa = xml_new("operation", xdata, NULL)) == NULL)
goto done; goto done;
xml_type_set(xa, CX_ATTR); xml_type_set(xa, CX_ATTR);
xml_prefix_set(xa, NETCONF_BASE_PREFIX);
op = OP_CREATE; op = OP_CREATE;
if (xml_value_set(xa, xml_operation2str(op)) < 0) if (xml_value_set(xa, xml_operation2str(op)) < 0)
goto done; goto done;
@ -542,7 +543,10 @@ api_data_put(clicon_handle h,
*/ */
username = clicon_username_get(h); username = clicon_username_get(h);
again: again:
cprintf(cbx, "<rpc username=\"%s\">", username?username:""); cprintf(cbx, "<rpc username=\"%s\" xmlns:%s=\"%s\">",
username?username:"",
NETCONF_BASE_PREFIX,
NETCONF_BASE_NAMESPACE); /* bind nc to netconf namespace */
cprintf(cbx, "<edit-config><target><candidate /></target>"); cprintf(cbx, "<edit-config><target><candidate /></target>");
cprintf(cbx, "<default-operation>none</default-operation>"); cprintf(cbx, "<default-operation>none</default-operation>");
if (clicon_xml2cbuf(cbx, xtop, 0, 0) < 0) if (clicon_xml2cbuf(cbx, xtop, 0, 0) < 0)
@ -720,6 +724,7 @@ api_data_delete(clicon_handle h,
if ((xa = xml_new("operation", xbot, NULL)) == NULL) if ((xa = xml_new("operation", xbot, NULL)) == NULL)
goto done; goto done;
xml_type_set(xa, CX_ATTR); xml_type_set(xa, CX_ATTR);
xml_prefix_set(xa, NETCONF_BASE_PREFIX);
if (xml_value_set(xa, xml_operation2str(op)) < 0) if (xml_value_set(xa, xml_operation2str(op)) < 0)
goto done; goto done;
if ((cbx = cbuf_new()) == NULL) if ((cbx = cbuf_new()) == NULL)
@ -727,7 +732,10 @@ api_data_delete(clicon_handle h,
/* For internal XML protocol: add username attribute for access control /* For internal XML protocol: add username attribute for access control
*/ */
username = clicon_username_get(h); username = clicon_username_get(h);
cprintf(cbx, "<rpc username=\"%s\">", username?username:""); cprintf(cbx, "<rpc username=\"%s\" xmlns:%s=\"%s\">",
username?username:"",
NETCONF_BASE_PREFIX,
NETCONF_BASE_NAMESPACE); /* bind nc to netconf namespace */
cprintf(cbx, "<edit-config><target><candidate /></target>"); cprintf(cbx, "<edit-config><target><candidate /></target>");
cprintf(cbx, "<default-operation>none</default-operation>"); cprintf(cbx, "<default-operation>none</default-operation>");
if (clicon_xml2cbuf(cbx, xtop, 0, 0) < 0) if (clicon_xml2cbuf(cbx, xtop, 0, 0) < 0)

View file

@ -259,6 +259,7 @@ api_data_post(clicon_handle h,
if ((xa = xml_new("operation", xdata, NULL)) == NULL) if ((xa = xml_new("operation", xdata, NULL)) == NULL)
goto done; goto done;
xml_type_set(xa, CX_ATTR); xml_type_set(xa, CX_ATTR);
xml_prefix_set(xa, NETCONF_BASE_PREFIX);
if (xml_value_set(xa, xml_operation2str(op)) < 0) if (xml_value_set(xa, xml_operation2str(op)) < 0)
goto done; goto done;
/* Replace xbot with x, ie bottom of api-path with data */ /* Replace xbot with x, ie bottom of api-path with data */
@ -304,7 +305,10 @@ api_data_post(clicon_handle h,
/* For internal XML protocol: add username attribute for access control /* For internal XML protocol: add username attribute for access control
*/ */
username = clicon_username_get(h); username = clicon_username_get(h);
cprintf(cbx, "<rpc username=\"%s\">", username?username:""); cprintf(cbx, "<rpc username=\"%s\" xmlns:%s=\"%s\">",
username?username:"",
NETCONF_BASE_PREFIX,
NETCONF_BASE_NAMESPACE); /* bind nc to netconf namespace */
cprintf(cbx, "<edit-config><target><candidate /></target>"); cprintf(cbx, "<edit-config><target><candidate /></target>");
cprintf(cbx, "<default-operation>none</default-operation>"); cprintf(cbx, "<default-operation>none</default-operation>");
if (clicon_xml2cbuf(cbx, xtop, 0, 0) < 0) if (clicon_xml2cbuf(cbx, xtop, 0, 0) < 0)

View file

@ -749,7 +749,7 @@ clixon_plugin_init(clicon_handle h)
/* Called after the regular system copy_config callback */ /* Called after the regular system copy_config callback */
if (rpc_callback_register(h, example_copy_extra, if (rpc_callback_register(h, example_copy_extra,
NULL, NULL,
"urn:ietf:params:xml:ns:netconf:base:1.0", NETCONF_BASE_NAMESPACE,
"copy-config" "copy-config"
) < 0) ) < 0)
goto done; goto done;

View file

@ -95,7 +95,8 @@ example_client_rpc(clicon_handle h,
/* User supplied variable in CLI command */ /* User supplied variable in CLI command */
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 (xml_parse_va(&xtop, NULL, "<rpc message-id=\"101\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" username=\"%s\"><example xmlns=\"urn:example:clixon\"><x>%s</x></example></rpc>", if (xml_parse_va(&xtop, NULL, "<rpc message-id=\"101\" xmlns=\"%s\" username=\"%s\"><example xmlns=\"urn:example:clixon\"><x>%s</x></example></rpc>",
NETCONF_BASE_NAMESPACE,
clicon_username_get(h), clicon_username_get(h),
cv_string_get(cva)) < 0) cv_string_get(cva)) < 0)
goto done; goto done;

View file

@ -44,9 +44,15 @@
/* Default NETCONF namespace (see rfc6241 3.1) /* Default NETCONF namespace (see rfc6241 3.1)
* See USE_NETCONF_NS_AS_DEFAULT for use of this namespace as default * See USE_NETCONF_NS_AS_DEFAULT for use of this namespace as default
* Also, bind it to prefix:nc as used by, for example, the operation attribute
*/ */
#define NETCONF_BASE_NAMESPACE "urn:ietf:params:xml:ns:netconf:base:1.0" #define NETCONF_BASE_NAMESPACE "urn:ietf:params:xml:ns:netconf:base:1.0"
#define NETCONF_BASE_PREFIX "nc"
/* See RFC 7950 Sec 5.3.1: YANG defines an XML namespace for NETCONF <edit-config>
* operations, <error-info> content, and the <action> element.
*/
#define YANG_XML_NAMESPACE "urn:ietf:params:xml:ns:yang:1"
/* /*
* Types * Types
*/ */

View file

@ -227,9 +227,8 @@ text_modify(clicon_handle h,
int changed = 0; /* Only if x0p's children have changed-> sort is necessary */ int changed = 0; /* Only if x0p's children have changed-> sort is necessary */
/* Check for operations embedded in tree according to netconf */ /* Check for operations embedded in tree according to netconf */
#ifdef notyet /* XXX breaks in test_cohoice.sh */
if ((ret = attr_ns_value(x1, if ((ret = attr_ns_value(x1,
"operation", "urn:ietf:params:xml:ns:netconf:base:1.0", "operation", NETCONF_BASE_NAMESPACE,
cbret, &opstr)) < 0) cbret, &opstr)) < 0)
goto done; goto done;
if (ret == 0) if (ret == 0)
@ -237,12 +236,6 @@ text_modify(clicon_handle h,
if (opstr != NULL) if (opstr != NULL)
if (xml_operation(opstr, &op) < 0) if (xml_operation(opstr, &op) < 0)
goto done; goto done;
#else
if ((opstr = xml_find_value(x1, "operation")) != NULL)
if (xml_operation(opstr, &op) < 0)
goto done;
#endif
x1name = xml_name(x1); x1name = xml_name(x1);
if (yang_keyword_get(y0) == Y_LEAF_LIST || if (yang_keyword_get(y0) == Y_LEAF_LIST ||
yang_keyword_get(y0) == Y_LEAF){ yang_keyword_get(y0) == Y_LEAF){
@ -260,7 +253,7 @@ text_modify(clicon_handle h,
if (yang_keyword_get(y0) == Y_LEAF_LIST && if (yang_keyword_get(y0) == Y_LEAF_LIST &&
yang_find(y0, Y_ORDERED_BY, "user") != NULL){ yang_find(y0, Y_ORDERED_BY, "user") != NULL){
if ((ret = attr_ns_value(x1, if ((ret = attr_ns_value(x1,
"insert", "urn:ietf:params:xml:ns:yang:1", "insert", YANG_XML_NAMESPACE,
cbret, &instr)) < 0) cbret, &instr)) < 0)
goto done; goto done;
if (ret == 0) if (ret == 0)
@ -269,7 +262,7 @@ text_modify(clicon_handle h,
xml_attr_insert2val(instr, &insert) < 0) xml_attr_insert2val(instr, &insert) < 0)
goto done; goto done;
if ((ret = attr_ns_value(x1, if ((ret = attr_ns_value(x1,
"value", "urn:ietf:params:xml:ns:yang:1", "value", YANG_XML_NAMESPACE,
cbret, &valstr)) < 0) cbret, &valstr)) < 0)
goto done; goto done;
/* if insert/before, value attribute must be there */ /* if insert/before, value attribute must be there */
@ -331,7 +324,8 @@ text_modify(clicon_handle h,
if (strcmp(xml_name(x1a),"xmlns")==0 || if (strcmp(xml_name(x1a),"xmlns")==0 ||
((xns = xml_prefix(x1a)) && strcmp(xns, "xmlns")==0)){ ((xns = xml_prefix(x1a)) && strcmp(xns, "xmlns")==0)){
#if 1 /* XXX Kludge to NOT copy RFC7950 xmlns:yang insert/key/value namespaces */ #if 1 /* XXX Kludge to NOT copy RFC7950 xmlns:yang insert/key/value namespaces */
if (strcmp(xml_value(x1a),"urn:ietf:params:xml:ns:yang:1")==0) if (strcmp(xml_value(x1a), YANG_XML_NAMESPACE)==0 ||
strcmp(xml_value(x1a), NETCONF_BASE_NAMESPACE)==0)
continue; continue;
#endif #endif
if ((x0a = xml_dup(x1a)) == NULL) if ((x0a = xml_dup(x1a)) == NULL)
@ -420,7 +414,7 @@ text_modify(clicon_handle h,
if (yang_keyword_get(y0) == Y_LIST && if (yang_keyword_get(y0) == Y_LIST &&
yang_find(y0, Y_ORDERED_BY, "user") != NULL){ yang_find(y0, Y_ORDERED_BY, "user") != NULL){
if ((ret = attr_ns_value(x1, if ((ret = attr_ns_value(x1,
"insert", "urn:ietf:params:xml:ns:yang:1", "insert", YANG_XML_NAMESPACE,
cbret, &instr)) < 0) cbret, &instr)) < 0)
goto done; goto done;
if (ret == 0) if (ret == 0)
@ -429,7 +423,7 @@ text_modify(clicon_handle h,
xml_attr_insert2val(instr, &insert) < 0) xml_attr_insert2val(instr, &insert) < 0)
goto done; goto done;
if ((ret = attr_ns_value(x1, if ((ret = attr_ns_value(x1,
"key", "urn:ietf:params:xml:ns:yang:1", "key", YANG_XML_NAMESPACE,
cbret, &keystr)) < 0) cbret, &keystr)) < 0)
goto done; goto done;
/* if insert/before, key attribute must be there */ /* if insert/before, key attribute must be there */
@ -517,7 +511,8 @@ text_modify(clicon_handle h,
if (strcmp(xml_name(x1a),"xmlns")==0 || if (strcmp(xml_name(x1a),"xmlns")==0 ||
((xns = xml_prefix(x1a)) && strcmp(xns, "xmlns")==0)){ ((xns = xml_prefix(x1a)) && strcmp(xns, "xmlns")==0)){
#if 1 /* XXX Kludge to NOT copy RFC7950 xmlns:yang insert/key/value namespaces */ #if 1 /* XXX Kludge to NOT copy RFC7950 xmlns:yang insert/key/value namespaces */
if (strcmp(xml_value(x1a),"urn:ietf:params:xml:ns:yang:1")==0) if (strcmp(xml_value(x1a), YANG_XML_NAMESPACE)==0 ||
strcmp(xml_value(x1a), NETCONF_BASE_NAMESPACE)==0)
continue; continue;
#endif #endif
if ((x0a = xml_dup(x1a)) == NULL) if ((x0a = xml_dup(x1a)) == NULL)
@ -650,12 +645,14 @@ text_modify_top(clicon_handle h,
char *opstr; char *opstr;
int ret; int ret;
/* Assure top-levels are 'config' */
// assert(x0 && strcmp(xml_name(x0),"config")==0);
// assert(x1 && strcmp(xml_name(x1),"config")==0);
/* Check for operations embedded in tree according to netconf */ /* Check for operations embedded in tree according to netconf */
if ((opstr = xml_find_value(x1, "operation")) != NULL) if ((ret = attr_ns_value(x1,
"operation", NETCONF_BASE_NAMESPACE,
cbret, &opstr)) < 0)
goto done;
if (ret == 0)
goto fail;
if (opstr != NULL)
if (xml_operation(opstr, &op) < 0) if (xml_operation(opstr, &op) < 0)
goto done; goto done;
/* Special case if x1 is empty, top-level only <config/> */ /* Special case if x1 is empty, top-level only <config/> */

View file

@ -357,6 +357,7 @@ clicon_rpc_edit_config(clicon_handle h,
if ((cb = cbuf_new()) == NULL) if ((cb = cbuf_new()) == NULL)
goto done; goto done;
cprintf(cb, "<rpc xmlns=\"%s\"", NETCONF_BASE_NAMESPACE); cprintf(cb, "<rpc xmlns=\"%s\"", NETCONF_BASE_NAMESPACE);
cprintf(cb, " xmlns:%s=\"%s\"", NETCONF_BASE_PREFIX, NETCONF_BASE_NAMESPACE);
if ((username = clicon_username_get(h)) != NULL) if ((username = clicon_username_get(h)) != NULL)
cprintf(cb, " username=\"%s\"", username); cprintf(cb, " username=\"%s\"", username);
cprintf(cb, "><edit-config><target><%s/></target>", db); cprintf(cb, "><edit-config><target><%s/></target>", db);

View file

@ -69,23 +69,22 @@ if [ $BE -ne 0 ]; then
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
err err
fi fi
new "start backend -s init -f $cfg"
# start new backend new "start backend -s init -f $cfg"
echo "sudo $clixon_backend -s init -f $cfg -D $DBG" start_backend -s init -f $cfg
sudo $clixon_backend -s init -f $cfg -D $DBG
if [ $? -ne 0 ]; then new "waiting"
err wait_backend
fi
fi fi
new "Add config to candidate" new "Add config to candidate"
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface operation="create"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><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><ok/></rpc-reply>]]>]]>$"
new "netconf commit to running" new "netconf commit to running"
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "Delete candidate" new "Delete candidate"
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface operation="delete"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' '^<rpc-reply><ok/></rpc-reply>]]>]]>$' expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><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><ok/></rpc-reply>]]>]]>$'
# 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
@ -123,7 +122,7 @@ new "Check startup content"
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc message-id="101"><get-config><source><startup/></source></get-config></rpc>]]>]]>' '^<rpc-reply 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 message-id="101"><get-config><source><startup/></source></get-config></rpc>]]>]]>' '^<rpc-reply 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>]]>]]>$'
new "Delete candidate" new "Delete candidate"
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface operation="delete"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' '^<rpc-reply><ok/></rpc-reply>]]>]]>$' expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><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><ok/></rpc-reply>]]>]]>$'
# Here candidate is empty and startup has content # Here candidate is empty and startup has content
# test startup->candidate # test startup->candidate
@ -138,7 +137,7 @@ expecteof "$clixon_netconf -qf $cfg" 0 '<rpc message-id="101"><get-config><sourc
# Negative test: check copying to running is not allowed # Negative test: check copying to running is not allowed
new "Delete candidate" new "Delete candidate"
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface operation="delete"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' '^<rpc-reply><ok/></rpc-reply>]]>]]>$' expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><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><ok/></rpc-reply>]]>]]>$'
new "netconf commit to running" new "netconf commit to running"
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"

View file

@ -168,7 +168,7 @@ new "leafref validate (ok)"
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>" expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>"
new "leafref delete leaf" new "leafref delete leaf"
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface operation="delete"><name>eth0</name></interface></interfaces></config></edit-config></rpc>]]>]]>' '^<rpc-reply><ok/></rpc-reply>' expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><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>eth0</name></interface></interfaces></config></edit-config></rpc>]]>]]>' '^<rpc-reply><ok/></rpc-reply>'
new "leafref validate (should fail)" new "leafref validate (should fail)"
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>eth0</bad-element></error-info><error-severity>error</error-severity><error-message>Leafref validation failed: No such leaf</error-message></rpc-error></rpc-reply>]]>]]>$' expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>eth0</bad-element></error-info><error-severity>error</error-severity><error-message>Leafref validation failed: No such leaf</error-message></rpc-error></rpc-reply>]]>]]>$'

View file

@ -65,7 +65,7 @@ new "Check nothing added"
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc message-id="101"><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply message-id="101"><data/></rpc-reply>]]>]]>$' expecteof "$clixon_netconf -qf $cfg" 0 '<rpc message-id="101"><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply message-id="101"><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><edit-config><target><candidate/></target><config><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface operation="create"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><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><ok/></rpc-reply>]]>]]>$"
# Too many quotes, (single inside double inside single) need to fool bash # Too many quotes, (single inside double inside single) need to fool bash
cat <<EOF > $tmp # new cat <<EOF > $tmp # new
@ -76,19 +76,19 @@ new "Check eth/0/0 added using xpath"
expecteof "$clixon_netconf -qf $cfg" 0 "$(cat $tmp)" '^<rpc-reply><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 "$(cat $tmp)" '^<rpc-reply><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 "Re-create same eth/0/0 which should generate error" new "Re-create same eth/0/0 which should generate error"
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface operation="create"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' '^<rpc-reply><rpc-error>' expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><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><rpc-error>'
new "Delete eth/0/0 using none config" new "Delete eth/0/0 using none config"
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface operation="delete"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' '^<rpc-reply><ok/></rpc-reply>]]>]]>$' expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><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><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 message-id="101"><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply message-id="101"><data/></rpc-reply>]]>]]>$' expecteof "$clixon_netconf -qf $cfg" 0 '<rpc message-id="101"><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply message-id="101"><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><edit-config><target><candidate/></target><config><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface operation="delete"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' '^<rpc-reply><rpc-error>' expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><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><rpc-error>'
new "Add interface without key" new "Add interface without key"
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface operation="create"><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>missing-element</error-tag><error-info><bad-element>name</bad-element></error-info><error-severity>error</error-severity><error-message>Mandatory key</error-message></rpc-error></rpc-reply>]]>]]>$' expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><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"><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>]]>]]>' '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>missing-element</error-tag><error-info><bad-element>name</bad-element></error-info><error-severity>error</error-severity><error-message>Mandatory key</error-message></rpc-error></rpc-reply>]]>]]>$'
new "netconf discard-changes" new "netconf discard-changes"
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"

View file

@ -317,7 +317,7 @@ new "check ordered-by-user: a,b,c,d,e"
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply><data><y0 xmlns="urn:example:order">a</y0><y0 xmlns="urn:example:order">b</y0><y0 xmlns="urn:example:order">c</y0><y0 xmlns="urn:example:order">d</y0><y0 xmlns="urn:example:order">e</y0></data></rpc-reply>]]>]]>$' expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply><data><y0 xmlns="urn:example:order">a</y0><y0 xmlns="urn:example:order">b</y0><y0 xmlns="urn:example:order">c</y0><y0 xmlns="urn:example:order">d</y0><y0 xmlns="urn:example:order">e</y0></data></rpc-reply>]]>]]>$'
new "move one entry (e) to leaf-list first" new "move one entry (e) to leaf-list first"
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><y0 operation="replace" xmlns="urn:example:order" xmlns:yang="urn:ietf:params:xml:ns:yang:1" yang:insert="first">e</y0></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><y0 nc:operation="replace" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns="urn:example:order" xmlns:yang="urn:ietf:params:xml:ns:yang:1" yang:insert="first">e</y0></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "check ordered-by-user: e,a,b,c,d" new "check ordered-by-user: e,a,b,c,d"
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply><data><y0 xmlns="urn:example:order">e</y0><y0 xmlns="urn:example:order">a</y0><y0 xmlns="urn:example:order">b</y0><y0 xmlns="urn:example:order">c</y0><y0 xmlns="urn:example:order">d</y0></data></rpc-reply>]]>]]>$' expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply><data><y0 xmlns="urn:example:order">e</y0><y0 xmlns="urn:example:order">a</y0><y0 xmlns="urn:example:order">b</y0><y0 xmlns="urn:example:order">c</y0><y0 xmlns="urn:example:order">d</y0></data></rpc-reply>]]>]]>$'

View file

@ -186,7 +186,7 @@ expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><discard-changes/></rpc>]]>]]>" "^<
new "netconf delete $perfreq small config" new "netconf delete $perfreq small config"
{ time -p for (( i=0; i<$perfreq; i++ )); do { time -p for (( i=0; i<$perfreq; i++ )); do
rnd=$(( ( RANDOM % $perfnr ) )) rnd=$(( ( RANDOM % $perfnr ) ))
echo "<rpc><edit-config><target><candidate/></target><config><x xmlns=\"urn:example:clixon\"><y operation=\"delete\"><a>$rnd</a></y></x></config></edit-config></rpc>]]>]]>" echo "<rpc><edit-config><target><candidate/></target><config><x xmlns=\"urn:example:clixon\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><y nc:operation=\"delete\"><a>$rnd</a></y></x></config></edit-config></rpc>]]>]]>"
done | $clixon_netconf -qf $cfg > /dev/null; } 2>&1 | awk '/real/ {print $2}' done | $clixon_netconf -qf $cfg > /dev/null; } 2>&1 | awk '/real/ {print $2}'
new "netconf discard-changes" new "netconf discard-changes"

View file

@ -318,4 +318,4 @@ fi
# kill backend # kill backend
stop_backend -f $cfg stop_backend -f $cfg
#rm -rf $dir rm -rf $dir

View file

@ -135,14 +135,14 @@ new "netconf validate ok"
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "make it invalid by adding port to ftp entry" new "make it invalid by adding port to ftp entry"
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><default-operation>none</default-operation><config><c xmlns="urn:example:clixon"><server><name>ftp</name><port operation="create">25</port></server> expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><default-operation>none</default-operation><config><c xmlns="urn:example:clixon" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"><server><name>ftp</name><port nc:operation="create">25</port></server>
</c></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$" </c></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf validate (should fail)" new "netconf validate (should fail)"
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>protocol</error-type><error-tag>operation-failed</error-tag><error-app-tag>data-not-unique</error-app-tag><error-severity>error</error-severity><error-info><non-unique><ip>192.0.2.1</ip></non-unique><non-unique><port>25</port></non-unique></error-info></rpc-error></rpc-reply>]]>]]>$' expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" '^<rpc-reply><rpc-error><error-type>protocol</error-type><error-tag>operation-failed</error-tag><error-app-tag>data-not-unique</error-app-tag><error-severity>error</error-severity><error-info><non-unique><ip>192.0.2.1</ip></non-unique><non-unique><port>25</port></non-unique></error-info></rpc-error></rpc-reply>]]>]]>$'
new "make it valid by deleting port from smtp entry" new "make it valid by deleting port from smtp entry"
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><default-operation>none</default-operation><config><c xmlns="urn:example:clixon"><server><name>smtp</name><port operation="delete">25</port></server> expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><default-operation>none</default-operation><config><c xmlns="urn:example:clixon" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"><server><name>smtp</name><port nc:operation="delete">25</port></server>
</c></config></edit-config></rpc>]]>]]>' '^<rpc-reply><ok/></rpc-reply>]]>]]>$' </c></config></edit-config></rpc>]]>]]>' '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
new "netconf validate ok" new "netconf validate ok"

View file

@ -257,7 +257,7 @@ new "netconf check replace"
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '<rpc-reply><data><x xmlns="urn:example:clixon"><y><a>1</a><b>1</b><c>1</c><val>replace</val></y><y><a>1</a><b>2</b><c>1</c><val>two</val></y></x></data></rpc-reply>]]>]]>' expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '<rpc-reply><data><x xmlns="urn:example:clixon"><y><a>1</a><b>1</b><c>1</c><val>replace</val></y><y><a>1</a><b>2</b><c>1</c><val>two</val></y></x></data></rpc-reply>]]>]]>'
new "netconf delete first" new "netconf delete first"
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><x xmlns="urn:example:clixon"><y operation="remove"><a>1</a><b>1</b><c>1</c></y></x></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><config><x xmlns="urn:example:clixon" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"><y nc:operation="remove"><a>1</a><b>1</b><c>1</c></y></x></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
new "netconf check delete" new "netconf check delete"
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '<rpc-reply><data><x xmlns="urn:example:clixon"><y><a>1</a><b>2</b><c>1</c><val>two</val></y></x></data></rpc-reply>]]>]]>' expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '<rpc-reply><data><x xmlns="urn:example:clixon"><y><a>1</a><b>2</b><c>1</c><val>two</val></y></x></data></rpc-reply>]]>]]>'