summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/completion/list_dumpable_interfaces.py2
-rwxr-xr-xsrc/completion/list_ipoe.py16
-rw-r--r--src/completion/list_ipsec_profile_tunnels.py2
-rwxr-xr-xsrc/completion/list_openconnect_users.py2
-rwxr-xr-xsrc/completion/list_openvpn_users.py2
-rwxr-xr-xsrc/conf_mode/arp.py2
-rwxr-xr-xsrc/conf_mode/bcast_relay.py2
-rwxr-xr-xsrc/conf_mode/conntrack.py10
-rwxr-xr-xsrc/conf_mode/conntrack_sync.py10
-rwxr-xr-xsrc/conf_mode/container.py10
-rwxr-xr-xsrc/conf_mode/dhcp_relay.py10
-rwxr-xr-xsrc/conf_mode/dhcp_server.py6
-rwxr-xr-xsrc/conf_mode/dhcpv6_relay.py13
-rwxr-xr-xsrc/conf_mode/dhcpv6_server.py4
-rwxr-xr-xsrc/conf_mode/dns_dynamic.py2
-rwxr-xr-xsrc/conf_mode/dns_forwarding.py6
-rwxr-xr-xsrc/conf_mode/firewall.py12
-rwxr-xr-xsrc/conf_mode/flow_accounting_conf.py4
-rwxr-xr-xsrc/conf_mode/high-availability.py9
-rwxr-xr-xsrc/conf_mode/host_name.py9
-rwxr-xr-xsrc/conf_mode/http-api.py4
-rwxr-xr-xsrc/conf_mode/https.py8
-rwxr-xr-xsrc/conf_mode/igmp_proxy.py4
-rwxr-xr-xsrc/conf_mode/intel_qat.py5
-rwxr-xr-xsrc/conf_mode/interfaces-bonding.py2
-rwxr-xr-xsrc/conf_mode/interfaces-bridge.py4
-rwxr-xr-xsrc/conf_mode/interfaces-ethernet.py6
-rwxr-xr-xsrc/conf_mode/interfaces-l2tpv3.py2
-rwxr-xr-xsrc/conf_mode/interfaces-macsec.py6
-rwxr-xr-xsrc/conf_mode/interfaces-openvpn.py18
-rwxr-xr-xsrc/conf_mode/interfaces-pppoe.py4
-rwxr-xr-xsrc/conf_mode/interfaces-sstpc.py8
-rwxr-xr-xsrc/conf_mode/interfaces-tunnel.py4
-rwxr-xr-xsrc/conf_mode/interfaces-vti.py2
-rwxr-xr-xsrc/conf_mode/interfaces-wireguard.py4
-rwxr-xr-xsrc/conf_mode/interfaces-wireless.py4
-rwxr-xr-xsrc/conf_mode/interfaces-wwan.py12
-rwxr-xr-xsrc/conf_mode/le_cert.py6
-rwxr-xr-xsrc/conf_mode/lldp.py4
-rwxr-xr-xsrc/conf_mode/load-balancing-haproxy.py6
-rwxr-xr-xsrc/conf_mode/load-balancing-wan.py2
-rwxr-xr-xsrc/conf_mode/nat.py15
-rwxr-xr-xsrc/conf_mode/nat66.py6
-rwxr-xr-xsrc/conf_mode/netns.py6
-rwxr-xr-xsrc/conf_mode/ntp.py6
-rwxr-xr-xsrc/conf_mode/pki.py4
-rwxr-xr-xsrc/conf_mode/policy-local-route.py2
-rwxr-xr-xsrc/conf_mode/policy-route.py8
-rwxr-xr-xsrc/conf_mode/policy.py2
-rwxr-xr-xsrc/conf_mode/protocols_babel.py2
-rwxr-xr-xsrc/conf_mode/protocols_bgp.py41
-rwxr-xr-xsrc/conf_mode/protocols_failover.py2
-rwxr-xr-xsrc/conf_mode/protocols_igmp.py5
-rwxr-xr-xsrc/conf_mode/protocols_isis.py4
-rwxr-xr-xsrc/conf_mode/protocols_mpls.py6
-rwxr-xr-xsrc/conf_mode/protocols_nhrp.py6
-rwxr-xr-xsrc/conf_mode/protocols_ospf.py6
-rwxr-xr-xsrc/conf_mode/protocols_ospfv3.py6
-rwxr-xr-xsrc/conf_mode/protocols_pim.py5
-rwxr-xr-xsrc/conf_mode/protocols_rip.py2
-rwxr-xr-xsrc/conf_mode/protocols_ripng.py2
-rwxr-xr-xsrc/conf_mode/protocols_rpki.py2
-rwxr-xr-xsrc/conf_mode/protocols_static.py2
-rwxr-xr-xsrc/conf_mode/protocols_static_multicast.py2
-rwxr-xr-xsrc/conf_mode/qos.py4
-rwxr-xr-xsrc/conf_mode/salt-minion.py4
-rwxr-xr-xsrc/conf_mode/service_config_sync.py111
-rwxr-xr-xsrc/conf_mode/service_console-server.py2
-rwxr-xr-xsrc/conf_mode/service_event_handler.py3
-rwxr-xr-xsrc/conf_mode/service_ids_fastnetmon.py2
-rwxr-xr-xsrc/conf_mode/service_ipoe-server.py4
-rwxr-xr-xsrc/conf_mode/service_mdns-repeater.py2
-rwxr-xr-xsrc/conf_mode/service_monitoring_telegraf.py6
-rwxr-xr-xsrc/conf_mode/service_pppoe-server.py4
-rwxr-xr-xsrc/conf_mode/service_router-advert.py2
-rwxr-xr-xsrc/conf_mode/service_sla.py2
-rwxr-xr-xsrc/conf_mode/service_upnp.py2
-rwxr-xr-xsrc/conf_mode/service_webproxy.py8
-rwxr-xr-xsrc/conf_mode/snmp.py14
-rwxr-xr-xsrc/conf_mode/ssh.py2
-rwxr-xr-xsrc/conf_mode/system-ip.py8
-rwxr-xr-xsrc/conf_mode/system-ipv6.py6
-rwxr-xr-xsrc/conf_mode/system-login-banner.py2
-rwxr-xr-xsrc/conf_mode/system-login.py14
-rwxr-xr-xsrc/conf_mode/system-logs.py2
-rwxr-xr-xsrc/conf_mode/system-option.py4
-rwxr-xr-xsrc/conf_mode/system-syslog.py44
-rwxr-xr-xsrc/conf_mode/system-timezone.py2
-rwxr-xr-xsrc/conf_mode/system_console.py8
-rwxr-xr-xsrc/conf_mode/system_frr.py6
-rwxr-xr-xsrc/conf_mode/system_lcd.py4
-rwxr-xr-xsrc/conf_mode/system_sflow.py2
-rwxr-xr-xsrc/conf_mode/system_sysctl.py2
-rwxr-xr-xsrc/conf_mode/system_update_check.py2
-rwxr-xr-xsrc/conf_mode/tftp_server.py4
-rwxr-xr-xsrc/conf_mode/vpn_ipsec.py8
-rwxr-xr-xsrc/conf_mode/vpn_l2tp.py8
-rwxr-xr-xsrc/conf_mode/vpn_openconnect.py10
-rwxr-xr-xsrc/conf_mode/vpn_pptp.py3
-rwxr-xr-xsrc/conf_mode/vpn_sstp.py10
-rwxr-xr-xsrc/conf_mode/vpp.py54
-rwxr-xr-xsrc/conf_mode/vrf.py14
-rw-r--r--src/conf_mode/vrf_vni.py2
-rwxr-xr-xsrc/etc/dhcp/dhclient-exit-hooks.d/99-ipsec-dhclient-hook16
-rwxr-xr-xsrc/etc/ipsec.d/vti-up-down6
-rwxr-xr-xsrc/etc/opennhrp/opennhrp-script.py4
-rwxr-xr-xsrc/etc/systemd/system-generators/vyos-generator94
-rw-r--r--src/etc/systemd/system/getty@.service.d/aftervyos.conf3
-rw-r--r--src/etc/systemd/system/serial-getty@.service.d/aftervyos.conf3
-rwxr-xr-xsrc/etc/telegraf/custom_scripts/show_firewall_input_filter.py2
-rwxr-xr-xsrc/etc/telegraf/custom_scripts/vyos_services_input_filter.py5
-rwxr-xr-xsrc/etc/vmware-tools/scripts/resume-vm-default.d/ether-resume.py6
-rwxr-xr-xsrc/helpers/run-config-migration.py2
-rwxr-xr-xsrc/helpers/vyos-boot-config-loader.py2
-rwxr-xr-xsrc/helpers/vyos-check-wwan.py2
-rwxr-xr-xsrc/helpers/vyos-domain-resolver.py10
-rwxr-xr-xsrc/helpers/vyos-failover.py2
-rwxr-xr-xsrc/helpers/vyos-interface-rescan.py2
-rwxr-xr-xsrc/helpers/vyos-merge-config.py7
-rwxr-xr-xsrc/helpers/vyos-sudo.py2
-rwxr-xr-xsrc/helpers/vyos_config_sync.py192
-rwxr-xr-xsrc/helpers/vyos_net_name7
-rwxr-xr-xsrc/init/vyos-config16
-rwxr-xr-xsrc/init/vyos-router421
-rwxr-xr-xsrc/migration-scripts/container/0-to-110
-rwxr-xr-xsrc/migration-scripts/interfaces/24-to-2511
-rwxr-xr-xsrc/migration-scripts/interfaces/7-to-85
-rwxr-xr-xsrc/migration-scripts/ipsec/6-to-78
-rwxr-xr-xsrc/migration-scripts/l2tp/3-to-46
-rwxr-xr-xsrc/migration-scripts/openconnect/0-to-16
-rwxr-xr-xsrc/migration-scripts/policy/3-to-48
-rwxr-xr-xsrc/migration-scripts/qos/1-to-22
-rwxr-xr-xsrc/migration-scripts/sstp/3-to-46
-rwxr-xr-xsrc/migration-scripts/system/13-to-142
-rwxr-xr-xsrc/migration-scripts/vrrp/3-to-451
-rwxr-xr-xsrc/op_mode/accelppp.py2
-rwxr-xr-xsrc/op_mode/bgp.py6
-rwxr-xr-xsrc/op_mode/bridge.py39
-rwxr-xr-xsrc/op_mode/clear_conntrack.py5
-rwxr-xr-xsrc/op_mode/clear_dhcp_lease.py6
-rwxr-xr-xsrc/op_mode/connect_disconnect.py10
-rwxr-xr-xsrc/op_mode/conntrack.py6
-rwxr-xr-xsrc/op_mode/conntrack_sync.py8
-rwxr-xr-xsrc/op_mode/container.py8
-rwxr-xr-xsrc/op_mode/dhcp.py6
-rwxr-xr-xsrc/op_mode/dns.py2
-rwxr-xr-xsrc/op_mode/dns_dynamic.py2
-rwxr-xr-xsrc/op_mode/dns_forwarding_reset.py2
-rwxr-xr-xsrc/op_mode/dns_forwarding_statistics.py2
-rwxr-xr-xsrc/op_mode/firewall.py4
-rwxr-xr-xsrc/op_mode/flow_accounting_op.py10
-rwxr-xr-xsrc/op_mode/format_disk.py8
-rwxr-xr-xsrc/op_mode/generate_interfaces_debug_archive.py2
-rwxr-xr-xsrc/op_mode/generate_ipsec_debug_archive.py2
-rwxr-xr-xsrc/op_mode/generate_openconnect_otp_key.py4
-rwxr-xr-xsrc/op_mode/generate_ovpn_client_file.py2
-rwxr-xr-xsrc/op_mode/generate_ssh_server_key.py6
-rwxr-xr-xsrc/op_mode/generate_system_login_user.py4
-rwxr-xr-xsrc/op_mode/igmp-proxy.py10
-rwxr-xr-xsrc/op_mode/ikev2_profile_generator.py2
-rwxr-xr-xsrc/op_mode/interfaces.py8
-rwxr-xr-xsrc/op_mode/ipoe-control.py5
-rwxr-xr-xsrc/op_mode/ipsec.py6
-rwxr-xr-xsrc/op_mode/lldp.py4
-rwxr-xr-xsrc/op_mode/log.py2
-rwxr-xr-xsrc/op_mode/memory.py2
-rwxr-xr-xsrc/op_mode/nat.py4
-rwxr-xr-xsrc/op_mode/neighbor.py7
-rwxr-xr-xsrc/op_mode/nhrp.py6
-rwxr-xr-xsrc/op_mode/openconnect-control.py11
-rwxr-xr-xsrc/op_mode/openconnect.py2
-rwxr-xr-xsrc/op_mode/openvpn.py8
-rwxr-xr-xsrc/op_mode/ping.py12
-rwxr-xr-xsrc/op_mode/pki.py40
-rwxr-xr-xsrc/op_mode/policy_route.py4
-rwxr-xr-xsrc/op_mode/powerctrl.py8
-rwxr-xr-xsrc/op_mode/ppp-server-ctrl.py5
-rwxr-xr-xsrc/op_mode/reset_openvpn.py4
-rwxr-xr-xsrc/op_mode/reset_vpn.py4
-rwxr-xr-xsrc/op_mode/restart_dhcp_relay.py4
-rwxr-xr-xsrc/op_mode/restart_frr.py10
-rwxr-xr-xsrc/op_mode/route.py4
-rwxr-xr-xsrc/op_mode/sflow.py2
-rwxr-xr-xsrc/op_mode/show-bond.py2
-rwxr-xr-xsrc/op_mode/show_acceleration.py6
-rwxr-xr-xsrc/op_mode/show_ntp.sh2
-rwxr-xr-xsrc/op_mode/show_openconnect_otp.py4
-rwxr-xr-xsrc/op_mode/show_openvpn_mfa.py6
-rwxr-xr-xsrc/op_mode/show_sensors.py22
-rw-r--r--src/op_mode/show_techsupport_report.py2
-rwxr-xr-xsrc/op_mode/show_virtual_server.py2
-rwxr-xr-xsrc/op_mode/show_wireless.py4
-rwxr-xr-xsrc/op_mode/show_wwan.py2
-rwxr-xr-xsrc/op_mode/snmp.py2
-rwxr-xr-xsrc/op_mode/snmp_ifmib.py4
-rwxr-xr-xsrc/op_mode/storage.py4
-rwxr-xr-xsrc/op_mode/traceroute.py2
-rwxr-xr-xsrc/op_mode/uptime.py8
-rwxr-xr-xsrc/op_mode/vpn_ike_sa.py6
-rwxr-xr-xsrc/op_mode/vpn_ipsec.py2
-rwxr-xr-xsrc/op_mode/vrf.py4
-rwxr-xr-xsrc/op_mode/vrrp.py11
-rwxr-xr-xsrc/op_mode/wireguard_client.py6
-rwxr-xr-xsrc/op_mode/zone.py4
-rwxr-xr-xsrc/services/api/graphql/generate/schema_from_op_mode.py2
-rw-r--r--src/services/api/graphql/libs/op_mode.py2
-rwxr-xr-xsrc/services/vyos-configd9
-rwxr-xr-xsrc/services/vyos-hostsd9
-rwxr-xr-xsrc/system/keepalived-fifo.py6
-rwxr-xr-xsrc/system/vyos-event-handler.py7
-rwxr-xr-xsrc/system/vyos-system-update-check.py2
-rw-r--r--src/systemd/vyos-router.service19
-rw-r--r--src/systemd/vyos.target3
-rw-r--r--src/tests/test_configverify.py2
-rw-r--r--src/tests/test_dict_search.py4
-rwxr-xr-xsrc/tests/test_find_device_file.py2
-rw-r--r--src/tests/test_util.py5
-rwxr-xr-xsrc/validators/port-multi2
-rwxr-xr-xsrc/validators/port-range2
-rwxr-xr-xsrc/validators/script6
-rwxr-xr-xsrc/validators/timezone2
221 files changed, 1640 insertions, 569 deletions
diff --git a/src/completion/list_dumpable_interfaces.py b/src/completion/list_dumpable_interfaces.py
index 67bf6206b..f9748352f 100755
--- a/src/completion/list_dumpable_interfaces.py
+++ b/src/completion/list_dumpable_interfaces.py
@@ -4,7 +4,7 @@
import re
-from vyos.util import cmd
+from vyos.utils.process import cmd
if __name__ == '__main__':
out = cmd('tcpdump -D').split('\n')
diff --git a/src/completion/list_ipoe.py b/src/completion/list_ipoe.py
index c386b46a2..5a8f4b0c5 100755
--- a/src/completion/list_ipoe.py
+++ b/src/completion/list_ipoe.py
@@ -1,7 +1,21 @@
#!/usr/bin/env python3
+# Copyright 2020-2023 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/>.
import argparse
-from vyos.util import popen
+from vyos.utils.process import popen
if __name__ == '__main__':
parser = argparse.ArgumentParser()
diff --git a/src/completion/list_ipsec_profile_tunnels.py b/src/completion/list_ipsec_profile_tunnels.py
index df6c52f6d..4a917dbd6 100644
--- a/src/completion/list_ipsec_profile_tunnels.py
+++ b/src/completion/list_ipsec_profile_tunnels.py
@@ -19,7 +19,7 @@ import sys
import argparse
from vyos.config import Config
-from vyos.util import dict_search
+from vyos.utils.dict import dict_search
def get_tunnels_from_ipsecprofile(profile):
config = Config()
diff --git a/src/completion/list_openconnect_users.py b/src/completion/list_openconnect_users.py
index a266fd893..db2f4b4da 100755
--- a/src/completion/list_openconnect_users.py
+++ b/src/completion/list_openconnect_users.py
@@ -15,7 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from vyos.config import Config
-from vyos.util import dict_search
+from vyos.utils.dict import dict_search
def get_user_from_ocserv():
config = Config()
diff --git a/src/completion/list_openvpn_users.py b/src/completion/list_openvpn_users.py
index c472dbeab..b2b0149fc 100755
--- a/src/completion/list_openvpn_users.py
+++ b/src/completion/list_openvpn_users.py
@@ -19,7 +19,7 @@ import sys
import argparse
from vyos.config import Config
-from vyos.util import dict_search
+from vyos.utils.dict import dict_search
def get_user_from_interface(interface):
config = Config()
diff --git a/src/conf_mode/arp.py b/src/conf_mode/arp.py
index 7dc5206e0..b141f1141 100755
--- a/src/conf_mode/arp.py
+++ b/src/conf_mode/arp.py
@@ -18,7 +18,7 @@ from sys import exit
from vyos.config import Config
from vyos.configdict import node_changed
-from vyos.util import call
+from vyos.utils.process import call
from vyos import ConfigError
from vyos import airbag
airbag.enable()
diff --git a/src/conf_mode/bcast_relay.py b/src/conf_mode/bcast_relay.py
index 7b93a31c0..ced5d212e 100755
--- a/src/conf_mode/bcast_relay.py
+++ b/src/conf_mode/bcast_relay.py
@@ -23,7 +23,7 @@ from sys import exit
from vyos.config import Config
from vyos.configverify import verify_interface_exists
from vyos.template import render
-from vyos.util import call
+from vyos.utils.process import call
from vyos.validate import is_afi_configured
from vyos import ConfigError
from vyos import airbag
diff --git a/src/conf_mode/conntrack.py b/src/conf_mode/conntrack.py
index 82289526f..2a77540f7 100755
--- a/src/conf_mode/conntrack.py
+++ b/src/conf_mode/conntrack.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2023 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
@@ -23,10 +23,10 @@ from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.firewall import find_nftables_rule
from vyos.firewall import remove_nftables_rule
-from vyos.util import cmd
-from vyos.util import run
-from vyos.util import process_named_running
-from vyos.util import dict_search
+from vyos.utils.process import process_named_running
+from vyos.utils.dict import dict_search
+from vyos.utils.process import cmd
+from vyos.utils.process import run
from vyos.template import render
from vyos.xml import defaults
from vyos import ConfigError
diff --git a/src/conf_mode/conntrack_sync.py b/src/conf_mode/conntrack_sync.py
index c4b2bb488..a83c2274d 100755
--- a/src/conf_mode/conntrack_sync.py
+++ b/src/conf_mode/conntrack_sync.py
@@ -20,11 +20,11 @@ from sys import exit
from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.configverify import verify_interface_exists
-from vyos.util import call
-from vyos.util import dict_search
-from vyos.util import process_named_running
-from vyos.util import read_file
-from vyos.util import run
+from vyos.utils.dict import dict_search
+from vyos.utils.process import process_named_running
+from vyos.utils.file import read_file
+from vyos.utils.process import call
+from vyos.utils.process import run
from vyos.template import render
from vyos.template import get_ipv4
from vyos.validate import is_addr_assigned
diff --git a/src/conf_mode/container.py b/src/conf_mode/container.py
index 6198bb65f..3378aac63 100755
--- a/src/conf_mode/container.py
+++ b/src/conf_mode/container.py
@@ -28,11 +28,11 @@ from vyos.configdict import node_changed
from vyos.configdict import is_node_changed
from vyos.configverify import verify_vrf
from vyos.ifconfig import Interface
-from vyos.util import call
-from vyos.util import cmd
-from vyos.util import run
-from vyos.util import rc_cmd
-from vyos.util import write_file
+from vyos.utils.file import write_file
+from vyos.utils.process import call
+from vyos.utils.process import cmd
+from vyos.utils.process import run
+from vyos.utils.process import rc_cmd
from vyos.template import inc_ip
from vyos.template import is_ipv4
from vyos.template import is_ipv6
diff --git a/src/conf_mode/dhcp_relay.py b/src/conf_mode/dhcp_relay.py
index 7e702a446..fd39bd9fe 100755
--- a/src/conf_mode/dhcp_relay.py
+++ b/src/conf_mode/dhcp_relay.py
@@ -23,8 +23,8 @@ from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.template import render
from vyos.base import Warning
-from vyos.util import call
-from vyos.util import dict_search
+from vyos.utils.process import call
+from vyos.utils.dict import dict_search
from vyos.xml import defaults
from vyos import ConfigError
from vyos import airbag
@@ -51,7 +51,7 @@ def get_config(config=None):
def verify(relay):
# bail out early - looks like removal from running config
- if not relay:
+ if not relay or 'disable' in relay:
return None
if 'lo' in (dict_search('interface', relay) or []):
@@ -78,7 +78,7 @@ def verify(relay):
def generate(relay):
# bail out early - looks like removal from running config
- if not relay:
+ if not relay or 'disable' in relay:
return None
render(config_file, 'dhcp-relay/dhcrelay.conf.j2', relay)
@@ -87,7 +87,7 @@ def generate(relay):
def apply(relay):
# bail out early - looks like removal from running config
service_name = 'isc-dhcp-relay.service'
- if not relay:
+ if not relay or 'disable' in relay:
call(f'systemctl stop {service_name}')
if os.path.exists(config_file):
os.unlink(config_file)
diff --git a/src/conf_mode/dhcp_server.py b/src/conf_mode/dhcp_server.py
index 2b2af252d..c29270367 100755
--- a/src/conf_mode/dhcp_server.py
+++ b/src/conf_mode/dhcp_server.py
@@ -25,9 +25,9 @@ from sys import exit
from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.template import render
-from vyos.util import call
-from vyos.util import dict_search
-from vyos.util import run
+from vyos.utils.dict import dict_search
+from vyos.utils.process import call
+from vyos.utils.process import run
from vyos.validate import is_subnet_connected
from vyos.validate import is_addr_assigned
from vyos.xml import defaults
diff --git a/src/conf_mode/dhcpv6_relay.py b/src/conf_mode/dhcpv6_relay.py
index c1bd51f62..0e7da6f89 100755
--- a/src/conf_mode/dhcpv6_relay.py
+++ b/src/conf_mode/dhcpv6_relay.py
@@ -22,8 +22,9 @@ from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.ifconfig import Interface
from vyos.template import render
-from vyos.util import call
-from vyos.util import dict_search
+from vyos.template import is_ipv6
+from vyos.utils.process import call
+from vyos.utils.dict import dict_search
from vyos.validate import is_ipv6_link_local
from vyos.xml import defaults
from vyos import ConfigError
@@ -51,7 +52,7 @@ def get_config(config=None):
def verify(relay):
# bail out early - looks like removal from running config
- if not relay:
+ if not relay or 'disable' in relay:
return None
if 'upstream_interface' not in relay:
@@ -69,7 +70,7 @@ def verify(relay):
for interface in relay['listen_interface']:
has_global = False
for addr in Interface(interface).get_addr():
- if not is_ipv6_link_local(addr):
+ if is_ipv6(addr) and not is_ipv6_link_local(addr):
has_global = True
if not has_global:
raise ConfigError(f'Interface {interface} does not have global '\
@@ -79,7 +80,7 @@ def verify(relay):
def generate(relay):
# bail out early - looks like removal from running config
- if not relay:
+ if not relay or 'disable' in relay:
return None
render(config_file, 'dhcp-relay/dhcrelay6.conf.j2', relay)
@@ -88,7 +89,7 @@ def generate(relay):
def apply(relay):
# bail out early - looks like removal from running config
service_name = 'isc-dhcp-relay6.service'
- if not relay:
+ if not relay or 'disable' in relay:
# DHCPv6 relay support is removed in the commit
call(f'systemctl stop {service_name}')
if os.path.exists(config_file):
diff --git a/src/conf_mode/dhcpv6_server.py b/src/conf_mode/dhcpv6_server.py
index 078ff327c..f89ad5b9c 100755
--- a/src/conf_mode/dhcpv6_server.py
+++ b/src/conf_mode/dhcpv6_server.py
@@ -23,8 +23,8 @@ from sys import exit
from vyos.config import Config
from vyos.template import render
from vyos.template import is_ipv6
-from vyos.util import call
-from vyos.util import dict_search
+from vyos.utils.process import call
+from vyos.utils.dict import dict_search
from vyos.validate import is_subnet_connected
from vyos import ConfigError
from vyos import airbag
diff --git a/src/conf_mode/dns_dynamic.py b/src/conf_mode/dns_dynamic.py
index 67134e681..d78eb70bc 100755
--- a/src/conf_mode/dns_dynamic.py
+++ b/src/conf_mode/dns_dynamic.py
@@ -21,7 +21,7 @@ from sys import exit
from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.template import render
-from vyos.util import call
+from vyos.utils.process import call
from vyos.xml import defaults
from vyos import ConfigError
from vyos import airbag
diff --git a/src/conf_mode/dns_forwarding.py b/src/conf_mode/dns_forwarding.py
index 0d86c6a52..2d98bffe3 100755
--- a/src/conf_mode/dns_forwarding.py
+++ b/src/conf_mode/dns_forwarding.py
@@ -25,9 +25,9 @@ from vyos.configdict import dict_merge
from vyos.hostsd_client import Client as hostsd_client
from vyos.template import render
from vyos.template import bracketize_ipv6
-from vyos.util import call
-from vyos.util import chown
-from vyos.util import dict_search
+from vyos.utils.process import call
+from vyos.utils.permission import chown
+from vyos.utils.dict import dict_search
from vyos.xml import defaults
from vyos import ConfigError
diff --git a/src/conf_mode/firewall.py b/src/conf_mode/firewall.py
index 190587980..07166d457 100755
--- a/src/conf_mode/firewall.py
+++ b/src/conf_mode/firewall.py
@@ -31,12 +31,12 @@ from vyos.configdep import set_dependents, call_dependents
from vyos.firewall import fqdn_config_parse
from vyos.firewall import geoip_update
from vyos.template import render
-from vyos.util import call
-from vyos.util import cmd
-from vyos.util import dict_search_args
-from vyos.util import dict_search_recursive
-from vyos.util import process_named_running
-from vyos.util import rc_cmd
+from vyos.utils.process import call
+from vyos.utils.process import cmd
+from vyos.utils.dict import dict_search_args
+from vyos.utils.dict import dict_search_recursive
+from vyos.utils.process import process_named_running
+from vyos.utils.process import rc_cmd
from vyos.xml import defaults
from vyos import ConfigError
from vyos import airbag
diff --git a/src/conf_mode/flow_accounting_conf.py b/src/conf_mode/flow_accounting_conf.py
index c36d52e05..bfe906c87 100755
--- a/src/conf_mode/flow_accounting_conf.py
+++ b/src/conf_mode/flow_accounting_conf.py
@@ -26,8 +26,8 @@ from vyos.configdict import dict_merge
from vyos.configverify import verify_vrf
from vyos.ifconfig import Section
from vyos.template import render
-from vyos.util import call
-from vyos.util import cmd
+from vyos.utils.process import call
+from vyos.utils.process import cmd
from vyos.validate import is_addr_assigned
from vyos.xml import defaults
from vyos import ConfigError
diff --git a/src/conf_mode/high-availability.py b/src/conf_mode/high-availability.py
index e18b426b1..0cbd4c49c 100755
--- a/src/conf_mode/high-availability.py
+++ b/src/conf_mode/high-availability.py
@@ -28,8 +28,8 @@ from vyos.ifconfig.vrrp import VRRP
from vyos.template import render
from vyos.template import is_ipv4
from vyos.template import is_ipv6
-from vyos.util import call
-from vyos.util import dict_search
+from vyos.utils.process import call
+from vyos.utils.dict import dict_search
from vyos.xml import defaults
from vyos import ConfigError
from vyos import airbag
@@ -175,6 +175,11 @@ def verify(ha):
# Virtual-server
if 'virtual_server' in ha:
for vs, vs_config in ha['virtual_server'].items():
+
+ if 'address' not in vs_config and 'fwmark' not in vs_config:
+ raise ConfigError('Either address or fwmark is required '
+ f'but not set for virtual-server "{vs}"')
+
if 'port' not in vs_config and 'fwmark' not in vs_config:
raise ConfigError(f'Port or fwmark is required but not set for virtual-server "{vs}"')
if 'port' in vs_config and 'fwmark' in vs_config:
diff --git a/src/conf_mode/host_name.py b/src/conf_mode/host_name.py
index 93f244f42..36d1f6493 100755
--- a/src/conf_mode/host_name.py
+++ b/src/conf_mode/host_name.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2021 VyOS maintainers and contributors
+# Copyright (C) 2018-2023 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
@@ -18,16 +18,15 @@ import re
import sys
import copy
-import vyos.util
import vyos.hostsd_client
from vyos.base import Warning
from vyos.config import Config
from vyos.ifconfig import Section
from vyos.template import is_ip
-from vyos.util import cmd
-from vyos.util import call
-from vyos.util import process_named_running
+from vyos.utils.process import cmd
+from vyos.utils.process import call
+from vyos.utils.process import process_named_running
from vyos import ConfigError
from vyos import airbag
airbag.enable()
diff --git a/src/conf_mode/http-api.py b/src/conf_mode/http-api.py
index 7e801eb26..7bdf448a3 100755
--- a/src/conf_mode/http-api.py
+++ b/src/conf_mode/http-api.py
@@ -27,8 +27,8 @@ from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.configdep import set_dependents, call_dependents
from vyos.template import render
-from vyos.util import cmd
-from vyos.util import call
+from vyos.utils.process import cmd
+from vyos.utils.process import call
from vyos.xml import defaults
from vyos import ConfigError
from vyos import airbag
diff --git a/src/conf_mode/https.py b/src/conf_mode/https.py
index b0c38e8d3..010490c7e 100755
--- a/src/conf_mode/https.py
+++ b/src/conf_mode/https.py
@@ -28,10 +28,10 @@ from vyos import ConfigError
from vyos.pki import wrap_certificate
from vyos.pki import wrap_private_key
from vyos.template import render
-from vyos.util import call
-from vyos.util import check_port_availability
-from vyos.util import is_listen_port_bind_service
-from vyos.util import write_file
+from vyos.utils.process import call
+from vyos.utils.network import check_port_availability
+from vyos.utils.network import is_listen_port_bind_service
+from vyos.utils.file import write_file
from vyos import airbag
airbag.enable()
diff --git a/src/conf_mode/igmp_proxy.py b/src/conf_mode/igmp_proxy.py
index de6a51c64..4ec2f1835 100755
--- a/src/conf_mode/igmp_proxy.py
+++ b/src/conf_mode/igmp_proxy.py
@@ -23,8 +23,8 @@ from vyos.base import Warning
from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.template import render
-from vyos.util import call
-from vyos.util import dict_search
+from vyos.utils.process import call
+from vyos.utils.dict import dict_search
from vyos.xml import defaults
from vyos import ConfigError
from vyos import airbag
diff --git a/src/conf_mode/intel_qat.py b/src/conf_mode/intel_qat.py
index dd04a002d..e4b248675 100755
--- a/src/conf_mode/intel_qat.py
+++ b/src/conf_mode/intel_qat.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2020 VyOS maintainers and contributors
+# Copyright (C) 2019-2023 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,7 +20,8 @@ import re
from sys import exit
from vyos.config import Config
-from vyos.util import popen, run
+from vyos.utils.process import popen
+from vyos.utils.process import run
from vyos import ConfigError
from vyos import airbag
airbag.enable()
diff --git a/src/conf_mode/interfaces-bonding.py b/src/conf_mode/interfaces-bonding.py
index 9936620c8..c2a569fa9 100755
--- a/src/conf_mode/interfaces-bonding.py
+++ b/src/conf_mode/interfaces-bonding.py
@@ -35,7 +35,7 @@ from vyos.configverify import verify_vlan_config
from vyos.configverify import verify_vrf
from vyos.ifconfig import BondIf
from vyos.ifconfig import Section
-from vyos.util import dict_search
+from vyos.utils.dict import dict_search
from vyos.validate import has_address_configured
from vyos.validate import has_vrf_configured
from vyos import ConfigError
diff --git a/src/conf_mode/interfaces-bridge.py b/src/conf_mode/interfaces-bridge.py
index 4da3b097f..087ead20a 100755
--- a/src/conf_mode/interfaces-bridge.py
+++ b/src/conf_mode/interfaces-bridge.py
@@ -34,8 +34,8 @@ from vyos.validate import has_address_configured
from vyos.validate import has_vrf_configured
from vyos.xml import defaults
-from vyos.util import cmd
-from vyos.util import dict_search
+from vyos.utils.process import cmd
+from vyos.utils.dict import dict_search
from vyos import ConfigError
from vyos import airbag
diff --git a/src/conf_mode/interfaces-ethernet.py b/src/conf_mode/interfaces-ethernet.py
index 9d2ea2eeb..b015bba88 100755
--- a/src/conf_mode/interfaces-ethernet.py
+++ b/src/conf_mode/interfaces-ethernet.py
@@ -40,9 +40,9 @@ from vyos.pki import encode_certificate
from vyos.pki import load_certificate
from vyos.pki import wrap_private_key
from vyos.template import render
-from vyos.util import call
-from vyos.util import dict_search
-from vyos.util import write_file
+from vyos.utils.process import call
+from vyos.utils.dict import dict_search
+from vyos.utils.file import write_file
from vyos import ConfigError
from vyos import airbag
airbag.enable()
diff --git a/src/conf_mode/interfaces-l2tpv3.py b/src/conf_mode/interfaces-l2tpv3.py
index ca321e01d..6efeac302 100755
--- a/src/conf_mode/interfaces-l2tpv3.py
+++ b/src/conf_mode/interfaces-l2tpv3.py
@@ -28,7 +28,7 @@ from vyos.configverify import verify_mtu_ipv6
from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_bond_bridge_member
from vyos.ifconfig import L2TPv3If
-from vyos.util import check_kmod
+from vyos.utils.kernel import check_kmod
from vyos.validate import is_addr_assigned
from vyos import ConfigError
from vyos import airbag
diff --git a/src/conf_mode/interfaces-macsec.py b/src/conf_mode/interfaces-macsec.py
index 649ea8d50..3f86e2638 100755
--- a/src/conf_mode/interfaces-macsec.py
+++ b/src/conf_mode/interfaces-macsec.py
@@ -33,9 +33,9 @@ from vyos.configverify import verify_bond_bridge_member
from vyos.ifconfig import MACsecIf
from vyos.ifconfig import Interface
from vyos.template import render
-from vyos.util import call
-from vyos.util import dict_search
-from vyos.util import is_systemd_service_running
+from vyos.utils.process import call
+from vyos.utils.dict import dict_search
+from vyos.utils.process import is_systemd_service_running
from vyos import ConfigError
from vyos import airbag
airbag.enable()
diff --git a/src/conf_mode/interfaces-openvpn.py b/src/conf_mode/interfaces-openvpn.py
index 6f227b0d1..607a19385 100755
--- a/src/conf_mode/interfaces-openvpn.py
+++ b/src/conf_mode/interfaces-openvpn.py
@@ -50,15 +50,15 @@ from vyos.pki import wrap_private_key
from vyos.template import render
from vyos.template import is_ipv4
from vyos.template import is_ipv6
-from vyos.util import call
-from vyos.util import chown
-from vyos.util import cmd
-from vyos.util import dict_search
-from vyos.util import dict_search_args
-from vyos.util import is_list_equal
-from vyos.util import makedir
-from vyos.util import read_file
-from vyos.util import write_file
+from vyos.utils.dict import dict_search
+from vyos.utils.dict import dict_search_args
+from vyos.utils.list import is_list_equal
+from vyos.utils.file import makedir
+from vyos.utils.file import read_file
+from vyos.utils.file import write_file
+from vyos.utils.process import call
+from vyos.utils.permission import chown
+from vyos.utils.process import cmd
from vyos.validate import is_addr_assigned
from vyos import ConfigError
diff --git a/src/conf_mode/interfaces-pppoe.py b/src/conf_mode/interfaces-pppoe.py
index 5f0b76f90..fca91253c 100755
--- a/src/conf_mode/interfaces-pppoe.py
+++ b/src/conf_mode/interfaces-pppoe.py
@@ -32,8 +32,8 @@ from vyos.configverify import verify_mtu_ipv6
from vyos.configverify import verify_mirror_redirect
from vyos.ifconfig import PPPoEIf
from vyos.template import render
-from vyos.util import call
-from vyos.util import is_systemd_service_running
+from vyos.utils.process import call
+from vyos.utils.process import is_systemd_service_running
from vyos import ConfigError
from vyos import airbag
airbag.enable()
diff --git a/src/conf_mode/interfaces-sstpc.py b/src/conf_mode/interfaces-sstpc.py
index b5cc4cf4e..b588910dc 100755
--- a/src/conf_mode/interfaces-sstpc.py
+++ b/src/conf_mode/interfaces-sstpc.py
@@ -27,10 +27,10 @@ from vyos.pki import encode_certificate
from vyos.pki import find_chain
from vyos.pki import load_certificate
from vyos.template import render
-from vyos.util import call
-from vyos.util import dict_search
-from vyos.util import is_systemd_service_running
-from vyos.util import write_file
+from vyos.utils.process import call
+from vyos.utils.dict import dict_search
+from vyos.utils.process import is_systemd_service_running
+from vyos.utils.file import write_file
from vyos import ConfigError
from vyos import airbag
airbag.enable()
diff --git a/src/conf_mode/interfaces-tunnel.py b/src/conf_mode/interfaces-tunnel.py
index 0a3726e94..6a075970e 100755
--- a/src/conf_mode/interfaces-tunnel.py
+++ b/src/conf_mode/interfaces-tunnel.py
@@ -33,8 +33,8 @@ from vyos.configverify import verify_bond_bridge_member
from vyos.ifconfig import Interface
from vyos.ifconfig import Section
from vyos.ifconfig import TunnelIf
-from vyos.util import get_interface_config
-from vyos.util import dict_search
+from vyos.utils.network import get_interface_config
+from vyos.utils.dict import dict_search
from vyos import ConfigError
from vyos import airbag
airbag.enable()
diff --git a/src/conf_mode/interfaces-vti.py b/src/conf_mode/interfaces-vti.py
index f4b0436af..9871810ae 100755
--- a/src/conf_mode/interfaces-vti.py
+++ b/src/conf_mode/interfaces-vti.py
@@ -21,7 +21,7 @@ from vyos.config import Config
from vyos.configdict import get_interface_dict
from vyos.configverify import verify_mirror_redirect
from vyos.ifconfig import VTIIf
-from vyos.util import dict_search
+from vyos.utils.dict import dict_search
from vyos import ConfigError
from vyos import airbag
airbag.enable()
diff --git a/src/conf_mode/interfaces-wireguard.py b/src/conf_mode/interfaces-wireguard.py
index 762bad94f..a02baba82 100755
--- a/src/conf_mode/interfaces-wireguard.py
+++ b/src/conf_mode/interfaces-wireguard.py
@@ -27,8 +27,8 @@ from vyos.configverify import verify_mtu_ipv6
from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_bond_bridge_member
from vyos.ifconfig import WireGuardIf
-from vyos.util import check_kmod
-from vyos.util import check_port_availability
+from vyos.utils.kernel import check_kmod
+from vyos.utils.network import check_port_availability
from vyos import ConfigError
from vyos import airbag
airbag.enable()
diff --git a/src/conf_mode/interfaces-wireless.py b/src/conf_mode/interfaces-wireless.py
index dd798b5a2..42326bea0 100755
--- a/src/conf_mode/interfaces-wireless.py
+++ b/src/conf_mode/interfaces-wireless.py
@@ -33,8 +33,8 @@ from vyos.configverify import verify_vrf
from vyos.configverify import verify_bond_bridge_member
from vyos.ifconfig import WiFiIf
from vyos.template import render
-from vyos.util import call
-from vyos.util import dict_search
+from vyos.utils.process import call
+from vyos.utils.dict import dict_search
from vyos import ConfigError
from vyos import airbag
airbag.enable()
diff --git a/src/conf_mode/interfaces-wwan.py b/src/conf_mode/interfaces-wwan.py
index 9ca495476..6658ca86a 100755
--- a/src/conf_mode/interfaces-wwan.py
+++ b/src/conf_mode/interfaces-wwan.py
@@ -27,12 +27,12 @@ from vyos.configverify import verify_interface_exists
from vyos.configverify import verify_mirror_redirect
from vyos.configverify import verify_vrf
from vyos.ifconfig import WWANIf
-from vyos.util import cmd
-from vyos.util import call
-from vyos.util import dict_search
-from vyos.util import DEVNULL
-from vyos.util import is_systemd_service_active
-from vyos.util import write_file
+from vyos.utils.dict import dict_search
+from vyos.utils.process import cmd
+from vyos.utils.process import call
+from vyos.utils.process import DEVNULL
+from vyos.utils.process import is_systemd_service_active
+from vyos.utils.file import write_file
from vyos import ConfigError
from vyos import airbag
airbag.enable()
diff --git a/src/conf_mode/le_cert.py b/src/conf_mode/le_cert.py
index 6e169a3d5..06c7e7b72 100755
--- a/src/conf_mode/le_cert.py
+++ b/src/conf_mode/le_cert.py
@@ -20,9 +20,9 @@ import os
import vyos.defaults
from vyos.config import Config
from vyos import ConfigError
-from vyos.util import cmd
-from vyos.util import call
-from vyos.util import is_systemd_service_running
+from vyos.utils.process import cmd
+from vyos.utils.process import call
+from vyos.utils.process import is_systemd_service_running
from vyos import airbag
airbag.enable()
diff --git a/src/conf_mode/lldp.py b/src/conf_mode/lldp.py
index c703c1fe0..0e5fc29d3 100755
--- a/src/conf_mode/lldp.py
+++ b/src/conf_mode/lldp.py
@@ -24,8 +24,8 @@ from vyos.configdict import dict_merge
from vyos.validate import is_addr_assigned
from vyos.validate import is_loopback_addr
from vyos.version import get_version_data
-from vyos.util import call
-from vyos.util import dict_search
+from vyos.utils.process import call
+from vyos.utils.dict import dict_search
from vyos.xml import defaults
from vyos.template import render
from vyos import ConfigError
diff --git a/src/conf_mode/load-balancing-haproxy.py b/src/conf_mode/load-balancing-haproxy.py
index b29fdffc7..2fb0edf8e 100755
--- a/src/conf_mode/load-balancing-haproxy.py
+++ b/src/conf_mode/load-balancing-haproxy.py
@@ -21,9 +21,9 @@ from shutil import rmtree
from vyos.config import Config
from vyos.configdict import dict_merge
-from vyos.util import call
-from vyos.util import check_port_availability
-from vyos.util import is_listen_port_bind_service
+from vyos.utils.process import call
+from vyos.utils.network import check_port_availability
+from vyos.utils.network import is_listen_port_bind_service
from vyos.pki import wrap_certificate
from vyos.pki import wrap_private_key
from vyos.template import render
diff --git a/src/conf_mode/load-balancing-wan.py b/src/conf_mode/load-balancing-wan.py
index 7086aaf8b..3533a5a04 100755
--- a/src/conf_mode/load-balancing-wan.py
+++ b/src/conf_mode/load-balancing-wan.py
@@ -22,7 +22,7 @@ from shutil import rmtree
from vyos.base import Warning
from vyos.config import Config
from vyos.configdict import dict_merge
-from vyos.util import cmd
+from vyos.utils.process import cmd
from vyos.template import render
from vyos.xml import defaults
from vyos import ConfigError
diff --git a/src/conf_mode/nat.py b/src/conf_mode/nat.py
index 9f8221514..e19b12937 100755
--- a/src/conf_mode/nat.py
+++ b/src/conf_mode/nat.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2022 VyOS maintainers and contributors
+# Copyright (C) 2020-2023 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,11 +28,11 @@ from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.template import render
from vyos.template import is_ip_network
-from vyos.util import cmd
-from vyos.util import run
-from vyos.util import check_kmod
-from vyos.util import dict_search
-from vyos.util import dict_search_args
+from vyos.utils.kernel import check_kmod
+from vyos.utils.dict import dict_search
+from vyos.utils.dict import dict_search_args
+from vyos.utils.process import cmd
+from vyos.utils.process import run
from vyos.validate import is_addr_assigned
from vyos.xml import defaults
from vyos import ConfigError
@@ -72,6 +72,7 @@ def verify_rule(config, err_msg, groups_dict):
""" Common verify steps used for both source and destination NAT """
if (dict_search('translation.port', config) != None or
+ dict_search('translation.redirect.port', config) != None or
dict_search('destination.port', config) != None or
dict_search('source.port', config)):
@@ -221,7 +222,7 @@ def verify(nat):
elif config['inbound_interface'] not in 'any' and config['inbound_interface'] not in interfaces():
Warning(f'rule "{rule}" interface "{config["inbound_interface"]}" does not exist on this system')
- if not dict_search('translation.address', config) and not dict_search('translation.port', config):
+ if not dict_search('translation.address', config) and not dict_search('translation.port', config) and not dict_search('translation.redirect.port', config):
if 'exclude' not in config:
raise ConfigError(f'{err_msg} translation requires address and/or port')
diff --git a/src/conf_mode/nat66.py b/src/conf_mode/nat66.py
index d8f913b0c..25f625b84 100755
--- a/src/conf_mode/nat66.py
+++ b/src/conf_mode/nat66.py
@@ -25,9 +25,9 @@ from vyos.base import Warning
from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.template import render
-from vyos.util import cmd
-from vyos.util import check_kmod
-from vyos.util import dict_search
+from vyos.utils.process import cmd
+from vyos.utils.kernel import check_kmod
+from vyos.utils.dict import dict_search
from vyos.template import is_ipv6
from vyos.xml import defaults
from vyos import ConfigError
diff --git a/src/conf_mode/netns.py b/src/conf_mode/netns.py
index 20129ce65..95ab83dbc 100755
--- a/src/conf_mode/netns.py
+++ b/src/conf_mode/netns.py
@@ -22,9 +22,9 @@ from tempfile import NamedTemporaryFile
from vyos.config import Config
from vyos.configdict import node_changed
from vyos.ifconfig import Interface
-from vyos.util import call
-from vyos.util import dict_search
-from vyos.util import get_interface_config
+from vyos.utils.process import call
+from vyos.utils.dict import dict_search
+from vyos.utils.network import get_interface_config
from vyos import ConfigError
from vyos import airbag
airbag.enable()
diff --git a/src/conf_mode/ntp.py b/src/conf_mode/ntp.py
index 95766c44c..1cc23a7df 100755
--- a/src/conf_mode/ntp.py
+++ b/src/conf_mode/ntp.py
@@ -20,9 +20,9 @@ from vyos.config import Config
from vyos.configdict import is_node_changed
from vyos.configverify import verify_vrf
from vyos.configverify import verify_interface_exists
-from vyos.util import call
-from vyos.util import chmod_750
-from vyos.util import get_interface_config
+from vyos.utils.process import call
+from vyos.utils.permission import chmod_750
+from vyos.utils.network import get_interface_config
from vyos.template import render
from vyos.template import is_ipv4
from vyos import ConfigError
diff --git a/src/conf_mode/pki.py b/src/conf_mode/pki.py
index 54de467ca..eb8cb3940 100755
--- a/src/conf_mode/pki.py
+++ b/src/conf_mode/pki.py
@@ -26,8 +26,8 @@ from vyos.pki import load_public_key
from vyos.pki import load_private_key
from vyos.pki import load_crl
from vyos.pki import load_dh_parameters
-from vyos.util import dict_search_args
-from vyos.util import dict_search_recursive
+from vyos.utils.dict import dict_search_args
+from vyos.utils.dict import dict_search_recursive
from vyos.xml import defaults
from vyos import ConfigError
from vyos import airbag
diff --git a/src/conf_mode/policy-local-route.py b/src/conf_mode/policy-local-route.py
index 3f834f55c..79526f82a 100755
--- a/src/conf_mode/policy-local-route.py
+++ b/src/conf_mode/policy-local-route.py
@@ -24,7 +24,7 @@ from vyos.configdict import dict_merge
from vyos.configdict import node_changed
from vyos.configdict import leaf_node_changed
from vyos.template import render
-from vyos.util import call
+from vyos.utils.process import call
from vyos import ConfigError
from vyos import airbag
airbag.enable()
diff --git a/src/conf_mode/policy-route.py b/src/conf_mode/policy-route.py
index 40a32efb3..adad012de 100755
--- a/src/conf_mode/policy-route.py
+++ b/src/conf_mode/policy-route.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2023 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
@@ -22,9 +22,9 @@ from sys import exit
from vyos.base import Warning
from vyos.config import Config
from vyos.template import render
-from vyos.util import cmd
-from vyos.util import dict_search_args
-from vyos.util import run
+from vyos.utils.dict import dict_search_args
+from vyos.utils.process import cmd
+from vyos.utils.process import run
from vyos import ConfigError
from vyos import airbag
airbag.enable()
diff --git a/src/conf_mode/policy.py b/src/conf_mode/policy.py
index 331194fec..4df893ebf 100755
--- a/src/conf_mode/policy.py
+++ b/src/conf_mode/policy.py
@@ -19,7 +19,7 @@ from sys import exit
from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.template import render_to_string
-from vyos.util import dict_search
+from vyos.utils.dict import dict_search
from vyos import ConfigError
from vyos import frr
from vyos import airbag
diff --git a/src/conf_mode/protocols_babel.py b/src/conf_mode/protocols_babel.py
index 20821c7f2..f5ac56f65 100755
--- a/src/conf_mode/protocols_babel.py
+++ b/src/conf_mode/protocols_babel.py
@@ -24,7 +24,7 @@ from vyos.configdict import node_changed
from vyos.configverify import verify_common_route_maps
from vyos.configverify import verify_access_list
from vyos.configverify import verify_prefix_list
-from vyos.util import dict_search
+from vyos.utils.dict import dict_search
from vyos.xml import defaults
from vyos.template import render_to_string
from vyos import ConfigError
diff --git a/src/conf_mode/protocols_bgp.py b/src/conf_mode/protocols_bgp.py
index b23584bdb..cec025fea 100755
--- a/src/conf_mode/protocols_bgp.py
+++ b/src/conf_mode/protocols_bgp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2022 VyOS maintainers and contributors
+# Copyright (C) 2020-2023 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,13 +20,15 @@ from sys import argv
from vyos.base import Warning
from vyos.config import Config
from vyos.configdict import dict_merge
+from vyos.configdict import node_changed
from vyos.configverify import verify_prefix_list
from vyos.configverify import verify_route_map
from vyos.configverify import verify_vrf
from vyos.template import is_ip
from vyos.template import is_interface
from vyos.template import render_to_string
-from vyos.util import dict_search
+from vyos.utils.dict import dict_search
+from vyos.utils.network import get_interface_vrf
from vyos.validate import is_addr_assigned
from vyos import ConfigError
from vyos import frr
@@ -55,6 +57,12 @@ def get_config(config=None):
get_first_key=True,
no_tag_node_value_mangle=True)
+ # Remove per interface MPLS configuration - get a list if changed
+ # nodes under the interface tagNode
+ interfaces_removed = node_changed(conf, base + ['interface'])
+ if interfaces_removed:
+ bgp['interface_removed'] = list(interfaces_removed)
+
# Assign the name of our VRF context. This MUST be done before the return
# statement below, else on deletion we will delete the default instance
# instead of the VRF instance.
@@ -195,14 +203,21 @@ def verify_remote_as(peer_config, bgp_config):
return None
def verify_afi(peer_config, bgp_config):
+ # If address_family configured under neighboor
if 'address_family' in peer_config:
return True
+ # If address_family configured under peer-group
+ # if neighbor interface configured
+ peer_group_name = ''
+ if dict_search('interface.peer_group', peer_config):
+ peer_group_name = peer_config['interface']['peer_group']
+ # if neighbor IP configured.
if 'peer_group' in peer_config:
peer_group_name = peer_config['peer_group']
+ if peer_group_name:
tmp = dict_search(f'peer_group.{peer_group_name}.address_family', bgp_config)
if tmp: return True
-
return False
def verify(bgp):
@@ -231,6 +246,18 @@ def verify(bgp):
if 'system_as' not in bgp:
raise ConfigError('BGP system-as number must be defined!')
+ # Verify vrf on interface and bgp section
+ if 'interface' in bgp:
+ for interface in bgp['interface']:
+ error_msg = f'Interface "{interface}" belongs to different VRF instance'
+ tmp = get_interface_vrf(interface)
+ if 'vrf' in bgp:
+ if bgp['vrf'] != tmp:
+ vrf = bgp['vrf']
+ raise ConfigError(f'{error_msg} "{vrf}"!')
+ elif tmp != 'default':
+ raise ConfigError(f'{error_msg} "{tmp}"!')
+
# Common verification for both peer-group and neighbor statements
for neighbor in ['neighbor', 'peer_group']:
# bail out early if there is no neighbor or peer-group statement
@@ -520,6 +547,14 @@ def apply(bgp):
vrf = ' vrf ' + bgp['vrf']
frr_cfg.load_configuration(bgp_daemon)
+
+ # Remove interface specific config
+ for key in ['interface', 'interface_removed']:
+ if key not in bgp:
+ continue
+ for interface in bgp[key]:
+ frr_cfg.modify_section(f'^interface {interface}', stop_pattern='^exit', remove_stop_mark=True)
+
frr_cfg.modify_section(f'^router bgp \d+{vrf}', stop_pattern='^exit', remove_stop_mark=True)
if 'frr_bgpd_config' in bgp:
frr_cfg.add_before(frr.default_add_before, bgp['frr_bgpd_config'])
diff --git a/src/conf_mode/protocols_failover.py b/src/conf_mode/protocols_failover.py
index 85e984afe..faf56d741 100755
--- a/src/conf_mode/protocols_failover.py
+++ b/src/conf_mode/protocols_failover.py
@@ -21,7 +21,7 @@ from pathlib import Path
from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.template import render
-from vyos.util import call
+from vyos.utils.process import call
from vyos.xml import defaults
from vyos import ConfigError
from vyos import airbag
diff --git a/src/conf_mode/protocols_igmp.py b/src/conf_mode/protocols_igmp.py
index 65cc2beba..f6097e282 100755
--- a/src/conf_mode/protocols_igmp.py
+++ b/src/conf_mode/protocols_igmp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020 VyOS maintainers and contributors
+# Copyright (C) 2020-2023 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
@@ -21,7 +21,8 @@ from sys import exit
from vyos import ConfigError
from vyos.config import Config
-from vyos.util import call, process_named_running
+from vyos.utils.process import process_named_running
+from vyos.utils.process import call
from vyos.template import render
from signal import SIGTERM
diff --git a/src/conf_mode/protocols_isis.py b/src/conf_mode/protocols_isis.py
index ecca87db0..4c637a99f 100755
--- a/src/conf_mode/protocols_isis.py
+++ b/src/conf_mode/protocols_isis.py
@@ -25,8 +25,8 @@ from vyos.configdict import node_changed
from vyos.configverify import verify_common_route_maps
from vyos.configverify import verify_interface_exists
from vyos.ifconfig import Interface
-from vyos.util import dict_search
-from vyos.util import get_interface_config
+from vyos.utils.dict import dict_search
+from vyos.utils.network import get_interface_config
from vyos.template import render_to_string
from vyos.xml import defaults
from vyos import ConfigError
diff --git a/src/conf_mode/protocols_mpls.py b/src/conf_mode/protocols_mpls.py
index 73af6595b..177a43444 100755
--- a/src/conf_mode/protocols_mpls.py
+++ b/src/conf_mode/protocols_mpls.py
@@ -21,9 +21,9 @@ from sys import exit
from glob import glob
from vyos.config import Config
from vyos.template import render_to_string
-from vyos.util import dict_search
-from vyos.util import read_file
-from vyos.util import sysctl_write
+from vyos.utils.dict import dict_search
+from vyos.utils.file import read_file
+from vyos.utils.system import sysctl_write
from vyos.configverify import verify_interface_exists
from vyos import ConfigError
from vyos import frr
diff --git a/src/conf_mode/protocols_nhrp.py b/src/conf_mode/protocols_nhrp.py
index d28ced4fd..5ec0bc9e5 100755
--- a/src/conf_mode/protocols_nhrp.py
+++ b/src/conf_mode/protocols_nhrp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2023 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
@@ -19,8 +19,8 @@ import os
from vyos.config import Config
from vyos.configdict import node_changed
from vyos.template import render
-from vyos.util import process_named_running
-from vyos.util import run
+from vyos.utils.process import process_named_running
+from vyos.utils.process import run
from vyos import ConfigError
from vyos import airbag
airbag.enable()
diff --git a/src/conf_mode/protocols_ospf.py b/src/conf_mode/protocols_ospf.py
index 460c9f1a4..f2075d25b 100755
--- a/src/conf_mode/protocols_ospf.py
+++ b/src/conf_mode/protocols_ospf.py
@@ -27,8 +27,8 @@ from vyos.configverify import verify_route_map
from vyos.configverify import verify_interface_exists
from vyos.configverify import verify_access_list
from vyos.template import render_to_string
-from vyos.util import dict_search
-from vyos.util import get_interface_config
+from vyos.utils.dict import dict_search
+from vyos.utils.network import get_interface_config
from vyos.xml import defaults
from vyos import ConfigError
from vyos import frr
@@ -88,6 +88,8 @@ def get_config(config=None):
del default_values['area']['area_type']['nssa']
if 'mpls_te' not in ospf:
del default_values['mpls_te']
+ if 'graceful_restart' not in ospf:
+ del default_values['graceful_restart']
for protocol in ['babel', 'bgp', 'connected', 'isis', 'kernel', 'rip', 'static', 'table']:
# table is a tagNode thus we need to clean out all occurances for the
diff --git a/src/conf_mode/protocols_ospfv3.py b/src/conf_mode/protocols_ospfv3.py
index cb21bd83c..fbea51f56 100755
--- a/src/conf_mode/protocols_ospfv3.py
+++ b/src/conf_mode/protocols_ospfv3.py
@@ -27,8 +27,8 @@ from vyos.configverify import verify_route_map
from vyos.configverify import verify_interface_exists
from vyos.template import render_to_string
from vyos.ifconfig import Interface
-from vyos.util import dict_search
-from vyos.util import get_interface_config
+from vyos.utils.dict import dict_search
+from vyos.utils.network import get_interface_config
from vyos.xml import defaults
from vyos import ConfigError
from vyos import frr
@@ -83,6 +83,8 @@ def get_config(config=None):
# need to check this first and probably drop that key.
if dict_search('default_information.originate', ospfv3) is None:
del default_values['default_information']
+ if 'graceful_restart' not in ospfv3:
+ del default_values['graceful_restart']
# XXX: T2665: we currently have no nice way for defaults under tag nodes,
# clean them out and add them manually :(
diff --git a/src/conf_mode/protocols_pim.py b/src/conf_mode/protocols_pim.py
index 78df9b6f8..0aaa0d2c6 100755
--- a/src/conf_mode/protocols_pim.py
+++ b/src/conf_mode/protocols_pim.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020 VyOS maintainers and contributors
+# Copyright (C) 2020-2023 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
@@ -21,7 +21,8 @@ from sys import exit
from vyos.config import Config
from vyos import ConfigError
-from vyos.util import call, process_named_running
+from vyos.utils.process import process_named_running
+from vyos.utils.process import call
from vyos.template import render
from signal import SIGTERM
diff --git a/src/conf_mode/protocols_rip.py b/src/conf_mode/protocols_rip.py
index c78d90396..5661dc377 100755
--- a/src/conf_mode/protocols_rip.py
+++ b/src/conf_mode/protocols_rip.py
@@ -24,7 +24,7 @@ from vyos.configdict import node_changed
from vyos.configverify import verify_common_route_maps
from vyos.configverify import verify_access_list
from vyos.configverify import verify_prefix_list
-from vyos.util import dict_search
+from vyos.utils.dict import dict_search
from vyos.xml import defaults
from vyos.template import render_to_string
from vyos import ConfigError
diff --git a/src/conf_mode/protocols_ripng.py b/src/conf_mode/protocols_ripng.py
index 21ff710b3..e3c904e33 100755
--- a/src/conf_mode/protocols_ripng.py
+++ b/src/conf_mode/protocols_ripng.py
@@ -23,7 +23,7 @@ from vyos.configdict import dict_merge
from vyos.configverify import verify_common_route_maps
from vyos.configverify import verify_access_list
from vyos.configverify import verify_prefix_list
-from vyos.util import dict_search
+from vyos.utils.dict import dict_search
from vyos.xml import defaults
from vyos.template import render_to_string
from vyos import ConfigError
diff --git a/src/conf_mode/protocols_rpki.py b/src/conf_mode/protocols_rpki.py
index 62ea9c878..035b7db05 100755
--- a/src/conf_mode/protocols_rpki.py
+++ b/src/conf_mode/protocols_rpki.py
@@ -21,7 +21,7 @@ from sys import exit
from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.template import render_to_string
-from vyos.util import dict_search
+from vyos.utils.dict import dict_search
from vyos.xml import defaults
from vyos import ConfigError
from vyos import frr
diff --git a/src/conf_mode/protocols_static.py b/src/conf_mode/protocols_static.py
index 7b6150696..5def8d645 100755
--- a/src/conf_mode/protocols_static.py
+++ b/src/conf_mode/protocols_static.py
@@ -47,7 +47,7 @@ def get_config(config=None):
base_path = ['protocols', 'static']
# eqivalent of the C foo ? 'a' : 'b' statement
base = vrf and ['vrf', 'name', vrf, 'protocols', 'static'] or base_path
- static = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
+ static = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True, no_tag_node_value_mangle=True)
# Assign the name of our VRF context
if vrf: static['vrf'] = vrf
diff --git a/src/conf_mode/protocols_static_multicast.py b/src/conf_mode/protocols_static_multicast.py
index 6afdf31f3..7f6ae3680 100755
--- a/src/conf_mode/protocols_static_multicast.py
+++ b/src/conf_mode/protocols_static_multicast.py
@@ -21,7 +21,7 @@ from sys import exit
from vyos import ConfigError
from vyos.config import Config
-from vyos.util import call
+from vyos.utils.process import call
from vyos.template import render
from vyos import airbag
diff --git a/src/conf_mode/qos.py b/src/conf_mode/qos.py
index 1be2c283f..53e9ff50d 100755
--- a/src/conf_mode/qos.py
+++ b/src/conf_mode/qos.py
@@ -36,8 +36,8 @@ from vyos.qos import RateLimiter
from vyos.qos import RoundRobin
from vyos.qos import TrafficShaper
from vyos.qos import TrafficShaperHFSC
-from vyos.util import call
-from vyos.util import dict_search_recursive
+from vyos.utils.process import call
+from vyos.utils.dict import dict_search_recursive
from vyos.xml import defaults
from vyos import ConfigError
from vyos import airbag
diff --git a/src/conf_mode/salt-minion.py b/src/conf_mode/salt-minion.py
index 00b889a11..3ff7880b2 100755
--- a/src/conf_mode/salt-minion.py
+++ b/src/conf_mode/salt-minion.py
@@ -25,8 +25,8 @@ from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.configverify import verify_interface_exists
from vyos.template import render
-from vyos.util import call
-from vyos.util import chown
+from vyos.utils.process import call
+from vyos.utils.permission import chown
from vyos.xml import defaults
from vyos import ConfigError
diff --git a/src/conf_mode/service_config_sync.py b/src/conf_mode/service_config_sync.py
new file mode 100755
index 000000000..5cde735a1
--- /dev/null
+++ b/src/conf_mode/service_config_sync.py
@@ -0,0 +1,111 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2023 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/>.
+
+import os
+import json
+from pathlib import Path
+
+from vyos.config import Config
+from vyos.configdict import dict_merge
+from vyos.xml import defaults
+from vyos import ConfigError
+from vyos import airbag
+
+airbag.enable()
+
+
+service_conf = Path(f'/run/config_sync_conf.conf')
+post_commit_dir = '/run/scripts/commit/post-hooks.d'
+post_commit_file_src = '/usr/libexec/vyos/vyos_config_sync.py'
+post_commit_file = f'{post_commit_dir}/vyos_config_sync'
+
+
+def get_config(config=None):
+ if config:
+ conf = config
+ else:
+ conf = Config()
+
+ base = ['service', 'config-sync']
+ if not conf.exists(base):
+ return None
+ config = conf.get_config_dict(base,
+ get_first_key=True,
+ no_tag_node_value_mangle=True)
+
+ default_values = defaults(base)
+ config = dict_merge(default_values, config)
+
+ return config
+
+
+def verify(config):
+ # bail out early - looks like removal from running config
+ if not config:
+ return None
+
+ if 'mode' not in config:
+ raise ConfigError(f'config-sync mode is mandatory!')
+
+ for option in ['secondary', 'section']:
+ if option not in config:
+ raise ConfigError(f"config-sync '{option}' is not configured!")
+
+ if 'address' not in config['secondary']:
+ raise ConfigError(f'secondary address is mandatory!')
+ if 'key' not in config['secondary']:
+ raise ConfigError(f'secondary key is mandatory!')
+
+
+def generate(config):
+ if not config:
+
+ if os.path.exists(post_commit_file):
+ os.unlink(post_commit_file)
+
+ if service_conf.exists():
+ service_conf.unlink()
+
+ return None
+
+ # Write configuration file
+ conf_json = json.dumps(config, indent=4)
+ service_conf.write_text(conf_json)
+
+ # Create post commit dir
+ if not os.path.isdir(post_commit_dir):
+ os.makedirs(post_commit_dir)
+
+ # Symlink from helpers to post-commit
+ if not os.path.exists(post_commit_file):
+ os.symlink(post_commit_file_src, post_commit_file)
+
+ return None
+
+
+def apply(config):
+ return None
+
+
+if __name__ == '__main__':
+ try:
+ c = get_config()
+ verify(c)
+ generate(c)
+ apply(c)
+ except ConfigError as e:
+ print(e)
+ exit(1)
diff --git a/src/conf_mode/service_console-server.py b/src/conf_mode/service_console-server.py
index 60eff6543..7eb41ea87 100755
--- a/src/conf_mode/service_console-server.py
+++ b/src/conf_mode/service_console-server.py
@@ -22,7 +22,7 @@ from psutil import process_iter
from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.template import render
-from vyos.util import call
+from vyos.utils.process import call
from vyos.xml import defaults
from vyos import ConfigError
diff --git a/src/conf_mode/service_event_handler.py b/src/conf_mode/service_event_handler.py
index 5440d1056..5028ef52f 100755
--- a/src/conf_mode/service_event_handler.py
+++ b/src/conf_mode/service_event_handler.py
@@ -18,7 +18,8 @@ import json
from pathlib import Path
from vyos.config import Config
-from vyos.util import call, dict_search
+from vyos.utils.dict import dict_search
+from vyos.utils.process import call
from vyos import ConfigError
from vyos import airbag
diff --git a/src/conf_mode/service_ids_fastnetmon.py b/src/conf_mode/service_ids_fastnetmon.py
index c58f8db9a..2e678cf0b 100755
--- a/src/conf_mode/service_ids_fastnetmon.py
+++ b/src/conf_mode/service_ids_fastnetmon.py
@@ -21,7 +21,7 @@ from sys import exit
from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.template import render
-from vyos.util import call
+from vyos.utils.process import call
from vyos.xml import defaults
from vyos import ConfigError
from vyos import airbag
diff --git a/src/conf_mode/service_ipoe-server.py b/src/conf_mode/service_ipoe-server.py
index 95c72df47..b70e32373 100755
--- a/src/conf_mode/service_ipoe-server.py
+++ b/src/conf_mode/service_ipoe-server.py
@@ -24,8 +24,8 @@ from vyos.configdict import get_accel_dict
from vyos.configverify import verify_accel_ppp_base_service
from vyos.configverify import verify_interface_exists
from vyos.template import render
-from vyos.util import call
-from vyos.util import dict_search
+from vyos.utils.process import call
+from vyos.utils.dict import dict_search
from vyos import ConfigError
from vyos import airbag
airbag.enable()
diff --git a/src/conf_mode/service_mdns-repeater.py b/src/conf_mode/service_mdns-repeater.py
index 2383a53fb..a2c90b537 100755
--- a/src/conf_mode/service_mdns-repeater.py
+++ b/src/conf_mode/service_mdns-repeater.py
@@ -23,7 +23,7 @@ from netifaces import ifaddresses, interfaces, AF_INET
from vyos.config import Config
from vyos.ifconfig.vrrp import VRRP
from vyos.template import render
-from vyos.util import call
+from vyos.utils.process import call
from vyos import ConfigError
from vyos import airbag
airbag.enable()
diff --git a/src/conf_mode/service_monitoring_telegraf.py b/src/conf_mode/service_monitoring_telegraf.py
index 47510ce80..0269bedd9 100755
--- a/src/conf_mode/service_monitoring_telegraf.py
+++ b/src/conf_mode/service_monitoring_telegraf.py
@@ -27,9 +27,9 @@ from vyos.configdict import is_node_changed
from vyos.configverify import verify_vrf
from vyos.ifconfig import Section
from vyos.template import render
-from vyos.util import call
-from vyos.util import chown
-from vyos.util import cmd
+from vyos.utils.process import call
+from vyos.utils.permission import chown
+from vyos.utils.process import cmd
from vyos.xml import defaults
from vyos import ConfigError
from vyos import airbag
diff --git a/src/conf_mode/service_pppoe-server.py b/src/conf_mode/service_pppoe-server.py
index adeefaa37..aace267a7 100755
--- a/src/conf_mode/service_pppoe-server.py
+++ b/src/conf_mode/service_pppoe-server.py
@@ -24,8 +24,8 @@ from vyos.configdict import is_node_changed
from vyos.configverify import verify_accel_ppp_base_service
from vyos.configverify import verify_interface_exists
from vyos.template import render
-from vyos.util import call
-from vyos.util import dict_search
+from vyos.utils.process import call
+from vyos.utils.dict import dict_search
from vyos import ConfigError
from vyos import airbag
airbag.enable()
diff --git a/src/conf_mode/service_router-advert.py b/src/conf_mode/service_router-advert.py
index 1dd973d67..fe33c43ea 100755
--- a/src/conf_mode/service_router-advert.py
+++ b/src/conf_mode/service_router-advert.py
@@ -21,7 +21,7 @@ from vyos.base import Warning
from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.template import render
-from vyos.util import call
+from vyos.utils.process import call
from vyos.xml import defaults
from vyos import ConfigError
from vyos import airbag
diff --git a/src/conf_mode/service_sla.py b/src/conf_mode/service_sla.py
index b1e22f37b..54b72e029 100755
--- a/src/conf_mode/service_sla.py
+++ b/src/conf_mode/service_sla.py
@@ -21,7 +21,7 @@ from sys import exit
from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.template import render
-from vyos.util import call
+from vyos.utils.process import call
from vyos.xml import defaults
from vyos import ConfigError
from vyos import airbag
diff --git a/src/conf_mode/service_upnp.py b/src/conf_mode/service_upnp.py
index c798fd515..b37d502c2 100755
--- a/src/conf_mode/service_upnp.py
+++ b/src/conf_mode/service_upnp.py
@@ -24,7 +24,7 @@ from ipaddress import IPv6Network
from vyos.config import Config
from vyos.configdict import dict_merge
-from vyos.util import call
+from vyos.utils.process import call
from vyos.template import render
from vyos.template import is_ipv4
from vyos.template import is_ipv6
diff --git a/src/conf_mode/service_webproxy.py b/src/conf_mode/service_webproxy.py
index 658e496a6..bbdb756bd 100755
--- a/src/conf_mode/service_webproxy.py
+++ b/src/conf_mode/service_webproxy.py
@@ -22,10 +22,10 @@ from sys import exit
from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.template import render
-from vyos.util import call
-from vyos.util import chmod_755
-from vyos.util import dict_search
-from vyos.util import write_file
+from vyos.utils.process import call
+from vyos.utils.permission import chmod_755
+from vyos.utils.dict import dict_search
+from vyos.utils.file import write_file
from vyos.validate import is_addr_assigned
from vyos.xml import defaults
from vyos.base import Warning
diff --git a/src/conf_mode/snmp.py b/src/conf_mode/snmp.py
index 9b7c04eb0..0f0d97ac3 100755
--- a/src/conf_mode/snmp.py
+++ b/src/conf_mode/snmp.py
@@ -26,9 +26,9 @@ from vyos.snmpv3_hashgen import plaintext_to_md5
from vyos.snmpv3_hashgen import plaintext_to_sha1
from vyos.snmpv3_hashgen import random
from vyos.template import render
-from vyos.util import call
-from vyos.util import chmod_755
-from vyos.util import dict_search
+from vyos.utils.process import call
+from vyos.utils.permission import chmod_755
+from vyos.utils.dict import dict_search
from vyos.validate import is_addr_assigned
from vyos.version import get_version_data
from vyos.xml import defaults
@@ -161,8 +161,12 @@ def verify(snmp):
for address in snmp['listen_address']:
# We only wan't to configure addresses that exist on the system.
# Hint the user if they don't exist
- if not is_addr_assigned(address):
- Warning(f'SNMP listen address "{address}" not configured!')
+ if 'vrf' in snmp:
+ vrf_name = snmp['vrf']
+ if not is_addr_assigned(address, vrf_name) and address not in ['::1','127.0.0.1']:
+ raise ConfigError(f'SNMP listen address "{address}" not configured in vrf "{vrf_name}"!')
+ elif not is_addr_assigned(address):
+ raise ConfigError(f'SNMP listen address "{address}" not configured in default vrf!')
if 'trap_target' in snmp:
for trap, trap_config in snmp['trap_target'].items():
diff --git a/src/conf_mode/ssh.py b/src/conf_mode/ssh.py
index 8de0617af..3b63fcb7d 100755
--- a/src/conf_mode/ssh.py
+++ b/src/conf_mode/ssh.py
@@ -24,7 +24,7 @@ from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.configdict import is_node_changed
from vyos.configverify import verify_vrf
-from vyos.util import call
+from vyos.utils.process import call
from vyos.template import render
from vyos.xml import defaults
from vyos import ConfigError
diff --git a/src/conf_mode/system-ip.py b/src/conf_mode/system-ip.py
index 95865c690..cca996e4f 100755
--- a/src/conf_mode/system-ip.py
+++ b/src/conf_mode/system-ip.py
@@ -20,10 +20,10 @@ from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.configverify import verify_route_map
from vyos.template import render_to_string
-from vyos.util import call
-from vyos.util import dict_search
-from vyos.util import sysctl_write
-from vyos.util import write_file
+from vyos.utils.process import call
+from vyos.utils.dict import dict_search
+from vyos.utils.file import write_file
+from vyos.utils.system import sysctl_write
from vyos.xml import defaults
from vyos import ConfigError
from vyos import frr
diff --git a/src/conf_mode/system-ipv6.py b/src/conf_mode/system-ipv6.py
index b6d3a79c3..22210c27a 100755
--- a/src/conf_mode/system-ipv6.py
+++ b/src/conf_mode/system-ipv6.py
@@ -21,9 +21,9 @@ from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.configverify import verify_route_map
from vyos.template import render_to_string
-from vyos.util import dict_search
-from vyos.util import sysctl_write
-from vyos.util import write_file
+from vyos.utils.dict import dict_search
+from vyos.utils.system import sysctl_write
+from vyos.utils.file import write_file
from vyos.xml import defaults
from vyos import ConfigError
from vyos import frr
diff --git a/src/conf_mode/system-login-banner.py b/src/conf_mode/system-login-banner.py
index a521c9834..65fa04417 100755
--- a/src/conf_mode/system-login-banner.py
+++ b/src/conf_mode/system-login-banner.py
@@ -18,7 +18,7 @@ from sys import exit
from copy import deepcopy
from vyos.config import Config
-from vyos.util import write_file
+from vyos.utils.file import write_file
from vyos import ConfigError
from vyos import airbag
airbag.enable()
diff --git a/src/conf_mode/system-login.py b/src/conf_mode/system-login.py
index 24766a5b5..afd75913e 100755
--- a/src/conf_mode/system-login.py
+++ b/src/conf_mode/system-login.py
@@ -29,12 +29,12 @@ from vyos.configverify import verify_vrf
from vyos.defaults import directories
from vyos.template import render
from vyos.template import is_ipv4
-from vyos.util import cmd
-from vyos.util import call
-from vyos.util import rc_cmd
-from vyos.util import run
-from vyos.util import DEVNULL
-from vyos.util import dict_search
+from vyos.utils.dict import dict_search
+from vyos.utils.process import cmd
+from vyos.utils.process import call
+from vyos.utils.process import rc_cmd
+from vyos.utils.process import run
+from vyos.utils.process import DEVNULL
from vyos.xml import defaults
from vyos import ConfigError
from vyos import airbag
@@ -389,7 +389,7 @@ def apply(login):
# command until user is removed - userdel might return 8 as
# SSH sessions are not all yet properly cleaned away, thus we
# simply re-run the command until the account wen't away
- while run(f'userdel --remove {user}', stderr=DEVNULL):
+ while run(f'userdel {user}', stderr=DEVNULL):
sleep(0.250)
except Exception as e:
diff --git a/src/conf_mode/system-logs.py b/src/conf_mode/system-logs.py
index c71938a79..12145d641 100755
--- a/src/conf_mode/system-logs.py
+++ b/src/conf_mode/system-logs.py
@@ -22,7 +22,7 @@ from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.logger import syslog
from vyos.template import render
-from vyos.util import dict_search
+from vyos.utils.dict import dict_search
from vyos.xml import defaults
airbag.enable()
diff --git a/src/conf_mode/system-option.py b/src/conf_mode/system-option.py
index e6c7a0ed2..5172b492e 100755
--- a/src/conf_mode/system-option.py
+++ b/src/conf_mode/system-option.py
@@ -24,8 +24,8 @@ from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.configverify import verify_source_interface
from vyos.template import render
-from vyos.util import cmd
-from vyos.util import is_systemd_service_running
+from vyos.utils.process import cmd
+from vyos.utils.process import is_systemd_service_running
from vyos.validate import is_addr_assigned
from vyos.validate import is_intf_addr_assigned
from vyos.xml import defaults
diff --git a/src/conf_mode/system-syslog.py b/src/conf_mode/system-syslog.py
index cf34bad2e..19c87bcee 100755
--- a/src/conf_mode/system-syslog.py
+++ b/src/conf_mode/system-syslog.py
@@ -22,7 +22,7 @@ from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.configdict import is_node_changed
from vyos.configverify import verify_vrf
-from vyos.util import call
+from vyos.utils.process import call
from vyos.template import render
from vyos.xml import defaults
from vyos import ConfigError
@@ -46,6 +46,7 @@ def get_config(config=None):
get_first_key=True, no_tag_node_value_mangle=True)
syslog.update({ 'logrotate' : logrotate_conf })
+
tmp = is_node_changed(conf, base + ['vrf'])
if tmp: syslog.update({'restart_required': {}})
@@ -70,35 +71,22 @@ def get_config(config=None):
syslog['console']['facility'][facility])
# XXX: add defaults for "host" tree
- if 'host' in syslog:
- default_values_host = defaults(base + ['host'])
+ for syslog_type in ['host', 'user', 'file']:
+ # Bail out early if there is nothing to do
+ if syslog_type not in syslog:
+ continue
+
+ default_values_host = defaults(base + [syslog_type])
if 'facility' in default_values_host:
del default_values_host['facility']
- default_values_facility = defaults(base + ['host', 'facility'])
-
- for host, host_config in syslog['host'].items():
- syslog['host'][host] = dict_merge(default_values_host, syslog['host'][host])
- if 'facility' in host_config:
- for facility in host_config['facility']:
- syslog['host'][host]['facility'][facility] = dict_merge(default_values_facility,
- syslog['host'][host]['facility'][facility])
-
- # XXX: add defaults for "user" tree
- if 'user' in syslog:
- default_values = defaults(base + ['user', 'facility'])
- for user, user_config in syslog['user'].items():
- if 'facility' in user_config:
- for facility in user_config['facility']:
- syslog['user'][user]['facility'][facility] = dict_merge(default_values,
- syslog['user'][user]['facility'][facility])
-
- # XXX: add defaults for "file" tree
- if 'file' in syslog:
- default_values = defaults(base + ['file'])
- for file, file_config in syslog['file'].items():
- for facility in file_config['facility']:
- syslog['file'][file]['facility'][facility] = dict_merge(default_values,
- syslog['file'][file]['facility'][facility])
+
+ for tmp, tmp_config in syslog[syslog_type].items():
+ syslog[syslog_type][tmp] = dict_merge(default_values_host, syslog[syslog_type][tmp])
+ if 'facility' in tmp_config:
+ default_values_facility = defaults(base + [syslog_type, 'facility'])
+ for facility in tmp_config['facility']:
+ syslog[syslog_type][tmp]['facility'][facility] = dict_merge(default_values_facility,
+ syslog[syslog_type][tmp]['facility'][facility])
return syslog
diff --git a/src/conf_mode/system-timezone.py b/src/conf_mode/system-timezone.py
index 3d98ba774..cd3d4b229 100755
--- a/src/conf_mode/system-timezone.py
+++ b/src/conf_mode/system-timezone.py
@@ -20,7 +20,7 @@ import os
from copy import deepcopy
from vyos.config import Config
from vyos import ConfigError
-from vyos.util import call
+from vyos.utils.process import call
from vyos import airbag
airbag.enable()
diff --git a/src/conf_mode/system_console.py b/src/conf_mode/system_console.py
index e922edc4e..87d587959 100755
--- a/src/conf_mode/system_console.py
+++ b/src/conf_mode/system_console.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020 VyOS maintainers and contributors
+# Copyright (C) 2020-2023 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,9 +20,9 @@ from pathlib import Path
from vyos.config import Config
from vyos.configdict import dict_merge
-from vyos.util import call
-from vyos.util import read_file
-from vyos.util import write_file
+from vyos.utils.process import call
+from vyos.utils.file import read_file
+from vyos.utils.file import write_file
from vyos.template import render
from vyos.xml import defaults
from vyos import ConfigError
diff --git a/src/conf_mode/system_frr.py b/src/conf_mode/system_frr.py
index 1af0055f6..fb252238a 100755
--- a/src/conf_mode/system_frr.py
+++ b/src/conf_mode/system_frr.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2023 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
@@ -22,7 +22,9 @@ from vyos import airbag
from vyos.config import Config
from vyos.logger import syslog
from vyos.template import render_to_string
-from vyos.util import read_file, write_file, run
+from vyos.utils.file import read_file
+from vyos.utils.file import write_file
+from vyos.utils.process import run
airbag.enable()
# path to daemons config and config status files
diff --git a/src/conf_mode/system_lcd.py b/src/conf_mode/system_lcd.py
index 3341dd738..eb88224d1 100755
--- a/src/conf_mode/system_lcd.py
+++ b/src/conf_mode/system_lcd.py
@@ -19,8 +19,8 @@ import os
from sys import exit
from vyos.config import Config
-from vyos.util import call
-from vyos.util import find_device_file
+from vyos.utils.process import call
+from vyos.utils.system import find_device_file
from vyos.template import render
from vyos import ConfigError
from vyos import airbag
diff --git a/src/conf_mode/system_sflow.py b/src/conf_mode/system_sflow.py
index a0c3fca7f..9e3d41100 100755
--- a/src/conf_mode/system_sflow.py
+++ b/src/conf_mode/system_sflow.py
@@ -21,7 +21,7 @@ from sys import exit
from vyos.config import Config
from vyos.configdict import dict_merge
from vyos.template import render
-from vyos.util import call
+from vyos.utils.process import call
from vyos.validate import is_addr_assigned
from vyos.xml import defaults
from vyos import ConfigError
diff --git a/src/conf_mode/system_sysctl.py b/src/conf_mode/system_sysctl.py
index 2e0004ffa..f6b02023d 100755
--- a/src/conf_mode/system_sysctl.py
+++ b/src/conf_mode/system_sysctl.py
@@ -20,7 +20,7 @@ from sys import exit
from vyos.config import Config
from vyos.template import render
-from vyos.util import cmd
+from vyos.utils.process import cmd
from vyos import ConfigError
from vyos import airbag
airbag.enable()
diff --git a/src/conf_mode/system_update_check.py b/src/conf_mode/system_update_check.py
index 08ecfcb81..8d641a97d 100755
--- a/src/conf_mode/system_update_check.py
+++ b/src/conf_mode/system_update_check.py
@@ -22,7 +22,7 @@ from pathlib import Path
from sys import exit
from vyos.config import Config
-from vyos.util import call
+from vyos.utils.process import call
from vyos import ConfigError
from vyos import airbag
airbag.enable()
diff --git a/src/conf_mode/tftp_server.py b/src/conf_mode/tftp_server.py
index c5daccb7f..2735772dc 100755
--- a/src/conf_mode/tftp_server.py
+++ b/src/conf_mode/tftp_server.py
@@ -28,8 +28,8 @@ from vyos.configdict import dict_merge
from vyos.configverify import verify_vrf
from vyos.template import render
from vyos.template import is_ipv4
-from vyos.util import call
-from vyos.util import chmod_755
+from vyos.utils.process import call
+from vyos.utils.permission import chmod_755
from vyos.validate import is_addr_assigned
from vyos.xml import defaults
from vyos import ConfigError
diff --git a/src/conf_mode/vpn_ipsec.py b/src/conf_mode/vpn_ipsec.py
index b82d90e4d..b0825d0ee 100755
--- a/src/conf_mode/vpn_ipsec.py
+++ b/src/conf_mode/vpn_ipsec.py
@@ -40,10 +40,10 @@ from vyos.template import is_ipv4
from vyos.template import is_ipv6
from vyos.template import render
from vyos.validate import is_ipv6_link_local
-from vyos.util import call
-from vyos.util import dict_search
-from vyos.util import dict_search_args
-from vyos.util import run
+from vyos.utils.dict import dict_search
+from vyos.utils.dict import dict_search_args
+from vyos.utils.process import call
+from vyos.utils.process import run
from vyos.xml import defaults
from vyos import ConfigError
from vyos import airbag
diff --git a/src/conf_mode/vpn_l2tp.py b/src/conf_mode/vpn_l2tp.py
index ffac3b023..6232ce64a 100755
--- a/src/conf_mode/vpn_l2tp.py
+++ b/src/conf_mode/vpn_l2tp.py
@@ -26,10 +26,10 @@ from ipaddress import ip_network
from vyos.config import Config
from vyos.template import is_ipv4
from vyos.template import render
-from vyos.util import call
-from vyos.util import get_half_cpus
-from vyos.util import check_port_availability
-from vyos.util import is_listen_port_bind_service
+from vyos.utils.process import call
+from vyos.utils.system import get_half_cpus
+from vyos.utils.network import check_port_availability
+from vyos.utils.network import is_listen_port_bind_service
from vyos import ConfigError
from vyos import airbag
diff --git a/src/conf_mode/vpn_openconnect.py b/src/conf_mode/vpn_openconnect.py
index 3d5dc12a4..e82862fa3 100755
--- a/src/conf_mode/vpn_openconnect.py
+++ b/src/conf_mode/vpn_openconnect.py
@@ -23,11 +23,11 @@ from vyos.configdict import dict_merge
from vyos.pki import wrap_certificate
from vyos.pki import wrap_private_key
from vyos.template import render
-from vyos.util import call
-from vyos.util import check_port_availability
-from vyos.util import is_systemd_service_running
-from vyos.util import is_listen_port_bind_service
-from vyos.util import dict_search
+from vyos.utils.process import call
+from vyos.utils.network import check_port_availability
+from vyos.utils.process import is_systemd_service_running
+from vyos.utils.network import is_listen_port_bind_service
+from vyos.utils.dict import dict_search
from vyos.xml import defaults
from vyos import ConfigError
from passlib.hash import sha512_crypt
diff --git a/src/conf_mode/vpn_pptp.py b/src/conf_mode/vpn_pptp.py
index b9d18110a..d542f57fe 100755
--- a/src/conf_mode/vpn_pptp.py
+++ b/src/conf_mode/vpn_pptp.py
@@ -23,7 +23,8 @@ from sys import exit
from vyos.config import Config
from vyos.template import render
-from vyos.util import call, get_half_cpus
+from vyos.utils.system import get_half_cpus
+from vyos.utils.process import call
from vyos import ConfigError
from vyos import airbag
diff --git a/src/conf_mode/vpn_sstp.py b/src/conf_mode/vpn_sstp.py
index 2949ab290..e98d8385b 100755
--- a/src/conf_mode/vpn_sstp.py
+++ b/src/conf_mode/vpn_sstp.py
@@ -25,11 +25,11 @@ from vyos.configverify import verify_accel_ppp_base_service
from vyos.pki import wrap_certificate
from vyos.pki import wrap_private_key
from vyos.template import render
-from vyos.util import call
-from vyos.util import check_port_availability
-from vyos.util import dict_search
-from vyos.util import is_listen_port_bind_service
-from vyos.util import write_file
+from vyos.utils.process import call
+from vyos.utils.network import check_port_availability
+from vyos.utils.dict import dict_search
+from vyos.utils.network import is_listen_port_bind_service
+from vyos.utils.file import write_file
from vyos import ConfigError
from vyos import airbag
airbag.enable()
diff --git a/src/conf_mode/vpp.py b/src/conf_mode/vpp.py
index dc13f4e60..80ce1e8e3 100755
--- a/src/conf_mode/vpp.py
+++ b/src/conf_mode/vpp.py
@@ -15,7 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
-import psutil
+from psutil import virtual_memory
from pathlib import Path
from re import search as re_search, MULTILINE as re_M
@@ -25,7 +25,11 @@ from vyos.configdep import set_dependents, call_dependents
from vyos.configdict import dict_merge
from vyos.configdict import node_changed
from vyos.ifconfig import Section
-from vyos.util import call, rc_cmd, boot_configuration_complete
+from vyos.utils.boot import boot_configuration_complete
+from vyos.utils.process import call
+from vyos.utils.process import rc_cmd
+from vyos.utils.system import sysctl_read
+from vyos.utils.system import sysctl_apply
from vyos.template import render
from vyos.xml import defaults
@@ -39,10 +43,10 @@ airbag.enable()
service_name = 'vpp'
service_conf = Path(f'/run/vpp/{service_name}.conf')
systemd_override = '/run/systemd/system/vpp.service.d/10-override.conf'
-sysctl_vpp = '/etc/sysctl.d/80-vpp.conf'
-# Min memory 6GB (2GB reserved for vpp)
-MIN_TOTAL_MEMORY = 6
+# Free memory required for VPP
+# 2 GB for hugepages + 1 GB for other services
+MIN_AVAILABLE_MEMORY: int = 3 * 1024**3
def _get_pci_address_by_interface(iface) -> str:
@@ -64,7 +68,6 @@ def _get_pci_address_by_interface(iface) -> str:
raise ConfigError(f'Cannot find PCI address for interface {iface}')
-
def get_config(config=None):
if config:
conf = config
@@ -131,32 +134,45 @@ def verify(config):
return None
if 'interface' not in config:
- raise ConfigError(f'"interface" is required but not set!')
+ raise ConfigError('"interface" is required but not set!')
if 'cpu' in config:
- if 'corelist_workers' in config['cpu'] and 'main_core' not in config['cpu']:
- raise ConfigError(f'"cpu main-core" is required but not set!')
+ if 'corelist_workers' in config['cpu'] and 'main_core' not in config[
+ 'cpu']:
+ raise ConfigError('"cpu main-core" is required but not set!')
- memory = psutil.virtual_memory()
- memory_total = round(memory.total / (1024 ** 3), 2)
- if memory_total < MIN_TOTAL_MEMORY:
+ memory_available: int = virtual_memory().available
+ if memory_available < MIN_AVAILABLE_MEMORY:
raise ConfigError(
- f'Not enough installed memory {memory_total}GB! '
- f'The minimum required memory is {MIN_TOTAL_MEMORY}GB.'
- )
+ 'Not enough free memory to start VPP:\n'
+ f'available: {round(memory_available / 1024**3, 1)}GB\n'
+ f'required: {round(MIN_AVAILABLE_MEMORY / 1024**3, 1)}GB')
def generate(config):
if not config or (len(config) == 1 and 'removed_ifaces' in config):
# Remove old config and return
service_conf.unlink(missing_ok=True)
- if os.path.isfile(sysctl_vpp):
- os.unlink(sysctl_vpp)
return None
render(service_conf, 'vpp/startup.conf.j2', config)
render(systemd_override, 'vpp/override.conf.j2', config)
- render(sysctl_vpp, 'vpp/sysctl.conf.j2', config)
+
+ # apply default sysctl values from
+ # https://github.com/FDio/vpp/blob/v23.06/src/vpp/conf/80-vpp.conf
+ sysctl_config: dict[str, str] = {
+ 'vm.nr_hugepages': '1024',
+ 'vm.max_map_count': '3096',
+ 'vm.hugetlb_shm_group': '0',
+ 'kernel.shmmax': '2147483648'
+ }
+ # we do not want to reduce `kernel.shmmax`
+ kernel_shmnax_current: str = sysctl_read('kernel.shmmax')
+ if int(kernel_shmnax_current) > int(sysctl_config['kernel.shmmax']):
+ sysctl_config['kernel.shmmax'] = kernel_shmnax_current
+
+ if not sysctl_apply(sysctl_config):
+ raise ConfigError('Cannot configure sysctl parameters for VPP')
return None
@@ -168,8 +184,6 @@ def apply(config):
call('systemctl daemon-reload')
call(f'systemctl restart {service_name}.service')
- call(f'sysctl -qp {sysctl_vpp}')
-
# Initialize interfaces removed from VPP
for iface in config.get('removed_ifaces', []):
host_control = HostControl()
diff --git a/src/conf_mode/vrf.py b/src/conf_mode/vrf.py
index 0b983293e..be867b208 100755
--- a/src/conf_mode/vrf.py
+++ b/src/conf_mode/vrf.py
@@ -26,13 +26,13 @@ from vyos.configverify import verify_route_map
from vyos.ifconfig import Interface
from vyos.template import render
from vyos.template import render_to_string
-from vyos.util import call
-from vyos.util import cmd
-from vyos.util import dict_search
-from vyos.util import get_interface_config
-from vyos.util import popen
-from vyos.util import run
-from vyos.util import sysctl_write
+from vyos.utils.dict import dict_search
+from vyos.utils.network import get_interface_config
+from vyos.utils.process import call
+from vyos.utils.process import cmd
+from vyos.utils.process import popen
+from vyos.utils.process import run
+from vyos.utils.system import sysctl_write
from vyos import ConfigError
from vyos import frr
from vyos import airbag
diff --git a/src/conf_mode/vrf_vni.py b/src/conf_mode/vrf_vni.py
index 9f33536e5..23b341079 100644
--- a/src/conf_mode/vrf_vni.py
+++ b/src/conf_mode/vrf_vni.py
@@ -19,7 +19,7 @@ from sys import exit
from vyos.config import Config
from vyos.template import render_to_string
-from vyos.util import dict_search
+from vyos.utils.dict import dict_search
from vyos import ConfigError
from vyos import frr
from vyos import airbag
diff --git a/src/etc/dhcp/dhclient-exit-hooks.d/99-ipsec-dhclient-hook b/src/etc/dhcp/dhclient-exit-hooks.d/99-ipsec-dhclient-hook
index 1f1926e17..c7a92fe26 100755
--- a/src/etc/dhcp/dhclient-exit-hooks.d/99-ipsec-dhclient-hook
+++ b/src/etc/dhcp/dhclient-exit-hooks.d/99-ipsec-dhclient-hook
@@ -15,7 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
if [ "$reason" == "REBOOT" ] || [ "$reason" == "EXPIRE" ]; then
- exit 0
+ return 0
fi
DHCP_HOOK_IFLIST="/tmp/ipsec_dhcp_waiting"
@@ -24,22 +24,22 @@ if [ -f $DHCP_HOOK_IFLIST ] && [ "$reason" == "BOUND" ]; then
if grep -qw $interface $DHCP_HOOK_IFLIST; then
sudo rm $DHCP_HOOK_IFLIST
sudo /usr/libexec/vyos/conf_mode/vpn_ipsec.py
- exit 0
+ return 0
fi
fi
if [ "$old_ip_address" == "$new_ip_address" ] && [ "$reason" == "BOUND" ]; then
- exit 0
+ return 0
fi
python3 - <<PYEND
import os
import re
-from vyos.util import call
-from vyos.util import cmd
-from vyos.util import read_file
-from vyos.util import write_file
+from vyos.utils.process import call
+from vyos.utils.process import cmd
+from vyos.utils.file import read_file
+from vyos.utils.file import write_file
SWANCTL_CONF="/etc/swanctl/swanctl.conf"
@@ -83,4 +83,4 @@ if __name__ == '__main__':
call('sudo swanctl -q')
exit(0)
-PYEND \ No newline at end of file
+PYEND
diff --git a/src/etc/ipsec.d/vti-up-down b/src/etc/ipsec.d/vti-up-down
index 1ffb32955..9eb6fac48 100755
--- a/src/etc/ipsec.d/vti-up-down
+++ b/src/etc/ipsec.d/vti-up-down
@@ -25,9 +25,9 @@ from syslog import LOG_PID
from syslog import LOG_INFO
from vyos.configquery import ConfigTreeQuery
-from vyos.util import call
-from vyos.util import get_interface_config
-from vyos.util import get_interface_address
+from vyos.utils.process import call
+from vyos.utils.network import get_interface_config
+from vyos.utils.network import get_interface_address
if __name__ == '__main__':
verb = os.getenv('PLUTO_VERB')
diff --git a/src/etc/opennhrp/opennhrp-script.py b/src/etc/opennhrp/opennhrp-script.py
index 688c7af2a..f6f6d075c 100755
--- a/src/etc/opennhrp/opennhrp-script.py
+++ b/src/etc/opennhrp/opennhrp-script.py
@@ -23,8 +23,8 @@ from json import loads
from pathlib import Path
from vyos.logger import getLogger
-from vyos.util import cmd
-from vyos.util import process_named_running
+from vyos.utils.process import cmd
+from vyos.utils.process import process_named_running
NHRP_CONFIG: str = '/run/opennhrp/opennhrp.conf'
diff --git a/src/etc/systemd/system-generators/vyos-generator b/src/etc/systemd/system-generators/vyos-generator
new file mode 100755
index 000000000..34faab6a2
--- /dev/null
+++ b/src/etc/systemd/system-generators/vyos-generator
@@ -0,0 +1,94 @@
+#!/bin/sh
+set -f
+
+LOG=""
+DEBUG_LEVEL=1
+LOG_D="/run/vyos-router"
+ENABLE="enabled"
+DISABLE="disabled"
+FOUND="found"
+NOTFOUND="notfound"
+RUN_ENABLED_FILE="$LOG_D/$ENABLE"
+VYOS_SYSTEM_TARGET="/lib/systemd/system/vyos.target"
+VYOS_TARGET_NAME="vyos.target"
+
+debug() {
+ local lvl="$1"
+ shift
+ [ "$lvl" -gt "$DEBUG_LEVEL" ] && return
+ if [ -z "$LOG" ]; then
+ local log="$LOG_D/${0##*/}.log"
+ { [ -d "$LOG_D" ] || mkdir -p "$LOG_D"; } &&
+ { : > "$log"; } >/dev/null 2>&1 && LOG="$log" ||
+ LOG="/dev/kmsg"
+ fi
+ echo "$@" >> "$LOG"
+}
+
+default() {
+ _RET="$ENABLE"
+}
+
+main() {
+ local normal_d="$1" early_d="$2" late_d="$3"
+ local target_name="multi-user.target" gen_d="$early_d"
+ local link_path="$gen_d/${target_name}.wants/${VYOS_TARGET_NAME}"
+ local ds="$NOTFOUND"
+
+ debug 1 "$0 normal=$normal_d early=$early_d late=$late_d"
+ debug 2 "$0 $*"
+
+ local search result="error" ret=""
+ for search in default; do
+ if $search; then
+ debug 1 "$search found $_RET"
+ [ "$_RET" = "$ENABLE" -o "$_RET" = "$DISABLE" ] &&
+ result=$_RET && break
+ else
+ ret=$?
+ debug 0 "search $search returned $ret"
+ fi
+ done
+
+ # enable AND ds=found == enable
+ # enable AND ds=notfound == disable
+ # disable || <any> == disabled
+ if [ "$result" = "$ENABLE" ]; then
+ if [ -e "$link_path" ]; then
+ debug 1 "already enabled: no change needed"
+ else
+ [ -d "${link_path%/*}" ] || mkdir -p "${link_path%/*}" ||
+ debug 0 "failed to make dir $link_path"
+ if ln -snf "$VYOS_SYSTEM_TARGET" "$link_path"; then
+ debug 1 "enabled via $link_path -> $VYOS_SYSTEM_TARGET"
+ else
+ ret=$?
+ debug 0 "[$ret] enable failed:" \
+ "ln $VYOS_SYSTEM_TARGET $link_path"
+ fi
+ fi
+ : > "$RUN_ENABLED_FILE"
+ elif [ "$result" = "$DISABLE" ]; then
+ if [ -f "$link_path" ]; then
+ if rm -f "$link_path"; then
+ debug 1 "disabled. removed existing $link_path"
+ else
+ ret=$?
+ debug 0 "[$ret] disable failed, remove $link_path"
+ fi
+ else
+ debug 1 "already disabled: no change needed [no $link_path]"
+ fi
+ if [ -e "$RUN_ENABLED_FILE" ]; then
+ rm -f "$RUN_ENABLED_FILE"
+ fi
+ else
+ debug 0 "unexpected result '$result' 'ds=$ds'"
+ ret=3
+ fi
+ return $ret
+}
+
+main "$@"
+
+# vi: ts=4 expandtab
diff --git a/src/etc/systemd/system/getty@.service.d/aftervyos.conf b/src/etc/systemd/system/getty@.service.d/aftervyos.conf
new file mode 100644
index 000000000..c5753900e
--- /dev/null
+++ b/src/etc/systemd/system/getty@.service.d/aftervyos.conf
@@ -0,0 +1,3 @@
+[Service]
+ExecStartPre=-/usr/libexec/vyos/init/vyos-config
+StandardOutput=journal+console
diff --git a/src/etc/systemd/system/serial-getty@.service.d/aftervyos.conf b/src/etc/systemd/system/serial-getty@.service.d/aftervyos.conf
new file mode 100644
index 000000000..8ba42778d
--- /dev/null
+++ b/src/etc/systemd/system/serial-getty@.service.d/aftervyos.conf
@@ -0,0 +1,3 @@
+[Service]
+ExecStartPre=-/usr/libexec/vyos/init/vyos-config SERIAL
+StandardOutput=journal+console
diff --git a/src/etc/telegraf/custom_scripts/show_firewall_input_filter.py b/src/etc/telegraf/custom_scripts/show_firewall_input_filter.py
index d7eca5894..bb7515a90 100755
--- a/src/etc/telegraf/custom_scripts/show_firewall_input_filter.py
+++ b/src/etc/telegraf/custom_scripts/show_firewall_input_filter.py
@@ -4,7 +4,7 @@ import json
import re
import time
-from vyos.util import cmd
+from vyos.utils.process import cmd
def get_nft_filter_chains():
diff --git a/src/etc/telegraf/custom_scripts/vyos_services_input_filter.py b/src/etc/telegraf/custom_scripts/vyos_services_input_filter.py
index df4eed131..00f2f184c 100755
--- a/src/etc/telegraf/custom_scripts/vyos_services_input_filter.py
+++ b/src/etc/telegraf/custom_scripts/vyos_services_input_filter.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2023 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
@@ -17,7 +17,8 @@
import time
from vyos.configquery import ConfigTreeQuery
-from vyos.util import is_systemd_service_running, process_named_running
+from vyos.utils.process import is_systemd_service_running
+from vyos.utils.process import process_named_running
# Availible services and prouceses
# 1 - service
diff --git a/src/etc/vmware-tools/scripts/resume-vm-default.d/ether-resume.py b/src/etc/vmware-tools/scripts/resume-vm-default.d/ether-resume.py
index 4e7fb117c..7da57bca8 100755
--- a/src/etc/vmware-tools/scripts/resume-vm-default.d/ether-resume.py
+++ b/src/etc/vmware-tools/scripts/resume-vm-default.d/ether-resume.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2021 VyOS maintainers and contributors
+# Copyright (C) 2018-2023 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
@@ -17,9 +17,9 @@
import sys
import syslog
-from vyos.config import Config
from vyos import ConfigError
-from vyos.util import run
+from vyos.config import Config
+from vyos.utils.process import run
def get_config():
c = Config()
diff --git a/src/helpers/run-config-migration.py b/src/helpers/run-config-migration.py
index cc7166c22..ce647ad0a 100755
--- a/src/helpers/run-config-migration.py
+++ b/src/helpers/run-config-migration.py
@@ -20,7 +20,7 @@ import sys
import argparse
import datetime
-from vyos.util import cmd
+from vyos.utils.process import cmd
from vyos.migrator import Migrator, VirtualMigrator
def main():
diff --git a/src/helpers/vyos-boot-config-loader.py b/src/helpers/vyos-boot-config-loader.py
index b9cc87bfa..01b06526d 100755
--- a/src/helpers/vyos-boot-config-loader.py
+++ b/src/helpers/vyos-boot-config-loader.py
@@ -26,7 +26,7 @@ from datetime import datetime
from vyos.defaults import directories, config_status
from vyos.configsession import ConfigSession, ConfigSessionError
from vyos.configtree import ConfigTree
-from vyos.util import cmd
+from vyos.utils.process import cmd
STATUS_FILE = config_status
TRACE_FILE = '/tmp/boot-config-trace'
diff --git a/src/helpers/vyos-check-wwan.py b/src/helpers/vyos-check-wwan.py
index 2ff9a574f..334f08dd3 100755
--- a/src/helpers/vyos-check-wwan.py
+++ b/src/helpers/vyos-check-wwan.py
@@ -17,7 +17,7 @@
from vyos.configquery import VbashOpRun
from vyos.configquery import ConfigTreeQuery
-from vyos.util import is_wwan_connected
+from vyos.utils.network import is_wwan_connected
conf = ConfigTreeQuery()
dict = conf.get_config_dict(['interfaces', 'wwan'], key_mangling=('-', '_'),
diff --git a/src/helpers/vyos-domain-resolver.py b/src/helpers/vyos-domain-resolver.py
index e31d9238e..2036ca72e 100755
--- a/src/helpers/vyos-domain-resolver.py
+++ b/src/helpers/vyos-domain-resolver.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright (C) 2022-2023 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
@@ -22,10 +22,10 @@ from vyos.configdict import dict_merge
from vyos.configquery import ConfigTreeQuery
from vyos.firewall import fqdn_config_parse
from vyos.firewall import fqdn_resolve
-from vyos.util import cmd
-from vyos.util import commit_in_progress
-from vyos.util import dict_search_args
-from vyos.util import run
+from vyos.utils.commit import commit_in_progress
+from vyos.utils.dict import dict_search_args
+from vyos.utils.process import cmd
+from vyos.utils.process import run
from vyos.xml import defaults
base = ['firewall']
diff --git a/src/helpers/vyos-failover.py b/src/helpers/vyos-failover.py
index ce4cf8fa4..cc7610370 100755
--- a/src/helpers/vyos-failover.py
+++ b/src/helpers/vyos-failover.py
@@ -20,7 +20,7 @@ import subprocess
import socket
import time
-from vyos.util import rc_cmd
+from vyos.utils.process import rc_cmd
from pathlib import Path
from systemd import journal
diff --git a/src/helpers/vyos-interface-rescan.py b/src/helpers/vyos-interface-rescan.py
index 1ac1810e0..012357259 100755
--- a/src/helpers/vyos-interface-rescan.py
+++ b/src/helpers/vyos-interface-rescan.py
@@ -24,7 +24,7 @@ import netaddr
from vyos.configtree import ConfigTree
from vyos.defaults import directories
-from vyos.util import get_cfg_group_id
+from vyos.utils.permission import get_cfg_group_id
debug = False
diff --git a/src/helpers/vyos-merge-config.py b/src/helpers/vyos-merge-config.py
index 14df2734b..8997705fe 100755
--- a/src/helpers/vyos-merge-config.py
+++ b/src/helpers/vyos-merge-config.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-# Copyright 2019 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright 2019-2023 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
@@ -20,11 +20,12 @@ import os
import tempfile
import vyos.defaults
import vyos.remote
+
from vyos.config import Config
from vyos.configtree import ConfigTree
from vyos.migrator import Migrator, VirtualMigrator
-from vyos.util import cmd, DEVNULL
-
+from vyos.utils.process import cmd
+from vyos.utils.process import DEVNULL
if (len(sys.argv) < 2):
print("Need config file name to merge.")
diff --git a/src/helpers/vyos-sudo.py b/src/helpers/vyos-sudo.py
index 3e4c196d9..75dd7f29d 100755
--- a/src/helpers/vyos-sudo.py
+++ b/src/helpers/vyos-sudo.py
@@ -18,7 +18,7 @@
import os
import sys
-from vyos.util import is_admin
+from vyos.utils.permission import is_admin
if __name__ == '__main__':
diff --git a/src/helpers/vyos_config_sync.py b/src/helpers/vyos_config_sync.py
new file mode 100755
index 000000000..7cfa8fe88
--- /dev/null
+++ b/src/helpers/vyos_config_sync.py
@@ -0,0 +1,192 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2023 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/>.
+#
+#
+
+import os
+import json
+import requests
+import urllib3
+import logging
+from typing import Optional, List, Union, Dict, Any
+
+from vyos.config import Config
+from vyos.template import bracketize_ipv6
+
+
+CONFIG_FILE = '/run/config_sync_conf.conf'
+
+# Logging
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger(__name__)
+logger.name = os.path.basename(__file__)
+
+# API
+API_HEADERS = {'Content-Type': 'application/json'}
+
+
+def post_request(url: str,
+ data: str,
+ headers: Dict[str, str]) -> requests.Response:
+ """Sends a POST request to the specified URL
+
+ Args:
+ url (str): The URL to send the POST request to.
+ data (Dict[str, Any]): The data to send with the POST request.
+ headers (Dict[str, str]): The headers to include with the POST request.
+
+ Returns:
+ requests.Response: The response object representing the server's response to the request
+ """
+
+ response = requests.post(url,
+ data=data,
+ headers=headers,
+ verify=False,
+ timeout=timeout)
+ return response
+
+
+def retrieve_config(section: str = None) -> Optional[Dict[str, Any]]:
+ """Retrieves the configuration from the local server.
+
+ Args:
+ section: str: The section of the configuration to retrieve. Default is None.
+
+ Returns:
+ Optional[Dict[str, Any]]: The retrieved configuration as a dictionary, or None if an error occurred.
+ """
+ if section is None:
+ section = []
+ else:
+ section = section.split()
+
+ conf = Config()
+ config = conf.get_config_dict(section, get_first_key=True)
+ if config:
+ return config
+ return None
+
+
+def set_remote_config(
+ address: str,
+ key: str,
+ op: str,
+ path: str = None,
+ section: Optional[str] = None) -> Optional[Dict[str, Any]]:
+ """Loads the VyOS configuration in JSON format to a remote host.
+
+ Args:
+ address (str): The address of the remote host.
+ key (str): The key to use for loading the configuration.
+ path (Optional[str]): The path of the configuration. Default is None.
+ section (Optional[str]): The section of the configuration to load. Default is None.
+
+ Returns:
+ Optional[Dict[str, Any]]: The response from the remote host as a dictionary, or None if an error occurred.
+ """
+
+ if path is None:
+ path = []
+ else:
+ path = path.split()
+ headers = {'Content-Type': 'application/json'}
+
+ # Disable the InsecureRequestWarning
+ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
+
+ url = f'https://{address}/configure-section'
+ data = json.dumps({
+ 'op': mode,
+ 'path': path,
+ 'section': section,
+ 'key': key
+ })
+
+ try:
+ config = post_request(url, data, headers)
+ return config.json()
+ except requests.exceptions.RequestException as e:
+ print(f"An error occurred: {e}")
+ logger.error(f"An error occurred: {e}")
+ return None
+
+
+def is_section_revised(section: str) -> bool:
+ from vyos.config_mgmt import is_node_revised
+ return is_node_revised([section])
+
+
+def config_sync(secondary_address: str,
+ secondary_key: str,
+ sections: List[str],
+ mode: str):
+ """Retrieve a config section from primary router in JSON format and send it to
+ secondary router
+ """
+ # Config sync only if sections changed
+ if not any(map(is_section_revised, sections)):
+ return
+
+ logger.info(
+ f"Config synchronization: Mode={mode}, Secondary={secondary_address}"
+ )
+
+ # Sync sections ("nat", "firewall", etc)
+ for section in sections:
+ config_json = retrieve_config(section=section)
+ # Check if config path deesn't exist, for example "set nat"
+ # we set empty value for config_json data
+ # As we cannot send to the remote host section "nat None" config
+ if not config_json:
+ config_json = ""
+ logger.debug(
+ f"Retrieved config for section '{section}': {config_json}")
+ set_config = set_remote_config(address=secondary_address,
+ key=secondary_key,
+ op=mode,
+ path=section,
+ section=config_json)
+ logger.debug(f"Set config for section '{section}': {set_config}")
+
+
+if __name__ == '__main__':
+ # Read configuration from file
+ if not os.path.exists(CONFIG_FILE):
+ logger.error(f"Post-commit: No config file '{CONFIG_FILE}' exists")
+ exit(0)
+
+ with open(CONFIG_FILE, 'r') as f:
+ config_data = f.read()
+
+ config = json.loads(config_data)
+
+ mode = config.get('mode')
+ secondary_address = config.get('secondary', {}).get('address')
+ secondary_address = bracketize_ipv6(secondary_address)
+ secondary_key = config.get('secondary', {}).get('key')
+ sections = config.get('section')
+ timeout = int(config.get('secondary', {}).get('timeout'))
+
+ if not all([
+ mode, secondary_address, secondary_key, sections
+ ]):
+ logger.error(
+ "Missing required configuration data for config synchronization.")
+ exit(0)
+
+ config_sync(secondary_address, secondary_key,
+ sections, mode)
diff --git a/src/helpers/vyos_net_name b/src/helpers/vyos_net_name
index 1798e92db..8c0992414 100755
--- a/src/helpers/vyos_net_name
+++ b/src/helpers/vyos_net_name
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2023 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
@@ -13,8 +13,6 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-#
import os
import re
@@ -26,7 +24,8 @@ from sys import argv
from vyos.configtree import ConfigTree
from vyos.defaults import directories
-from vyos.util import cmd, boot_configuration_complete
+from vyos.utils.process import cmd
+from vyos.utils.boot import boot_configuration_complete
from vyos.migrator import VirtualMigrator
vyos_udev_dir = directories['vyos_udev_dir']
diff --git a/src/init/vyos-config b/src/init/vyos-config
new file mode 100755
index 000000000..356427024
--- /dev/null
+++ b/src/init/vyos-config
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+while [ ! -f /tmp/vyos-config-status ]
+do
+ sleep 1
+done
+
+status=$(cat /tmp/vyos-config-status)
+
+if [ -z "$1" ]; then
+ if [ $status -ne 0 ]; then
+ echo "Configuration error"
+ else
+ echo "Configuration success"
+ fi
+fi
diff --git a/src/init/vyos-router b/src/init/vyos-router
new file mode 100755
index 000000000..7b752b84b
--- /dev/null
+++ b/src/init/vyos-router
@@ -0,0 +1,421 @@
+#!/bin/bash
+# Copyright (C) 2021 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/>.
+
+. /lib/lsb/init-functions
+
+: ${vyatta_env:=/etc/default/vyatta}
+source $vyatta_env
+
+declare progname=${0##*/}
+declare action=$1; shift
+
+declare -x BOOTFILE=$vyatta_sysconfdir/config/config.boot
+
+# If vyos-config= boot option is present, use that file instead
+for x in $(cat /proc/cmdline); do
+ [[ $x = vyos-config=* ]] || continue
+ VYOS_CONFIG="${x#vyos-config=}"
+done
+
+if [ ! -z "$VYOS_CONFIG" ]; then
+ if [ -r "$VYOS_CONFIG" ]; then
+ echo "Config selected manually: $VYOS_CONFIG"
+ declare -x BOOTFILE="$VYOS_CONFIG"
+ else
+ echo "WARNING: Could not read selected config file, using default!"
+ fi
+fi
+
+declare -a subinit
+declare -a all_subinits=( firewall )
+
+if [ $# -gt 0 ] ; then
+ for s in $@ ; do
+ [ -x ${vyatta_sbindir}/${s}.init ] && subinit[${#subinit}]=$s
+ done
+else
+ for s in ${all_subinits[@]} ; do
+ [ -x ${vyatta_sbindir}/${s}.init ] && subinit[${#subinit}]=$s
+ done
+fi
+
+GROUP=vyattacfg
+
+# easy way to make empty file without any command
+empty()
+{
+ >$1
+}
+
+# check if bootup of this portion is disabled
+disabled () {
+ grep -q -w no-vyos-$1 /proc/cmdline
+}
+
+# if necessary, provide initial config
+init_bootfile () {
+ if [ ! -r $BOOTFILE ] ; then
+ if [ -f $vyatta_sysconfdir/config.boot.default ]; then
+ cp $vyatta_sysconfdir/config.boot.default $BOOTFILE
+ else
+ $vyos_libexec_dir/system-versions-foot.py > $BOOTFILE
+ fi
+ chgrp ${GROUP} $BOOTFILE
+ chmod 660 $BOOTFILE
+ fi
+}
+
+# if necessary, migrate initial config
+migrate_bootfile ()
+{
+ if [ -x $vyos_libexec_dir/run-config-migration.py ]; then
+ log_progress_msg migrate
+ sg ${GROUP} -c "$vyos_libexec_dir/run-config-migration.py $BOOTFILE"
+ fi
+}
+
+# load the initial config
+load_bootfile ()
+{
+ log_progress_msg configure
+ (
+ if [ -f /etc/default/vyatta-load-boot ]; then
+ # build-specific environment for boot-time config loading
+ source /etc/default/vyatta-load-boot
+ fi
+ if [ -x $vyos_libexec_dir/vyos-boot-config-loader.py ]; then
+ sg ${GROUP} -c "$vyos_libexec_dir/vyos-boot-config-loader.py $BOOTFILE"
+ fi
+ )
+}
+
+# execute the pre-config script
+run_preconfig_script ()
+{
+ if [ -x $vyatta_sysconfdir/config/scripts/vyos-preconfig-bootup.script ]; then
+ $vyatta_sysconfdir/config/scripts/vyos-preconfig-bootup.script
+ fi
+}
+
+# execute the post-config scripts
+run_postconfig_scripts ()
+{
+ if [ -x $vyatta_sysconfdir/config/scripts/vyatta-postconfig-bootup.script ]; then
+ $vyatta_sysconfdir/config/scripts/vyatta-postconfig-bootup.script
+ fi
+ if [ -x $vyatta_sysconfdir/config/scripts/vyos-postconfig-bootup.script ]; then
+ $vyatta_sysconfdir/config/scripts/vyos-postconfig-bootup.script
+ fi
+}
+
+run_postupgrade_script ()
+{
+ if [ -f $vyatta_sysconfdir/config/.upgraded ]; then
+ # Run the system script
+ /usr/libexec/vyos/system/post-upgrade
+
+ # Run user scripts
+ if [ -d $vyatta_sysconfdir/config/scripts/post-upgrade.d ]; then
+ run-parts $vyatta_sysconfdir/config/scripts/post-upgrade.d
+ fi
+ rm -f $vyatta_sysconfdir/config/.upgraded
+ fi
+}
+
+#
+# On image booted machines, we need to mount /boot from the image-specific
+# boot directory so that kernel package installation will put the
+# files in the right place. We also have to mount /boot/grub from the
+# system-wide grub directory so that tools that edit the grub.cfg
+# file will find it in the expected location.
+#
+bind_mount_boot ()
+{
+ persist_path=$(/opt/vyatta/sbin/vyos-persistpath)
+ if [ $? == 0 ]; then
+ if [ -e $persist_path/boot ]; then
+ image_name=$(cat /proc/cmdline | sed -e s+^.*vyos-union=/boot/++ | sed -e 's/ .*$//')
+
+ if [ -n "$image_name" ]; then
+ mount --bind $persist_path/boot/$image_name /boot
+ if [ $? -ne 0 ]; then
+ echo "Couldn't bind mount /boot"
+ fi
+
+ if [ ! -d /boot/grub ]; then
+ mkdir /boot/grub
+ fi
+
+ mount --bind $persist_path/boot/grub /boot/grub
+ if [ $? -ne 0 ]; then
+ echo "Couldn't bind mount /boot/grub"
+ fi
+ fi
+ fi
+ fi
+}
+
+clear_or_override_config_files ()
+{
+ for conf in snmp/snmpd.conf snmp/snmptrapd.conf snmp/snmp.conf \
+ keepalived/keepalived.conf cron.d/vyos-crontab \
+ ipvsadm.rules default/ipvsadm resolv.conf
+ do
+ if [ -s /etc/$conf ] ; then
+ empty /etc/$conf
+ chmod 0644 /etc/$conf
+ fi
+ done
+}
+
+update_interface_config ()
+{
+ if [ -d /run/udev/vyos ]; then
+ $vyos_libexec_dir/vyos-interface-rescan.py $BOOTFILE
+ fi
+}
+
+cleanup_post_commit_hooks () {
+ # Remove links from the post-commit hooks directory.
+ # note that this approach only supports hooks that are "configured",
+ # i.e., it does not support hooks that need to always be present.
+ cpostdir=$(cli-shell-api getPostCommitHookDir)
+ # exclude commits hooks from vyatta-cfg
+ excluded="10vyatta-log-commit.pl 99vyos-user-postcommit-hooks"
+ if [ -d "$cpostdir" ]; then
+ for f in $cpostdir/*; do
+ if [[ ! $excluded =~ $(basename $f) ]]; then
+ rm -f $cpostdir/$(basename $f)
+ fi
+ done
+ fi
+}
+
+# These are all the default security setting which are later
+# overridden when configuration is read. These are the values the
+# system defaults.
+security_reset ()
+{
+ # restore PAM back to virgin state (no radius/tacacs services)
+ pam-auth-update --package --remove radius
+ rm -f /etc/pam_radius_auth.conf
+ pam-auth-update --package --remove tacplus
+ rm -f /etc/tacplus_nss.conf /etc/tacplus_servers
+
+ # Certain configuration files are re-generated by the configuration
+ # subsystem and must reside under /etc and can not easily be moved to /run.
+ # So on every boot we simply delete any remaining files and let the CLI
+ # regenearte them.
+
+ # PPPoE
+ rm -f /etc/ppp/peers/pppoe* /etc/ppp/peers/wlm*
+
+ # IPSec
+ rm -rf /etc/ipsec.conf /etc/ipsec.secrets
+ find /etc/swanctl -type f | xargs rm -f
+
+ # limit cleanup
+ rm -f /etc/security/limits.d/10-vyos.conf
+
+ # iproute2 cleanup
+ rm -f /etc/iproute2/rt_tables.d/vyos-*.conf
+
+ # Container
+ rm -f /etc/containers/storage.conf /etc/containers/registries.conf /etc/containers/containers.conf
+ # Clean all networks and re-create them from our CLI
+ rm -f /etc/containers/networks/*
+
+ # System Options (SSH/cURL)
+ rm -f /etc/ssh/ssh_config.d/*vyos*.conf
+ rm -f /etc/curlrc
+}
+
+# XXX: T3885 - generate persistend DHCPv6 DUID (Type4 - UUID based)
+gen_duid ()
+{
+ DUID_FILE="/var/lib/dhcpv6/dhcp6c_duid"
+ UUID_FILE="/sys/class/dmi/id/product_uuid"
+ UUID_FILE_ALT="/sys/class/dmi/id/product_serial"
+ if [ ! -f ${UUID_FILE} ] && [ ! -f ${UUID_FILE_ALT} ]; then
+ return 1
+ fi
+
+ # DUID is based on the BIOS/EFI UUID. We omit additional - characters
+ if [ -f ${UUID_FILE} ]; then
+ UUID=$(cat ${UUID_FILE} | tr -d -)
+ fi
+ if [ -z ${UUID} ]; then
+ UUID=$(uuidgen --sha1 --namespace @dns --name $(cat ${UUID_FILE_ALT}) | tr -d -)
+ fi
+ # Add DUID type4 (UUID) information
+ DUID_TYPE="0004"
+
+ # The length-information (as per RFC6355 UUID is 128 bits long) is in big-endian
+ # format - beware when porting to ARM64. The length field consists out of the
+ # UUID (128 bit + 16 bits DUID type) resulting in hex 12.
+ DUID_LEN="0012"
+ if [ "$(echo -n I | od -to2 | head -n1 | cut -f2 -d" " | cut -c6 )" -eq 1 ]; then
+ # true on little-endian (x86) systems
+ DUID_LEN="1200"
+ fi
+
+ for i in $(echo -n ${DUID_LEN}${DUID_TYPE}${UUID} | sed 's/../& /g'); do
+ echo -ne "\x$i"
+ done > ${DUID_FILE}
+}
+
+start ()
+{
+ # reset and clean config files
+ security_reset || log_failure_msg "security reset failed"
+
+ # some legacy directories migrated over from old rl-system.init
+ mkdir -p /var/run/vyatta /var/log/vyatta
+ chgrp vyattacfg /var/run/vyatta /var/log/vyatta
+ chmod 775 /var/run/vyatta /var/log/vyatta
+
+ log_daemon_msg "Waiting for NICs to settle down"
+ # On boot time udev migth take a long time to reorder nic's, this will ensure that
+ # all udev activity is completed and all nics presented at boot-time will have their
+ # final name before continuing with vyos-router initialization.
+ SECONDS=0
+ udevadm settle
+ STATUS=$?
+ log_progress_msg "settled in ${SECONDS}sec."
+ log_end_msg ${STATUS}
+
+ # mountpoint for bpf maps required by xdp
+ mount -t bpf none /sys/fs/bpf
+
+ # Clear out Debian APT source config file
+ empty /etc/apt/sources.list
+
+ # Generate DHCPv6 DUID
+ gen_duid || log_failure_msg "could not generate DUID"
+
+ # Mount a temporary filesystem for container networks.
+ # Configuration should be loaded from VyOS cli.
+ cni_dir="/etc/cni/net.d"
+ [ ! -d ${cni_dir} ] && mkdir -p ${cni_dir}
+ mount -t tmpfs none ${cni_dir}
+
+ # Init firewall
+ nfct helper add rpc inet tcp
+ nfct helper add rpc inet udp
+ nfct helper add tns inet tcp
+ nft -f /usr/share/vyos/vyos-firewall-init.conf || log_failure_msg "could not initiate firewall rules"
+
+ rm -f /etc/hostname
+ ${vyos_conf_scripts_dir}/host_name.py || log_failure_msg "could not reset host-name"
+ systemctl start frr.service
+
+ # As VyOS does not execute commands that are not present in the CLI we call
+ # the script by hand to have a single source for the login banner and MOTD
+ ${vyos_conf_scripts_dir}/system_console.py || log_failure_msg "could not reset serial console"
+ ${vyos_conf_scripts_dir}/system-login.py || log_failure_msg "could not reset system login"
+ ${vyos_conf_scripts_dir}/system-login-banner.py || log_failure_msg "could not reset motd and issue files"
+ ${vyos_conf_scripts_dir}/system-option.py || log_failure_msg "could not reset system option files"
+ ${vyos_conf_scripts_dir}/conntrack.py || log_failure_msg "could not reset conntrack subsystem"
+ ${vyos_conf_scripts_dir}/container.py || log_failure_msg "could not reset container subsystem"
+
+ clear_or_override_config_files || log_failure_msg "could not reset config files"
+
+ # enable some debugging before loading the configuration
+ if grep -q vyos-debug /proc/cmdline; then
+ log_action_begin_msg "Enable runtime debugging options"
+ touch /tmp/vyos.container.debug
+ touch /tmp/vyos.ifconfig.debug
+ touch /tmp/vyos.frr.debug
+ touch /tmp/vyos.container.debug
+ fi
+
+ log_action_begin_msg "Mounting VyOS Config"
+ # ensure the vyatta_configdir supports a large number of inodes since
+ # the config hierarchy is often inode-bound (instead of size).
+ # impose a minimum and then scale up dynamically with the actual size
+ # of the system memory.
+ local tmem=$(sed -n 's/^MemTotal: \+\([0-9]\+\) kB$/\1/p' /proc/meminfo)
+ local tpages
+ local tmpfs_opts="nosuid,nodev,mode=775,nr_inodes=0" #automatically allocate inodes
+ mount -o $tmpfs_opts -t tmpfs none ${vyatta_configdir} \
+ && chgrp ${GROUP} ${vyatta_configdir}
+ log_action_end_msg $?
+
+ disabled bootfile || init_bootfile
+
+ cleanup_post_commit_hooks
+
+ log_daemon_msg "Starting VyOS router"
+ disabled migrate || migrate_bootfile
+
+ run_preconfig_script
+
+ run_postupgrade_script
+
+ update_interface_config
+
+ for s in ${subinit[@]} ; do
+ if ! disabled $s; then
+ log_progress_msg $s
+ if ! ${vyatta_sbindir}/${s}.init start
+ then log_failure_msg
+ exit 1
+ fi
+ fi
+ done
+
+ bind_mount_boot
+
+ disabled configure || load_bootfile
+ log_end_msg $?
+
+ telinit q
+ chmod g-w,o-w /
+
+ run_postconfig_scripts
+}
+
+stop()
+{
+ local -i status=0
+ log_daemon_msg "Stopping VyOS router"
+ for ((i=${#sub_inits[@]} - 1; i >= 0; i--)) ; do
+ s=${subinit[$i]}
+ log_progress_msg $s
+ ${vyatta_sbindir}/${s}.init stop
+ let status\|=$?
+ done
+ log_end_msg $status
+ log_action_begin_msg "Un-mounting VyOS Config"
+ umount ${vyatta_configdir}
+ log_action_end_msg $?
+
+ systemctl stop frr.service
+}
+
+case "$action" in
+ start) start ;;
+ stop) stop ;;
+ restart|force-reload) stop && start ;;
+ *) log_failure_msg "usage: $progname [ start|stop|restart ] [ subinit ... ]" ;
+ false ;;
+esac
+
+exit $?
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 4
+# End:
diff --git a/src/migration-scripts/container/0-to-1 b/src/migration-scripts/container/0-to-1
index d0461389b..86f89ee04 100755
--- a/src/migration-scripts/container/0-to-1
+++ b/src/migration-scripts/container/0-to-1
@@ -21,7 +21,7 @@ import shutil
import sys
from vyos.configtree import ConfigTree
-from vyos.util import call
+from vyos.utils.process import call
if (len(sys.argv) < 1):
print("Must specify file name!")
@@ -39,12 +39,12 @@ config = ConfigTree(config_file)
if config.exists(base):
for container in config.list_nodes(base):
# Stop any given container first
- call(f'systemctl stop vyos-container-{container}.service')
+ call(f'sudo systemctl stop vyos-container-{container}.service')
# Export container image for later re-import to new filesystem. We store
# the backup on a real disk as a tmpfs (like /tmp) could probably lack
# memory if a host has too many containers stored.
image_name = config.return_value(base + [container, 'image'])
- call(f'podman image save --quiet --output /root/{container}.tar --format oci-archive {image_name}')
+ call(f'sudo podman image save --quiet --output /root/{container}.tar --format oci-archive {image_name}')
# No need to adjust the strage driver online (this is only used for testing and
# debugging on a live system) - it is already overlay2 when the migration script
@@ -66,10 +66,10 @@ if config.exists(base):
# Export container image for later re-import to new filesystem
image_name = config.return_value(base + [container, 'image'])
image_path = f'/root/{container}.tar'
- call(f'podman image load --quiet --input {image_path}')
+ call(f'sudo podman image load --quiet --input {image_path}')
# Start any given container first
- call(f'systemctl start vyos-container-{container}.service')
+ call(f'sudo systemctl start vyos-container-{container}.service')
# Delete temporary container image
if os.path.exists(image_path):
diff --git a/src/migration-scripts/interfaces/24-to-25 b/src/migration-scripts/interfaces/24-to-25
index 4095f2a3e..f3a1dc464 100755
--- a/src/migration-scripts/interfaces/24-to-25
+++ b/src/migration-scripts/interfaces/24-to-25
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2023 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
@@ -19,6 +19,7 @@
import os
import sys
+
from vyos.configtree import ConfigTree
from vyos.pki import CERT_BEGIN
from vyos.pki import load_certificate
@@ -29,7 +30,7 @@ from vyos.pki import encode_certificate
from vyos.pki import encode_dh_parameters
from vyos.pki import encode_private_key
from vyos.pki import verify_crl
-from vyos.util import run
+from vyos.utils.process import run
def wrapped_pem_to_config_value(pem):
out = []
@@ -241,7 +242,7 @@ if config.exists(base):
config.set(pki_base + ['certificate', pki_name, 'private', 'key'], value=wrapped_pem_to_config_value(key_pem))
else:
print(f'Failed to migrate private key on openvpn interface {interface}')
-
+
config.delete(x509_base + ['key-file'])
if config.exists(x509_base + ['dh-file']):
@@ -276,7 +277,7 @@ base = ['interfaces', 'wireguard']
if config.exists(base):
for interface in config.list_nodes(base):
private_key_path = base + [interface, 'private-key']
-
+
key_file = 'default'
if config.exists(private_key_path):
key_file = config.return_value(private_key_path)
@@ -375,7 +376,7 @@ if config.exists(base):
config.set(pki_base + ['certificate', pki_name, 'private', 'key'], value=wrapped_pem_to_config_value(key_pem))
else:
print(f'Failed to migrate private key on eapol config for interface {interface}')
-
+
config.delete(x509_base + ['key-file'])
try:
diff --git a/src/migration-scripts/interfaces/7-to-8 b/src/migration-scripts/interfaces/7-to-8
index a4051301f..9845098a7 100755
--- a/src/migration-scripts/interfaces/7-to-8
+++ b/src/migration-scripts/interfaces/7-to-8
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020 VyOS maintainers and contributors
+# Copyright (C) 2020-2023 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
@@ -21,7 +21,8 @@ import os
from sys import exit, argv
from vyos.configtree import ConfigTree
-from vyos.util import chown, chmod_750
+from vyos.utils.permission import chown
+from vyos.utils.permission import chmod_750
def migrate_default_keys():
kdir = r'/config/auth/wireguard'
diff --git a/src/migration-scripts/ipsec/6-to-7 b/src/migration-scripts/ipsec/6-to-7
index 788a87095..649a18cb3 100755
--- a/src/migration-scripts/ipsec/6-to-7
+++ b/src/migration-scripts/ipsec/6-to-7
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2023 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
@@ -27,7 +27,7 @@ from vyos.pki import load_crl
from vyos.pki import load_private_key
from vyos.pki import encode_certificate
from vyos.pki import encode_private_key
-from vyos.util import run
+from vyos.utils.process import run
if (len(argv) < 1):
print("Must specify file name!")
@@ -127,7 +127,7 @@ if config.exists(ipsec_site_base):
config.set(pki_base + ['ca', pki_name, 'crl'], value=wrapped_pem_to_config_value(crl_pem))
else:
print(f'Failed to migrate CRL on peer "{peer}"')
-
+
config.delete(peer_x509_base + ['crl-file'])
if config.exists(peer_x509_base + ['key', 'file']):
@@ -157,7 +157,7 @@ if config.exists(ipsec_site_base):
config.set(peer_x509_base + ['private-key-passphrase'], value=key_passphrase)
else:
print(f'Failed to migrate private key on peer "{peer}"')
-
+
config.delete(peer_x509_base + ['key'])
if changes_made:
diff --git a/src/migration-scripts/l2tp/3-to-4 b/src/migration-scripts/l2tp/3-to-4
index 18eabadec..ee6079864 100755
--- a/src/migration-scripts/l2tp/3-to-4
+++ b/src/migration-scripts/l2tp/3-to-4
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2023 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
@@ -27,7 +27,7 @@ from vyos.pki import load_crl
from vyos.pki import load_private_key
from vyos.pki import encode_certificate
from vyos.pki import encode_private_key
-from vyos.util import run
+from vyos.utils.process import run
if (len(argv) < 1):
print("Must specify file name!")
@@ -156,7 +156,7 @@ if config.exists(x509_base + ['server-key-file']):
config.set(x509_base + ['private-key-passphrase'], value=key_passphrase)
else:
print(f'Failed to migrate private key on l2tp remote-access config')
-
+
config.delete(x509_base + ['server-key-file'])
if config.exists(x509_base + ['server-key-password']):
config.delete(x509_base + ['server-key-password'])
diff --git a/src/migration-scripts/openconnect/0-to-1 b/src/migration-scripts/openconnect/0-to-1
index 83cd09143..b26023a5b 100755
--- a/src/migration-scripts/openconnect/0-to-1
+++ b/src/migration-scripts/openconnect/0-to-1
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2023 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
@@ -26,7 +26,7 @@ from vyos.pki import load_crl
from vyos.pki import load_private_key
from vyos.pki import encode_certificate
from vyos.pki import encode_private_key
-from vyos.util import run
+from vyos.utils.process import run
if (len(argv) < 1):
print("Must specify file name!")
@@ -125,7 +125,7 @@ if config.exists(x509_base + ['key-file']):
config.set(pki_base + ['certificate', pki_name, 'private', 'key'], value=wrapped_pem_to_config_value(key_pem))
else:
print(f'Failed to migrate private key on openconnect config')
-
+
config.delete(x509_base + ['key-file'])
try:
diff --git a/src/migration-scripts/policy/3-to-4 b/src/migration-scripts/policy/3-to-4
index bae30cffc..49e0b4c38 100755
--- a/src/migration-scripts/policy/3-to-4
+++ b/src/migration-scripts/policy/3-to-4
@@ -51,7 +51,7 @@ def community_migrate(config: ConfigTree, rule: list[str]) -> bool:
:rtype: bool
"""
community_list = list((config.return_value(rule)).split(" "))
- config.delete(rule)
+
if 'none' in community_list:
config.set(rule + ['none'])
return False
@@ -61,8 +61,10 @@ def community_migrate(config: ConfigTree, rule: list[str]) -> bool:
community_action = 'add'
community_list.remove('additive')
for community in community_list:
- config.set(rule + [community_action], value=community,
- replace=False)
+ if len(community):
+ config.set(rule + [community_action], value=community,
+ replace=False)
+ config.delete(rule)
if community_action == 'replace':
return False
else:
diff --git a/src/migration-scripts/qos/1-to-2 b/src/migration-scripts/qos/1-to-2
index 14d3a6e0a..a689bacc5 100755
--- a/src/migration-scripts/qos/1-to-2
+++ b/src/migration-scripts/qos/1-to-2
@@ -18,7 +18,7 @@ from sys import argv,exit
from vyos.base import Warning
from vyos.configtree import ConfigTree
-from vyos.util import read_file
+from vyos.utils.file import read_file
def bandwidth_percent_to_val(interface, percent) -> int:
speed = read_file(f'/sys/class/net/{interface}/speed')
diff --git a/src/migration-scripts/sstp/3-to-4 b/src/migration-scripts/sstp/3-to-4
index 0568f043f..ea814fdc5 100755
--- a/src/migration-scripts/sstp/3-to-4
+++ b/src/migration-scripts/sstp/3-to-4
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2023 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
@@ -26,7 +26,7 @@ from vyos.pki import load_crl
from vyos.pki import load_private_key
from vyos.pki import encode_certificate
from vyos.pki import encode_private_key
-from vyos.util import run
+from vyos.utils.process import run
if (len(argv) < 1):
print("Must specify file name!")
@@ -125,7 +125,7 @@ if config.exists(x509_base + ['key-file']):
config.set(pki_base + ['certificate', pki_name, 'private', 'key'], value=wrapped_pem_to_config_value(key_pem))
else:
print(f'Failed to migrate private key on sstp config')
-
+
config.delete(x509_base + ['key-file'])
try:
diff --git a/src/migration-scripts/system/13-to-14 b/src/migration-scripts/system/13-to-14
index 5b068f4fc..1751f1865 100755
--- a/src/migration-scripts/system/13-to-14
+++ b/src/migration-scripts/system/13-to-14
@@ -12,7 +12,7 @@ import re
import sys
from vyos.configtree import ConfigTree
-from vyos.util import cmd
+from vyos.utils.process import cmd
if (len(sys.argv) < 1):
diff --git a/src/migration-scripts/vrrp/3-to-4 b/src/migration-scripts/vrrp/3-to-4
new file mode 100755
index 000000000..b0a6975c2
--- /dev/null
+++ b/src/migration-scripts/vrrp/3-to-4
@@ -0,0 +1,51 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2023 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/>.
+
+from sys import argv
+from vyos.configtree import ConfigTree
+
+if (len(argv) < 1):
+ print('Must specify file name!')
+ exit(1)
+
+file_name = argv[1]
+
+with open(file_name, 'r') as f:
+ config_file = f.read()
+
+base = ['high-availability', 'virtual-server']
+config = ConfigTree(config_file)
+
+if not config.exists(base):
+ # Nothing to do
+ exit(0)
+
+if config.exists(base):
+ for vs in config.list_nodes(base):
+ vs_base = base + [vs]
+
+ # If the fwmark is used, the address is not required
+ if not config.exists(vs_base + ['fwmark']):
+ # add option: 'virtual-server <tag> address x.x.x.x'
+ config.set(vs_base + ['address'], value=vs)
+
+
+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/op_mode/accelppp.py b/src/op_mode/accelppp.py
index 00de45fc8..67ce786d0 100755
--- a/src/op_mode/accelppp.py
+++ b/src/op_mode/accelppp.py
@@ -21,7 +21,7 @@ import vyos.accel_ppp
import vyos.opmode
from vyos.configquery import ConfigTreeQuery
-from vyos.util import rc_cmd
+from vyos.utils.process import rc_cmd
accel_dict = {
diff --git a/src/op_mode/bgp.py b/src/op_mode/bgp.py
index af9ea788b..096113cb4 100755
--- a/src/op_mode/bgp.py
+++ b/src/op_mode/bgp.py
@@ -81,7 +81,7 @@ ArgFamily = typing.Literal['inet', 'inet6', 'l2vpn']
ArgFamilyModifier = typing.Literal['unicast', 'labeled_unicast', 'multicast', 'vpn', 'flowspec']
def show_summary(raw: bool):
- from vyos.util import cmd
+ from vyos.utils.process import cmd
if raw:
from json import loads
@@ -96,7 +96,7 @@ def show_summary(raw: bool):
return output
def show_neighbors(raw: bool):
- from vyos.util import cmd
+ from vyos.utils.process import cmd
from vyos.utils.dict import dict_to_list
if raw:
@@ -129,7 +129,7 @@ def show(raw: bool,
frr_command = frr_command_template.render(kwargs)
frr_command = re.sub(r'\s+', ' ', frr_command)
- from vyos.util import cmd
+ from vyos.utils.process import cmd
output = cmd(f"vtysh -c '{frr_command}'")
if raw:
diff --git a/src/op_mode/bridge.py b/src/op_mode/bridge.py
index d6098c158..1834b9cc9 100755
--- a/src/op_mode/bridge.py
+++ b/src/op_mode/bridge.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright (C) 2022-2023 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
@@ -22,8 +22,10 @@ import typing
from sys import exit
from tabulate import tabulate
-from vyos.util import cmd, rc_cmd
-from vyos.util import dict_search
+from vyos.utils.process import cmd
+from vyos.utils.process import rc_cmd
+from vyos.utils.process import call
+from vyos.utils.dict import dict_search
import vyos.opmode
@@ -128,7 +130,8 @@ def _get_formatted_output_vlan(data):
if vlan_entry.get('vlanEnd'):
vlan_end = vlan_entry.get('vlanEnd')
vlan = f'{vlan}-{vlan_end}'
- flags = ', '.join(vlan_entry.get('flags')).lower()
+ flags_raw = vlan_entry.get('flags')
+ flags = ', '.join(flags_raw if isinstance(flags_raw,list) else "").lower()
data_entries.append([interface, vlan, flags])
headers = ["Interface", "Vlan", "Flags"]
@@ -163,6 +166,23 @@ def _get_formatted_output_mdb(data):
output = tabulate(data_entries, headers)
return output
+def _get_bridge_detail(iface):
+ """Get interface detail statistics"""
+ return call(f'vtysh -c "show interface {iface}"')
+
+def _get_bridge_detail_nexthop_group(iface):
+ """Get interface detail nexthop_group statistics"""
+ return call(f'vtysh -c "show interface {iface} nexthop-group"')
+
+def _get_bridge_detail_nexthop_group_raw(iface):
+ out = cmd(f'vtysh -c "show interface {iface} nexthop-group"')
+ return out
+
+def _get_bridge_detail_raw(iface):
+ """Get interface detail json statistics"""
+ data = cmd(f'vtysh -c "show interface {iface} json"')
+ data_dict = json.loads(data)
+ return data_dict
def show(raw: bool):
bridge_data = _get_raw_data_summary()
@@ -195,6 +215,17 @@ def show_mdb(raw: bool, interface: str):
else:
return _get_formatted_output_mdb(mdb_data)
+def show_detail(raw: bool, nexthop_group: typing.Optional[bool], interface: str):
+ if raw:
+ if nexthop_group:
+ return _get_bridge_detail_nexthop_group_raw(interface)
+ else:
+ return _get_bridge_detail_raw(interface)
+ else:
+ if nexthop_group:
+ return _get_bridge_detail_nexthop_group(interface)
+ else:
+ return _get_bridge_detail(interface)
if __name__ == '__main__':
try:
diff --git a/src/op_mode/clear_conntrack.py b/src/op_mode/clear_conntrack.py
index 423694187..fec7cf144 100755
--- a/src/op_mode/clear_conntrack.py
+++ b/src/op_mode/clear_conntrack.py
@@ -16,8 +16,9 @@
import sys
-from vyos.util import ask_yes_no
-from vyos.util import cmd, DEVNULL
+from vyos.utils.io import ask_yes_no
+from vyos.utils.process import cmd
+from vyos.utils.process import DEVNULL
if not ask_yes_no("This will clear all currently tracked and expected connections. Continue?"):
sys.exit(1)
diff --git a/src/op_mode/clear_dhcp_lease.py b/src/op_mode/clear_dhcp_lease.py
index 250dbcce1..f372d3af0 100755
--- a/src/op_mode/clear_dhcp_lease.py
+++ b/src/op_mode/clear_dhcp_lease.py
@@ -7,9 +7,9 @@ from isc_dhcp_leases import Lease
from isc_dhcp_leases import IscDhcpLeases
from vyos.configquery import ConfigTreeQuery
-from vyos.util import ask_yes_no
-from vyos.util import call
-from vyos.util import commit_in_progress
+from vyos.utils.io import ask_yes_no
+from vyos.utils.process import call
+from vyos.utils.commit import commit_in_progress
config = ConfigTreeQuery()
diff --git a/src/op_mode/connect_disconnect.py b/src/op_mode/connect_disconnect.py
index d39e88bf3..89f929be7 100755
--- a/src/op_mode/connect_disconnect.py
+++ b/src/op_mode/connect_disconnect.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020-2021 VyOS maintainers and contributors
+# Copyright (C) 2020-2023 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
@@ -19,10 +19,10 @@ import argparse
from psutil import process_iter
-from vyos.util import call
-from vyos.util import commit_in_progress
-from vyos.util import DEVNULL
-from vyos.util import is_wwan_connected
+from vyos.utils.process import call
+from vyos.utils.commit import commit_in_progress
+from vyos.utils.network import is_wwan_connected
+from vyos.utils.process import DEVNULL
def check_ppp_interface(interface):
if not os.path.isfile(f'/etc/ppp/peers/{interface}'):
diff --git a/src/op_mode/conntrack.py b/src/op_mode/conntrack.py
index ea7c4c208..cf8adf795 100755
--- a/src/op_mode/conntrack.py
+++ b/src/op_mode/conntrack.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright (C) 2022-2023 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
@@ -19,8 +19,8 @@ import typing
import xmltodict
from tabulate import tabulate
-from vyos.util import cmd
-from vyos.util import run
+from vyos.utils.process import cmd
+from vyos.utils.process import run
import vyos.opmode
diff --git a/src/op_mode/conntrack_sync.py b/src/op_mode/conntrack_sync.py
index c3345a936..a38688e45 100755
--- a/src/op_mode/conntrack_sync.py
+++ b/src/op_mode/conntrack_sync.py
@@ -24,10 +24,10 @@ import vyos.opmode
from argparse import ArgumentParser
from vyos.configquery import CliShellApiConfigQuery
from vyos.configquery import ConfigTreeQuery
-from vyos.util import call
-from vyos.util import commit_in_progress
-from vyos.util import cmd
-from vyos.util import run
+from vyos.utils.commit import commit_in_progress
+from vyos.utils.process import call
+from vyos.utils.process import cmd
+from vyos.utils.process import run
from vyos.template import render_to_string
conntrackd_bin = '/usr/sbin/conntrackd'
diff --git a/src/op_mode/container.py b/src/op_mode/container.py
index 7f726f076..5a022d0c0 100755
--- a/src/op_mode/container.py
+++ b/src/op_mode/container.py
@@ -19,7 +19,7 @@ import sys
from sys import exit
-from vyos.util import cmd
+from vyos.utils.process import cmd
import vyos.opmode
@@ -36,14 +36,14 @@ def _get_raw_data(command: str) -> list:
return data
def add_image(name: str):
- from vyos.util import rc_cmd
+ from vyos.utils.process import rc_cmd
rc, output = rc_cmd(f'podman image pull {name}')
if rc != 0:
raise vyos.opmode.InternalError(output)
def delete_image(name: str):
- from vyos.util import rc_cmd
+ from vyos.utils.process import rc_cmd
rc, output = rc_cmd(f'podman image rm --force {name}')
if rc != 0:
@@ -77,7 +77,7 @@ def show_network(raw: bool):
def restart(name: str):
- from vyos.util import rc_cmd
+ from vyos.utils.process import rc_cmd
rc, output = rc_cmd(f'systemctl restart vyos-container-{name}.service')
if rc != 0:
diff --git a/src/op_mode/dhcp.py b/src/op_mode/dhcp.py
index fe7f252ba..3e51e990b 100755
--- a/src/op_mode/dhcp.py
+++ b/src/op_mode/dhcp.py
@@ -27,9 +27,9 @@ import vyos.opmode
from vyos.base import Warning
from vyos.configquery import ConfigTreeQuery
-from vyos.util import cmd
-from vyos.util import dict_search
-from vyos.util import is_systemd_service_running
+from vyos.utils.process import cmd
+from vyos.utils.dict import dict_search
+from vyos.utils.process import is_systemd_service_running
config = ConfigTreeQuery()
lease_valid_states = ['all', 'active', 'free', 'expired', 'released', 'abandoned', 'reset', 'backup']
diff --git a/src/op_mode/dns.py b/src/op_mode/dns.py
index f8863c530..2168aef89 100755
--- a/src/op_mode/dns.py
+++ b/src/op_mode/dns.py
@@ -20,7 +20,7 @@ import sys
from tabulate import tabulate
from vyos.configquery import ConfigTreeQuery
-from vyos.util import cmd
+from vyos.utils.process import cmd
import vyos.opmode
diff --git a/src/op_mode/dns_dynamic.py b/src/op_mode/dns_dynamic.py
index 76ca5249b..12aa5494a 100755
--- a/src/op_mode/dns_dynamic.py
+++ b/src/op_mode/dns_dynamic.py
@@ -22,7 +22,7 @@ from tabulate import tabulate
from vyos.config import Config
from vyos.template import is_ipv4, is_ipv6
-from vyos.util import call
+from vyos.utils.process import call
cache_file = r'/run/ddclient/ddclient.cache'
diff --git a/src/op_mode/dns_forwarding_reset.py b/src/op_mode/dns_forwarding_reset.py
index bfc640a26..55e20918f 100755
--- a/src/op_mode/dns_forwarding_reset.py
+++ b/src/op_mode/dns_forwarding_reset.py
@@ -25,7 +25,7 @@ import argparse
from sys import exit
from vyos.config import Config
-from vyos.util import call
+from vyos.utils.process import call
PDNS_CMD='/usr/bin/rec_control --socket-dir=/run/powerdns'
diff --git a/src/op_mode/dns_forwarding_statistics.py b/src/op_mode/dns_forwarding_statistics.py
index d79b6c024..32b5c76a7 100755
--- a/src/op_mode/dns_forwarding_statistics.py
+++ b/src/op_mode/dns_forwarding_statistics.py
@@ -4,7 +4,7 @@ import jinja2
from sys import exit
from vyos.config import Config
-from vyos.util import cmd
+from vyos.utils.process import cmd
PDNS_CMD='/usr/bin/rec_control --socket-dir=/run/powerdns'
diff --git a/src/op_mode/firewall.py b/src/op_mode/firewall.py
index 46bda5f7e..8260bbb77 100755
--- a/src/op_mode/firewall.py
+++ b/src/op_mode/firewall.py
@@ -21,8 +21,8 @@ import re
import tabulate
from vyos.config import Config
-from vyos.util import cmd
-from vyos.util import dict_search_args
+from vyos.utils.process import cmd
+from vyos.utils.dict import dict_search_args
def get_firewall_interfaces(firewall, name=None, ipv6=False):
directions = ['in', 'out', 'local']
diff --git a/src/op_mode/flow_accounting_op.py b/src/op_mode/flow_accounting_op.py
index 514143cd7..497ccafdf 100755
--- a/src/op_mode/flow_accounting_op.py
+++ b/src/op_mode/flow_accounting_op.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018 VyOS maintainers and contributors
+# Copyright (C) 2018-2023 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
@@ -13,18 +13,18 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
import sys
import argparse
import re
import ipaddress
import os.path
+
from tabulate import tabulate
from json import loads
-from vyos.util import cmd
-from vyos.util import commit_in_progress
-from vyos.util import run
+from vyos.utils.commit import commit_in_progress
+from vyos.utils.process import cmd
+from vyos.utils.process import run
from vyos.logger import syslog
# some default values
diff --git a/src/op_mode/format_disk.py b/src/op_mode/format_disk.py
index b3ba44e87..31ceb196a 100755
--- a/src/op_mode/format_disk.py
+++ b/src/op_mode/format_disk.py
@@ -20,10 +20,10 @@ import re
from datetime import datetime
-from vyos.util import ask_yes_no
-from vyos.util import call
-from vyos.util import cmd
-from vyos.util import DEVNULL
+from vyos.utils.io import ask_yes_no
+from vyos.utils.process import call
+from vyos.utils.process import cmd
+from vyos.utils.process import DEVNULL
def list_disks():
disks = set()
diff --git a/src/op_mode/generate_interfaces_debug_archive.py b/src/op_mode/generate_interfaces_debug_archive.py
index f5767080a..3059aad23 100755
--- a/src/op_mode/generate_interfaces_debug_archive.py
+++ b/src/op_mode/generate_interfaces_debug_archive.py
@@ -20,7 +20,7 @@ from shutil import rmtree
from socket import gethostname
from sys import exit
from tarfile import open as tar_open
-from vyos.util import rc_cmd
+from vyos.utils.process import rc_cmd
import os
# define a list of commands that needs to be executed
diff --git a/src/op_mode/generate_ipsec_debug_archive.py b/src/op_mode/generate_ipsec_debug_archive.py
index 1422559a8..60195d48b 100755
--- a/src/op_mode/generate_ipsec_debug_archive.py
+++ b/src/op_mode/generate_ipsec_debug_archive.py
@@ -20,7 +20,7 @@ from shutil import rmtree
from socket import gethostname
from sys import exit
from tarfile import open as tar_open
-from vyos.util import rc_cmd
+from vyos.utils.process import rc_cmd
# define a list of commands that needs to be executed
CMD_LIST: list[str] = [
diff --git a/src/op_mode/generate_openconnect_otp_key.py b/src/op_mode/generate_openconnect_otp_key.py
index 363bcf3ea..99b67d261 100755
--- a/src/op_mode/generate_openconnect_otp_key.py
+++ b/src/op_mode/generate_openconnect_otp_key.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright (C) 2022-2023 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
@@ -17,7 +17,7 @@
import argparse
import os
-from vyos.util import popen
+from vyos.utils.process import popen
from secrets import token_hex
from base64 import b32encode
diff --git a/src/op_mode/generate_ovpn_client_file.py b/src/op_mode/generate_ovpn_client_file.py
index 0628e6135..cec370a07 100755
--- a/src/op_mode/generate_ovpn_client_file.py
+++ b/src/op_mode/generate_ovpn_client_file.py
@@ -22,7 +22,7 @@ from textwrap import fill
from vyos.configquery import ConfigTreeQuery
from vyos.ifconfig import Section
-from vyos.util import cmd
+from vyos.utils.process import cmd
client_config = """
diff --git a/src/op_mode/generate_ssh_server_key.py b/src/op_mode/generate_ssh_server_key.py
index 43e94048d..d6063c43c 100755
--- a/src/op_mode/generate_ssh_server_key.py
+++ b/src/op_mode/generate_ssh_server_key.py
@@ -15,9 +15,9 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from sys import exit
-from vyos.util import ask_yes_no
-from vyos.util import cmd
-from vyos.util import commit_in_progress
+from vyos.utils.io import ask_yes_no
+from vyos.utils.process import cmd
+from vyos.utils.commit import commit_in_progress
if not ask_yes_no('Do you really want to remove the existing SSH host keys?'):
exit(0)
diff --git a/src/op_mode/generate_system_login_user.py b/src/op_mode/generate_system_login_user.py
index 8f8827b1b..1b328eae0 100755
--- a/src/op_mode/generate_system_login_user.py
+++ b/src/op_mode/generate_system_login_user.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright (C) 2022-2023 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
@@ -17,7 +17,7 @@
import argparse
import os
-from vyos.util import popen
+from vyos.utils.process import popen
from secrets import token_hex
from base64 import b32encode
diff --git a/src/op_mode/igmp-proxy.py b/src/op_mode/igmp-proxy.py
index 0086c9aa6..709e25915 100755
--- a/src/op_mode/igmp-proxy.py
+++ b/src/op_mode/igmp-proxy.py
@@ -28,16 +28,14 @@ import tabulate
import vyos.config
import vyos.opmode
-from vyos.util import bytes_to_human, print_error
+from vyos.utils.convert import bytes_to_human
+from vyos.utils.io import print_error
+from vyos.utils.process import process_named_running
def _is_configured():
"""Check if IGMP proxy is configured"""
return vyos.config.Config().exists_effective('protocols igmp-proxy')
-def _is_running():
- """Check if IGMP proxy is currently running"""
- return not vyos.util.run('ps -C igmpproxy')
-
def _kernel_to_ip(addr):
"""
Convert any given address from Linux kernel to a proper, IPv4 address
@@ -84,7 +82,7 @@ def show_interface(raw: bool):
if not _is_configured():
print_error('IGMP proxy is not configured.')
sys.exit(0)
-if not _is_running():
+if not process_named_running('igmpproxy'):
print_error('IGMP proxy is not running.')
sys.exit(0)
diff --git a/src/op_mode/ikev2_profile_generator.py b/src/op_mode/ikev2_profile_generator.py
index a22f04c45..5454cc0ce 100755
--- a/src/op_mode/ikev2_profile_generator.py
+++ b/src/op_mode/ikev2_profile_generator.py
@@ -24,7 +24,7 @@ from cryptography.x509.oid import NameOID
from vyos.configquery import ConfigTreeQuery
from vyos.pki import load_certificate
from vyos.template import render_to_string
-from vyos.util import ask_input
+from vyos.utils.io import ask_input
# Apple profiles only support one IKE/ESP encryption cipher and hash, whereas
# VyOS comes with a multitude of different proposals for a connection.
diff --git a/src/op_mode/interfaces.py b/src/op_mode/interfaces.py
index f38b95a71..782e178c6 100755
--- a/src/op_mode/interfaces.py
+++ b/src/op_mode/interfaces.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright (C) 2022-2023 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,7 +28,9 @@ import vyos.opmode
from vyos.ifconfig import Section
from vyos.ifconfig import Interface
from vyos.ifconfig import VRRP
-from vyos.util import cmd, rc_cmd, call
+from vyos.utils.process import cmd
+from vyos.utils.process import rc_cmd
+from vyos.utils.process import call
def catch_broken_pipe(func):
def wrapped(*args, **kwargs):
@@ -384,7 +386,7 @@ def _format_show_counters(data: list):
rx_errors = entry.get('rx_over_errors')
tx_errors = entry.get('tx_carrier_errors')
data_entries.append([interface, rx_packets, rx_bytes, tx_packets, tx_bytes, rx_dropped, tx_dropped, rx_errors, tx_errors])
-
+
headers = ['Interface', 'Rx Packets', 'Rx Bytes', 'Tx Packets', 'Tx Bytes', 'Rx Dropped', 'Tx Dropped', 'Rx Errors', 'Tx Errors']
output = tabulate(data_entries, headers, numalign="left")
print (output)
diff --git a/src/op_mode/ipoe-control.py b/src/op_mode/ipoe-control.py
index 7111498b2..0f33beca7 100755
--- a/src/op_mode/ipoe-control.py
+++ b/src/op_mode/ipoe-control.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020 VyOS maintainers and contributors
+# Copyright (C) 2020-2023 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
@@ -18,7 +18,8 @@ import sys
import argparse
from vyos.config import Config
-from vyos.util import popen, run
+from vyos.utils.process import popen
+from vyos.utils.process import run
cmd_dict = {
'cmd_base' : '/usr/bin/accel-cmd -p 2002 ',
diff --git a/src/op_mode/ipsec.py b/src/op_mode/ipsec.py
index 823bd039d..57d3cfed9 100755
--- a/src/op_mode/ipsec.py
+++ b/src/op_mode/ipsec.py
@@ -21,9 +21,9 @@ from hurry import filesize
from re import split as re_split
from tabulate import tabulate
-from vyos.util import convert_data
-from vyos.util import seconds_to_human
-from vyos.util import cmd
+from vyos.utils.convert import convert_data
+from vyos.utils.convert import seconds_to_human
+from vyos.utils.process import cmd
from vyos.configquery import ConfigTreeQuery
import vyos.opmode
diff --git a/src/op_mode/lldp.py b/src/op_mode/lldp.py
index 1a1b94783..c287b8fa6 100755
--- a/src/op_mode/lldp.py
+++ b/src/op_mode/lldp.py
@@ -22,8 +22,8 @@ import typing
from tabulate import tabulate
from vyos.configquery import ConfigTreeQuery
-from vyos.util import cmd
-from vyos.util import dict_search
+from vyos.utils.process import cmd
+from vyos.utils.dict import dict_search
import vyos.opmode
unconf_message = 'LLDP is not configured'
diff --git a/src/op_mode/log.py b/src/op_mode/log.py
index b0abd6191..797ba5a88 100755
--- a/src/op_mode/log.py
+++ b/src/op_mode/log.py
@@ -21,7 +21,7 @@ import typing
from jinja2 import Template
-from vyos.util import rc_cmd
+from vyos.utils.process import rc_cmd
import vyos.opmode
diff --git a/src/op_mode/memory.py b/src/op_mode/memory.py
index 7666de646..eb530035b 100755
--- a/src/op_mode/memory.py
+++ b/src/op_mode/memory.py
@@ -54,7 +54,7 @@ def _get_raw_data():
return mem_data
def _get_formatted_output(mem):
- from vyos.util import bytes_to_human
+ from vyos.utils.convert import bytes_to_human
# For human-readable outputs, we convert bytes to more convenient units
# (100M, 1.3G...)
diff --git a/src/op_mode/nat.py b/src/op_mode/nat.py
index c92795745..71a40c0e1 100755
--- a/src/op_mode/nat.py
+++ b/src/op_mode/nat.py
@@ -25,8 +25,8 @@ from tabulate import tabulate
import vyos.opmode
from vyos.configquery import ConfigTreeQuery
-from vyos.util import cmd
-from vyos.util import dict_search
+from vyos.utils.process import cmd
+from vyos.utils.dict import dict_search
base = 'nat'
unconf_message = 'NAT is not configured'
diff --git a/src/op_mode/neighbor.py b/src/op_mode/neighbor.py
index b329ea280..1edeb0045 100755
--- a/src/op_mode/neighbor.py
+++ b/src/op_mode/neighbor.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright (C) 2022-2023 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
@@ -41,7 +41,7 @@ def interface_exists(interface):
def get_raw_data(family, interface=None, state=None):
from json import loads
- from vyos.util import cmd
+ from vyos.utils.process import cmd
if interface:
if not interface_exists(interface):
@@ -102,7 +102,7 @@ def show(raw: bool, family: ArgFamily, interface: typing.Optional[str],
return format_neighbors(data, interface)
def reset(family: ArgFamily, interface: typing.Optional[str], address: typing.Optional[str]):
- from vyos.util import run
+ from vyos.utils.process import run
if address and interface:
raise ValueError("interface and address parameters are mutually exclusive")
@@ -114,7 +114,6 @@ def reset(family: ArgFamily, interface: typing.Optional[str], address: typing.Op
# Flush an entire neighbor table
run(f"""ip --family {family} neighbor flush""")
-
if __name__ == '__main__':
try:
res = vyos.opmode.run(sys.modules[__name__])
diff --git a/src/op_mode/nhrp.py b/src/op_mode/nhrp.py
index 5ff91a59c..e66f33079 100755
--- a/src/op_mode/nhrp.py
+++ b/src/op_mode/nhrp.py
@@ -18,9 +18,9 @@ import sys
import tabulate
import vyos.opmode
-from vyos.util import cmd
-from vyos.util import process_named_running
-from vyos.util import colon_separated_to_dict
+from vyos.utils.process import cmd
+from vyos.utils.process import process_named_running
+from vyos.utils.dict import colon_separated_to_dict
def _get_formatted_output(output_dict: dict) -> str:
diff --git a/src/op_mode/openconnect-control.py b/src/op_mode/openconnect-control.py
index 20c50e779..b70d4fa16 100755
--- a/src/op_mode/openconnect-control.py
+++ b/src/op_mode/openconnect-control.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020 VyOS maintainers and contributors
+# Copyright (C) 2020-2023 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
@@ -18,12 +18,13 @@ import sys
import argparse
import json
-from vyos.config import Config
-from vyos.util import popen
-from vyos.util import run
-from vyos.util import DEVNULL
from tabulate import tabulate
+from vyos.config import Config
+from vyos.utils.process import popen
+from vyos.utils.process import run
+from vyos.utils.process import DEVNULL
+
occtl = '/usr/bin/occtl'
occtl_socket = '/run/ocserv/occtl.socket'
diff --git a/src/op_mode/openconnect.py b/src/op_mode/openconnect.py
index b21890728..cfa0678a7 100755
--- a/src/op_mode/openconnect.py
+++ b/src/op_mode/openconnect.py
@@ -19,7 +19,7 @@ import json
from tabulate import tabulate
from vyos.configquery import ConfigTreeQuery
-from vyos.util import rc_cmd
+from vyos.utils.process import rc_cmd
import vyos.opmode
diff --git a/src/op_mode/openvpn.py b/src/op_mode/openvpn.py
index d9ae965c5..fd9d2db92 100755
--- a/src/op_mode/openvpn.py
+++ b/src/op_mode/openvpn.py
@@ -23,10 +23,10 @@ import typing
from tabulate import tabulate
import vyos.opmode
-from vyos.util import bytes_to_human
-from vyos.util import commit_in_progress
-from vyos.util import call
-from vyos.util import rc_cmd
+from vyos.utils.convert import bytes_to_human
+from vyos.utils.commit import commit_in_progress
+from vyos.utils.process import call
+from vyos.utils.process import rc_cmd
from vyos.config import Config
ArgMode = typing.Literal['client', 'server', 'site_to_site']
diff --git a/src/op_mode/ping.py b/src/op_mode/ping.py
index 610e63cb3..f1d87a118 100755
--- a/src/op_mode/ping.py
+++ b/src/op_mode/ping.py
@@ -18,7 +18,7 @@ import os
import sys
import socket
import ipaddress
-from vyos.util import get_all_vrfs
+from vyos.utils.network import get_all_vrfs
from vyos.ifconfig import Section
@@ -90,6 +90,16 @@ options = {
'type': '<seconds>',
'help': 'Number of seconds to wait between requests'
},
+ 'ipv4': {
+ 'ping': '{command} -4',
+ 'type': 'noarg',
+ 'help': 'Use IPv4 only'
+ },
+ 'ipv6': {
+ 'ping': '{command} -6',
+ 'type': 'noarg',
+ 'help': 'Use IPv6 only'
+ },
'mark': {
'ping': '{command} -m {value}',
'type': '<fwmark>',
diff --git a/src/op_mode/pki.py b/src/op_mode/pki.py
index b054690b0..4c31291ad 100755
--- a/src/op_mode/pki.py
+++ b/src/op_mode/pki.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2023 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
@@ -34,10 +34,11 @@ from vyos.pki import create_dh_parameters
from vyos.pki import load_certificate, load_certificate_request, load_private_key
from vyos.pki import load_crl, load_dh_parameters, load_public_key
from vyos.pki import verify_certificate
+from vyos.utils.io import ask_input
+from vyos.utils.io import ask_yes_no
+from vyos.utils.misc import install_into_config
+from vyos.utils.process import cmd
from vyos.xml import defaults
-from vyos.util import ask_input, ask_yes_no
-from vyos.util import cmd
-from vyos.util import install_into_config
CERT_REQ_END = '-----END CERTIFICATE REQUEST-----'
auth_dir = '/config/auth'
@@ -190,7 +191,7 @@ def install_ssh_key(name, public_key, private_key, passphrase=None):
def install_keypair(name, key_type, private_key=None, public_key=None, passphrase=None, prompt=True):
# Show/install conf commands for key-pair
-
+
config_paths = []
if public_key:
@@ -840,7 +841,7 @@ def import_openvpn_secret(name, path):
install_openvpn_key(name, key_data, key_version)
# Show functions
-def show_certificate_authority(name=None):
+def show_certificate_authority(name=None, pem=False):
headers = ['Name', 'Subject', 'Issuer CN', 'Issued', 'Expiry', 'Private Key', 'Parent']
data = []
certs = get_config_ca_certificate()
@@ -852,6 +853,11 @@ def show_certificate_authority(name=None):
continue
cert = load_certificate(cert_dict['certificate'])
+
+ if name and pem:
+ print(encode_certificate(cert))
+ return
+
parent_ca_name = get_certificate_ca(cert, certs)
cert_issuer_cn = cert.issuer.rfc4514_string().split(",")[0]
@@ -867,7 +873,7 @@ def show_certificate_authority(name=None):
print("Certificate Authorities:")
print(tabulate.tabulate(data, headers))
-def show_certificate(name=None):
+def show_certificate(name=None, pem=False):
headers = ['Name', 'Type', 'Subject CN', 'Issuer CN', 'Issued', 'Expiry', 'Revoked', 'Private Key', 'CA Present']
data = []
certs = get_config_certificate()
@@ -885,6 +891,10 @@ def show_certificate(name=None):
if not cert:
continue
+ if name and pem:
+ print(encode_certificate(cert))
+ return
+
ca_name = get_certificate_ca(cert, ca_certs)
cert_subject_cn = cert.subject.rfc4514_string().split(",")[0]
cert_issuer_cn = cert.issuer.rfc4514_string().split(",")[0]
@@ -906,7 +916,7 @@ def show_certificate(name=None):
print("Certificates:")
print(tabulate.tabulate(data, headers))
-def show_crl(name=None):
+def show_crl(name=None, pem=False):
headers = ['CA Name', 'Updated', 'Revokes']
data = []
certs = get_config_ca_certificate()
@@ -927,9 +937,16 @@ def show_crl(name=None):
if not crl:
continue
+ if name and pem:
+ print(encode_certificate(crl))
+ continue
+
certs = get_revoked_by_serial_numbers([revoked.serial_number for revoked in crl])
data.append([cert_name, crl.last_update, ", ".join(certs)])
+ if name and pem:
+ return
+
print("Certificate Revocation Lists:")
print(tabulate.tabulate(data, headers))
@@ -943,6 +960,7 @@ if __name__ == '__main__':
parser.add_argument('--crl', help='Certificate Revocation List', required=False)
parser.add_argument('--sign', help='Sign certificate with specified CA', required=False)
parser.add_argument('--self-sign', help='Self-sign the certificate', action='store_true')
+ parser.add_argument('--pem', help='Output using PEM encoding', action='store_true')
# SSH
parser.add_argument('--ssh', help='SSH Key', required=False)
@@ -1032,16 +1050,16 @@ if __name__ == '__main__':
if not conf.exists(['pki', 'ca', ca_name]):
print(f'CA "{ca_name}" does not exist!')
exit(1)
- show_certificate_authority(ca_name)
+ show_certificate_authority(ca_name, args.pem)
elif args.certificate:
cert_name = None if args.certificate == 'all' else args.certificate
if cert_name:
if not conf.exists(['pki', 'certificate', cert_name]):
print(f'Certificate "{cert_name}" does not exist!')
exit(1)
- show_certificate(None if args.certificate == 'all' else args.certificate)
+ show_certificate(None if args.certificate == 'all' else args.certificate, args.pem)
elif args.crl:
- show_crl(None if args.crl == 'all' else args.crl)
+ show_crl(None if args.crl == 'all' else args.crl, args.pem)
else:
show_certificate_authority()
show_certificate()
diff --git a/src/op_mode/policy_route.py b/src/op_mode/policy_route.py
index fae47adec..eff99de7f 100755
--- a/src/op_mode/policy_route.py
+++ b/src/op_mode/policy_route.py
@@ -19,8 +19,8 @@ import re
import tabulate
from vyos.config import Config
-from vyos.util import cmd
-from vyos.util import dict_search_args
+from vyos.utils.process import cmd
+from vyos.utils.dict import dict_search_args
def get_config_policy(conf, name=None, ipv6=False):
config_path = ['policy']
diff --git a/src/op_mode/powerctrl.py b/src/op_mode/powerctrl.py
index dfacd45c2..3ac5991b4 100755
--- a/src/op_mode/powerctrl.py
+++ b/src/op_mode/powerctrl.py
@@ -22,7 +22,11 @@ from datetime import datetime, timedelta, time as type_time, date as type_date
from sys import exit
from time import time
-from vyos.util import ask_yes_no, cmd, call, run, STDOUT
+from vyos.utils.io import ask_yes_no
+from vyos.utils.process import call
+from vyos.utils.process import cmd
+from vyos.utils.process import run
+from vyos.utils.process import STDOUT
systemd_sched_file = "/run/systemd/shutdown/scheduled"
@@ -104,7 +108,7 @@ def cancel_shutdown():
def check_unsaved_config():
from vyos.config_mgmt import unsaved_commits
- from vyos.util import boot_configuration_success
+ from vyos.utils.boot import boot_configuration_success
if unsaved_commits() and boot_configuration_success():
print("Warning: there are unsaved configuration changes!")
diff --git a/src/op_mode/ppp-server-ctrl.py b/src/op_mode/ppp-server-ctrl.py
index e93963fdd..2bae5b32a 100755
--- a/src/op_mode/ppp-server-ctrl.py
+++ b/src/op_mode/ppp-server-ctrl.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019 VyOS maintainers and contributors
+# Copyright (C) 2019-2023 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
@@ -18,7 +18,8 @@ import sys
import argparse
from vyos.config import Config
-from vyos.util import popen, DEVNULL
+from vyos.utils.process import popen
+from vyos.utils.process import DEVNULL
cmd_dict = {
'cmd_base' : '/usr/bin/accel-cmd -p {} ',
diff --git a/src/op_mode/reset_openvpn.py b/src/op_mode/reset_openvpn.py
index efbf65083..cef5299da 100755
--- a/src/op_mode/reset_openvpn.py
+++ b/src/op_mode/reset_openvpn.py
@@ -16,8 +16,8 @@
import os
from sys import argv, exit
-from vyos.util import call
-from vyos.util import commit_in_progress
+from vyos.utils.process import call
+from vyos.utils.commit import commit_in_progress
if __name__ == '__main__':
if (len(argv) < 1):
diff --git a/src/op_mode/reset_vpn.py b/src/op_mode/reset_vpn.py
index 46195d6cd..61d7c8c81 100755
--- a/src/op_mode/reset_vpn.py
+++ b/src/op_mode/reset_vpn.py
@@ -13,10 +13,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/>.
+
import sys
import typing
-from vyos.util import run
+from vyos.utils.process import run
import vyos.opmode
@@ -29,7 +30,6 @@ cmd_dict = {
}
}
-
def reset_conn(protocol: str, username: typing.Optional[str] = None,
interface: typing.Optional[str] = None):
if protocol in cmd_dict['vpn_types']:
diff --git a/src/op_mode/restart_dhcp_relay.py b/src/op_mode/restart_dhcp_relay.py
index 9203c009f..3ead97f4c 100755
--- a/src/op_mode/restart_dhcp_relay.py
+++ b/src/op_mode/restart_dhcp_relay.py
@@ -23,8 +23,8 @@ import argparse
import os
import vyos.config
-from vyos.util import call
-from vyos.util import commit_in_progress
+from vyos.utils.process import call
+from vyos.utils.commit import commit_in_progress
parser = argparse.ArgumentParser()
diff --git a/src/op_mode/restart_frr.py b/src/op_mode/restart_frr.py
index 680d9f8cc..5cce377eb 100755
--- a/src/op_mode/restart_frr.py
+++ b/src/op_mode/restart_frr.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2021 VyOS maintainers and contributors
+# Copyright (C) 2019-2023 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
@@ -23,10 +23,10 @@ from logging.handlers import SysLogHandler
from shutil import rmtree
from vyos.base import Warning
-from vyos.util import call
-from vyos.util import ask_yes_no
-from vyos.util import process_named_running
-from vyos.util import makedir
+from vyos.utils.io import ask_yes_no
+from vyos.utils.file import makedir
+from vyos.utils.process import call
+from vyos.utils.process import process_named_running
# some default values
watchfrr = '/usr/lib/frr/watchfrr.sh'
diff --git a/src/op_mode/route.py b/src/op_mode/route.py
index d6d6b7d6f..4aa57dbf4 100755
--- a/src/op_mode/route.py
+++ b/src/op_mode/route.py
@@ -57,7 +57,7 @@ frr_command_template = Template("""
ArgFamily = typing.Literal['inet', 'inet6']
def show_summary(raw: bool, family: ArgFamily, table: typing.Optional[int], vrf: typing.Optional[str]):
- from vyos.util import cmd
+ from vyos.utils.process import cmd
if family == 'inet':
family_cmd = 'ip'
@@ -119,7 +119,7 @@ def show(raw: bool,
frr_command = frr_command_template.render(kwargs)
frr_command = re.sub(r'\s+', ' ', frr_command)
- from vyos.util import cmd
+ from vyos.utils.process import cmd
output = cmd(f"vtysh -c '{frr_command}'")
if raw:
diff --git a/src/op_mode/sflow.py b/src/op_mode/sflow.py
index 88f70d6bd..dca7f44cb 100755
--- a/src/op_mode/sflow.py
+++ b/src/op_mode/sflow.py
@@ -20,7 +20,7 @@ import sys
from tabulate import tabulate
from vyos.configquery import ConfigTreeQuery
-from vyos.util import cmd
+from vyos.utils.process import cmd
import vyos.opmode
diff --git a/src/op_mode/show-bond.py b/src/op_mode/show-bond.py
index edf7847fc..f676e0841 100755
--- a/src/op_mode/show-bond.py
+++ b/src/op_mode/show-bond.py
@@ -19,7 +19,7 @@ import jinja2
from argparse import ArgumentParser
from vyos.ifconfig import Section
from vyos.ifconfig import BondIf
-from vyos.util import read_file
+from vyos.utils.file import read_file
from sys import exit
diff --git a/src/op_mode/show_acceleration.py b/src/op_mode/show_acceleration.py
index 48c31d4d9..1c4831f1d 100755
--- a/src/op_mode/show_acceleration.py
+++ b/src/op_mode/show_acceleration.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2022 VyOS maintainers and contributors
+# Copyright (C) 2019-2023 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,8 +20,8 @@ import re
import argparse
from vyos.config import Config
-from vyos.util import popen
-from vyos.util import call
+from vyos.utils.process import call
+from vyos.utils.process import popen
def detect_qat_dev():
output, err = popen('lspci -nn', decode='utf-8')
diff --git a/src/op_mode/show_ntp.sh b/src/op_mode/show_ntp.sh
index 85f8eda15..4b59b801e 100755
--- a/src/op_mode/show_ntp.sh
+++ b/src/op_mode/show_ntp.sh
@@ -18,7 +18,7 @@ if ! ps -C chronyd &>/dev/null; then
fi
PID=$(pgrep chronyd | head -n1)
-VRF_NAME=$(ip vrf identify )
+VRF_NAME=$(ip vrf identify ${PID})
if [ ! -z ${VRF_NAME} ]; then
VRF_CMD="sudo ip vrf exec ${VRF_NAME}"
diff --git a/src/op_mode/show_openconnect_otp.py b/src/op_mode/show_openconnect_otp.py
index 88982c50b..415a5f72c 100755
--- a/src/op_mode/show_openconnect_otp.py
+++ b/src/op_mode/show_openconnect_otp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
-# Copyright 2017, 2022 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright 2017-2023 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
@@ -21,7 +21,7 @@ import os
from vyos.config import Config
from vyos.xml import defaults
from vyos.configdict import dict_merge
-from vyos.util import popen
+from vyos.utils.process import popen
from base64 import b32encode
otp_file = '/run/ocserv/users.oath'
diff --git a/src/op_mode/show_openvpn_mfa.py b/src/op_mode/show_openvpn_mfa.py
index 1ab54600c..100c42154 100755
--- a/src/op_mode/show_openvpn_mfa.py
+++ b/src/op_mode/show_openvpn_mfa.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
-
-# Copyright 2017, 2021 VyOS maintainers and contributors <maintainers@vyos.io>
+#
+# Copyright 2017-2023 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
@@ -20,7 +20,7 @@ import socket
import urllib.parse
import argparse
-from vyos.util import popen
+from vyos.utils.process import popen
otp_file = '/config/auth/openvpn/{interface}-otp-secrets'
diff --git a/src/op_mode/show_sensors.py b/src/op_mode/show_sensors.py
index 6ae477647..5e3084fe9 100755
--- a/src/op_mode/show_sensors.py
+++ b/src/op_mode/show_sensors.py
@@ -1,9 +1,25 @@
#!/usr/bin/env python3
+#
+# Copyright 2017-2023 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/>.
import re
import sys
-from vyos.util import popen
-from vyos.util import DEVNULL
+from vyos.utils.process import popen
+from vyos.utils.process import DEVNULL
+
output,retcode = popen("sensors --no-adapter", stderr=DEVNULL)
if retcode == 0:
print (output)
@@ -23,5 +39,3 @@ else:
print ("No sensors found")
sys.exit(1)
-
-
diff --git a/src/op_mode/show_techsupport_report.py b/src/op_mode/show_techsupport_report.py
index 782004144..d27221e54 100644
--- a/src/op_mode/show_techsupport_report.py
+++ b/src/op_mode/show_techsupport_report.py
@@ -17,7 +17,7 @@
import os
from typing import List
-from vyos.util import rc_cmd
+from vyos.utils.process import rc_cmd
from vyos.ifconfig import Section
from vyos.ifconfig import Interface
diff --git a/src/op_mode/show_virtual_server.py b/src/op_mode/show_virtual_server.py
index 377180dec..7880edc97 100755
--- a/src/op_mode/show_virtual_server.py
+++ b/src/op_mode/show_virtual_server.py
@@ -15,7 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from vyos.configquery import ConfigTreeQuery
-from vyos.util import call
+from vyos.utils.process import call
def is_configured():
""" Check if high-availability virtual-server is configured """
diff --git a/src/op_mode/show_wireless.py b/src/op_mode/show_wireless.py
index 19ab6771c..340163057 100755
--- a/src/op_mode/show_wireless.py
+++ b/src/op_mode/show_wireless.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019 VyOS maintainers and contributors
+# Copyright (C) 2019-2023 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
@@ -21,7 +21,7 @@ from sys import exit
from copy import deepcopy
from vyos.config import Config
-from vyos.util import popen
+from vyos.utils.process import popen
parser = argparse.ArgumentParser()
parser.add_argument("-s", "--scan", help="Scan for Wireless APs on given interface, e.g. 'wlan0'")
diff --git a/src/op_mode/show_wwan.py b/src/op_mode/show_wwan.py
index eb601a456..bd97bb0e5 100755
--- a/src/op_mode/show_wwan.py
+++ b/src/op_mode/show_wwan.py
@@ -18,7 +18,7 @@ import argparse
from sys import exit
from vyos.configquery import ConfigTreeQuery
-from vyos.util import cmd
+from vyos.utils.process import cmd
parser = argparse.ArgumentParser()
parser.add_argument("--model", help="Get module model", action="store_true")
diff --git a/src/op_mode/snmp.py b/src/op_mode/snmp.py
index 5fae67881..43f5d9e0a 100755
--- a/src/op_mode/snmp.py
+++ b/src/op_mode/snmp.py
@@ -24,7 +24,7 @@ import sys
import argparse
from vyos.config import Config
-from vyos.util import call
+from vyos.utils.process import call
config_file_daemon = r'/etc/snmp/snmpd.conf'
diff --git a/src/op_mode/snmp_ifmib.py b/src/op_mode/snmp_ifmib.py
index 2479936bd..c71febac9 100755
--- a/src/op_mode/snmp_ifmib.py
+++ b/src/op_mode/snmp_ifmib.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018 VyOS maintainers and contributors
+# Copyright (C) 2018-2023 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
@@ -24,7 +24,7 @@ import argparse
import netifaces
from vyos.config import Config
-from vyos.util import popen
+from vyos.utils.process import popen
parser = argparse.ArgumentParser(description='Retrieve SNMP interfaces information')
parser.add_argument('--ifindex', action='store', nargs='?', const='all', help='Show interface index')
diff --git a/src/op_mode/storage.py b/src/op_mode/storage.py
index d16e271bd..6bc3d3a2d 100755
--- a/src/op_mode/storage.py
+++ b/src/op_mode/storage.py
@@ -18,7 +18,7 @@
import sys
import vyos.opmode
-from vyos.util import cmd
+from vyos.utils.process import cmd
# FIY: As of coreutils from Debian Buster and Bullseye,
# the outpt looks like this:
@@ -43,7 +43,7 @@ def _get_system_storage(only_persistent=False):
def _get_raw_data():
from re import sub as re_sub
- from vyos.util import human_to_bytes
+ from vyos.utils.convert import human_to_bytes
out = _get_system_storage(only_persistent=True)
lines = out.splitlines()
diff --git a/src/op_mode/traceroute.py b/src/op_mode/traceroute.py
index 6c7030ea0..2f0edf53a 100755
--- a/src/op_mode/traceroute.py
+++ b/src/op_mode/traceroute.py
@@ -18,7 +18,7 @@ import os
import sys
import socket
import ipaddress
-from vyos.util import get_all_vrfs
+from vyos.utils.network import get_all_vrfs
from vyos.ifconfig import Section
diff --git a/src/op_mode/uptime.py b/src/op_mode/uptime.py
index 2ebe6783b..d6adf6f4d 100755
--- a/src/op_mode/uptime.py
+++ b/src/op_mode/uptime.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2022 VyOS maintainers and contributors
+# Copyright (C) 2021-2023 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 as
@@ -20,7 +20,7 @@ import vyos.opmode
def _get_uptime_seconds():
from re import search
- from vyos.util import read_file
+ from vyos.utils.file import read_file
data = read_file("/proc/uptime")
seconds = search("([0-9\.]+)\s", data).group(1)
@@ -29,7 +29,7 @@ def _get_uptime_seconds():
def _get_load_averages():
from re import search
- from vyos.util import cmd
+ from vyos.utils.process import cmd
from vyos.cpu import get_core_count
data = cmd("uptime")
@@ -45,7 +45,7 @@ def _get_load_averages():
return res
def _get_raw_data():
- from vyos.util import seconds_to_human
+ from vyos.utils.convert import seconds_to_human
res = {}
res["uptime_seconds"] = _get_uptime_seconds()
diff --git a/src/op_mode/vpn_ike_sa.py b/src/op_mode/vpn_ike_sa.py
index 4b44c5c15..069c12069 100755
--- a/src/op_mode/vpn_ike_sa.py
+++ b/src/op_mode/vpn_ike_sa.py
@@ -19,7 +19,7 @@ import re
import sys
import vici
-from vyos.util import process_named_running
+from vyos.utils.process import process_named_running
ike_sa_peer_prefix = """\
Peer ID / IP Local ID / IP
@@ -39,8 +39,6 @@ def ike_sa(peer, nat):
peers = []
for conn in sas:
for name, sa in conn.items():
- if peer and not name.startswith('peer_' + peer):
- continue
if name.startswith('peer_') and name in peers:
continue
if nat and 'nat-local' not in sa:
@@ -70,7 +68,7 @@ if __name__ == '__main__':
args = parser.parse_args()
- if not process_named_running('charon'):
+ if not process_named_running('charon-systemd'):
print("IPsec Process NOT Running")
sys.exit(0)
diff --git a/src/op_mode/vpn_ipsec.py b/src/op_mode/vpn_ipsec.py
index b81d1693e..ef89e605f 100755
--- a/src/op_mode/vpn_ipsec.py
+++ b/src/op_mode/vpn_ipsec.py
@@ -17,7 +17,7 @@
import re
import argparse
-from vyos.util import call
+from vyos.utils.process import call
SWANCTL_CONF = '/etc/swanctl/swanctl.conf'
diff --git a/src/op_mode/vrf.py b/src/op_mode/vrf.py
index a9a416761..1f0bbbaeb 100755
--- a/src/op_mode/vrf.py
+++ b/src/op_mode/vrf.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright (C) 2022-2023 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,7 +20,7 @@ import sys
import typing
from tabulate import tabulate
-from vyos.util import cmd
+from vyos.utils.process import cmd
import vyos.opmode
diff --git a/src/op_mode/vrrp.py b/src/op_mode/vrrp.py
index dab146d28..b3ab55cc3 100755
--- a/src/op_mode/vrrp.py
+++ b/src/op_mode/vrrp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2022 VyOS maintainers and contributors
+# Copyright (C) 2018-2023 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
@@ -13,7 +13,6 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
import sys
import time
@@ -21,12 +20,10 @@ import argparse
import json
import tabulate
-import vyos.util
-
from vyos.configquery import ConfigTreeQuery
from vyos.ifconfig.vrrp import VRRP
-from vyos.ifconfig.vrrp import VRRPError, VRRPNoData
-
+from vyos.ifconfig.vrrp import VRRPError
+from vyos.ifconfig.vrrp import VRRPNoData
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
@@ -44,7 +41,7 @@ def is_configured():
return True
# Exit early if VRRP is dead or not configured
-if is_configured() == False:
+if is_configured() == False:
print('VRRP not configured!')
exit(0)
if not VRRP.is_running():
diff --git a/src/op_mode/wireguard_client.py b/src/op_mode/wireguard_client.py
index 76c1ff7d1..04d8ce28c 100755
--- a/src/op_mode/wireguard_client.py
+++ b/src/op_mode/wireguard_client.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021 VyOS maintainers and contributors
+# Copyright (C) 2021-2023 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
@@ -23,8 +23,8 @@ from ipaddress import ip_interface
from vyos.ifconfig import Section
from vyos.template import is_ipv4
from vyos.template import is_ipv6
-from vyos.util import cmd
-from vyos.util import popen
+from vyos.utils.process import cmd
+from vyos.utils.process import popen
if os.geteuid() != 0:
exit("You need to have root privileges to run this script.\nPlease try again, this time using 'sudo'. Exiting.")
diff --git a/src/op_mode/zone.py b/src/op_mode/zone.py
index f326215b1..17ce90396 100755
--- a/src/op_mode/zone.py
+++ b/src/op_mode/zone.py
@@ -19,8 +19,8 @@ import vyos.opmode
import tabulate
from vyos.configquery import ConfigTreeQuery
-from vyos.util import dict_search_args
-from vyos.util import dict_search
+from vyos.utils.dict import dict_search_args
+from vyos.utils.dict import dict_search
def get_config_zone(conf, name=None):
diff --git a/src/services/api/graphql/generate/schema_from_op_mode.py b/src/services/api/graphql/generate/schema_from_op_mode.py
index 229ccf90f..ab7cb691f 100755
--- a/src/services/api/graphql/generate/schema_from_op_mode.py
+++ b/src/services/api/graphql/generate/schema_from_op_mode.py
@@ -27,7 +27,7 @@ from jinja2 import Template
from vyos.defaults import directories
from vyos.opmode import _is_op_mode_function_name as is_op_mode_function_name
from vyos.opmode import _get_literal_values as get_literal_values
-from vyos.util import load_as_module
+from vyos.utils.system import load_as_module
if __package__ is None or __package__ == '':
sys.path.append(os.path.join(directories['services'], 'api'))
from graphql.libs.op_mode import is_show_function_name
diff --git a/src/services/api/graphql/libs/op_mode.py b/src/services/api/graphql/libs/op_mode.py
index e91d8bd0f..5022f7d4e 100644
--- a/src/services/api/graphql/libs/op_mode.py
+++ b/src/services/api/graphql/libs/op_mode.py
@@ -20,7 +20,7 @@ from typing import Union, Tuple, Optional
from humps import decamelize
from vyos.defaults import directories
-from vyos.util import load_as_module
+from vyos.utils.system import load_as_module
from vyos.opmode import _normalize_field_names
from vyos.opmode import _is_literal_type, _get_literal_values
diff --git a/src/services/vyos-configd b/src/services/vyos-configd
index 48c9135e2..355182b26 100755
--- a/src/services/vyos-configd
+++ b/src/services/vyos-configd
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020 VyOS maintainers and contributors
+# Copyright (C) 2020-2023 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
@@ -13,8 +13,6 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-#
import os
import sys
@@ -28,8 +26,9 @@ import zmq
from contextlib import contextmanager
from vyos.defaults import directories
-from vyos.util import boot_configuration_complete
-from vyos.configsource import ConfigSourceString, ConfigSourceError
+from vyos.utils.boot import boot_configuration_complete
+from vyos.configsource import ConfigSourceString
+from vyos.configsource import ConfigSourceError
from vyos.config import Config
from vyos import ConfigError
diff --git a/src/services/vyos-hostsd b/src/services/vyos-hostsd
index 894f9e24d..e34a4b740 100755
--- a/src/services/vyos-hostsd
+++ b/src/services/vyos-hostsd
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019-2020 VyOS maintainers and contributors
+# Copyright (C) 2019-2023 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
@@ -241,9 +241,14 @@ import traceback
import re
import logging
import zmq
+
from voluptuous import Schema, MultipleInvalid, Required, Any
from collections import OrderedDict
-from vyos.util import popen, chown, chmod_755, makedir, process_named_running
+from vyos.utils.file import makedir
+from vyos.utils.permission import chown
+from vyos.utils.permission import chmod_755
+from vyos.utils.process import popen
+from vyos.utils.process import process_named_running
from vyos.template import render
debug = True
diff --git a/src/system/keepalived-fifo.py b/src/system/keepalived-fifo.py
index 864ee8419..5e19bdbad 100755
--- a/src/system/keepalived-fifo.py
+++ b/src/system/keepalived-fifo.py
@@ -28,9 +28,9 @@ from logging.handlers import SysLogHandler
from vyos.ifconfig.vrrp import VRRP
from vyos.configquery import ConfigTreeQuery
-from vyos.util import cmd
-from vyos.util import dict_search
-from vyos.util import commit_in_progress
+from vyos.utils.process import cmd
+from vyos.utils.dict import dict_search
+from vyos.utils.commit import commit_in_progress
# configure logging
logger = logging.getLogger(__name__)
diff --git a/src/system/vyos-event-handler.py b/src/system/vyos-event-handler.py
index 1c85380bc..74112ec91 100755
--- a/src/system/vyos-event-handler.py
+++ b/src/system/vyos-event-handler.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright (C) 2022-2023 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
@@ -18,6 +18,7 @@ import argparse
import json
import re
import select
+
from copy import deepcopy
from os import getpid, environ
from pathlib import Path
@@ -25,13 +26,13 @@ from signal import signal, SIGTERM, SIGINT
from sys import exit
from systemd import journal
-from vyos.util import run, dict_search
+from vyos.utils.dict import dict_search
+from vyos.utils.process import run
# Identify this script
my_pid = getpid()
my_name = Path(__file__).stem
-
# handle termination signal
def handle_signal(signal_type, frame):
if signal_type == SIGTERM:
diff --git a/src/system/vyos-system-update-check.py b/src/system/vyos-system-update-check.py
index c9597721b..c874f1e2c 100755
--- a/src/system/vyos-system-update-check.py
+++ b/src/system/vyos-system-update-check.py
@@ -22,7 +22,7 @@ from pathlib import Path
from sys import exit
from time import sleep
-from vyos.util import call
+from vyos.utils.process import call
import vyos.version
diff --git a/src/systemd/vyos-router.service b/src/systemd/vyos-router.service
new file mode 100644
index 000000000..6f683cebb
--- /dev/null
+++ b/src/systemd/vyos-router.service
@@ -0,0 +1,19 @@
+[Unit]
+Description=VyOS Router
+After=systemd-journald-dev-log.socket time-sync.target local-fs.target cloud-config.service
+Requires=frr.service
+Conflicts=shutdown.target
+Before=systemd-user-sessions.service
+
+[Service]
+Type=simple
+Restart=no
+TimeoutSec=20min
+KillMode=process
+RemainAfterExit=yes
+ExecStart=/usr/libexec/vyos/init/vyos-router start
+ExecStop=/usr/libexec/vyos/init/vyos-router stop
+StandardOutput=journal+console
+
+[Install]
+WantedBy=vyos.target
diff --git a/src/systemd/vyos.target b/src/systemd/vyos.target
new file mode 100644
index 000000000..47c91c1cc
--- /dev/null
+++ b/src/systemd/vyos.target
@@ -0,0 +1,3 @@
+[Unit]
+Description=VyOS target
+After=multi-user.target
diff --git a/src/tests/test_configverify.py b/src/tests/test_configverify.py
index 6fb43ece2..15ccdf13d 100644
--- a/src/tests/test_configverify.py
+++ b/src/tests/test_configverify.py
@@ -16,7 +16,7 @@
from unittest import TestCase
from vyos.configverify import verify_diffie_hellman_length
-from vyos.util import cmd
+from vyos.utils.process import cmd
dh_file = '/tmp/dh.pem'
diff --git a/src/tests/test_dict_search.py b/src/tests/test_dict_search.py
index 1028437b2..2435d89c7 100644
--- a/src/tests/test_dict_search.py
+++ b/src/tests/test_dict_search.py
@@ -15,8 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from unittest import TestCase
-from vyos.util import dict_search
-from vyos.util import dict_search_recursive
+from vyos.utils.dict import dict_search
+from vyos.utils.dict import dict_search_recursive
data = {
'string': 'fooo',
diff --git a/src/tests/test_find_device_file.py b/src/tests/test_find_device_file.py
index 43c80dc76..f18043d65 100755
--- a/src/tests/test_find_device_file.py
+++ b/src/tests/test_find_device_file.py
@@ -15,7 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from unittest import TestCase
-from vyos.util import find_device_file
+from vyos.utils.system import find_device_file
class TestDeviceFile(TestCase):
""" used to find USB devices on target """
diff --git a/src/tests/test_util.py b/src/tests/test_util.py
index 473052bef..27ee648d4 100644
--- a/src/tests/test_util.py
+++ b/src/tests/test_util.py
@@ -15,14 +15,15 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from unittest import TestCase
-from vyos.util import *
class TestVyOSUtil(TestCase):
- def test_key_mangline(self):
+ def test_key_mangling(self):
+ from vyos.utils.dict import mangle_dict_keys
data = {"foo-bar": {"baz-quux": None}}
expected_data = {"foo_bar": {"baz_quux": None}}
new_data = mangle_dict_keys(data, '-', '_')
self.assertEqual(new_data, expected_data)
def test_sysctl_read(self):
+ from vyos.utils.system import sysctl_read
self.assertEqual(sysctl_read('net.ipv4.conf.lo.forwarding'), '1')
diff --git a/src/validators/port-multi b/src/validators/port-multi
index bd6f0ef60..ed6ff6849 100755
--- a/src/validators/port-multi
+++ b/src/validators/port-multi
@@ -4,7 +4,7 @@ from sys import argv
from sys import exit
import re
-from vyos.util import read_file
+from vyos.utils.file import read_file
services_file = '/etc/services'
diff --git a/src/validators/port-range b/src/validators/port-range
index 5468000a7..526c639ad 100755
--- a/src/validators/port-range
+++ b/src/validators/port-range
@@ -3,7 +3,7 @@
import sys
import re
-from vyos.util import read_file
+from vyos.utils.file import read_file
services_file = '/etc/services'
diff --git a/src/validators/script b/src/validators/script
index 4ffdeb2a0..eb176d23b 100755
--- a/src/validators/script
+++ b/src/validators/script
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2018-2021 VyOS maintainers and contributors
+# Copyright (C) 2018-2023 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
@@ -19,7 +19,7 @@ import os
import sys
import shlex
-import vyos.util
+from vyos.utils.file import file_is_persistent
if __name__ == '__main__':
if len(sys.argv) < 2:
@@ -35,7 +35,7 @@ if __name__ == '__main__':
sys.exit(f'File {script} is not an executable file')
# File outside the config dir is just a warning
- if not vyos.util.file_is_persistent(script):
+ if not file_is_persistent(script):
sys.exit(0)(
f'Warning: file {script} is outside the "/config" directory\n'
'It will not be automatically migrated to a new image on system update'
diff --git a/src/validators/timezone b/src/validators/timezone
index 107571181..e55af8d2a 100755
--- a/src/validators/timezone
+++ b/src/validators/timezone
@@ -17,7 +17,7 @@
import argparse
import sys
-from vyos.util import cmd
+from vyos.utils.process import cmd
if __name__ == '__main__':