diff options
-rw-r--r-- | data/templates/monitoring/telegraf.tmpl | 1 | ||||
-rw-r--r-- | data/templates/ntp/ntpd.conf.tmpl | 1 | ||||
-rw-r--r-- | interface-definitions/firewall.xml.in | 2 | ||||
-rw-r--r-- | interface-definitions/interfaces-wireguard.xml.in | 1 | ||||
-rw-r--r-- | op-mode-definitions/show-virtual-server.xml.in | 13 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_system_ntp.py | 60 | ||||
-rwxr-xr-x | src/conf_mode/service_monitoring_telegraf.py | 25 | ||||
-rwxr-xr-x | src/etc/telegraf/custom_scripts/show_interfaces_input_filter.py | 123 | ||||
-rwxr-xr-x | src/helpers/strip-private.py | 10 | ||||
-rwxr-xr-x | src/migration-scripts/bgp/1-to-2 | 2 | ||||
-rwxr-xr-x | src/migration-scripts/dns-forwarding/1-to-2 | 83 | ||||
-rwxr-xr-x | src/migration-scripts/interfaces/11-to-12 | 2 | ||||
-rwxr-xr-x | src/migration-scripts/interfaces/12-to-13 | 2 | ||||
-rwxr-xr-x | src/migration-scripts/interfaces/22-to-23 | 2 | ||||
-rwxr-xr-x | src/migration-scripts/interfaces/5-to-6 | 9 | ||||
-rwxr-xr-x | src/migration-scripts/interfaces/9-to-10 | 2 | ||||
-rwxr-xr-x | src/op_mode/show_virtual_server.py | 33 | ||||
-rwxr-xr-x | src/op_mode/vrrp.py | 13 |
18 files changed, 243 insertions, 141 deletions
diff --git a/data/templates/monitoring/telegraf.tmpl b/data/templates/monitoring/telegraf.tmpl index 62fa4df7a..afc04aa6d 100644 --- a/data/templates/monitoring/telegraf.tmpl +++ b/data/templates/monitoring/telegraf.tmpl @@ -41,6 +41,7 @@ files = ["ip_conntrack_count","ip_conntrack_max","nf_conntrack_count","nf_conntrack_max"] dirs = ["/proc/sys/net/ipv4/netfilter","/proc/sys/net/netfilter"] [[inputs.ethtool]] + interface_include = {{ interfaces_ethernet }} [[inputs.iptables]] use_sudo = false table = "filter" diff --git a/data/templates/ntp/ntpd.conf.tmpl b/data/templates/ntp/ntpd.conf.tmpl index 38e68f24f..e7afcc16b 100644 --- a/data/templates/ntp/ntpd.conf.tmpl +++ b/data/templates/ntp/ntpd.conf.tmpl @@ -27,6 +27,7 @@ restrict -6 ::1 {% if allow_clients is defined and allow_clients.address is defined %} # Allowed clients configuration +restrict default ignore {% for address in allow_clients.address %} restrict {{ address|address_from_cidr }} mask {{ address|netmask_from_cidr }} nomodify notrap nopeer {% endfor %} diff --git a/interface-definitions/firewall.xml.in b/interface-definitions/firewall.xml.in index f428efe58..fd98ae138 100644 --- a/interface-definitions/firewall.xml.in +++ b/interface-definitions/firewall.xml.in @@ -125,7 +125,7 @@ </tagNode> <tagNode name="ipv6-network-group"> <properties> - <help>Network-group member</help> + <help>Firewall ipv6-network-group</help> </properties> <children> #include <include/generic-description.xml.i> diff --git a/interface-definitions/interfaces-wireguard.xml.in b/interface-definitions/interfaces-wireguard.xml.in index 7a7c9c1d9..1b4b4a816 100644 --- a/interface-definitions/interfaces-wireguard.xml.in +++ b/interface-definitions/interfaces-wireguard.xml.in @@ -101,6 +101,7 @@ </valueHelp> <constraint> <validator name="ip-address"/> + <validator name="ipv6-link-local"/> </constraint> </properties> </leafNode> diff --git a/op-mode-definitions/show-virtual-server.xml.in b/op-mode-definitions/show-virtual-server.xml.in new file mode 100644 index 000000000..5dbd3c759 --- /dev/null +++ b/op-mode-definitions/show-virtual-server.xml.in @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interfaceDefinition> + <node name="show"> + <children> + <node name="virtual-server"> + <properties> + <help>Show virtual server information</help> + </properties> + <command>${vyos_op_scripts_dir}/show_virtual_server.py</command> + </node> + </children> + </node> +</interfaceDefinition> diff --git a/smoketest/scripts/cli/test_system_ntp.py b/smoketest/scripts/cli/test_system_ntp.py index e8cc64463..c8cf04b7d 100755 --- a/smoketest/scripts/cli/test_system_ntp.py +++ b/smoketest/scripts/cli/test_system_ntp.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2019-2020 VyOS maintainers and contributors +# Copyright (C) 2019-2022 VyOS maintainers and contributors # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 or later as @@ -14,7 +14,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 re import unittest from base_vyostest_shim import VyOSUnitTestSHIM @@ -29,17 +28,14 @@ PROCESS_NAME = 'ntpd' NTP_CONF = '/run/ntpd/ntpd.conf' base_path = ['system', 'ntp'] -def get_config_value(key): - tmp = read_file(NTP_CONF) - tmp = re.findall(r'\n?{}\s+(.*)'.format(key), tmp) - # remove possible trailing whitespaces - return [item.strip() for item in tmp] - class TestSystemNTP(VyOSUnitTestSHIM.TestCase): - def setUp(self): + @classmethod + def setUpClass(cls): + super(cls, cls).setUpClass() + # ensure we can also run this test on a live system - so lets clean # out the current configuration :) - self.cli_delete(base_path) + cls.cli_delete(cls, base_path) def tearDown(self): self.cli_delete(base_path) @@ -47,35 +43,38 @@ class TestSystemNTP(VyOSUnitTestSHIM.TestCase): self.assertFalse(process_named_running(PROCESS_NAME)) - def test_ntp_options(self): + def test_01_ntp_options(self): # Test basic NTP support with multiple servers and their options servers = ['192.0.2.1', '192.0.2.2'] options = ['noselect', 'preempt', 'prefer'] - ntp_pool = 'pool.vyos.io' + pools = ['pool.vyos.io'] for server in servers: for option in options: self.cli_set(base_path + ['server', server, option]) # Test NTP pool - self.cli_set(base_path + ['server', ntp_pool, 'pool']) + for pool in pools: + self.cli_set(base_path + ['server', pool, 'pool']) # commit changes self.cli_commit() # Check generated configuration - tmp = get_config_value('server') - for server in servers: - test = f'{server} iburst ' + ' '.join(options) - self.assertTrue(test in tmp) + config = read_file(NTP_CONF) + self.assertIn('driftfile /var/lib/ntp/ntp.drift', config) + self.assertIn('restrict default noquery nopeer notrap nomodify', config) + self.assertIn('restrict source nomodify notrap noquery', config) + self.assertIn('restrict 127.0.0.1', config) + self.assertIn('restrict -6 ::1', config) - tmp = get_config_value('pool') - self.assertTrue(f'{ntp_pool} iburst' in tmp) + for server in servers: + self.assertIn(f'server {server} iburst ' + ' '.join(options), config) - # Check for running process - self.assertTrue(process_named_running(PROCESS_NAME)) + for pool in pools: + self.assertIn(f'pool {pool} iburst', config) - def test_ntp_clients(self): + def test_02_ntp_clients(self): # Test the allowed-networks statement listen_address = ['127.0.0.1', '::1'] for listen in listen_address: @@ -96,23 +95,18 @@ class TestSystemNTP(VyOSUnitTestSHIM.TestCase): self.cli_commit() # Check generated client address configuration + config = read_file(NTP_CONF) + self.assertIn('restrict default ignore', config) + for network in networks: network_address = address_from_cidr(network) network_netmask = netmask_from_cidr(network) - - tmp = get_config_value(f'restrict {network_address}')[0] - test = f'mask {network_netmask} nomodify notrap nopeer' - self.assertTrue(tmp in test) + self.assertIn(f'restrict {network_address} mask {network_netmask} nomodify notrap nopeer', config) # Check listen address - tmp = get_config_value('interface') - test = ['ignore wildcard'] + self.assertIn('interface ignore wildcard', config) for listen in listen_address: - test.append(f'listen {listen}') - self.assertEqual(tmp, test) - - # Check for running process - self.assertTrue(process_named_running(PROCESS_NAME)) + self.assertIn(f'interface listen {listen}', config) if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/src/conf_mode/service_monitoring_telegraf.py b/src/conf_mode/service_monitoring_telegraf.py index a1e7a7286..8a972b9fe 100755 --- a/src/conf_mode/service_monitoring_telegraf.py +++ b/src/conf_mode/service_monitoring_telegraf.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2021 VyOS maintainers and contributors +# Copyright (C) 2021-2022 VyOS maintainers and contributors # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 or later as @@ -22,6 +22,7 @@ from shutil import rmtree from vyos.config import Config from vyos.configdict import dict_merge +from vyos.ifconfig import Section from vyos.template import render from vyos.util import call from vyos.util import chown @@ -42,6 +43,24 @@ systemd_telegraf_override_dir = '/etc/systemd/system/vyos-telegraf.service.d' systemd_override = f'{systemd_telegraf_override_dir}/10-override.conf' +def get_interfaces(type='', vlan=True): + """ + Get interfaces + get_interfaces() + ['dum0', 'eth0', 'eth1', 'eth1.5', 'lo', 'tun0'] + + get_interfaces("dummy") + ['dum0'] + """ + interfaces = [] + ifaces = Section.interfaces(type) + for iface in ifaces: + if vlan == False and '.' in iface: + continue + interfaces.append(iface) + + return interfaces + def get_nft_filter_chains(): """ Get nft chains for table filter @@ -57,6 +76,7 @@ def get_nft_filter_chains(): return chain_list + def get_config(config=None): if config: @@ -75,8 +95,9 @@ def get_config(config=None): default_values = defaults(base) monitoring = dict_merge(default_values, monitoring) - monitoring['nft_chains'] = get_nft_filter_chains() monitoring['custom_scripts_dir'] = custom_scripts_dir + monitoring['interfaces_ethernet'] = get_interfaces('ethernet', vlan=False) + monitoring['nft_chains'] = get_nft_filter_chains() return monitoring diff --git a/src/etc/telegraf/custom_scripts/show_interfaces_input_filter.py b/src/etc/telegraf/custom_scripts/show_interfaces_input_filter.py index 0f5e366cd..0c7474156 100755 --- a/src/etc/telegraf/custom_scripts/show_interfaces_input_filter.py +++ b/src/etc/telegraf/custom_scripts/show_interfaces_input_filter.py @@ -1,47 +1,88 @@ #!/usr/bin/env python3 -import subprocess +from vyos.ifconfig import Section +from vyos.ifconfig import Interface + import time -def status_to_int(status): - switcher={ - 'u':'0', - 'D':'1', - 'A':'2' - } - return switcher.get(status,"") - -def description_check(line): - desc=" ".join(line[3:]) - if desc == "": +def get_interfaces(type='', vlan=True): + """ + Get interfaces: + ['dum0', 'eth0', 'eth1', 'eth1.5', 'lo', 'tun0'] + """ + interfaces = [] + ifaces = Section.interfaces(type) + for iface in ifaces: + if vlan == False and '.' in iface: + continue + interfaces.append(iface) + + return interfaces + +def get_interface_addresses(iface, link_local_v6=False): + """ + Get IP and IPv6 addresses from interface in one string + By default don't get IPv6 link-local addresses + If interface doesn't have address, return "-" + """ + addresses = [] + addrs = Interface(iface).get_addr() + + for addr in addrs: + if link_local_v6 == False: + if addr.startswith('fe80::'): + continue + addresses.append(addr) + + if not addresses: + return "-" + + return (" ".join(addresses)) + +def get_interface_description(iface): + """ + Get interface description + If none return "empty" + """ + description = Interface(iface).get_alias() + + if not description: return "empty" + + return description + +def get_interface_admin_state(iface): + """ + Interface administrative state + up => 0, down => 2 + """ + state = Interface(iface).get_admin_state() + if state == 'up': + admin_state = 0 + if state == 'down': + admin_state = 2 + + return admin_state + +def get_interface_oper_state(iface): + """ + Interface operational state + up => 0, down => 1 + """ + state = Interface(iface).operational.get_state() + if state == 'down': + oper_state = 1 else: - return desc - -def gen_ip_list(index,interfaces): - line=interfaces[index].split() - ip_list=line[1] - if index < len(interfaces): - index += 1 - while len(interfaces[index].split())==1: - ip = interfaces[index].split() - ip_list = ip_list + " " + ip[0] - index += 1 - if index == len(interfaces): - break - return ip_list - -interfaces = subprocess.check_output("/usr/libexec/vyos/op_mode/show_interfaces.py --action=show-brief", shell=True).decode('utf-8').splitlines() -del interfaces[:3] -lines_count=len(interfaces) -index=0 -while index<lines_count: - line=interfaces[index].split() - if len(line)>1: - print(f'show_interfaces,interface={line[0]} ' - f'ip_addresses="{gen_ip_list(index,interfaces)}",' - f'state={status_to_int(line[2][0])}i,' - f'link={status_to_int(line[2][2])}i,' - f'description="{description_check(line)}" ' - f'{str(int(time.time()))}000000000') - index += 1 + oper_state = 0 + + return oper_state + +interfaces = get_interfaces() + +for iface in interfaces: + print(f'show_interfaces,interface={iface} ' + f'ip_addresses="{get_interface_addresses(iface)}",' + f'state={get_interface_admin_state(iface)}i,' + f'link={get_interface_oper_state(iface)}i,' + f'description="{get_interface_description(iface)}" ' + f'{str(int(time.time()))}000000000') diff --git a/src/helpers/strip-private.py b/src/helpers/strip-private.py index e4e1fe11d..eb584edaf 100755 --- a/src/helpers/strip-private.py +++ b/src/helpers/strip-private.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 -# Copyright 2021 VyOS maintainers and contributors <maintainers@vyos.io> +# Copyright 2021-2022 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 @@ -111,6 +111,10 @@ if __name__ == "__main__": (True, re.compile(r'public-keys \S+'), 'public-keys xxxx@xxx.xxx'), (True, re.compile(r'type \'ssh-(rsa|dss)\''), 'type ssh-xxx'), (True, re.compile(r' key \S+'), ' key xxxxxx'), + # Strip bucket + (True, re.compile(r' bucket \S+'), ' bucket xxxxxx'), + # Strip tokens + (True, re.compile(r' token \S+'), ' token xxxxxx'), # Strip OpenVPN secrets (True, re.compile(r'(shared-secret-key-file|ca-cert-file|cert-file|dh-file|key-file|client) (\S+)'), r'\1 xxxxxx'), # Strip IPSEC secrets @@ -123,8 +127,8 @@ if __name__ == "__main__": # Strip MAC addresses (args.mac, re.compile(r'([0-9a-fA-F]{2}\:){5}([0-9a-fA-F]{2}((\:{0,1})){3})'), r'xx:xx:xx:xx:xx:\2'), - # Strip host-name, domain-name, and domain-search - (args.hostname, re.compile(r'(host-name|domain-name|domain-search) \S+'), r'\1 xxxxxx'), + # Strip host-name, domain-name, domain-search and url + (args.hostname, re.compile(r'(host-name|domain-name|domain-search|url) \S+'), r'\1 xxxxxx'), # Strip user-names (args.username, re.compile(r'(user|username|user-id) \S+'), r'\1 xxxxxx'), diff --git a/src/migration-scripts/bgp/1-to-2 b/src/migration-scripts/bgp/1-to-2 index 4c6d5ceb8..4aa24bf3c 100755 --- a/src/migration-scripts/bgp/1-to-2 +++ b/src/migration-scripts/bgp/1-to-2 @@ -52,8 +52,6 @@ if config.exists(base + ['parameters', 'default', 'no-ipv4-unicast']): if len(config.list_nodes(base + ['parameters'])) == 0: config.delete(base + ['parameters']) - exit(0) - # As we now install a new default option into BGP we need to migrate all # existing BGP neighbors and restore the old behavior if config.exists(base + ['neighbor']): diff --git a/src/migration-scripts/dns-forwarding/1-to-2 b/src/migration-scripts/dns-forwarding/1-to-2 index ba10c26f2..a8c930be7 100755 --- a/src/migration-scripts/dns-forwarding/1-to-2 +++ b/src/migration-scripts/dns-forwarding/1-to-2 @@ -16,7 +16,7 @@ # # This migration script will remove the deprecated 'listen-on' statement -# from the dns forwarding service and will add the corresponding +# from the dns forwarding service and will add the corresponding # listen-address nodes instead. This is required as PowerDNS can only listen # on interface addresses and not on interface names. @@ -37,53 +37,50 @@ with open(file_name, 'r') as f: config = ConfigTree(config_file) base = ['service', 'dns', 'forwarding'] -if not config.exists(base): +if not config.exists(base + ['listen-on']): # Nothing to do exit(0) -if config.exists(base + ['listen-on']): - listen_intf = config.return_values(base + ['listen-on']) - # Delete node with abandoned command - config.delete(base + ['listen-on']) +listen_intf = config.return_values(base + ['listen-on']) +# Delete node with abandoned command +config.delete(base + ['listen-on']) - # retrieve interface addresses for every configured listen-on interface - listen_addr = [] - for intf in listen_intf: - # we need to evaluate the interface section before manipulating the 'intf' variable - section = Interface.section(intf) - if not section: - raise ValueError(f'Invalid interface name {intf}') +# retrieve interface addresses for every configured listen-on interface +listen_addr = [] +for intf in listen_intf: + # we need to evaluate the interface section before manipulating the 'intf' variable + section = Interface.section(intf) + if not section: + raise ValueError(f'Invalid interface name {intf}') - # we need to treat vif and vif-s interfaces differently, - # both "real interfaces" use dots for vlan identifiers - those - # need to be exchanged with vif and vif-s identifiers - if intf.count('.') == 1: - # this is a regular VLAN interface - intf = intf.split('.')[0] + ' vif ' + intf.split('.')[1] - elif intf.count('.') == 2: - # this is a QinQ VLAN interface - intf = intf.split('.')[0] + ' vif-s ' + intf.split('.')[1] + ' vif-c ' + intf.split('.')[2] - - # retrieve corresponding interface addresses in CIDR format - # those need to be converted in pure IP addresses without network information - path = ['interfaces', section, intf, 'address'] - try: - for addr in config.return_values(path): - listen_addr.append( ip_interface(addr).ip ) - except: - # Some interface types do not use "address" option (e.g. OpenVPN) - # and may not even have a fixed address - print("Could not retrieve the address of the interface {} from the config".format(intf)) - print("You will need to update your DNS forwarding configuration manually") - - for addr in listen_addr: - config.set(base + ['listen-address'], value=addr, replace=False) + # we need to treat vif and vif-s interfaces differently, + # both "real interfaces" use dots for vlan identifiers - those + # need to be exchanged with vif and vif-s identifiers + if intf.count('.') == 1: + # this is a regular VLAN interface + intf = intf.split('.')[0] + ' vif ' + intf.split('.')[1] + elif intf.count('.') == 2: + # this is a QinQ VLAN interface + intf = intf.split('.')[0] + ' vif-s ' + intf.split('.')[1] + ' vif-c ' + intf.split('.')[2] + # retrieve corresponding interface addresses in CIDR format + # those need to be converted in pure IP addresses without network information + path = ['interfaces', section, intf, 'address'] try: - with open(file_name, 'w') as f: - f.write(config.to_string()) - except OSError as e: - print("Failed to save the modified config: {}".format(e)) - exit(1) + for addr in config.return_values(path): + listen_addr.append( ip_interface(addr).ip ) + except: + # Some interface types do not use "address" option (e.g. OpenVPN) + # and may not even have a fixed address + print("Could not retrieve the address of the interface {} from the config".format(intf)) + print("You will need to update your DNS forwarding configuration manually") -exit(0) +for addr in listen_addr: + config.set(base + ['listen-address'], value=addr, replace=False) + +try: + with open(file_name, 'w') as f: + f.write(config.to_string()) +except OSError as e: + print(f'Failed to save the modified config: {e}') + exit(1) diff --git a/src/migration-scripts/interfaces/11-to-12 b/src/migration-scripts/interfaces/11-to-12 index ca4ebe741..0dad24642 100755 --- a/src/migration-scripts/interfaces/11-to-12 +++ b/src/migration-scripts/interfaces/11-to-12 @@ -31,8 +31,6 @@ if __name__ == '__main__': config_file = f.read() config = ConfigTree(config_file) - if not config.exists(['interfaces']): - exit(0) for type in config.list_nodes(['interfaces']): for interface in config.list_nodes(['interfaces', type]): diff --git a/src/migration-scripts/interfaces/12-to-13 b/src/migration-scripts/interfaces/12-to-13 index fbd7e6f47..f866ca9a6 100755 --- a/src/migration-scripts/interfaces/12-to-13 +++ b/src/migration-scripts/interfaces/12-to-13 @@ -33,8 +33,6 @@ if __name__ == '__main__': config_file = f.read() config = ConfigTree(config_file) - if not config.exists(['interfaces']): - exit(0) # # T2903 diff --git a/src/migration-scripts/interfaces/22-to-23 b/src/migration-scripts/interfaces/22-to-23 index 734aa1fd8..06e07572f 100755 --- a/src/migration-scripts/interfaces/22-to-23 +++ b/src/migration-scripts/interfaces/22-to-23 @@ -84,8 +84,6 @@ if __name__ == '__main__': config_file = f.read() config = ConfigTree(config_file) - if not config.exists(['interfaces']): - exit(0) # # Migrate "interface ethernet eth0 ip ospf" to "protocols ospf interface eth0" diff --git a/src/migration-scripts/interfaces/5-to-6 b/src/migration-scripts/interfaces/5-to-6 index dc8d9554f..ae79c1d1b 100755 --- a/src/migration-scripts/interfaces/5-to-6 +++ b/src/migration-scripts/interfaces/5-to-6 @@ -107,15 +107,10 @@ if __name__ == '__main__': config_file = f.read() config = ConfigTree(config_file) - base = ['interfaces'] - - if not config.exists(base): - # Nothing to do - exit(0) # list all individual interface types like dummy, ethernet and so on - for if_type in config.list_nodes(base): - base_if_type = base + [if_type] + for if_type in config.list_nodes(['interfaces']): + base_if_type = ['interfaces', if_type] # for every individual interface we need to check if there is an # ipv6 ra configured ... and also for every VIF (VLAN) interface diff --git a/src/migration-scripts/interfaces/9-to-10 b/src/migration-scripts/interfaces/9-to-10 index c6311a24d..4aa2c42b5 100755 --- a/src/migration-scripts/interfaces/9-to-10 +++ b/src/migration-scripts/interfaces/9-to-10 @@ -32,8 +32,6 @@ if __name__ == '__main__': config_file = f.read() config = ConfigTree(config_file) - if not config.exists(['interfaces']): - exit(0) for intf_type in config.list_nodes(['interfaces']): for intf in config.list_nodes(['interfaces', intf_type]): diff --git a/src/op_mode/show_virtual_server.py b/src/op_mode/show_virtual_server.py new file mode 100755 index 000000000..377180dec --- /dev/null +++ b/src/op_mode/show_virtual_server.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2022 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from vyos.configquery import ConfigTreeQuery +from vyos.util import call + +def is_configured(): + """ Check if high-availability virtual-server is configured """ + config = ConfigTreeQuery() + if not config.exists(['high-availability', 'virtual-server']): + return False + return True + +if __name__ == '__main__': + + if is_configured() == False: + print('Virtual server not configured!') + exit(0) + + call('sudo ipvsadm --list --numeric') diff --git a/src/op_mode/vrrp.py b/src/op_mode/vrrp.py index 2c1db20bf..dab146d28 100755 --- a/src/op_mode/vrrp.py +++ b/src/op_mode/vrrp.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2018 VyOS maintainers and contributors +# Copyright (C) 2018-2022 VyOS maintainers and contributors # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 or later as @@ -23,6 +23,7 @@ import tabulate import vyos.util +from vyos.configquery import ConfigTreeQuery from vyos.ifconfig.vrrp import VRRP from vyos.ifconfig.vrrp import VRRPError, VRRPNoData @@ -35,7 +36,17 @@ group.add_argument("-d", "--data", action="store_true", help="Print detailed VRR args = parser.parse_args() +def is_configured(): + """ Check if VRRP is configured """ + config = ConfigTreeQuery() + if not config.exists(['high-availability', 'vrrp', 'group']): + return False + return True + # Exit early if VRRP is dead or not configured +if is_configured() == False: + print('VRRP not configured!') + exit(0) if not VRRP.is_running(): print('VRRP is not running') sys.exit(0) |