diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4127a252..848fdcb0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,13 +1,57 @@
# Clixon CHANGELOG
Major changes:
+- Changed top-level netconf get-config and get to return .. instead of ... to comply to the RFC.
+-- If you use direct netconf get or get-config calls, you may need to handle the return XML differently.
+-- RESTCONF and CLI is not affected.
+-- Example:
+--- new style: -->
+--- old style: -->
+
+
- Added support for yang presence and no-presence containers. Previous default was "presence".
+-- This means that empty containers will be removed unless you have used the "presence" yang declaration.
+-- Example YANG:
+```
+ container
+ nopresence {
+ leaf j {
+ type string;
+ }
+ }
+```
+If you submit "nopresence" without a leaf, it will automatically be removed:
+```
+ # removed
+ # not removed
+ hello
+
+```
-- Added YANG RPC support for nentconf and CLI. With example rpc documentation and testcase. This replaces the previous "downcall" mechanism.
+- Added YANG RPC support for netconf and CLI. With example rpc documentation and testcase. This replaces the previous "downcall" mechanism.
+-- This means you can make netconf rpc calls as defined by YANG.
+-- However you need to register an RPC backend callback using the backend_rpc_cb_register() function. See documentation and example for more details.
+-- Note that RESTCONF PUT for RCP calls is not yet supported.
+-- For example, the following yang rpc definition enables you to run a netconf rpc.
+```
+ YANG:
+ rpc myrpc {
+ input {
+ leaf name {
+ type string;
+ }
+ }
+ }
+ NETCONF:
+ hello
+```
-- Enhanced leafref functionality: (1) validation for leafref forward and backward references; (2)CLI completion for generated cli leafrefs for both absolute and relatve paths.
+- Enhanced leafref functionality: (1) validation for leafref forward and backward references; (2)CLI completion for generated cli leafrefs for both absolute and relative paths.
- Added state data: Netconf operation, new backend plugin callback: "plugin_statedata()" for retreiving state data.
+-- This means that you can use NETCONF and it will return both config and state data.
+-- It also means that RESTCONF GET will return state data also, if defined.
+-- However, you need to define state data in a backend callback. See the example and documentation for more details.
Minor changes:
- Removed 'margin' parameter of yang_print().
diff --git a/README.md b/README.md
index adb627dd..e15be22b 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,8 @@ Table of contents
Documentation
=============
-- [Frequently asked questions](doc/FAQ.md)
+- [Frequently asked questions](doc/FAQ.md
+- [CHANGELOG](CHANGELOG.md) recent changes.
- [XML datastore](datastore/README.md)
- [Netconf support](apps/netconf/README.md)
- [Restconf support](apps/restconf/README.md)
@@ -58,7 +59,7 @@ Licenses
Clixon is dual license. Either Apache License, Version 2.0 or GNU
General Public License Version 2. You choose.
-See [LICENSE.md](LICENSE.md) for license, [CHANGELOG](CHANGELOG.md) for recent changes.
+See [LICENSE.md](LICENSE.md) for license.
Background
==========
diff --git a/apps/backend/backend_client.c b/apps/backend/backend_client.c
index 9b7728bf..7ecd2508 100644
--- a/apps/backend/backend_client.c
+++ b/apps/backend/backend_client.c
@@ -241,11 +241,16 @@ from_client_get_config(clicon_handle h,
"");
goto ok;
}
- cprintf(cbret, "");
- if (xret!=NULL &&
- clicon_xml2cbuf(cbret, xret, 0, 0) < 0)
+ cprintf(cbret, "");
+ if (xret==NULL)
+ cprintf(cbret, "");
+ else{
+ if (xml_name_set(xret, "data") < 0)
goto done;
- cprintf(cbret, "");
+ if (clicon_xml2cbuf(cbret, xret, 0, 0) < 0)
+ goto done;
+ }
+ cprintf(cbret, "");
ok:
retval = 0;
done:
@@ -288,17 +293,16 @@ from_client_get(clicon_handle h,
assert(xret);
if (backend_statedata_call(h, selector, xret) < 0)
goto done;
- cprintf(cbret, "");
- /* if empty only */
- if (xret!=NULL){
- if (xml_child_nr(xret)){
- if (xml_name_set(xret, "config") < 0)
- goto done;
- if (clicon_xml2cbuf(cbret, xret, 0, 0) < 0)
- goto done;
- }
+ cprintf(cbret, "");
+ if (xret==NULL)
+ cprintf(cbret, "");
+ else{
+ if (xml_name_set(xret, "data") < 0)
+ goto done;
+ if (clicon_xml2cbuf(cbret, xret, 0, 0) < 0)
+ goto done;
}
- cprintf(cbret, "");
+ cprintf(cbret, "");
ok:
retval = 0;
done:
diff --git a/apps/netconf/netconf_rpc.c b/apps/netconf/netconf_rpc.c
index 56fd81bf..773afb85 100644
--- a/apps/netconf/netconf_rpc.c
+++ b/apps/netconf/netconf_rpc.c
@@ -159,7 +159,7 @@ netconf_get_config(clicon_handle h,
goto done;
if (xfilter &&
(xfilterconf = xpath_first(xfilter, "//configuration"))!= NULL &&
- (xconf = xpath_first(*xret, "/rpc-reply/data/configuration")) != NULL){
+ (xconf = xpath_first(*xret, "/rpc-reply/data")) != NULL){
/* xml_filter removes parts of xml tree not matching */
if ((strcmp(xml_name(xfilterconf), xml_name(xconf))!=0) ||
xml_filter(xfilterconf, xconf) < 0){
@@ -571,7 +571,7 @@ netconf_get(clicon_handle h,
goto done;
if (xfilter &&
(xfilterconf = xpath_first(xfilter, "//configuration"))!= NULL &&
- (xconf = xpath_first(*xret, "/rpc-reply/data/configuration")) != NULL){
+ (xconf = xpath_first(*xret, "/rpc-reply/data")) != NULL){
/* xml_filter removes parts of xml tree not matching */
if ((strcmp(xml_name(xfilterconf), xml_name(xconf))!=0) ||
xml_filter(xfilterconf, xconf) < 0){
diff --git a/lib/src/clixon_proto_client.c b/lib/src/clixon_proto_client.c
index 9c111676..d98f9620 100644
--- a/lib/src/clixon_proto_client.c
+++ b/lib/src/clixon_proto_client.c
@@ -272,8 +272,8 @@ clicon_rpc_get_config(clicon_handle h,
/* Send xml error back: first check error, then ok */
if ((xd = xpath_first(xret, "/rpc-reply/rpc-error")) != NULL)
xd = xml_parent(xd); /* point to rpc-reply */
- else if ((xd = xpath_first(xret, "/rpc-reply/data/config")) == NULL)
- if ((xd = xml_new("config", NULL)) == NULL)
+ else if ((xd = xpath_first(xret, "/rpc-reply/data")) == NULL)
+ if ((xd = xml_new("data", NULL)) == NULL)
goto done;
if (xt){
if (xml_rm(xd) < 0)
@@ -521,8 +521,8 @@ clicon_rpc_get(clicon_handle h,
/* Send xml error back: first check error, then ok */
if ((xd = xpath_first(xret, "/rpc-reply/rpc-error")) != NULL)
xd = xml_parent(xd); /* point to rpc-reply */
- else if ((xd = xpath_first(xret, "/rpc-reply/data/config")) == NULL)
- if ((xd = xml_new("config", NULL)) == NULL)
+ else if ((xd = xpath_first(xret, "/rpc-reply/data")) == NULL)
+ if ((xd = xml_new("data", NULL)) == NULL)
goto done;
if (xt){
if (xml_rm(xd) < 0)
diff --git a/test/test_leafref.sh b/test/test_leafref.sh
index 34389b7c..5a22c42a 100755
--- a/test/test_leafref.sh
+++ b/test/test_leafref.sh
@@ -64,7 +64,7 @@ new "leafref base config"
expecteof "$clixon_netconf -qf $clixon_cf -y /tmp/leafref" "eth0up192.0.2.1192.0.2.2loup127.0.0.1]]>]]>" "^]]>]]>$"
new "leafref get config"
-expecteof "$clixon_netconf -qf $clixon_cf" ']]>]]>' '^eth0'
+expecteof "$clixon_netconf -qf $clixon_cf" ']]>]]>' '^eth0'
new "leafref base commit"
expecteof "$clixon_netconf -qf $clixon_cf -y /tmp/leafref" "]]>]]>" "^]]>]]>$"
diff --git a/test/test_netconf.sh b/test/test_netconf.sh
index a3f9c0ef..0d5ff583 100755
--- a/test/test_netconf.sh
+++ b/test/test_netconf.sh
@@ -24,19 +24,19 @@ fi
new "netconf tests"
new "netconf get empty config"
-expecteof "$clixon_netconf -qf $clixon_cf" ']]>]]>' '^]]>]]>$'
+expecteof "$clixon_netconf -qf $clixon_cf" ']]>]]>' '^]]>]]>$'
new "Add subtree eth/0/0 using none which should not change anything"
expecteof "$clixon_netconf -qf $clixon_cf" "noneeth/0/0]]>]]>" "^]]>]]>$"
new "Check nothing added"
-expecteof "$clixon_netconf -qf $clixon_cf" ']]>]]>' '^]]>]]>$'
+expecteof "$clixon_netconf -qf $clixon_cf" ']]>]]>' '^]]>]]>$'
new "Add subtree eth/0/0 using none and create which should add eth/0/0"
expecteof "$clixon_netconf -qf $clixon_cf" 'eth/0/0ethnone]]>]]>' "^]]>]]>$"
new "Check eth/0/0 added using xpath"
-expecteof "$clixon_netconf -qf $clixon_cf" ']]>]]>' "^eth/0/0ethtrue]]>]]>$"
+expecteof "$clixon_netconf -qf $clixon_cf" ']]>]]>' "^eth/0/0ethtrue]]>]]>$"
new "Re-create same eth/0/0 which should generate error"
expecteof "$clixon_netconf -qf $clixon_cf" 'eth/0/0ethnone]]>]]>' "^"
@@ -45,7 +45,7 @@ new "Delete eth/0/0 using none config"
expecteof "$clixon_netconf -qf $clixon_cf" 'eth/0/0ethnone]]>]]>' "^]]>]]>$"
new "Check deleted eth/0/0 (non-presence container)"
-expecteof "$clixon_netconf -qf $clixon_cf" ']]>]]>' '^]]>]]>$'
+expecteof "$clixon_netconf -qf $clixon_cf" ']]>]]>' '^]]>]]>$'
new "Re-Delete eth/0/0 using none should generate error"
expecteof "$clixon_netconf -qf $clixon_cf" 'eth/0/0ethnone]]>]]>' "^"
@@ -54,10 +54,10 @@ new "netconf edit config"
expecteof "$clixon_netconf -qf $clixon_cf" "eth/0/0eth1true9.2.3.424]]>]]>" "^]]>]]>$"
new "netconf get config xpath"
-expecteof "$clixon_netconf -qf $clixon_cf" ']]>]]>' "^eth1true]]>]]>$"
+expecteof "$clixon_netconf -qf $clixon_cf" ']]>]]>' "^eth1true]]>]]>$"
new "netconf get config xpath parent"
-expecteof "$clixon_netconf -qf $clixon_cf" ']]>]]>' "^eth/0/0trueeth1truetruefalse9.2.3.424]]>]]>$"
+expecteof "$clixon_netconf -qf $clixon_cf" ']]>]]>' "^eth/0/0trueeth1truetruefalse9.2.3.424]]>]]>$"
new "netconf validate missing type"
expecteof "$clixon_netconf -qf $clixon_cf" "]]>]]>" "^"
@@ -66,7 +66,7 @@ new "netconf discard-changes"
expecteof "$clixon_netconf -qf $clixon_cf" "]]>]]>" "^]]>]]>$"
new "netconf get empty config2"
-expecteof "$clixon_netconf -qf $clixon_cf" "]]>]]>" "^]]>]]>$"
+expecteof "$clixon_netconf -qf $clixon_cf" "]]>]]>" "^]]>]]>$"
new "netconf edit config eth1"
expecteof "$clixon_netconf -qf $clixon_cf" "eth1eth]]>]]>" "^]]>]]>$"
@@ -81,7 +81,7 @@ new "netconf edit config replace"
expecteof "$clixon_netconf -qf $clixon_cf" "eth2ethmerge]]>]]>" "^]]>]]>$"
new "netconf get replaced config"
-expecteof "$clixon_netconf -qf $clixon_cf" "]]>]]>" "^eth1ethtrueeth2ethtrue]]>]]>$"
+expecteof "$clixon_netconf -qf $clixon_cf" "]]>]]>" "^eth1ethtrueeth2ethtrue]]>]]>$"
new "netconf discard-changes"
expecteof "$clixon_netconf -qf $clixon_cf" "]]>]]>" "^]]>]]>$"
@@ -111,13 +111,13 @@ new "copy startup"
expecteof "$clixon_netconf -qf $clixon_cf" "]]>]]>" "^]]>]]>$"
new "netconf get startup"
-expecteof "$clixon_netconf -qf $clixon_cf" "]]>]]>" "^eth1ethtrue]]>]]>$"
+expecteof "$clixon_netconf -qf $clixon_cf" "]]>]]>" "^eth1ethtrue]]>]]>$"
new "netconf delete startup"
expecteof "$clixon_netconf -qf $clixon_cf" "]]>]]>" "^]]>]]>$"
new "netconf check empty startup"
-expecteof "$clixon_netconf -qf $clixon_cf" "]]>]]>" "^]]>]]>$"
+expecteof "$clixon_netconf -qf $clixon_cf" "]]>]]>" "^]]>]]>$"
new "netconf rpc"
expecteof "$clixon_netconf -qf $clixon_cf" "ipv4ipv4]]>]]>" "^ipv4"
diff --git a/test/test_yang.sh b/test/test_yang.sh
index e01c09b2..784dd6f4 100755
--- a/test/test_yang.sh
+++ b/test/test_yang.sh
@@ -78,19 +78,19 @@ new "netconf commit"
expecteof "$clixon_netconf -qf $clixon_cf -y /tmp/test" "]]>]]>" "^]]>]]>$"
new "netconf get config xpath"
-expecteof "$clixon_netconf -qf $clixon_cf -y /tmp/test" "]]>]]>" "^125]]>]]>$"
+expecteof "$clixon_netconf -qf $clixon_cf -y /tmp/test" "]]>]]>" "^125]]>]]>$"
new "netconf edit leaf-list"
expecteof "$clixon_netconf -qf $clixon_cf -y /tmp/test" "hejhopp]]>]]>" "^]]>]]>$"
new "netconf get leaf-list"
-expecteof "$clixon_netconf -qf $clixon_cf -y /tmp/test" "]]>]]>" "^hejhopp]]>]]>$"
+expecteof "$clixon_netconf -qf $clixon_cf -y /tmp/test" "]]>]]>" "^hejhopp]]>]]>$"
new "netconf get leaf-list path"
-expecteof "$clixon_netconf -qf $clixon_cf -y /tmp/test" "]]>]]>" "^hejhopp]]>]]>$"
+expecteof "$clixon_netconf -qf $clixon_cf -y /tmp/test" "]]>]]>" "^hejhopp]]>]]>$"
new "netconf get (should be some)"
-expecteof "$clixon_netconf -qf $clixon_cf -y /tmp/test" "]]>]]>" "^125]]>]]>$"
+expecteof "$clixon_netconf -qf $clixon_cf -y /tmp/test" "]]>]]>" "^125]]>]]>$"
new "cli set leaf-list"
expectfn "$clixon_cli -1f $clixon_cf -y /tmp/test set x f e foo" ""
@@ -104,7 +104,7 @@ new "netconf set presence and not present"
expecteof "$clixon_netconf -qf $clixon_cf -y /tmp/test" "]]>]]>" "^]]>]]>$"
new "netconf get"
-expecteof "$clixon_netconf -qf $clixon_cf -y /tmp/test" "]]>]]>" "^]]>]]>$"
+expecteof "$clixon_netconf -qf $clixon_cf -y /tmp/test" "]]>]]>" "^]]>]]>$"
new "Kill backend"
# Check if still alive