* More YANG extension functionality,
* See [Augment auto-cli for hiding/modifying cli syntax #156](https://github.com/clicon/clixon/issues/156) and [hiding auto-generated CLI entries #153](https://github.com/clicon/clixon/issues/153) * Extensions can be used in augmentations * Extension `autocli-op` has been added to add "hidden" commands in the autocli * Documentation: https://clixon-docs.readthedocs.io/en/latest/misc.html#extensions
This commit is contained in:
parent
e1b94d94d2
commit
b8641f30bd
14 changed files with 547 additions and 50 deletions
|
|
@ -985,8 +985,8 @@ yang_find_schemanode(yang_stmt *yn,
|
|||
* @retval NULL No prefix found. This is an error
|
||||
* @retval prefix OK: Prefix as char* pointer into yang tree
|
||||
* @code
|
||||
* char *myprefix;
|
||||
* myprefix = yang_find_myprefix(ys);
|
||||
* char *myprefix;
|
||||
* myprefix = yang_find_myprefix(ys);
|
||||
* @endcode
|
||||
*/
|
||||
char *
|
||||
|
|
@ -3236,6 +3236,65 @@ yang_anydata_add(yang_stmt *yp,
|
|||
return ys;
|
||||
}
|
||||
|
||||
/*! Find extension argument and return extension argument value
|
||||
* @param[in] ys Yang statement
|
||||
* @param[in] name Name of the extension
|
||||
* @param[in] ns The namespace
|
||||
* @param[out] value clispec operator (hide/none) - direct pointer into yang, dont free
|
||||
* This is for extensions with an argument
|
||||
* @code
|
||||
* char *value = NULL;
|
||||
* if (yang_extension_value(ys, "mymode", "urn:example:lib", &value) < 0)
|
||||
* err;
|
||||
* if (value != NULL){
|
||||
* // use extension value
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
int
|
||||
yang_extension_value(yang_stmt *ys,
|
||||
char *name,
|
||||
char *ns,
|
||||
char **value)
|
||||
{
|
||||
int retval = -1;
|
||||
yang_stmt *yext;
|
||||
yang_stmt *ymod;
|
||||
cg_var *cv;
|
||||
char *prefix = NULL;
|
||||
cbuf *cb = NULL;
|
||||
|
||||
if ((cb = cbuf_new()) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
yext = NULL; /* This loop gets complicated in trhe case the extension is augmented */
|
||||
while ((yext = yn_each(ys, yext)) != NULL) {
|
||||
if (yang_keyword_get(yext) != Y_UNKNOWN)
|
||||
continue;
|
||||
if ((ymod = ys_module(yext)) == NULL)
|
||||
continue;
|
||||
if (yang_find_prefix_by_namespace(ymod, ns, &prefix) < 0)
|
||||
goto ok;
|
||||
cprintf(cb, "%s:%s", prefix, name);
|
||||
if (strcmp(yang_argument_get(yext), cbuf_get(cb)) != 0)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (yext != NULL){ /* Found */
|
||||
if ((cv = yang_cv_get(yext)) == NULL)
|
||||
goto ok;
|
||||
if (value)
|
||||
*value = cv_string_get(cv);
|
||||
}
|
||||
ok:
|
||||
retval = 0;
|
||||
done:
|
||||
if (cb)
|
||||
cbuf_free(cb);
|
||||
return retval;
|
||||
}
|
||||
|
||||
#ifdef XML_EXPLICIT_INDEX
|
||||
/*! Mark element as search_index in list
|
||||
* @retval 0 OK
|
||||
|
|
|
|||
|
|
@ -1393,6 +1393,7 @@ augment_substmt : when_stmt { clicon_debug(3,"augment-substmt -> when-s
|
|||
| case_stmt { clicon_debug(3,"augment-substmt -> case-stmt");}
|
||||
| action_stmt { clicon_debug(3,"augment-substmt -> action-stmt");}
|
||||
| notification_stmt { clicon_debug(3,"augment-substmt -> notification-stmt");}
|
||||
| unknown_stmt { clicon_debug(3,"augment-substmt -> unknown-stmt");}
|
||||
| { clicon_debug(3,"augment-substmt -> "); }
|
||||
;
|
||||
|
||||
|
|
|
|||
|
|
@ -253,15 +253,6 @@ yang_augment_node(yang_stmt *ys)
|
|||
/* The target node MUST be either a container, list, choice, case, input, output, or notification node.
|
||||
* which means it is slightly different than a schema-nodeid ? */
|
||||
targetkey = yang_keyword_get(ytarget);
|
||||
if (targetkey != Y_CONTAINER && targetkey != Y_LIST && targetkey != Y_CHOICE &&
|
||||
targetkey != Y_CASE && targetkey != Y_INPUT &&
|
||||
targetkey != Y_OUTPUT && targetkey != Y_NOTIFICATION){
|
||||
clicon_log(LOG_WARNING, "Warning: Augment failed in module %s: target node %s has wrong type %s",
|
||||
yang_argument_get(ys_module(ys)),
|
||||
schema_nodeid,
|
||||
yang_key2str(targetkey));
|
||||
goto ok;
|
||||
}
|
||||
|
||||
/* Find when statement, if present */
|
||||
if ((ywhen = yang_find(ys, Y_WHEN, NULL)) != NULL){
|
||||
|
|
@ -272,16 +263,17 @@ yang_augment_node(yang_stmt *ys)
|
|||
/* Extend ytarget with ys' schemanode children */
|
||||
yc0 = NULL;
|
||||
while ((yc0 = yn_each(ys, yc0)) != NULL) {
|
||||
if (!yang_schemanode(yc0))
|
||||
continue;
|
||||
childkey = yang_keyword_get(yc0);
|
||||
/* Only shemanodes and extensions */
|
||||
if (!yang_schemanode(yc0) && childkey != Y_UNKNOWN)
|
||||
continue;
|
||||
switch (targetkey){
|
||||
case Y_CONTAINER:
|
||||
case Y_LIST:
|
||||
/* If the target node is a container or list node, the "action" and
|
||||
"notification" statements can be used within the "augment" statement.
|
||||
*/
|
||||
if (childkey != Y_ACTION && childkey != Y_NOTIFICATION &&
|
||||
if (childkey != Y_ACTION && childkey != Y_NOTIFICATION && childkey != Y_UNKNOWN &&
|
||||
childkey != Y_CONTAINER && childkey != Y_LEAF && childkey != Y_LIST &&
|
||||
childkey != Y_LEAF_LIST && childkey != Y_USES && childkey != Y_CHOICE){
|
||||
clicon_log(LOG_WARNING, "Warning: A Augment failed in module %s: node %s %d cannot be added to target node %s",
|
||||
|
|
@ -300,8 +292,9 @@ yang_augment_node(yang_stmt *ys)
|
|||
notification node, the "container", "leaf", "list", "leaf-list",
|
||||
"uses", and "choice" statements can be used within the "augment"
|
||||
statement. */
|
||||
if (childkey != Y_CONTAINER && childkey != Y_LEAF && childkey != Y_LIST &&
|
||||
childkey != Y_LEAF_LIST && childkey != Y_USES && childkey != Y_CHOICE){
|
||||
if (childkey != Y_CONTAINER && childkey != Y_LEAF && childkey != Y_LIST &&
|
||||
childkey != Y_LEAF_LIST && childkey != Y_USES && childkey != Y_CHOICE &&
|
||||
childkey != Y_UNKNOWN){
|
||||
clicon_log(LOG_WARNING, "Warning: B Augment failed in module %s: node %s %d cannot be added to target node %s",
|
||||
yang_argument_get(ys_module(ys)),
|
||||
yang_key2str(childkey),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue