netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [net-next,v1 0/2] tools/net/ynl: enable json configuration
@ 2023-07-27  8:55 mtahhan
  2023-07-27  8:55 ` [net-next,v1 1/2] tools/net/ynl: configuration through json mtahhan
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: mtahhan @ 2023-07-27  8:55 UTC (permalink / raw)
  To: netdev, kuba, davem, edumazet, pabeni; +Cc: Maryam Tahhan

From: Maryam Tahhan <mtahhan@redhat.com>

Use a json configuration file to pass parameters to ynl to allow
for operations on multiple specs in one go. Additionally, check
this new configuration against a schema to validate it in the cli
module before parsing it and passing info to the ynl module.

Example configs would be:
{
    "yaml-specs-path": "/<path-to>/linux/Documentation/netlink/specs",
    "spec-args": {
        "ethtool.yaml": {
            "do": "rings-get",
            "json-params": {
                "header": {
                    "dev-name": "eno1"
                }
            }
        },
       "netdev.yaml": {
            "do": "dev-get",
            "json-params": {
            "ifindex": 3
            }
        }
    }
}

OR

{
    "yaml-specs-path": "/<path-to>/linux/Documentation/netlink/specs",
    "spec-args": {
        "ethtool.yaml": {
            "subscribe": "monitor",
            "sleep": 10
        },
        "netdev.yaml": {
            "subscribe": "mgmt",
            "sleep": 5
        }
    }
}

Maryam Tahhan (2):
  tools/net/ynl: configuration through json
  tools/net/ynl: validate config against schema

 tools/net/ynl/cli.py            | 135 +++++++++++++++++++++++++++-----
 tools/net/ynl/ynl-config.schema |  72 +++++++++++++++++
 2 files changed, 187 insertions(+), 20 deletions(-)
 create mode 100644 tools/net/ynl/ynl-config.schema

-- 
2.39.2


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [net-next,v1 1/2] tools/net/ynl: configuration through json
  2023-07-27  8:55 [net-next,v1 0/2] tools/net/ynl: enable json configuration mtahhan
@ 2023-07-27  8:55 ` mtahhan
  2023-07-27  8:55 ` [net-next,v1 2/2] tools/net/ynl: validate config against schema mtahhan
  2023-07-27  9:38 ` [net-next,v1 0/2] tools/net/ynl: enable json configuration Maryam Tahhan
  2 siblings, 0 replies; 4+ messages in thread
From: mtahhan @ 2023-07-27  8:55 UTC (permalink / raw)
  To: netdev, kuba, davem, edumazet, pabeni; +Cc: Maryam Tahhan

From: Maryam Tahhan <mtahhan@redhat.com>

Enable YNL configuration through a json file alongside the
current commandline arguments. This will allow one to cycle
through multiple specs and commands at once.

Signed-off-by: Maryam Tahhan <mtahhan@redhat.com>
---
 tools/net/ynl/cli.py | 108 ++++++++++++++++++++++++++++++++++---------
 1 file changed, 87 insertions(+), 21 deletions(-)

diff --git a/tools/net/ynl/cli.py b/tools/net/ynl/cli.py
index ffaa8038aa8c..1749851f8460 100755
--- a/tools/net/ynl/cli.py
+++ b/tools/net/ynl/cli.py
@@ -5,13 +5,54 @@ import argparse
 import json
 import pprint
 import time
+import os
 
 from lib import YnlFamily
 
+class ynlConfig():
+    def __init__(self):
+        self.no_schema = True
+        self.schema = None
+        self.spec = None
+        self.json_text = None
+        self.ntf = None
+        self.sleep = None
+        self.do = None
+        self.dump = None
+    def run(self):
+        ynl_cfg(self.no_schema, self.spec, self.schema, self.json_text, self.ntf, self.sleep, self.do, self.dump)
+
+def ynl_cfg(no_schema, spec, schema, json_text, ntf, sleep, do, dump):
+
+        if no_schema:
+            schema = ''
+
+        attrs = {}
+        if json_text:
+            attrs = json.loads(json_text)
+
+        ynl = YnlFamily(spec, schema)
+
+        if ntf:
+            ynl.ntf_subscribe(ntf)
+
+        if sleep:
+            time.sleep(sleep)
+
+        if do:
+            reply = ynl.do(do, attrs)
+            pprint.PrettyPrinter().pprint(reply)
+        if dump:
+            reply = ynl.dump(dump, attrs)
+            pprint.PrettyPrinter().pprint(reply)
+
+        if ntf:
+            ynl.check_ntf()
+            pprint.PrettyPrinter().pprint(ynl.async_msg_queue)
 
 def main():
     parser = argparse.ArgumentParser(description='YNL CLI sample')
-    parser.add_argument('--spec', dest='spec', type=str, required=True)
+    parser.add_argument('--spec', dest='spec', type=str)
     parser.add_argument('--schema', dest='schema', type=str)
     parser.add_argument('--no-schema', action='store_true')
     parser.add_argument('--json', dest='json_text', type=str)
