* [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).