diff options
-rw-r--r-- | data/op-mode-standardized.json | 1 | ||||
-rw-r--r-- | op-mode-definitions/include/vni-tagnode-all.xml.i | 5 | ||||
-rw-r--r-- | op-mode-definitions/include/vni-tagnode.xml.i | 5 | ||||
-rw-r--r-- | op-mode-definitions/show-evpn.xml.in | 59 | ||||
-rwxr-xr-x | src/completion/list_esi.sh | 20 | ||||
-rwxr-xr-x | src/completion/list_vni.sh | 20 | ||||
-rwxr-xr-x | src/conf_mode/nat_cgnat.py | 21 | ||||
-rw-r--r-- | src/op_mode/evpn.py | 46 |
8 files changed, 167 insertions, 10 deletions
diff --git a/data/op-mode-standardized.json b/data/op-mode-standardized.json index eea8244ec..c14133127 100644 --- a/data/op-mode-standardized.json +++ b/data/op-mode-standardized.json @@ -10,6 +10,7 @@ "cpu.py", "dhcp.py", "dns.py", +"evpn.py", "interfaces.py", "ipsec.py", "lldp.py", diff --git a/op-mode-definitions/include/vni-tagnode-all.xml.i b/op-mode-definitions/include/vni-tagnode-all.xml.i index 0fedb9371..fabab19d7 100644 --- a/op-mode-definitions/include/vni-tagnode-all.xml.i +++ b/op-mode-definitions/include/vni-tagnode-all.xml.i @@ -3,9 +3,10 @@ <properties> <help>VXLAN network identifier (VNI) number</help> <completionHelp> - <list>1-16777215 all</list> + <list><1-16777215> all</list> + <script>${vyos_completion_dir}/list_vni.sh</script> </completionHelp> </properties> - <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command> + <command>${vyos_op_scripts_dir}/evpn.py show_evpn --command "$*"</command> </tagNode> <!-- included end --> diff --git a/op-mode-definitions/include/vni-tagnode.xml.i b/op-mode-definitions/include/vni-tagnode.xml.i index 22f2d33bd..f5b99dcc8 100644 --- a/op-mode-definitions/include/vni-tagnode.xml.i +++ b/op-mode-definitions/include/vni-tagnode.xml.i @@ -3,9 +3,10 @@ <properties> <help>VXLAN network identifier (VNI) number</help> <completionHelp> - <list>1-16777215</list> + <list><1-16777215></list> + <script>${vyos_completion_dir}/list_vni.sh</script> </completionHelp> </properties> - <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command> + <command>${vyos_op_scripts_dir}/evpn.py show_evpn --command "$*"</command> </tagNode> <!-- included end --> diff --git a/op-mode-definitions/show-evpn.xml.in b/op-mode-definitions/show-evpn.xml.in index a005cbc30..3c1e5c7d6 100644 --- a/op-mode-definitions/show-evpn.xml.in +++ b/op-mode-definitions/show-evpn.xml.in @@ -14,7 +14,7 @@ <children> #include <include/frr-detail.xml.i> </children> - <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command> + <command>${vyos_op_scripts_dir}/evpn.py show_evpn --command "$*"</command> </node> <tagNode name="access-vlan"> <properties> @@ -31,7 +31,7 @@ <list><1-4094></list> </completionHelp> </properties> - <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command> + <command>${vyos_op_scripts_dir}/evpn.py show_evpn --command "$*"</command> </node> </children> </tagNode> @@ -43,6 +43,45 @@ #include <include/vni-tagnode-all.xml.i> </children> </node> + <tagNode name="es"> + <properties> + <help>Show ESI information for specified ESI</help> + <completionHelp> + <list><esi></list> + <script>${vyos_completion_dir}/list_esi.sh</script> + </completionHelp> + </properties> + <command>${vyos_op_scripts_dir}/evpn.py show_evpn --command "$*"</command> + </tagNode> + <node name="es"> + <properties> + <help>Show ESI information</help> + </properties> + <command>${vyos_op_scripts_dir}/evpn.py show_evpn --command "$*"</command> + <children> + <leafNode name="detail"> + <properties> + <help>Show ESI details</help> + </properties> + <command>${vyos_op_scripts_dir}/evpn.py show_evpn --command "$*"</command> + </leafNode> + </children> + </node> + <node name="es-evi"> + <properties> + <help>Show ESI information per EVI</help> + </properties> + <command>${vyos_op_scripts_dir}/evpn.py show_evpn --command "$*"</command> + <children> + <leafNode name="detail"> + <properties> + <help>Show ESI per EVI details</help> + </properties> + <command>${vyos_op_scripts_dir}/evpn.py show_evpn --command "$*"</command> + </leafNode> + #include <include/vni-tagnode.xml.i> + </children> + </node> <node name="mac"> <properties> <help>MAC addresses</help> @@ -67,7 +106,23 @@ #include <include/vni-tagnode-all.xml.i> </children> </node> + #include <include/vni-tagnode.xml.i> + <node name="vni"> + <properties> + <help>Show VNI information</help> + </properties> + <command>${vyos_op_scripts_dir}/evpn.py show_evpn --command "$*"</command> + <children> + <leafNode name="detail"> + <properties> + <help>Show VNI details</help> + </properties> + <command>${vyos_op_scripts_dir}/evpn.py show_evpn --command "$*"</command> + </leafNode> + </children> + </node> </children> + <command>${vyos_op_scripts_dir}/evpn.py show_evpn --command "$*"</command> </node> </children> </node> diff --git a/src/completion/list_esi.sh b/src/completion/list_esi.sh new file mode 100755 index 000000000..b8373fa57 --- /dev/null +++ b/src/completion/list_esi.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright (C) 2024 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# This script is completion helper to list all valid ESEs that are visible to FRR + +esiJson=$(vtysh -c 'show evpn es json') +echo "$(echo "$esiJson" | jq -r '.[] | .esi')" diff --git a/src/completion/list_vni.sh b/src/completion/list_vni.sh new file mode 100755 index 000000000..f8bd4a993 --- /dev/null +++ b/src/completion/list_vni.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# +# Copyright (C) 2024 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# This script is completion helper to list all configured VNIs that are visible to FRR + +vniJson=$(vtysh -c 'show evpn vni json') +echo "$(echo "$vniJson" | jq -r 'keys | .[]')" diff --git a/src/conf_mode/nat_cgnat.py b/src/conf_mode/nat_cgnat.py index f41d66c66..9a20a3c54 100755 --- a/src/conf_mode/nat_cgnat.py +++ b/src/conf_mode/nat_cgnat.py @@ -203,6 +203,11 @@ def verify(config): f'Range for "{pool} pool {pool_name}" must be defined!' ) + external_pools_query = "keys(pool.external)" + external_pools: list = jmespath.search(external_pools_query, config) + internal_pools_query = "keys(pool.internal)" + internal_pools: list = jmespath.search(internal_pools_query, config) + for rule, rule_config in config['rule'].items(): if 'source' not in rule_config: raise ConfigError(f'Rule "{rule}" source pool must be defined!') @@ -212,6 +217,14 @@ def verify(config): if 'translation' not in rule_config: raise ConfigError(f'Rule "{rule}" translation pool must be defined!') + internal_pool = rule_config['source']['pool'] + if internal_pool not in internal_pools: + raise ConfigError(f'Internal pool "{internal_pool}" does not exist!') + + external_pool = rule_config['translation']['pool'] + if external_pool not in external_pools: + raise ConfigError(f'External pool "{external_pool}" does not exist!') + def generate(config): if not config: @@ -219,8 +232,8 @@ def generate(config): # first external pool as we allow only one as PoC ext_pool_name = jmespath.search("rule.*.translation | [0]", config).get('pool') int_pool_name = jmespath.search("rule.*.source | [0]", config).get('pool') - ext_query = f"pool.external.{ext_pool_name}.range | keys(@)" - int_query = f"pool.internal.{int_pool_name}.range" + ext_query = f'pool.external."{ext_pool_name}".range | keys(@)' + int_query = f'pool.internal."{int_pool_name}".range' external_ranges = jmespath.search(ext_query, config) internal_ranges = [jmespath.search(int_query, config)] @@ -246,10 +259,10 @@ def generate(config): external_host_count = sum(external_list_count) internal_host_count = sum(internal_list_count) ports_per_user = int( - jmespath.search(f'pool.external.{ext_pool_name}.per_user_limit.port', config) + jmespath.search(f'pool.external."{ext_pool_name}".per_user_limit.port', config) ) external_port_range: str = jmespath.search( - f'pool.external.{ext_pool_name}.external_port_range', config + f'pool.external."{ext_pool_name}".external_port_range', config ) proto_maps, other_maps = generate_port_rules( diff --git a/src/op_mode/evpn.py b/src/op_mode/evpn.py new file mode 100644 index 000000000..cae4ab9f5 --- /dev/null +++ b/src/op_mode/evpn.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2016-2024 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# This script is a helper to run VTYSH commands for "show evpn", allowing for the --raw flag to output JSON + +import sys +import typing +import json + +import vyos.opmode +from vyos.utils.process import cmd + +def show_evpn(raw: bool, command: typing.Optional[str]): + if raw: + command = f"{command} json" + evpnDict = {} + try: + evpnDict['evpn'] = json.loads(cmd(f"vtysh -c '{command}'")) + except: + raise vyos.opmode.DataUnavailable(f"\"{command.replace(' json', '')}\" is invalid or has no JSON option") + + return evpnDict + else: + return cmd(f"vtysh -c '{command}'") + +if __name__ == '__main__': + try: + res = vyos.opmode.run(sys.modules[__name__]) + if res: + print(res) + except (ValueError, vyos.opmode.Error) as e: + print(e) + sys.exit(1) |