@@ -19,34 +60,59 @@ def main():
     parser.add_argument('--dump', dest='dump', type=str)
     parser.add_argument('--sleep', dest='sleep', type=int)
     parser.add_argument('--subscribe', dest='ntf', type=str)
+    parser.add_argument('--config', dest='config', type=str)
     args = parser.parse_args()
 
-    if args.no_schema:
-        args.schema = ''
-
-    attrs = {}
-    if args.json_text:
-        attrs = json.loads(args.json_text)
+    if args.config:
+        directory = ""
+        yamls = {}
 
-    ynl = YnlFamily(args.spec, args.schema)
+        if not os.path.exists(args.config):
+             print("Error: ", args.config, " doesn't exist")
+             exit(-1)
 
-    if args.ntf:
-        ynl.ntf_subscribe(args.ntf)
+        f = open(args.config)
+        data = json.load(f)
 
-    if args.sleep:
-        time.sleep(args.sleep)
+        for k in data:
+            if k == 'yaml-specs-path':
+                directory = data[k]
 
-    if args.do:
-        reply = ynl.do(args.do, attrs)
-        pprint.PrettyPrinter().pprint(reply)
-    if args.dump:
-        reply = ynl.dump(args.dump, attrs)
-        pprint.PrettyPrinter().pprint(reply)
+                # Scan the dir and get all the yaml files.
+                for filename in os.scandir(directory):
+                    if filename.is_file():
+                        if filename.name.endswith('.yaml'):
+                            yamls[filename.name] = filename.path
 
-    if args.ntf:
-        ynl.check_ntf()
-        pprint.PrettyPrinter().pprint(ynl.async_msg_queue)
+            elif k == 'spec-args':
+               for v in data[k]:
+                    print("############### ",v," ###############\n")
+                    cfg = ynlConfig()
+                    # Check for yaml from the specs we found earlier
+                    if v in yamls:
+                        # FOUND
+                        cfg.spec = yamls[v]
+                        if 'no-schema' in data[k][v]:
+                            cfg.no_schema = data[k][v]['no-schema']
+                        if 'schema' in data[k][v]:
+                            cfg.schema = data[k][v]['schema']
+                            cfg.no_schema = False
+                        if 'do' in data[k][v]:
+                            cfg.do = data[k][v]['do']
+                        if 'dump' in data[k][v]:
+                            cfg.dump = data[k][v]['dump']
+                        if 'subscribe' in data[k][v]:
+                            cfg.ntf = data[k][v]['subscribe']
+                        if 'sleep' in data[k][v]:
+                            cfg.sleep = data[k][v]['sleep']
+                        if 'json-params' in data[k][v]:
+                            cfg.json_text = json.dumps(data[k][v]['json-params'])
 
