Exec Mode

Command Execution Mode
The Exec Mode is the normal way for Invoking yangcli-pro Commands.
Builtin YANG-Based Commands
All of the built-in commands are defined as 'RPC' operations in the yangcli-pro.yang module.
The Commands section lists the full set of built-in commands
The yangcli-pro Command Reference section contains the complete documentation for each built-in command.
Server YANG-Based Commands
All of the RPC operations advertised by a server (within a session) are available as commands in Exec Mode.
All server commands can be suppressed by setting the --server-commands parameter to 'false'.
A server command is shown with a '*' character appended when then tab key is pressed.
Example: tab key pressed after the 'd' key
Commands such as 'delete' are yangcli-pro built-in commands
Commands such as 'delete-backup' are server commands
andy@localhost> d delete delete-backup* delete-subscription* devices-cfg delete-all delete-config* device-cfg discard-changes* andy@localhost> d
Hiding Exec Commands
The --hide-command CLI parameter can be used to hide specific commands from the user.
Example:
> yangcli-pro --hide-command=delete-backup
Now when the tab key is pressed during a session, the 'delete-backup' command is not shown:
andy@localhost> d
delete delete-config* device-cfg discard-changes*
delete-all delete-subscription* devices-cfg
andy@localhost> d
Script Integration
The yangcli-pro Exec Mode can be used to integrate your own scripts. The scripts can be installed anywhere in the --runpath and it will be found.
Enabling Script Usage
Permission to access scripts is handled differently for yangcli-pro and yp-shell.
In both cases, the --allow-shell parameter must be 'true' to invoke the run-shell command directly. The default is 'false' Custom commands are allowed even if this parameter is 'false'.
In yangcli-pro, the '$$allow-shell' system variable can be changed at run-time.
In yp-shell, the '$$allow-shell' system variable cannot be changed at run-time. It is a read-only variable in this mode.
The run command is always allowed for yangcli-pro. For yp-shell, the --ypshell-exec-ok parameter must be set to 'true' or both the run and run-shell commands will fail with an error:
user@server1> run foo
Error: The run command is not allowed in this mode
The --shell-command and --python-command CLI parameters are used for custom commands or the run-shell command. There is no special 'run-python' command. Instead, the script suffix is used to pick the script type (see Script Types).
Script Integration Modes
There are 2 ways to use scripts:
Manual: Built in run or run-shell command used to invoke a script directly.
The script name does not appear as a built-in command.
There is no YANG representation of the script input parameters, just the 'run-shell' parameters ('P1', 'P2', etc.).
There is no tab-key or help-key support for the script parameters.
The --allow-shell parameter must be 'true' to use this mode.
There is no vendor control over script selection except making sure no unwanted scripts are present in the --runpath.
Automatic: Custom Commands are installed with the --custom-command CLI parameter. They are defined in YANG modules as 'RPC' operations.
The script name does appear as a built-in command.
There is a full YANG representation of the script input parameters.
There is full tab-key and help-key support for the script parameters.
The --allow-shell parameter is ignored in this mode.
There is full vendor control over script selection so no unwanted scripts are present as commands.
Script Types
There are 3 types of scripts supported. For custom commands, the script name is derived from the RPC operation name.
Script Type |
Suffix |
Description |
---|---|---|
Python |
|
Script invoked with the --python-command |
Shell |
|
Script invoked with the --shell-command |
yangcli |
none |
Script invoked with the run command |
Custom Commands
A custom command is a user or vendor-added command added to the Exec Mode command set. It is defined with a YANG 'rpc' statement like most other commands.
The --custom-command CLI parameter is used to specify the YANG module name and optionally the specific RPC operation to install as a custom command.
Warning
Custom commands are enabled automatically since they require explicit configuration to add to the command parser.
The --allow-shell and --ypshell-exec-ok CLI parameters do not affect custom command access.
Custom Command YANG Usage
A YANG 'rpc' statement is used to define a custom command.
The YANG 'rpc' name identifies the command name
The YANG 'rpc' input statement defines the command input parameters.
The script is expected to process the parameters (if any) and print messages to the 'stdout' device (if any).
No output parameters are returned and the YANG output statement is ignored if present.
YANG field validation is done for each input parameter
YANG 'must' and 'when' statements are ignored and not validated.
YANG augments are not supported. Only the input parameters listed in the specified 'rpc' statement are supported.
Custom Command Usage Restrictions
The custom commands are loaded at boot-time and cannot be updated or changed at run-time.
If the wildcard '*' form is used for a module, then no other --custom-command parameters are allowed for that module,
The custom command name cannot be the same as any yangcli-pro built-in command or the same name as any other custom command.
It is not possible to replace a built-in command with a custom command instead.
Custom Command CLI Syntax
The --custom-command parameter is a structured string with 3 parts:
module-name ':' rpc-name [ '/' scope-id ]
Example: Load all the RPC statements in the 'test-commands' YANG module as top-level commands.
yangcli-pro --custom-command=test-commands:*
Fields:
The module name must be provided. It is expected to contain at least one RPC statement to define the custom command.
The rpc name is the identifier for the RPC statement.
The value '*' can be used to indicate that all the RPC statements found in the module should be used as custom commands.
If the '*' wildcard is used then a warning is printed if no RPC statements are found in that module.
Otherwise this string is the name of an RPC operation in the specified YANG module.
An error is printed if the specific RPC statement is not found. The custom command will not be loaded but the program will not exit.
The scope-id is a 1 letter code identifying the RPC command scope.
The letter
T
is used to identify a top-level command that is always available.The letter
S
is used to identify a session-level command that is only available in a connected session.If the scope ID is missing then the default is
T
for yangcli-pro or yangcli-gw.This field is ignored for yp-shell, and the value used is always
S
. The scope ID is not relevant for yp-shell sessions since it is always connected to the local server.
Custom Command Script Parameters
When the command is executed, the command parser will look in the --runpath for a Python, Shell, or yangcli script (in that order).
If a script is found, it will be invoked with the following parameters. The same 5 parameters are always passed to a custom command script.
Script Identifier
Parameter 0
Full filespec path for the script
Example:
/home/user1/scripts/command1.sh
RPC Identifier
Parameter 1
modname:version:rpc for the YANG source
Example:
test-commands@2025-05-30:command1
The version field will be
none
if the module does not have a revision date.
Session Identifier
Parameter 2
username@server-address OR
none
Example:
user1@192,168.0.10
This parameter value will be the string
none
if the yangcli session is not connected to a server.
YANG Input Parameters
Parameter 3
Full input filespec OR
none
Input parameters are encoded in JSON similar to a RESTCONF POST request.
The JSON object is for the 'input' container for the specified 'rpc' operation.
The RFC 7951 syntax is followed except there is no module-name prefix used.
YANG defaults are added to the input parameters if any are defined.
Example:
/home/user1/.yumapro/tmp/20250605013521171838/command1-input-1.json
Example script file contents:
{ "input": { "parm1":"test2", "parm2":18 } }
This parameter value will be the string
none
if the script does not define any input parameters of none were provided when the command was invoked.If no session is active, the temporary input file will be created within the 'tmp' directory for the program instance that is running.
Example:
/home/user1/.yumapro/tmp/20250605013521171838/
If a session is active, the temporary input file will be created within the 'tmp' directory for the session, in the program instance that is running.
Example:
/home/user1/.yumapro/tmp/20250605013521171838/12
The last number in the filename is the command invocation sequence which will increment each time any custom command is invoked. It is shared across all commands, not the sequence number for that specific command.
Current Log Level
Parameter 4
Current log level
Example:
info
This parameter will contain the string
none
if some error occurred and the real --log-level value cannot be determined.
Custom Command Usage Example
This example is intentionally simple but it shows all the steps of setting up and using custom commands.
Example YANG Module
A YANG module is needed to define the RPC operations. In this example 'test-commands.yang' is used. The module used must be found in one of the directories specified in the --modpath (or default search path).
module test-commands {
yang-version 1.1;
namespace "urn:yumaworks:params:xml:ns:yang:test-commands";
prefix tc;
revision "2025-05-30";
rpc command1 {
description
"Custom CLI command 1";
input {
leaf parm1 {
type string;
description "Parameter 1";
}
leaf parm2 {
type uint32;
description "Parameter 2";
}
}
}
rpc command2 {
description
"Custom CLI command 2";
input {
leaf parm3 {
type string;
description "Parameter 3";
}
leaf parm4 {
type int32;
description "Parameter 4";
}
}
}
}
Example Bash Command Script
This simple script just echos the input parameters and prints the contents of the JSON input parameters file if present.
#
# yangcli-pro Custom Command Script
# Bash script for the test-commands:command1 RPC operation
#
echo ""
echo "Script (P0)= $0"
echo "RPC (P1)= $1"
echo "Session (P2)= $2"
echo "Input (P3)= $3"
echo "Log Level (P4)= $4"
if [[ "$3" != "none" && "$3" != "" ]]; then
echo "Input File Contents:";
cat $3;
fi
Example Python Command Script
This simple script just echos the input parameters and loads the JSON input file as a JSON object.
# yangcli-pro Custom Command Script
# Python script for the test-commands:command2 RPC operation
#
import argparse
import json
def load_and_parse_json(file_path):
"""
Loads a JSON file, parses it, and returns the JSON object.
Args:
file_path (str): The path to the JSON file.
Returns:
dict: The parsed JSON object as a Python dictionary,
or None if an error occurs.
"""
try:
with open(file_path, 'r') as file:
data = json.load(file)
return data
except FileNotFoundError:
print(f"Error: File not found at {file_path}")
return None
except json.JSONDecodeError:
print(f"Error: Invalid JSON format in {file_path}")
return None
except Exception as e:
print(f"An unexpected error occurred: {e}")
return None
def main():
"""
Loads the Custom Command input parameters
P1 = RPC identifier
P2 = Session Info
P3 = Input Parameter File
P4 = Log Level
"""
parser = argparse.ArgumentParser(description="Command2 Help")
parser.add_argument("rpc", type=str, help="The operation being invoked.")
parser.add_argument("session", type=str, help="The session information.")
parser.add_argument("input", type=str, help="The input parameters file.")
parser.add_argument("loglevel", type=str, help="The current log-level.")
args = parser.parse_args()
print()
print(f"RPC (P1)= {args.rpc}")
print(f"Session (P2)= {args.session}")
print(f"Input (P3)= {args.input}")
print(f"Log Level (P4)= {args.loglevel}")
if args.input is not None and args.input != 'none':
data = load_and_parse_json(args.input)
if data:
print(f"Got JSON Input {data}")
if "input" in data:
topdata = data["input"]
if "parm3" in topdata:
parm3 = topdata["parm3"]
print(f"Parm 3: {parm3}")
else:
print(f"Parm 3: none")
if "parm4" in topdata:
parm4 = topdata["parm4"]
print(f"Parm 4: {parm4}")
else:
print(f"Parm 4: none")
if __name__ == "__main__":
main()
Example Tab and Help Key
The 'command1' and 'command2' keywords are automatically supported within the context sensitive help keys.
Example: tab key pressed after the letter 'c'
> c
callhome-server cd collector command2
callhome-user clear command1 connect
Example: help '?' key pressed after the letter 'c'
> c
callhome-server Access and control the CallHome server.
callhome-user Access and configure the CallHome Users.
cd Change the current working directory.
clear Clear the screen in interactive mode.
collector Access and control the UDP-Notif Collector.
command1 Custom CLI command 1
command2 Custom CLI command 2
connect Connect to a NETCONF server.
> c
Example Command Invocations
Example: command1 invoked without any session connection:
> command1 parm1=test1 parm2=17
Script (P0)= command1.sh
RPC (P1)= test-commands@2025-05-30:command1
Session (P2)= none
Input (P3)= /home/andy/.yumapro/tmp/20250606155131395334/command1-input-1.json
Log Level (P4)= info
Input File Contents:
{
"input": {
"parm1":"test1",
"parm2":17
}
}
>
Example: command1 invoked with a session connected:
andy@localhost> command1 parm1=test2 parm2=18
Script (P0)= command1.sh
RPC (P1)= test-commands@2025-05-30:command1
Session (P2)= andy@localhost
Input (P3)= /home/andy/.yumapro/tmp/20250606155131395334/11/command1-input-2.json
Log Level (P4)= info
Input File Contents:
{
"input": {
"parm1":"test2",
"parm2":18
}
}
andy@localhost>
Example: command1 invoked with no parameters
andy@localhost> command1
Script (P0)= command1.sh
RPC (P1)= test-commands@2025-05-30:command1
Session (P2)= andy@localhost
Input (P3)= none
Log Level (P4)= info
andy@localhost>
Example: command2 invoked without any session connection:
> command2 parm3=test parm4=3
RPC (P1)= test-commands@2025-05-30:command2
Session (P2)= none
Input (P3)= /home/andy/.yumapro/tmp/20250607175808652315/command2-input-4.json
Log Level (P4)= info
Got JSON Input {'input': {'parm3': 'test', 'parm4': 3}}
Parm 3: test
Parm 4: 3
>
Example: command2 invoked with a session connected:
andy@localhost> command2 parm3=test parm4=3
RPC (P1)= test-commands@2025-05-30:command2
Session (P2)= andy@localhost
Input (P3)= /home/andy/.yumapro/tmp/20250607175808652315/11/command2-input-5.json
Log Level (P4)= info
Got JSON Input {'input': {'parm3': 'test', 'parm4': 3}}
Parm 3: test
Parm 4: 3
andy@localhost>
Example: command2 invoked with no parameters
andy@localhost> command2
RPC (P1)= test-commands@2025-05-30:command2
Session (P2)= andy@localhost
Input (P3)= none
Log Level (P4)= info
andy@localhost>
Example Error If Script Not Found
An error will be printed if the script execution fails for some reason.
Example: script not installed
> command1 parm1=test1 parm2=17
Error: Error getting script for custom command 'command1' (not found)
>