From 47889a9b0ac34eacf45926ebafd4da79def2b536 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Wed, 15 May 2019 18:35:28 +0200 Subject: [PATCH] Check restconf PUT different keys for leaf-list --- apps/restconf/restconf_methods.c | 52 ++++++++++++++++++++++++-------- test/test_restconf_listkey.sh | 21 +++++++++---- 2 files changed, 55 insertions(+), 18 deletions(-) diff --git a/apps/restconf/restconf_methods.c b/apps/restconf/restconf_methods.c index a84aae4a..d6b5bfc4 100644 --- a/apps/restconf/restconf_methods.c +++ b/apps/restconf/restconf_methods.c @@ -665,22 +665,35 @@ match_list_keys(yang_stmt *y, char *keya; char *keyd; - if (yang_keyword_get(y) != Y_LIST && yang_keyword_get(y) != Y_LEAF_LIST) - goto done; - cvk = yang_cvec_get(y); /* Use Y_LIST cache, see ys_populate_list() */ - cvi = NULL; - while ((cvi = cvec_each(cvk, cvi)) != NULL) { - keyname = cv_string_get(cvi); - if ((xkeya = xml_find(xapipath, keyname)) == NULL) + clicon_debug(1, "%s", __FUNCTION__); + switch (yang_keyword_get(y)){ + case Y_LIST: + cvk = yang_cvec_get(y); /* Use Y_LIST cache, see ys_populate_list() */ + cvi = NULL; + while ((cvi = cvec_each(cvk, cvi)) != NULL) { + keyname = cv_string_get(cvi); + if ((xkeya = xml_find(xapipath, keyname)) == NULL) + goto done; /* No key in api-path */ + if ((keya = xml_body(xkeya)) == NULL) + goto done; + if ((xkeyd = xml_find(xdata, keyname)) == NULL) + goto done; /* No key in data */ + if ((keyd = xml_body(xkeyd)) == NULL) + goto done; + if (strcmp(keya, keyd) != 0) + goto done; /* keys dont match */ + } + break; + case Y_LEAF_LIST: + if ((keya = xml_body(xapipath)) == NULL) goto done; /* No key in api-path */ - if ((keya = xml_body(xkeya)) == NULL) - goto done; - if ((xkeyd = xml_find(xdata, keyname)) == NULL) + if ((keyd = xml_body(xdata)) == NULL) goto done; /* No key in data */ - if ((keyd = xml_body(xkeyd)) == NULL) - goto done; if (strcmp(keya, keyd) != 0) goto done; /* keys dont match */ + break; + default: + goto done; } retval = 0; done: @@ -878,6 +891,21 @@ api_data_put(clicon_handle h, * That is why the conditional is somewhat hairy */ xparent = xml_parent(xbot); +#if 1 + if (debug){ + cbuf *ccc=cbuf_new(); + if (clicon_xml2cbuf(ccc, xtop, 0, 0) < 0) + goto done; + clicon_debug(1, "%s AAA XPATH:%s", __FUNCTION__, cbuf_get(ccc)); + } + if (debug){ + cbuf *ccc=cbuf_new(); + if (clicon_xml2cbuf(ccc, xdata, 0, 0) < 0) + goto done; + clicon_debug(1, "%s DATA:%s", __FUNCTION__, cbuf_get(ccc)); + } +#endif + if (y){ yp = yang_parent_get(y); if (((yang_keyword_get(y) == Y_LIST || yang_keyword_get(y) == Y_LEAF_LIST) && diff --git a/test/test_restconf_listkey.sh b/test/test_restconf_listkey.sh index 9759e6e6..473ac4a9 100755 --- a/test/test_restconf_listkey.sh +++ b/test/test_restconf_listkey.sh @@ -1,5 +1,6 @@ #!/bin/bash -# Testcases for lists, key operations for netconf and restconf +# Testcases for Restconf list and leaf-list keys, check matching keys for RFC8040 4.5: +# the key values must match in URL and data # Magic line must be first in script (see README.md) s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi @@ -39,6 +40,9 @@ module list{ type string; } } + leaf-list d{ + type string; + } } } EOF @@ -65,18 +69,23 @@ new "waiting" wait_backend wait_restconf -new "restconf PUT add entry" +new "restconf PUT add list entry" expectfn 'curl -s -X PUT http://localhost/restconf/data/list:c/a=x -d {"list:a":{"b":"x","c":"0"}}' 0 '' -new "restconf PUT change regular entry" +new "restconf PUT change regular list entry" expectfn 'curl -s -X PUT http://localhost/restconf/data/list:c/a=x -d {"list:a":{"b":"x","c":"z"}}' 0 '' -new "restconf PUT change key entry" +new "restconf PUT change list key entry (expect fail)" expectfn 'curl -s -X PUT http://localhost/restconf/data/list:c/a=x -d {"list:a":{"b":"y"}}' 0 '{"ietf-restconf:errors" : {"error": {"error-type": "protocol","error-tag": "operation-failed","error-severity": "error","error-message": "api-path keys do not match data keys"}}}' -new "restconf PUT change actual key entry" +new "restconf PUT change actual list key entry (expect fail)" expectfn 'curl -s -X PUT http://localhost/restconf/data/list:c/a=x/b -d {"b":"y"}' 0 '{"ietf-restconf:errors" : {"error": {"error-type": "protocol","error-tag": "operation-failed","error-severity": "error","error-message": "api-path keys do not match data keys"}}}' -exit + +new "restconf PUT add leaf-list entry" +expectfn 'curl -s -X PUT http://localhost/restconf/data/list:c/d=x -d {"list:d":"x"}' 0 '' + +new "restconf PUT change leaf-list entry (expect fail)" +expectfn 'curl -s -X PUT http://localhost/restconf/data/list:c/d=x -d {"list:d":"y"}' 0 '{"ietf-restconf:errors" : {"error": {"error-type": "protocol","error-tag": "operation-failed","error-severity": "error","error-message": "api-path keys do not match data keys"}}}' new "Kill restconf daemon" stop_restconf