From 2ef4a0f958a72342df926907488807c2be44cf0f Mon Sep 17 00:00:00 2001 From: Vasek Sraier Date: Wed, 11 Mar 2020 13:38:23 +0100 Subject: [PATCH] sysrepo-lua: validating results of operational data serialization --- modules/sysrepo-lua/cbindings/sysrepo_clib.c | 18 +++++++++++++++++- modules/sysrepo-lua/cbindings/sysrepo_clib.h | 4 ++++ modules/sysrepo-lua/ffi.lua.in | 4 ++++ modules/sysrepo-lua/model.lua | 15 ++++++++++++++- 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/modules/sysrepo-lua/cbindings/sysrepo_clib.c b/modules/sysrepo-lua/cbindings/sysrepo_clib.c index 2adf8dd13..1f9141a68 100644 --- a/modules/sysrepo-lua/cbindings/sysrepo_clib.c +++ b/modules/sysrepo-lua/cbindings/sysrepo_clib.c @@ -42,6 +42,7 @@ static apply_conf_f apply_conf = NULL; static read_conf_f read_conf = NULL; static el_subscription_ctx_t *el_subscription_ctx = NULL; static const struct lys_node* lys_root = NULL; +static const struct ly_ctx* ly_context = NULL; /** * Change callback getting called by sysrepo. Iterates over changed options and passes @@ -182,7 +183,8 @@ int sysrepo_init(apply_conf_f apply_conf_callback, read_conf_f read_conf_callbac goto cleanup; /* obtain schema root node, will be used from within Lua */ - const struct ly_ctx* ly_context = sr_get_context(sr_connection); + ly_context = sr_get_context(sr_connection); + assert(ly_context != NULL); lys_root = ly_ctx_get_node(ly_context, NULL, XPATH_BASE, 0); assert(lys_root != NULL); @@ -264,10 +266,12 @@ KR_EXPORT struct lyd_node* node_new_container(struct lyd_node* parent, const str return lyd_new(parent, module, name); } KR_EXPORT const struct lys_module* schema_get_module(const struct lys_node* schema) { + assert(schema != NULL); return schema->module; } KR_EXPORT const struct lys_node* schema_child_first(const struct lys_node* parent) { + assert(parent != NULL); assert( parent->nodetype == LYS_CONTAINER || parent->nodetype == LYS_LIST || @@ -278,10 +282,12 @@ KR_EXPORT const struct lys_node* schema_child_first(const struct lys_node* paren } KR_EXPORT const struct lys_node* schema_child_next(const struct lys_node* prev_child) { + assert(prev_child != NULL); return prev_child->next; } KR_EXPORT const char* schema_get_name(const struct lys_node* node) { + assert(node != NULL); return node->name; } @@ -289,3 +295,13 @@ KR_EXPORT const struct lys_node* schema_root() { assert(lys_root != NULL); return lys_root; } + +KR_EXPORT int node_validate(struct lyd_node* node) { + assert(node != NULL); + assert(ly_context != NULL); + return lyd_validate(&node, LYD_OPT_DATA | LYD_OPT_STRICT, (void*) ly_context); +} + +KR_EXPORT void node_free(struct lyd_node* node) { + lyd_free_withsiblings(node); +} diff --git a/modules/sysrepo-lua/cbindings/sysrepo_clib.h b/modules/sysrepo-lua/cbindings/sysrepo_clib.h index 634481ed5..9305c659d 100644 --- a/modules/sysrepo-lua/cbindings/sysrepo_clib.h +++ b/modules/sysrepo-lua/cbindings/sysrepo_clib.h @@ -72,3 +72,7 @@ KR_EXPORT const struct lys_node* schema_child_next(const struct lys_node* prev_c KR_EXPORT const char* schema_get_name(const struct lys_node* node); /** Get schema root */ KR_EXPORT const struct lys_node* schema_root(); +/** Validate data tree */ +KR_EXPORT int node_validate(struct lyd_node* node); +/** Free data nodes recursively */ +KR_EXPORT void node_free(struct lyd_node* node); diff --git a/modules/sysrepo-lua/ffi.lua.in b/modules/sysrepo-lua/ffi.lua.in index 146444b6f..a1c843eb7 100644 --- a/modules/sysrepo-lua/ffi.lua.in +++ b/modules/sysrepo-lua/ffi.lua.in @@ -43,6 +43,10 @@ local function initialize_ffi() const char* schema_get_name(const struct lys_node* node); /** Get schema root */ const struct lys_node* schema_root(); + /** Validate data tree */ + int node_validate(struct lyd_node* node); + /** Free data nodes recursively */ + void node_free(struct lyd_node* node); ]] end diff --git a/modules/sysrepo-lua/model.lua b/modules/sysrepo-lua/model.lua index 479218931..52b38460d 100644 --- a/modules/sysrepo-lua/model.lua +++ b/modules/sysrepo-lua/model.lua @@ -174,7 +174,20 @@ return function(clib_binding) local module = {} function module.serialize_configuration(root_node) init_schema() - model:serialize(root_node) + + -- serialize operational data + local node = model:serialize(root_node) + assert(node ~= nil) + + -- validate the result + local validation_result = clib().node_validate(node) + if validation_result ~= 0 then + clib().node_free(node) + print("Tree validation failed, see printed libyang errors") + node = nil + end + + return node end function module.apply_configuration(root_node) -- 2.47.2