+                        cfg.run()
+                    else:
+                        print("Error: ", v, " doesn't have a valid yaml file in ", directory, "\n")
+    else:
+        ynl_cfg(args.no_schema, args.spec, args.schema, args.json_text, args.ntf, args.sleep, args.do, args.dump)
 
 if __name__ == "__main__":
     main()
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [net-next,v1 2/2] tools/net/ynl: validate config against schema
  2023-07-27  8:55 [net-next,v1 0/2] tools/net/ynl: enable json configuration mtahhan
  2023-07-27  8:55 ` [net-next,v1 1/2] tools/net/ynl: configuration through json mtahhan
@ 2023-07-27  8:55 ` mtahhan
  2023-07-27  9:38 ` [net-next,v1 0/2] tools/net/ynl: enable json configuration Maryam Tahhan
  2 siblings, 0 replies; 4+ messages in thread
From: mtahhan @ 2023-07-27  8:55 UTC (permalink / raw)
  To: netdev, kuba, davem, edumazet, pabeni; +Cc: Maryam Tahhan, Keith Wiles

From: Maryam Tahhan <mtahhan@redhat.com>

Signed-off-by: Maryam Tahhan <mtahhan@redhat.com>
Signed-off-by: Keith Wiles <keith.wiles@intel.com>
---
 tools/net/ynl/cli.py            | 43 ++++++++++++++++----
 tools/net/ynl/ynl-config.schema | 72 +++++++++++++++++++++++++++++++++
 2 files changed, 108 insertions(+), 7 deletions(-)
 create mode 100644 tools/net/ynl/ynl-config.schema

diff --git a/tools/net/ynl/cli.py b/tools/net/ynl/cli.py
index 1749851f8460..3071ef9e3117 100755
--- a/tools/net/ynl/cli.py
+++ b/tools/net/ynl/cli.py
@@ -9,6 +9,12 @@ import os
 
 from lib import YnlFamily
 
+try:
+    import jsonschema
+except ModuleNotFoundError as e:
+    print('Error: {}. Try `pip install jsonschema`'.format(e))
+    raise SystemExit(1)
+
 class ynlConfig():
     def __init__(self):
         self.no_schema = True
@@ -66,13 +72,36 @@ def main():
     if args.config:
         directory = ""
         yamls = {}
-
-        if not os.path.exists(args.config):
-             print("Error: ", args.config, " doesn't exist")
-             exit(-1)
-
-        f = open(args.config)
-        data = json.load(f)
+        configSchema = os.path.dirname(__file__) + "/ynl-config.schema"
+
+        # Load ynl-config json schema
+        try:
+            with open(configSchema, 'r') as f:
+                s = json.load(f)
+        except FileNotFoundError as e:
+            print('Error:', e)
+            raise SystemExit(1)
+        except json.decoder.JSONDecodeError as e:
+            print('Error: {}:'.format(args.schema), e)
+            raise SystemExit(1)
+
+        # Load config file
+        try:
+            with open(args.config, 'r') as f:
+                data = json.load(f)
+        except FileNotFoundError as e:
+            print('Error:', e)
+            raise SystemExit(1)
+        except json.decoder.JSONDecodeError as e:
+            print('Error: {}:'.format(args.schema), e)
+            raise SystemExit(1)
+
+        # Validate json config against the ynl-config schema
+        try:
+            jsonschema.validate(instance=data, schema=s)
+        except jsonschema.exceptions.ValidationError as e:
+            print('Error:', e)
+            raise SystemExit(1)
 
         for k in data:
             if k == 'yaml-specs-path':
diff --git a/tools/net/ynl/ynl-config.schema b/tools/net/ynl/ynl-config.schema
new file mode 100644
index 000000000000..c127e2acbabb
--- /dev/null
+++ b/tools/net/ynl/ynl-config.schema
@@ -0,0 +1,72 @@
+{
+    "$schema": "https://json-schema.org/draft-07/schema",
+    "description": "YNL specs configuration file",
+    "type": "object",
+
+    "properties": {
+        "yaml-specs-path": {
+            "description": "Path to Yaml specs",
+            "type": "string"
+        },
+        "spec-args": {
+            "description": "Individual spec args",
+            "type": "object",
+            "patternProperties": {
+                "^.*(\\.yaml)$": {
+                    "description": "Specific yaml spec arguments",
+                    "type": "object",
+                    "properties": {
+                        "schema": {
+                            "description": "The schema to use",
+                            "type": "string"
+                        },
+                        "no-schema": {
+                            "description": "No schema",
+                            "type": "boolean",
+                            "default": true
+                        },
+                        "do": {
+                            "description": "The do function to use",
+                            "type": "string"
+                        },
+                        "dump": {
+                            "description": "The dump function to use",
+                            "type": "string"
+                        },
+                        "subscribe": {
+                            "description": "The multicast group to subscribe to",
+                            "type": "string"
+                        },
+                        "sleep": {
+                            "description": "The number to seconds to sleep",
+                            "type": "number",
+                            "default": 0
+                        },
+                        "json-params": {
+                            "description": "The json params to use for different functions",
+                            "type": "object",
+                            "patternProperties": {
+                                "^.*$": {
+                                  "type": ["string", "number", "object"],
+                                  "patternProperties": {
+                                        "^.*$": {
+                                        "type": ["string", "number"]
+                                        }
+                                    },
+                                    "additionalProperties": false
+                                }
+                            }
+                        },
+                        "additionalProperties": false
+                    },
+                    "additionalProperties": false
+                }
+            },
+            "additionalProperties": false
+        }
+    },
+    "additionalProperties": false,
+    "required": [
+        "yaml-specs-path"
+    ]
+}
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [net-next,v1 0/2] tools/net/ynl: enable json configuration
  2023-07-27  8:55 [net-next,v1 0/2] tools/net/ynl: enable json configuration mtahhan
  2023-07-27  8:55 ` [net-next,v1 1/2] tools/net/ynl: configuration through json mtahhan
  2023-07-27  8:55 ` [net-next,v1 2/2] tools/net/ynl: validate config against schema mtahhan
@ 2023-07-27  9:38 ` Maryam Tahhan
  2 siblings, 0 replies; 4+ messages in thread
From: Maryam Tahhan @ 2023-07-27  9:38 UTC (permalink / raw)
  To: netdev, kuba, davem, edumazet, pabeni

On 27/07/2023 09:55, mtahhan@redhat.com wrote:
> From: Maryam Tahhan <mtahhan@redhat.com>
>
> Use a json configuration file to pass parameters to ynl to allow
> for operations on multiple specs in one go. Additionally, check
> this new configuration against a schema to validate it in the cli
> module before parsing it and passing info to the ynl module.

Apologies all. I didn't notice format patch inserting my email address 
at the start of the commits in the patch files
I will respin...

...


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-07-27  9:39 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-07-27  8:55 [net-next,v1 0/2] tools/net/ynl: enable json configuration mtahhan
2023-07-27  8:55 ` [net-next,v1 1/2] tools/net/ynl: configuration through json mtahhan
2023-07-27  8:55 ` [net-next,v1 2/2] tools/net/ynl: validate config against schema mtahhan
2023-07-27  9:38 ` [net-next,v1 0/2] tools/net/ynl: enable json configuration Maryam Tahhan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).