diff options
Diffstat (limited to 'tools')
| -rwxr-xr-x | tools/net/ynl/pyynl/cli.py | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/tools/net/ynl/pyynl/cli.py b/tools/net/ynl/pyynl/cli.py index 8c192e900bd3..4d91a2cee381 100755 --- a/tools/net/ynl/pyynl/cli.py +++ b/tools/net/ynl/pyynl/cli.py @@ -7,6 +7,7 @@ import os import pathlib import pprint import sys +import textwrap sys.path.append(pathlib.Path(__file__).resolve().parent.as_posix()) from lib import YnlFamily, Netlink, NlError @@ -39,6 +40,37 @@ class YnlEncoder(json.JSONEncoder): return json.JSONEncoder.default(self, obj) +def print_attr_list(attr_names, attr_set): + """Print a list of attributes with their types and documentation.""" + for attr_name in attr_names: + if attr_name in attr_set.attrs: + attr = attr_set.attrs[attr_name] + attr_info = f' - {attr_name}: {attr.type}' + if 'enum' in attr.yaml: + attr_info += f" (enum: {attr.yaml['enum']})" + if attr.yaml.get('doc'): + doc_text = textwrap.indent(attr.yaml['doc'], ' ') + attr_info += f"\n{doc_text}" + print(attr_info) + + +def print_mode_attrs(mode, mode_spec, attr_set, print_request=True): + """Print a given mode (do/dump/event/notify).""" + mode_title = mode.capitalize() + + if print_request and 'request' in mode_spec and 'attributes' in mode_spec['request']: + print(f'\n{mode_title} request attributes:') + print_attr_list(mode_spec['request']['attributes'], attr_set) + + if 'reply' in mode_spec and 'attributes' in mode_spec['reply']: + print(f'\n{mode_title} reply attributes:') + print_attr_list(mode_spec['reply']['attributes'], attr_set) + + if 'attributes' in mode_spec: + print(f'\n{mode_title} attributes:') + print_attr_list(mode_spec['attributes'], attr_set) + + def main(): description = """ YNL CLI utility - a general purpose netlink utility that uses YAML @@ -70,6 +102,8 @@ def main(): group.add_argument('--dump', dest='dump', metavar='DUMP-OPERATION', type=str) group.add_argument('--list-ops', action='store_true') group.add_argument('--list-msgs', action='store_true') + group.add_argument('--list-attrs', dest='list_attrs', metavar='OPERATION', type=str, + help='List attributes for an operation') parser.add_argument('--duration', dest='duration', type=int, help='when subscribed, watch for DURATION seconds') @@ -135,6 +169,28 @@ def main(): for op_name, op in ynl.msgs.items(): print(op_name, " [", ", ".join(op.modes), "]") + if args.list_attrs: + op = ynl.msgs.get(args.list_attrs) + if not op: + print(f'Operation {args.list_attrs} not found') + exit(1) + + print(f'Operation: {op.name}') + print(op.yaml['doc']) + + for mode in ['do', 'dump', 'event']: + if mode in op.yaml: + print_mode_attrs(mode, op.yaml[mode], op.attr_set, True) + + if 'notify' in op.yaml: + mode_spec = op.yaml['notify'] + ref_spec = ynl.msgs.get(mode_spec).yaml.get('do') + if ref_spec: + print_mode_attrs('notify', ref_spec, op.attr_set, False) + + if 'mcgrp' in op.yaml: + print(f"\nMulticast group: {op.yaml['mcgrp']}") + try: if args.do: reply = ynl.do(args.do, attrs, args.flags) |
