Skip to content

Commit

Permalink
* More precise Yang validation and better error messages
Browse files Browse the repository at this point in the history
   * For Example, adding bad-, missing-, or unknown-element error messages, etc instead of operation-failed
* Removed delete-config support for candidate db since it is not supported in RFC6241.
* Switched the order of `error-type` and `error-tag` in all netconf and restconf error messages to comply to RFC order.
* Added example_rpc RPC to example backend
* Renamed xml_namespace[_set]() to xml_prefix[_set]()
* Some restconf error messages contained "rpc-reply" or "rpc-error" which have now been removed.
* Netconf/Restconf RPC extra input arguments are ignored (#47)
  • Loading branch information
olofhagsand committed Dec 21, 2018
1 parent 03e618b commit f872c7e
Show file tree
Hide file tree
Showing 45 changed files with 806 additions and 404 deletions.
15 changes: 11 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
* [Roadmap](ROADMAP.md) (Uncommitted and unprioritized)

### Major New features

* NACM extension (RFC8341)
* NACM module support (RFC8341 A1+A2)
* Recovery user "_nacm_recovery" added.
Expand All @@ -20,25 +19,29 @@
* Support of submodule, include and belongs-to.
* Openconfig yang specs parsed: https://github.com/openconfig/public
* Improved "unknown" handling
* More precise Yang validation and better error messages
* For Example, adding bad-, missing-, or unknown-element error messages, etc instead of operation-failed
* Yang load file configure options changed
* `CLICON_YANG_DIR` is changed from a single directory to a path of directories
* Note CLIXON_DATADIR (=/usr/local/share/clixon) need to be in the list
* CLICON_YANG_MAIN_FILE Provides a filename with a single module filename.
* CLICON_YANG_MAIN_DIR Provides a directory where all yang modules should be loaded.
* Correct XML namespace handling
* XML multiple modules was based on "loose" semantics so that yang modules were found by iterating thorugh namespaces until a match was made. This did not adhere to proper [XML namespace handling](https://www.w3.org/TR/2009/REC-xml-names-20091208), and causes problems with overlapping names and false positives. Below see XML accepted (but wrong), and correct namespace declaration:
```
```
<rpc><my-own-method></rpc> # Wrong but accepted
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> # Correct
<my-own-method xmlns="http://example.net/me/my-own/1.0">
</rpc>
```
```
* To keep old loose semantics set config option CLICON_XML_NS_ITERATE (true by default)
* XML to JSON translator support for mapping xmlns attribute to module name prefix.
* Default namespace is still "urn:ietf:params:xml:ns:netconf:base:1.0"
* See https://github.com/clicon/clixon/issues/49

### API changes on existing features (you may need to change your code)
* Removed delete-config support for candidate db since it is not supported in RFC6241.
* Switched the order of `error-type` and `error-tag` in all netconf and restconf error messages to comply to RFC order.
* Yang parser is stricter (see above) which may break parsing of existing yang specs.
* XML namespace handling is corrected (see above)
* For backward compatibility set config option CLICON_XML_NS_ITERATE
Expand All @@ -49,6 +52,8 @@
* For backward compatibility, define CLICON_CLI_MODEL_TREENAME_PATCH in clixon_custom.h

### Minor changes
* Added example_rpc RPC to example backend
* Renamed xml_namespace[_set]() to xml_prefix[_set]()
* Changed all make tags --> make TAGS
* Keyvalue datastore removed (it has been disabled since 3.3.3)
* Removed return value ymodp from yang parse functions (eg yang_parse()).
Expand All @@ -60,8 +65,10 @@
* <!DOCTYPE (ie DTD) is not supported.
### Corrected Bugs
* Some restconf error messages contained "rpc-reply" or "rpc-error" which have now been removed.
* getopt return value changed from char to int (https://github.com/clicon/clixon/issues/58)
* Netconf/Restconf RPC extra input arguments are ignored (https://github.com/clicon/clixon/issues/47)
### Known issues
* debug rpc added in example application (should be in clixon-config).
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,9 @@ However, the following YANG syntax modules are not implemented:
- belongs-to

Restrictions on Yang types are as follows:
- The range statement does not support multiple values (RFC7895 sec 9.2.4)
- The range statement does not support multiple values (RFC7950 9.2.4)
- Submodules cannot re-use a prefix in an import statement that is already used for another imported module in the module that the submodule belongs to. (see https://github.com/clicon/clixon/issues/60)
- default values on leaf-lists (RFC7950 7.7.2)

Netconf
=======
Expand Down
20 changes: 9 additions & 11 deletions ROADMAP.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,42 @@
# Clixon roadmap

In prio order

High prio
## High prio
- NACM (RFC 8341)
- Module rules
- Module rules (done)
- Data node rules (read/create/delete/update/execute)
- Special handling of the initial startup transaction to avoid exit at startup
- Possibly - draft-wu-netconf-restconf-factory-restore-03
- Handle revisions to data model.
- Possibly draft-wang-netmod-module-revision-management-01
- XML [Namespace handling](https://github.com/clicon/clixon/issues/49)

Medium prio:
- Input validation on custom RPCs/
## Medium prio:
- Input validation on custom RPCs/ (done)
- [Sanity checks](https://github.com/clicon/clixon/issues/47)
- Support for XML regex's.
- Currently Posix extended regular expressions
- Support a plugin callback that is invoked when copy-config is called.
- Preserve CLI command history across sessions. The up/down arrows

Low prio:
## Low prio:
- Provide a client library to access netconf APIs provided by system services.
- Netconf backend (Clixon acts as netconf controller)
- Support for restconf call-home (RFC 8071)
- Support for restconf PATCH method

Not prioritized:
- XML [Namespace handling](https://github.com/clicon/clixon/issues/49)
- Support for restconf PATCH method
- NETCONF
- Support for additional Netconf [edit-config modes](https://github.com/clicon/clixon/issues/53)
- Netconf [framing](https://github.com/clicon/clixon/issues/50)
- [Child ordering](https://github.com/clicon/clixon/issues/22)
- Netconf backend (Clixon acts as netconf controller)
- Restconf
- Query parameters
- Streams (netconf and restconf)
- Extend native stream mode with external persistent timeseries database, eg influxdb.
- Jenkins CI/CD and webhooks
- YANG
- RFC 6022 [NETCONF monitoring](https://github.com/clicon/clixon/issues/39)
- Deviation, belongs-to, min/max-elements, action, unique
- Deviation, min/max-elements, action, unique
- Containers
- [Docker improvements](https://github.com/clicon/clixon/issues/44)
- Kubernetes Helm chart definition
Expand Down
31 changes: 14 additions & 17 deletions apps/backend/backend_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -468,12 +468,12 @@ from_client_edit_config(clicon_handle h,
}
}
if ((xc = xpath_first(xn, "config")) == NULL){
if (netconf_missing_element(cbret, "protocol", "<bad-element>config</bad-element>", NULL) < 0)
if (netconf_missing_element(cbret, "protocol", "config", NULL) < 0)
goto done;
goto ok;
}
else{
/* <config> yang spec may be set to anyxml by ingress yang check,...*/
/* <config> yang spec may be set to anyxmly by ingress yang check,...*/
if (xml_spec(xc) != NULL)
xml_spec_set(xc, NULL);
/* Populate XML with Yang spec (why not do this in parser?)
Expand Down Expand Up @@ -530,7 +530,7 @@ from_client_lock(clicon_handle h,
cbuf *cbx = NULL; /* Assist cbuf */

if ((db = netconf_db_find(xe, "target")) == NULL){
if (netconf_missing_element(cbret, "protocol", "<bad-element>target</bad-element>", NULL) < 0)
if (netconf_missing_element(cbret, "protocol", "target", NULL) < 0)
goto done;
goto ok;
}
Expand Down Expand Up @@ -589,7 +589,7 @@ from_client_unlock(clicon_handle h,
cbuf *cbx = NULL; /* Assist cbuf */

if ((db = netconf_db_find(xe, "target")) == NULL){
if (netconf_missing_element(cbret, "protocol", "<bad-element>target</bad-element>", NULL) < 0)
if (netconf_missing_element(cbret, "protocol", "target", NULL) < 0)
goto done;
goto ok;
}
Expand Down Expand Up @@ -651,7 +651,7 @@ from_client_kill_session(clicon_handle h,

if ((x = xml_find(xe, "session-id")) == NULL ||
(str = xml_find_value(x, "body")) == NULL){
if (netconf_missing_element(cbret, "protocol", "<bad-element>session-id</bad-element>", NULL) < 0)
if (netconf_missing_element(cbret, "protocol", "session-id", NULL) < 0)
goto done;
goto ok;
}
Expand Down Expand Up @@ -709,7 +709,7 @@ from_client_copy_config(clicon_handle h,
cbuf *cbx = NULL; /* Assist cbuf */

if ((source = netconf_db_find(xe, "source")) == NULL){
if (netconf_missing_element(cbret, "protocol", "<bad-element>source</bad-element>", NULL) < 0)
if (netconf_missing_element(cbret, "protocol", "source", NULL) < 0)
goto done;
goto ok;
}
Expand All @@ -724,7 +724,7 @@ from_client_copy_config(clicon_handle h,
goto ok;
}
if ((target = netconf_db_find(xe, "target")) == NULL){
if (netconf_missing_element(cbret, "protocol", "<bad-element>target</bad-element>", NULL) < 0)
if (netconf_missing_element(cbret, "protocol", "target", NULL) < 0)
goto done;
goto ok;
}
Expand Down Expand Up @@ -777,7 +777,7 @@ from_client_delete_config(clicon_handle h,

if ((target = netconf_db_find(xe, "target")) == NULL||
strcmp(target, "running")==0){
if (netconf_missing_element(cbret, "protocol", "<bad-element>target</bad-element>", NULL) < 0)
if (netconf_missing_element(cbret, "protocol", "target", NULL) < 0)
goto done;
goto ok;
}
Expand Down Expand Up @@ -856,15 +856,15 @@ from_client_create_subscription(clicon_handle h,
if ((x = xpath_first(xe, "//stopTime")) != NULL){
if ((stoptime = xml_find_value(x, "body")) != NULL &&
str2time(stoptime, &stop) < 0){
if (netconf_bad_element(cbret, "application", "<bad-element>stopTime</bad-element>", "Expected timestamp") < 0)
if (netconf_bad_element(cbret, "application", "stopTime", "Expected timestamp") < 0)
goto done;
goto ok;
}
}
if ((x = xpath_first(xe, "//startTime")) != NULL){
if ((starttime = xml_find_value(x, "body")) != NULL &&
str2time(starttime, &start) < 0){
if (netconf_bad_element(cbret, "application", "<bad-element>startTime</bad-element>", "Expected timestamp") < 0)
if (netconf_bad_element(cbret, "application", "startTime", "Expected timestamp") < 0)
goto done;
goto ok;
}
Expand Down Expand Up @@ -925,7 +925,7 @@ from_client_debug(clicon_handle h,
char *valstr;

if ((valstr = xml_find_body(xe, "level")) == NULL){
if (netconf_missing_element(cbret, "application", "<bad-element>level</bad-element>", NULL) < 0)
if (netconf_missing_element(cbret, "application", "level", NULL) < 0)
goto done;
goto ok;
}
Expand Down Expand Up @@ -993,13 +993,10 @@ from_client_msg(clicon_handle h,
/* Populate incoming XML tree with yang */
if (xml_spec_populate_rpc(h, x, yspec) < 0)
goto done;
if ((ret = xml_yang_validate_rpc(x)) < 0)
if ((ret = xml_yang_validate_rpc(x, cbret)) < 0)
goto done;
if (ret == 0){
if (netconf_operation_failed(cbret, "application", "Validation failed")< 0)
goto done;
if (ret == 0)
goto reply;
}
xe = NULL;
username = xml_find_value(x, "username");
while ((xe = xml_child_each(x, xe, CX_ELMNT)) != NULL) {
Expand Down Expand Up @@ -1059,7 +1056,7 @@ from_client_msg(clicon_handle h,
}
else if (strcmp(rpc, "validate") == 0){
if ((db = netconf_db_find(xe, "source")) == NULL){
if (netconf_missing_element(cbret, "protocol", "<bad-element>source</bad-element>", NULL) < 0)
if (netconf_missing_element(cbret, "protocol", "source", NULL) < 0)
goto done;
goto reply;
}
Expand Down
Loading

0 comments on commit f872c7e

Please sign in to comment.