Table of Contents
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.
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
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%
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.
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.
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)#
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.
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.
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
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.
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).
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).
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.
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.
If this argument is given, then the confd_cli program will be a bit more talkative during the ConfD handshake phase.
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.
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.
Force the CLI to provide a I-style CLI.
Force the CLI to provide a Juniper style CLI.
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.
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.
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.
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.
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.
Disables AAA. This is useful during development but should be removed in a production 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.
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.
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.
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>
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>
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.
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
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.
Character class, which matches any of the characters abc... Char- acter ranges are specified by a pair of characters separated by a -.
negated character class, which matches any character except abc....
Alternation. It matches either r1 or r2.
Concatenation. It matches r1 and then r2.
Matches one or more rs.
Matches zero or more rs.
Matches zero or one rs.
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;
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;
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
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.
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.
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
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.
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.
Ctrl-b or Left Arrow
Esc-b or Alt-b
Ctrl-f or Right Arrow
Esc-f or Alt-f
Ctrl-a or Home
Ctrl-e or End
Ctrl-h, Delete, or Backspace
Ctrl-d
Ctrl-k
Ctrl-u or Ctrl-x
Ctrl-w, Esc-Backspace, or Alt-Backspace
Esc-d or Alt-d
Ctrl-p or Up Arrow
Ctrl-n or Down Arrow
Ctrl-r
run the "show cli history" command
Esc-c
Esc-l
Esc-u
Ctrl-c
Ctrl-v/ESC-q
Ctrl-l
Ctrl-t
ESC-m
Ctrl-z
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"
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.
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 (").
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.
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.
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%
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.
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.
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
Controls if command completion should be attempted when <space> is entered. Entering <tab> always results in command completion.
Controls if certain commands that are useful for developers should be enabled. The commands xpath and timecmd are examples of such a command.
Controls if leading spaces should be ignored or not. This is useful to turn off when pasting commands into the CLI.
Size of CLI command history.
Maximum idle time before being logged out. Use 0 (zero) for for infinity.
Some commands paginate their output, for example. This can be disabled or enabled. It is enabled by default.
Current width of terminal. This is used when paginating output to get proper line count.
Current length of terminal. This is used when paginating output to get proper line count.
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.
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 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.
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.
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 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.
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.
Edit a private copy of the running configuration, no lock is taken.
Edit a private copy of the startup configuration, no lock is taken.
Lock the running configuration and the candidate configuration and edit the candidate configuration.
Lock the running configuration (if enabled) and the startup configuration and edit the startup configuration.
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%
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 ]] && . ~/.bashrc [ok][2006-06-02 12:31:59] admin@io>
List files in <directory>.
Example:
admin@io> file list /config rollback0 rollback1 rollback2 rollback3 rollback4 [ok][2006-06-02 12:31:59] admin@io>
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>
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 }
Log out a specific user or session from the device. If the user held the configure exclusive lock, it will be released.
Log out a specific user.
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>
Display a message on the screens of all users who are logged in to the device or on a specific screen.
Display the message to all currently logged in users.
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
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 CLI properties.
Example:
admin@io> set autowizard true [ok][2006-06-02 12:31:59] admin@io>
This commands lets you 'cd' into a status part of the tree. Similar to the 'edit' command in configure mode.
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>
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>
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.
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>
Shows all possible commands starting with command prefix.
Display current values of read-only nodes in the configuration.
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>
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>
Display currently running background jobs.
Example:
admin@io> show jobs JOB COMMAND 3 monitor start /var/log/messages
Display contents of a log file.
Example:
admin@io> show log messages
Execute commands from <file> as if they had been entered by the user. The autowizard is disabled when executing commands from the file.
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
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
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#
Activate a statement that has previously been deactivated.
Only available in when the system has been configured with support for inactive.
Deactivate a statement in the configuration.
Only available in when the system has been configured with support for inactive.
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 current configuration to running.
Validate current configuration.
Commit to running and quit configure mode.
Commit current configuration to running and startup configuration. Only available if the system is configured to have a startup configuration.
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.
Associate a comment with the commit. The comment can later be seen when examining rollback files.
Associate a label with the commit. The label can later be seen when examining rollback files.
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.
Validates current configuration. This is the same operation as commit check.
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 a new element into an ordered list. The element can be added first, last (default), before or after another element.
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 an instance.
Delete a data element.
Edit a sub-element. Missing elements in path will be created.
Exit from this level. If performed on the top level, will exit configure mode. This is the default if no option is given.
Exit from configuration mode regardless of which edit level.
Shows help text for command.
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.
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 configuration from file or terminal.
Merge content of file/terminal with current configuration.
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.
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 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.
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 in operational mode.
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 current configuration. The show command can be limited to a part of the configuration by providing a <pathfilter>.
Shows all possible commands starting with command prefix.
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 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 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.
Add a tag to a configuration statement.
Only available in when the system has been configured with attributes enabled.
Remove a tag from a configuration statement.
Only available in when the system has been configured with attributes enabled.
Remove all tags from a configuration statement.
Only available in when the system has been configured with attributes enabled.
Exit to top level of configuration, or execute a command at the top level of the configuration.
Exit one level of configuration, or execute a command at one level up.
Copy running configuration into current configuration.
Display users currently editing the configuration.
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
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.
Evaluate an XPath expression.
Evaluate the expression as a YANG must expression.
Evaluate the expression as a YANG when expression.
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#
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.
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 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 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.
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.
Edit a private copy of the running configuration, no lock is taken.
Edit a private copy of the startup configuration, no lock is taken.
Lock the running configuration and the candidate configuration and edit the candidate configuration.
Lock the running configuration (if enabled) and the startup configuration and edit the startup configuration.
Edit the candidate configuration without locking it.
Example:
io# config terminal Entering configuration mode terminal io(config)#
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#
Only available in IOS (i) mode. Downgrade to a lower privilege level.
Example:
io# disable 4 io#
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 ]] && . ~/.bashrc io#
List files in <directory>.
Example:
io# file list /config rollback0 rollback1 rollback2 rollback3 rollback4 io#
Display help text related to <command>.
Example:
io# help config Help for command: config Manipulate software configuration information io#
Show user id information; uid, gid, and groups
Example:
io# id user = joe(1000), gid=100, groups=wheel, gids=10,100 io#
Display a message on the screens of all users who are logged in to the device or on a specific screen.
Display the message to all currently logged in users.
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#
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#
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#
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#
List rollback files (C-style only). Note that this command is only available if rollback has been enabled in confd.conf.
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.
Shows all possible commands starting with command prefix.
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.
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.
Display current configuration.
Copy running configuration to startup configuration. Only available when the system has been configured to have a startup database.
Copy running configuration to startup configuration. Only available when the system has been configured to have a startup database.
Execute commands from <file> as if they had been entered by the user. The autowizard is disabled when executing commands from the file.
Display current values of read-only parameters. If a list element is encountered then the command attempts to arrange the output as a table.
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#
Terminates the current session.
Log out a specific user or session from the device. If the user held the configure exclusive lock, it will be released.
Log out a specific user.
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#
Display currently running background jobs.
Example:
io# show jobs JOB COMMAND 2 monitor start /tmp/saved io#
Display contents of a log file.
Example:
io# show log messages
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
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)#
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
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#
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 a statement in the configuration that has previously been deactivated.
Only available in when the system has been configured with support for inactive.
Deactivate a statement in the configuration.
Only available in when the system has been configured with support for inactive.
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.
Add a tag to a configuration statement.
Only available in when the system has been configured with attributes enabled.
Remove a tag from a configuration statement.
Only available in when the system has been configured with attributes enabled.
Remove all tags from a configuration statement.
Only available in when the system has been configured with attributes enabled.
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.
Specifies how the password is to be encrypted
The EXEC level to password protect
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.
The actual password
Example:
io(config)# enable secret level 3 0 bluebox io(config)#
Only available in IOS (i) mode. Configures for which level a command should be available.
In which mode is the command.
In which privilege level should the command be available
Command string.
Example:
io(config)# privilege exec level 4 show io(config)#
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.
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 current configuration to running.
Validate current configuration.
Commit to running and quit configure mode.
Commit current configuration to running and startup configuration. Only available if the system is configured to have a startup configuration.
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.
Associate a comment with the commit. The comment can later be seen when examining rollback files.
Associate a label with the commit. The label can later be seen when examining rollback files.
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.
Validates current configuration. This is the same operation as commit check.
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 a new element into an ordered list. The element can be added first, last (default), before or after another element.
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 an instance.
Delete or unsets a data element.
Exit from current mode. If performed on the top level, will exit configure mode. This is the default if no option is given.
Exit from configuration mode regardless of mode.
Shows help text for command.
Load configuration from file.
Display current submode path.
Save the whole or parts of the current configuration to file.
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.
Run command in operational mode.
Show current configuration buffer. The show command can be limited to a part of the configuration by providing a <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 changes that were committed for a given commit id.
List rollback files (C-style only). Note that this command is only available if rollback has been enabled in confd.conf.
Show changes for rolling back to rollback file nr.
Show current configuration. The show command can be limited to a part of the configuration by providing a <pathfilter>.
Shows all possible commands starting with command prefix.
Copy running configuration into current configuration.
Remove all configuration changes.
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
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.
Evaluate an XPath expression.
Evaluate the expression as a YANG must expression.
Evaluate the expression as a YANG when expression.
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#
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.
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.
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.
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".
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, &mode, 1) < 0) confd_fatal("Failed to reply to confd\n"); return CONFD_OK; }
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'.
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.
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.
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.
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.
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>
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}"
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", &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*)&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*)&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.
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.
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.
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.
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.
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
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.
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:
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:
And when rendering a set of list elements the following is used:
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.
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.