summaryrefslogtreecommitdiff
path: root/src/op_mode
diff options
context:
space:
mode:
Diffstat (limited to 'src/op_mode')
-rwxr-xr-xsrc/op_mode/ping.py10
-rwxr-xr-xsrc/op_mode/restart_frr.py133
-rwxr-xr-xsrc/op_mode/show_dhcp.py8
-rwxr-xr-xsrc/op_mode/show_interfaces.py30
-rwxr-xr-xsrc/op_mode/show_system_integrity.py70
-rwxr-xr-xsrc/op_mode/show_wwan.py18
6 files changed, 92 insertions, 177 deletions
diff --git a/src/op_mode/ping.py b/src/op_mode/ping.py
index 2144ab53c..60bbc0c78 100755
--- a/src/op_mode/ping.py
+++ b/src/op_mode/ping.py
@@ -62,8 +62,8 @@ options = {
},
'interface': {
'ping': '{command} -I {value}',
- 'type': '<interface> <X.X.X.X> <h:h:h:h:h:h:h:h>',
- 'help': 'Interface to use as source for ping'
+ 'type': '<interface>',
+ 'help': 'Source interface'
},
'interval': {
'ping': '{command} -i {value}',
@@ -115,6 +115,10 @@ options = {
'type': '<bytes>',
'help': 'Number of bytes to send'
},
+ 'source-address': {
+ 'ping': '{command} -I {value}',
+ 'type': '<x.x.x.x> <h:h:h:h:h:h:h:h>',
+ },
'ttl': {
'ping': '{command} -t {value}',
'type': '<ttl>',
@@ -234,4 +238,4 @@ if __name__ == '__main__':
# print(f'{command} {host}')
os.system(f'{command} {host}')
- \ No newline at end of file
+
diff --git a/src/op_mode/restart_frr.py b/src/op_mode/restart_frr.py
index d1b66b33f..109c8dd7b 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 VyOS maintainers and contributors
+# Copyright (C) 2019-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
@@ -13,16 +13,19 @@
#
# 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 os
import argparse
import logging
-from logging.handlers import SysLogHandler
-from pathlib import Path
import psutil
+from logging.handlers import SysLogHandler
+from shutil import rmtree
+
from vyos.util import call
+from vyos.util import ask_yes_no
+from vyos.util import process_named_running
+from vyos.util import makedir
# some default values
watchfrr = '/usr/lib/frr/watchfrr.sh'
@@ -40,40 +43,45 @@ logger.setLevel(logging.INFO)
def _check_safety():
try:
# print warning
- answer = input("WARNING: This is a potentially unsafe function! You may lose the connection to the router or active configuration after running this command. Use it at your own risk! Continue? [y/N]: ")
- if not answer.lower() == "y":
- logger.error("User aborted command")
+ if not ask_yes_no('WARNING: This is a potentially unsafe function!\n' \
+ 'You may lose the connection to the router or active configuration after\n' \
+ 'running this command. Use it at your own risk!\n\n'
+ 'Continue?'):
return False
# check if another restart process already running
if len([process for process in psutil.process_iter(attrs=['pid', 'name', 'cmdline']) if 'python' in process.info['name'] and 'restart_frr.py' in process.info['cmdline'][1]]) > 1:
- logger.error("Another restart_frr.py already running")
- answer = input("Another restart_frr.py process is already running. It is unsafe to continue. Do you want to process anyway? [y/N]: ")
- if not answer.lower() == "y":
+ message = 'Another restart_frr.py process is already running!'
+ logger.error(message)
+ if not ask_yes_no(f'\n{message} It is unsafe to continue.\n\n' \
+ 'Do you want to process anyway?'):
return False
# check if watchfrr.sh is running
- for process in psutil.process_iter(attrs=['pid', 'name', 'cmdline']):
- if 'bash' in process.info['name'] and watchfrr in process.info['cmdline']:
- logger.error("Another {} already running".format(watchfrr))
- answer = input("Another {} process is already running. It is unsafe to continue. Do you want to process anyway? [y/N]: ".format(watchfrr))
- if not answer.lower() == "y":
- return False
+ tmp = os.path.basename(watchfrr)
+ if process_named_running(tmp):
+ message = f'Another {tmp} process is already running.'
+ logger.error(message)
+ if not ask_yes_no(f'{message} It is unsafe to continue.\n\n' \
+ 'Do you want to process anyway?'):
+ return False
# check if vtysh is running
- for process in psutil.process_iter(attrs=['pid', 'name', 'cmdline']):
- if 'vtysh' in process.info['name']:
- logger.error("The vtysh is running by another task")
- answer = input("The vtysh is running by another task. It is unsafe to continue. Do you want to process anyway? [y/N]: ")
- if not answer.lower() == "y":
- return False
+ if process_named_running('vtysh'):
+ message = 'vtysh process is executed by another task.'
+ logger.error(message)
+ if not ask_yes_no(f'{message} It is unsafe to continue.\n\n' \
+ 'Do you want to process anyway?'):
+ return False
# check if temporary directory exists
- if Path(frrconfig_tmp).exists():
- logger.error("The temporary directory \"{}\" already exists".format(frrconfig_tmp))
- answer = input("The temporary directory \"{}\" already exists. It is unsafe to continue. Do you want to process anyway? [y/N]: ".format(frrconfig_tmp))
- if not answer.lower() == "y":
+ if os.path.exists(frrconfig_tmp):
+ message = f'Temporary directory "{frrconfig_tmp}" already exists!'
+ logger.error(message)
+ if not ask_yes_no(f'{message} It is unsafe to continue.\n\n' \
+ 'Do you want to process anyway?'):
return False
+
except:
logger.error("Something goes wrong in _check_safety()")
return False
@@ -84,94 +92,68 @@ def _check_safety():
# write active config to file
def _write_config():
# create temporary directory
- Path(frrconfig_tmp).mkdir(parents=False, exist_ok=True)
+ makedir(frrconfig_tmp)
# save frr.conf to it
- command = "{} -n -w --config_dir {} 2> /dev/null".format(vtysh, frrconfig_tmp)
+ command = f'{vtysh} -n -w --config_dir {frrconfig_tmp} 2> /dev/null'
return_code = call(command)
- if not return_code == 0:
- logger.error("Failed to save active config: \"{}\" returned exit code: {}".format(command, return_code))
+ if return_code != 0:
+ logger.error(f'Failed to save active config: "{command}" returned exit code: {return_code}')
return False
- logger.info("Active config saved to {}".format(frrconfig_tmp))
+ logger.info(f'Active config saved to {frrconfig_tmp}')
return True
# clear and remove temporary directory
def _cleanup():
- tmpdir = Path(frrconfig_tmp)
- try:
- if tmpdir.exists():
- for file in tmpdir.iterdir():
- file.unlink()
- tmpdir.rmdir()
- except:
- logger.error("Failed to remove temporary directory {}".format(frrconfig_tmp))
- print("Failed to remove temporary directory {}".format(frrconfig_tmp))
-
-# check if daemon is running
-def _daemon_check(daemon):
- command = "{} print_status {}".format(watchfrr, daemon)
- return_code = call(command)
- if not return_code == 0:
- logger.error("Daemon \"{}\" is not running".format(daemon))
- return False
-
- # return True if all checks were passed
- return True
+ if os.path.isdir(frrconfig_tmp):
+ rmtree(frrconfig_tmp)
# restart daemon
def _daemon_restart(daemon):
- command = "{} restart {}".format(watchfrr, daemon)
+ command = f'{watchfrr} restart {daemon}'
return_code = call(command)
if not return_code == 0:
- logger.error("Failed to restart daemon \"{}\"".format(daemon))
+ logger.error(f'Failed to restart daemon "{daemon}"!')
return False
# return True if restarted successfully
- logger.info("Daemon \"{}\" restarted".format(daemon))
+ logger.info(f'Daemon "{daemon}" restarted!')
return True
# reload old config
def _reload_config(daemon):
if daemon != '':
- command = "{} -n -b --config_dir {} -d {} 2> /dev/null".format(vtysh, frrconfig_tmp, daemon)
+ command = f'{vtysh} -n -b --config_dir {frrconfig_tmp} -d {daemon} 2> /dev/null'
else:
- command = "{} -n -b --config_dir {} 2> /dev/null".format(vtysh, frrconfig_tmp)
+ command = f'{vtysh} -n -b --config_dir {frrconfig_tmp} 2> /dev/null'
return_code = call(command)
if not return_code == 0:
- logger.error("Failed to reinstall configuration")
+ logger.error('Failed to re-install configuration!')
return False
# return True if restarted successfully
- logger.info("Configuration reinstalled successfully")
- return True
-
-# check all daemons if they are running
-def _check_args_daemon(daemons):
- for daemon in daemons:
- if not _daemon_check(daemon):
- return False
+ logger.info('Configuration re-installed successfully!')
return True
# define program arguments
cmd_args_parser = argparse.ArgumentParser(description='restart frr daemons')
cmd_args_parser.add_argument('--action', choices=['restart'], required=True, help='action to frr daemons')
-cmd_args_parser.add_argument('--daemon', choices=['bfdd', 'bgpd', 'ospfd', 'ospf6d', 'ripd', 'ripngd', 'staticd', 'zebra'], required=False, nargs='*', help='select single or multiple daemons')
+cmd_args_parser.add_argument('--daemon', choices=['bfdd', 'bgpd', 'ospfd', 'ospf6d', 'isisd', 'ripd', 'ripngd', 'staticd', 'zebra'], required=False, nargs='*', help='select single or multiple daemons')
# parse arguments
cmd_args = cmd_args_parser.parse_args()
-
# main logic
# restart daemon
if cmd_args.action == 'restart':
# check if it is safe to restart FRR
if not _check_safety():
print("\nOne of the safety checks was failed or user aborted command. Exiting.")
- sys.exit(1)
+ exit(1)
if not _write_config():
print("Failed to save active config")
_cleanup()
- sys.exit(1)
+ exit(1)
# a little trick to make further commands more clear
if not cmd_args.daemon:
@@ -179,19 +161,20 @@ if cmd_args.action == 'restart':
# check all daemons if they are running
if cmd_args.daemon != ['']:
- if not _check_args_daemon(cmd_args.daemon):
- print("Warning: some of listed daemons are not running")
+ for daemon in cmd_args.daemon:
+ if not process_named_running(daemon):
+ print('WARNING: some of listed daemons are not running!')
# run command to restart daemon
for daemon in cmd_args.daemon:
if not _daemon_restart(daemon):
- print("Failed to restart daemon: {}".format(daemon))
+ print('Failed to restart daemon: {daemon}')
_cleanup()
- sys.exit(1)
+ exit(1)
# reinstall old configuration
_reload_config(daemon)
# cleanup after all actions
_cleanup()
-sys.exit(0)
+exit(0)
diff --git a/src/op_mode/show_dhcp.py b/src/op_mode/show_dhcp.py
index ff1e3cc56..9f65b1bd6 100755
--- a/src/op_mode/show_dhcp.py
+++ b/src/op_mode/show_dhcp.py
@@ -178,7 +178,7 @@ if __name__ == '__main__':
group = parser.add_mutually_exclusive_group()
group.add_argument("-l", "--leases", action="store_true", help="Show DHCP leases")
group.add_argument("-s", "--statistics", action="store_true", help="Show DHCP statistics")
- group.add_argument("--allowed", type=str, choices=["pool", "sort", "state"], help="Show allowed values for argument")
+ group.add_argument("--allowed", type=str, choices=["sort", "state"], help="Show allowed values for argument")
parser.add_argument("-p", "--pool", type=str, help="Show lease for specific pool")
parser.add_argument("-S", "--sort", type=str, default='ip', help="Sort by")
@@ -189,11 +189,7 @@ if __name__ == '__main__':
conf = Config()
- if args.allowed == 'pool':
- if conf.exists_effective('service dhcp-server'):
- print(' '.join(conf.list_effective_nodes("service dhcp-server shared-network-name")))
- exit(0)
- elif args.allowed == 'sort':
+ if args.allowed == 'sort':
print(' '.join(lease_display_fields.keys()))
exit(0)
elif args.allowed == 'state':
diff --git a/src/op_mode/show_interfaces.py b/src/op_mode/show_interfaces.py
index 79bb8e2a6..aef2d8060 100755
--- a/src/op_mode/show_interfaces.py
+++ b/src/op_mode/show_interfaces.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
-# Copyright 2017, 2019 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright 2017-2021 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
@@ -19,9 +19,7 @@ import os
import re
import sys
import glob
-import datetime
import argparse
-import netifaces
from vyos.ifconfig import Section
from vyos.ifconfig import Interface
@@ -54,27 +52,27 @@ def filtered_interfaces(ifnames, iftypes, vif, vrrp):
ifnames: a list of interfaces names to consider, empty do not filter
return an instance of the interface class
"""
- allnames = Section.interfaces()
+ if isinstance(iftypes, list):
+ for iftype in iftypes:
+ yield from filtered_interfaces(ifnames, iftype, vif, vrrp)
- vrrp_interfaces = VRRP.active_interfaces() if vrrp else []
-
- for ifname in allnames:
+ for ifname in Section.interfaces(iftypes):
+ # Bail out early if interface name not part of our search list
if ifnames and ifname not in ifnames:
continue
- # return the class which can handle this interface name
- klass = Section.klass(ifname)
- # connect to the interface
- interface = klass(ifname, create=False, debug=False)
-
- if iftypes and interface.definition['section'] not in iftypes:
- continue
+ # As we are only "reading" from the interface - we must use the
+ # generic base class which exposes all the data via a common API
+ interface = Interface(ifname, create=False, debug=False)
+ # VLAN interfaces have a '.' in their name by convention
if vif and not '.' in ifname:
continue
- if vrrp and ifname not in vrrp_interfaces:
- continue
+ if vrrp:
+ vrrp_interfaces = VRRP.active_interfaces()
+ if ifname not in vrrp_interfaces:
+ continue
yield interface
diff --git a/src/op_mode/show_system_integrity.py b/src/op_mode/show_system_integrity.py
deleted file mode 100755
index c34d41e80..000000000
--- a/src/op_mode/show_system_integrity.py
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright (C) 2020 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 sys
-import os
-import re
-import json
-from datetime import datetime, timedelta
-
-version_file = r'/usr/share/vyos/version.json'
-
-
-def _get_sys_build_version():
- if not os.path.exists(version_file):
- return None
- buf = open(version_file, 'r').read()
- j = json.loads(buf)
- if not 'built_on' in j:
- return None
- return datetime.strptime(j['built_on'], '%a %d %b %Y %H:%M %Z')
-
-
-def _check_pkgs(build_stamp):
- pkg_diffs = {
- 'buildtime': str(build_stamp),
- 'pkg': {}
- }
-
- pkg_info = os.listdir('/var/lib/dpkg/info/')
- for file in pkg_info:
- if re.search('\.list$', file):
- fts = os.stat('/var/lib/dpkg/info/' + file).st_mtime
- dt_str = (datetime.utcfromtimestamp(
- fts).strftime('%Y-%m-%d %H:%M:%S'))
- fdt = datetime.strptime(dt_str, '%Y-%m-%d %H:%M:%S')
- if fdt > build_stamp:
- pkg_diffs['pkg'].update(
- {str(re.sub('\.list', '', file)): str(fdt)})
-
- if len(pkg_diffs['pkg']) != 0:
- return pkg_diffs
- else:
- return None
-
-
-if __name__ == '__main__':
- built_date = _get_sys_build_version()
- if not built_date:
- sys.exit(1)
- pkgs = _check_pkgs(built_date)
- if pkgs:
- print (
- "The following packages don\'t fit the image creation time\nbuild time:\t" + pkgs['buildtime'])
- for k, v in pkgs['pkg'].items():
- print ("installed: " + v + '\t' + k)
diff --git a/src/op_mode/show_wwan.py b/src/op_mode/show_wwan.py
index 249dda2a5..529b5bd0f 100755
--- a/src/op_mode/show_wwan.py
+++ b/src/op_mode/show_wwan.py
@@ -34,13 +34,17 @@ required = parser.add_argument_group('Required arguments')
required.add_argument("--interface", help="WWAN interface name, e.g. wwan0", required=True)
def qmi_cmd(device, command, silent=False):
- tmp = cmd(f'qmicli --device={device} --device-open-proxy {command}')
- tmp = tmp.replace(f'[{cdc}] ', '')
- if not silent:
- # skip first line as this only holds the info headline
- for line in tmp.splitlines()[1:]:
- print(line.lstrip())
- return tmp
+ try:
+ tmp = cmd(f'qmicli --device={device} --device-open-proxy {command}')
+ tmp = tmp.replace(f'[{cdc}] ', '')
+ if not silent:
+ # skip first line as this only holds the info headline
+ for line in tmp.splitlines()[1:]:
+ print(line.lstrip())
+ return tmp
+ except:
+ print('Command not supported by Modem')
+ exit(1)
if __name__ == '__main__':
args = parser.parse_args()