blob: ae6322f5962b436ced4273b6dda888349117a9b9 [file] [log] [blame]
/**
* @file parser_data.h
* @author Radek Krejci <rkrejci@cesnet.cz>
* @brief Data parsers for libyang
*
* Copyright (c) 2015-2020 CESNET, z.s.p.o.
*
* This source code is licensed under BSD 3-Clause License (the "License").
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*/
#ifndef LY_PARSER_DATA_H_
#define LY_PARSER_DATA_H_
#include "tree_data.h"
#ifdef __cplusplus
extern "C" {
#endif
struct ly_in;
/**
* @page howtoDataParsers Parsing Data
*
* Data parser allows to read instances from a specific format. libyang supports the following data formats:
*
* - XML
*
* Original data format used in NETCONF protocol. XML mapping is part of the YANG specification
* ([RFC 6020](http://tools.ietf.org/html/rfc6020)).
*
* - JSON
*
* The alternative data format available in RESTCONF protocol. Specification of JSON encoding of data modeled by YANG
* can be found in [RFC 7951](http://tools.ietf.org/html/rfc7951). The specification does not cover RPCs, actions and
* Notifications, so the representation of these data trees is proprietary and corresponds to the representation of these
* trees in XML.
*
* While the parsers themselves process the input data only syntactically, all the parser functions actually incorporate
* the [common validator](@ref howtoDataValidation) checking the input data semantically. Therefore, the parser functions
* accepts two groups of options - @ref dataparseroptions and @ref datavalidationoptions.
*
* In contrast to the schema parser, data parser also accepts empty input data if such an empty data tree is valid
* according to the schemas in the libyang context (i.e. there are no top level mandatory nodes).
*
* There are individual functions to process different types of the data instances trees:
* - ::lyd_parse_data() is intended for standard configuration data trees. According to the given
* [parser options](@ref dataparseroptions), the caller can further specify which kind of data tree is expected:
* - *complete :running datastore*: this is the default case, possibly with the use of (some of) the
* ::LYD_PARSE_STRICT, ::LYD_PARSE_OPAQ or ::LYD_VALIDATE_PRESENT options.
* - *complete configuration-only datastore* (such as :startup): in this case it is necessary to except all state data
* using ::LYD_PARSE_NO_STATE option.
* - *incomplete datastore*: there are situation when the data tree is incomplete or invalid by specification. For
* example the *:operational* datastore is not necessarily valid and results of the NETCONF's \<get\> or \<get-config\>
* oprations used with filters will be incomplete (and thus invalid). This can be allowed using ::LYD_PARSE_ONLY,
* the ::LYD_PARSE_NO_STATE should be used for the data returned by \<get-config\> operation.
* - ::lyd_parse_rpc() is used for parsing RPCs/Actions, optionally including the RPC envelopes known from the NETCONF
* protocol.
* - ::lyd_parse_reply() processes reply to a previous RPC/Action, which must be provided.
* - ::lyd_parse_notif() is able to process complete Notification message.
*
* Further information regarding the processing input instance data can be found on the following pages.
* - @subpage howtoDataValidation
* - @subpage howtoDataWD
*
* Functions List
* --------------
* - ::lyd_parse_data()
* - ::lyd_parse_data_mem()
* - ::lyd_parse_data_fd()
* - ::lyd_parse_data_path()
* - ::lyd_parse_rpc()
* - ::lyd_parse_reply()
* - ::lyd_parse_notif()
*/
/**
* @page howtoDataValidation Validating Data
*
* Data validation is performed implicitly to the input data processed by the [parser](@ref howtoDataParsers) and
* on demand via the lyd_validate_*() functions. The explicit validation process is supposed to be used when a (complex or
* simple) change is done on the data tree (via [data manipulation](@ref howtoDataManipulation) functions) and the data
* tree is expected to be valid (it doesn't make sense to validate modified result of filtered \<get\> operation).
*
* Similarly to the [data parser](@ref howtoDataParsers), there are individual functions to validate standard data tree
* (::lyd_validate_all()) and RPC, Action and Notification (::lyd_validate_op()). For the standard data trees, it is possible
* to modify the validation process by @ref datavalidationoptions. This way the state data can be prohibited
* (::LYD_VALIDATE_NO_STATE) and checking for mandatory nodes can be limited to the YANG modules with already present data
* instances (::LYD_VALIDATE_PRESENT). Validation of the standard data tree can be also limited with ::lyd_validate_module()
* function, which scopes only to a specified single YANG module.
*
* Since the operation data trees (RPCs, Actions or Notifications) can reference (leafref, instance-identifier, when/must
* expressions) data from a datastore tree, ::lyd_validate_op() may require additional data tree to be provided. This is a
* difference in contrast to the parsing process, when the data are loaded from an external source and invalid reference
* outside the operation tree is acceptable.
*
* Functions List
* --------------
* - ::lyd_validate_all()
* - ::lyd_validate_module()
* - ::lyd_validate_op()
*/
/**
* @addtogroup datatree
* @{
*/
/**
* @ingroup datatree
* @defgroup dataparseroptions Data parser options
*
* Various options to change the data tree parsers behavior.
*
* Default parser behavior:
* - complete input file is always parsed. In case of XML, even not well-formed XML document (multiple top-level
* elements) is parsed in its entirety,
* - parser silently ignores data without matching schema node definition,
* - list instances are checked whether they have all the keys, error is raised if not.
*
* Default parser validation behavior:
* - the provided data are expected to provide complete datastore content (both the configuration and state data)
* and performs data validation according to all YANG rules, specifics follow,
* - list instances are expected to have all the keys (it is not checked),
* - instantiated (status) obsolete data print a warning,
* - all types are fully resolved (leafref/instance-identifier targets, unions) and must be valid (lists have
* all the keys, leaf(-lists) correct values),
* - when statements on existing nodes are evaluated, if not satisfied, a validation error is raised,
* - if-feature statements are evaluated,
* - invalid multiple data instances/data from several cases cause a validation error,
* - implicit nodes (NP containers and default values) are added.
* @{
*/
/* note: keep the lower 16bits free for use by LYD_VALIDATE_ flags. They are not supposed to be combined together,
* but since they are used (as a separate parameter) together in some functions, we want to keep them in a separated
* range to be able detect that the caller put wrong flags into the parser/validate options parameter. */
#define LYD_PARSE_ONLY 0x010000 /**< Data will be only parsed and no validation will be performed. When statements
are kept unevaluated, union types may not be fully resolved, if-feature
statements are not checked, and default values are not added (only the ones
parsed are present). */
#define LYD_PARSE_TRUSTED 0x020000 /**< Data are considered trusted so they will be parsed as validated. If the parsed
data are not valid, using this flag may lead to some unexpected behavior!
This flag can be used only with #LYD_PARSE_ONLY. */
#define LYD_PARSE_STRICT 0x040000 /**< Instead of silently ignoring data without schema definition raise an error.
Do not combine with #LYD_PARSE_OPAQ (except for ::LYD_LYB). */
#define LYD_PARSE_OPAQ 0x080000 /**< Instead of silently ignoring data without definition, parse them into
an opaq node. Do not combine with #LYD_PARSE_STRICT (except for ::LYD_LYB). */
#define LYD_PARSE_NO_STATE 0x100000 /**< Forbid state data in the parsed data. */
#define LYD_PARSE_LYB_MOD_UPDATE 0x200000 /**< Only for LYB format, allow parsing data printed using a specific module
revision to be loaded even with a module with the same name but newer
revision. */
#define LYD_PARSE_OPTS_MASK 0xFFFF0000 /**< Mask for all the LYD_PARSE_ options. */
/** @} dataparseroptions */
/**
* @ingroup datatree
* @defgroup datavalidationoptions Data validation options
*
* Various options to change data validation behaviour, both for the parser and separate validation.
*
* Default separate validation behavior:
* - the provided data are expected to provide complete datastore content (both the configuration and state data)
* and performs data validation according to all YANG rules, specifics follow,
* - instantiated (status) obsolete data print a warning,
* - all types are fully resolved (leafref/instance-identifier targets, unions) and must be valid (lists have
* all the keys, leaf(-lists) correct values),
* - when statements on existing nodes are evaluated. Depending on the previous when state (from previous validation
* or parsing), the node is silently auto-deleted if the state changed from true to false, otherwise a validation error
* is raised if it evaluates to false,
* - if-feature statements are evaluated,
* - data from several cases behave based on their previous state (from previous validation or parsing). If there existed
* already a case and another one was added, the previous one is silently auto-deleted. Otherwise (if data from 2 or
* more cases were created) a validation error is raised,
* - default values are added.
*
* @{
*/
#define LYD_VALIDATE_NO_STATE 0x0001 /**< Consider state data not allowed and raise an error if they are found. */
#define LYD_VALIDATE_PRESENT 0x0002 /**< Validate only modules whose data actually exist. */
#define LYD_VALIDATE_OPTS_MASK 0x0000FFFF /**< Mask for all the LYD_VALIDATE_* options. */
/** @} datavalidationoptions */
/**
* @ingroup datatree
* @defgroup datavalidateop Operation to validate
*
* Operation provided to ::lyd_validate_op() to validate.
*
* The operation cannot be determined automatically since RPC/action and a reply to it share the common top level node
* referencing the RPC/action schema node and may not have any input/output children to use for distinction.
*
* @{
*/
typedef enum {
LYD_VALIDATE_OP_RPC = 1, /**< Validate RPC/action request (input parameters). */
LYD_VALIDATE_OP_REPLY, /**< Validate RPC/action reply (output parameters). */
LYD_VALIDATE_OP_NOTIF /**< Validate Notification operation. */
} LYD_VALIDATE_OP;
/** @} datavalidateop */
/**
* @brief Parse (and validate) data from the input handler as a YANG data tree.
*
* @param[in] ctx Context to connect with the tree being built here.
* @param[in] in The input handle to provide the dumped data in the specified @p format to parse (and validate).
* @param[in] format Format of the input data to be parsed. Can be 0 to try to detect format from the input handler.
* @param[in] parse_options Options for parser, see @ref dataparseroptions.
* @param[in] validate_options Options for the validation phase, see @ref datavalidationoptions.
* @param[out] tree Resulting data tree built from the input data. Note that NULL can be a valid result as a representation of an empty YANG data tree.
* The returned data are expected to be freed using ::lyd_free_all().
* @return LY_SUCCESS in case of successful parsing (and validation).
* @return LY_ERR value in case of error. Additional error information can be obtained from the context using ly_err* functions.
*/
LY_ERR lyd_parse_data(const struct ly_ctx *ctx, struct ly_in *in, LYD_FORMAT format, uint32_t parse_options,
uint32_t validate_options, struct lyd_node **tree);
/**
* @brief Parse (and validate) input data as a YANG data tree.
*
* Wrapper around ::lyd_parse_data() hiding work with the input handler.
*
* @param[in] ctx Context to connect with the tree being built here.
* @param[in] data The input data in the specified @p format to parse (and validate).
* @param[in] format Format of the input data to be parsed. Can be 0 to try to detect format from the input handler.
* @param[in] parse_options Options for parser, see @ref dataparseroptions.
* @param[in] validate_options Options for the validation phase, see @ref datavalidationoptions.
* @param[out] tree Resulting data tree built from the input data. Note that NULL can be a valid result as a representation of an empty YANG data tree.
* The returned data are expected to be freed using ::lyd_free_all().
* @return LY_SUCCESS in case of successful parsing (and validation).
* @return LY_ERR value in case of error. Additional error information can be obtained from the context using ly_err* functions.
*/
LY_ERR lyd_parse_data_mem(const struct ly_ctx *ctx, const char *data, LYD_FORMAT format, uint32_t parse_options,
uint32_t validate_options, struct lyd_node **tree);
/**
* @brief Parse (and validate) input data as a YANG data tree.
*
* Wrapper around ::lyd_parse_data() hiding work with the input handler.
*
* @param[in] ctx Context to connect with the tree being built here.
* @param[in] fd File descriptor of a regular file (e.g. sockets are not supported) containing the input data in the specified @p format to parse (and validate).
* @param[in] format Format of the input data to be parsed. Can be 0 to try to detect format from the input handler.
* @param[in] parse_options Options for parser, see @ref dataparseroptions.
* @param[in] validate_options Options for the validation phase, see @ref datavalidationoptions.
* @param[out] tree Resulting data tree built from the input data. Note that NULL can be a valid result as a representation of an empty YANG data tree.
* The returned data are expected to be freed using ::lyd_free_all().
* @return LY_SUCCESS in case of successful parsing (and validation).
* @return LY_ERR value in case of error. Additional error information can be obtained from the context using ly_err* functions.
*/
LY_ERR lyd_parse_data_fd(const struct ly_ctx *ctx, int fd, LYD_FORMAT format, uint32_t parse_options, uint32_t validate_options,
struct lyd_node **tree);
/**
* @brief Parse (and validate) input data as a YANG data tree.
*
* Wrapper around ::lyd_parse_data() hiding work with the input handler.
*
* @param[in] ctx Context to connect with the tree being built here.
* @param[in] path Path to the file with the input data in the specified @p format to parse (and validate).
* @param[in] format Format of the input data to be parsed. Can be 0 to try to detect format from the input handler.
* @param[in] parse_options Options for parser, see @ref dataparseroptions.
* @param[in] validate_options Options for the validation phase, see @ref datavalidationoptions.
* @param[out] tree Resulting data tree built from the input data. Note that NULL can be a valid result as a representation of an empty YANG data tree.
* The returned data are expected to be freed using ::lyd_free_all().
* @return LY_SUCCESS in case of successful parsing (and validation).
* @return LY_ERR value in case of error. Additional error information can be obtained from the context using ly_err* functions.
*/
LY_ERR lyd_parse_data_path(const struct ly_ctx *ctx, const char *path, LYD_FORMAT format, uint32_t parse_options,
uint32_t validate_options, struct lyd_node **tree);
/**
* @brief Parse (and validate) data from the input handler as a YANG RPC/action invocation.
*
* In case o LYD_XML @p format, the \<rpc\> envelope element is accepted if present. It is [checked](https://tools.ietf.org/html/rfc6241#section-4.1), an opaq
* data node (lyd_node_opaq) is created and all its XML attributes are parsed and inserted into the node. As a content of the envelope, an RPC data or
* \<action\> envelope element is expected. The \<action\> envelope element is also [checked](https://tools.ietf.org/html/rfc7950#section-7.15.2) and parsed as
* the \<rpc\> envelope. Inside the \<action\> envelope, only an action data are expected.
*
* Similarly, in the case of LYD_JSON @p format, the same envelopes in form of JSON objects are accepted. Nothing
* corresponding to the XML attributes is accepted in this case.
*
* @param[in] ctx Context to connect with the tree being built here.
* @param[in] in The input handle to provide the dumped data in the specified @p format to parse (and validate).
* @param[in] format Format of the input data to be parsed.
* @param[out] tree Resulting full RPC/action tree built from the input data. The returned data are expected to be freed using ::lyd_free_all().
* In contrast to YANG data tree, result of parsing RPC/action cannot be NULL until an error occurs.
* @param[out] op Optional pointer to the actual operation node inside the full action @p tree, useful only for action.
* @return LY_SUCCESS in case of successful parsing (and validation).
* @return LY_ERR value in case of error. Additional error information can be obtained from the context using ly_err* functions.
*/
LY_ERR lyd_parse_rpc(const struct ly_ctx *ctx, struct ly_in *in, LYD_FORMAT format, struct lyd_node **tree,
struct lyd_node **op);
/**
* @brief Parse (and validate) data from the input handler as a YANG RPC/action reply.
*
* In case o LYD_XML @p format, the \<rpc-reply\> envelope element is accepted if present. It is [checked](https://tools.ietf.org/html/rfc6241#section-4.2), an opaq
* data node (lyd_node_opaq) is created and all its XML attributes are parsed and inserted into the node.
*
* Similarly, in the case of LYD_JSON @p format, the same envelopes in form of JSON objects are accepted. Nothing
* corresponding to the XML attributes is processed in this case.
*
* The reply data are strictly expected to be related to the provided RPC/action @p request.
*
* @param[in] request The RPC/action tree (result of ::lyd_parse_rpc()) of the request for the reply being parsed.
* @param[in] in The input handle to provide the dumped data in the specified @p format to parse (and validate).
* @param[in] format Format of the input data to be parsed.
* @param[out] tree Resulting full RPC/action reply tree built from the input data. The returned data are expected to be freed using ::lyd_free_all().
* The reply tree always includes duplicated operation node (and its parents) of the @p request, so in contrast to YANG data tree,
* the result of parsing RPC/action reply cannot be NULL until an error occurs. At least one of the @p tree and @p op output variables must be provided.
* @param[out] op Pointer to the actual operation node inside the full action reply @p tree, useful only for action. At least one of the @p op
* and @p tree output variables must be provided.
* @return LY_SUCCESS in case of successful parsing (and validation).
* @return LY_ERR value in case of error. Additional error information can be obtained from the request's context using ly_err* functions.
*/
LY_ERR lyd_parse_reply(const struct lyd_node *request, struct ly_in *in, LYD_FORMAT format, struct lyd_node **tree,
struct lyd_node **op);
/**
* @brief Parse XML string as YANG notification.
*
* In case o LYD_XML @p format, the \<notification\> envelope element in combination with the child \<eventTime\> element are accepted if present. They are
* [checked](https://tools.ietf.org/html/rfc5277#page-25), opaq data nodes (lyd_node_opaq) are created and all their XML attributes are parsed and inserted into the nodes.
*
* Similarly, in the case of LYD_JSON @p format, the same envelopes in form of JSON objects are accepted. Nothing
* corresponding to the XML attributes is accepted in this case.
*
* @param[in] ctx Context to connect with the tree being built here.
* @param[in] in The input handle to provide the dumped data in the specified @p format to parse (and validate).
* @param[in] format Format of the input data to be parsed.
* @param[out] tree Resulting full Notification tree built from the input data. The returned data are expected to be freed using ::lyd_free_all().
* In contrast to YANG data tree, result of parsing Notification cannot be NULL until an error occurs.
* @param[out] ntf Optional pointer to the actual notification node inside the full Notification @p tree, useful for nested notifications.
* @return LY_SUCCESS in case of successful parsing (and validation).
* @return LY_ERR value in case of error. Additional error information can be obtained from the context using ly_err* functions.
*/
LY_ERR lyd_parse_notif(const struct ly_ctx *ctx, struct ly_in *in, LYD_FORMAT format, struct lyd_node **tree,
struct lyd_node **ntf);
/**
* @brief Fully validate a data tree.
*
* @param[in,out] tree Data tree to recursively validate. May be changed by validation.
* @param[in] ctx libyang context. Can be NULL if @p tree is set.
* @param[in] val_opts Validation options (@ref datavalidationoptions).
* @param[out] diff Optional diff with any changes made by the validation.
* @return LY_SUCCESS on success.
* @return LY_ERR error on error.
*/
LY_ERR lyd_validate_all(struct lyd_node **tree, const struct ly_ctx *ctx, uint32_t val_opts, struct lyd_node **diff);
/**
* @brief Fully validate a data tree of a module.
*
* @param[in,out] tree Data tree to recursively validate. May be changed by validation.
* @param[in] module Module whose data (and schema restrictions) to validate.
* @param[in] val_opts Validation options (@ref datavalidationoptions).
* @param[out] diff Optional diff with any changes made by the validation.
* @return LY_SUCCESS on success.
* @return LY_ERR error on error.
*/
LY_ERR lyd_validate_module(struct lyd_node **tree, const struct lys_module *module, uint32_t val_opts, struct lyd_node **diff);
/**
* @brief Validate an RPC/action, notification, or RPC/action reply.
*
* @param[in,out] op_tree Operation tree with any parents. It can point to the operation itself or any of
* its parents, only the operation subtree is actually validated.
* @param[in] tree Tree to be used for validating references from the operation subtree.
* @param[in] op Operation to validate (@ref datavalidateop), the given @p op_tree must correspond to this value. Note that
* it isn't possible to detect the operation simply from the @p op_tree since RPC/action and their reply share the same
* RPC/action data node and in case one of the input and output do not define any data node children, it is not possible
* to get know what is here given for validation and if it is really valid.
* @param[out] diff Optional diff with any changes made by the validation.
* @return LY_SUCCESS on success.
* @return LY_ERR error on error.
*/
LY_ERR lyd_validate_op(struct lyd_node *op_tree, const struct lyd_node *tree, LYD_VALIDATE_OP op, struct lyd_node **diff);
/** @} datatree */
#ifdef __cplusplus
}
#endif
#endif /* LY_PARSER_DATA_H_ */