lib: northbound cli support to end config nodes

Some more complex CLI usages will require northbound to support
signalizing a custom configuration node end.

For an example:

```
router bgp 100
 bgp router-id 10.254.254.1
 neighbor 10.0.0.100 remote-as 200
 !
 address-family ipv4 unicast
  network 10.0.1.0/24
  network 10.0.2.0/24
  network 10.0.3.0/24
 exit-address-family
 !
 address-family ipv6 unicast
  neighbor 10.0.0.100 activate
 exit-address-family
!
```

This commit implements a new callback called `cli_show_end` which
complements `cli_show` and is only called at the end of processing the
yang configuration node. It will be used to write the configuration
node termination like: "!" or "exit-address-family".

Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
This commit is contained in:
Rafael Zalamena 2019-05-24 22:11:27 -03:00
parent 990e89e5ed
commit a4d3c1d41d
2 changed files with 54 additions and 1 deletions

View File

@ -337,6 +337,27 @@ struct nb_callbacks {
*/
void (*cli_show)(struct vty *vty, struct lyd_node *dnode,
bool show_defaults);
/*
* Optional callback to show the CLI node end for lists or containers.
*
* vty
* The vty terminal to dump the configuration to.
*
* dnode
* libyang data node that should be shown in the form of a CLI
* command.
*
* show_defaults
* Specify whether to display default configuration values or not.
* This parameter can be ignored most of the time since the
* northbound doesn't call this callback for default leaves or
* non-presence containers that contain only default child nodes.
* The exception are commands associated to multiple configuration
* nodes, in which case it might be desirable to hide one or more
* parts of the command when this parameter is set to false.
*/
void (*cli_show_end)(struct vty *vty, struct lyd_node *dnode);
};
/*

View File

@ -434,10 +434,29 @@ static int nb_cli_candidate_load_transaction(struct vty *vty,
return CMD_SUCCESS;
}
/*
* ly_iter_next_is_up: detects when iterating up on the yang model.
*
* This function detects whether next node in the iteration is upwards,
* then return the node otherwise return NULL.
*/
static struct lyd_node *ly_iter_next_up(struct lyd_node *elem)
{
/* Are we going downwards? Is this still not a leaf? */
if (!(elem->schema->nodetype & (LYS_LEAF | LYS_LEAFLIST | LYS_ANYDATA)))
return NULL;
/* Are there still leaves in this branch? */
if (elem->next != NULL)
return NULL;
return elem->parent;
}
void nb_cli_show_dnode_cmds(struct vty *vty, struct lyd_node *root,
bool with_defaults)
{
struct lyd_node *next, *child;
struct lyd_node *next, *child, *parent;
LY_TREE_DFS_BEGIN (root, next, child) {
struct nb_node *nb_node;
@ -452,6 +471,19 @@ void nb_cli_show_dnode_cmds(struct vty *vty, struct lyd_node *root,
(*nb_node->cbs.cli_show)(vty, child, with_defaults);
next:
/*
* When transiting upwards in the yang model we should
* give the previous container/list node a chance to
* print its close vty output (e.g. "!" or "end-family"
* etc...).
*/
parent = ly_iter_next_up(child);
if (parent != NULL) {
nb_node = parent->schema->priv;
if (nb_node->cbs.cli_show_end)
(*nb_node->cbs.cli_show_end)(vty, parent);
}
LY_TREE_DFS_END(root, next, child);
}
}