Improved netconf error handling for data-not-unique and missing-choice

* Follows RFC7950 Sec 15.1 and 15.6 more closely
* Fixed: [When multiple lists have same key name, need more elaborate error message in case of configuration having duplicate keys](https://github.com/clicon/clixon/issues/362)
This commit is contained in:
Olof hagsand 2022-09-19 14:33:44 +02:00
parent e579d959fa
commit 51d1a2d41c
11 changed files with 143 additions and 65 deletions

View file

@ -69,6 +69,15 @@ Expected: September 2022
Users may have to change how they access the system
* NETCONF error handling for `data-not-unique` and `missing-choice` follows standard more closely
* data-not-unique:
* Added YANG namespace to `<non-unique>` tag
* Changed `yang-unique` value to path insytead of single name
* See RFC 7950 Sec 15.1
* missing-choice:
* Added `<error-path>`
* Added YANG namespace to `<missing-choice>` tag
* See RFC 7950 Sec 15.6
* Backend transaction plugins: edit of choice node will always result in a "del/add" event for all edits of change nodes, never a "change" event.
* Before, some cases were using a "change" event if the "yang ordering" happended to be the same.
* See more details in: [Clixon backend transactions for choice/case is not logical](https://github.com/clicon/clixon/issues/361)
@ -110,6 +119,8 @@ e`
### Corrected Bugs
* Fixed: [When multiple lists have same key name, need more elaborate error message in case of configuration having duplicate keys](https://github.com/clicon/clixon/issues/362)
* Solved by implementing RFC7950 Sec 5.1 correctly
* Fixed: [All values in list don't appear when writing "show <list>" in cli](https://github.com/clicon/clixon/issues/359)
* Fixed: [yang regular char \w not include underline char](https://github.com/clicon/clixon/issues/357)
* Fixed: [Clixon backend transactions for choice/case is not logical](https://github.com/clicon/clixon/issues/361)

View file

@ -143,8 +143,9 @@ int netconf_lock_denied(cbuf *cb, char *info, char *message);
int netconf_resource_denied(cbuf *cb, char *type, char *message);
int netconf_rollback_failed(cbuf *cb, char *type, char *message);
int netconf_data_exists(cbuf *cb, char *message);
int netconf_data_missing(cbuf *cb, char *missing_choice, char *message);
int netconf_data_missing_xml(cxobj **xret, char *missing_choice, char *message);
int netconf_data_missing(cbuf *cb, char *message);
int netconf_data_missing_xml(cxobj **xret, char *message);
int netconf_missing_choice_xml(cxobj **xret, cxobj *x, char *missing_choice, char *message);
int netconf_operation_not_supported_xml(cxobj **xret, char *type, char *message);
int netconf_operation_not_supported(cbuf *cb, char *type, char *message);
int netconf_operation_failed(cbuf *cb, char *type, char *message);

View file

@ -540,7 +540,7 @@ text_modify(clicon_handle h,
/* RFC 8040 4.6 PATCH:
* If the target resource instance does not exist, the server MUST NOT create it.
*/
if (netconf_data_missing(cbret, NULL,
if (netconf_data_missing(cbret,
"RFC 8040 4.6. PATCH: If the target resource instance does not exist, the server MUST NOT create it") < 0)
goto done;
goto fail;
@ -714,7 +714,7 @@ text_modify(clicon_handle h,
break;
case OP_DELETE:
if (x0==NULL){
if (netconf_data_missing(cbret, NULL, "Data does not exist; cannot delete resource") < 0)
if (netconf_data_missing(cbret, "Data does not exist; cannot delete resource") < 0)
goto done;
goto fail;
}
@ -735,7 +735,7 @@ text_modify(clicon_handle h,
}
else {
if (op == OP_DELETE){
if (netconf_data_missing(cbret, NULL, "Data does not exist; cannot delete resource") < 0)
if (netconf_data_missing(cbret, "Data does not exist; cannot delete resource") < 0)
goto done;
goto fail;
}
@ -941,7 +941,7 @@ text_modify(clicon_handle h,
break;
case OP_DELETE:
if (x0==NULL){
if (netconf_data_missing(cbret, NULL, "Data does not exist; cannot delete resource") < 0)
if (netconf_data_missing(cbret, "Data does not exist; cannot delete resource") < 0)
goto done;
goto fail;
}
@ -1060,7 +1060,7 @@ text_modify_top(clicon_handle h,
I.e., curl -u andy:bar -sS -X DELETE http://localhost/restconf/data
*/
case OP_DELETE:
if (netconf_data_missing(cbret, NULL, "Data does not exist; cannot delete resource") < 0)
if (netconf_data_missing(cbret, "Data does not exist; cannot delete resource") < 0)
goto done;
goto fail;
break;

View file

@ -923,18 +923,16 @@ netconf_data_exists(cbuf *cb,
* does not exist. For example, a "delete" operation was attempted on
* data that does not exist.
* @param[out] cb CLIgen buf. Error XML is written in this buffer
* @param[in] missing_choice If set, see RFC7950: 15.6 violates mandatory choice
* @param[in] message Error message
*/
int
netconf_data_missing(cbuf *cb,
char *missing_choice,
char *message)
{
int retval = -1;
cxobj *xret = NULL;
if (netconf_data_missing_xml(&xret, missing_choice, message) < 0)
if (netconf_data_missing_xml(&xret, message) < 0)
goto done;
if (clixon_xml2cbuf(cb, xret, 0, 0, -1, 0) < 0)
goto done;
@ -945,18 +943,16 @@ netconf_data_missing(cbuf *cb,
return retval;
}
/*! Create Netconf data-missing error XML tree according to RFC 6241 App A
/*! Create Netconf data-missing error XML tree according to RFC 6241 App A / RFC 7950 15.6(choice)
*
* Request could not be completed because the relevant data model content
* does not exist. For example, a "delete" operation was attempted on
* data that does not exist.
* @param[out] xret Error XML tree. Free with xml_free after use
* @param[in] missing_choice If set, see RFC7950: 15.6 violates mandatiry choice
* @param[in] message Error message
*/
int
netconf_data_missing_xml(cxobj **xret,
char *missing_choice,
char *message)
{
int retval = -1;
@ -984,12 +980,6 @@ netconf_data_missing_xml(cxobj **xret,
"<error-type>application</error-type>"
"<error-tag>data-missing</error-tag>") < 0)
goto done;
if (missing_choice) /* NYI: RFC7950: 15.6 <error-path> */
if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL,
"<error-app-tag>missing-choice</error-app-tag>"
"<error-info><missing-choice>%s</missing-choice></error-info>",
missing_choice) < 0)
goto done;
if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL,
"<error-severity>error</error-severity>") < 0)
goto done;
@ -1007,6 +997,79 @@ netconf_data_missing_xml(cxobj **xret,
return retval;
}
/*! Create Netconf data-missing / missing-choice as defeind in RFC 7950 15.6
*
* If a NETCONF operation would result in configuration data where no
* nodes exists in a mandatory choice, the following error MUST be
* returned:
* @param[out] xret Error XML tree. Free with xml_free after use
* @param[in] x Element with missing choice
* @param[in] name Name of missing mandatory choice
* @param[in] message Error message
*/
int
netconf_missing_choice_xml(cxobj **xret,
cxobj *x,
char *name,
char *message)
{
int retval = -1;
char *encstr = NULL;
cxobj *xerr;
cxobj *xa;
char *path = NULL;
char *encpath = NULL;
if (xret == NULL || name == NULL){
clicon_err(OE_NETCONF, EINVAL, "xret or name is NULL");
goto done;
}
if (*xret == NULL){
if ((*xret = xml_new("rpc-reply", NULL, CX_ELMNT)) == NULL)
goto done;
}
else if (xml_name_set(*xret, "rpc-reply") < 0)
goto done;
if ((xa = xml_new("xmlns", *xret, CX_ATTR)) == NULL)
goto done;
if (xml_value_set(xa, NETCONF_BASE_NAMESPACE) < 0)
goto done;
if ((xerr = xml_new("rpc-error", *xret, CX_ELMNT)) == NULL)
goto done;
/* error-path: Path to the element with the missing choice. */
if (xml2xpath(x, NULL, &path) < 0)
goto done;
if (xml_chardata_encode(&encpath, "%s", path) < 0)
goto done;
if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL,
"<error-type>application</error-type>"
"<error-tag>data-missing</error-tag>"
"<error-app-tag>missing-choice</error-app-tag>"
"<error-path>%s</error-path>"
"<error-info><missing-choice xmlns=\"%s\">%s</missing-choice></error-info>"
"<error-severity>error</error-severity>",
encpath,
YANG_XML_NAMESPACE,
name) < 0)
goto done;
if (message){
if (xml_chardata_encode(&encstr, "%s", message) < 0)
goto done;
if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL,
"<error-message>%s</error-message>", encstr) < 0)
goto done;
}
retval = 0;
done:
if (path)
free(path);
if (encstr)
free(encstr);
if (encpath)
free(encpath);
return retval;
}
/*! Create Netconf operation-not-supported error XML according to RFC 6241 App A
*
* Request could not be completed because the requested operation is not
@ -1287,8 +1350,9 @@ netconf_data_not_unique_xml(cxobj **xret,
cg_var *cvi = NULL;
cxobj *xerr;
cxobj *xinfo;
cbuf *cb = NULL;
cxobj *xa;
char *path = NULL;
char *encpath = NULL;
if (xret == NULL){
clicon_err(OE_NETCONF, EINVAL, "xret is NULL");
@ -1312,23 +1376,31 @@ netconf_data_not_unique_xml(cxobj **xret,
"<error-app-tag>data-not-unique</error-app-tag>"
"<error-severity>error</error-severity>") < 0)
goto done;
/* error-info: <non-unique> Contains an instance identifier that points to a leaf
* that invalidates the "unique" constraint. This element is present once for each
* non-unique leaf. */
if (cvec_len(cvk)){
if ((xinfo = xml_new("error-info", xerr, CX_ELMNT)) == NULL)
goto done;
if ((cb = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
if (xml2xpath(x, NULL, &path) < 0)
goto done;
if (xml_chardata_encode(&encpath, "%s", path) < 0)
goto done;
}
while ((cvi = cvec_each(cvk, cvi)) != NULL){
if (clixon_xml_parse_va(YB_NONE, NULL, &xinfo, NULL,
"<non-unique>%s</non-unique>", cv_string_get(cvi)) < 0)
"<non-unique xmlns=\"%s\">%s/%s</non-unique>",
YANG_XML_NAMESPACE,
encpath,
cv_string_get(cvi)) < 0)
goto done;
}
}
retval = 0;
done:
if (cb)
cbuf_free(cb);
if (path)
free(path);
if (encpath)
free(encpath);
return retval;
}
@ -1351,7 +1423,7 @@ netconf_minmax_elements_xml(cxobj **xret,
int retval = -1;
cxobj *xerr;
char *path = NULL;
cbuf *cb = NULL;
char *encpath = NULL;
cxobj *xa;
if (xret == NULL){
@ -1370,31 +1442,27 @@ netconf_minmax_elements_xml(cxobj **xret,
goto done;
if ((xerr = xml_new("rpc-error", *xret, CX_ELMNT)) == NULL)
goto done;
if ((cb = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
if (xml_parent(xp)){ /* Dont include root, eg <config> */
if (xml2xpath(xp, NULL, &path) < 0)
goto done;
if (path)
cprintf(cb, "%s", path);
if (xml_chardata_encode(&encpath, "%s", path) < 0)
goto done;
}
cprintf(cb, "/%s", name);
if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL, "<error-type>protocol</error-type>"
"<error-tag>operation-failed</error-tag>"
"<error-app-tag>too-%s-elements</error-app-tag>"
"<error-severity>error</error-severity>"
"<error-path>%s</error-path>",
"<error-path>%s/%s</error-path>",
max?"many":"few",
cbuf_get(cb)) < 0)
encpath?encpath:"",
name) < 0)
goto done;
retval = 0;
done:
if (path)
free(path);
if (cb)
cbuf_free(cb);
if (encpath)
free(encpath);
return retval;
}

View file

@ -818,7 +818,7 @@ check_mandatory(cxobj *xt,
if (x == NULL){
/* @see RFC7950: 15.6 Error Message for Data That Violates
* a Mandatory "choice" Statement */
if (xret && netconf_data_missing_xml(xret, yang_argument_get(yc), NULL) < 0)
if (xret && netconf_missing_choice_xml(xret, xt, yang_argument_get(yc), NULL) < 0)
goto done;
goto fail;
}

View file

@ -138,17 +138,15 @@ unique_search_xpath(cxobj *x,
goto done;
}
/*! New element last in list, check if already exists if sp return -1
/*! New element last in list, return error if already exists
*
* @param[in] vec Vector of existing entries (new is last)
* @param[in] i1 The new entry is placed at vec[i1]
* @param[in] vlen Lenght of entry
* @param[in] vlen Length of vec
* @param[in] sorted Sorted by system, ie sorted by key, otherwise no assumption
* @retval 0 OK, entry is unique
* @retval -1 Duplicate detected
* @note This is currently quadratic complexity. It could be improved by inserting new element sorted and binary search.
* @retval 1 Validation OK
* @retval 0 Validation failed (cbret set)
* @retval -1 Error
*/
static int
check_insert_duplicate(char **vec,
@ -684,8 +682,8 @@ xml_yang_minmax_recurse(cxobj *xt,
nr=1;
/* new list check */
if (ret &&
keyw == Y_LIST &&
(ret = xml_yang_minmax_newlist(x, xt, y, xret)) < 0)
keyw == Y_LIST)
if ((ret = xml_yang_minmax_newlist(x, xt, y, xret)) < 0)
goto done;
if (ret == 0)
goto fail;

View file

@ -340,7 +340,7 @@ new "netconf get mandatory empty"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get-config><source><candidate/></source></get-config></rpc>" "" "<rpc-reply $DEFAULTNS><data><system xmlns=\"urn:example:config\"><mandatory/></system></data></rpc-reply>"
new "netconf validate mandatory"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</error-type><error-tag>data-missing</error-tag><error-app-tag>missing-choice</error-app-tag><error-info><missing-choice>name</missing-choice></error-info><error-severity>error</error-severity></rpc-error></rpc-reply>"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</error-type><error-tag>data-missing</error-tag><error-app-tag>missing-choice</error-app-tag><error-path>/system/mandatory</error-path><error-info><missing-choice xmlns=\"urn:ietf:params:xml:ns:yang:1\">name</missing-choice></error-info><error-severity>error</error-severity></rpc-error></rpc-reply>"
new "netconf set mandatory udp"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><system xmlns=\"urn:example:config\"><mandatory><udp/></mandatory></system></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"

View file

@ -151,7 +151,7 @@ new "restconf DELETE"
expectpart "$(curl $CURLOPTS -X DELETE $RCPROTO://localhost/restconf/data/example:cont1)" 0 "HTTP/$HVER 204"
new "restconf POST from top containing duplicate keys expect error"
expectpart "$(curl $CURLOPTS -X POST -H "Content-Type: application/yang-data+json" $RCPROTO://localhost/restconf/data -d '{"example:cont1":{"interface":[{"name":"TEST","type":"eth0"},{"name":"TEST","type":"eth0"}]}}')" 0 "HTTP/$HVER 412" '{"ietf-restconf:errors":{"error":{"error-type":"application","error-tag":"operation-failed","error-app-tag":"data-not-unique","error-severity":"error","error-info":{"non-unique":"name"}}}}'
expectpart "$(curl $CURLOPTS -X POST -H "Content-Type: application/yang-data+json" $RCPROTO://localhost/restconf/data -d '{"example:cont1":{"interface":[{"name":"TEST","type":"eth0"},{"name":"TEST","type":"eth0"}]}}')" 0 "HTTP/$HVER 412" '{"ietf-restconf:errors":{"error":{"error-type":"application","error-tag":"operation-failed","error-app-tag":"data-not-unique","error-severity":"error","error-info":{"non-unique":"/rpc/edit-config/config/cont1/interface\[name=\\"TEST\\"\]/name"}}}}'
new "restconf GET null datastore"
expectpart "$(curl $CURLOPTS -X GET $RCPROTO://localhost/restconf/data/example:cont1)" 0 "HTTP/$HVER 404" '{"ietf-restconf:errors":{"error":{"error-type":"application","error-tag":"invalid-value","error-severity":"error","error-message":"Instance does not exist"}}}'

View file

@ -301,13 +301,13 @@ expecteof_netconf "$clixon_netconf -qef $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS
fi
new "netconf edit-config empty target: should fail"
expecteof_netconf "$clixon_netconf -qef $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><target/><config/></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</error-type><error-tag>data-missing</error-tag><error-app-tag>missing-choice</error-app-tag><error-info><missing-choice>config-target</missing-choice></error-info><error-severity>error</error-severity></rpc-error></rpc-reply>"
expecteof_netconf "$clixon_netconf -qef $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><target/><config/></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</error-type><error-tag>data-missing</error-tag><error-app-tag>missing-choice</error-app-tag><error-path>/rpc/edit-config/target</error-path><error-info><missing-choice xmlns=\"urn:ietf:params:xml:ns:yang:1\">config-target</missing-choice></error-info><error-severity>error</error-severity></rpc-error></rpc-reply>"
new "netconf edit-config missing target: should fail"
expecteof_netconf "$clixon_netconf -qef $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><config/></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</error-type><error-tag>missing-element</error-tag><error-info><bad-element>target</bad-element></error-info><error-severity>error</error-severity><error-message>Mandatory variable of edit-config in module ietf-netconf</error-message></rpc-error></rpc-reply>"
new "netconf edit-config missing config: should fail"
expecteof_netconf "$clixon_netconf -qef $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><target><candidate/></target></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</error-type><error-tag>data-missing</error-tag><error-app-tag>missing-choice</error-app-tag><error-info><missing-choice>edit-content</missing-choice></error-info><error-severity>error</error-severity></rpc-error></rpc-reply>"
expecteof_netconf "$clixon_netconf -qef $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><target><candidate/></target></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</error-type><error-tag>data-missing</error-tag><error-app-tag>missing-choice</error-app-tag><error-path>/rpc/edit-config</error-path><error-info><missing-choice xmlns=\"urn:ietf:params:xml:ns:yang:1\">edit-content</missing-choice></error-info><error-severity>error</error-severity></rpc-error></rpc-reply>"
# Negative errors (namespace/module missing)
new "netconf wrong rpc namespace: should fail"
@ -320,7 +320,7 @@ expectpart "$(curl $CURLOPTS -X POST -H "Content-Type: application/yang-data+jso
LIST='<u0 xmlns="urn:example:clixon"><uk>foo</uk></u0><u0 xmlns="urn:example:clixon"><uk>bar</uk></u0><u0 xmlns="urn:example:clixon"><uk>bar</uk></u0>'
# On docker /fcgi the return is bar,foo,bar
new "netconf example rpc input list without key with non-unique entriesxxx"
new "netconf example rpc input list without key with non-unique entries"
rpc=$(chunked_framing "<rpc $DEFAULTNS><example xmlns=\"urn:example:clixon\"><x>mandatory</x>$LIST</example></rpc>")
ret=$($clixon_netconf -qef $cfg <<EOF
$DEFAULTHELLO$rpc
@ -349,7 +349,7 @@ expecteof_netconf "$clixon_netconf -qef $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS
LIST='<u1 xmlns="urn:example:clixon"><uk>bar</uk><val>1</val></u1><u1 xmlns="urn:example:clixon"><uk>bar</uk><val>2</val></u1>'
new "netconf example rpc input list with non-unique keys (should fail)"
expecteof_netconf "$clixon_netconf -qef $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><example xmlns=\"urn:example:clixon\"><x>mandatory</x>$LIST</example></rpc>" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</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>uk</non-unique></error-info></rpc-error></rpc-reply>"
expecteof_netconf "$clixon_netconf -qef $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><example xmlns=\"urn:example:clixon\"><x>mandatory</x>$LIST</example></rpc>" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</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 xmlns=\"urn:ietf:params:xml:ns:yang:1\">/rpc/example/u1[uk=\"bar\"]/uk</non-unique></error-info></rpc-error></rpc-reply>"
new "netconf choice ok"
expecteof_netconf "$clixon_netconf -qef $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><example xmlns=\"urn:example:clixon\"><x>42</x><a1>x</a1><a21>x</a21><a22>x</a22></example></rpc>" "" "<rpc-reply $DEFAULTNS><x xmlns=\"urn:example:clixon\">42</x><y xmlns=\"urn:example:clixon\">42</y><a1 xmlns=\"urn:example:clixon\">x</a1><a21 xmlns=\"urn:example:clixon\">x</a21><a22 xmlns=\"urn:example:clixon\">x</a22></rpc-reply>"

View file

@ -106,7 +106,7 @@ expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS>
<ip>192.0.2.1</ip>
<port>25</port>
</server>
</c></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</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</non-unique><non-unique>port</non-unique></error-info></rpc-error></rpc-reply>"
</c></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</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 xmlns=\"urn:ietf:params:xml:ns:yang:1\">/rpc/edit-config/config/c/server[name=\"http\"]/ip</non-unique><non-unique xmlns=\"urn:ietf:params:xml:ns:yang:1\">/rpc/edit-config/config/c/server[name=\"http\"]/port</non-unique></error-info></rpc-error></rpc-reply>"
new "Add valid example"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><default-operation>replace</default-operation><config><c xmlns=\"urn:example:clixon\"><server>
@ -132,7 +132,7 @@ expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS>
</c></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
new "netconf validate (should fail)"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</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</non-unique><non-unique>port</non-unique></error-info></rpc-error></rpc-reply>"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</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 xmlns=\"urn:ietf:params:xml:ns:yang:1\">/c/server[name=\"smtp\"]/ip</non-unique><non-unique xmlns=\"urn:ietf:params:xml:ns:yang:1\">/c/server[name=\"smtp\"]/port</non-unique></error-info></rpc-error></rpc-reply>"
new "make it valid by deleting port from smtp entry"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><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>
@ -160,8 +160,8 @@ expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS>
</single>
</c></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
new "netconf validate (should fail)"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</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</non-unique></error-info></rpc-error></rpc-reply>"
new "netconf validate (should fail) 2nd"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</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 xmlns=\"urn:ietf:params:xml:ns:yang:1\">/c/single[name=\"smtp\"]/ip</non-unique></error-info></rpc-error></rpc-reply>"
new "make valid by replacing IP of http entry"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><default-operation>none</default-operation><config><c xmlns=\"urn:example:clixon\"><single><name>http</name><ip>178.23.34.1</ip></single>
@ -201,8 +201,8 @@ expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS>
</server>
</c></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
new "netconf validate (should fail)"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</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</non-unique><non-unique>port</non-unique></error-info></rpc-error></rpc-reply>"
new "netconf validate (should fail) example3"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</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 xmlns=\"urn:ietf:params:xml:ns:yang:1\">/c/server[name=\"smtp\"]/ip</non-unique><non-unique xmlns=\"urn:ietf:params:xml:ns:yang:1\">/c/server[name=\"smtp\"]/port</non-unique></error-info></rpc-error></rpc-reply>"
new "netconf discard-changes"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><discard-changes/></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"

View file

@ -98,12 +98,12 @@ expecteof_netconf "$clixon_netconf -qef $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS
rpc="<rpc $DEFAULTNS><edit-config><target><candidate/></target><default-operation>replace</default-operation><config><outer xmlns=\"urn:example:clixon\"><name>x</name><c><inner><name>a</name><value>foo</value></inner><inner><name>b</name><value>foo</value></inner></c></outer><outer xmlns=\"urn:example:clixon\"><name>y</name><c><inner><name>a</name><value>fie</value></inner><inner><name>b</name><value>fum</value></inner></c></outer></config></edit-config></rpc>"
new "Add invalid example 1"
expecteof_netconf "$clixon_netconf -qef $cfg" 0 "$DEFAULTHELLO" "${rpc}" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</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>c/inner/value</non-unique></error-info></rpc-error></rpc-reply>"
expecteof_netconf "$clixon_netconf -qef $cfg" 0 "$DEFAULTHELLO" "${rpc}" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</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 xmlns=\"urn:ietf:params:xml:ns:yang:1\">/rpc/edit-config/config/outer[name=\"x\"]/c/inner/value</non-unique></error-info></rpc-error></rpc-reply>"
rpc="<rpc $DEFAULTNS><edit-config><target><candidate/></target><default-operation>replace</default-operation><config><outer xmlns=\"urn:example:clixon\"><name>x</name><c><inner><name>a</name><value>foo</value></inner><inner><name>b</name><value>bar</value></inner></c></outer><outer xmlns=\"urn:example:clixon\"><name>y</name><c><inner><name>a</name><value>fie</value></inner><inner><name>b</name><value>bar</value></inner></c></outer></config></edit-config></rpc>"
new "Add invalid example 2"
expecteof_netconf "$clixon_netconf -qef $cfg" 0 "$DEFAULTHELLO" "${rpc}" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</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>c/inner/value</non-unique></error-info></rpc-error></rpc-reply>"
expecteof_netconf "$clixon_netconf -qef $cfg" 0 "$DEFAULTHELLO" "${rpc}" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</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 xmlns=\"urn:ietf:params:xml:ns:yang:1\">/rpc/edit-config/config/outer[name=\"y\"]/c/inner/value</non-unique></error-info></rpc-error></rpc-reply>"
if [ $BE -ne 0 ]; then
new "Kill backend"