Fixed three-key list entry problem (reported by jdl@netgate)
This commit is contained in:
parent
835674bbe0
commit
cce76faa79
3 changed files with 56 additions and 19 deletions
|
|
@ -37,6 +37,7 @@ enables saved files to be used as datastore without any editing. Thanks Matt.
|
||||||
* Added cli_show_version()
|
* Added cli_show_version()
|
||||||
|
|
||||||
### Corrected Bugs
|
### Corrected Bugs
|
||||||
|
* Fixed three-key list entry problem (reported by jdl@netgate)
|
||||||
* Translate xml->json \n correctly
|
* Translate xml->json \n correctly
|
||||||
* Fix issue: https://github.com/clicon/clixon/issues/15 Replace whole config
|
* Fix issue: https://github.com/clicon/clixon/issues/15 Replace whole config
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -167,7 +167,7 @@ xml_cmp(const void* arg1,
|
||||||
return equal;
|
return equal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*! Compare xml object
|
||||||
* @param[in] yangi Yang order
|
* @param[in] yangi Yang order
|
||||||
* @param[in] keynr Length of keyvec/keyval vector when applicable
|
* @param[in] keynr Length of keyvec/keyval vector when applicable
|
||||||
* @param[in] keyvec Array of of yang key identifiers
|
* @param[in] keyvec Array of of yang key identifiers
|
||||||
|
|
@ -192,36 +192,38 @@ xml_cmp1(cxobj *x,
|
||||||
int i;
|
int i;
|
||||||
char *keyname;
|
char *keyname;
|
||||||
char *key;
|
char *key;
|
||||||
|
int match = 0;
|
||||||
|
|
||||||
/* Check if same yang spec (order in yang stmt list) */
|
/* Check if same yang spec (order in yang stmt list) */
|
||||||
switch (keyword){
|
switch (keyword){
|
||||||
case Y_CONTAINER: /* Match with name */
|
case Y_CONTAINER: /* Match with name */
|
||||||
case Y_LEAF: /* Match with name */
|
case Y_LEAF: /* Match with name */
|
||||||
return strcmp(name, xml_name(x));
|
match = strcmp(name, xml_name(x));
|
||||||
break;
|
break;
|
||||||
case Y_LEAF_LIST: /* Match with name and value */
|
case Y_LEAF_LIST: /* Match with name and value */
|
||||||
if (userorder && yang_find((yang_node*)y, Y_ORDERED_BY, "user") != NULL)
|
if (userorder && yang_find((yang_node*)y, Y_ORDERED_BY, "user") != NULL)
|
||||||
*userorder=1;
|
*userorder=1;
|
||||||
b=xml_body(x);
|
b=xml_body(x);
|
||||||
return strcmp(keyval[0], b);
|
match = strcmp(keyval[0], b);
|
||||||
break;
|
break;
|
||||||
case Y_LIST: /* Match with array of key values */
|
case Y_LIST: /* Match with array of key values */
|
||||||
if (userorder && yang_find((yang_node*)y, Y_ORDERED_BY, "user") != NULL)
|
if (userorder && yang_find((yang_node*)y, Y_ORDERED_BY, "user") != NULL)
|
||||||
*userorder=1;
|
*userorder=1;
|
||||||
|
/* All must match */
|
||||||
for (i=0; i<keynr; i++){
|
for (i=0; i<keynr; i++){
|
||||||
keyname = keyvec[i];
|
keyname = keyvec[i];
|
||||||
key = keyval[i];
|
key = keyval[i];
|
||||||
/* Eg return "e0" in <if><name>e0</name></name></if> given "name" */
|
/* Eg return "e0" in <if><name>e0</name></name></if> given "name" */
|
||||||
if ((b = xml_find_body(x, keyname)) == NULL)
|
if ((b = xml_find_body(x, keyname)) == NULL)
|
||||||
break; /* error case */
|
break; /* error case */
|
||||||
return strcmp(key, b);
|
if ((match = strcmp(key, b)) != 0)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0; /* should not reach here */
|
return match; /* should not reach here */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Sort children of an XML node
|
/*! Sort children of an XML node
|
||||||
|
|
@ -522,7 +524,7 @@ xml_sort_verify(cxobj *x0,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Given child tree x1c, find matching child in base tree x0
|
/*! Given child tree x1c, find matching child in base tree x0 and return as x0cp
|
||||||
* param[in] x0 Base tree node
|
* param[in] x0 Base tree node
|
||||||
* param[in] x1c Modification tree child
|
* param[in] x1c Modification tree child
|
||||||
* param[in] yc Yang spec of tree child
|
* param[in] yc Yang spec of tree child
|
||||||
|
|
@ -567,7 +569,10 @@ match_base_child(cxobj *x0,
|
||||||
break;
|
break;
|
||||||
case Y_LIST: /* Match with key values */
|
case Y_LIST: /* Match with key values */
|
||||||
cvk = yc->ys_cvec; /* Use Y_LIST cache, see ys_populate_list() */
|
cvk = yc->ys_cvec; /* Use Y_LIST cache, see ys_populate_list() */
|
||||||
/* Count number of key indexes */
|
/* Count number of key indexes
|
||||||
|
* Then create two vectors one with names and one with values of x1c,
|
||||||
|
* ec: keyvec: [a,b,c] keyval: [1,2,3]
|
||||||
|
*/
|
||||||
cvi = NULL; keynr = 0;
|
cvi = NULL; keynr = 0;
|
||||||
while ((cvi = cvec_each(cvk, cvi)) != NULL)
|
while ((cvi = cvec_each(cvk, cvi)) != NULL)
|
||||||
keynr++;
|
keynr++;
|
||||||
|
|
@ -591,7 +596,7 @@ match_base_child(cxobj *x0,
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Get match */
|
/* Get match. Sorting mode(optimized) or not?*/
|
||||||
if (xml_child_sort==0)
|
if (xml_child_sort==0)
|
||||||
*x0cp = xml_match(x0, xml_name(x1c), yc->ys_keyword, keynr, keyvec, keyval);
|
*x0cp = xml_match(x0, xml_name(x1c), yc->ys_keyword, keynr, keyvec, keyval);
|
||||||
else{
|
else{
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ module example{
|
||||||
ex:c-define "MY_INTERFACES";
|
ex:c-define "MY_INTERFACES";
|
||||||
container x {
|
container x {
|
||||||
list y {
|
list y {
|
||||||
key "a b";
|
key "a b c";
|
||||||
leaf a {
|
leaf a {
|
||||||
type string;
|
type string;
|
||||||
}
|
}
|
||||||
|
|
@ -44,6 +44,9 @@ module example{
|
||||||
leaf c {
|
leaf c {
|
||||||
type string;
|
type string;
|
||||||
}
|
}
|
||||||
|
leaf val {
|
||||||
|
type string;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
leaf d {
|
leaf d {
|
||||||
type empty;
|
type empty;
|
||||||
|
|
@ -115,7 +118,7 @@ new "cli not defined extension"
|
||||||
#expectfn "$clixon_cli -1f $cfg -y $fyangerr show version" "Yang error: Extension ex:not-defined not found"
|
#expectfn "$clixon_cli -1f $cfg -y $fyangerr show version" "Yang error: Extension ex:not-defined not found"
|
||||||
|
|
||||||
new "netconf edit config"
|
new "netconf edit config"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><x><y><a>1</a><b>2</b><c>5</c></y><d/></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><x><y><a>1</a><b>2</b><c>5</c><val>one</val></y><d/></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf commit"
|
new "netconf commit"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
@ -125,7 +128,7 @@ new "netconf commit 2nd"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get config xpath"
|
new "netconf get config xpath"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><get-config><source><candidate/></source><filter type=\"xpath\" select=\"/x/y[a=1][b=2]\"/></get-config></rpc>]]>]]>" "^<rpc-reply><data><x><y><a>1</a><b>2</b><c>5</c></y></x></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><get-config><source><candidate/></source><filter type=\"xpath\" select=\"/x/y[a=1][b=2][c=5]\"/></get-config></rpc>]]>]]>" "^<rpc-reply><data><x><y><a>1</a><b>2</b><c>5</c><val>one</val></y></x></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf edit leaf-list"
|
new "netconf edit leaf-list"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><x><f><e>hej</e><e>hopp</e></f></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><x><f><e>hej</e><e>hopp</e></f></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
@ -137,7 +140,7 @@ new "netconf get leaf-list path"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><get-config><source><candidate/></source><filter type=\"xpath\" select=\"/x/f[e=hej]\"/></get-config></rpc>]]>]]>" "^<rpc-reply><data><x><f><e>hej</e><e>hopp</e></f></x></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><get-config><source><candidate/></source><filter type=\"xpath\" select=\"/x/f[e=hej]\"/></get-config></rpc>]]>]]>" "^<rpc-reply><data><x><f><e>hej</e><e>hopp</e></f></x></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf get (should be some)"
|
new "netconf get (should be some)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><get><filter type=\"xpath\" select=\"/\"/></get></rpc>]]>]]>" "^<rpc-reply><data><x><y><a>1</a><b>2</b><c>5</c></y><d/></x></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><get><filter type=\"xpath\" select=\"/\"/></get></rpc>]]>]]>" "^<rpc-reply><data><x><y><a>1</a><b>2</b><c>5</c><val>one</val></y><d/></x></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "cli set leaf-list"
|
new "cli set leaf-list"
|
||||||
expectfn "$clixon_cli -1f $cfg -y $fyang set x f e foo" ""
|
expectfn "$clixon_cli -1f $cfg -y $fyang set x f e foo" ""
|
||||||
|
|
@ -162,6 +165,34 @@ expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candi
|
||||||
new "netconf validate anyxml"
|
new "netconf validate anyxml"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
new "netconf delete candidate"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg" "<rpc><delete-config><target><candidate/></target></delete-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
# Check 3-keys
|
||||||
|
new "netconf add one 3-key entry"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><x><y><a>1</a><b>1</b><c>1</c><val>one</val></y></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
new "netconf check add one 3-key"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '<rpc-reply><data><x><y><a>1</a><b>1</b><c>1</c><val>one</val></y></x></data></rpc-reply>]]>]]>'
|
||||||
|
|
||||||
|
new "netconf add another (with same 1st key)"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><x><y><a>1</a><b>2</b><c>1</c><val>two</val></y></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
new "netconf check add another"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '<rpc-reply><data><x><y><a>1</a><b>1</b><c>1</c><val>one</val></y><y><a>1</a><b>2</b><c>1</c><val>two</val></y></x></data></rpc-reply>]]>]]>'
|
||||||
|
|
||||||
|
new "netconf replace first"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><x><y><a>1</a><b>1</b><c>1</c><val>replace</val></y></x></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
new "netconf check replace"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '<rpc-reply><data><x><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"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" '<rpc><edit-config><target><candidate/></target><config><x><y 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"
|
||||||
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '<rpc-reply><data><x><y><a>1</a><b>2</b><c>1</c><val>two</val></y></x></data></rpc-reply>]]>]]>'
|
||||||
|
|
||||||
# Check if still alive
|
# Check if still alive
|
||||||
pid=`pgrep clixon_backend`
|
pid=`pgrep clixon_backend`
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue