Chapter 16. The CLI agent

Table of Contents

16.1. Overview
16.2. The J-style CLI
16.3. The C- and I-style CLI
16.4. The CLI in action
16.5. Environment for OS command execution
16.6. Command output processing
16.7. Range expressions
16.8. Autorendering of enabled/disabled
16.9. Actions
16.10. Command history
16.11. Command line editing
16.12. Using CLI completion
16.13. Using the comment characters # or !
16.14. Annotations and tags
16.15. Activate and Deactivate
16.16. CLI messages
16.17. confd.conf settings
16.18. CLI Environment
16.19. Commands in J-style
16.20. Commands in C/I-style
16.21. Customizing the CLI
16.22. User defined wizards
16.23. User defined wizards in C
16.24. User defined commands in C using the C-API
16.25. User defined commands as shell scripts
16.26. Modifying built-in commands
16.27. Tailoring show commands
16.28. Change password at initial login

16.1. Overview

Confd provides three different CLI styles, one inspired by the Junos CLI (J), one inspired by the Cisco XR CLI (C), and one inspired by the Cisco IOS CLI (I). All styles can be supported at the same time, or one style can be chosen for a given deployment of ConfD. The default style is configured in the confd.conf file using the style setting in the cli section.

The CLI is automatically rendered using the data model described by the yang files. This way we get an auto-generated CLI, without any extra effort, except the design of our yang files. The auto-generated CLI supports the following features:

  • Command line history and command line editor.

  • Tab completion for content of the configuration database.

  • Monitoring and inspecting log files.

  • Inspecting the system configuration and system state.

  • Fully configuring the system.

Alias expansion is performed when a command line is entered. Aliases are part of the configuration and are manipulated accordingly. In the J-style CLI this is done by manipulating the nodes in the alias configuration tree. In the C- and I-style CLIs this is done by the alias command in configuration mode.

The C- and I-style CLIs automatically create modes for each list node in the yang files, and commands for setting each parameter are generated. Actions specified in the yang files are mapped to commands in the mode where they appear.

The J-style CLI contains commands for manipulating the configuration and actions in the yang files are mapped into request commands in operational mode.

Even though the auto-generated CLI is fully functional it can be customized and extended in numerous ways:

  • Built-in commands can be moved, deleted and reordered.

  • Confirmation prompts can be added to built-in commands.

  • New commands can be implemented using the C-API and ordinary executables, and shell scripts can be invoked from a command.

  • New commands can be mounted freely in the existing command hierarchy.

  • The built-in tab completion mechanism can be overridden using user defined callbacks.

  • New command hierarchies can be created.

  • A command timeout can be added, both a global timeout for all commands, and command specific timeouts.

  • Actions and parts of the data tree can be hidden and can later be made visible when the user enters a password.

In the C- and I-style CLIs some additional customizations are possible.

  • The automatically generated modes can be suppressed.

  • New modes can be added at internal nodes.

  • The builtin show output can be replaced with an arbitrary command, either for the whole configuration or just parts of it.

  • Custom mode names can be assigned statically or dynamically through a C-callback

  • Transactions can be disabled so that all CLI modifications take effect immediately. The IOS style CLI automatically disables transactions.

How to customize and extend the auto-generated CLI is described in the clispec(5) manual page.

Tip: In the ConfD distribution there is an Emacs mode suitable for clispec editing.

16.2. The J-style CLI

16.2.1. Command Hierarchy

The CLI is built around a hierarchy of commands. This makes it possible to logically group commands. The operational mode command hierarchy looks like this for the XR CLI:

--|- commit
  |- compare -
  |         |- file
  |         |- startup
  |- configure
  |- file ---
  |         |- list
  |         |- show
  |         |- rename
  |         |- delete
  |         |- compare -
  |         |          |- files
  |         |- copy
  |- help
  |- id
  |- monitor -
  |          |
  |          |- stop
  |          |- start
  |- ping
  |- quit
  |- request -
  |          |- <action>
  |          |- job -
  |                 |- stop
  |          |- message
  |          |- system -
  |                    |- logout -
  |                              |- user
  |
  |- set
  |- set-path
  |- show ---
  |          |- all
  |          |- jobs
  |          |- users
  |          |- status
  |          |- configuration
  |          |- cli
  |          |- cli -
  |          |      |- history
  |          |- log
  |          |- notification
  |          |- parser -
  |          |         |- dump
  |- source
  |- ssh
  |- telnet
  |- traceroute

The configure mode command hierarchy looks like this:

--|- activate
  |- annotate
  |- commit -
  |         |- confirmed
  |         |- check
  |         |- and-quit
  |- compare -
  |          |- file
  |          |- running
  |- deactivate
  |- delete
  |- edit
  |- exit
  |- help
  |- hide
  |- insert
  |- move
  |- load
  |- quit
  |- rename
  |- revert
  |- rollback
  |- run
  |- save
  |- set
  |- show -
  |       |- parser -
  |       |         |- dump
  |- status
  |- tag -
  |      |- add
  |      |- clear
  |      |- del
  |- top
  |- unhide
  |- up
  |- validate
  |- wizard -
  |- adduser

16.2.2. Two CLI modes

The ConfD CLI provides various commands for configuring and monitoring software, hardware, and network connectivity of target devices. The CLI supports two modes: operational mode, for monitoring the state of the device; and configure mode, for changing the state of the device.

The prompt indicates which mode the CLI is in. When moving from operational mode to configure mode using the configure command, the prompt is changed from user@host> to user@host%. The prompts can be configured using the prompt1 and prompt2 settings in the confd.conf file.

For example:

joe@io> configure
Entering configuration mode "private"

[ok][2006-06-02 12:31:59]
[edit]
joe@io%

16.2.3. Operational mode

Operational mode is the initial mode after successful login to the CLI. It is primarily used for viewing the system status, controlling the CLI environment, monitoring and troubleshooting network connectivity, and initiating the configure mode.

The full list of commands available in operational mode is listed below in the "Operational mode commands" section.

16.2.4. Configure mode

Configure mode can be initiated by entering the configure command in operational mode. All changes to the device's configuration are done to a copy of the active configuration, called a candidate configuration. These changes do not take effect until a successful commit or commit confirm command is entered.

The full list of commands available in configure mode is listed below in the "Configure mode commands" section.

16.3. The C- and I-style CLI

The C- and I-style CLI is inspired by the Cisco XR CLI and Cisco IOS CLI. The configuration is manipulated through a series of commands and modes. Each parameter in the yang files is represented by a separate command.

The CLI provides various commands for configuring and monitoring software, hardware, and network connectivity of target devices. The CLI supports two modes: operational mode, for monitoring the state of the device; and configure mode, for changing the state of the device. The configure mode consists of a number of sub-modes for manipulating different parts of the configuration, i.e. the mode aaa authentication users user is present for configuring user authentication parameters.

The prompt indicates which mode the CLI is in. When moving from operational/EXEC mode to configure mode using the config command, the prompt is changed from host# to host(mode)#. The prompts can be configured using the cPrompt1 and cPrompt2 settings in the confd.conf file, and additionally in the IOS style through the prompt setting in the AAA configuration.

For example:

joe connected from 127.0.0.1 using console on io
io# config terminal
Entering configuration mode private
io(config)# 

16.3.1. Operational/EXEC mode

Operational mode is the initial mode after successful login to the CLI. It is primarily used for viewing the system status, controlling the CLI environment, monitoring and troubleshooting network connectivity, and initiating the configure mode.

The full list of commands available in operational mode is listed below in the "Operational mode commands" section.

16.3.2. Configure mode

Configure mode can be initiated by entering the config command in operational mode. All changes to the device's configuration are done to a copy of the active configuration, called a candidate configuration. These changes do not take effect until a successful commit or commit confirm command is entered.

The full list of commands available in configure mode is listed below in the "Configure mode commands" section. Additional commands and modes are dynamically derived from the yang files.

16.4. The CLI in action

16.4.1. Starting the CLI

The CLI is started using the confd_cli program. It can either be used as a login program or started manually once the user has logged in.

In a typical device, ordinary users would have the confd_cli program as login shell, and the root user would have to login and then start the CLI using confd_cli.

confd_cli is a fairly small program (about 800 lines of C code) which we distribute both as a binary and source code (in $CONFD_DIR/src/confd/cli). When started it sets the terminal in raw mode, connects to the ConfD daemon through a socket over the loopback interface, and sends user name, the user's groups, protocol, client IP address, terminal settings etc., and then enters a proxying mode where it sends key strokes from the user and prints characters sent by the ConfD daemon.

It is straightforward to modify the C program to send, for example, custom group information. The default behavior is to send the UNIX groups the user belongs to.

Out of the box, the confd_cli program supports a range of options, primarily intended for debug and development purposes.

The confd_cli program can also be used for batch processing of CLI commands, either by storing the commands in a file and running confd_cli on the file, or by having the following line at the top of the file (with the location of the program modified appropriately):

#!/bin/confd_cli

When the CLI is run non-interactively it will terminate at the first error and will only show the output of the commands executed. It will not output the prompt or echo the commands. This is the same behavior as for shell scripts.

If you want to run a script non-interactively, e.g. as a script or through a pipe, and still want the prompts and commands echoed, you can give the --interactive option.

Command line options:

confd_cli --help
Usage: confd_cli [options] [file]
Options:
--help, -h            display this help
--host, -H <host>     current host name (used in prompt)
--address, -A <addr>  cli address to connect to
--port, -P <port>     cli port to connect to
--cwd,  -c <dir>      current working directory
--proto, -p <proto>   type of connection (tcp, ssh, console)
--verbose, -v         verbose output
--ip, -i              clients source ip
--interactive, -n     force interactive mode
--juniper, -J         Juniper style CLI
--cisco, -C           Cisco XR style CLI
--user, -u <user>     clients user name
--uid, -U <uid>       clients user id
--groups, -g <groups> clients group list
--gids, -D <gids>     clients group id list
--gid, -G <gid>       clients group id
--noaaa               disable AAA

host

The argument to host should be the host name of the device. The confd_cli program will use the result of the system call gethostname() as default value. The host name is used in the CLI prompt.

address

If ConfD has been configured to listen to a different address than 127.0.0.1 for the communication between subsystems, then that address should be given as argument to address (or we can use the CONFD_IPC_ADDRESS environment variable, or recompile the confd_cli program with the new address compiled in).

port

If ConfD has been configured to use a non-default port for the communication between subsystems, then that port number should be given as argument to port (or we can use the CONFD_IPC_PORT environment variable, or recompile the confd_cli program with the new port compiled in).

cwd

Directory to use as current working directory in the CLI. Normally the user's home directory. The default is the directory where the confd_cli program is started.

proto

Should be the protocol used by the user to connect to the box, one of tcp, ssh, and console. The default is ssh for connections established with OpenSSH (the program inspects the SSH_CONNECTION environment variable), and console for everything else. This value is printed in the audit logs.

verbose

If this argument is given, then the confd_cli program will be a bit more talkative during the ConfD handshake phase.

ip

Should be the user's source IP address, if the user connects through SSH or telnet. The default is 127.0.0.1 to indicate the console. This value is printed in the audit logs.

interactive

Force the CLI to echo commands and prompts even when not invoked from a terminal, i.e. when reading input from a file or through a pipe.

cisco

Force the CLI to provide a I-style CLI.

juniper

Force the CLI to provide a Juniper style CLI.

user

The name of the user connecting. Used to set proper access rules and assign proper groups (if the group mapping is kept in ConfD). The default is to use the login name of the user.

uid

The numeric user id of the connected user. The uid will be used when executing osCommands, when checking file access permissions, and when creating files. Note that ConfD needs to run as root for this to work properly.

gid

The numeric group id of the connected user. The gid will be used when executing osCommands, when checking file access permissions, and when creating files. Note that ConfD needs to run as root for this to work properly.

groups

The argument to groups should be a comma-separated list of groups. The default is to send the OS groups that the user belongs to, i.e. the same as the groups shell command gives us.

gids

The argument to gids should be a comma-separated list of numeric group ids representing the Unix supplementary groups for the user. These are used when executing osCommands and when checking file access permissions.

noaaa

Disables AAA. This is useful during development but should be removed in a production system.

16.4.2. Starting the CLI in an overloaded system

If the number of ongoing sessions have reached the configured system limit, no more CLI sessions will be allowed until one of the existing sessions have been terminated.

This makes it impossible to get into the system. A situation which may not be acceptable. The CLI therefore has a mechanism for handling this problem. When the CLI detects that the session limit has been reached it will check if the new user has privileges to execute the logout command. If the user does it will display a list of the current user sessions on the box and ask the user if one of the sessions should be terminated to make room for the new session.

16.5. Environment for OS command execution

All OS commands, i.e. executables or shell scripts, are executed using a program called cmdptywrapper. To be able to execute an os-command as root or a specific user we need to make cmdptywrapper setuid root, i.e.

# chown root cmdptywrapper
# chmod u+s cmdptywrapper

Failing that, all programs will be executed as the user who started the ConfD daemon. Consequently, if that user is root we do not have to perform the chmod operation above.

16.6. Command output processing

It is possible to process the output from a command using an output redirect. This is done using the | character. This redirect feature is supported in both the C- and I-style and the J-style CLI. Most of the commands are the same but some commands differ. The redirect targets (pipe commands) can be modified using the clispec file, just as a regular CLI command. The commands can be chained to achieve more complex processing.

In the J-style CLI the commands are called - append, count, display set (show configuration only), display annotations, display json, display keypath, display xml, display xpath, show tags, hide annotations, hide tags, except (exclude), extended, find (begin), linnum, match (include), match-all, match-any, more, nomore, notab (auto-rendered show commands only), repeat (auto-rendered show commands only), save, tab (show commands only) and until. It may look look this in the J-style CLI:

