diff --git a/CHANGELOG.md b/CHANGELOG.md
index 82ba6372..588c5e10 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -94,6 +94,7 @@
* For backward compatibility, define CLICON_CLI_MODEL_TREENAME_PATCH in clixon_custom.h
### Minor changes
+* Added new clixon-lib yang module for internal netconf protocol. Currently only extends the standard with a debug RPC.
* Added three-valued return values for several validate functions where -1 is fatal error, 0 is validation failed and 1 is validation OK.
* This includes: `xmldb_put`, `xml_yang_validate_all`, `xml_yang_validate_add`, `xml_yang_validate_rpc`, `api_path2xml`, `api_path2xpath`
* Added new xml functions for specific types: `xml_child_nr_notype`, `xml_child_nr_notype`, `xml_child_i_type`, `xml_find_type`.
diff --git a/apps/backend/backend_main.c b/apps/backend/backend_main.c
index 8e05c175..6fbb8750 100644
--- a/apps/backend/backend_main.c
+++ b/apps/backend/backend_main.c
@@ -805,6 +805,9 @@ main(int argc,
if ((str = clicon_yang_main_dir(h)) != NULL)
if (yang_spec_load_dir(h, str, yspec) < 0)
goto done;
+ /* Load clixon lib yang module */
+ if (yang_spec_parse_module(h, "clixon-lib", NULL, yspec) < 0)
+ goto done;
/* Load yang module library, RFC7895 */
if (yang_modules_init(h) < 0)
goto done;
diff --git a/apps/cli/cli_main.c b/apps/cli/cli_main.c
index e6d7925a..ce994fee 100644
--- a/apps/cli/cli_main.c
+++ b/apps/cli/cli_main.c
@@ -446,6 +446,9 @@ main(int argc, char **argv)
if (yang_spec_load_dir(h, str, yspec) < 0)
goto done;
}
+ /* Load clixon lib yang module */
+ if (yang_spec_parse_module(h, "clixon-lib", NULL, yspec) < 0)
+ goto done;
/* Load yang module library, RFC7895 */
if (yang_modules_init(h) < 0)
diff --git a/apps/netconf/netconf_main.c b/apps/netconf/netconf_main.c
index e60a5d08..eadbcc1b 100644
--- a/apps/netconf/netconf_main.c
+++ b/apps/netconf/netconf_main.c
@@ -468,7 +468,9 @@ main(int argc,
if (yang_spec_load_dir(h, str, yspec) < 0)
goto done;
}
-
+ /* Load clixon lib yang module */
+ if (yang_spec_parse_module(h, "clixon-lib", NULL, yspec) < 0)
+ goto done;
/* Load yang module library, RFC7895 */
if (yang_modules_init(h) < 0)
goto done;
diff --git a/apps/restconf/restconf_main.c b/apps/restconf/restconf_main.c
index e6234884..0819c7cb 100644
--- a/apps/restconf/restconf_main.c
+++ b/apps/restconf/restconf_main.c
@@ -645,7 +645,9 @@ main(int argc,
if (yang_spec_load_dir(h, str, yspec) < 0)
goto done;
}
-
+ /* Load clixon lib yang module */
+ if (yang_spec_parse_module(h, "clixon-lib", NULL, yspec) < 0)
+ goto done;
/* Load yang module library, RFC7895 */
if (yang_modules_init(h) < 0)
goto done;
diff --git a/apps/restconf/restconf_methods.c b/apps/restconf/restconf_methods.c
index 8f3cb4a5..58980589 100644
--- a/apps/restconf/restconf_methods.c
+++ b/apps/restconf/restconf_methods.c
@@ -1132,27 +1132,23 @@ api_operations_get(clicon_handle h,
if (use_xml)
cprintf(cbx, "");
else
- cprintf(cbx, "{\"operations\": ");
+ cprintf(cbx, "{\"operations\": {");
ymod = NULL;
+ i = 0;
while ((ymod = yn_each((yang_node*)yspec, ymod)) != NULL) {
namespace = yang_find_mynamespace(ymod);
- yc = NULL; i=0;
+ yc = NULL;
while ((yc = yn_each((yang_node*)ymod, yc)) != NULL) {
if (yc->ys_keyword != Y_RPC)
continue;
if (use_xml)
cprintf(cbx, "<%s xmlns=\"%s\"/>", yc->ys_argument, namespace);
else{
- if (i==0)
- cprintf(cbx, "{");
- if (i)
+ if (i++)
cprintf(cbx, ",");
cprintf(cbx, "\"%s:%s\": null", ymod->ys_argument, yc->ys_argument);
}
- i++;
}
- if (!use_xml && i)
- cprintf(cbx, "}");
}
if (use_xml)
cprintf(cbx, "");
diff --git a/example/example.yang b/example/example.yang
index 749b10ff..f5e82063 100644
--- a/example/example.yang
+++ b/example/example.yang
@@ -128,13 +128,4 @@ module example {
}
}
}
- rpc debug {
- description "Set debug level of backend. XXX should be in clixon-config";
- input {
- leaf level {
- type uint32;
- }
- }
- }
-
}
diff --git a/lib/src/clixon_proto_client.c b/lib/src/clixon_proto_client.c
index 0dbb76d1..b454b608 100644
--- a/lib/src/clixon_proto_client.c
+++ b/lib/src/clixon_proto_client.c
@@ -827,7 +827,7 @@ clicon_rpc_debug(clicon_handle h,
username = clicon_username_get(h);
/* XXX: hardcoded example yang, should be clixon-config!!! */
- if ((msg = clicon_msg_encode("%d", username?username:"", level)) == NULL)
+ if ((msg = clicon_msg_encode("%d", username?username:"", level)) == NULL)
goto done;
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
goto done;
diff --git a/test/test_install.sh b/test/test_install.sh
index 032bba4a..09867c42 100755
--- a/test/test_install.sh
+++ b/test/test_install.sh
@@ -12,19 +12,23 @@ if [ $? -ne 0 ]; then
err
fi
-new "Check installed files"
+new "Check installed files /usr"
if [ ! -d $dir/usr ]; then
err $dir/usr
fi
+new "Check installed files /www-data"
if [ ! -d $dir/www-data ]; then
err $dir/www-data
fi
+new "Check installed files clixon-config"
if [ ! -f $dir/usr/local/share/clixon/clixon-config* ]; then
err $dir/usr/local/share/clixon/clixon-config*
fi
+new "Check installed files libclixon.so"
if [ ! -h $dir/usr/local/lib/libclixon.so ]; then
err $dir/usr/local/lib/libclixon.so
fi
+new "Check installed files libclixon_backend.so"
if [ ! -h $dir/usr/local/lib/libclixon_backend.so ]; then
err $dir/usr/local/lib/libclixon_backend.so
fi
diff --git a/test/test_restconf.sh b/test/test_restconf.sh
index e7451d0a..2a1fd961 100755
--- a/test/test_restconf.sh
+++ b/test/test_restconf.sh
@@ -118,12 +118,12 @@ expecteq "$(curl -s -H 'Accept: application/yang-data+xml' -G http://localhost/r
# Should be alphabetically ordered
new2 "restconf get restconf/operations. RFC8040 3.3.2 (json)"
-expecteq "$(curl -sG http://localhost/restconf/operations)" '{"operations": {"example:empty": null,"example:client-rpc": null}{"ietf-routing:fib-route": null,"ietf-routing:route-count": null}}
+expecteq "$(curl -sG http://localhost/restconf/operations)" '{"operations": {"example:empty": null,"example:client-rpc": null,"ietf-routing:fib-route": null,"ietf-routing:route-count": null,"clixon-lib:debug": null}
'
new "restconf get restconf/operations. RFC8040 3.3.2 (xml)"
ret=$(curl -s -H "Accept: application/yang-data+xml" -G http://localhost/restconf/operations)
-expect=''
+expect=''
match=`echo $ret | grep -EZo "$expect"`
if [ -z "$match" ]; then
err "$expect" "$ret"
diff --git a/yang/Makefile.in b/yang/Makefile.in
index fb32b74d..a1d0be57 100644
--- a/yang/Makefile.in
+++ b/yang/Makefile.in
@@ -41,10 +41,12 @@ datarootdir = @datarootdir@
CLIXON_DATADIR = @CLIXON_DATADIR@
YANGSPECS = clixon-config@2018-10-21.yang
+YANGSPECS += clixon-lib@2019-01-02.yang
YANGSPECS += ietf-netconf@2011-06-01.yang
YANGSPECS += ietf-netconf-acm@2018-02-14.yang
YANGSPECS += ietf-inet-types@2013-07-15.yang
YANGSPECS += ietf-yang-types@2013-07-15.yang
+YANGSPECS += ietf-restconf@2017-01-26.yang
YANGSPECS += ietf-restconf-monitoring@2017-01-26.yang
YANGSPECS += ietf-netconf-notification@2008-07-01.yang
YANGSPECS += ietf-yang-library@2016-06-21.yang
diff --git a/yang/clixon-config@2018-10-21.yang b/yang/clixon-config@2018-10-21.yang
index efa777e3..a9ad7414 100644
--- a/yang/clixon-config@2018-10-21.yang
+++ b/yang/clixon-config@2018-10-21.yang
@@ -1,6 +1,6 @@
module clixon-config {
yang-version 1.1;
- namespace "http://clicon.org";
+ namespace "http://clicon.org/config";
prefix cc;
organization
@@ -455,12 +455,4 @@ module clixon-config {
}
}
- rpc debug {
- description "Set debug level of backend.";
- input {
- leaf level {
- type uint32;
- }
- }
- }
}
diff --git a/yang/clixon-lib@2019-01-02.yang b/yang/clixon-lib@2019-01-02.yang
new file mode 100644
index 00000000..1e26187b
--- /dev/null
+++ b/yang/clixon-lib@2019-01-02.yang
@@ -0,0 +1,55 @@
+module clixon-lib {
+ yang-version 1.1;
+ namespace "http://clicon.org/lib";
+ prefix cl;
+
+ organization
+ "Clicon / Clixon";
+
+ contact
+ "Olof Hagsand ";
+
+ description
+ "Clixon Netconf extensions for communication between clients and backend.
+
+ ***** BEGIN LICENSE BLOCK *****
+ Copyright (C) 2009-2019 Olof Hagsand and Benny Holmgren
+
+ This file is part of CLIXON
+
+ Licensed under the Apache License, Version 2.0 (the \"License\");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an \"AS IS\" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ Alternatively, the contents of this file may be used under the terms of
+ the GNU General Public License Version 3 or later (the \"GPL\"),
+ in which case the provisions of the GPL are applicable instead
+ of those above. If you wish to allow use of your version of this file only
+ under the terms of the GPL, and not to allow others to
+ use your version of this file under the terms of Apache License version 2,
+ indicate your decision by deleting the provisions above and replace them with
+ the notice and other provisions required by the GPL. If you do not delete
+ the provisions above, a recipient may use your version of this file under
+ the terms of any one of the Apache License version 2 or the GPL.
+
+ ***** END LICENSE BLOCK *****";
+
+ revision 2019-01-02 {
+ description
+ "Released in Clixon 3.9";
+ }
+ rpc debug {
+ description "Set debug level of backend.";
+ input {
+ leaf level {
+ type uint32;
+ }
+ }
+ }
+}
diff --git a/yang/ietf-restconf@2017-01-26.yang b/yang/ietf-restconf@2017-01-26.yang
new file mode 100644
index 00000000..249006af
--- /dev/null
+++ b/yang/ietf-restconf@2017-01-26.yang
@@ -0,0 +1,279 @@
+module ietf-restconf {
+ yang-version 1.1;
+ namespace "urn:ietf:params:xml:ns:yang:ietf-restconf";
+ prefix "rc";
+
+ organization
+ "IETF NETCONF (Network Configuration) Working Group";
+
+ contact
+ "WG Web:
+ WG List:
+
+ Author: Andy Bierman
+
+
+ Author: Martin Bjorklund
+
+
+ Author: Kent Watsen
+ ";
+
+ description
+ "This module contains conceptual YANG specifications
+ for basic RESTCONF media type definitions used in
+ RESTCONF protocol messages.
+
+ Note that the YANG definitions within this module do not
+ represent configuration data of any kind.
+ The 'restconf-media-type' YANG extension statement
+ provides a normative syntax for XML and JSON
+ message-encoding purposes.
+
+ Copyright (c) 2017 IETF Trust and the persons identified as
+ authors of the code. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or
+ without modification, is permitted pursuant to, and subject
+ to the license terms contained in, the Simplified BSD License
+ set forth in Section 4.c of the IETF Trust's Legal Provisions
+ Relating to IETF Documents
+ (http://trustee.ietf.org/license-info).
+
+ This version of this YANG module is part of RFC 8040; see
+ the RFC itself for full legal notices.";
+
+ revision 2017-01-26 {
+ description
+ "Initial revision.";
+ reference
+ "RFC 8040: RESTCONF Protocol.";
+ }
+
+ extension yang-data {
+ argument name {
+ yin-element true;
+ }
+ description
+ "This extension is used to specify a YANG data template that
+ represents conceptual data defined in YANG. It is
+ intended to describe hierarchical data independent of
+ protocol context or specific message-encoding format.
+ Data definition statements within a yang-data extension
+ specify the generic syntax for the specific YANG data
+ template, whose name is the argument of the 'yang-data'
+ extension statement.
+
+ Note that this extension does not define a media type.
+ A specification using this extension MUST specify the
+ message-encoding rules, including the content media type.
+
+ The mandatory 'name' parameter value identifies the YANG
+ data template that is being defined. It contains the
+ template name.
+
+ This extension is ignored unless it appears as a top-level
+ statement. It MUST contain data definition statements
+ that result in exactly one container data node definition.
+ An instance of a YANG data template can thus be translated
+ into an XML instance document, whose top-level element
+ corresponds to the top-level container.
+
+ The module name and namespace values for the YANG module using
+ the extension statement are assigned to instance document data
+ conforming to the data definition statements within
+ this extension.
+
+ The substatements of this extension MUST follow the
+ 'data-def-stmt' rule in the YANG ABNF.
+
+ The XPath document root is the extension statement itself,
+ such that the child nodes of the document root are
+ represented by the data-def-stmt substatements within
+ this extension. This conceptual document is the context
+ for the following YANG statements:
+
+ - must-stmt
+ - when-stmt
+ - path-stmt
+ - min-elements-stmt
+ - max-elements-stmt
+ - mandatory-stmt
+ - unique-stmt
+ - ordered-by
+ - instance-identifier data type
+
+ The following data-def-stmt substatements are constrained
+ when used within a 'yang-data' extension statement.
+
+ - The list-stmt is not required to have a key-stmt defined.
+ - The if-feature-stmt is ignored if present.
+ - The config-stmt is ignored if present.
+ - The available identity values for any 'identityref'
+ leaf or leaf-list nodes are limited to the module
+ containing this extension statement and the modules
+ imported into that module.
+ ";
+ }
+
+ rc:yang-data yang-errors {
+ uses errors;
+ }
+
+ rc:yang-data yang-api {
+ uses restconf;
+ }
+
+ grouping errors {
+ description
+ "A grouping that contains a YANG container
+ representing the syntax and semantics of a
+ YANG Patch error report within a response message.";
+
+ container errors {
+ description
+ "Represents an error report returned by the server if
+ a request results in an error.";
+
+ list error {
+ description
+ "An entry containing information about one
+ specific error that occurred while processing
+ a RESTCONF request.";
+ reference
+ "RFC 6241, Section 4.3.";
+
+ leaf error-type {
+ type enumeration {
+ enum transport {
+ description
+ "The transport layer.";
+ }
+ enum rpc {
+ description
+ "The rpc or notification layer.";
+ }
+ enum protocol {
+ description
+ "The protocol operation layer.";
+ }
+ enum application {
+ description
+ "The server application layer.";
+ }
+ }
+ mandatory true;
+ description
+ "The protocol layer where the error occurred.";
+ }
+
+ leaf error-tag {
+ type string;
+ mandatory true;
+ description
+ "The enumerated error-tag.";
+ }
+
+ leaf error-app-tag {
+ type string;
+ description
+ "The application-specific error-tag.";
+ }
+
+ leaf error-path {
+ type instance-identifier;
+ description
+ "The YANG instance identifier associated
+ with the error node.";
+ }
+
+ leaf error-message {
+ type string;
+ description
+ "A message describing the error.";
+ }
+
+ anydata error-info {
+ description
+ "This anydata value MUST represent a container with
+ zero or more data nodes representing additional
+ error information.";
+ }
+ }
+ }
+ }
+
+ grouping restconf {
+ description
+ "Conceptual grouping representing the RESTCONF
+ root resource.";
+
+ container restconf {
+ description
+ "Conceptual container representing the RESTCONF
+ root resource.";
+ container data {
+ description
+ "Container representing the datastore resource.
+ Represents the conceptual root of all state data
+ and configuration data supported by the server.
+ The child nodes of this container can be any data
+ resources that are defined as top-level data nodes
+ from the YANG modules advertised by the server in
+ the 'ietf-yang-library' module.";
+ }
+
+ container operations {
+ description
+ "Container for all operation resources.
+
+ Each resource is represented as an empty leaf with the
+ name of the RPC operation from the YANG 'rpc' statement.
+
+ For example, the 'system-restart' RPC operation defined
+ in the 'ietf-system' module would be represented as
+ an empty leaf in the 'ietf-system' namespace. This is
+ a conceptual leaf and will not actually be found in
+ the module:
+
+ module ietf-system {
+ leaf system-reset {
+ type empty;
+ }
+ }
+
+ To invoke the 'system-restart' RPC operation:
+
+ POST /restconf/operations/ietf-system:system-restart
+
+ To discover the RPC operations supported by the server:
+
+ GET /restconf/operations
+
+ In XML, the YANG module namespace identifies the module:
+
+
+
+ In JSON, the YANG module name identifies the module:
+
+ { 'ietf-system:system-restart' : [null] }
+ ";
+ }
+
+ leaf yang-library-version {
+ type string {
+ pattern '\d{4}-\d{2}-\d{2}';
+ }
+ config false;
+ mandatory true;
+ description
+ "Identifies the revision date of the 'ietf-yang-library'
+ module that is implemented by this RESTCONF server.
+ Indicates the year, month, and day in YYYY-MM-DD
+ numeric format.";
+ }
+ }
+ }
+
+}