diff options
20 files changed, 261 insertions, 153 deletions
diff --git a/.github/workflows/unused-imports.yml b/.github/workflows/unused-imports.yml index d6e820ae6..da57bd270 100644 --- a/.github/workflows/unused-imports.yml +++ b/.github/workflows/unused-imports.yml @@ -1,7 +1,9 @@ name: Check for unused imports using Pylint on: pull_request_target: - types: [opened, reopened, ready_for_review, locked] + branches: + - current + - sagitta jobs: Check-Unused-Imports: diff --git a/data/templates/conntrackd/conntrackd.conf.j2 b/data/templates/conntrackd/conntrackd.conf.j2 index 669b20877..30e619daf 100644 --- a/data/templates/conntrackd/conntrackd.conf.j2 +++ b/data/templates/conntrackd/conntrackd.conf.j2 @@ -4,6 +4,7 @@ Sync { Mode FTFW { DisableExternalCache {{ 'on' if disable_external_cache is vyos_defined else 'off' }} + StartupResync {{ 'on' if startup_resync is vyos_defined else 'off' }} } {% for iface, iface_config in interface.items() %} {% if iface_config.peer is vyos_defined %} diff --git a/interface-definitions/container.xml.in b/interface-definitions/container.xml.in index 7e1f4811a..94f2e92f5 100644 --- a/interface-definitions/container.xml.in +++ b/interface-definitions/container.xml.in @@ -21,9 +21,9 @@ <valueless/> </properties> </leafNode> - <leafNode name="cap-add"> + <leafNode name="capability"> <properties> - <help>Container capabilities/permissions</help> + <help>Grant individual Linux capability to container instance</help> <completionHelp> <list>net-admin net-bind-service net-raw setpcap sys-admin sys-module sys-time</list> </completionHelp> diff --git a/interface-definitions/include/version/container-version.xml.i b/interface-definitions/include/version/container-version.xml.i index 129469cec..ed6e942cd 100644 --- a/interface-definitions/include/version/container-version.xml.i +++ b/interface-definitions/include/version/container-version.xml.i @@ -1,3 +1,3 @@ <!-- include start from include/version/container-version.xml.i --> -<syntaxVersion component='container' version='1'></syntaxVersion> +<syntaxVersion component='container' version='2'></syntaxVersion> <!-- include end --> diff --git a/interface-definitions/service_conntrack-sync.xml.in b/interface-definitions/service_conntrack-sync.xml.in index 397864867..631c830b4 100644 --- a/interface-definitions/service_conntrack-sync.xml.in +++ b/interface-definitions/service_conntrack-sync.xml.in @@ -81,6 +81,12 @@ <multi/> </properties> </leafNode> + <leafNode name="startup-resync"> + <properties> + <help>Order conntrackd to request a complete conntrack table resync against the other node at startup</help> + <valueless/> + </properties> + </leafNode> <node name="failover-mechanism"> <properties> <help>Failover mechanism to use for conntrack-sync</help> diff --git a/smoketest/config-tests/container-simple b/smoketest/config-tests/container-simple new file mode 100644 index 000000000..299af64cb --- /dev/null +++ b/smoketest/config-tests/container-simple @@ -0,0 +1,12 @@ +set system config-management commit-revisions '50' +set system host-name 'vyos' +set system login user vyos authentication encrypted-password '$6$r/Yw/07NXNY$/ZB.Rjf9jxEV.BYoDyLdH.kH14rU52pOBtrX.4S34qlPt77chflCHvpTCq9a6huLzwaMR50rEICzA5GoIRZlM0' +set system login user vyos authentication plaintext-password '' +set system console device ttyS0 speed '115200' +set container name c01 allow-host-networks +set container name c01 capability 'net-bind-service' +set container name c01 capability 'net-raw' +set container name c01 image 'busybox:stable' +set container name c02 allow-host-networks +set container name c02 capability 'sys-time' +set container name c02 image 'busybox:stable' diff --git a/smoketest/config-tests/ipoe-server b/smoketest/config-tests/ipoe-server new file mode 100644 index 000000000..fb32fdb14 --- /dev/null +++ b/smoketest/config-tests/ipoe-server @@ -0,0 +1,35 @@ +set interfaces ethernet eth0 address 'dhcp' +set interfaces ethernet eth1 address '192.168.0.1/24' +set interfaces loopback lo +set service ntp server time1.vyos.net +set service ntp server time2.vyos.net +set service ntp server time3.vyos.net +set service ipoe-server authentication interface eth1 mac 08:00:27:2f:d8:06 rate-limit download '1000' +set service ipoe-server authentication interface eth1 mac 08:00:27:2f:d8:06 rate-limit upload '500' +set service ipoe-server authentication interface eth1 mac 08:00:27:2f:d8:06 vlan '100' +set service ipoe-server authentication interface eth2 mac 08:00:27:2f:d8:06 +set service ipoe-server authentication mode 'local' +set service ipoe-server client-ip-pool POOL1 range '192.0.2.0/24' +set service ipoe-server client-ipv6-pool ipv6-pool delegate 2001:db8:1::/48 delegation-prefix '56' +set service ipoe-server client-ipv6-pool ipv6-pool prefix 2001:db8::/48 mask '64' +set service ipoe-server default-ipv6-pool 'ipv6-pool' +set service ipoe-server default-pool 'POOL1' +set service ipoe-server gateway-address '192.0.2.1/24' +set service ipoe-server interface eth1 mode 'l3' +set service ipoe-server interface eth1 network 'vlan' +set service ipoe-server interface eth1 vlan '100' +set service ipoe-server interface eth1 vlan '200' +set service ipoe-server interface eth1 vlan '1000-2000' +set service ipoe-server interface eth1 vlan '2500-2700' +set service ipoe-server name-server '10.10.1.1' +set service ipoe-server name-server '10.10.1.2' +set service ipoe-server name-server '2001:db8:aaa::' +set service ipoe-server name-server '2001:db8:bbb::' +set system config-management commit-revisions '100' +set system host-name 'vyos' +set system login user vyos authentication encrypted-password '$6$O5gJRlDYQpj$MtrCV9lxMnZPMbcxlU7.FI793MImNHznxGoMFgm3Q6QP3vfKJyOSRCt3Ka/GzFQyW1yZS4NS616NLHaIPPFHc0' +set system login user vyos authentication plaintext-password '' +set system console device ttyS0 speed '115200' +set nat source rule 100 outbound-interface name 'eth0' +set nat source rule 100 source address '192.168.0.0/24' +set nat source rule 100 translation address 'masquerade' diff --git a/smoketest/configs/container-simple b/smoketest/configs/container-simple new file mode 100644 index 000000000..05efe05e9 --- /dev/null +++ b/smoketest/configs/container-simple @@ -0,0 +1,46 @@ +container { + name c01 { + allow-host-networks + cap-add net-bind-service + cap-add net-raw + image busybox:stable + } + name c02 { + allow-host-networks + cap-add sys-time + image busybox:stable + } +} +interfaces { + ethernet eth0 { + duplex auto + speed auto + } + ethernet eth1 { + duplex auto + speed auto + } +} +system { + config-management { + commit-revisions 50 + } + console { + device ttyS0 { + speed 115200 + } + } + host-name vyos + login { + user vyos { + authentication { + encrypted-password $6$r/Yw/07NXNY$/ZB.Rjf9jxEV.BYoDyLdH.kH14rU52pOBtrX.4S34qlPt77chflCHvpTCq9a6huLzwaMR50rEICzA5GoIRZlM0 + plaintext-password "" + } + } + } +} + +// Warning: Do not remove the following line. +// vyos-config-version: "broadcast-relay@1:cluster@1:config-management@1:conntrack@3:conntrack-sync@2:container@1:dhcp-relay@2:dhcp-server@6:dhcpv6-server@1:dns-forwarding@3:firewall@5:https@2:interfaces@23:ipoe-server@1:ipsec@5:isis@1:l2tp@3:lldp@1:mdns@1:nat@5:ntp@1:pppoe-server@5:pptp@2:qos@1:quagga@8:rpki@1:salt@1:snmp@2:ssh@2:sstp@3:system@21:vrrp@2:vyos-accel-ppp@2:wanloadbalance@3:webproxy@2:zone-policy@1" +// Release version: 1.3.6 diff --git a/smoketest/configs/ipoe-server b/smoketest/configs/ipoe-server index a375e91de..fdd554b7d 100644 --- a/smoketest/configs/ipoe-server +++ b/smoketest/configs/ipoe-server @@ -56,7 +56,6 @@ service { } } interface eth1 { - client-subnet 192.168.0.0/24 network vlan network-mode L3 vlan-id 100 @@ -64,9 +63,6 @@ service { vlan-range 1000-2000 vlan-range 2500-2700 } - interface eth2 { - client-subnet 192.168.1.0/24 - } name-server 10.10.1.1 name-server 10.10.1.2 name-server 2001:db8:aaa:: @@ -94,11 +90,11 @@ system { } } ntp { - server 0.pool.ntp.org { + server time1.vyos.net { } - server 1.pool.ntp.org { + server time2.vyos.net { } - server 2.pool.ntp.org { + server time3.vyos.net { } } syslog { diff --git a/smoketest/scripts/cli/test_interfaces_pppoe.py b/smoketest/scripts/cli/test_interfaces_pppoe.py index e99d8b3d1..2683a3122 100755 --- a/smoketest/scripts/cli/test_interfaces_pppoe.py +++ b/smoketest/scripts/cli/test_interfaces_pppoe.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2019-2023 VyOS maintainers and contributors +# Copyright (C) 2019-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 @@ -20,6 +20,7 @@ from psutil import process_iter from base_vyostest_shim import VyOSUnitTestSHIM from vyos.configsession import ConfigSessionError +from vyos.xml_ref import default_value config_file = '/etc/ppp/peers/{}' base_path = ['interfaces', 'pppoe'] @@ -169,10 +170,10 @@ class PPPoEInterfaceTest(VyOSUnitTestSHIM.TestCase): for interface in self._interfaces: user = f'VyOS-user-{interface}' passwd = f'VyOS-passwd-{interface}' + mtu_default = default_value(base_path + [interface, 'mtu']) - # verify "normal" PPPoE value - 1492 is default MTU tmp = get_config_value(interface, 'mtu')[1] - self.assertEqual(tmp, '1492') + self.assertEqual(tmp, mtu_default) tmp = get_config_value(interface, 'user')[1].replace('"', '') self.assertEqual(tmp, user) tmp = get_config_value(interface, 'password')[1].replace('"', '') diff --git a/smoketest/scripts/cli/test_interfaces_wireless.py b/smoketest/scripts/cli/test_interfaces_wireless.py index 95246a7b9..83b00ac0c 100755 --- a/smoketest/scripts/cli/test_interfaces_wireless.py +++ b/smoketest/scripts/cli/test_interfaces_wireless.py @@ -25,6 +25,7 @@ from vyos.configsession import ConfigSessionError from vyos.utils.process import process_named_running from vyos.utils.kernel import check_kmod from vyos.utils.file import read_file +from vyos.xml_ref import default_value def get_config_value(interface, key): tmp = read_file(f'/run/hostapd/{interface}.conf') @@ -127,7 +128,8 @@ class WirelessInterfaceTest(BasicInterfaceTest.TestCase): # channel tmp = get_config_value(interface, 'channel') - self.assertEqual('0', tmp) # default is channel 0 + cli_default = default_value(self._base_path + [interface, 'channel']) + self.assertEqual(cli_default, tmp) # auto-powersave is special tmp = get_config_value(interface, 'uapsd_advertisement_enabled') diff --git a/smoketest/scripts/cli/test_service_https.py b/smoketest/scripts/cli/test_service_https.py index 94eade2d7..f2a64627f 100755 --- a/smoketest/scripts/cli/test_service_https.py +++ b/smoketest/scripts/cli/test_service_https.py @@ -27,6 +27,7 @@ from vyos.utils.file import read_file from vyos.utils.file import write_file from vyos.utils.process import call from vyos.utils.process import process_named_running +from vyos.xml_ref import default_value from vyos.configsession import ConfigSessionError @@ -147,10 +148,8 @@ class TestHTTPSService(VyOSUnitTestSHIM.TestCase): @ignore_warning(InsecureRequestWarning) def test_api_auth(self): - vhost_id = 'example' address = '127.0.0.1' - port = '443' # default value - name = 'localhost' + port = default_value(base_path + ['port']) key = 'MySuperSecretVyOS' self.cli_set(base_path + ['api', 'keys', 'id', 'key-01', 'key', key]) @@ -420,7 +419,6 @@ class TestHTTPSService(VyOSUnitTestSHIM.TestCase): url = f'https://{address}/config-file' url_config = f'https://{address}/configure' headers = {} - tmp_file = 'tmp-config.boot' self.cli_set(base_path + ['api', 'keys', 'id', 'key-01', 'key', key]) self.cli_commit() diff --git a/smoketest/scripts/cli/test_service_ssh.py b/smoketest/scripts/cli/test_service_ssh.py index 031897c26..b09990c92 100755 --- a/smoketest/scripts/cli/test_service_ssh.py +++ b/smoketest/scripts/cli/test_service_ssh.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2019-2022 VyOS maintainers and contributors +# Copyright (C) 2019-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 @@ -28,6 +28,7 @@ from vyos.utils.process import cmd from vyos.utils.process import is_systemd_service_running from vyos.utils.process import process_named_running from vyos.utils.file import read_file +from vyos.xml_ref import default_value PROCESS_NAME = 'sshd' SSHD_CONF = '/run/sshd/sshd_config' @@ -78,9 +79,10 @@ class TestServiceSSH(VyOSUnitTestSHIM.TestCase): # commit changes self.cli_commit() - # Check configured port - port = get_config_value('Port')[0] - self.assertEqual('22', port) # default value + # Check configured port agains CLI default value + port = get_config_value('Port') + cli_default = default_value(base_path + ['port']) + self.assertEqual(port, cli_default) def test_ssh_single_listen_address(self): # Check if SSH service can be configured and runs diff --git a/src/conf_mode/container.py b/src/conf_mode/container.py index 910a92a7c..0b57221b2 100755 --- a/src/conf_mode/container.py +++ b/src/conf_mode/container.py @@ -262,12 +262,11 @@ def generate_run_arguments(name, container_config): restart = container_config['restart'] # Add capability options. Should be in uppercase - cap_add = '' - if 'cap_add' in container_config: - for c in container_config['cap_add']: - c = c.upper() - c = c.replace('-', '_') - cap_add += f' --cap-add={c}' + capabilities = '' + if 'capability' in container_config: + for cap in container_config['capability']: + cap = cap.upper().replace('-', '_') + capabilities += f' --cap-add={cap}' # Add a host device to the container /dev/x:/dev/x device = '' @@ -330,7 +329,7 @@ def generate_run_arguments(name, container_config): prop = vol_config['propagation'] volume += f' --volume {svol}:{dvol}:{mode},{prop}' - container_base_cmd = f'--detach --interactive --tty --replace {cap_add} ' \ + container_base_cmd = f'--detach --interactive --tty --replace {capabilities} ' \ f'--memory {memory}m --shm-size {shared_memory}m --memory-swap 0 --restart {restart} ' \ f'--name {name} {hostname} {device} {port} {volume} {env_opt} {label} {uid}' diff --git a/src/conf_mode/service_dhcp-server.py b/src/conf_mode/service_dhcp-server.py index f4fb78f57..3b9198ed0 100755 --- a/src/conf_mode/service_dhcp-server.py +++ b/src/conf_mode/service_dhcp-server.py @@ -165,7 +165,6 @@ def verify(dhcp): # Inspect shared-network/subnet listen_ok = False subnets = [] - failover_ok = False shared_networks = len(dhcp['shared_network_name']) disabled_shared_networks = 0 diff --git a/src/conf_mode/service_ipoe-server.py b/src/conf_mode/service_ipoe-server.py index 852b714eb..11e950782 100755 --- a/src/conf_mode/service_ipoe-server.py +++ b/src/conf_mode/service_ipoe-server.py @@ -68,8 +68,8 @@ def verify(ipoe): for interface, iface_config in ipoe['interface'].items(): verify_interface_exists(interface) if 'client_subnet' in iface_config and 'vlan' in iface_config: - raise ConfigError('Option "client-subnet" incompatible with "vlan"!' - 'Use "ipoe client-ip-pool" instead.') + raise ConfigError('Option "client-subnet" and "vlan" are mutually exclusive, ' + 'use "client-ip-pool" instead!') verify_accel_ppp_authentication(ipoe, local_users=False) verify_accel_ppp_ip_pool(ipoe) diff --git a/src/conf_mode/system_login.py b/src/conf_mode/system_login.py index 49306c894..20121f170 100755 --- a/src/conf_mode/system_login.py +++ b/src/conf_mode/system_login.py @@ -336,27 +336,31 @@ def apply(login): command += f' --groups frr,frrvty,vyattacfg,sudo,adm,dip,disk,_kea {user}' try: cmd(command) - # we should not rely on the value stored in - # user_config['home_directory'], as a crazy user will choose - # username root or any other system user which will fail. + # we should not rely on the value stored in user_config['home_directory'], as a + # crazy user will choose username root or any other system user which will fail. # # XXX: Should we deny using root at all? home_dir = getpwnam(user).pw_dir - # T5875: ensure UID is properly set on home directory if user is re-added - # the home directory will always exist, as it's created above by --create-home, - # retrieve current owner of home directory and adjust it on demand - dir_owner = getpwuid(os.stat(home_dir).st_uid).pw_name - if dir_owner != user: - chown(home_dir, user=user, recursive=True) - + # always re-render SSH keys with appropriate permissions render(f'{home_dir}/.ssh/authorized_keys', 'login/authorized_keys.j2', user_config, permission=0o600, formater=lambda _: _.replace(""", '"'), user=user, group='users') - except Exception as e: raise ConfigError(f'Adding user "{user}" raised exception: "{e}"') + # T5875: ensure UID is properly set on home directory if user is re-added + # the home directory will always exist, as it's created above by --create-home, + # retrieve current owner of home directory and adjust on demand + dir_owner = None + try: + dir_owner = getpwuid(os.stat(home_dir).st_uid).pw_name + except: + pass + + if dir_owner != user: + chown(home_dir, user=user, recursive=True) + # Generate 2FA/MFA One-Time-Pad configuration if dict_search('authentication.otp.key', user_config): enable_otp = True diff --git a/src/migration-scripts/container/1-to-2 b/src/migration-scripts/container/1-to-2 new file mode 100755 index 000000000..408faf978 --- /dev/null +++ b/src/migration-scripts/container/1-to-2 @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +# +# 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/>. + +# T6208: container: rename "cap-add" CLI node to "capability" + +from sys import argv +from sys import exit +from vyos.configtree import ConfigTree + +if len(argv) < 2: + print("Must specify file name!") + exit(1) + +file_name = argv[1] + +with open(file_name, 'r') as f: + config_file = f.read() + +base = ['container', 'name'] +config = ConfigTree(config_file) + +# Check if containers exist and we need to perform image manipulation +if not config.exists(base): + # Nothing to do + exit(0) + +for container in config.list_nodes(base): + cap_path = base + [container, 'cap-add'] + if config.exists(cap_path): + config.rename(cap_path, 'capability') + +try: + with open(file_name, 'w') as f: + f.write(config.to_string()) +except OSError as e: + print(f'Failed to save the modified config: {e}') + exit(1) diff --git a/src/migration-scripts/ipoe-server/0-to-1 b/src/migration-scripts/ipoe-server/0-to-1 deleted file mode 100755 index ac9d13abc..000000000 --- a/src/migration-scripts/ipoe-server/0-to-1 +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2022 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/>. - -# - T4703: merge vlan-id and vlan-range to vlan CLI node - -# L2|L3 -> l2|l3 -# mac-address -> mac -# network-mode -> mode - -import os -import sys - -from sys import argv, exit -from vyos.configtree import ConfigTree - -if len(argv) < 2: - print("Must specify file name!") - exit(1) - -file_name = argv[1] - -with open(file_name, 'r') as f: - config_file = f.read() - -config = ConfigTree(config_file) -base = ['service', 'ipoe-server'] -if not config.exists(base): - # Nothing to do - exit(0) - -if config.exists(base + ['authentication', 'interface']): - for interface in config.list_nodes(base + ['authentication', 'interface']): - config.rename(base + ['authentication', 'interface', interface, 'mac-address'], 'mac') - - mac_base = base + ['authentication', 'interface', interface, 'mac'] - for mac in config.list_nodes(mac_base): - vlan_config = mac_base + [mac, 'vlan-id'] - if config.exists(vlan_config): - config.rename(vlan_config, 'vlan') - -for interface in config.list_nodes(base + ['interface']): - base_path = base + ['interface', interface] - for vlan in ['vlan-id', 'vlan-range']: - if config.exists(base_path + [vlan]): - print(interface, vlan) - for tmp in config.return_values(base_path + [vlan]): - config.set(base_path + ['vlan'], value=tmp, replace=False) - config.delete(base_path + [vlan]) - - if config.exists(base_path + ['network-mode']): - tmp = config.return_value(base_path + ['network-mode']) - config.delete(base_path + ['network-mode']) - # Change L2|L3 to lower case l2|l3 - config.set(base_path + ['mode'], value=tmp.lower()) - -try: - with open(file_name, 'w') as f: - f.write(config.to_string()) -except OSError as e: - print("Failed to save the modified config: {}".format(e)) - exit(1) diff --git a/src/migration-scripts/ipoe-server/1-to-2 b/src/migration-scripts/ipoe-server/1-to-2 index 378702693..6a7111541 100755 --- a/src/migration-scripts/ipoe-server/1-to-2 +++ b/src/migration-scripts/ipoe-server/1-to-2 @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2023 VyOS maintainers and contributors +# Copyright (C) 2023-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 @@ -14,6 +14,11 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. +# - T4703: merge vlan-id and vlan-range to vlan CLI node +# L2|L3 -> l2|l3 +# mac-address -> mac +# network-mode -> mode + # - changed cli of all named pools # - moved gateway-address from pool to global configuration with / netmask # gateway can exist without pool if radius is used @@ -39,43 +44,67 @@ with open(file_name, 'r') as f: config = ConfigTree(config_file) base = ['service', 'ipoe-server'] -pool_base = base + ['client-ip-pool'] + if not config.exists(base): exit(0) -if not config.exists(pool_base): - exit(0) -default_pool = '' -gateway = '' - -#named pool migration -namedpools_base = pool_base + ['name'] - -for pool_name in config.list_nodes(namedpools_base): - pool_path = namedpools_base + [pool_name] - if config.exists(pool_path + ['subnet']): - subnet = config.return_value(pool_path + ['subnet']) - config.set(pool_base + [pool_name, 'range'], value=subnet, replace=False) - # Get netmask from subnet - mask = subnet.split("/")[1] - if config.exists(pool_path + ['next-pool']): - next_pool = config.return_value(pool_path + ['next-pool']) - config.set(pool_base + [pool_name, 'next-pool'], value=next_pool) - if not default_pool: - default_pool = pool_name - if config.exists(pool_path + ['gateway-address']) and mask: - gateway = f'{config.return_value(pool_path + ["gateway-address"])}/{mask}' - config.set(base + ['gateway-address'], value=gateway, replace=False) - -if not default_pool and config.list_nodes(namedpools_base): - default_pool = config.list_nodes(namedpools_base)[0] - -config.delete(namedpools_base) - -if default_pool: - config.set(base + ['default-pool'], value=default_pool) -# format as tag node -config.set_tag(pool_base) +if config.exists(base + ['authentication', 'interface']): + for interface in config.list_nodes(base + ['authentication', 'interface']): + config.rename(base + ['authentication', 'interface', interface, 'mac-address'], 'mac') + + mac_base = base + ['authentication', 'interface', interface, 'mac'] + for mac in config.list_nodes(mac_base): + vlan_config = mac_base + [mac, 'vlan-id'] + if config.exists(vlan_config): + config.rename(vlan_config, 'vlan') + +for interface in config.list_nodes(base + ['interface']): + base_path = base + ['interface', interface] + for vlan in ['vlan-id', 'vlan-range']: + if config.exists(base_path + [vlan]): + for tmp in config.return_values(base_path + [vlan]): + config.set(base_path + ['vlan'], value=tmp, replace=False) + config.delete(base_path + [vlan]) + + if config.exists(base_path + ['network-mode']): + tmp = config.return_value(base_path + ['network-mode']) + config.delete(base_path + ['network-mode']) + # Change L2|L3 to lower case l2|l3 + config.set(base_path + ['mode'], value=tmp.lower()) + +pool_base = base + ['client-ip-pool'] +if config.exists(pool_base): + default_pool = '' + gateway = '' + + #named pool migration + namedpools_base = pool_base + ['name'] + + for pool_name in config.list_nodes(namedpools_base): + pool_path = namedpools_base + [pool_name] + if config.exists(pool_path + ['subnet']): + subnet = config.return_value(pool_path + ['subnet']) + config.set(pool_base + [pool_name, 'range'], value=subnet, replace=False) + # Get netmask from subnet + mask = subnet.split("/")[1] + if config.exists(pool_path + ['next-pool']): + next_pool = config.return_value(pool_path + ['next-pool']) + config.set(pool_base + [pool_name, 'next-pool'], value=next_pool) + if not default_pool: + default_pool = pool_name + if config.exists(pool_path + ['gateway-address']) and mask: + gateway = f'{config.return_value(pool_path + ["gateway-address"])}/{mask}' + config.set(base + ['gateway-address'], value=gateway, replace=False) + + if not default_pool and config.list_nodes(namedpools_base): + default_pool = config.list_nodes(namedpools_base)[0] + + config.delete(namedpools_base) + + if default_pool: + config.set(base + ['default-pool'], value=default_pool) + # format as tag node + config.set_tag(pool_base) try: with open(file_name, 'w') as f: |