diff options
-rw-r--r-- | python/vyos/util.py | 35 | ||||
-rwxr-xr-x | src/conf_mode/host_name.py | 16 | ||||
-rwxr-xr-x | src/conf_mode/interfaces-tunnel.py | 7 | ||||
-rwxr-xr-x | src/conf_mode/snmp.py | 20 | ||||
-rwxr-xr-x | src/conf_mode/system-login.py | 8 | ||||
-rw-r--r-- | src/etc/systemd/system/pdns-recursor.service.d/override.conf | 2 | ||||
-rwxr-xr-x | src/op_mode/dns_forwarding_reset.py | 6 | ||||
-rwxr-xr-x | src/op_mode/dns_forwarding_statistics.py | 7 | ||||
-rwxr-xr-x | src/system/on-dhcp-event.sh | 2 |
9 files changed, 49 insertions, 54 deletions
diff --git a/python/vyos/util.py b/python/vyos/util.py index 49c47cd85..eb78c4a26 100644 --- a/python/vyos/util.py +++ b/python/vyos/util.py @@ -14,20 +14,16 @@ # License along with this library. If not, see <http://www.gnu.org/licenses/>. import os -import re -import sys -from subprocess import Popen -from subprocess import PIPE -from subprocess import STDOUT -from subprocess import DEVNULL -from vyos import debug +# +# NOTE: Do not import full classes here, move your import to the function +# where it is used so it is as local as possible to the execution +# # There is many (too many) ways to run command with python # os.system, subprocess.Popen, subproces.{run,call,check_output} # which all have slighty different behaviour - - +from subprocess import Popen, PIPE, STDOUT, DEVNULL def popen(command, flag='', shell=None, input=None, timeout=None, env=None, stdout=PIPE, stderr=None, decode=None): """ @@ -57,7 +53,7 @@ def popen(command, flag='', shell=None, input=None, timeout=None, env=None, to get both stdout, and stderr: popen('command', stdout=PIPE, stderr=STDOUT) to discard stdout and get stderr: popen('command', stdout=DEVNUL, stderr=PIPE) """ - + from vyos import debug # log if the flag is set, otherwise log if command is set if not debug.enabled(flag): flag = 'command' @@ -229,6 +225,7 @@ def colon_separated_to_dict(data_string, uniquekeys=False): If uniquekeys=True, then dict entries are always strings, otherwise they are always lists of strings. """ + import re key_value_re = re.compile('([^:]+)\s*\:\s*(.*)') data_raw = re.split('\n', data_string) @@ -268,6 +265,17 @@ def process_running(pid_file): return pid_exists(int(pid)) +def process_named_running(name): + """ Checks if process with given name is running and returns its PID. + If Process is not running, return None + """ + from psutil import process_iter + for p in process_iter(): + if name in p.name(): + return p.pid + return None + + def seconds_to_human(s, separator=""): """ Converts number of seconds passed to a human-readable interval such as 1w4d18h35m59s @@ -317,6 +325,7 @@ def get_cfg_group_id(): def file_is_persistent(path): + import re if not re.match(r'^(/config|/opt/vyatta/etc/config)', os.path.dirname(path)): warning = "Warning: file {0} is outside the /config directory\n".format(path) warning += "It will not be automatically migrated to a new image on system update" @@ -373,9 +382,10 @@ def wait_for_commit_lock(): def ask_yes_no(question, default=False) -> bool: """Ask a yes/no question via input() and return their answer.""" + from sys import stdout default_msg = "[Y/n]" if default else "[y/N]" while True: - sys.stdout.write("%s %s " % (question, default_msg)) + stdout.write("%s %s " % (question, default_msg)) c = input().lower() if c == '': return default @@ -384,7 +394,7 @@ def ask_yes_no(question, default=False) -> bool: elif c in ("n", "no"): return False else: - sys.stdout.write("Please respond with yes/y or no/n\n") + stdout.write("Please respond with yes/y or no/n\n") def is_admin() -> bool: @@ -402,6 +412,7 @@ def mac2eui64(mac, prefix=None): IPv6 address. Thankfully copied from https://gist.github.com/wido/f5e32576bb57b5cc6f934e177a37a0d3 """ + import re from ipaddress import ip_network # http://tools.ietf.org/html/rfc4291#section-2.5.1 eui64 = re.sub(r'[.:-]', '', mac).lower() diff --git a/src/conf_mode/host_name.py b/src/conf_mode/host_name.py index dd5819f9f..a669580ae 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 VyOS maintainers and contributors +# Copyright (C) 2018-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 @@ -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/>. -# -# """ conf-mode script for 'system host-name' and 'system domain-name'. @@ -33,10 +31,7 @@ import vyos.hostsd_client from vyos.config import Config from vyos import ConfigError -from vyos.util import cmd -from vyos.util import call -from vyos.util import run - +from vyos.util import cmd, call, run, process_named_running default_config_data = { 'hostname': 'vyos', @@ -166,12 +161,11 @@ def apply(config): call("systemctl restart rsyslog.service") # If SNMP is running, restart it too - ret = run("pgrep snmpd") - if ret == 0: - call("systemctl restart snmpd.service") + if process_named_running('snmpd'): + call('systemctl restart snmpd.service') # restart pdns if it is used - ret = run('/usr/bin/rec_control ping') + ret = run('/usr/bin/rec_control --socket-dir=/run/powerdns ping') if ret == 0: call('systemctl restart pdns-recursor.service') diff --git a/src/conf_mode/interfaces-tunnel.py b/src/conf_mode/interfaces-tunnel.py index c51048aeb..06c2ea29b 100755 --- a/src/conf_mode/interfaces-tunnel.py +++ b/src/conf_mode/interfaces-tunnel.py @@ -19,6 +19,7 @@ import netifaces from sys import exit from copy import deepcopy +from netifaces import interfaces from vyos.config import Config from vyos.ifconfig import Interface, GREIf, GRETapIf, IPIPIf, IP6GREIf, IPIP6If, IP6IP6If, SitIf, Sit6RDIf @@ -506,6 +507,12 @@ def verify(conf): if ipv6_count and not IP6 in kls.ip: print(f'Should not use IPv6 addresses on tunnel {iftype} {ifname}') + # vrf check + + vrf = options['vrf'] + if vrf and vrf not in interfaces(): + raise ConfigError(f'VRF "{vrf}" does not exist') + # tunnel encapsulation check convert = { diff --git a/src/conf_mode/snmp.py b/src/conf_mode/snmp.py index d654dcb84..7530da2dc 100755 --- a/src/conf_mode/snmp.py +++ b/src/conf_mode/snmp.py @@ -535,23 +535,9 @@ def apply(snmp): # start SNMP daemon call("systemctl restart snmpd.service") - # Passwords are not available immediately in the configuration file, - # after daemon startup - we wait until they have been processed by - # snmpd, which we see when a magic line appears in this file. - while True: - while not os.path.exists(config_file_user): - sleep(0.5) - - try: - with open(config_file_user, 'r') as f: - for line in f: - # Search for our magic string inside the file - if 'usmUser' in line: - break - except IOError: - continue - else: - break + while (call('systemctl -q is-active snmpd.service') != 0): + print("service not yet started") + sleep(0.5) # net-snmp is now regenerating the configuration file in the background # thus we need to re-open and re-read the file as the content changed. diff --git a/src/conf_mode/system-login.py b/src/conf_mode/system-login.py index 6008ca0b3..91e2b369f 100755 --- a/src/conf_mode/system-login.py +++ b/src/conf_mode/system-login.py @@ -16,6 +16,7 @@ import os +from crypt import crypt, METHOD_SHA512 from psutil import users from pwd import getpwall, getpwnam from stat import S_IRUSR, S_IWUSR, S_IRWXU, S_IRGRP, S_IXGRP @@ -52,11 +53,6 @@ def get_local_users(): return local_users - -def get_crypt_pw(password): - return cmd(f'/usr/bin/mkpasswd --method=sha-512 {password}') - - def get_config(): login = default_config_data conf = Config() @@ -204,7 +200,7 @@ def generate(login): # calculate users encrypted password for user in login['add_users']: if user['password_plaintext']: - user['password_encrypted'] = get_crypt_pw(user['password_plaintext']) + user['password_encrypted'] = crypt(user['password_plaintext'], METHOD_SHA512) user['password_plaintext'] = '' # remove old plaintext password diff --git a/src/etc/systemd/system/pdns-recursor.service.d/override.conf b/src/etc/systemd/system/pdns-recursor.service.d/override.conf index 602d7b774..ef4dec303 100644 --- a/src/etc/systemd/system/pdns-recursor.service.d/override.conf +++ b/src/etc/systemd/system/pdns-recursor.service.d/override.conf @@ -2,4 +2,4 @@ WorkingDirectory= WorkingDirectory=/run/powerdns ExecStart= -ExecStart=/usr/sbin/pdns_recursor --daemon=no --write-pid=no --disable-syslog --log-timestamp=no --config-dir=/run/powerdns +ExecStart=/usr/sbin/pdns_recursor --daemon=no --write-pid=no --disable-syslog --log-timestamp=no --config-dir=/run/powerdns --socket-dir=/run/powerdns diff --git a/src/op_mode/dns_forwarding_reset.py b/src/op_mode/dns_forwarding_reset.py index 8e2ee546c..bfc640a26 100755 --- a/src/op_mode/dns_forwarding_reset.py +++ b/src/op_mode/dns_forwarding_reset.py @@ -27,6 +27,8 @@ from sys import exit from vyos.config import Config from vyos.util import call +PDNS_CMD='/usr/bin/rec_control --socket-dir=/run/powerdns' + parser = argparse.ArgumentParser() parser.add_argument("-a", "--all", action="store_true", help="Reset all cache") parser.add_argument("domain", type=str, nargs="?", help="Domain to reset cache entries for") @@ -41,11 +43,11 @@ if __name__ == '__main__': exit(0) if args.all: - call("rec_control wipe-cache \'.$\'") + call(f"{PDNS_CMD} wipe-cache \'.$\'") exit(0) elif args.domain: - call("rec_control wipe-cache \'{0}$\'".format(args.domain)) + call(f"{PDNS_CMD} wipe-cache \'{0}$\'".format(args.domain)) else: parser.print_help() diff --git a/src/op_mode/dns_forwarding_statistics.py b/src/op_mode/dns_forwarding_statistics.py index c400a72cd..8ae92beb7 100755 --- a/src/op_mode/dns_forwarding_statistics.py +++ b/src/op_mode/dns_forwarding_statistics.py @@ -1,12 +1,12 @@ #!/usr/bin/env python3 import jinja2 -import sys +from sys import exit from vyos.config import Config from vyos.config import cmd -PDNS_CMD='/usr/bin/rec_control' +PDNS_CMD='/usr/bin/rec_control --socket-dir=/run/powerdns' OUT_TMPL_SRC = """ DNS forwarding statistics: @@ -16,13 +16,12 @@ Cache size: {{ cache_size }} kbytes """ - if __name__ == '__main__': # Do nothing if service is not configured c = Config() if not c.exists_effective('service dns forwarding'): print("DNS forwarding is not configured") - sys.exit(0) + exit(0) data = {} diff --git a/src/system/on-dhcp-event.sh b/src/system/on-dhcp-event.sh index 5046912a6..385ae460f 100755 --- a/src/system/on-dhcp-event.sh +++ b/src/system/on-dhcp-event.sh @@ -63,7 +63,7 @@ if [ $changes -gt 0 ]; then echo Success pid=`pgrep pdns_recursor` if [ -n "$pid" ]; then - sudo rec_control reload-zones + sudo rec_control --socket-dir=/run/powerdns reload-zones fi else echo No changes made |