admin@tellus> show configuration | ?
Possible completions:
  annotation  - Show only statements whose annotation matches a pattern
  append      - Append output text to a file
  best-effort - Display data even if data provider is unavailable or continue loading from file in presence of failures
  count       - Count the number of lines in the output
  details     - Display details
  display     - Display options
  except      - Show only text that does not matches a pattern
  extended    - Show referring elements
  find        - Search for the first occurrence of a pattern
  hide        - Hide display options
  linnum      - Enumerate lines in the output
  match       - Show only text that matches a pattern
  match-all   - All selected filters must match
  match-any   - At least one filter must match
  more        - Paginate output
  nomore      - Suppress pagination
  save        - Save output text to a file
  select      - Select additional columns
  sort-by     - Select sorting indices
  tab         - Enforce table output
  tags        - Show only statements whose tags matches a pattern
  until       - Display until the first occurrence of a pattern

In the C- and I-style CLIs the commands are called - append, count, exclude (except), display annotations, display tags, hide annotations, hide tags, begin (find), include (match), linnum, match-all, match-any, more, nomore, notab (auto-rendered show commands only), repeat (auto-rendered show commands only), save, tab (show commands only) and until. It may look look this in the C- and I-style CLI:

tellus# show running-config | ?
Possible completions:
  annotation   Show only statements whose annotation matches a pattern
  append       Append output text to a file
  begin        Begin with the line that matches
  count        Count the number of lines in the output
  details      Display commit progress
  display      Display options
  exclude      Exclude lines that match
  extended     Display referring entries
  hide         Hide display options
  include      Include lines that match
  linnum       Enumerate lines in the output
  match-all    All selected filters must match
  match-any    At least one filter must match
  more         Paginate output
  nomore       Suppress pagination
  save         Save output text to a file
  select       Select additional columns
  sort-by      Select sorting indices
  tab          Enforce table output
  tags         Show only statements whose tags matches a pattern
  until        End with the line that matches

The show annotations/tags and hide annotations/tags pipe targets are only available when viewing the configuration, and only if attributes have been enabled in the confd.conf file.

16.6.1. Sort the the Output

The sort-by target makes it possible for the CLI user to control in which order instances should be displayed, and can be used when the path points to a list. The argument to sort-by can either be a secondary index or an arbitrary set of leafs in the list. If a secondary index is given as an argument, the table will be sorted in the order defined by the secondary index. If a set of leafs is given as an argument, the table will be sorted in the order in which the leafs are entered. For example:

admin@io 13:28:07> show configuration server | sort-by port ip | tab

NAME  IP        PORT  DESCRIPTION
-----------------------------------
1     1.1.1.1   1010  -
7     1.1.1.17  1020  -
10    1.1.1.11  1040  -
3     1.1.1.3   1070  -
6     1.1.1.4   1070  -
5     1.1.1.5   1070  -
4     1.1.1.7   1070  -
8     1.1.1.8   1070  -
9     1.1.1.9   1070  -
11    1.1.1.10  1070  -
2     1.1.1.12  1070  -

[ok][2013-08-31 13:49:44]
admin@io 13:50:12>

16.6.2. Count the Number of Lines in the Output

This redirect target counts the number of lines in the output. For example:

admin@io 13:28:07> show configuration | count
[ok][2007-08-31 13:49:44]
Count: 99 lines
admin@io 13:49:44> show configuration aaa | count
[ok][2007-08-31 13:50:12]
Count: 90 lines
admin@io 13:50:12>

16.6.3. Search for a String in the Output

The match target (include in C- and I- style) is used to only include lines matching a regular expression. For example:

admin@io 13:53:59> show configuration aaa | match {
aaa {
    authentication {
        users {
            user admin {
            user oper {
            user private {
            user public {
        groups {
            group admin {
            group oper {
    authorization {
        cmdrules {
            cmdrule 1 {
            cmdrule 2 {
            cmdrule 3 {
            cmdrule 150 {
        datarules {
            datarule 101 {
            datarule 203 {

In the example above only lines containing { are shown. Similarly lines not containing a regular expression can be included. This is done using the except target (exclude in C- and I- style). For example:

admin@io 13:56:30> show configuration aaa authentication | except {
            uid        1000;
            gid        100;
            password   $1$fB$0w68PmacQ4VmE3/M3nK3Ug==;
            ssh_keydir /var/confd/homes/admin/.ssh;
            homedir    /var/confd/homes/admin;
        }
            uid        1000;
            gid        100;
            password   $1$S6$brGZW9wSDifHoU7Rf5KSHA==;
            ssh_keydir /var/confd/homes/oper/.ssh;
            homedir    /var/confd/homes/oper;
        }
            uid        1000;
            gid        100;
            password   $1$L4$YcCoIivO4mrzoj8vCrEjlw==;
            ssh_keydir /var/confd/homes/private/.ssh;
            homedir    /var/confd/homes/private;
        }
            uid        1000;
            gid        100;
            password   $1$Ft$9zTEc79NWFE0E8v7I2RxVQ==;
            ssh_keydir /var/confd/homes/public/.ssh;
            homedir    /var/confd/homes/public;
        }
    }
            users "admin private";
        }
            users "oper public";
        }
    }
}

It is also possible to display the output starting at the first match of a regular expression, using the find target (begin in C- and I- style). For example:

admin@io 14:03:44> show configuration aaa authentication users | find private
user private {
    uid        1019;
    gid        1013;
    password   $1$AO$hbQEgdGQLzlWhX/1FNL5f.;
    ssh_keydir /var/confd/homes/private/.ssh;
    homedir    /var/confd/homes/private;
}
user public {
    uid        1019;
    gid        1013;
    password   $1$Kh$0Lor2g1yrSQ7MYDLxFr9h0;
    ssh_keydir /var/confd/homes/public/.ssh;
    homedir    /var/confd/homes/public;
}

Output can also be ended when a line matches a regular expression. This is done with the until target. For example:

admin@io 14:03:44> show configuration aaa authentication users | find private | until public
user private {
    uid        1019;
    gid        1013;
    password   $1$AO$hbQEgdGQLzlWhX/1FNL5f.;
    ssh_keydir /var/confd/homes/private/.ssh;
    homedir    /var/confd/homes/private;
}
user public {

It is also possible to filter the output by using a sequence of select statements followed by match-any or match-any. Consider the configuration:

admin@io 14:03:44> show configuration servers server
server a {
    ip   1.2.3.4;
    port 23;
}
server b {
    ip   2.3.4.5;
    port 24;
}
server c {
    ip   3.4.5.6;
    port 25;
}

If we were to show all servers that has either ip 1.2.3.4 or port 24, this can be done by using select statements, like so

admin@io 14:03:44> show configuration servers server | select ip 1.2.3.4 | select port 24 | match-any
server a {
    ip   1.2.3.4;
    port 23;
}
server b {
    ip   2.3.4.5;
    port 24;
}

whereas a match-all filtering would in this case result in

admin@io 14:03:44> show configuration servers server | select ip 1.2.3.4 | select port 24 | match-all
No entries found.

as there are no servers that has both ip 1.2.3.4 and port 24.

16.6.4. Saving the Output to a File

The output can also be saved to a file using the save or append redirect target. For example:

admin@io 14:03:51> show configuration aaa  | save /tmp/saved

Or to save the configuration, except all passwords

admin@io 14:03:51> show configuration | except password | save /tmp/saved

16.6.5. Regular expressions

The regular expressions is a subset of the regular expressions found in egrep and in the AWK programming language. Some common operators are:

.

Matches any character.

^

Matches the beginning of a string.

$

Matches the end of a string.

[abc...]

Character class, which matches any of the characters abc... Char- acter ranges are specified by a pair of characters separated by a -.

[^abc...]

negated character class, which matches any character except abc....

r1 | r2

Alternation. It matches either r1 or r2.

r1r2

Concatenation. It matches r1 and then r2.

r+

Matches one or more rs.

r*

Matches zero or more rs.

r?

Matches zero or one rs.

(r)

Grouping. It matches r.

For example, to only display uid and gid you can do the following:

admin@io 15:11:24> show configuration | match "(uid)|(gid)"
                uid        1000;
                gid        100;
                uid        1000;
                gid        100;
                uid        1000;
                gid        100;
                uid        1000;
                gid        100;

16.6.6. Display line numbers

The linnum target causes a line number to be displayed at the beginning of each line in the display.

admin@io 15:11:24> show configuration | match "(uid)|(gid)" | linnum
1:                 uid        1019;
2:                 gid        1013;
3:                 uid        1019;
4:                 gid        1013;
5:                 uid        1019;
6:                 gid        1013;
7:                 uid        1019;
8:                 gid        1013;

16.6.7. Display as format

The display target can be used to display output in a set of output formats. Some of these output formats are unique to specific modes, such as configuration or operational mode. The output formats json, keypath, xml, and xpath are available in most modes and CLI styles (J, I, and C).

For instance, assuming we have a data model featuring a set of hosts, each containing a set of servers, we can display the configuration data as JSON. This is depicted in the example below.

admin@io 15:11:24> show configuration hosts | display json
{
  "data": {
    "pipetargets_model:hosts": {
      "host": [
        {
          "name": "host1",
          "enabled": true,
          "numberOfServers": 2,
          "servers": {
            "server": [
              {
                "name": "serv1",
                "ip": "192.168.0.1",
                "port": 5001
              },
              {
                "name": "serv2",
                "ip": "192.168.0.1",
                "port": 5000
              }
            ]
          }
        },
        {
          "name": "host2",
          "enabled": false,
          "numberOfServers": 0
...

Still working with the same data model as used in the example above, we might want to see the current configuration in keypath format. The following example shows how to do that, and shows the resulting output.

admin@io 15:11:24> show configuration hosts | display keypath
/hosts/host{host1} enabled
/hosts/host{host1}/numberOfServers 2
/hosts/host{host1}/servers/server{serv1}/ip 192.168.0.1
/hosts/host{host1}/servers/server{serv1}/port 5001
/hosts/host{host1}/servers/server{serv2}/ip 192.168.0.1
/hosts/host{host1}/servers/server{serv2}/port 5000
/hosts/host{host2} disabled
/hosts/host{host2}/numberOfServers 0

16.7. Range expressions

It is possible to modify a range of instances at the same time using range expressions, and to display a range of instances using a range expression.

Key attributes that are integers are automatically support range expressions, both in the J- style and the I- and C- style CLI. The syntax is slightly different in the J-style than in I- and C- style.

Automatic range expressions are also supported for key elements of other types as long as they are restricted to the pattern [a-zA-Z-]*[0-9]+/[0-9]+/[0-9]+/.../[0-9]+. I.e., the CLI understands the [integer]/[integer] syntax.

If you have more complicated data-types then you may need to write a custom range callback. See the examples.confd/cli/custom_ranges example.

Suppose we have data model like this:

module range {
  namespace "http://tail-f.com/ns/example/range";
  prefix range;

  import ietf-inet-types {
    prefix inet;
  }

  import tailf-common {
    prefix tailf;
  }

  typedef interface-type {
    type string {
      pattern "((FastEthernet-)|(GigaEthernet-))[0-9]+/[0-9]+/[0-9]+";
    }
  }

  list server {
    key name;
    max-elements 64;
    leaf name {
      type int32;
    }
    leaf ip {
      type inet:ip-address;
      mandatory true;
    }
    leaf port {
      type inet:port-number;
      mandatory true;
    }
    leaf description {
      type string;
    }
  }

  list interface {
    key name;
    max-elements 64;
    leaf name {
      type interface-type;
    }
    leaf ip {
      type inet:ip-address;
      mandatory true;
    }
    leaf mtu {
      type int32;
      mandatory true;
    }
    leaf description {
      type string;
    }
    tailf:action reset {
        tailf:actionpoint reset-point;
        input {
            leaf mode {
                type string;
                mandatory true;
            }
            leaf debug {
                type empty;
            }
        }
        output {
            leaf time {
                type string;
                mandatory true;
            }
        }

    }
  }
}

Then you can do the following in the J-style CLI. Display a selected subset of the servers:

show configuration server 1-3,5

Display the configuration of a subset of the interfaces:

show configuration interface FastEthernet-1/1/1,2

In configure mode you can edit a range of interfaces in one go. For example:

jb@io> configure
Entering configuration mode private
[ok][2009-06-16 12:57:59]

[edit]
jb@io% edit interface FastEthernet-1/1/1-3
[ok][2009-06-16 12:58:14]

[edit interface FastEthernet-1/1/1-3]
jb@io% set mtu 1400
[ok][2009-06-16 12:58:20]

[edit interface FastEthernet-1/1/1-3]
jb@io% commit
Commit complete.
[ok][2009-06-16 12:58:22]

[edit interface FastEthernet-1/1/1-3]
jb@io%

In the C- and I- style CLIs the syntax is slightly different in configure mode. When you want to modify a range of instances you enter a specific range mode.

io# config
Entering configuration mode terminal
io(config)# interface range FastEthernet-1/1/1-3
io(config-interface-FastEthernet-1/1/1-3)# mtu 1300
io(config-interface-FastEthernet-1/1/1-3)# commit
Commit complete.
io(config-interface-FastEthernet-1/1/1-3)#

See the examples.confd/cli/ranges example.

16.8. Autorendering of enabled/disabled

If the data model contains an element called enabled of type xs:boolean then it will get some special treatment. Normally the user would have to enter enabled true and enabled false to enable/disable. To make this a bit more user friendly the CLI will also accept enabled and disabled. A disabled command will be auto generated if there is an enabled option of the proper type.

However, the disabled command will not be visible in configuration dumps, instead enabled false will be shown. The disabled command is only provided as a sugar in the CLI.

This behaviour can be controlled on a global level by configuring the confd.conf setting /confdConfig/cli/useShortEnabled. If the value is set to 'true', it is possible to disable the behavior on a per leaf basis, by using the extension tailf:cli-suppress-shortenabled.

16.9. Actions

Actions are invoked differently in C/I- and J-mode. In C/I-mode an action appears as a mode specific command, whereas in J-mode an action is invoked using the request command in operational mode.

For example, given the data model fragment below:

tailf:action shutdown {
  tailf:actionpoint actions;
  input {
    tailf:constant-leaf flags {
      type uint64 {
        range "1 .. max";
      }
      tailf:constant-value 42;
    }
    leaf timeout {
      type xs:duration;
      default PT60S;
    }
    leaf message {
      type string;
    }
    container options {
      leaf rebootAfterShutdown {
        type boolean;
        default false;
      }
      leaf forceFsckAfterReboot {
        type boolean;
        default false;
      }
      leaf powerOffAfterShutdown {
        type boolean;
        default true;
      }
    }
  }
}

In J-mode the restart action is invoked as follows:

joe@io> request shutdown timeout 10s message reboot options { forceFsckAfterReboot true }

And in C/I-mode as a mode specific command as follows:

io(config)# system restart mode quick restore { db startup  fast } debug timeout 45

Full command and argument completion is available when entering the command.

The order in which the action arguments are entered is not important. The parameters are reordered by the CLI-backend before invoking the action callback.

In the CLI the action is not paginated by default and will only do so if it is piped to more.

          joe@io> example_action | more
        

16.10. Command history

Command history is maintained in each mode. When we enter configure mode, we will get an empty history, i.e. we cannot access the command history from operational mode. When we exit back into operational mode we will again have access to the command history from the preceding operational mode session.

16.11. Command line editing

The default key strokes for editing the command line and moving around the command history are as follows. Note that it is possible to change these commands using the keymap clispec modification. See the clispec.5 man page for more details.

16.11.1. Moving the cursor:

Move the cursor back one character

Ctrl-b or Left Arrow

Move the cursor back one word

Esc-b or Alt-b

Move the cursor forward one character

Ctrl-f or Right Arrow

Move the cursor forward one word

Esc-f or Alt-f

Move the cursor to the beginning of the command line

Ctrl-a or Home

Move the cursor to the end of the command line

Ctrl-e or End

16.11.2. Delete characters:

Delete the character before the cursor

Ctrl-h, Delete, or Backspace

Delete the character following the cursor

Ctrl-d

Delete all characters from the cursor to the end of the line

Ctrl-k

Delete the whole line

Ctrl-u or Ctrl-x

Delete the word before the cursor

Ctrl-w, Esc-Backspace, or Alt-Backspace

Delete the word after the cursor

Esc-d or Alt-d

16.11.3. Insert recently deleted text:

Insert the most recently deleted text at the cursor

Ctrl-y

16.11.4. Display previous command lines:

Scroll backward through the command history

Ctrl-p or Up Arrow

Scroll forward through the command history

Ctrl-n or Down Arrow

Search the command history in reverse order

Ctrl-r

Show a list of previous commands

run the "show cli history" command

16.11.5. Capitalization:

Capitalize the word at the cursor, i.e. make the first character uppercase and the rest of the word lowercase.

Esc-c

Change the word at the cursor to lowercase.

Esc-l

Change the word at the cursor to uppercase.

Esc-u

16.11.6. Special:

Abort a command/Clear line

Ctrl-c

Quote insert character, i.e. do not treat the next keystroke as an edit command.

Ctrl-v/ESC-q

Redraw the screen

Ctrl-l

Transpose characters

Ctrl-t

Enter multi-line mode. This lets you enter multi-line values when prompted for a value in the CLI. It is not available when editing a CLI command.

ESC-m

Exit configuration mode. Only in C- and I-style.

Ctrl-z

16.12. Using CLI completion

We do not always have to type the full command or option name for the CLI to recognize it. To display possible completions, type the partial command followed immediately by <tab> or <space>.

If the partially typed command uniquely identifies a command, the full command name will appear. Otherwise a list of possible completions is displayed.

Completion is disabled inside quotes; in other words, if we want to type an argument containing spaces, we can either quote them with a \ (e.g. show file foo\ bar) or with a " (e.g. show file "foo bar"). Space completion is disabled when entering a filename.

Command completion also applies to filenames and directories.

Example:

admin@io> <space>
Possible completions:
commit     - Confirm a pending commit
configure  - Manipulate software configuration information
file       - Perform file operations
help       - Provide help information
monitor    - Real-time debugging
ping       - Ping a host
quit       - Exit the management session
request    - Make system-level requests
set        - Set CLI properties
set-path   - Set relative show-path
show       - Show information about the system
ssh        - Open a secure shell on another host
telnet     - Open a telnet session to another host
traceroute - Trace the route to a remote host
admin@io> re<space>quest <space>
Possible completions:
job     - Job operations
message - Send message to terminal of one or all users
system  - System operations
admin@io> request  m<space>essage all "hello"

16.12.1. Customizing CLI completion

CLI completion kicks in for both command parameters and for values adhering to leaf elements in yang. By default completions are generated automatically depending on the parameter or leaf element type. Some examples:

d199# history ?
<size>

Above we trigger a ?-completion for the built-in history command which takes a single parameter of type xs:nonNegativeInteger. The built-in history command chooses to answer with a <size> completion string.

d199# config
Entering configuration mode terminal
d199(config)# interface ?
Possible completions:
  <name: GigaEthernetX/Y>

Above we trigger a ?-completion for the list element interface which has a key leaf element of type interfaceNameType defined in the http://tail-f.com/ns/example/config/1.0 namespace:

  typedef interfaceNameType {
    tailf:info "GigaEthernetX/Y";
    type string;
  }

If the default completion behavior is not satisfactory a custom completion callback can be used instead. This holds true for both built-in and user defined commands as well for leaf elements in built-in and user defined data models.

In the following examples we redefined the completion behavior for the two examples above.

d199# history ?
Possible completions:
  500  750  The history must be a non-negative value (preferably 500 or 750)

and

d199# config
Entering configuration mode terminal
d199(config)# interface ?
Possible completions:
  FastEthernet0/1   FastEthernet IEEE 802.3
  GigaEthernet0/1   GigabitEtherenet IEEE 802.3z
  GigaEthernet0/2   GigabitEtherenet IEEE 802.3z
  GigaEthernet1/1   GigabitEtherenet IEEE 802.3z
  GigaEthernet1/2   GigabitEtherenet IEEE 802.3z
d199(config)# interface GigaEthernet ?
Possible completions:
  GigaEthernet0/1  GigaEthernet0/2  GigaEthernet1/1  GigaEthernet1/2

This was achieved using the following clispec fragment:

    <modifications>
      <simpleType namespace="" name="uint64">
        <callback>
          <capi>
            <completionpoint>generic-complete</completionpoint>
          </capi>
        </callback>
      </simpleType>
      <simpleType namespace="http://tail-f.com/ns/example/config"
                  name="interfaceNameType">
        <callback>
          <capi>
            <completionpoint>ifs-complete</completionpoint>
          </capi>
        </callback>
      </simpleType>

The generic-complete and ifs-complete callbacks look like this (fragments):

static int generic_complete(struct confd_user_info *uinfo, int cli_style,
                            char *token, int completion_char,
                            confd_hkeypath_t *kp, char *cmdpath,
                            char *cmdparam_id,
                            struct confd_qname *simpleType, char *extra) {
    char keypath[BUFSIZ] = {0};
    struct confd_completion_value values[6];
    int i = 0;


    if (strcmp(cmdpath, "history") == 0 ||
        strcmp(cmdpath, "set history") == 0) {
        values[i].type = CONFD_COMPLETION_INFO;
        values[i].value = "The history must be a non-negative value (preferably 500 or 750)";
        i++;

        values[i].type = CONFD_COMPLETION;
        values[i].value = "500";
        values[i].extra = NULL;
        i++;

        values[i].type = CONFD_COMPLETION;
        values[i].value = "750";
        values[i].extra = NULL;
        i++;
    }


    if (confd_action_reply_completion(uinfo, values, i) < 0)
        confd_fatal("Failed to reply to confd\n");

    return CONFD_OK;
}


static int ifs_complete(struct confd_user_info *uinfo, int cli_style,
                        char *token, int completion_char, confd_hkeypath_t *kp,
                        char *cmdpath, char *cmdparam_id,
                        struct confd_qname *simpleType, char *extra) {
    char keypath[BUFSIZ] = {0};
    struct confd_completion_value values[6];
    int i = 0;


    if (completion_char == '?') {
        values[i].type = CONFD_COMPLETION;
        values[i].value = "GigaEthernet0/1";
        values[i].extra = "GigabitEtherenet IEEE 802.3z";
        i++;

        values[i].type = CONFD_COMPLETION;
        values[i].value = "GigaEthernet0/2";
        values[i].extra = "GigabitEtherenet IEEE 802.3z";
        i++;

        values[i].type = CONFD_COMPLETION;
        values[i].value = "GigaEthernet1/1";
        values[i].extra = "GigabitEtherenet IEEE 802.3z";
        i++;

        values[i].type = CONFD_COMPLETION;
        values[i].value = "GigaEthernet1/2";
        values[i].extra = "GigabitEtherenet IEEE 802.3z";
        i++;

        values[i].type = CONFD_COMPLETION;
        values[i].value = "FastEthernet0/1";
        values[i].extra = "FastEthernet IEEE 802.3";
        i++;
    }


    if (confd_action_reply_completion(uinfo, values, i) < 0)
        confd_fatal("Failed to reply to confd\n");

    return CONFD_OK;
}

Take a look at the completion callback example which comes bundled with the ConfD distribution, i.e. cli/completions and read more about the completion callback API in the confd_lib_dp(3) manual page.

16.13. Using the comment characters # or !

All characters following a # (in J-style) or ! (in C-style) character up to the next newline are ignored. This makes it possible to have comments in a file containing CLI commands, and still be able to paste the file into the command-line interface. For example:

# Command file create 2006-05-20 by Joe Smith
# First show the configuration before we change it
show configuration
# Enter configuration mode and add joe as user
configure
wizard adduser
joe
foobar
foobar
admin
commit
exit
# Done

If we want to enter the # or the ! character as an argument, it has to be prefixed with a backslash (\) or used inside quotes (").

16.14. Annotations and tags

If you have large configurations it may make sense to be able to associate comments (annotations) and tags with the different parts. And then be able to filter the configuration with respect to the annotations or tags. For example, tagging parts of the configuration that relates to a certain department or customer.

ConfD has support for both tags and annotations. The support is enabled by enabling configuration attributes in the confd.conf file. I.e.,

  <enableAttributes>true</enableAttributes>

Once attributes has been enabled a set of new commands will be available in the CLI for annotating and tagging parts of the configuration. There will also be a set of pipe targets for controlling whether the tags and annotations should be displayed, and for filtering depending on annotation and tag content.

The new commands are:

  • annotate <statement> <text>

  • tag add <statement> <tag>

  • tag del <statement> <tag>

  • tag clear <statement> <tag>

The annotations and tags will be displayed as comments where the tags are prefixed by Tags:. For example:

joe@io 16:10:17% annotate aaa authentication users user admin "Only allow the XX department access to this user."
[ok][2009-09-29 16:17:16]

[edit]
joe@io 16:17:16% tag add aaa authentication users user oper foo
[ok][2009-09-29 16:28:28]

[edit]
joe@io 16:29:02% show aaa authentication users user | tags foo
/* Tags: foo */
user oper {
    uid        1000;
    gid        1000;
    password   $1$mfy4jdVt$dNJbiaylcbjpNIeRvHs3X0;
    ssh_keydir /var/confd/homes/oper/.ssh;
    homedir    /var/confd/homes/oper;
}
[ok][2009-09-29 16:29:18]

[edit]
joe@io 16:29:29% show aaa authentication users user | annotation *XX*
/* Only allow the XX department access to this user. */
user admin {
    uid        1000;
    gid        1000;
    password   $1$Qe$71aKksCOyR.KTBG6ojcGg1;
    ssh_keydir /var/confd/homes/admin/.ssh;
    homedir    /var/confd/homes/admin;
}
[ok][2009-09-29 16:29:33]

[edit]
joe@io 16:29:33%

It is possible to hide the tags and annotations when viewing the configuration, or to explicitly include them in the listing. This is done using the display annotations/tags and hide annotations/tags pipe targets.

Note that annotations are tags are part of the configuration. If you add, remove or modify an annotation or tag you need to commit the new configuration, just as you would if you have made any other change to the configuration. In I-style this will happen automatically once you press enter.

See the examples.confd/cli/annotations example for a hands on experience.

16.15. Activate and Deactivate

It may be useful to be able to deactivate parts of a configuration without actually removing it from the configuration file. It makes it possible to, for example, pre-provision a device or temporarily disable parts of a configuration without loosing the config.

ConfD has support for activate/deactivate. The support is enabled by enabling configuration attributes in the confd.conf file. I.e.,

  <enableInactive>true</enableInactive>

Once inactive has been enabled two new commands becomes available in configure mode: activate and deactivate. The argument to the command is a path into the configuration with the same properties as a path that is deletable.

The new commands are:

  • activate <statement>

  • deactivate <statement>

A deactivated statement will be indicated by a comment that says Inactive on a line before the deactivated statement in C- and I-style, and by an inactive: prefix in J-style.

In the J-style CLI

joe@io% deactivate server 1
[ok][2010-11-02 14:45:25]

[edit]
joe@io% show server
inactive: server 1 {
    ip   1.1.1.1;
    port 1071;
}
server 2 {
    ip   1.1.1.2;
    port 1072;
}
server 3 {
    ip   1.1.1.3;
    port 1073;
}
[ok][2010-11-02 14:45:33]

[edit]
joe@io%

In the C- and I-style CLIs

io(config)# deactivate server 1
io(config)# show config
/* Inactive */
server 1
!
io(config)# show configuration merge server
/* Inactive */
server 1
 ip   1.1.1.1
 port 1071
!
server 2
 ip   1.1.1.2
 port 1072
!
server 3
 ip   1.1.1.3
 port 1073
!
io(config)#

See the examples.confd/cli/annotations example for a hands on experience.

16.16. CLI messages

Messages appear when we enter and exit configure mode, when we commit a configuration, and when we type a command or value that is not valid.

Examples:

admin@io> show c
----------------^
syntax error: unknown command
Possible commands starting with c:
configuration - Display current configuration
cli           - Display cli settings
admin@io> show configuration
------------------^
syntax error: unknown command
[error][2006-06-09 10:12:05]

admin@io% set aaa auth
----------------------^
syntax error: element does not exist
Possible  values starting with auth:
authentication
authorization

When we commit a configuration, the CLI first validates the configuration and if there is a problem indicates what the problem is, for example a missing identifier or a value out of range. A message indicates where the errors are.

Examples:

admin@io> configure
Entering configuration mode "private"
[ok][2006-06-02 12:31:59]

[edit]
admin@io% set aaa authorization rules rule 200
[ok][2006-06-02 12:31:59]

[edit]
admin@io% commit
Aborted: value is unset 'aaa authorization rules rule 200 action'
[error][2006-06-02 12:31:59]

[edit]
admin@io%

16.17. confd.conf settings

Parts of the CLI behavior can be controlled from the confd.conf file. See the confd.conf.5 man page for a comprehensive description of all the options.

16.18. CLI Environment

There are a number of session variables in the CLI. They are only used during the session and are not persistent. Their values are inspected using show cli in operational mode, and set using set in operational mode. Their initial values are in order derived from the content of the confd.conf file, and the global defaults as configured under /aaa:session, and finally from user specific settings configured under under /aaa:user{<user>}/setting.

admin@io> show cli
cli {
    autowizard true;
    complete-on-space true;
    ignore-leading-space false;
    history 100;
    idle-timeout 1800;
    output {
        file terminal;
    }
    paginate true;
    screen {
        length 82;
        width 80;
    }
    show {
        defaults false;
    }
    terminal xterm;
}
[ok][2006-06-02 12:31:59]
admin@io>

The different values control different parts of the CLI behavior.

autowizard (true | false)

When enabled, the CLI will prompt the user for required settings when a new identifier is created and for mandatory action parameters.

For example:

admin@io% set aaa authorization rules rule 200
Value for 'context' (<string>): *
Value for 'path' (<string>): *
Value for 'group' (<string>): *
Value for 'op' (<string>): rw
Value for 'action' [reject,accept]: reject
[ok][2006-06-02 12:31:59]

[edit]
admin@io%

This saves the user from typing explicit set commands to set each required setting.

Note that it is recommended to disable the autowizard before pasting in a list of commands, in order to avoid prompting. A good practice is to start all such scripts with a line that disables the autowizard:

set autowizard false
...
set autowizard true
complete-on-space (true | false)

Controls if command completion should be attempted when <space> is entered. Entering <tab> always results in command completion.

devtools (true | false)

Controls if certain commands that are useful for developers should be enabled. The commands xpath and timecmd are examples of such a command.

ignore-leading--space (true | false)

Controls if leading spaces should be ignored or not. This is useful to turn off when pasting commands into the CLI.

history (<integer>)

Size of CLI command history.

idle-timeout (<seconds>)

Maximum idle time before being logged out. Use 0 (zero) for for infinity.

paginate (true | false)

Some commands paginate their output, for example. This can be disabled or enabled. It is enabled by default.

screen width (<integer>)

Current width of terminal. This is used when paginating output to get proper line count.

screen length (<integer>)

Current length of terminal. This is used when paginating output to get proper line count.

service prompt config

Controls whether a prompt should be displayed in configure mode in the C- and I-style CLI. If set to false then no prompt will be displayed. The setting is changed using the commands no service prompt config and service prompt config in configure mode.

show defaults (true | false)

Controls if defaults values should be shown when displaying the configuration. The default values are shown as comments after the configured value.

For example:

admin@io% show hosts host
host x15 {
    domain tail-f.com;
    defgw 10.1.5.2;
    interfaces {
        interface 1 {
            name eth0;
            ipMask {
                ip 192.68.0.60;   # 10.0.0.0
                mask 255.255.0.0;   # 255.255.0.0
            }
            enabled false;
        }
    }
}
[ok][2006-06-02 12:31:59]

[edit]
admin@io%
terminal (string)

Terminal type. This setting is used for controlling how line editing is performed. Supported terminals are: dumb, vt100, xterm, linux, and ansi. Other terminals may also work but have no explicit support.

16.19. Commands in J-style

It is possible to get a full XML listing of the commands available in a running ConfD instance by using the confd option --cli-j-dump <file>. The generated file is only intended for documentation purposes and cannot be used as input to confdc.

16.19.1. Operational mode commands

compare startup [brief] [<pathfilter>]

Compare current configuration to the startup configuration. This command is only available when the system has been configured to have a startup configuration. Differences will be annotated with - (removed) and + (added). With the brief option, only the actual diffs will be shown.

compare file <file> [brief] [<pathfilter>]

Compare current configuration to a configuration stored on file, i.e. previously saved using the save command. Differences will be annotated with - (removed) and + (added). With the brief option, only the actual diffs will be shown.

configure (private | exclusive | shared)

Enter configure mode. The default is private. The options have slightly different meaning depending on how the system is configured; with a writable running configuration, with a startup configuration, and with a candidate configuration.

private (writable running enabled)

Edit a private copy of the running configuration, no lock is taken.

private (writable running disabled, startup enabled)

Edit a private copy of the startup configuration, no lock is taken.

exclusive (candidate enabled)

Lock the running configuration and the candidate configuration and edit the candidate configuration.

exclusive (candidate disabled, startup enabled)

Lock the running configuration (if enabled) and the startup configuration and edit the startup configuration.

shared (writable running enabled, candidate enabled)

Edit the candidate configuration without locking it.

Example:

admin@io> configure private
              Entering configuration mode "private"
              [ok][2006-06-02 12:31:59]
              [edit]
              admin%
file show <file>

Display contents of a <file>.

Example:

admin@io> file show /etc/skel/.bash_profile
              # /etc/skel/.bash_profile

              # This file is sourced by bash for login shells.  The following line
              # runs our .bashrc and is recommended by the bash info pages.
              [[ -f ~/.bashrc ]] &amp;&amp; . ~/.bashrc
              [ok][2006-06-02 12:31:59]
              admin@io>
file list <directory>

List files in <directory>.

Example:

admin@io> file list /config
              rollback0
              rollback1
              rollback2
              rollback3
              rollback4
              [ok][2006-06-02 12:31:59]
              admin@io>
help <command>

Display help text related to <command>.

Example:

admin@io> help request job
              Help for command: request job
              Job operations
              [ok][2006-06-02 12:31:59]
              admin@io>
request <path> <parameters>

Invokes the action found at path using the supplied parameters. For example, given the following action specification in a yang file:

tailf:action shutdown {
              tailf:actionpoint actions;
              input {
              tailf:constant-leaf flags {
              type uint64 {
              range "1 .. max";
              }
              tailf:constant-value 42;
              }
              leaf timeout {
              type xs:duration;
              default PT60S;
              }
              leaf message {
              type string;
              }
              container options {
              leaf rebootAfterShutdown {
              type boolean;
              default false;
              }
              leaf forceFsckAfterReboot {
              type boolean;
              default false;
              }
              leaf powerOffAfterShutdown {
              type boolean;
              default true;
              }
              }
              }
              }

the action can be invoked in the following way

admin@io> request shutdown timeout 10s message reboot options { forceFsckAfterReboot true }
request system logout user (<username> | <sessionid>)

Log out a specific user or session from the device. If the user held the configure exclusive lock, it will be released.

<username>

Log out a specific user.

<sessionid>

Terminate a specific session.

Example:

admin@io> show users
              SID USER  TYPE FROM      PROTO   LOGIN
              *4  admin cli  127.0.0.1 console 13:11:03
              3  oper  cli  127.0.0.1 console 13:11:01
              [ok][2006-06-02 12:31:59]
              admin@io> request system logout user oper
              [ok][2006-06-02 12:31:59]
              admin@io> show users
              SID USER  TYPE FROM      PROTO   LOGIN
              *4  admin cli  127.0.0.1 console 13:11:03
              [ok][2006-06-02 12:31:59]
              admin@io>
request message (all | <user>) <message>

Display a message on the screens of all users who are logged in to the device or on a specific screen.

all

Display the message to all currently logged in users.

<user>

Display the message to a specific user.

Example:

admin@io> request message oper "I will reboot system in 5 minutes."
              admin@io>

              oper@io> Message from admin@io at 13:16:41...
              I will reboot system in 5 minutes.
              EOF
request job stop <job id>

Stop a specific background job. In the default CLI the only command that creates background jobs is monitor start.

Example:

admin@io> monitor start /var/log/messages
        [ok][2006-06-02 12:31:59]
        admin@io> show jobs
        JOB COMMAND
        3   monitor start /var/log/messages
        [ok][2006-06-02 12:31:59]
        admin@io> request job stop 3
        [ok][2006-06-02 12:31:59]
        admin@io> show jobs
        JOB COMMAND
        [ok][2006-06-02 12:31:59]
        admin@io>
set (complete-on-space | ignore-leading-space | idle-timeout | paginate | screen length | screen width | terminal |autowizard | show defaults) <value>

Set CLI properties.

Example:

admin@io> set autowizard true
        [ok][2006-06-02 12:31:59]
        admin@io>
set-path <path>

This commands lets you 'cd' into a status part of the tree. Similar to the 'edit' command in configure mode.

show cli

Display CLI properties.

Example:

admin@io> show cli
        cli {
        autowizard true;
        complete-on-space true;
        ignore-leading-space false;
        history 100;
        idle-timeout 1800;
        output {
        file terminal;
        }
        paginate true;
        screen {
        length 82;
        width 80;
        }
        show {
        defaults false;
        }
        terminal xterm;
        }
        [ok][2006-06-02 12:31:59]
        admin@io>
show cli history [<limit>]

Display CLI command history. By default the last 100 commands are listed. The size of the history list is configured using the history CLI setting. If you specify a history limit, only the last number of commands up to that limit will be shown.

Example:

admin@io> show cli history
        06-19 14:34:02 -- ping router
        06-20 14:42:35 -- show configuration
        06-20 14:42:37 -- show users
        06-20 14:42:40 -- show cli history
        [ok][2006-06-20 14:42:40]
        admin@io> show cli history 3
        14:42:37 -- show users
        14:42:40 -- show cli history
        14:42:46 -- show cli history 3
        [ok][2006-06-20 14:42:46]
        admin@io>
show all [details] [<pathfilter>]

Display both configuration and status. By default the whole configuration and the whole status tree is displayed. It is possible to limit what is shown by supplying a pathfilter.

The pathfilter may be either a path pointing to a specific instance, or if an instance id is omitted, the part following the omitted instance is treated as a filter.

show configuration [details] [<pathfilter>]

Display current configuration. By default the whole configuration is displayed. It is possible to limit what is shown by supplying a pathfilter.

The pathfilter may be either a path pointing to a specific instance, or if an instance id is omitted, the part following the omitted instance is treated as a filter.

Example:

To show the aaa settings for the admin user, you can do:

admin@io> show configuration aaa authentication users user admin
        uid 100;
        gid 10;
        password $1$feedbabe$nGlMYlZpQ0bzenyFOQI3L1;
        ssh_keydir /var/confd/homes/admin/.ssh;
        homedir /var/confd/homes/admin;
        [ok][2006-07-31 17:16:01]
        admin@io>

To show all users that have group id 10, you would omit the user id, and instead specify gid 10.

admin@io> show configuration aaa authentication users user gid 10
        user admin {
        uid 100;
        gid 10;
        password $1$feedbabe$nGlMYlZpQ0bzenyFOQI3L1;
        ssh_keydir /var/confd/homes/admin/.ssh;
        homedir /var/confd/homes/admin;
        }
        user oper {
        uid 100;
        gid 10;
        password $1$feedbabe$i2glnaB.iUj2VXh/zlq.o/;
        ssh_keydir /var/confd/homes/oper/.ssh;
        homedir /var/confd/homes/oper;
        }
        [ok][2006-07-31 17:16:56]
        admin@io>
show parser dump <command prefix>

Shows all possible commands starting with command prefix.

show status <pathfilter>

Display current values of read-only nodes in the configuration.

show table <path>

This command shows the configuration as a table provided that path leads to a list element.

Example:

admin@io 09:42:08> show table aaa authentication groups group
        NAME   GID  USERS
        ---------------------------
        admin       admin private
        oper        oper public
        [ok][2007-09-17 09:44:12]

        [edit]
        admin@io 09:44:12> 
show users

Display currently logged on users. The current session, i.e. the session running the show status command, is marked with an asterisk.

Example:

admin@io> show users
        SID USER  TYPE FROM      PROTO   LOGIN
        *4  admin cli  127.0.0.1 console 13:11:03
        3  oper  cli  127.0.0.1 console 13:11:01
        [ok][2006-06-02 12:31:59]
        admin@io>
show jobs

Display currently running background jobs.

Example:

admin@io> show jobs
        JOB COMMAND
        3   monitor start /var/log/messages
show log <file>

Display contents of a log file.

Example:

admin@io> show log messages
source <file>

Execute commands from <file> as if they had been entered by the user. The autowizard is disabled when executing commands from the file.

commit (abort | confirm) [persist-id <id>]

Abort or confirm a pending confirming commit. A pending confirming commit will also be aborted if the CLI session is terminated without doing commit confirm. The default is confirm.

If the confirming commit has been initiated with the persist option then user needs to supply the same token as a persist-id for the commit to have effect.

Example:

admin@io> commit abort
describe <command>

Display detailed information about a command.

Example:

admin@io> describe ping
Common
    Source : clispec
    File   : commands-c.cli

Callback [os command]
    OS command  : ping
    Run as user : confd

Help
    Verify IP (ICMP) connectivity to a host.

Info
    Ping a host
              
timecmd <command>

Time command. It measures and displays the execution time of <command>.

Note that this command will only be available if devtools has been set to true in the CLI session settings.

Example:

io# timecmd id
user = admin(501), gid=20, groups=admin, gids=12,20,33,61,79,80,81,98,100
Command executed in 0.00 sec

[ok][2016-09-16 14:06:15]
io#

16.19.2. Configure mode commands

activate <statement>

Activate a statement that has previously been deactivated.

Only available in when the system has been configured with support for inactive.

deactivate <statement>

Deactivate a statement in the configuration.

Only available in when the system has been configured with support for inactive.

annotate <statement> <text>

Associate an annotation with a given configuration statement. To remove an annotation leave the text empty.

Only available in when the system has been configured with attributes enabled.

commit (check | and-quit | confirmed [<timeout>] [persist <token>] | to-startup) [comment <text>] [label <text>] [persist-id <id>]

Commit current configuration to running.

check

Validate current configuration.

and-quit

Commit to running and quit configure mode.

to-startup

Commit current configuration to running and startup configuration. Only available if the system is configured to have a startup configuration.

confirmed

Commits the current configuration to running with a timeout. If no commit confirm command has been issued before the timeout expires, then the configuration will be reverted to the configuration that was active before the commit confirmed command was issued. If no timeout is given then the confirming commit will have a timeout of 10 minutes. The configuration session will be terminated after this command since no further editing is possible. Only available in configure exclusive and configure shared mode when the system has been configured with a candidate.

The confirming commit will be rolled back if the CLI session is terminated before confirming the commit, unless the persist argument is given. If the persist command is given then the CLI session can be terminated and a later session may confirm the pending commit by supplying the persist token as an argument to the commit command using the persist-id argument.

comment <text>

Associate a comment with the commit. The comment can later be seen when examining rollback files.

label <text>

Associate a label with the commit. The label can later be seen when examining rollback files.

persist-id <id>

If a prior confirming commit operation has been performed with the persist argument, then to modify the ongoing confirming commit process the persist-id argument needs to be supplied with the same persist token. This makes it possible to, for example, abort an onging persist commit, or extend the timeout.

validate

Validates current configuration. This is the same operation as commit check.

insert <path>

Inserts a new element. If the element already exists and has the indexedView option set in the data model, then the old element will be renamed to element+1 and the new element inserted in its place.

insert <path> [first | last| before key| after key]

Insert a new element into an ordered list. The element can be added first, last (default), before or after another element.

move <path>[first|last|beforekey|afterkey]

Move an existing element to a new position in an ordered list. The element can be moved first, last (default), before or after another element.

rename <instance path> <new id>

Rename an instance.

delete <path>

Delete a data element.

edit <path>

Edit a sub-element. Missing elements in path will be created.

exit (level | configuration-mode)

level

Exit from this level. If performed on the top level, will exit configure mode. This is the default if no option is given.

configuration-mode

Exit from configuration mode regardless of which edit level.

help <command>

Shows help text for command.

hide <hide-group>

Re-hides the elements and actions belonging to the hide groups. No password is required for hiding. Note that this command is hidden and not shown during command completion.

unhide <hide-group>

Unhides all elements and actions belonging to the hide-group. You may be required to enter a password. Note that this command is hidden and not shown during command completion

load (merge | replace | override) (<file> | terminal)

Load configuration from file or terminal.

merge

Merge content of file/terminal with current configuration.

replace

Replace the content of file/terminal for the corresponding parts of the current configuration. This is different from override in the that only the parts that occur in the file/terminal are replace, the rest of the configuration is left as is. In the case of override the entire configuration is deleted (with the exception of hidden data) before loading the new configuration from the file/terminal.

There currently exists a discrepancy in behavior between different CLI:s and file formats. List nodes will be replaced for the following combinations:

  • Juniper CLI, XML and curly bracket format.

  • Cisco CLI, XML format.

List nodes will be merged for the following combination:

  • Cisco CLI, curly bracket format.

override

The current configuration is deleted and a new configuration is loaded from file/terminal. Hidden data is not affected.

The configuration file may contain replace: and delete: directives. For example if you have the configuration

system {
    parent-mo {
        child-mo 1 {
            attr 10;
        }
        child-mo 2 {
            attr 5;
        }
    }
}

and want to delete child-mo 2, you can create a configuration file containing either (using replace:)

system {
    replace:
    parent-mo {
        child-mo 1 {
            attr 2;
        }
    }
}

or (using delete:)

system {
    parent-mo {
        delete:
        child-mo 2 {
            attr 5;
        }
    }
}
save <file> [xml] [<pathfilter>]

Save the whole or parts of the current configuration to file. By the default the configuration is saved in curly bracket format. If the xml argument is given then the configuration is saved in XML format.

rollback [<number>]

Return the configuration to a previously committed configuration. The system stores a limited number of old configurations. The number of old configurations to store is configured in the confd.conf file. If more than the configured number of configurations are stored, then the oldest configuration is removed before creating a new one.

The most recently committed configuration (the running configuration) is number 0, the next most recent 1, etc.

The files are called rollback0 - rollbackX, where X is the maximum number of saved committed configurations.

Example:

admin@io% rollback 1
[ok][2006-06-02 12:31:59]
admin@io% 

Note that this command is only available if rollback has been enabled in confd.conf.

run <command>

Run command in operational mode.

set <path> [<value>]

Set a parameter. If a new identifier is created and autowizard is enabled, then the CLI will prompt the user for all mandatory sub-elements of that identifier. It will also prompt for mandatory action parameters.

If no <value> is provided, then the CLI will prompt the user for the value. No echo of the entered value will occur if <path> is an encrypted value, i.e. of the type tailf:md5-digest-string, tailf:des3-cbc-encrypted-string, or tailf:aes-cfb-128-encrypted-string as described in confd_types(3).

show [details] [<pathfilter>]

Show current configuration. The show command can be limited to a part of the configuration by providing a <pathfilter>.

show parser dump <command prefix>

Shows all possible commands starting with command prefix.

compare running [brief] [<pathfilter>]

Compare current configuration to the running configuration. Differences will be annotated with - (removed) and + (added). With the brief option, only the actual diffs will be shown.

compare startup [brief] [<pathfilter>]

Compare current configuration to the startup configuration. This command is only available when the system has been configured to have a startup configuration. With the brief option, only the actual diffs will be shown.

compare file <file> [brief] [<pathfilter>]

Compare current configuration to a configuration stored on file, i.e. previously saved using the save command. With the brief option, only the actual diffs will be shown.

tag add <statement> <tag>

Add a tag to a configuration statement.

Only available in when the system has been configured with attributes enabled.

tag del <statement> <tag>

Remove a tag from a configuration statement.

Only available in when the system has been configured with attributes enabled.

tag clear <statement>

Remove all tags from a configuration statement.

Only available in when the system has been configured with attributes enabled.

top [command]

Exit to top level of configuration, or execute a command at the top level of the configuration.

up [command]

Exit one level of configuration, or execute a command at one level up.

revert

Copy running configuration into current configuration.

status

Display users currently editing the configuration.

describe [<path> | <command>]

Display detailed information about a command. This information may for example consist of the source of the command (YANG, clispec or built-in), the corresponding path in the YANG file (in case of an auto-rendered command) and information regarding what callpoints, actionpoints and validation points that may be tied to the command. Due to the verbose information that may be displayed, it may be desirable to restrict the usage of this command by including it in an appropriate set of authorization rules or by the means of any other authorization functionality.

Example:

admin@io% describe dhcp
Common
    Source          : YANG
    Module          : dhcpd
    Namespace       : http://tail-f.com/ns/example/dhcpd
    Path            : /dhcp
    Node            : container
    Exported agents : all
    Checksum        : 3c893927631cceee3700c23bb38cd050
              
xpath [ctx <path>] (eval | must | when) <expression>

Evaluate an XPath expression. A context-path may be given to be used as the current context for the evaluation of the expression. If no context-path is given, the current sub-mode will be used as the context-path. The pipe command trace may be used to display debug/trace information during execution of the command.

Note that this command will only be available if devtools has been set to true in the CLI session settings.

eval

Evaluate an XPath expression.

must

Evaluate the expression as a YANG must expression.

when

Evaluate the expression as a YANG when expression.

timecmd <command>

Time command. It measures and displays the execution time of <command>.

Note that this command will only be available if devtools has been set to true in the CLI session settings.

Example:

io# timecmd status
Users currently editing the configuration:
admin console (cli from 127.0.0.1) on since 2016-09-16 14:15:29 private mode
Command executed in 0.00 sec

[ok][2016-09-16 14:16:01]

[edit]

io#

16.20. Commands in C/I-style

It is possible to get a full XML listing of the commands available in a running ConfD instance by using the confd option --cli-c-dump <file>, for C-style and --cli-i-dump for I-style. The generated file is only intended for documentation purposes and cannot be used as input to confdc.

16.20.1. Operational mode commands

The IOS CLI does not have any of the commands associated with transactions, i.e. commit, abort, show configuration.

The IOS CLI has commands for entering and leaving privileged mode, settings passwords and secrets and assigning privilege levels to commands in EXEC mode.

The privilege information for the IOS mode is stored in the AAA namespace under the aaa/ios element. Note that all EXEC commands are available at level 15 without needing to specify them in the aaa-configuration.

It is possible to assign custom prompt to the different levels in EXEC mode. The default is for level 0 to have the "\h> " prompt and for all other levels to have the "\h# " prompt.

compare startup [brief] [<pathfilter>]

Compare current configuration to the startup configuration. This command is only available when the system has been configured to have a startup configuration. Differences will be annotated with - (removed) and + (added). With the brief option, only the actual diffs will be shown.

compare file <file> [brief] [<pathfilter>]

Compare current configuration to a configuration stored on file, i.e. previously saved using the save command. Differences will be annotated with - (removed) and + (added). With the brief option, only the actual diffs will be shown.

config (terminal | shared | exclusive )

Enter configure mode. The default is terminal. The options have slightly different meaning depending on how the system is configured; with a writable running configuration, with a startup configuration, and with a candidate configuration.

terminal (writable running enabled)

Edit a private copy of the running configuration, no lock is taken.

terminal (writable running disabled, startup enabled)

Edit a private copy of the startup configuration, no lock is taken.

exclusive (candidate enabled)

Lock the running configuration and the candidate configuration and edit the candidate configuration.

exclusive (candidate disabled, startup enabled)

Lock the running configuration (if enabled) and the startup configuration and edit the startup configuration.

shared (writable running enabled, candidate enabled)

Edit the candidate configuration without locking it.

Example:

io# config terminal
Entering configuration mode terminal
io(config)#
enable (<level>)

Only available in IOS (i) mode. Enables privileged EXEC commands. The default level is 15. The CLI will prompt for a password if a password has been assigned to the level.

Example:

io> enable
io#
disable (<level>)

Only available in IOS (i) mode. Downgrade to a lower privilege level.

Example:

io# disable 4
io#
file show <file>

Display contents of a <file>.

Example:

io# file show /etc/skel/.bash_profile
# /etc/skel/.bash_profile

# This file is sourced by bash for login shells.  The following line
# runs your .bashrc and is recommended by the bash info pages.
[[ -f ~/.bashrc ]] &amp;&amp; . ~/.bashrc
io# 
file list <directory>

List files in <directory>.

Example:

io# file list /config
rollback0
rollback1
rollback2
rollback3
rollback4
io#
help <command>

Display help text related to <command>.

Example:

io# help config
Help for command: config
    Manipulate software configuration information
io#
id

Show user id information; uid, gid, and groups

Example:

io# id
user = joe(1000), gid=100, groups=wheel, gids=10,100
io#
message (all | <user>) <message>

Display a message on the screens of all users who are logged in to the device or on a specific screen.

all

Display the message to all currently logged in users.

<user>

Display the message to a specific user.

Example:

io# message all "I will reboot the system in 5 minutes."
Message from joe@io at 13:26:49...
I will reboot the system in 5 minutes.
EOF
io#
job stop <job id>

Stop a specific background job. In the default C-style CLI there are no commands that create background jobs. Custom commands can be created that do this.

Example:

io# show jobs
JOB COMMAND
1   monitor start /tmp/saved
io# job stop 1
io# show jobs
JOB COMMAND
io#
show cli

Display CLI properties.

Example:

io# show cli
autowizard           true
complete-on-space    true
ignore-leading-space false
history              50
idle-timeout         1800
output-file          terminal
paginate             true
screen-length        82
screen-width         80
show-defaults        false
terminal             xterm
io#
history [<limit>]

Display CLI command history. By default the last 100 commands are listed. The size of the history list is configured using the CLI history setting. If you specify a history limit, only the last number of commands up to that limit will be shown.

Example:

io# history
13:28:46 -- show jobs
13:28:53 -- job stop 1
13:29:05 -- show jobs
13:29:51 -- show
13:29:53 -- show cli
13:30:31 -- history
io#
show configuration commit list <id>

List rollback files (C-style only). Note that this command is only available if rollback has been enabled in confd.conf.

show notification stream <event stream name> [last <number of events>] [from <dateTime (ccyy-mm-dd|hh:mm:ss|ccyy-mm-ddThh:mm:ss)>] [to <dateTime (ccyy-mm-dd|hh:mm:ss|ccyy-mm-ddThh:mm:ss)>]

Display the last notifications in a selected stream. The stream must use the builtin store and have replay enabled. It is possible to limit the output by specifying the maximum number of events and/or a time range.

show parser dump <command prefix>

Shows all possible commands starting with command prefix.

show running-config [details | all] [<pathfilter>]

Display current configuration. By default the whole configuration is displayed. It is possible to limit what is shown by supplying a pathfilter. The pathfilter may be either a path pointing to a specific instance, or if an instance id is omitted, the part following the omitted instance is treated as a filter.

Example:

To show the aaa settings for the admin user, you can do:

io# show running-config aaa authentication users user admin
aaa authentication users user admin
uid        1000
gid        100
password   $1$fB$0w68PmacQ4VmE3/M3nK3Ug==
ssh_keydir /var/confd/homes/admin/.ssh
homedir    /var/confd/homes/admin
!
io#

To show all users that have group id 10, you would omit the user id, and instead specify gid 10.

io# show running-config aaa authentication users user gid 100
aaa authentication users user admin
uid        1000
gid        100
password   $1$fB$0w68PmacQ4VmE3/M3nK3Ug==
ssh_keydir /var/confd/homes/admin/.ssh
homedir    /var/confd/homes/admin
!
aaa authentication users user oper
uid        1000
gid        100
password   $1$S6$brGZW9wSDifHoU7Rf5KSHA==
ssh_keydir /var/confd/homes/oper/.ssh
homedir    /var/confd/homes/oper
!

Per default only elements that have been explicitly set to a value are shown. This makes it easier to handle large configurations. However, it is possible to force the show command to display all elements. This is done using the 'details' or 'all' options.

show startup-config [details | all] [<pathfilter>]

Display the startup configuration. This command is only available if ConfD has been configured with a startup configuration. By default the whole configuration is displayed. It is possible to limit what is shown by supplying a pathfilter. The pathfilter may be either a path pointing to a specific instance, or if an instance id is omitted, the part following the omitted instance is treated as a filter.

Per default only elements that have been explicitly set to a value are shown. This makes it easier to handle large configurations. However, it is possible to force the show command to display all elements. This is done using the 'details' or 'all' options.

write terminal [<pathfilter>]

Display current configuration.

copy running-config startup-config

Copy running configuration to startup configuration. Only available when the system has been configured to have a startup database.

write memory

Copy running configuration to startup configuration. Only available when the system has been configured to have a startup database.

source <file>

Execute commands from <file> as if they had been entered by the user. The autowizard is disabled when executing commands from the file.

show <pathfilter>

Display current values of read-only parameters. If a list element is encountered then the command attempts to arrange the output as a table.

who

Display currently logged on users. The current session, i.e. the session running the show status command, is marked with an asterisk.

Example:

io# who
Session User Context From      Proto   Date
*7      joe  cli     127.0.0.1 console 13:19:05
io#
logout (<username> | <sessionid>)

Terminates the current session.

logout (<username> | <sessionid>)

Log out a specific user or session from the device. If the user held the configure exclusive lock, it will be released.

<username>

Log out a specific user.

<sessionid>

Terminate a specific session.

Example:

io# who
Session User  Context From      Proto   Date
*5      admin cli     127.0.0.1 console 10:25:46
4      jb    cli     127.0.0.1 console 10:25:37
io# logout jb
io# who
Session User  Context From      Proto   Date
*5      admin cli     127.0.0.1 console 10:25:46
io#
show jobs

Display currently running background jobs.

Example:

io# show jobs
JOB COMMAND
2   monitor start /tmp/saved
io#
show log <file>

Display contents of a log file.

Example:

io# show log messages
commit (abort | confirm) [persist-id <id>]

Abort or confirm a pending confirming commit. A pending confirming commit will also be aborted if the CLI session is terminated without doing commit confirm. The default is confirm.

If the confirming commit was initiated with a persist argument then the same token needs to be supplied using the persist-id argument to this command.

Example:

io# commit abort
timestamp (enable | disable)

Display a timestamp after a command has been executed. The timestamp is displayed in the timezone UTC+-00:00 by default. A UTC offset may be configured in confd.conf.

Example:

io# timestamp enable
io# config
Tue Mar  12 11:31:03.698 UTC
Entering configuration mode terminal
io(config)#
describe <command>

Display detailed information about a command.

Example:

# describe ping
Common
    Source : clispec
    File   : commands-c.cli

Callback [os command]
    OS command  : ping
    Run as user : confd

Help
    Verify IP (ICMP) connectivity to a host.

Info
    Ping a host
                
timecmd <command>

Time command. It measures and displays the execution time of <command>.

Note that this command will only be available if devtools has been set to true in the CLI session settings.

Example:

io# timecmd pwd
At top level
Command executed in 0.00 sec

io#

16.20.2. Configure mode commands

alias ( <alias-name> <alias-expansion>)

Defines the alias alias-name. It will be expanded to alias-expansion.

It is possible to define parametrised aliases, i.e. aliases that accepts parameters. The parameters are then expanded when the alias is applied.

The alias can be used anywhere on the command line. After a command with an alias has been entered, the expanded command line is displayed so that you can verify the alias value.

For example:

io(config)# alias foo(a,b) "show $(a) ; show $(b)"
io(config)# alias myUser c87923
io(config)# commit
io(config)# foo(history,configuration)
io(config)# show history ; show configuration
...
io(config)# aaa authentication users user myUser
io(config)# aaa authentication users user c87923

The aliases are stored persistently in cdb in the aaa namespace. Note that the clispec file needs to contain the following three entries in the modifications section:

<dropElem src="alias expansion"/>
<multiValue src="alias expansion"/>
<suppressMode src="alias "/>
activate <statement>

Activate a statement in the configuration that has previously been deactivated.

Only available in when the system has been configured with support for inactive.

deactivate <statement>

Deactivate a statement in the configuration.

Only available in when the system has been configured with support for inactive.

annotate <statement> <text>

Associate an annotation with a given configuration statement. To remove an annotation leave the text empty.

Only available in when the system has been configured with attributes enabled.

tag add <statement> <tag>

Add a tag to a configuration statement.

Only available in when the system has been configured with attributes enabled.

tag del <statement> <tag>

Remove a tag from a configuration statement.

Only available in when the system has been configured with attributes enabled.

tag clear <statement>

Remove all tags from a configuration statement.

Only available in when the system has been configured with attributes enabled.

enable (secret | password) level <level> ( 0 | 7) <password>

Only available in IOS (i) mode. Configures a password for a specific EXEC level. If both a password and a secret is configured, the secret is used.

secret | password

Specifies how the password is to be encrypted

<level>

The EXEC level to password protect

0 | 7

Use 0 to indicate that the password given at the end of the command is in plain text, and 7 for an already encrypted password.

<password>

The actual password

Example:

io(config)# enable secret level 3 0 bluebox
io(config)#
privilege <mode> level <level> <command>

Only available in IOS (i) mode. Configures for which level a command should be available.

<mode>

In which mode is the command.

<level>

In which privilege level should the command be available

<command>

Command string.

Example:

io(config)# privilege exec level 4 show
io(config)# 
hide <hide-group>

Re-hides the elements and actions belonging to the hide groups. No password is required for hiding. Note that this command is hidden and not shown during command completion.

unhide <hide-group>

Unhides all elements and actions belonging to the hide-group. You may be required to enter a password. Note that this command is hidden and not shown during command completion

commit (check | and-quit | confirmed [<timeout>] [persist <token>] to-startup) [comment <text>] [label <text>] [persist-id <id>]

Commit current configuration to running.

check

Validate current configuration.

and-quit

Commit to running and quit configure mode.

to-startup

Commit current configuration to running and startup configuration. Only available if the system is configured to have a startup configuration.

confirmed

Commits the current configuration to running with a timeout. If no commit confirm command has been issued before the timeout expires, then the configuration will be reverted to the configuration that was active before the commit confirmed command was issued. If no timeout is given then the confirming commit will have a timeout of 10 minutes. The configuration session will be terminated after this command since no further editing is possible. Only available in configure exclusive and configure shared mode when the system has been configured with a candidate.

The confirming commit will be rolled back if the CLI session is terminated before confirming the commit, unless the persist argument is given. If the persist command is given then the CLI session can be terminated and a later session may confirm the pending commit by supplying the persist token as an argument to the commit command using the persist-id argument.

comment <text>

Associate a comment with the commit. The comment can later be seen when examining rollback files.

label <text>

Associate a label with the commit. The label can later be seen when examining rollback files.

persist-id <id>

If a prior confirming commit operation has been performed with the persist argument, then to modify the ongoing confirming commit process the persist-id argument needs to be supplied with the same persist token. This makes it possible to, for example, abort an onging persist commit, or extend the timeout.

validate

Validates current configuration. This is the same operation as commit check.

insert <path>

Inserts a new element. If the element already exists and has the indexedView option set in the data model, then the old element will be renamed to element+1 and the new element inserted in its place.

insert <path>[first|last|beforekey|afterkey]

Insert a new element into an ordered list. The element can be added first, last (default), before or after another element.

move <path>[first|last|beforekey|afterkey]

Move an existing element to a new position in an ordered list. The element can be moved first, last (default), before or after another element.

rename <instance path> <new id>

Rename an instance.

no <path>

Delete or unsets a data element.

exit (level | configuration-mode)
level

Exit from current mode. If performed on the top level, will exit configure mode. This is the default if no option is given.

configuration-mode

Exit from configuration mode regardless of mode.

help <command>

Shows help text for command.

load (<file> )

Load configuration from file.

pwd

Display current submode path.

save <file> [xml] [<pathfilter>]

Save the whole or parts of the current configuration to file.

rollback configuration [<number>]

Return the configuration to a previously committed configuration. The system stores a limited number of old configurations. The number of old configurations to store is configured in the confd.conf file. If more than the configured number of configurations are stored, then the oldest configuration is removed before creating a new one.

The most recently committed configuration (the running configuration) is number 0, the next most recent 1, etc.

The files are called rollback0 - rollbackX, where X is the maximum number of saved committed configurations.

Example:

io(config)# rollback configuration 1
io# 

Note that this command is only available if rollback has been enabled in confd.conf.

do <command>

Run command in operational mode.

show configuration [<pathfilter>]

Show current configuration buffer. The show command can be limited to a part of the configuration by providing a <pathfilter>.

show configuration diff [<pathfilter>]

Show configuration changes in diff style, ie new lines prefixed with a plus (+) sign, and removed lines prefixed with a minus (-) sign.. The show command can be limited <pathfilter>.

show configuration commit changes <id>

Show changes that were committed for a given commit id.

show configuration commit list <id>

List rollback files (C-style only). Note that this command is only available if rollback has been enabled in confd.conf.

show configuration rollback changes <nr>

Show changes for rolling back to rollback file nr.

show full-configuration [details] [<pathfilter>]

Show current configuration. The show command can be limited to a part of the configuration by providing a <pathfilter>.

show parser dump <command prefix>

Shows all possible commands starting with command prefix.

revert

Copy running configuration into current configuration.

clear

Remove all configuration changes.

describe [<path> | <command>]

Display detailed information about a command. This information may for example consist of the source of the command (YANG, clispec or built-in), the corresponding path in the YANG file (in case of an auto-rendered command) and information regarding what callpoints, actionpoints and validation points that may be tied to the command. Due to the verbose information that may be displayed, it may be desirable to restrict the usage of this command by including it in an appropriate set of authorization rules or by the means of any other authorization functionality.

Example:

(config)# describe dhcp
Common
    Source          : YANG
    Module          : dhcpd
    Namespace       : http://tail-f.com/ns/example/dhcpd
    Path            : /dhcp
    Node            : container
    Exported agents : all
    Checksum        : 3c893927631cceee3700c23bb38cd050
              
xpath [ctx <path>] (eval | must | when) <expression>

Evaluate an XPath expression. A context-path may be given to be used as the current context for the evaluation of the expression. If no context-path is given, the current sub-mode will be used as the context-path. The pipe command trace may be used to display debug/trace information during execution of the command

Note that this command will only be available if devtools has been set to true in the CLI session settings.

eval

Evaluate an XPath expression.

must

Evaluate the expression as a YANG must expression.

when

Evaluate the expression as a YANG when expression.

timecmd <command>

Time command. It measures and displays the execution time of <command>.

Note that this command will only be available if devtools has been set to true in the CLI session settings.

Example:

io# timecmd pwd
At top level
Command executed in 0.00 sec

io#

16.21. Customizing the CLI

16.21.1. Modifying builtin commands

There are a number of built-in commands in each CLI style. These can be modified in a number of ways. It is possible to remove them, rename them, hide them, change their help and info texts, add a command timeout and to add confirmation prompts. This is done using the <modifications> section of the clispec file. For example:

<modifications>
  <confirmText src="configure">
    Are your really sure you know what you are doing?
  </confirmText>
  <delete src="request system logout"/>
  <delete src="show log"/>
  <help src="configure private">
    Enter private configuration mode.
  </help>
  <info src="configure">Hi there info configure!</info>
  <help src="configure">Hi there help configure!</help>
  <timeout src="show configuration">
  10
  </timeout> -->
</modifications>

See the clispec.5 man page for a detailed description of each modifications option.

16.21.2. Adding new commands

New commands can be added in two different ways, either as an action in the YANG file, or as a command in the clispec file. The advantage of using an action is that the command will be available through all northbound interfaces. However, a clispec command may give you better control over your input parameters.

It is also possible to use a dedicated data model for the CLI, i.e. a YANG file that is only visible (exported) in the CLI. This is useful if you want to add custom modes in the C- and I-style CLIs.

16.21.3. Suppressing automatically generated modes

The C- and I- style CLIs will automatically create new modes for all list elements in the configuration, i.e. all elements that have maxOccurs larger than 1.

It is possible to suppress this behavior by adding a suppressMode direction in the modifications section of the clispec file.

For example:

<modifications>
  <suppressMode src="config hosts host"/>
</modifications>

The src attribute is the clispec path as it appears in the CLI. It should be the path to a list element.

16.21.4. Creating new configuration modes

Similarly to suppressing an automatically generated mode it is sometimes desirable to create modes at points in the configuration where there isn't a list element. This can be done trough a declaration in the modifications section of the clispec file.

For example:

<modifications>
  <addMode src="config hosts"/>
</modifications>

The src attribute should be a path to a static/internal element, i.e. an element with minOccurs="1" maxOccurs="1".

16.21.5. Custom mode names

ConfD automatically assigns a mode name based on the element name and the key elements of the container. There are two styles, full and short, where the short style only contains the last element of the path and the full all components of the path. Which style to use is configured in the confd.conf file.

The automatic mode name can be overridden either by a fixed mode name or by a dynamically generated mode name. It is done through a modeName declaration in the modifications section of the clispec file.

For example:

<modifications>
  <modeName src="config hosts">
    <fixed>hosts</fixed>
  </modeName>
  <modeName src="config hosts host interfaces interface">
    <capi><cmdpoint>custommode</cmdpoint></capi>
  </modeName>
</modifications>

ConfD will invoke the cmdpoint/action custommode the first time the mode is entered for a given instance. It will then cache the mode name. The callback will receive the path to the instance as argv/argc arguments and is expected to reply by calling the function confd_action_reply_command().

An example from actions.c in the cli/c_cli example:

static int do_modename(struct confd_user_info *uinfo,
                       char *path, int argc, char **argv)
{
    int i;
    int sock;
    char *mode = "config-priv";

    printf("do_modename called\n");

    printf("path: %s\n", path);
    for (i = 0; i < argc; i++) {
        printf("param %2d: %s\n", i, argv[i]);
    }

    if (confd_action_reply_command(uinfo, &amp;mode, 1) < 0)
        confd_fatal("Failed to reply to confd\n");

    return CONFD_OK;
}

16.21.6. Adding custom show output

It is possible to override the default output from the auto-rendered show commands but not for the J-style 'show configuration', 'show status', 'show all', and 'show table'. It can be done in two different ways. Either using a show element in the clispec file or as a regular CLI command.

For example:

<show path="aaa authentication users user">
  <callback>
    <exec>
      <osCommand>./aaa_auth.sh</osCommand>
    </exec>
  </callback>
</show>

The aaa_auth.sh executable will be invoked whenever the user enters "show aaa authentication users user" or a path prefix. The command will receive the indent depth and path as arguments. The callback can be either a C-function (capi), or an executable, and it will be invoked as an ordinary CLI command.

It is also possible to create an ordinary CLI command and mount it on the same path as the show command target.

For example:

<cmd name="group" mount="show aaa authentication groups">
  <help></help>
  <info></info>
  <callback>
    <exec>
      <osCommand>./aaa_group.sh</osCommand>
    </exec>
  </callback>
</cmd> 

The advantage with this approach is that the command may take additional parameters, for example 'details' or 'statistics'.

16.21.7. Command parameters

A custom CLI command can be defined to have a set of parameters. These parameters can be arranged as a mix of:

  • a straight list of command options

  • a parameter tree

  • a choice list of parameters, where a minimum and maximum number of required parameters can be specified

Suppose you want a command that accepts a number of options in an arbitrary order. For example:

show alarm [type <type>] [severity <minor|major>] [acknowledged] [active]

The parameters can be entered in arbitrary order and they are all optional. This can be achieved with a choice params list with min and max set.

<params mode="choice" min="0" max="4">
  <param>
    <info/><help/>
    <name>type</name>
    <prefix>--type </prefix>
  </param>
  <param>
    <info/><help/>
    <name>severity</name>
    <type><enums>major minor</enums></type>
    <prefix>--severity </prefix>
  </param>
  <param>
    <info/><help/>
    <type><enums>acknowledged</enums></type>
    <prefix>--acknowledged</prefix>
  </param>
  <param>
    <info/><help/>
    <type><enums>active</enums></type>
    <prefix>--active</prefix>
  </param>
</params>

Suppose instead that you want the following command:

show alarm [type <type> severity <minor|major>] [acknowledged] [active]

That is, if you enter type you must also enter severity. You can specify this with a parameter tree where severity is a child to the type parameter.

<params mode="choice" min="0" max="3">
  <param>
    <info/><help/>
    <name>type</name>
    <prefix>--type </prefix>
    <params>
      <param>
        <info/><help/>
        <name>severity</name>
        <type><enums>major minor</enums></type>
        <prefix>--severity </prefix>
      </param>
    </params>
  </param>
  <param>
    <info/><help/>
    <type><enums>acknowledged</enums></type>
    <prefix>--acknowledged</prefix>
  </param>
  <param>
    <info/><help/>
    <type><enums>active</enums></type>
    <prefix>--active</prefix>
  </param>
</params>

You can have nested params lists where some are of choice mode and others are straight lists. However, in a choice list there cannot be two possible paths given a token, i.e., you cannot have two items that have the same name, or one named item and one that accepts a generic value. All paths must be deterministic.

For example, you cannot have the following command parameters:

<params mode="choice" min="0" max="2">
  <param>
    <info/><help/>
    <prefix>--type </prefix>
  </param>
  <param>
    <info/><help/>
    <type><enums>major minor</enums></type>
    <prefix>--severity </prefix>
  </param>
</params>

The reason is that if you enter the parameter major, then the CLI parser cannot determine if it is intended as the first parameter or the second. The first parameter accepts any input.

16.21.8. Hiding parts of the configuration

It is possible to hide parts of the configuration using the hidden attribute in the yang files, and the hideGroup attribute in the clispec file. All elements with the same hidden attribute belong to the same 'hide group'

For example (yang):

leaf resetuser {
  tailf:hidden debug;
  type boolean;
  default false;
}

For example (clispec):

<cmd name="test">
  <help/>
  <info/>
  <callback>
    <exec>
      <osCommand>
        test.sh
      </osCommand>
    </exec>
  </callback>
  <options>
    <hideGroup>debug</hideGroup>
  </options>
</cmd>

In the yang example the resetuser leaf belongs to the debug hide group. All hidden yang elements must have default values or be optional since they cannot be configured by the user unless they have been unhidden.

Elements hidden in this way will be hidden to users when using the Web UI or the CLI, but can optionally be made visible, i.e. unhidden, through a hidden CLI command. An entry in the confd.conf file is needed to make this possible.

For example:

<hideGroup>
  <name>debug</name>
  <password>verysecret</password>
</hideGroup>

The debug hide group can be 'unhidden' in the CLI provided that the user knows the name of the hide group and the password. It is possible to leave out the password parameter in which case the CLI will not prompt for one. The unhide and hide commands are used to interactively hide and unhide hide groups in the CLI.

It is also possible to define a C-callback that is used to authenticate the user. This is useful when you want short lived 'unhide' password, or user-specific unhide password.

Note that CLI commands and actions can also be hidden in the same way, but not individual action parameters. Also, hidden elements are only hidden from the CLI and the Web UI unless the special hide group full is used, in which case it is hidden from all northbound interfaces as well as the rollback file.

The special hide groups full is useful when the data is only used by the application and should not be part of the actual configuration of the device.

16.21.9. EXEC commands

The I-style style has an additional concept of privilege levels. Only a subset of commands are initially available when the user logs on to the box. It is then possible to enable a higher privilege level using the enable command. Entering a new privilege level may require a password and the prompt may change as a result of entering the level.

The AAA data model contains a section for controlling which commands are available in the different levels, which prompt to use for each level and if a password or secret is configured.

The configuration mode commands enable and privilege are used for dynamically modifying this configuration. The initial configuration should be supplied in the aaa_init.xml file.

16.21.10. File access

The default behavior is to enforce Unix style access restrictions. That is, the users uid, gid, and gids are used to control what the user has read and write access to.

However, it is also possible to jail a CLI user to its home directory (or the directory where confd_cli is started). This is controlled using the confd.conf parameter /confdConfig/cli/restrictedFileAccess. If this is set to true, then the user only has access to the home directory, or if a directory is specified in a cli command parameter (params/param/type/directory{wd} or params/param/type/file{wd}) to that directory.

16.21.11. Help texts

Help and information texts are specified in a number of places. In the yang files the tailf:info element is used to specify a descriptive text that is shown when the user enters ? in the CLI. The first sentence of the description text is used when showing one-line descriptions in the CLI, e.g.:

In the YANG file:

list ifs {
  tailf:info "Configure interfaces";
  ...
}
list hosts {
  tailf:info "Configure hosts";
  ...
}
list routing-protocol {
  tailf:info "Routing protocols";
  ...
}

In the CLI:

io(config)# config ?
Possible completions:
  hosts                    Configure hosts
  ifs                      Configure interfaces
  routing-protocol         Routing protocols
io(config)# config

It is also possible to specify help texts for simpleTypes in the YANG files. For example:

typedef service-type {
    type enumeration {
        enum http { tailf:info "Web server"; }
        enum smtp { tailf:info "Mail server"; }
    }
}

typedef service-name {
    tailf:info "Name of service";
    type string;
}

When used in the CLI it looks like this:

io(config)# server ?
<name:server type [smtp|www|imap]>
io(config)# server

It is also possible to modify the help texts for built-in types using the /clispec/$MODE/modifications/typehelp element. For example:

<typehelp type="unsignedShort">integer</typehelp>

16.22. User defined wizards

If our configuration contains large structures that are nontrivial to configure in the CLI, we probably wish to add tailor-made wizards to the CLI which aid the user in the process. Typically we want a wizard to interact with the user, prompt the user, read some responses, and depending on the responses, populate some structures with reasonable default values depending on the user's responses.

We can write our wizards either as executables or as callbacks. In this section we show how to add a user to the AAA namespace using a shell script.

The wizard code needs to be able to perform the following tasks:

  • It must be able to interact with the user, i.e. it must be able to read and write to the CLI terminal.

  • It must be able to read and write to the db session which is used by the CLI. The CLI will start a db session whenever it enters configuration mode, the wizard code must be able to read and write, not to the database, but to the particular db session which is used by the running CLI. This is done in a shell script using the maapi command which will attach to the current CLI session.

The command to invoke the wizard is added by editing the confd.cli file, and recompile it. The workings of the confd.cli file is fully described in the UNIX man page clispec(5). A new wizard may be added by adding the following in the confd.cli file:

.....
<configureMode>
  .....
  <cmd name="wizard">
    <info>Configuration wizards</info>
    <help>Configuration wizards</help>
    <cmd name="adduser">
      <info>Create a Confd user</info>
      <help>
        Create a Confd user and assign him/her to the proper group
        to control what parts of the system he/she has access to.
      </help>
      <callback>
        <exec>
          <osCommand>./adduser.sh</osCommand
          <args> </args>
        </exec>
      </callback>
    </cmd>
  </cmd>
</configureMode>

This way, once inside configuration mode, the command "wizard adduser" will be available. The type of the callback is <exec>, indicating that the wizard is implemented as an executable.

For example, adduser.sh:

#!/bin/bash

## Ask for user name
while true; do
    echo -n "Enter user name: "
    read user

    if [ ! -n "${user}" ]; then
	echo "You failed to supply a user name."
    elif maapi --exists "/aaa:aaa/authentication/users/user{${user}}"; then
	echo "The user already exists."
    else
	break
    fi
done

## Ask for password
while true; do
    echo -n "Enter password: "
    read -s pass1
    echo

    if [ "${pass1:0:1}" == "$" ]; then
	echo -n "The password must not start with $. Please choose a "
	echo    "different password."
    else
	echo -n "Confirm password: "
	read -s pass2
	echo

	if [ "${pass1}" != "${pass2}" ]; then
	    echo "Passwords do not match."
	else
	    break
	fi
    fi
done

groups=`maapi --keys "/aaa:aaa/authentication/groups/group"`
while true; do
    echo "Choose a group for the user."
    echo -n "Available groups are: "
    for i in ${groups}; do echo -n "${i} "; done    
    echo
    echo -n "Enter group for user: "
    read group

    if [ ! -n "${group}" ]; then
	echo "You must enter a valid group."
    else
	for i in ${groups}; do
	    if [ "${i}" == "${group}" ]; then
		# valid group found
		break 2;
	    fi
	done
	echo "You entered an invalid group."
    fi
    echo
done

echo "Creating user"

maapi --create "/aaa:aaa/authentication/users/user{${user}}"
maapi --set "/aaa:aaa/authentication/users/user{${user}}/password" "${pass1}"

echo "Setting home directory to: /var/confd/homes/${user}"
maapi --set "/aaa:aaa/authentication/users/user{${user}}/homedir" \
            "/var/confd/homes/${user}"

echo "Setting ssh key directory to: /var/confd/homes/${user}/ssh_keydir"
maapi --set "/aaa:aaa/authentication/users/user{${user}}/ssh_keydir" \
            "/var/confd/homes/${user}/ssh_keydir"

maapi --set "/aaa:aaa/authentication/users/user{${user}}/uid" "1000"
maapi --set "/aaa:aaa/authentication/users/user{${user}}/gid" "100"

echo "Adding user to the ${group} group."
gusers=`maapi --get "/aaa:aaa/authentication/groups/group{${group}}/users"`

for i in ${gusers}; do
    if [ "${i}" == "${user}" ]; then
	echo "User already in group"
	exit 0
    fi
done

maapi --set "/aaa:aaa/authentication/groups/group{${group}}/users" \
            "${gusers} ${user}"



16.23. User defined wizards in C

We can write precisely the same wizard in C as well. This example makes use of the MAAPI interface, described in the UNIX man page confd_lib_maapi(3) as well as in the user guide chapter "MAAPI - Management Agent API". Thus to fully understand this section, the MAAPI documentation must be read.

Similar to the shell script wizard we must modify the clispec file "confd.cli" to indicate the name of a program to execute. We have:

<configureMode>
  .....
  <cmd name="wizard">
    <info>Configuration wizards</info>
    <help>Configuration wizards</help>

    <cmd name="cadduser">
      <info>Add a user</info>
      <help>Add a user</help>
      <callback>
        <exec>
          <osCommand>/usr/local/bin/maapi_add_user</osCommand>
          <options>
            <uid>user</uid>
          </options>
        </exec>
      </callback>
    </cmd>
    ....
  </cmd>
</configureMode>

Using our modified "confd.cli", a command called "wizard cadduser" will be available in the CLI configuration mode. When this CLI command is executed, the ConfD CLI will invoke the external program called "/usr/local/bin/maapi_add_user".

This program will execute under a pseudo terminal (pty) which is connected to the actual CLI terminal. Thus the external programs invoked by the CLI can manipulate the terminal - not just stdin and stdout.

The invoked program will have two environment variables set which can be used in the MAAPI interface to create an attached MAAPI session towards the currently executing transaction in the CLI. Thus the program must read "CONFD_MAAPI_USID" and "CONFD_MAAPI_THANDLE" from its environment.

Another thing which is different in the C implementation of a CLI wizard is that the C code must be explicitly aware of which namespace it wants to manipulate. In our case, where we wish to add a user, we wish to manipulate the AAA namespace, "http://tail-f.com/ns/aaa/1.1". The data model defining the AAA namespace is included in a ConfD release and when the data model is compiled a .h file is generated which contains the symbols defined in the namespace. This .h file must be included. Thus:

.....

#include "confd_lib.h"
#include "confd_maapi.h"
#include "aaa_bridge.h"

int main(int argc, char **argv)
{
    int msock;
    int debuglevel = CONFD_DEBUG;
    struct in_addr in;
    struct sockaddr_in addr;
    int usid, thandle;
    char user[255], *pwd, home[255], sshdir[255];
    char buf[BUFSIZ];
    inet_aton("127.0.0.1", &amp;in);
    addr.sin_addr.s_addr = in.s_addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(4565);

    confd_init("adduser", stderr, debuglevel);
    confd_load_schemas((struct sockaddr*)&amp;addr,
                       sizeof (struct sockaddr_in));
    if ((msock = socket(PF_INET, SOCK_STREAM, 0)) < 0 )
        confd_fatal("Failed to open socket\n");

    if (maapi_connect(msock, (struct sockaddr*)&amp;addr,
                      sizeof (struct sockaddr_in)) < 0)
        confd_fatal("Failed to confd_connect() to confd: %s\n",
                    confd_lasterr());
    usid = atoi(getenv("CONFD_MAAPI_USID"));
    thandle = atoi(getenv("CONFD_MAAPI_THANDLE"));

    if ((maapi_attach2(msock, aaa__ns, usid, thandle)) != CONFD_OK)
        confd_fatal("Failed to attach: %s\n", confd_lasterr());

  again0:
    printf("Adding a user\n");
    printf("Username: ");
    if ((fgets(user,255, stdin)) == NULL)
        exit(1);
    user[strlen(user)-1] = 0;
    if (maapi_cd(msock,thandle,"/aaa/authentication/users") != CONFD_OK)
        confd_fatal("cannot CD: %s", confd_lasterr());

    /* check if user exists */
    if (maapi_exists(msock, thandle,"user{%s}", user) == 1) {
        printf("user %s already exists: %s\n", user, confd_lasterr());
        goto again0;
    }

  again:
    if ((pwd = getpass("Password: ")) == NULL)
        exit(1);
    strcpy(buf, pwd);
    if ((pwd = getpass("Confirm password: ")) == NULL)
        exit(1);
    if (strcmp(pwd, buf) != 0) {
        printf("Password not confirmed\n");
        goto again;
    }

    printf("Home: ");
    if ((fgets(home,255,stdin)) == NULL)
        exit(1);
    home[strlen(home)-1] = 0;


    printf("SSH dir: ");
    if ((fgets(sshdir, 255, stdin)) == NULL)
        exit(1);
    sshdir[strlen(sshdir)-1] = 0;



    if (maapi_create(msock,thandle,"user{%s}",user) != CONFD_OK)
        confd_fatal("failed to create user %s: %s\n", user, confd_lasterr());

    if (maapi_set_elem2(msock,thandle,sshdir,"user{%s}/ssh_keydir",user) !=
        CONFD_OK)
        confd_fatal("failed to set ssh keydir: %s\n", confd_lasterr());

    if (maapi_set_elem2(msock,thandle,pwd,"user{%s}/password",user) !=
        CONFD_OK)
        confd_fatal("failed to set password: %s\n", confd_lasterr());

    if (maapi_set_elem2(msock,thandle,home,"user{%s}/homedir",user) !=
        CONFD_OK)
        confd_fatal("failed to set home: %s\n", confd_lasterr());

    printf("user %s added successfully \n", user);
    exit(0);
}

The code illustrates several points:

  • It reads the above mentioned environment variables and calls maapi_attach2() to attach to the transaction.

  • The code includes the generated .h file from the AAA namespace. Furthermore, since the code is manipulating the AAA namespace.

  • It makes use of the libc function getpass() which opens "/dev/tty" to read a password without echoing the characters entered by the user.

  • It uses the MAAPI interface to read and write data. Once the program returns, the data written by the program is still not committed. Not until the user executes the commit command in the CLI will the data be actually written to the database opened by the CLI, whether running or the candidate.

16.24. User defined commands in C using the C-API

A command can be implemented as a C-callback using the same API as used for actions, with some minor modifications of the input parameters.

The arguments to the command are passed as string params where the first param is the full name of the command, and the remaining params are the arguments that were used when invoking the command from the CLI.

Maapi contains five CLI related functions which can be used for reading and writing to the CLI from inside an action invoked from the CLI - maapi_cli_write, maapi_cli_printf, maapi_cli_prompt, maapi_cli_prompt_oneof, and maapi_cli_read_eof.

Similar to commands implemented as executables, there is an option in the confd.cli file for specifying that the command is implemented through a CAPI callback. It may look like this:

<configureMode>
  ...
    <cmd name="ctest">
      <info>C-API command example</info>
      <help>C-API command example</help>
      <callback>
        <capi>
          <cmdpoint>testcommand</cmdpoint>
        </capi>
      </callback>
    </cmd>
  ...
</configureMode>

The capi tag tells confd that the command is implemented using CAPI and the cmdpoint is the name of the action callback to invoke when the command is used from the CLI.

16.25. User defined commands as shell scripts

ConfD comes with a small C program called maapi. This program can be used inside shell scripts that are defined as CLI commands, as exemplified in the add_user.sh script above. The maapi program is thoroughly described in the man page maapi(1).

The program attaches itself to the current transaction using maapi_attach() (see confd_lib_maapi(3)) and executes a single change.

16.26. Modifying built-in commands

There are a number of built-in commands which can be modified in a number of ways. There should not be confused with the auto-rendered commands which cannot be modified in the same way. The auto-rendered commands are derived from the data-model at run-time and does not exist when confd is started. The section below only relates to the built-in commands.

16.26.1. Renaming a command

A built-in command often consists of a command name part and a parameter part. For example, the command config in C-mode has the name config and takes an optional parameter which can be either terminal or exclusive.

It is possible to rename the command config but not the command argument. I.e. the following is possible,

<operationalMode>
  <modifications>
    <move src="config" dest="configure"/>
  </modifications>
</operationalMode>

The following will not work since the command is config not config terminal.

<operationalMode>
  <modifications>
    <move src="config terminal" dest="config private"/>
  </modifications>
</operationalMode>

In the general case it is difficult to know what are commands and what are arguments to the command. The above could have been defined as two commands config private and config exclusive without affecting the CLI behavior. Using confd --cli-c-dump can be used for determining which part is a command name and which parts are command arguments.

16.26.2. Hiding the old, creating new

If you want to change the way a builtin command works, for example the config command above. There is a trick that can be used. It consists of renaming the original command and hiding it. Then add your own command and have it invoke the original hidden command.

Suppose we want to change the config command above to take the parameters private and exclusive instead of terminal and exclusive. This is the way to do it:

<operationalMode>
  <modifications>
    <move src="config" dest="xxconfig"/>
    <hide src="xxconfig"/>
  </modifications>
    <cmd name="config">
      <info>Manipulate software configuration information</info>
      <help>Manipulate software configuration information</help>
      <callback>
        <exec><osCommand>/usr/local/bin/config.sh</osCommand></exec>
      </callback>
      <params>
        <param>
          <type>
            <enumerate>
              <enum>
                <name>private</name>
                <info>non-locked editing of configuration</info>
              </enum>
              <enum>
                <name>exclusive</name>
                <info>locked editing of configuration</info>
              </enum>
            </enumerate>
          </type>
        </param>
      </params>
    </cmd>
</operationalMode>
#!/bin/bash

case $1 in
private)
        maapi --clicmd --no-hidden 'xxconfig terminal'
        ;;
shared)
        maapi --clicmd --no-hidden 'xxconfig shared'
        ;;
*)
        maapi --clicmd --no-hidden 'xxconfig terminal'
        ;;
esac

16.27. Tailoring show commands

There are several ways show commands can be tailored in the CLI. The data model can be modified, explicit commands can be defined in the clispec files, the auto-rendered commands can be tweaked using clispec modifications, specific show callbacks can be defined in the clispec files, and show templates can be defined in the clispec files.

16.27.1. How config="false" data is rendered

By default the CLI will create show commands in operational mode for displaying config="false" data. Leaves and containers will be displayed as Name-Value pairs whereas list elements will be displayed as tables, provided that the table will fit on the terminal screen.

A leaf element is rendered as follows:

Rendering of leaves and containers

Two different algorithms are used when rendering list elements. One for rendering a single element and one for rendering multiple elements (either the entire table or a subset of the table).

When rendering a single element the following method is used:

Rendering of a single list element

And when rendering a set of list elements the following is used:

Rendering of a set of list elements

16.27.2. Show templates

Show templates can be used in a few different ways. Either as a replacement for the default Name-Value rendering, or for replacing the auto-rendered tables. By default only the Name-Value rendering is replaced when a show template is defined, i.e. the show template will only be invoked for list elements if the table is too wide for the screen (or if table view has been suppressed in some other way).

In order to also replace the default table rendering with the show template the auto-rendered table needs to be suppressed. This is done using the YANG tailf:cli-suppress-table statement in the YANG file.

If a show template is used for rendering a table then the show template needs to render the table header, this is done using a tailf:cli-show-template-legend statement. It also needs to suppress the default enter text that is displayed for each instance. This is done by defining an empty tailf:cli-show-template-enter template. Finally, a show template needs to be defined for the list element node that renders each table line. A customized footer can be displayed by using a tailf:cli-show-template-footer statement.

The above will work fine when displaying an entire table. However, when displaying a single instance it might be desirable to either display it as a table line, in which case a table header also needs to be displayed, or in some other way. The problem is that the same show template is used in both situations.

The solution is to add a conditional in the template and display different texts in the two situations. For example ( from the example/cli/show_template/jdemo.yang):

tailf:cli-show-template
       "$(.legend_shown!=true?"
       +"Address         Interface   "
       +"$(.selected~=hwaddr?HW Address         )"
       +"$(.selected~=permanent?Permant  )"
       +"$(.selected~=published?Published)"
       +"$(.selected~=bignum?$(.show_bignum? Bignum ))\n"
       +"============================"
       +"$(.selected~=hwaddr?===================)"
       +"$(.selected~=permanent?=========)"
       +"$(.selected~=published?=========)"
       +"$(.selected~=bignum?$(.show_bignum?========))\n)"
       +"$(ip|ljust:15) $(ifname|ljust:9) - "
       +"$(.selected~=hwaddr?$(hwaddr|ljust:17)  )"
       +"$(.selected~=permanent?$(permanent|ljust:8) )"
       +"$(.selected~=published?$(published|ljust:7)  )"
       +"$(.selected~=bignum?$(.show_bignum?$(.humanreadable? "

In the example above the legend is only displayed if it has not already been displayed. This is achieved by inspecting the built-in variable .legend_shown. The same behavior can be achieved by using the substatement tailf:cli-auto-legend (see listing below). The example above also tests on the .selected variable to determine if each column has been selected to be displayed using the select pipe command.

tailf:cli-show-template
       "$(ip|ljust:15) $(ifname|ljust:9) - "
       +"$(.selected~=hwaddr?$(hwaddr|ljust:17)  )"
       +"$(.selected~=permanent?$(permanent|ljust:8) )"
       +"$(.selected~=published?$(published|ljust:7)  )"
       +"$(.selected~=bignum?$(.show_bignum?$(.humanreadable? " {
         tailf:cli-auto-legend;
      }

It is possible to ask confd to perform a validation of the paths that appear in the templates in the YANG files. This is done by running the command confd --cli-check-templates once confd has been started.

16.28. Change password at initial login

To force the user to change the password at initial login, or when the password has expired, a start script can be used.

The start script is specified in the clispec file. Only one start script can be present, if more are present (for example in different clispec files) then only one of them will be executed (unspecified which).

In the clispec file:

<start>
  <callback>
   <exec>
   <osCommand>./startup.sh</osCommand>
      <args>$(user)</args>
   </exec>
  </callback>
</start>

In startup.sh something along the lines of:

#!/bin/bash

user=$1
oldpass=`maapi --get "/aaa:aaa/authentication/users/user{${user}}/password"`

echo "oldpass=${oldpass}"

if [ ${oldpass} == '$1$Dd0v2$Rd899rbrbFTeHuEjAtzvW/' ]; then
     echo "You need to set a new password"

## Ask for password

     while true; do
         echo -n "Enter password: "
         read -s pass1
         echo

         if [ "${pass1:0:1}" == "$" ]; then
            echo -n "The password must not start with $. Please choose a "
            echo    "different password."
         else
            echo -n "Confirm password: "
            read -s pass2
            echo

            if [ "${pass1}" != "${pass2}" ]; then
                echo "Passwords do not match."
            else
                break
            fi
         fi
     done
## create new transaction and write password

     confd_cmd -r -m -c \
         "mset /aaa:aaa/authentication/users/user{${user}}/password ${pass1}"

fi

echo "Welcome!"

Note that the old password needs to be updated to your default startup password, or the test changed into something a bit more sophisticated.