* New yang changelog experimental feature for automatic upgrade

* Added modules-state diff parameter to xmldb_get datastore function for startup scenarios.
* Allowed Yang extended Xpath functions (syntax only):
  * re-match, deref, derived-from, derived-from-or-self, enum-value, bit-is-set
* XSD regular expression handling of dash(`-`)
  *: Translate XDS `[xxx\-yyy]` to POSIX `[xxxyyy-]`.
* YANG Anydata treated same as Anyxml
This commit is contained in:
Olof hagsand 2019-03-21 17:42:53 +01:00
parent 434f0b930e
commit 3f68cca06c
37 changed files with 1475 additions and 351 deletions

View file

@ -90,6 +90,7 @@
#include <clixon/clixon_json.h>
#include <clixon/clixon_netconf_lib.h>
#include <clixon/clixon_nacm.h>
#include <clixon/clixon_yang_changelog.h>
/*
* Global variables generated by Makefile

View file

@ -206,8 +206,12 @@ int clicon_startup_status_set(clicon_handle h, enum startup_status status);
int clicon_socket_get(clicon_handle h);
int clicon_socket_set(clicon_handle h, int s);
/*! Set and set module state cache */
/*! Set and get module state cache */
cxobj *clicon_module_state_get(clicon_handle h);
int clicon_module_state_set(clicon_handle h, cxobj *xms);
/*! Set and get module revision changelog */
cxobj *clicon_yang_changelog_get(clicon_handle h);
int clicon_yang_changelog_set(clicon_handle h, cxobj *xchlog);
#endif /* _CLIXON_OPTIONS_H_ */

View file

