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