summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorDaniil Baturin <daniil@baturin.org>2025-09-26 14:45:30 +0100
committerDaniil Baturin <daniil@baturin.org>2025-09-26 14:45:30 +0100
commit28a605928daa951ea140bb3d30258508d00450e5 (patch)
tree3263d5afbadd83016801357d658bad98fbeaf2e6 /python
parent06e491caf2fdd8b4e2fe5f3b4396680fca61eeab (diff)
downloadvyos-1x-28a605928daa951ea140bb3d30258508d00450e5.tar.gz
vyos-1x-28a605928daa951ea140bb3d30258508d00450e5.zip
op-mode: T7871: add support for op mode command argument constraints
Diffstat (limited to 'python')
-rwxr-xr-xpython/vyos/xml_ref/generate_op_cache.py37
-rw-r--r--python/vyos/xml_ref/op_definition.py2
2 files changed, 39 insertions, 0 deletions
diff --git a/python/vyos/xml_ref/generate_op_cache.py b/python/vyos/xml_ref/generate_op_cache.py
index f49b2290b..1c183fc8c 100755
--- a/python/vyos/xml_ref/generate_op_cache.py
+++ b/python/vyos/xml_ref/generate_op_cache.py
@@ -139,6 +139,39 @@ def sort_op_data(obj):
key_func = cmp_to_key(compare_keys)
return sort_func(obj, key_func)
+def get_constraints(props):
+ if props is None:
+ return None
+
+ # Put regexes and validators into separate dict fields.
+ # Since multiple constraints work like logical OR,
+ # it's better for the runner can evaluate regexes internally first,
+ # which is much faster than calling external validators.
+ constraints = {
+ 'regexes': [],
+ 'validators': []
+ }
+
+ constraint_elem = props.find('constraint')
+
+ if constraint_elem is not None:
+ constraint_elems = list(constraint_elem)
+ if constraint_elems:
+ for ce in constraint_elems:
+ if ce.tag == 'regex':
+ constraints['regexes'].append(ce.text)
+ elif ce.tag == 'validator':
+ name = ce.get('name')
+ arg = ce.get('argument')
+ validator = {'name': name, 'argument': arg}
+ constraints['validators'].append(validator)
+ else:
+ print(f"Ignoring unknown validator type {ce.tag}")
+
+ if constraints['regexes'] or constraints['validators']:
+ return constraints
+ else:
+ return None
def insert_node(
n: Element, d: dict, path: list[str] = None, parent: NodeData = None, file: str = ''
@@ -148,6 +181,8 @@ def insert_node(
children: OptElement = n.find('children')
command: OptElement = n.find('command')
standalone: OptElement = n.find('standalone')
+ constraints: OptElement = get_constraints(prop)
+ constraint_error_message: OptElement = n.find('constraintErrorMessage')
node_type: str = n.tag
if node_type == 'virtualTagNode':
@@ -224,6 +259,8 @@ def insert_node(
new_node_data.command = command_text
new_node_data.standalone_help_text = standalone_help_text
new_node_data.standalone_command = standalone_command
+ new_node_data.constraints = constraints
+ new_node_data.constraint_error_message = constraint_error_message
new_node_data.path = path
new_node_data.files = [file]
diff --git a/python/vyos/xml_ref/op_definition.py b/python/vyos/xml_ref/op_definition.py
index d4b767324..a172f890a 100644
--- a/python/vyos/xml_ref/op_definition.py
+++ b/python/vyos/xml_ref/op_definition.py
@@ -34,6 +34,8 @@ class NodeData:
command: str = ''
standalone_help_text: Optional[str] = None
standalone_command: Optional[str] = None
+ constraints: Optional[dict] = None
+ constraint_error_message: Optional[str] = None
path: list[str] = field(default_factory=list)
files: list[str] = field(default_factory=list)
children: list[tuple] = field(default_factory=list)