@ -65,6 +65,30 @@ typedef int (*clicon_rpc_cb)(
cbuf *cbret,
void *arg,
void *regarg
);
/*! Registered Upgrade callback function
* @param[in] h Clicon handle
* @param[in] xn XML tree to be updated
* @param[in] modname Name of module
* @param[in] modns Namespace of module (for info)
* @param[in] from From revision on the form YYYYMMDD
* @param[in] to To revision on the form YYYYMMDD (0 not in system)
* @param[in] arg User argument given at rpc_callback_register()
* @param[out] cbret Return xml tree, eg <rpc-reply>..., <rpc-error..
* @retval 1 OK
* @retval 0 Invalid
* @retval -1 Error
*/
typedef int (*clicon_upgrade_cb)(
clicon_handle h,
cxobj *xn,
char *modname,
char *modns,
uint32_t from,
uint32_t to,
void *arg,
cbuf *cbret
);
/*
@ -128,14 +152,6 @@ enum startup_status{
STARTUP_OK /* Everything OK (may still be modules-mismatch) */
};
/*! Upgrade configuration callback given a diff of yang module state
* @param[in] h Clicon handle
* @param[in] xms XML tree of module state differences
* @retval 0 OK
* @retval -1 Error
*/
typedef int (upgrade_cb_t)(clicon_handle, cxobj *xms);
/* plugin init struct for the api
* Note: Implicit init function
*/
@ -162,7 +178,6 @@ struct clixon_plugin_api{
struct { /* backend-specific */
plgreset_t *cb_reset; /* Reset system status */
plgstatedata_t *cb_statedata; /* Get state data from plugin (backend only) */
upgrade_cb_t *cb_upgrade; /* Upgrade callback */
trans_cb_t *cb_trans_begin; /* Transaction start */
trans_cb_t *cb_trans_validate; /* Transaction validation */
trans_cb_t *cb_trans_complete; /* Transaction validation complete */
@ -181,7 +196,6 @@ struct clixon_plugin_api{
#define ca_auth u.cau_restconf.cr_auth
#define ca_reset u.cau_backend.cb_reset
#define ca_statedata u.cau_backend.cb_statedata
#define ca_upgrade u.cau_backend.cb_upgrade
#define ca_trans_begin u.cau_backend.cb_trans_begin
#define ca_trans_validate u.cau_backend.cb_trans_validate
#define ca_trans_complete u.cau_backend.cb_trans_complete
@ -228,9 +242,12 @@ int clixon_plugin_auth(clicon_handle h, void *arg);
/* rpc callback API */
int rpc_callback_register(clicon_handle h, clicon_rpc_cb cb, void *arg, char *namespace, char *name);
int rpc_callback_delete_all(void);
int rpc_callback_call(clicon_handle h, cxobj *xe, cbuf *cbret, void *arg);
/* upgrade callback API */
int upgrade_callback_register(clicon_handle h, clicon_upgrade_cb cb, void *arg, char *name, char *namespace, uint32_t from, uint32_t to);
int upgrade_callback_delete_all(void);
int upgrade_callback_call(clicon_handle h, cxobj *xt, char *modname, char *modns, uint32_t from, uint32_t to, cbuf *cbret);
#endif /* _CLIXON_PLUGIN_H_ */

View file

@ -75,7 +75,7 @@ typedef int (xmldb_getopt_t)(xmldb_handle xh, char *optname, void **value);
typedef int (xmldb_setopt_t)(xmldb_handle xh, char *optname, void *value);
/* Type of xmldb get function */
typedef int (xmldb_get_t)(xmldb_handle xh, const char *db, char *xpath, int config, cxobj **xtop, cxobj **xmodst);
typedef int (xmldb_get_t)(xmldb_handle xh, const char *db, char *xpath, int config, cxobj **xtop, modstate_diff_t *msd);
/* Type of xmldb put function */
typedef int (xmldb_put_t)(xmldb_handle xh, const char *db, enum operation_type op, cxobj *xt, char *username, cbuf *cbret);
@ -138,7 +138,7 @@ int xmldb_connect(clicon_handle h);
int xmldb_disconnect(clicon_handle h);
int xmldb_getopt(clicon_handle h, char *optname, void **value);
int xmldb_setopt(clicon_handle h, char *optname, void *value);
int xmldb_get(clicon_handle h, const char *db, char *xpath, int config, cxobj **xtop, cxobj **xmodst);
int xmldb_get(clicon_handle h, const char *db, char *xpath, int config, cxobj **xtop, modstate_diff_t *msd);
int xmldb_put(clicon_handle h, const char *db, enum operation_type op, cxobj *xt, char *username, cbuf *cbret);
int xmldb_copy(clicon_handle h, const char *from, const char *to);
int xmldb_lock(clicon_handle h, const char *db, int pid);

View file

@ -150,7 +150,7 @@ typedef enum yang_class yang_class;
* data tree. One of container, leaf, leaf-list, list, anydata, and
* anyxml.
*/
#define yang_datanode(y) ((y)->ys_keyword == Y_CONTAINER || (y)->ys_keyword == Y_LEAF || (y)->ys_keyword == Y_LIST || (y)->ys_keyword == Y_LEAF_LIST || (y)->ys_keyword == Y_ANYXML)
#define yang_datanode(y) ((y)->ys_keyword == Y_CONTAINER || (y)->ys_keyword == Y_LEAF || (y)->ys_keyword == Y_LIST || (y)->ys_keyword == Y_LEAF_LIST || (y)->ys_keyword == Y_ANYXML || (y)->ys_keyword == Y_ANYDATA)
/* Yang data definition statement
* See RFC 7950 Sec 3:
@ -283,6 +283,8 @@ int yang_abs_schema_nodeid(yang_spec *yspec, yang_stmt *ys,
enum rfc_6020 keyword, yang_stmt **yres);
int yang_desc_schema_nodeid(yang_node *yn, char *schema_nodeid,
enum rfc_6020 keyword, yang_stmt **yres);
int ys_parse_date_arg(char *datearg, uint32_t *dateint);
cg_var *ys_parse(yang_stmt *ys, enum cv_type cvtype);
int ys_parse_sub(yang_stmt *ys, char *extra);
int yang_mandatory(yang_stmt *ys);

View file

@ -0,0 +1,46 @@
/*
*
***** BEGIN LICENSE BLOCK *****
Copyright (C) 2009-2019 Olof Hagsand
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 *****
* YANG module revision change management.
* See draft-wang-netmod-module-revision-management-01
*/
#ifndef _CLIXON_YANG_CHANGELOG_H
#define _CLIXON_YANG_CHANGELOG_H
/*
* Prototypes
*/
int yang_changelog_upgrade(clicon_handle h, cxobj *xn, char *modname, char *modns, uint32_t from, uint32_t to, void *arg, cbuf *cbret);
int clixon_yang_changelog_init(clicon_handle h);
#endif /* _CLIXON_YANG_CHANGELOG_H */

View file

@ -46,15 +46,26 @@
* Types
*/
/* Struct contataining module state differences between two modules or two
* revisions of same module.
* This is in state of flux so it needss to be conatained and easily changed.
*/
typedef struct {
cxobj *md_del; /* yang mdoule state deletes */
cxobj *md_mod; /* yang mdoule state modifications */
} modstate_diff_t;
/*
* Prototypes
*/
modstate_diff_t * modstate_diff_new(void);
int modstate_diff_free(modstate_diff_t *);
int modules_state_cache_set(clicon_handle h, cxobj *msx);
int yang_modules_init(clicon_handle h);
char *yang_modules_revision(clicon_handle h);
int yang_modules_state_get(clicon_handle h, yang_spec *yspec, char *xpath,
int brief, cxobj **xret);
int clixon_module_upgrade(clicon_handle h, cxobj *xt, modstate_diff_t *msd, cbuf *cb);
#endif /* _CLIXON_YANG_MODULE_H_ */