diff options
| author | Daniil Baturin <daniil@vyos.io> | 2025-10-02 15:21:48 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-10-02 15:21:48 +0100 |
| commit | b4d33753c2f414609167cd18c7a5d39a3a7b4b6f (patch) | |
| tree | 2f61c3f4bddfdae7670d008cd05854ab38d8a8e3 | |
| parent | 2323b1ba6d7218c36434cfe988b1a2c9b517221c (diff) | |
| parent | 28a605928daa951ea140bb3d30258508d00450e5 (diff) | |
| download | vyos-1x-b4d33753c2f414609167cd18c7a5d39a3a7b4b6f.tar.gz vyos-1x-b4d33753c2f414609167cd18c7a5d39a3a7b4b6f.zip | |
Merge pull request #4758 from dmbaturin/T7871-op-mode-constraints
op-mode: T7871: add support for op mode command argument constraints
| -rwxr-xr-x | python/vyos/xml_ref/generate_op_cache.py | 37 | ||||
| -rw-r--r-- | python/vyos/xml_ref/op_definition.py | 2 | ||||
| -rw-r--r-- | schema/interface_definition.rng | 8 | ||||
| -rw-r--r-- | schema/op-mode-definition.rnc | 23 | ||||
| -rw-r--r-- | schema/op-mode-definition.rng | 45 |
5 files changed, 102 insertions, 13 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) diff --git a/schema/interface_definition.rng b/schema/interface_definition.rng index d653d1b01..f36d95eed 100644 --- a/schema/interface_definition.rng +++ b/schema/interface_definition.rng @@ -2,19 +2,19 @@ <grammar xmlns="http://relaxng.org/ns/structure/1.0"> <!-- interface_definition.rnc: VyConf reference tree XML grammar - + Copyright VyOS maintainers and contributors <maintainers@vyos.io> - + This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. - + This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - + You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 diff --git a/schema/op-mode-definition.rnc b/schema/op-mode-definition.rnc index c10cf0431..4dc2592c0 100644 --- a/schema/op-mode-definition.rnc +++ b/schema/op-mode-definition.rnc @@ -89,12 +89,12 @@ children = element children # Nodes may have properties # For simplicity, any property is allowed in any node, # but whether they are used or not is implementation-defined - - properties = element properties { help? & - completionHelp* + completionHelp* & + constraint? & + (element constraintErrorMessage { text })? } # All nodes must have "name" attribute @@ -103,9 +103,22 @@ nodeNameAttr = attribute name text } +# Tag and leaf nodes may have constraints on their names and values +# (respectively). +# When multiple constraints are listed, they work as logical OR +constraint = element constraint +{ + ( (element regex { text }) | + validator )+ +} - - +# A constraint may also use an external validator rather than regex +validator = element validator +{ + ( (attribute name { text }) & + (attribute argument { text })? ), + empty +} # help tags contains brief description of the purpose of the node help = element help diff --git a/schema/op-mode-definition.rng b/schema/op-mode-definition.rng index 692584fb4..ec2a4c649 100644 --- a/schema/op-mode-definition.rng +++ b/schema/op-mode-definition.rng @@ -2,19 +2,19 @@ <grammar xmlns="http://relaxng.org/ns/structure/1.0"> <!-- interface_definition.rnc: VyConf reference tree XML grammar - + Copyright VyOS maintainers and contributors <maintainers@vyos.io> - + This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. - + This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - + You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 @@ -178,6 +178,14 @@ <zeroOrMore> <ref name="completionHelp"/> </zeroOrMore> + <optional> + <ref name="constraint"/> + </optional> + <optional> + <element name="constraintErrorMessage"> + <text/> + </element> + </optional> </interleave> </element> </define> @@ -185,6 +193,35 @@ <define name="nodeNameAttr"> <attribute name="name"/> </define> + <!-- + Tag and leaf nodes may have constraints on their names and values + (respectively). + When multiple constraints are listed, they work as logical OR + --> + <define name="constraint"> + <element name="constraint"> + <oneOrMore> + <choice> + <element name="regex"> + <text/> + </element> + <ref name="validator"/> + </choice> + </oneOrMore> + </element> + </define> + <!-- A constraint may also use an external validator rather than regex --> + <define name="validator"> + <element name="validator"> + <interleave> + <attribute name="name"/> + <optional> + <attribute name="argument"/> + </optional> + </interleave> + <empty/> + </element> + </define> <!-- help tags contains brief description of the purpose of the node --> <define name="help"> <element name="help"> |
