All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.