- Revision
- Scope
- Definitions/Abbreviations
- Overview
- Feature overview
- Motivation
- Requirements
- Architecture Design
- High-level design
- Configuration and management
- SAI API
- Warmboot and Fastboot Design Impact
- Restrictions Limitations
- Testing Requirements Design
- Open questions
- Development plan
Rev | Date | Author | Change Description |
---|---|---|---|
1.0 | 04/2021 | Vadym Hlushko | Phase 1 Design |
This document describes the high-level design details of the SONiC CLI Auto-generation tool for SONiC Application extensions infrastructure.
Abbreviation | Definition |
---|---|
SONiC | Software for Open Networking in Cloud |
SAE | SONiC Application Extension |
DB | Database |
API | Application Programming Interface |
SAI | Switch Abstraction Interface |
YANG | Yet Another Next Generation |
CLI | Command-line interface |
NOS | Network operating system |
The SONiC CLI Auto-generation tool - is a utility for generating the command-line interface for third-party features, called application extensions, that provide their functionality as separate docker containers. The YANG model will be used to describe the CONFIG DB schema and CLI will be generated according to CONFIG DB schema. The YANG model will serve as an input parameter for the SONiC Auto-generation utility. The CLI should be a part of SONiC utilities and support - show, config operations.
To make SONiC NOS more flexible for developers SONiC Application Extension infrastructure was introduced.
If someone wants to extend the SONiC NOS functionality - the SAE infrastructure should be used. Some of the third-party features that will be integrated into the SONiC - may require the command-line interface. To avoid spending time on the investigation of how to develop and add a new CLI to sonic-utilities - the CLI Auto-generation utility was introduced. The command line interface that would be generated will be intuitive for people familiar with the SONiC NOS and CONFIG DB schema.
- Should support:
- CONFIG DB tables with ability to add/delete/update entries
A current SONiC NOS architecture does not require changes, because the SONiC CLI Auto-generation feature comes as a component for the SONiC Application extension infrastructure. So, only the sonic-package-manager utility requires changes.
There are three main entities:
YANG model
- YANG model file which contains a description of CONFIG DB schema. Should be written strictly according to SONiC Yang Model Guidelines
SONiC CLI Auto-generation tool
- a utility that reads the YANG model and produces the Auto-generated CLI plugin.
Auto-generated CLI plugin
- python script, which will be used as a plugin for existing CLI, will be placed in the specific place (described later) and provide to the user a CLI for a new feature.
A current SONiC utilities support show
, config
, sonic-clear
operations. A plugin approach is taken when extending those utilities. A common way to introduce plugin support for a python application is to structure a plugin as a python module that can be discovered by the application in a well known location in the system.
admin@sonic: /usr/local/lib/<python version>/dist-packages/config/plugins/auto
admin@sonic: /usr/local/lib/<python version>/dist-packages/show/plugins/auto
Auto-generated CLI plugins will be placed to a package directory named plugins/auto
under each show
, config
python package so that by iterating modules inside those packages utilities can load them. This is implemented in a way defined in Python Packaging Guide. Creating and discovering plugins.
A code snipped describing the approach is given:
import show.plugins
def iter_plugins_namespace(ns_pkg):
return pkgutil.iter_modules(ns_pkg.__path__, ns_pkg.__name__ + ".")
discovered_plugins = {
name: importlib.import_module(name)
for finder, name, ispkg
in iter_namespace(show.plugins)
}
The SONiC CLI Auto-generation tool is a part of sonic-package-manager utility. A package installation and upgrade flow will trigger the SONiC CLI auto-generation tool
if the YANG model was provided as part of the Application extension docker image.
In order to get the auto-generated CLI - the YANG model should be a part of the Application extension Docker image and placed along with manifest.json file. The user should be able to reach the YANG model by using the docker labels. Several YANG modules might be provided by an application extension:
com.azure.sonic.yang-module.sonic-<xxx>
com.azure.sonic.yang-module.sonic-<yyy>
where sonic-<xxx>
, sonic-<yyy>
are the names of the modules, e.g (sonic-vlan, sonic-port, etc.) and should match the module name.
If the Application Extension will be installed or updated by sonic-package-manager
and the CLI will be generated - the YANG model for the current Application Extension will be placed in a well-known system location on the switch along with existing YANG models. This step is done in order to provide data validation - when the user executing generated CLI.
admin@sonic: /usr/local/yang-models/
The manifest.json file should have a specific ON/OFF triggers for CLI auto-generation:
Path | Type | Mandatory | Description |
---|---|---|---|
/cli/auto-generate-config | boolean | yes | ON/OFF triger for auto-generation of CLI command config. Default: false |
/cli/auto-generate-show | boolean | yes | ON/OFF triger for auto-generation of CLI command show. Default: false |
By default, CLI is autogenerated for all YANG modules provided by the extension. Developer can optionally specify explicitelly which YANG modules to use for auto-generated CLI:
Path | Type | Mandatory | Description |
---|---|---|---|
/cli/auto-generate-config-source-yang-modules | list of strings | no | If set, config CLI auto-generation will only apply to specified YANG modules. The YANG module is referenced by the name recorded in labels (which should match the name of the module) |
/cli/auto-generate-show-source-yang-modules | list of strings | no | If set, config CLI auto-generation will only apply to specified YANG modules. The YANG module is referenced by the name recorded in labels (which should match the name of the module) |
Inside the manifest.json there are other keys, that describing a path to a NOT auto-generated CLI plugins
. For example, there are:
Path | Type | Mandatory | Description |
---|---|---|---|
/cli/show-cli-plugin | list of strings | no | List of paths to plugins for sonic-utilities show CLI command. |
/cli/config-cli-plugin | list of strings | no | List of paths to plugins for sonic-utilities config CLI command. |
/cli/clear-cli-plugin | list of strings | no | List of paths to plugins for sonic-utilities sonic-clear CLI command. |
For example, the user can have a config
CLI auto-generated and the show
CLI NOT auto-generated.
For debugging
purposes the SONiC CLI Auto-generation
tool will be accessible from the switch CLI as an independent utility called - sonic-cli-gen
. The user could provide a YANG model and place on the switch to:
admin@sonic: /usr/local/yang-models/
The sonic-cli-gen
utility can generate CLI plugin for config
and show
CLI groups, yang_model_name
is a YANG model from the directory above:
admin@sonic: sonic-cli-gen generate config <yang_model_name>
admin@sonic: sonic-cli-gen generate show <yang_model_name>
admin@sonic: sonic-cli-gen generate config sonic-acl
Loaded below Yang Models
['sonic-acl', 'sonic-breakout_cfg', 'sonic-crm', 'sonic-device_metadata', 'sonic-device_neighbor', 'sonic-extension', 'sonic-flex_counter', 'sonic-interface', 'sonic-loopback-interface', 'sonic-port', 'sonic-portchannel', 'sonic-types', 'sonic-versions', 'sonic-vlan', 'sonic-vrf']
Note: Below table(s) have no YANG models:
COPP_GROUP, COPP_TRAP, FEATURE, KDUMP, MGMT_INTERFACE, SNMP, SNMP_COMMUNITY, WJH, WJH_CHANNEL,
INFO:sonic-cli-gen: Auto-generation successful! Location: /usr/local/lib/python3.7/dist-packages/config/plugins/auto/sonic-acl_yang.py
Also, the sonic-cli-gen
can remove auto-generated plugins:
admin@sonic: sonic-cli-gen remove config sonic-acl
/usr/local/lib/python3.7/dist-packages/config/plugins/auto/sonic-acl_yang.py was removed.
Most of the existed YANG models could be passed to sonic-cli-gen
. List of the worked YANG models from /usr/local/yang-models:
sonic-acl.yang
sonic-breakout_cfg.yang
sonic-crm.yang
sonic-device_metadata.yang
sonic-device_neighbor.yang
sonic-flex_counter.yang
sonic-interface.yang
sonic-loopback-interface.yang
sonic-port.yang
sonic-portchannel.yang
sonic-versions.yang
sonic-vlan.yang
The auto-generated CLI will use the next scenario:
- The user executes an auto-generated CLI command.
- The auto-generated command produces a file, which describes the configuration to apply.
- The YANG library validates data provided by the user in 1 step, according to the YANG model.
- After successful validation, it writes data to Config DB.
- Please make sure that you read all the rules.
- Because you will often have a question that is covered in the next rule.
1. For auto-generated CLI (sub-commands, arguments) will be used - hyphen separated style:
For instance let's take a feature called FEATURE-A:
admin@sonic:~$ config feature-a sub-command-1 add <KEY> ...
2. For every container
, that goes after top-level container
, (top-level container goes after module
) will be generated dedicated sub-command for show
and config
command groups AND in case if container
is without list
, for every leaf
will be generated dedicated sub-command:
For instance let's take a PART of existing sonic-device_metadata.yang
module sonic-device_metadata {
//..
container sonic-device_metadata {
container DEVICE_METADATA {
container localhost{
leaf hwsku {
type stypes:hwsku;
}
leaf default_bgp_status {
type enumeration {
enum up;
enum down;
}
default up;
}
leaf hostname {
type string {
length 1..255;
}
}
leaf platform {
type string {
length 1..255;
}
}
}
}
}
}
admin@sonic:~$ config device-metadata localhost hwsku "ACS-MSN2100"
admin@sonic:~$ config device-metadata localhost default-bgp-status up
admin@sonic:~$ config device-metadata localhost hostname "r-sonic-switch"
admin@sonic:~$ config device-metadata localhost platform "x86_64-mlnx_msn2100-r0"
The show
command produces named columns. Each column name is an uppercase of leaf
name from the YANG model, if leaf
contain -
or _
those will be trimmed:
admin@sonic:~$ show device-metadata localhost
HWSKU DEFAULT BGP STATUS HOSTNAME PLATFORM
----- ------------------ -------- --------
ACS-MSN2100 UP r-sonic-switch x86_64-mlnx_msn2100-r0
{
"DEVICE_METADATA": {
"locahost": {
"hwsku": "ACS-MSN2100",
"default_bgp_status": "up",
"hostname": "r-sonic-switch",
"platform": "x86_64-mlnx_msn2100-r0"
}
}
}
3. For every list
element will be generated add/del/update
commands:
For instance let's take a PART of existing sonic-vlan.yang
module sonic-vlan {
// ...
container sonic-vlan {
// ...
container VLAN {
list VLAN_LIST {
key "name";
leaf name {
type string {
pattern 'Vlan([0-9]{1,3}|[1-3][0-9]{3}|[4][0][0-8][0-9]|[4][0][9][0-4])';
}
}
leaf vlanid {
type uint16 {
range 1..4094;
}
}
leaf mtu {
type uint16 {
range 1..9216;
}
}
leaf admin_status {
type stypes:admin_status;
}
}
}
}
}
In the case of below, Vlan11
- is a positional argument and key
for the list
.
vlanid
, mtu
, admin-status
- are not-positional arguments, and to give them the next style MUST be used (check config command
)
This style "--arg" is NOT RELATED to the Linux CLI optional parameter style
admin@sonic:~$ config vlan add Vlan11 --vlanid 11 --mtu 128 --admin-status up
admin@sonic:~$ config vlan del Vlan11
The update
command will be generated but not always could be executed. The user will get an error message from the YANG validator if the update command
is not supported.
admin@sonic:~$ config vlan update Vlan11 --vlanid 12 --mtu 129
admin@sonic:~$ config vlan update Vlan11 --admin-status down
YANG models support The leaf's "mandatory" Statement. If the user wants to distinguish whether a CLI argument is mandatory or not, he can use the --help command (covered in the next rules)
If the user wants to add to the list a new element with KEY that already existed in the list, he will get a warning message.
admin@sonic:~$ config vlan add Vlan11 --vlanid 11 --mtu 128 --admin-status up
Vlan11 already exist! Do you want to replace it? yes/no
admin@sonic:~$ show vlan
NAME VLANID MTU ADMIN STATUS
---- ------ --- ------------
Vlan11 11 128 up
{
"VLAN": {
"Vlan11": {
"vlanid": 11,
"mtu": 128,
"admin_status": up
}
}
}
In case if the YANG models have more than 1 list
entity inside container
:
For instance let's take a PART of existing sonic-vlan.yang
module sonic-vlan {
// ...
container sonic-vlan {
container VLAN_INTERFACE {
// ...
list VLAN_INTERFACE_LIST {
// ...
}
list VLAN_INTERFACE_IPPREFIX_LIST {
// ...
}
}
}
}
If there is more than 1 list
entity inside container
then dedicated sub-command for every list
will be generated:
admin@sonic:~$ config vlan-interface vlan-interface-list add <KEY> ...
admin@sonic:~$ config vlan-interface vlan-interface-ipprefix-list add <KEY> ...
If there is only 1 list
entity inside container
then there will be NO dedicated sub-command.
admin@sonic:~$ config vlan-interface add <KEY> ...
4. For every leaf-list
element will be generated dedicated add/del/update
commands, also the user can use a comma-separated list when creating a new list element to fill leaf-list
. Also will be added dedicated command clear
to delete all the elements from leaf-list
:
For instance let's take a PART of existing sonic-vlan.yang
module sonic-vlan {
// ...
container sonic-vlan {
// ...
container VLAN {
list VLAN_LIST {
key "name";
leaf name {
type string {
pattern 'Vlan([0-9]{1,3}|[1-3][0-9]{3}|[4][0][0-8][0-9]|[4][0][9][0-4])';
}
}
leaf vlanid {
type uint16 {
range 1..4094;
}
}
leaf mtu {
type uint16 {
range 1..9216;
}
}
leaf admin_status {
type stypes:admin_status;
}
leaf-list dhcp_servers {
type inet:ip-address;
}
}
}
}
}
The user can create a new list object, and provide values to leaf-list
dhcp_servers
by using a comma-separated list (example below)
admin@sonic:~$ config vlan add Vlan11 --vlanid 11 --mtu 128 --admin-status up --dhcp-servers "192.168.0.10,11.12.13.14"
The user can use dedicated sub-commands add/del
, a clear
sub-command will delete all the elements from leaf-list
.
The add
subcommand will append a new element to the end of the list.
admin@sonic:~$ config vlan dhcp-servers add Vlan11 10.10.10.10
admin@sonic:~$ config vlan dhcp-servers del Vlan11 10.10.10.10
admin@sonic:~$ config vlan dhcp-servers clear Vlan11
The update
command will be generated but not always could be executed. The user will get an error message from the YANG validator if the update command
is not supported.
admin@sonic:~$ show vlan
NAME VLANID MTU ADMIN STATUS DHCP SERVERS
---- ------ --- ------------ ------------
Vlan11 11 128 up 192.168.0.10
11.12.13.14
{
"VLAN": {
"Vlan11": {
"vlanid": 11,
"mtu": 128,
"admin_status": up,
"dhcp_servers": [
"192.168.0.10",
"11.12.13.14"
]
}
}
}
5. In case if YANG model contains grouping
and uses
syntax:
Please note that grouping
MUST be located:
- in the same YANG model and placed under
module
entity (i.e. NOT nested incontainer
entities) - in other YANG model under
module
entity (i.e. NOT nested incontainer
entities), theimport
statement should be used to importgrouping
from another YANG model.
module sonic-feature-a {
// ...
grouping target {
leaf address {
type inet:ip-address;
}
leaf port {
type inet:port-number;
}
}
container sonic-feature-a {
// ...
container FEATURE_A {
list FEATURE_A_LIST {
key "host_name";
leaf host_name {
type string;
}
uses target;
}
}
}
}
admin@sonic:~$ config feature-a add Linux --address "10.10.10.10" --port 1024
admin@sonic:~$ show feature-a
HOST NAME TARGET
--------- ------
Linux address: "192.168.0.20"
port: "1024"
{
"FEATURE_A": {
"Linux": {
"address: "192.168.0.20",
"port": 1024
}
}
}
6. In case if YANG model contains description
, it will be used for CLI --help
:
module sonic-feature-a {
// ...
container sonic-feature-a {
// ...
container FEATURE_A {
description "FEATURE_A overview";
list FEATURE_A_LIST {
key "host_name";
leaf host_name {
type string;
}
}
}
}
}
admin@sonic:~$ config feature-a --help
Usage: config feature-a [OPTIONS] COMMAND [ARGS]...
FEATURE_A overview
Options:
--help Show this message and exit.
Commands:
add Add configuration.
del Del configuration.
In case if leaf
contain "mandatory" statement
admin@sonic:~$ config feature-a add --help
Usage: config feature-a add [OPTIONS] <key>
Add configuration
Options:
--help Show this message and exit.
--adrress [mandatory] IP address.
--port Port number.
No SAI API changes required for this feature.
No impact for warmboot/fastboot flows.
- The YANG models for Application extension MUST have unique names for constructs - module, container, that are located on the same nested level in comparison to existing YANG models. This needed to avoid an intersection with the existing CLI on the switch. The below sonic-vlan.yang has a module name - "sonic-vlan", so the developer can NOT use this "sonic-vlan" name for another module in another YANG mode.
module sonic-vlan {
// ...
container sonic-vlan {
container VLAN_INTERFACE {
}
}
}
If there will be some conflicts, CLI auto-generation process will fail with an error message.
The unit tests will be provided during implementation.
- Should support:
- CONFIG DB tables with the ability to add/delete/update entries
- Should support:
- All SONiC DB tables with the ability to add/delete/update entries
- Auto-generation of sonic-clear CLI