* Pagination according to new draft
* count/skip -> limit/offset * ietf-yang-metadata RFC 7952 support, placeholder parsing and extension
This commit is contained in:
parent
77bacc93bb
commit
0c7f2043f3
26 changed files with 751 additions and 620 deletions
|
|
@ -1256,9 +1256,9 @@ _json_parse(char *str,
|
|||
/* RFC 7951 Section 4: A namespace-qualified member name MUST be used for all
|
||||
* members of a top-level JSON object
|
||||
*/
|
||||
if (yspec && xml_prefix(x) == NULL
|
||||
/* && yb != YB_MODULE_NEXT XXX Dont know what this is for */
|
||||
){
|
||||
if (yspec && xml_prefix(x) == NULL &&
|
||||
/* XXX: For top-level config file: */
|
||||
(yb != YB_NONE || strcmp(xml_name(x),DATASTORE_TOP_SYMBOL)!=0)){
|
||||
if ((cberr = cbuf_new()) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||
goto done;
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <syslog.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
/* cligen */
|
||||
#include <cligen/cligen.h>
|
||||
|
|
@ -72,6 +73,8 @@
|
|||
#include "clixon_xpath.h"
|
||||
#include "clixon_yang_module.h"
|
||||
#include "clixon_yang_parse_lib.h"
|
||||
#include "clixon_plugin.h"
|
||||
|
||||
#include "clixon_netconf_lib.h"
|
||||
|
||||
/*! Create Netconf in-use error XML tree according to RFC 6241 Appendix A
|
||||
|
|
@ -1485,6 +1488,7 @@ netconf_module_features(clicon_handle h)
|
|||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*! Load generic yang specs, ie ietf netconf yang module and set enabled features
|
||||
* @param[in] h Clixon handle
|
||||
* @retval 0 OK
|
||||
|
|
@ -1494,8 +1498,8 @@ netconf_module_features(clicon_handle h)
|
|||
int
|
||||
netconf_module_load(clicon_handle h)
|
||||
{
|
||||
int retval = -1;
|
||||
yang_stmt *yspec;
|
||||
int retval = -1;
|
||||
yang_stmt *yspec;
|
||||
|
||||
yspec = clicon_dbspec_yang(h);
|
||||
/* Load yang spec */
|
||||
|
|
@ -1530,6 +1534,15 @@ netconf_module_load(clicon_handle h)
|
|||
/* Load netconf list pagination */
|
||||
if (yang_spec_parse_module(h, "ietf-netconf-list-pagination", NULL, yspec)< 0)
|
||||
goto done;
|
||||
#if 0
|
||||
/* XXX Clixon test harness problem: when loading ietf-list-pagination, it loads
|
||||
* ietf-system-capabilities which in turn loads ietf-netconf-acm. As this is a
|
||||
* system module (always loaded) it means all test-cases
|
||||
*/
|
||||
/* Load list pagination */
|
||||
if (yang_spec_parse_module(h, "ietf-list-pagination", NULL, yspec)< 0)
|
||||
goto done;
|
||||
#endif
|
||||
#endif
|
||||
retval = 0;
|
||||
done:
|
||||
|
|
|
|||
|
|
@ -1403,9 +1403,8 @@ api_path_resolve(clixon_path *cplist,
|
|||
/*! Resolve instance-id prefix:names to yang statements
|
||||
* @param[in] cplist Lisp of clixon-path
|
||||
* @param[in] yt Yang statement of top symbol (can be yang-spec if top-level)
|
||||
* @param[in] xt XML statement for prefix context
|
||||
* @retval -1 Error
|
||||
* @retval 0 Fail
|
||||
* @retval 0 Fail error in xerr
|
||||
* @retval 1 OK
|
||||
* @note: The spec says: prefixes depend on the XML context in which the value occurs.
|
||||
* However, canonical prefixes/namespaces are used based on loaded yang modules.
|
||||
|
|
@ -1440,7 +1439,7 @@ instance_id_resolve(clixon_path *cplist,
|
|||
}
|
||||
if (yang_keyword_get(yt) == Y_SPEC){
|
||||
if ((yt = yang_find_module_by_prefix_yspec(yspec, cp->cp_prefix)) == NULL){
|
||||
clicon_err(OE_YANG, ENOENT, "Prefix does not correspond to existing module.");
|
||||
clicon_err(OE_YANG, ENOENT, "Prefix \"%s\" does not correspond to any existing module", cp->cp_prefix);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
|
@ -1857,6 +1856,7 @@ clixon_instance_id_bind(yang_stmt *yt,
|
|||
* example.
|
||||
* @param[in] yt Yang statement of top symbol (can be yang-spec if top-level)
|
||||
* @param[out] cplistp Path parse-tree
|
||||
* @param[out] xerr Contains error if retval=0
|
||||
* @param[in] format Format string for xpath syntax
|
||||
* @retval -1 Error
|
||||
* @retval 0 Non-fatal failure, yang bind failures, etc,
|
||||
|
|
@ -1865,6 +1865,7 @@ clixon_instance_id_bind(yang_stmt *yt,
|
|||
int
|
||||
clixon_instance_id_parse(yang_stmt *yt,
|
||||
clixon_path **cplistp,
|
||||
cxobj **xerr,
|
||||
const char *format,
|
||||
...)
|
||||
{
|
||||
|
|
@ -1898,8 +1899,11 @@ clixon_instance_id_parse(yang_stmt *yt,
|
|||
/* Resolve module:name to pointer to yang-stmt, fail if not successful */
|
||||
if ((ret = instance_id_resolve(cplist, yt)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
if (ret == 0){
|
||||
if (xerr && netconf_invalid_value_xml(xerr, "application", clicon_err_reason) < 0)
|
||||
goto done;
|
||||
goto fail;
|
||||
}
|
||||
if (cplistp){
|
||||
*cplistp = cplist;
|
||||
cplist = NULL;
|
||||
|
|
|
|||
|
|
@ -159,7 +159,6 @@ plugin_module_struct_set(clicon_handle h,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Access functions */
|
||||
|
||||
/*! Get plugin api
|
||||
|
|
|
|||
|
|
@ -887,8 +887,8 @@ clicon_rpc_get(clicon_handle h,
|
|||
* @param[in] nsc Namespace context for filter
|
||||
* @param[in] content Clixon extension: all, config, noconfig. -1 means all
|
||||
* @param[in] depth Nr of XML levels to get, -1 is all, 0 is none
|
||||
* @param[in] count Collection/clixon extension
|
||||
* @param[in] skip Collection/clixon extension
|
||||
* @param[in] limit Collection/clixon extension
|
||||
* @param[in] offset Collection/clixon extension
|
||||
* @param[in] direction Collection/clixon extension
|
||||
* @param[in] sort Collection/clixon extension
|
||||
* @param[in] where Collection/clixon extension
|
||||
|
|
@ -909,8 +909,8 @@ clicon_rpc_get_pageable_list(clicon_handle h,
|
|||
cvec *nsc, /* namespace context for xpath */
|
||||
netconf_content content,
|
||||
char *depth,
|
||||
char *count,
|
||||
char *skip,
|
||||
char *limit,
|
||||
char *offset,
|
||||
char *direction,
|
||||
char *sort,
|
||||
char *where,
|
||||
|
|
@ -941,7 +941,7 @@ clicon_rpc_get_pageable_list(clicon_handle h,
|
|||
cprintf(cb, " xmlns:%s=\"%s\"",
|
||||
NETCONF_BASE_PREFIX, NETCONF_BASE_NAMESPACE);
|
||||
cprintf(cb, " %s", NETCONF_MESSAGE_ID_ATTR);
|
||||
cprintf(cb, "><get-pageable-list xmlns=\"%s\"", NETCONF_COLLECTION_NAMESPACE);
|
||||
cprintf(cb, "><get-pagable-list xmlns=\"%s\"", NETCONF_COLLECTION_NAMESPACE);
|
||||
/* Clixon extension, content=all,config, or nonconfig */
|
||||
if ((int)content != -1)
|
||||
cprintf(cb, " content=\"%s\"", netconf_content_int2str(content));
|
||||
|
|
@ -955,17 +955,17 @@ clicon_rpc_get_pageable_list(clicon_handle h,
|
|||
goto done;
|
||||
cprintf(cb, ">%s</list-target>", xpath);
|
||||
}
|
||||
if (count)
|
||||
cprintf(cb, "<count>%s</count>", count);
|
||||
if (skip)
|
||||
cprintf(cb, "<skip>%s</skip>", skip);
|
||||
if (limit)
|
||||
cprintf(cb, "<limit>%s</limit>", limit);
|
||||
if (offset)
|
||||
cprintf(cb, "<offset>%s</offset>", offset);
|
||||
if (direction)
|
||||
cprintf(cb, "<direction>%s</direction>", direction);
|
||||
if (sort)
|
||||
cprintf(cb, "<sort>%s</sort>", sort);
|
||||
if (where)
|
||||
cprintf(cb, "<where>%s</where>", where);
|
||||
cprintf(cb, "</get-pageable-list></rpc>");
|
||||
cprintf(cb, "</get-pagable-list></rpc>");
|
||||
if ((msg = clicon_msg_encode(session_id, "%s", cbuf_get(cb))) == NULL)
|
||||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret) < 0)
|
||||
|
|
|
|||
|
|
@ -736,7 +736,7 @@ xpath_first_localonly(cxobj *xcur,
|
|||
* If result is not nodeset, return empty nodeset
|
||||
* @param[in] xcur xml-tree where to search
|
||||
* @param[in] nsc External XML namespace context, or NULL
|
||||
* @param[in] xpformat Format string for XPATH syntax
|
||||
* @param[in] xpformat Format string for XPATH syntax
|
||||
* @param[out] vec vector of xml-trees. Vector must be free():d after use
|
||||
* @param[out] veclen returns length of vector in return value
|
||||
* @retval 0 OK
|
||||
|
|
|
|||
|
|
@ -1604,8 +1604,8 @@ yang_print(FILE *f,
|
|||
}
|
||||
|
||||
/* Log/debug info about top-level (sub)modules no recursion
|
||||
* @param[in] f File to print to.
|
||||
* @param[in] yspec Yang spec
|
||||
* @param[in] dbglevel Debug level
|
||||
*/
|
||||
int
|
||||
yang_spec_dump(yang_stmt *yspec,
|
||||
|
|
@ -2402,7 +2402,6 @@ ys_populate_unknown(clicon_handle h,
|
|||
*/
|
||||
if (clixon_plugin_extension_all(h, yext, ys) < 0)
|
||||
goto done;
|
||||
|
||||
retval = 0;
|
||||
done:
|
||||
if (prefix)
|
||||
|
|
|
|||
|
|
@ -679,3 +679,60 @@ yang_find_module_by_name(yang_stmt *yspec,
|
|||
return ymod;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*! Callback for handling RFC 7952 annotations
|
||||
*
|
||||
* a server indicates that it is prepared to handle that annotation according to the
|
||||
* annotation's definition. That is, an annotation advertised by the
|
||||
* server may be attached to an instance of a data node defined in any
|
||||
* YANG module that is implemented by the server.
|
||||
* Possibly add them to yang parsing, cardinality, etc?
|
||||
* as described in Section 3.
|
||||
* Note this is called by the module using the extension md:annotate, not by
|
||||
* ietf-yang-metadata.yang
|
||||
*/
|
||||
static int
|
||||
ietf_yang_metadata_extension_cb(clicon_handle h,
|
||||
yang_stmt *yext,
|
||||
yang_stmt *ys)
|
||||
{
|
||||
int retval = -1;
|
||||
char *extname;
|
||||
char *modname;
|
||||
yang_stmt *ymod;
|
||||
|
||||
ymod = ys_module(yext);
|
||||
modname = yang_argument_get(ymod);
|
||||
extname = yang_argument_get(yext);
|
||||
if (strcmp(modname, "ietf-yang-metadata") != 0 || strcmp(extname, "annotation") != 0)
|
||||
goto ok;
|
||||
clicon_debug(1, "%s Enabled extension:%s:%s", __FUNCTION__, modname, extname);
|
||||
/* XXX Nothing yet - this should signal that xml attribute annotations are allowed
|
||||
* Possibly, add an "annotation" YANG node.
|
||||
*/
|
||||
ok:
|
||||
retval = 0;
|
||||
// done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! In case ietf-yang-metadata is loaded by application, handle annotation extension
|
||||
* Consider moving fn
|
||||
*/
|
||||
int
|
||||
yang_metadata_init(clicon_handle h)
|
||||
{
|
||||
int retval = -1;
|
||||
clixon_plugin_t *cp = NULL;
|
||||
|
||||
|
||||
/* Create a pseudo-plugin to create extension callback to set the ietf-yang-meta
|
||||
* yang-data extension for api-root top-level restconf function.
|
||||
*/
|
||||
if (clixon_pseudo_plugin(h, "pseudo yang metadata", &cp) < 0)
|
||||
goto done;
|
||||
clixon_plugin_api_get(cp)->ca_extension = ietf_yang_metadata_extension_cb;
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue