diff options
Diffstat (limited to 'src/migration-scripts/dhcp-server')
| -rw-r--r--[-rwxr-xr-x] | src/migration-scripts/dhcp-server/10-to-11 | 52 | ||||
| -rw-r--r--[-rwxr-xr-x] | src/migration-scripts/dhcp-server/4-to-5 | 202 | ||||
| -rw-r--r--[-rwxr-xr-x] | src/migration-scripts/dhcp-server/5-to-6 | 132 | ||||
| -rw-r--r--[-rwxr-xr-x] | src/migration-scripts/dhcp-server/6-to-7 | 94 | ||||
| -rw-r--r--[-rwxr-xr-x] | src/migration-scripts/dhcp-server/7-to-8 | 98 | ||||
| -rw-r--r--[-rwxr-xr-x] | src/migration-scripts/dhcp-server/8-to-9 | 82 | ||||
| -rw-r--r--[-rwxr-xr-x] | src/migration-scripts/dhcp-server/9-to-10 | 81 | 
7 files changed, 314 insertions, 427 deletions
| diff --git a/src/migration-scripts/dhcp-server/10-to-11 b/src/migration-scripts/dhcp-server/10-to-11 index a0dc96ad0..f54a4c7b7 100755..100644 --- a/src/migration-scripts/dhcp-server/10-to-11 +++ b/src/migration-scripts/dhcp-server/10-to-11 @@ -1,48 +1,28 @@ -#!/usr/bin/env python3 +# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>  # -# Copyright (C) 2024 VyOS maintainers and contributors +# 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 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, +# 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 General Public License for more details. +# 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 General Public License -# along with this program.  If not, see <http://www.gnu.org/licenses/>. +# You should have received a copy of the GNU Lesser General Public License +# along with this library.  If not, see <http://www.gnu.org/licenses/>.  # T6171: rename "service dhcp-server failover" to "service dhcp-server high-availability" -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 = ['service', 'dhcp-server'] -config = ConfigTree(config_file) - -if not config.exists(base): -    # Nothing to do -    exit(0) -if config.exists(base + ['failover']): -    config.rename(base + ['failover'],'high-availability') +def migrate(config: ConfigTree) -> None: +    if not config.exists(base): +        # Nothing to do +        return -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)
\ No newline at end of file +    if config.exists(base + ['failover']): +        config.rename(base + ['failover'],'high-availability') diff --git a/src/migration-scripts/dhcp-server/4-to-5 b/src/migration-scripts/dhcp-server/4-to-5 index d15e0baf5..a655515dc 100755..100644 --- a/src/migration-scripts/dhcp-server/4-to-5 +++ b/src/migration-scripts/dhcp-server/4-to-5 @@ -1,122 +1,118 @@  #!/usr/bin/env python3 +# Copyright 2018-2024 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, see <http://www.gnu.org/licenses/>. +  # Removes boolean operator from:  #   - "set service dhcp-server shared-network-name <xyz> subnet 172.31.0.0/24 ip-forwarding enable (true|false)"  #   - "set service dhcp-server shared-network-name <xyz> authoritative (true|false)"  #   - "set service dhcp-server disabled (true|false)" -import sys -  from vyos.configtree import ConfigTree -if len(sys.argv) < 2: -    print("Must specify file name!") -    sys.exit(1) - -file_name = sys.argv[1] - -with open(file_name, 'r') as f: -    config_file = f.read() - -config = ConfigTree(config_file) - -if not config.exists(['service', 'dhcp-server']): -    # Nothing to do -    sys.exit(0) -else: -    base = ['service', 'dhcp-server'] -    # Make node "set service dhcp-server dynamic-dns-update enable (true|false)" valueless -    if config.exists(base + ['dynamic-dns-update']): -        bool_val = config.return_value(base + ['dynamic-dns-update', 'enable']) - -        # Delete the node with the old syntax -        config.delete(base + ['dynamic-dns-update']) -        if str(bool_val) == 'true': -            # Enable dynamic-dns-update with new syntax -            config.set(base + ['dynamic-dns-update'], value=None) - -    # Make node "set service dhcp-server disabled (true|false)" valueless -    if config.exists(base + ['disabled']): -        bool_val = config.return_value(base + ['disabled']) - -        # Delete the node with the old syntax -        config.delete(base + ['disabled']) -        if str(bool_val) == 'true': -            # Now disable DHCP server with the new syntax -            config.set(base + ['disable'], value=None) - -    # Make node "set service dhcp-server hostfile-update (enable|disable) valueless -    if config.exists(base + ['hostfile-update']): -        bool_val = config.return_value(base + ['hostfile-update']) - -        # Delete the node with the old syntax incl. all subnodes -        config.delete(base + ['hostfile-update']) -        if str(bool_val) == 'enable': -            # Enable hostfile update with new syntax -            config.set(base + ['hostfile-update'], value=None) - -    # Run this for every instance if 'shared-network-name' -    for network in config.list_nodes(base + ['shared-network-name']): -        base_network = base + ['shared-network-name', network] -        # format as tag node to avoid loading problems -        config.set_tag(base + ['shared-network-name']) - -        # Run this for every specified 'subnet' -        for subnet in config.list_nodes(base_network + ['subnet']): -            base_subnet = base_network + ['subnet', subnet] +def migrate(config: ConfigTree) -> None: +    if not config.exists(['service', 'dhcp-server']): +        # Nothing to do +        return +    else: +        base = ['service', 'dhcp-server'] +        # Make node "set service dhcp-server dynamic-dns-update enable (true|false)" valueless +        if config.exists(base + ['dynamic-dns-update']): +            bool_val = config.return_value(base + ['dynamic-dns-update', 'enable']) + +            # Delete the node with the old syntax +            config.delete(base + ['dynamic-dns-update']) +            if str(bool_val) == 'true': +                # Enable dynamic-dns-update with new syntax +                config.set(base + ['dynamic-dns-update'], value=None) + +        # Make node "set service dhcp-server disabled (true|false)" valueless +        if config.exists(base + ['disabled']): +            bool_val = config.return_value(base + ['disabled']) + +            # Delete the node with the old syntax +            config.delete(base + ['disabled']) +            if str(bool_val) == 'true': +                # Now disable DHCP server with the new syntax +                config.set(base + ['disable'], value=None) + +        # Make node "set service dhcp-server hostfile-update (enable|disable) valueless +        if config.exists(base + ['hostfile-update']): +            bool_val = config.return_value(base + ['hostfile-update']) + +            # Delete the node with the old syntax incl. all subnodes +            config.delete(base + ['hostfile-update']) +            if str(bool_val) == 'enable': +                # Enable hostfile update with new syntax +                config.set(base + ['hostfile-update'], value=None) + +        # Run this for every instance if 'shared-network-name' +        for network in config.list_nodes(base + ['shared-network-name']): +            base_network = base + ['shared-network-name', network]              # format as tag node to avoid loading problems -            config.set_tag(base_network + ['subnet']) +            config.set_tag(base + ['shared-network-name']) -            # Make node "set service dhcp-server shared-network-name <xyz> subnet 172.31.0.0/24 ip-forwarding enable" valueless -            if config.exists(base_subnet + ['ip-forwarding', 'enable']): -                bool_val = config.return_value(base_subnet + ['ip-forwarding', 'enable']) -                # Delete the node with the old syntax -                config.delete(base_subnet + ['ip-forwarding']) -                if str(bool_val) == 'true': -                    # Recreate node with new syntax -                    config.set(base_subnet + ['ip-forwarding'], value=None) - -            # Rename node "set service dhcp-server shared-network-name <xyz> subnet 172.31.0.0/24 start <172.16.0.4> stop <172.16.0.9> -            if config.exists(base_subnet + ['start']): -                # This is the new "range" id for DHCP lease ranges -                r_id = 0 -                for range in config.list_nodes(base_subnet + ['start']): -                    range_start = range -                    range_stop = config.return_value(base_subnet + ['start', range_start, 'stop']) +            # Run this for every specified 'subnet' +            for subnet in config.list_nodes(base_network + ['subnet']): +                base_subnet = base_network + ['subnet', subnet] +                # format as tag node to avoid loading problems +                config.set_tag(base_network + ['subnet']) +                # Make node "set service dhcp-server shared-network-name <xyz> subnet 172.31.0.0/24 ip-forwarding enable" valueless +                if config.exists(base_subnet + ['ip-forwarding', 'enable']): +                    bool_val = config.return_value(base_subnet + ['ip-forwarding', 'enable'])                      # Delete the node with the old syntax -                    config.delete(base_subnet + ['start', range_start]) +                    config.delete(base_subnet + ['ip-forwarding']) +                    if str(bool_val) == 'true': +                        # Recreate node with new syntax +                        config.set(base_subnet + ['ip-forwarding'], value=None) + +                # Rename node "set service dhcp-server shared-network-name <xyz> subnet 172.31.0.0/24 start <172.16.0.4> stop <172.16.0.9> +                if config.exists(base_subnet + ['start']): +                    # This is the new "range" id for DHCP lease ranges +                    r_id = 0 +                    for range in config.list_nodes(base_subnet + ['start']): +                        range_start = range +                        range_stop = config.return_value(base_subnet + ['start', range_start, 'stop']) + +                        # Delete the node with the old syntax +                        config.delete(base_subnet + ['start', range_start]) + +                        # Create the node for the new syntax +                        # Note: range is a tag node, counter is its child, not a value +                        config.set(base_subnet + ['range', r_id]) +                        config.set(base_subnet + ['range', r_id, 'start'], value=range_start) +                        config.set(base_subnet + ['range', r_id, 'stop'], value=range_stop) + +                        # format as tag node to avoid loading problems +                        config.set_tag(base_subnet + ['range']) + +                        # increment range id for possible next range definition +                        r_id += 1 -                    # Create the node for the new syntax -                    # Note: range is a tag node, counter is its child, not a value -                    config.set(base_subnet + ['range', r_id]) -                    config.set(base_subnet + ['range', r_id, 'start'], value=range_start) -                    config.set(base_subnet + ['range', r_id, 'stop'], value=range_stop) +                    # Delete the node with the old syntax +                    config.delete(['service', 'dhcp-server', 'shared-network-name', network, 'subnet', subnet, 'start']) -                    # format as tag node to avoid loading problems -                    config.set_tag(base_subnet + ['range']) -                    # increment range id for possible next range definition -                    r_id += 1 +            # Make node "set service dhcp-server shared-network-name <xyz> authoritative" valueless +            if config.exists(['service', 'dhcp-server', 'shared-network-name', network, 'authoritative']): +                authoritative = config.return_value(['service', 'dhcp-server', 'shared-network-name', network, 'authoritative'])                  # Delete the node with the old syntax -                config.delete(['service', 'dhcp-server', 'shared-network-name', network, 'subnet', subnet, 'start']) +                config.delete(['service', 'dhcp-server', 'shared-network-name', network, 'authoritative']) - -        # Make node "set service dhcp-server shared-network-name <xyz> authoritative" valueless -        if config.exists(['service', 'dhcp-server', 'shared-network-name', network, 'authoritative']): -            authoritative = config.return_value(['service', 'dhcp-server', 'shared-network-name', network, 'authoritative']) - -            # Delete the node with the old syntax -            config.delete(['service', 'dhcp-server', 'shared-network-name', network, 'authoritative']) - -            # Recreate node with new syntax - if required -            if authoritative == "enable": -                config.set(['service', 'dhcp-server', 'shared-network-name', network, 'authoritative']) - -    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)) -        sys.exit(1) +                # Recreate node with new syntax - if required +                if authoritative == "enable": +                    config.set(['service', 'dhcp-server', 'shared-network-name', network, 'authoritative']) diff --git a/src/migration-scripts/dhcp-server/5-to-6 b/src/migration-scripts/dhcp-server/5-to-6 index f5c766a09..9404cd038 100755..100644 --- a/src/migration-scripts/dhcp-server/5-to-6 +++ b/src/migration-scripts/dhcp-server/5-to-6 @@ -1,87 +1,69 @@ -#!/usr/bin/env python3 +# Copyright 2021-2024 VyOS maintainers and contributors <maintainers@vyos.io>  # -# Copyright (C) 2021 VyOS maintainers and contributors +# 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 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, +# 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 General Public License for more details. +# 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 General Public License -# along with this program.  If not, see <http://www.gnu.org/licenses/>. +# You should have received a copy of the GNU Lesser General Public License +# along with this library.  If not, see <http://www.gnu.org/licenses/>.  # T1968: allow multiple static-routes to be configured  # T3838: rename dns-server -> name-server -import sys  from vyos.configtree import ConfigTree -if len(sys.argv) < 2: -    print("Must specify file name!") -    sys.exit(1) - -file_name = sys.argv[1] - -with open(file_name, 'r') as f: -    config_file = f.read() -  base = ['service', 'dhcp-server'] -config = ConfigTree(config_file) - -if not config.exists(base + ['shared-network-name']): -    # Nothing to do -    exit(0) - -# Run this for every instance if 'shared-network-name' -for network in config.list_nodes(base + ['shared-network-name']): -    base_network = base + ['shared-network-name', network] - -    if not config.exists(base_network + ['subnet']): -        continue - -    # Run this for every specified 'subnet' -    for subnet in config.list_nodes(base_network + ['subnet']): -        base_subnet = base_network + ['subnet', subnet] - -        # T1968: allow multiple static-routes to be configured -        if config.exists(base_subnet + ['static-route']): -            prefix = config.return_value(base_subnet + ['static-route', 'destination-subnet']) -            router = config.return_value(base_subnet + ['static-route', 'router']) -            config.delete(base_subnet + ['static-route']) - -            config.set(base_subnet + ['static-route', prefix, 'next-hop'], value=router) -            config.set_tag(base_subnet + ['static-route']) - -        # T3838: rename dns-server -> name-server -        if config.exists(base_subnet + ['dns-server']): -            config.rename(base_subnet + ['dns-server'], 'name-server') - - -        # T3672: ISC DHCP server only supports one failover peer -        if config.exists(base_subnet + ['failover']): -            # There can only be one failover configuration, if none is present -            # we add the first one -            if not config.exists(base + ['failover']): -                local = config.return_value(base_subnet + ['failover', 'local-address']) -                remote = config.return_value(base_subnet + ['failover', 'peer-address']) -                status = config.return_value(base_subnet + ['failover', 'status']) -                name = config.return_value(base_subnet + ['failover', 'name']) - -                config.set(base + ['failover', 'remote'], value=remote) -                config.set(base + ['failover', 'source-address'], value=local) -                config.set(base + ['failover', 'status'], value=status) -                config.set(base + ['failover', 'name'], value=name) - -            config.delete(base_subnet + ['failover']) -            config.set(base_subnet + ['enable-failover']) -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) +def migrate(config: ConfigTree) -> None: +    if not config.exists(base + ['shared-network-name']): +        # Nothing to do +        return + +    # Run this for every instance if 'shared-network-name' +    for network in config.list_nodes(base + ['shared-network-name']): +        base_network = base + ['shared-network-name', network] + +        if not config.exists(base_network + ['subnet']): +            continue + +        # Run this for every specified 'subnet' +        for subnet in config.list_nodes(base_network + ['subnet']): +            base_subnet = base_network + ['subnet', subnet] + +            # T1968: allow multiple static-routes to be configured +            if config.exists(base_subnet + ['static-route']): +                prefix = config.return_value(base_subnet + ['static-route', 'destination-subnet']) +                router = config.return_value(base_subnet + ['static-route', 'router']) +                config.delete(base_subnet + ['static-route']) + +                config.set(base_subnet + ['static-route', prefix, 'next-hop'], value=router) +                config.set_tag(base_subnet + ['static-route']) + +            # T3838: rename dns-server -> name-server +            if config.exists(base_subnet + ['dns-server']): +                config.rename(base_subnet + ['dns-server'], 'name-server') + + +            # T3672: ISC DHCP server only supports one failover peer +            if config.exists(base_subnet + ['failover']): +                # There can only be one failover configuration, if none is present +                # we add the first one +                if not config.exists(base + ['failover']): +                    local = config.return_value(base_subnet + ['failover', 'local-address']) +                    remote = config.return_value(base_subnet + ['failover', 'peer-address']) +                    status = config.return_value(base_subnet + ['failover', 'status']) +                    name = config.return_value(base_subnet + ['failover', 'name']) + +                    config.set(base + ['failover', 'remote'], value=remote) +                    config.set(base + ['failover', 'source-address'], value=local) +                    config.set(base + ['failover', 'status'], value=status) +                    config.set(base + ['failover', 'name'], value=name) + +                config.delete(base_subnet + ['failover']) +                config.set(base_subnet + ['enable-failover']) diff --git a/src/migration-scripts/dhcp-server/6-to-7 b/src/migration-scripts/dhcp-server/6-to-7 index e6c298a60..4e6583a31 100755..100644 --- a/src/migration-scripts/dhcp-server/6-to-7 +++ b/src/migration-scripts/dhcp-server/6-to-7 @@ -1,76 +1,58 @@ -#!/usr/bin/env python3 +# Copyright 2022-2024 VyOS maintainers and contributors <maintainers@vyos.io>  # -# Copyright (C) 2024 VyOS maintainers and contributors +# 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 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, +# 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 General Public License for more details. +# 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 General Public License -# along with this program.  If not, see <http://www.gnu.org/licenses/>. +# You should have received a copy of the GNU Lesser General Public License +# along with this library.  If not, see <http://www.gnu.org/licenses/>.  # T6079: Disable duplicate static mappings -import sys  from vyos.configtree import ConfigTree -if len(sys.argv) < 2: -    print("Must specify file name!") -    sys.exit(1) - -file_name = sys.argv[1] - -with open(file_name, 'r') as f: -    config_file = f.read() -  base = ['service', 'dhcp-server'] -config = ConfigTree(config_file) - -if not config.exists(base + ['shared-network-name']): -    # Nothing to do -    exit(0) -# Run this for every instance if 'shared-network-name' -for network in config.list_nodes(base + ['shared-network-name']): -    base_network = base + ['shared-network-name', network] +def migrate(config: ConfigTree) -> None: +    if not config.exists(base + ['shared-network-name']): +        # Nothing to do +        return -    if not config.exists(base_network + ['subnet']): -        continue +    # Run this for every instance if 'shared-network-name' +    for network in config.list_nodes(base + ['shared-network-name']): +        base_network = base + ['shared-network-name', network] -    for subnet in config.list_nodes(base_network + ['subnet']): -        base_subnet = base_network + ['subnet', subnet] +        if not config.exists(base_network + ['subnet']): +            continue -        if config.exists(base_subnet + ['static-mapping']): -            used_mac = [] -            used_ip = [] +        for subnet in config.list_nodes(base_network + ['subnet']): +            base_subnet = base_network + ['subnet', subnet] -            for mapping in config.list_nodes(base_subnet + ['static-mapping']): -                base_mapping = base_subnet + ['static-mapping', mapping] +            if config.exists(base_subnet + ['static-mapping']): +                used_mac = [] +                used_ip = [] -                if config.exists(base_mapping + ['mac-address']): -                    mac = config.return_value(base_mapping + ['mac-address']) +                for mapping in config.list_nodes(base_subnet + ['static-mapping']): +                    base_mapping = base_subnet + ['static-mapping', mapping] -                    if mac in used_mac: -                        config.set(base_mapping + ['disable']) -                    else: -                        used_mac.append(mac) +                    if config.exists(base_mapping + ['mac-address']): +                        mac = config.return_value(base_mapping + ['mac-address']) -                if config.exists(base_mapping + ['ip-address']): -                    ip = config.return_value(base_mapping + ['ip-address']) +                        if mac in used_mac: +                            config.set(base_mapping + ['disable']) +                        else: +                            used_mac.append(mac) -                    if ip in used_ip: -                        config.set(base_subnet + ['static-mapping', mapping, 'disable']) -                    else: -                        used_ip.append(ip) +                    if config.exists(base_mapping + ['ip-address']): +                        ip = config.return_value(base_mapping + ['ip-address']) -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) +                        if ip in used_ip: +                            config.set(base_subnet + ['static-mapping', mapping, 'disable']) +                        else: +                            used_ip.append(ip) diff --git a/src/migration-scripts/dhcp-server/7-to-8 b/src/migration-scripts/dhcp-server/7-to-8 index ccf385a30..7fcb62e86 100755..100644 --- a/src/migration-scripts/dhcp-server/7-to-8 +++ b/src/migration-scripts/dhcp-server/7-to-8 @@ -1,18 +1,17 @@ -#!/usr/bin/env python3 +# Copyright 2023-2024 VyOS maintainers and contributors <maintainers@vyos.io>  # -# Copyright (C) 2023 VyOS maintainers and contributors +# 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 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, +# 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 General Public License for more details. +# 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 General Public License -# along with this program.  If not, see <http://www.gnu.org/licenses/>. +# You should have received a copy of the GNU Lesser General Public License +# along with this library.  If not, see <http://www.gnu.org/licenses/>.  # T3316: Migrate to Kea  #        - global-parameters will not function @@ -23,65 +22,48 @@  #        - ping-check no longer supported  #        - failover is default enabled on all subnets that exist on failover servers -import sys  from vyos.configtree import ConfigTree -if (len(sys.argv) < 2): -    print("Must specify file name!") -    sys.exit(1) - -file_name = sys.argv[1] - -with open(file_name, 'r') as f: -    config_file = f.read() -  base = ['service', 'dhcp-server'] -config = ConfigTree(config_file) - -if not config.exists(base): -    # Nothing to do -    sys.exit(0) -if config.exists(base + ['host-decl-name']): -    config.delete(base + ['host-decl-name']) +def migrate(config: ConfigTree) -> None: +    if not config.exists(base): +        # Nothing to do +        return -if config.exists(base + ['global-parameters']): -    config.delete(base + ['global-parameters']) +    if config.exists(base + ['host-decl-name']): +        config.delete(base + ['host-decl-name']) -if config.exists(base + ['shared-network-name']): -    for network in config.list_nodes(base + ['shared-network-name']): -        base_network = base + ['shared-network-name', network] +    if config.exists(base + ['global-parameters']): +        config.delete(base + ['global-parameters']) -        if config.exists(base_network + ['ping-check']): -            config.delete(base_network + ['ping-check']) +    if config.exists(base + ['shared-network-name']): +        for network in config.list_nodes(base + ['shared-network-name']): +            base_network = base + ['shared-network-name', network] -        if config.exists(base_network + ['shared-network-parameters']): -            config.delete(base_network +['shared-network-parameters']) +            if config.exists(base_network + ['ping-check']): +                config.delete(base_network + ['ping-check']) -        if not config.exists(base_network + ['subnet']): -            continue +            if config.exists(base_network + ['shared-network-parameters']): +                config.delete(base_network +['shared-network-parameters']) -        # Run this for every specified 'subnet' -        for subnet in config.list_nodes(base_network + ['subnet']): -            base_subnet = base_network + ['subnet', subnet] +            if not config.exists(base_network + ['subnet']): +                continue -            if config.exists(base_subnet + ['enable-failover']): -                config.delete(base_subnet + ['enable-failover']) +            # Run this for every specified 'subnet' +            for subnet in config.list_nodes(base_network + ['subnet']): +                base_subnet = base_network + ['subnet', subnet] -            if config.exists(base_subnet + ['ping-check']): -                config.delete(base_subnet + ['ping-check']) +                if config.exists(base_subnet + ['enable-failover']): +                    config.delete(base_subnet + ['enable-failover']) -            if config.exists(base_subnet + ['subnet-parameters']): -                config.delete(base_subnet + ['subnet-parameters']) +                if config.exists(base_subnet + ['ping-check']): +                    config.delete(base_subnet + ['ping-check']) -            if config.exists(base_subnet + ['static-mapping']): -                for mapping in config.list_nodes(base_subnet + ['static-mapping']): -                    if config.exists(base_subnet + ['static-mapping', mapping, 'static-mapping-parameters']): -                        config.delete(base_subnet + ['static-mapping', mapping, 'static-mapping-parameters']) +                if config.exists(base_subnet + ['subnet-parameters']): +                    config.delete(base_subnet + ['subnet-parameters']) -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) +                if config.exists(base_subnet + ['static-mapping']): +                    for mapping in config.list_nodes(base_subnet + ['static-mapping']): +                        if config.exists(base_subnet + ['static-mapping', mapping, 'static-mapping-parameters']): +                            config.delete(base_subnet + ['static-mapping', mapping, 'static-mapping-parameters']) diff --git a/src/migration-scripts/dhcp-server/8-to-9 b/src/migration-scripts/dhcp-server/8-to-9 index 151aa6d7b..5843e9fda 100755..100644 --- a/src/migration-scripts/dhcp-server/8-to-9 +++ b/src/migration-scripts/dhcp-server/8-to-9 @@ -1,65 +1,47 @@ -#!/usr/bin/env python3 +# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>  # -# Copyright (C) 2023 VyOS maintainers and contributors +# 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 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, +# 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 General Public License for more details. +# 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 General Public License -# along with this program.  If not, see <http://www.gnu.org/licenses/>. +# You should have received a copy of the GNU Lesser General Public License +# along with this library.  If not, see <http://www.gnu.org/licenses/>.  # T3316:  # - Adjust hostname to have valid FQDN characters only (underscores aren't allowed anymore)  # - Rename "service dhcp-server shared-network-name ... static-mapping <hostname> mac-address ..."  #       to "service dhcp-server shared-network-name ... static-mapping <hostname> mac ..." -import sys  import re  from vyos.configtree import ConfigTree -if len(sys.argv) < 2: -    print("Must specify file name!") -    sys.exit(1) - -file_name = sys.argv[1] - -with open(file_name, 'r') as f: -    config_file = f.read() -  base = ['service', 'dhcp-server', 'shared-network-name'] -config = ConfigTree(config_file) - -if not config.exists(base): -    # Nothing to do -    sys.exit(0) - -for network in config.list_nodes(base): -    # Run this for every specified 'subnet' -    if config.exists(base + [network, 'subnet']): -        for subnet in config.list_nodes(base + [network, 'subnet']): -            base_subnet = base + [network, 'subnet', subnet] -            if config.exists(base_subnet + ['static-mapping']): -                for hostname in config.list_nodes(base_subnet + ['static-mapping']): -                    base_mapping = base_subnet + ['static-mapping', hostname] - -                    # Rename the 'mac-address' node to 'mac' -                    if config.exists(base_mapping + ['mac-address']): -                        config.rename(base_mapping + ['mac-address'], 'mac') - -                    # Adjust hostname to have valid FQDN characters only -                    new_hostname = re.sub(r'[^a-zA-Z0-9-.]', '-', hostname) -                    if new_hostname != hostname: -                        config.rename(base_mapping, new_hostname) -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) +def migrate(config: ConfigTree) -> None: +    if not config.exists(base): +        # Nothing to do +        return + +    for network in config.list_nodes(base): +        # Run this for every specified 'subnet' +        if config.exists(base + [network, 'subnet']): +            for subnet in config.list_nodes(base + [network, 'subnet']): +                base_subnet = base + [network, 'subnet', subnet] +                if config.exists(base_subnet + ['static-mapping']): +                    for hostname in config.list_nodes(base_subnet + ['static-mapping']): +                        base_mapping = base_subnet + ['static-mapping', hostname] + +                        # Rename the 'mac-address' node to 'mac' +                        if config.exists(base_mapping + ['mac-address']): +                            config.rename(base_mapping + ['mac-address'], 'mac') + +                        # Adjust hostname to have valid FQDN characters only +                        new_hostname = re.sub(r'[^a-zA-Z0-9-.]', '-', hostname) +                        if new_hostname != hostname: +                            config.rename(base_mapping, new_hostname) diff --git a/src/migration-scripts/dhcp-server/9-to-10 b/src/migration-scripts/dhcp-server/9-to-10 index a459b65b5..eda97550d 100755..100644 --- a/src/migration-scripts/dhcp-server/9-to-10 +++ b/src/migration-scripts/dhcp-server/9-to-10 @@ -1,41 +1,25 @@ -#!/usr/bin/env python3 +# Copyright 2024 VyOS maintainers and contributors <maintainers@vyos.io>  # -# Copyright (C) 2024 VyOS maintainers and contributors +# 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 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, +# 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 General Public License for more details. +# 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 General Public License -# along with this program.  If not, see <http://www.gnu.org/licenses/>. +# You should have received a copy of the GNU Lesser General Public License +# along with this library.  If not, see <http://www.gnu.org/licenses/>.  # T3316:  # - Migrate dhcp options under new option node  # - Add subnet IDs to existing subnets -import sys  from vyos.configtree import ConfigTree -if len(sys.argv) < 2: -    print("Must specify file name!") -    sys.exit(1) - -file_name = sys.argv[1] - -with open(file_name, 'r') as f: -    config_file = f.read() -  base = ['service', 'dhcp-server', 'shared-network-name'] -config = ConfigTree(config_file) - -if not config.exists(base): -    # Nothing to do -    sys.exit(0)  option_nodes = ['bootfile-name', 'bootfile-server', 'bootfile-size', 'captive-portal',                  'client-prefix-length', 'default-router', 'domain-name', 'domain-search', @@ -44,31 +28,30 @@ option_nodes = ['bootfile-name', 'bootfile-server', 'bootfile-size', 'captive-po                  'tftp-server-name', 'time-offset', 'time-server', 'time-zone',                  'vendor-option', 'wins-server', 'wpad-url'] -subnet_id = 1 -for network in config.list_nodes(base): -    for option in option_nodes: -        if config.exists(base + [network, option]): -            config.set(base + [network, 'option']) -            config.copy(base + [network, option], base + [network, 'option', option]) -            config.delete(base + [network, option]) +def migrate(config: ConfigTree) -> None: +    if not config.exists(base): +        # Nothing to do +        return + +    subnet_id = 1 -    if config.exists(base + [network, 'subnet']): -        for subnet in config.list_nodes(base + [network, 'subnet']): -            base_subnet = base + [network, 'subnet', subnet] +    for network in config.list_nodes(base): +        for option in option_nodes: +            if config.exists(base + [network, option]): +                config.set(base + [network, 'option']) +                config.copy(base + [network, option], base + [network, 'option', option]) +                config.delete(base + [network, option]) -            for option in option_nodes: -                if config.exists(base_subnet + [option]): -                    config.set(base_subnet + ['option']) -                    config.copy(base_subnet + [option], base_subnet + ['option', option]) -                    config.delete(base_subnet + [option]) +        if config.exists(base + [network, 'subnet']): +            for subnet in config.list_nodes(base + [network, 'subnet']): +                base_subnet = base + [network, 'subnet', subnet] -            config.set(base_subnet + ['subnet-id'], value=subnet_id) -            subnet_id += 1 +                for option in option_nodes: +                    if config.exists(base_subnet + [option]): +                        config.set(base_subnet + ['option']) +                        config.copy(base_subnet + [option], base_subnet + ['option', option]) +                        config.delete(base_subnet + [option]) -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) +                config.set(base_subnet + ['subnet-id'], value=subnet_id) +                subnet_id += 1 | 
