Skip to content

Commit

Permalink
Solve the bugs for SONiC CLI Auto-generation (#3221)
Browse files Browse the repository at this point in the history
1. Fixed the error description for config update
2. Not displaying the command of not configurable table that defined config false in the yang model.
3. Support showing other db table data defined in sonic yang model, not just config db.
  • Loading branch information
oplklum committed Mar 19, 2024
1 parent 125f36f commit d6c86bc
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 3 deletions.
6 changes: 5 additions & 1 deletion sonic-utilities-data/templates/sonic-cli-gen/config.py.j2
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ E.g:
{{ gen_click_options(object.attrs) }}
@clicommon.pass_db
def {{ group }}_update(db, {{ pythonize(object["keys"] + object.attrs) }}):
""" Add object in {{ table.name }}. """
""" Update object in {{ table.name }}. """

table = "{{ table.name }}"
key = {{ pythonize(object["keys"]) }}
Expand Down Expand Up @@ -531,6 +531,7 @@ def {{ group }}():


{% for table in tables %}
{% if table.config == 'true' %}
@click.group(name="{{ cli_name(table.name) }}",
cls=clicommon.AliasedGroup)
def {{ table.name }}():
Expand All @@ -550,6 +551,7 @@ def {{ table.name }}():
{% endfor %}
{% endif %}

{% endif %}
{% endfor %}

def register(cli):
Expand All @@ -563,8 +565,10 @@ def register(cli):
"""

{%- for table in tables %}
{%- if table.config == 'true' %}
cli_node = {{ table.name }}
if cli_node.name in cli.commands:
raise Exception(f"{cli_node.name} already exists in CLI")
cli.add_command({{ table.name }})
{%- endif %}
{%- endfor %}
33 changes: 31 additions & 2 deletions sonic-utilities-data/templates/sonic-cli-gen/show.py.j2
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,35 @@ def format_group_value(entry, attrs):
return tabulate.tabulate(data, tablefmt="plain")


def get_db_table(db, ytable):
""" Retrieve data table from redis DB, support CONFIG_DB|STATE_DB.

Args:
db: Db object in utilities_common.
ytable: dict data from yang parser

Returns:
dict: data table.
"""

name = ytable['name']
table = {}

if ytable['config'] == 'true':
table = db.cfgdb.get_table(name)
else:
db_name = ytable['db-name']
db.db.connect(db_name)
seps = db.db.get_db_separator(db_name)
keys = db.db.keys(db_name, name + seps + '*')

for key in keys:
t = db.db.get_all(db_name, key)
table[key[(key.find(seps) + 1):]] = t

return table


{# Generates a python list that represents a row in the table view.
E.g:
Jinja2:
Expand Down Expand Up @@ -185,7 +214,7 @@ def {{ table.name }}_{{ object.name }}(db):
header = {{ gen_header(object.attrs) }}
body = []

table = db.cfgdb.get_table("{{ table.name }}")
table = get_db_table(db, {{ table }})
entry = table.get("{{ object.name }}", {})
row = {{ gen_row("entry", object.attrs) }}
body.append(row)
Expand Down Expand Up @@ -222,7 +251,7 @@ def {{ name }}(db):
header = {{ gen_header(object["keys"] + object.attrs) }}
body = []

table = db.cfgdb.get_table("{{ table.name }}")
table = get_db_table(db, {{ table }})
for key in natsort.natsorted(table):
entry = table[key]
if not isinstance(key, tuple):
Expand Down
14 changes: 14 additions & 0 deletions sonic_cli_gen/yang_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ def on_table_container(y_module: OrderedDict,
"""
y2d_elem = {
'name': tbl_container.get('@name'),
'config': get_value(tbl_container, 'config', 'true'),
'db-name': get_value(tbl_container, 'sonic-ext:db-name', 'CONFIG_DB'),
'description': get_description(tbl_container)
}

Expand Down Expand Up @@ -407,6 +409,18 @@ def get_mandatory(y_leaf: OrderedDict) -> bool:

return y_leaf.get('mandatory').get('@value') == 'true'

def get_value(node: OrderedDict, key: str, default_value: str) -> str:
""" Parse the specified key entity from any YANG element
Args:
node: reference to YANG 'container' OR 'list' OR 'leaf' ...
key: string of the query key
default_value: default string to return when query failed
Returns:
value of the specified key
"""

return node.get(key).get('@value') if node.get(key) is not None else default_value

def get_description(y_entity: OrderedDict) -> str:
""" Parse the 'description' entity from any YANG element
Expand Down

0 comments on commit d6c86bc

Please sign in to comment.